refactor: key type as parameter

This commit is contained in:
Richard Ramos 2023-11-20 15:56:52 -04:00 committed by richΛrd
parent d9b8fdc98e
commit 6baa061f0e
10 changed files with 173 additions and 117 deletions

View File

@ -1,15 +1,13 @@
import { ChaCha20Poly1305 } from "@stablelib/chacha20poly1305";
import { Hash } from "@stablelib/hash";
import { HKDF as hkdf } from "@stablelib/hkdf";
import { RandomSource } from "@stablelib/random";
import { hash } from "@stablelib/sha256";
import * as x25519 from "@stablelib/x25519";
import { concat as uint8ArrayConcat } from "uint8arrays/concat";
import type { bytes32 } from "./@types/basic.js";
import type { KeyPair } from "./@types/keypair.js";
export const Curve25519KeySize = x25519.PUBLIC_KEY_LENGTH;
/**
* Generate hash using SHA2-256
* @param data data to hash
@ -19,21 +17,6 @@ export function hashSHA256(data: Uint8Array): Uint8Array {
return hash(data);
}
/**
* Convert an Uint8Array into a 32-byte value. If the input data length is different
* from 32, throw an error. This is used mostly as a validation function to ensure
* that an Uint8Array represents a valid x25519 key
* @param s input data
* @return 32-byte key
*/
export function intoCurve25519Key(s: Uint8Array): bytes32 {
if (s.length != x25519.PUBLIC_KEY_LENGTH) {
throw new Error("invalid public key length");
}
return s;
}
/**
* HKDF key derivation function using SHA256
* @param ck chaining key
@ -59,33 +42,6 @@ export function HKDF(
return result;
}
/**
* Generate a random keypair
* @returns Keypair
*/
export function generateX25519KeyPair(): KeyPair {
const keypair = x25519.generateKeyPair();
return {
publicKey: keypair.publicKey,
privateKey: keypair.secretKey,
};
}
/**
* Generate x25519 keypair using an input seed
* @param seed 32-byte secret
* @returns Keypair
*/
export function generateX25519KeyPairFromSeed(seed: bytes32): KeyPair {
const keypair = x25519.generateKeyPairFromSeed(seed);
return {
publicKey: keypair.publicKey,
privateKey: keypair.secretKey,
};
}
/**
* Encrypt and authenticate data using ChaCha20-Poly1305
* @param plaintext data to encrypt
@ -123,27 +79,6 @@ export function chaCha20Poly1305Decrypt(
return ctx.open(nonce, ciphertext, ad);
}
/**
* Perform a DiffieHellman key exchange
* @param privateKey x25519 private key
* @param publicKey x25519 public key
* @returns shared secret
*/
export function dh(privateKey: bytes32, publicKey: bytes32): bytes32 {
try {
const derivedU8 = x25519.sharedKey(privateKey, publicKey);
if (derivedU8.length === 32) {
return derivedU8;
}
return derivedU8.subarray(0, 32);
} catch (e) {
console.error(e);
return new Uint8Array(32);
}
}
/**
* Generates a random static key commitment using a public key pk for randomness r as H(pk || s)
* @param publicKey x25519 public key
@ -153,3 +88,43 @@ export function dh(privateKey: bytes32, publicKey: bytes32): bytes32 {
export function commitPublicKey(publicKey: bytes32, r: Uint8Array): bytes32 {
return hashSHA256(uint8ArrayConcat([publicKey, r]));
}
/**
* Represents a key uses for DiffieHellman key exchange
*/
export interface DHKey {
/**
* Convert an Uint8Array into a 32-byte value. If the input data length is different
* from 32, throw an error. This is used mostly as a validation function to ensure
* that an Uint8Array represents a valid key
* @param s input data
* @return 32-byte key
*/
intoKey(s: Uint8Array): bytes32;
/**
* Get key length
*/
DHLen(): number;
/**
* Perform a DiffieHellman key exchange
* @param privateKey private key
* @param publicKey public key
* @returns shared secret
*/
DH(privateKey: bytes32, publicKey: bytes32): bytes32;
/**
* Generate a random keypair
* @returns Keypair
*/
generateKeyPair(prng?: RandomSource): KeyPair;
/**
* Generate keypair using an input seed
* @param seed 32-byte secret
* @returns Keypair
*/
generateKeyPairFromSeed(seed: bytes32): KeyPair;
}

52
src/dh25519.ts Normal file
View File

@ -0,0 +1,52 @@
import * as x25519 from "@stablelib/x25519";
import type { bytes32 } from "./@types/basic.js";
import type { KeyPair } from "./@types/keypair.js";
import { DHKey } from "./crypto.js";
export class DH25519 implements DHKey {
intoKey(s: Uint8Array): bytes32 {
if (s.length != x25519.PUBLIC_KEY_LENGTH) {
throw new Error("invalid public key length");
}
return s;
}
generateKeyPair(): KeyPair {
const keypair = x25519.generateKeyPair();
return {
publicKey: keypair.publicKey,
privateKey: keypair.secretKey,
};
}
generateKeyPairFromSeed(seed: bytes32): KeyPair {
const keypair = x25519.generateKeyPairFromSeed(seed);
return {
publicKey: keypair.publicKey,
privateKey: keypair.secretKey,
};
}
DH(privateKey: bytes32, publicKey: bytes32): bytes32 {
try {
const derivedU8 = x25519.sharedKey(privateKey, publicKey);
if (derivedU8.length === 32) {
return derivedU8;
}
return derivedU8.subarray(0, 32);
} catch (e) {
console.error(e);
return new Uint8Array(32);
}
}
DHLen(): number {
return x25519.PUBLIC_KEY_LENGTH;
}
}

View File

@ -5,7 +5,7 @@ import { equals as uint8ArrayEquals } from "uint8arrays/equals";
import { bytes32 } from "./@types/basic.js";
import { MessageNametag } from "./@types/handshake.js";
import type { KeyPair } from "./@types/keypair.js";
import { Curve25519KeySize, dh, generateX25519KeyPair, HKDF, intoCurve25519Key } from "./crypto.js";
import { HKDF } from "./crypto.js";
import { MessageNametagLength } from "./messagenametag.js";
import { SymmetricState } from "./noise.js";
import { HandshakePattern, MessageDirection, NoiseTokens, PreMessagePattern } from "./patterns.js";
@ -212,7 +212,7 @@ export class HandshakeState {
// We check if current key is encrypted or not. We assume pre-message public keys are all unencrypted on users' end
if (currPK.flag == 0) {
// Sets re and calls MixHash(re.public_key).
this.re = intoCurve25519Key(currPK.pk);
this.re = this.handshakePattern.dhKey.intoKey(currPK.pk);
this.ss.mixHash(this.re);
} else {
throw new Error("noise read e, incorrect encryption flag for pre-message public key");
@ -223,7 +223,7 @@ export class HandshakeState {
// When writing, the user is sending a public key,
// We check that the public part corresponds to the set local key and we call MixHash(e.public_key).
if (this.e && uint8ArrayEquals(this.e.publicKey, intoCurve25519Key(currPK.pk))) {
if (this.e && uint8ArrayEquals(this.e.publicKey, this.handshakePattern.dhKey.intoKey(currPK.pk))) {
this.ss.mixHash(this.e.publicKey);
} else {
throw new Error("noise pre-message e key doesn't correspond to locally set e key pair");
@ -256,7 +256,7 @@ export class HandshakeState {
// We check if current key is encrypted or not. We assume pre-message public keys are all unencrypted on users' end
if (currPK.flag == 0) {
// Sets re and calls MixHash(re.public_key).
this.rs = intoCurve25519Key(currPK.pk);
this.rs = this.handshakePattern.dhKey.intoKey(currPK.pk);
this.ss.mixHash(this.rs);
} else {
throw new Error("noise read s, incorrect encryption flag for pre-message public key");
@ -268,7 +268,7 @@ export class HandshakeState {
// If writing, it means that the user is sending a public key,
// We check that the public part corresponds to the set local key and we call MixHash(s.public_key).
if (this.s && uint8ArrayEquals(this.s.publicKey, intoCurve25519Key(currPK.pk))) {
if (this.s && uint8ArrayEquals(this.s.publicKey, this.handshakePattern.dhKey.intoKey(currPK.pk))) {
this.ss.mixHash(this.s.publicKey);
} else {
throw new Error("noise pre-message s key doesn't correspond to locally set s key pair");
@ -358,14 +358,14 @@ export class HandshakeState {
if (currPK.flag == 0) {
// Unencrypted Public Key
// Sets re and calls MixHash(re.public_key).
this.re = intoCurve25519Key(currPK.pk);
this.re = this.handshakePattern.dhKey.intoKey(currPK.pk);
this.ss.mixHash(this.re);
// The following is out of specification: we call decryptAndHash for encrypted ephemeral keys, similarly as happens for (encrypted) static keys
} else if (currPK.flag == 1) {
// Encrypted public key
// Decrypts re, sets re and calls MixHash(re.public_key).
this.re = intoCurve25519Key(this.ss.decryptAndHash(currPK.pk));
this.re = this.handshakePattern.dhKey.intoKey(this.ss.decryptAndHash(currPK.pk));
} else {
throw new Error("noise read e, incorrect encryption flag for public key");
}
@ -386,7 +386,7 @@ export class HandshakeState {
log("noise write e");
// We generate a new ephemeral keypair
this.e = generateX25519KeyPair();
this.e = this.handshakePattern.dhKey.generateKeyPair();
// We update the state
this.ss.mixHash(this.e.publicKey);
@ -420,12 +420,12 @@ export class HandshakeState {
if (currPK.flag == 0) {
// Unencrypted Public Key
// Sets re and calls MixHash(re.public_key).
this.rs = intoCurve25519Key(currPK.pk);
this.rs = this.handshakePattern.dhKey.intoKey(currPK.pk);
this.ss.mixHash(this.rs);
} else if (currPK.flag == 1) {
// Encrypted public key
// Decrypts rs, sets rs and calls MixHash(rs.public_key).
this.rs = intoCurve25519Key(this.ss.decryptAndHash(currPK.pk));
this.rs = this.handshakePattern.dhKey.intoKey(this.ss.decryptAndHash(currPK.pk));
} else {
throw new Error("noise read s, incorrect encryption flag for public key");
}
@ -449,7 +449,7 @@ export class HandshakeState {
// We add the (encrypted) static public key to the Waku payload
// Note that encS = (Enc(s) || tag) if encryption key is set, otherwise encS = s.
// We distinguish these two cases by checking length of encryption and we set the proper encryption flag
if (encS.length > Curve25519KeySize) {
if (encS.length > this.handshakePattern.dhKey.DHLen()) {
outHandshakeMessage.push(new NoisePublicKey(1, encS));
} else {
outHandshakeMessage.push(new NoisePublicKey(0, encS));
@ -478,7 +478,7 @@ export class HandshakeState {
}
// Calls MixKey(DH(e, re)).
this.ss.mixKey(dh(this.e.privateKey, this.re));
this.ss.mixKey(this.handshakePattern.dhKey.DH(this.e.privateKey, this.re));
break;
case NoiseTokens.es:
@ -493,13 +493,13 @@ export class HandshakeState {
throw new Error("local or remote ephemeral/static key not set");
}
this.ss.mixKey(dh(this.e.privateKey, this.rs));
this.ss.mixKey(this.handshakePattern.dhKey.DH(this.e.privateKey, this.rs));
} else {
if (!this.re || !this.s) {
throw new Error("local or remote ephemeral/static key not set");
}
this.ss.mixKey(dh(this.s.privateKey, this.re));
this.ss.mixKey(this.handshakePattern.dhKey.DH(this.s.privateKey, this.re));
}
break;
@ -515,13 +515,13 @@ export class HandshakeState {
throw new Error("local or remote ephemeral/static key not set");
}
this.ss.mixKey(dh(this.s.privateKey, this.re));
this.ss.mixKey(this.handshakePattern.dhKey.DH(this.s.privateKey, this.re));
} else {
if (!this.rs || !this.e) {
throw new Error("local or remote ephemeral/static key not set");
}
this.ss.mixKey(dh(this.e.privateKey, this.rs));
this.ss.mixKey(this.handshakePattern.dhKey.DH(this.e.privateKey, this.rs));
}
break;
@ -536,7 +536,7 @@ export class HandshakeState {
}
// Calls MixKey(DH(s, rs)).
this.ss.mixKey(dh(this.s.privateKey, this.rs));
this.ss.mixKey(this.handshakePattern.dhKey.DH(this.s.privateKey, this.rs));
break;
}
}

View File

@ -3,7 +3,8 @@ import { randomBytes } from "@stablelib/random";
import { expect } from "chai";
import { equals as uint8ArrayEquals } from "uint8arrays/equals";
import { chaCha20Poly1305Encrypt, dh, generateX25519KeyPair } from "./crypto";
import { chaCha20Poly1305Encrypt } from "./crypto";
import { DH25519 } from "./dh25519";
import { Handshake, HandshakeStepResult } from "./handshake";
import { MessageNametagBuffer, MessageNametagLength } from "./messagenametag";
import { CipherState, createEmptyKey, SymmetricState } from "./noise";
@ -31,7 +32,8 @@ function randomChaChaPolyCipherState(rng: HMACDRBG): ChaChaPolyCipherState {
}
function randomNoisePublicKey(): NoisePublicKey {
const keypair = generateX25519KeyPair();
const dhKey = new DH25519();
const keypair = dhKey.generateKeyPair();
return new NoisePublicKey(0, keypair.publicKey);
}
@ -138,13 +140,15 @@ describe("js-noise", () => {
});
it("Noise State Machine: Diffie-Hellman operation", function () {
const aliceKey = generateX25519KeyPair();
const bobKey = generateX25519KeyPair();
const dhKey = new DH25519();
const aliceKey = dhKey.generateKeyPair();
const bobKey = dhKey.generateKeyPair();
// A Diffie-Hellman operation between Alice's private key and Bob's public key must be equal to
// a Diffie-hellman operation between Alice's public key and Bob's private key
const dh1 = dh(aliceKey.privateKey, bobKey.publicKey);
const dh2 = dh(bobKey.privateKey, aliceKey.publicKey);
const dh1 = dhKey.DH(aliceKey.privateKey, bobKey.publicKey);
const dh2 = dhKey.DH(bobKey.privateKey, aliceKey.publicKey);
expect(uint8ArrayEquals(dh1, dh2)).to.be.true;
});
@ -355,13 +359,14 @@ describe("js-noise", () => {
});
it("Noise XX Handshake and message encryption (extended test)", function () {
const dhKey = new DH25519();
const hsPattern = NoiseHandshakePatterns.Noise_XX_25519_ChaChaPoly_SHA256;
// We initialize Alice's and Bob's Handshake State
const aliceStaticKey = generateX25519KeyPair();
const aliceStaticKey = dhKey.generateKeyPair();
const aliceHS = new Handshake({ hsPattern, staticKey: aliceStaticKey, initiator: true });
const bobStaticKey = generateX25519KeyPair();
const bobStaticKey = dhKey.generateKeyPair();
const bobHS = new Handshake({ hsPattern, staticKey: bobStaticKey });
let sentTransportMessage: Uint8Array;
@ -466,16 +471,17 @@ describe("js-noise", () => {
});
it("Noise XXpsk0 Handhshake and message encryption (short test)", function () {
const dhKey = new DH25519();
const hsPattern = NoiseHandshakePatterns.Noise_XXpsk0_25519_ChaChaPoly_SHA256;
// We generate a random psk
const psk = randomBytes(32, rng);
// We initialize Alice's and Bob's Handshake State
const aliceStaticKey = generateX25519KeyPair();
const aliceStaticKey = dhKey.generateKeyPair();
const aliceHS = new Handshake({ hsPattern, staticKey: aliceStaticKey, psk, initiator: true });
const bobStaticKey = generateX25519KeyPair();
const bobStaticKey = dhKey.generateKeyPair();
const bobHS = new Handshake({ hsPattern, staticKey: bobStaticKey, psk });
let sentTransportMessage: Uint8Array;
@ -561,12 +567,13 @@ describe("js-noise", () => {
});
it("Noise K1K1 Handhshake and message encryption (short test)", function () {
const dhKey = new DH25519();
const hsPattern = NoiseHandshakePatterns.Noise_K1K1_25519_ChaChaPoly_SHA256;
// We initialize Alice's and Bob's Handshake State
const aliceStaticKey = generateX25519KeyPair();
const aliceStaticKey = dhKey.generateKeyPair();
const bobStaticKey = generateX25519KeyPair();
const bobStaticKey = dhKey.generateKeyPair();
// This handshake has the following pre-message pattern:
// -> s
@ -663,11 +670,12 @@ describe("js-noise", () => {
});
it("Noise XK1 Handhshake and message encryption (short test)", function () {
const dhKey = new DH25519();
const hsPattern = NoiseHandshakePatterns.Noise_XK1_25519_ChaChaPoly_SHA256;
// We initialize Alice's and Bob's Handshake State
const aliceStaticKey = generateX25519KeyPair();
const bobStaticKey = generateX25519KeyPair();
const aliceStaticKey = dhKey.generateKeyPair();
const bobStaticKey = dhKey.generateKeyPair();
// This handshake has the following pre-message pattern:
// <- s

View File

@ -4,7 +4,7 @@ import {
NoiseSecureTransferDecoder,
NoiseSecureTransferEncoder,
} from "./codec.js";
import { generateX25519KeyPair, generateX25519KeyPairFromSeed } from "./crypto.js";
import { DH25519 } from "./dh25519.js";
import {
Handshake,
HandshakeParameters,
@ -35,7 +35,7 @@ export {
MessageNametagError,
StepHandshakeParameters,
};
export { generateX25519KeyPair, generateX25519KeyPairFromSeed };
export { DH25519 as X25519DHKey };
export {
HandshakePattern,
MessageDirection,

View File

@ -7,7 +7,7 @@ import { pEvent } from "p-event";
import { equals as uint8ArrayEquals } from "uint8arrays/equals";
import { NoiseHandshakeMessage } from "./codec";
import { generateX25519KeyPair } from "./crypto";
import { DH25519 } from "./dh25519";
import { MessageNametagBufferSize } from "./messagenametag";
import { ResponderParameters, WakuPairing } from "./pairing";
@ -66,8 +66,10 @@ describe("js-noise: pairing object", () => {
// =================
it("should pair", async function () {
const bobStaticKey = generateX25519KeyPair();
const aliceStaticKey = generateX25519KeyPair();
const dhKey = new DH25519();
const bobStaticKey = dhKey.generateKeyPair();
const aliceStaticKey = dhKey.generateKeyPair();
const recvParameters = new ResponderParameters();
const bobPairingObj = new WakuPairing(sender, responder, bobStaticKey, recvParameters);
@ -112,8 +114,9 @@ describe("js-noise: pairing object", () => {
});
it("should timeout", async function () {
const bobPairingObj = new WakuPairing(sender, responder, generateX25519KeyPair(), new ResponderParameters());
const alicePairingObj = new WakuPairing(sender, responder, generateX25519KeyPair(), bobPairingObj.getPairingInfo());
const dhKey = new DH25519();
const bobPairingObj = new WakuPairing(sender, responder, dhKey.generateKeyPair(), new ResponderParameters());
const alicePairingObj = new WakuPairing(sender, responder, dhKey.generateKeyPair(), bobPairingObj.getPairingInfo());
const bobExecP1 = bobPairingObj.execute(1000);
const aliceExecP1 = alicePairingObj.execute(1000);
@ -130,8 +133,9 @@ describe("js-noise: pairing object", () => {
});
it("pairs and `meta` field is encoded", async function () {
const bobStaticKey = generateX25519KeyPair();
const aliceStaticKey = generateX25519KeyPair();
const dhKey = new DH25519();
const bobStaticKey = dhKey.generateKeyPair();
const aliceStaticKey = dhKey.generateKeyPair();
// Encode the length of the payload
// Not a relevant real life example

View File

@ -14,7 +14,8 @@ import {
NoiseSecureTransferDecoder,
NoiseSecureTransferEncoder,
} from "./codec.js";
import { commitPublicKey, generateX25519KeyPair } from "./crypto.js";
import { commitPublicKey } from "./crypto.js";
import { DH25519 } from "./dh25519.js";
import { Handshake, HandshakeResult, HandshakeStepResult, MessageNametagError } from "./handshake.js";
import { MessageNametagLength } from "./messagenametag.js";
import { NoiseHandshakePatterns } from "./patterns.js";
@ -94,7 +95,7 @@ export class WakuPairing {
private responder: IReceiver,
private myStaticKey: KeyPair,
pairingParameters: InitiatorParameters | ResponderParameters,
private myEphemeralKey: KeyPair = generateX25519KeyPair(),
private myEphemeralKey: KeyPair = new DH25519().generateKeyPair(),
private readonly encoderParameters: EncoderParameters = {}
) {
this.randomFixLenVal = randomBytes(32, rng);

View File

@ -2,6 +2,9 @@ import { TAG_LENGTH as ChaChaPolyTagLen } from "@stablelib/chacha20poly1305";
import { Hash } from "@stablelib/hash";
import { SHA256 } from "@stablelib/sha256";
import { DHKey } from "./crypto";
import { DH25519 } from "./dh25519";
/**
* The Noise tokens appearing in Noise (pre)message patterns
* as in http://www.noiseprotocol.org/noise.html#handshake-pattern-basics
@ -72,13 +75,18 @@ export class MessagePattern {
* handshake pre message patterns and the handshake message patterns
*/
export class HandshakePattern {
public readonly dhKey: DHKey;
constructor(
public readonly name: string,
dhKeyType: new () => DHKey,
public readonly hash: new () => Hash,
public readonly tagLen: number,
public readonly preMessagePatterns: Array<PreMessagePattern>,
public readonly messagePatterns: Array<MessagePattern>
) {}
) {
this.dhKey = new dhKeyType();
}
/**
* Check HandshakePattern equality
@ -106,6 +114,7 @@ export class HandshakePattern {
export const NoiseHandshakePatterns: Record<string, HandshakePattern> = {
Noise_K1K1_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_K1K1_25519_ChaChaPoly_SHA256",
DH25519,
SHA256,
ChaChaPolyTagLen,
[
@ -120,6 +129,7 @@ export const NoiseHandshakePatterns: Record<string, HandshakePattern> = {
),
Noise_XK1_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_XK1_25519_ChaChaPoly_SHA256",
DH25519,
SHA256,
ChaChaPolyTagLen,
[new PreMessagePattern(MessageDirection.l, [NoiseTokens.s])],
@ -131,6 +141,7 @@ export const NoiseHandshakePatterns: Record<string, HandshakePattern> = {
),
Noise_XX_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_XX_25519_ChaChaPoly_SHA256",
DH25519,
SHA256,
ChaChaPolyTagLen,
[],
@ -142,6 +153,7 @@ export const NoiseHandshakePatterns: Record<string, HandshakePattern> = {
),
Noise_XXpsk0_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_XXpsk0_25519_ChaChaPoly_SHA256",
DH25519,
SHA256,
ChaChaPolyTagLen,
[],
@ -153,6 +165,7 @@ export const NoiseHandshakePatterns: Record<string, HandshakePattern> = {
),
Noise_WakuPairing_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_WakuPairing_25519_ChaChaPoly_SHA256",
DH25519,
SHA256,
ChaChaPolyTagLen,
[new PreMessagePattern(MessageDirection.l, [NoiseTokens.e])],

View File

@ -2,7 +2,6 @@ import { concat as uint8ArrayConcat } from "uint8arrays/concat";
import { equals as uint8ArrayEquals } from "uint8arrays/equals";
import { MessageNametag } from "./@types/handshake.js";
import { Curve25519KeySize } from "./crypto.js";
import { MessageNametagLength } from "./messagenametag.js";
import { NoiseHandshakePatterns, PayloadV2ProtocolIDs } from "./patterns.js";
import { NoisePublicKey } from "./publickey.js";
@ -140,6 +139,7 @@ export class PayloadV2 {
const pattern = NoiseHandshakePatterns[protocolName];
const tagLen = pattern ? pattern.tagLen : 0;
const keySize = pattern ? pattern.dhKey.DHLen() : 0;
i++;
@ -163,13 +163,13 @@ export class PayloadV2 {
const flag = payload[i];
// If the key is unencrypted, we only read the X coordinate of the EC public key and we deserialize into a Noise Public Key
if (flag === 0) {
const pkLen = 1 + Curve25519KeySize;
const pkLen = 1 + keySize;
handshakeMessage.push(NoisePublicKey.deserialize(payload.subarray(i, i + pkLen)));
i += pkLen;
written += pkLen;
// If the key is encrypted, we only read the encrypted X coordinate and the authorization tag, and we deserialize into a Noise Public Key
} else if (flag === 1) {
const pkLen = 1 + Curve25519KeySize + tagLen;
const pkLen = 1 + keySize + tagLen;
handshakeMessage.push(NoisePublicKey.deserialize(payload.subarray(i, i + pkLen)));
i += pkLen;
written += pkLen;

View File

@ -9,7 +9,8 @@ import {
NoiseSecureTransferDecoder,
NoiseSecureTransferEncoder,
} from "./codec";
import { commitPublicKey, generateX25519KeyPair } from "./crypto";
import { commitPublicKey } from "./crypto";
import { DH25519 } from "./dh25519";
import { Handshake } from "./handshake";
import { MessageNametagBufferSize, MessageNametagLength } from "./messagenametag";
import { NoiseHandshakePatterns } from "./patterns";
@ -27,17 +28,19 @@ describe("Waku Noise Sessions", () => {
// Pairing Phase
// ==========
const dhKey = new DH25519();
const hsPattern = NoiseHandshakePatterns.Noise_WakuPairing_25519_ChaChaPoly_SHA256;
// Alice static/ephemeral key initialization and commitment
const aliceStaticKey = generateX25519KeyPair();
const aliceEphemeralKey = generateX25519KeyPair();
const aliceStaticKey = dhKey.generateKeyPair();
const aliceEphemeralKey = dhKey.generateKeyPair();
const s = randomBytes(32, rng);
const aliceCommittedStaticKey = commitPublicKey(aliceStaticKey.publicKey, s);
// Bob static/ephemeral key initialization and commitment
const bobStaticKey = generateX25519KeyPair();
const bobEphemeralKey = generateX25519KeyPair();
const bobStaticKey = dhKey.generateKeyPair();
const bobEphemeralKey = dhKey.generateKeyPair();
const r = randomBytes(32, rng);
const bobCommittedStaticKey = commitPublicKey(bobStaticKey.publicKey, r);