refactor: tagLen as parameter

This commit is contained in:
Richard Ramos 2023-11-20 15:14:02 -04:00
parent bf665a0222
commit 83d6d553a3
No known key found for this signature in database
GPG Key ID: 1CE87DB518195760
6 changed files with 41 additions and 39 deletions

View File

@ -1,4 +1,4 @@
import { ChaCha20Poly1305, TAG_LENGTH } from "@stablelib/chacha20poly1305"; import { ChaCha20Poly1305 } from "@stablelib/chacha20poly1305";
import { Hash } from "@stablelib/hash"; import { Hash } from "@stablelib/hash";
import { HKDF as hkdf } from "@stablelib/hkdf"; import { HKDF as hkdf } from "@stablelib/hkdf";
import { hash } from "@stablelib/sha256"; import { hash } from "@stablelib/sha256";
@ -10,8 +10,6 @@ import type { KeyPair } from "./@types/keypair.js";
export const Curve25519KeySize = x25519.PUBLIC_KEY_LENGTH; export const Curve25519KeySize = x25519.PUBLIC_KEY_LENGTH;
export const ChachaPolyTagLen = TAG_LENGTH;
/** /**
* Generate hash using SHA2-256 * Generate hash using SHA2-256
* @param data data to hash * @param data data to hash

View File

@ -8,7 +8,7 @@ import { Handshake, HandshakeStepResult } from "./handshake";
import { MessageNametagBuffer, MessageNametagLength } from "./messagenametag"; import { MessageNametagBuffer, MessageNametagLength } from "./messagenametag";
import { CipherState, createEmptyKey, SymmetricState } from "./noise"; import { CipherState, createEmptyKey, SymmetricState } from "./noise";
import { MAX_NONCE, Nonce } from "./nonce"; import { MAX_NONCE, Nonce } from "./nonce";
import { NoiseHandshakePatterns } from "./patterns"; import { NoiseHandshakePatterns, PayloadV2ProtocolIDs } from "./patterns";
import { PayloadV2 } from "./payload"; import { PayloadV2 } from "./payload";
import { ChaChaPolyCipherState, NoisePublicKey } from "./publickey"; import { ChaChaPolyCipherState, NoisePublicKey } from "./publickey";
@ -38,13 +38,15 @@ function randomNoisePublicKey(): NoisePublicKey {
function randomPayloadV2(rng: HMACDRBG): PayloadV2 { function randomPayloadV2(rng: HMACDRBG): PayloadV2 {
const messageNametag = randomBytes(MessageNametagLength, rng); const messageNametag = randomBytes(MessageNametagLength, rng);
const protocolId = 14; const protocolId = 14;
const protocolName = Object.keys(PayloadV2ProtocolIDs).find((key) => PayloadV2ProtocolIDs[key] === protocolId);
const handshakePattern = NoiseHandshakePatterns[protocolName!];
const handshakeMessage = [randomNoisePublicKey(), randomNoisePublicKey(), randomNoisePublicKey()]; const handshakeMessage = [randomNoisePublicKey(), randomNoisePublicKey(), randomNoisePublicKey()];
const transportMessage = randomBytes(128); const transportMessage = randomBytes(128);
return new PayloadV2(messageNametag, protocolId, handshakeMessage, transportMessage); return new PayloadV2(messageNametag, protocolId, handshakePattern.tagLen, handshakeMessage, transportMessage);
} }
describe("js-noise", () => { describe("js-noise", () => {
const rng = new HMACDRBG(); const rng = new HMACDRBG(undefined);
it("ChaChaPoly Encryption/Decryption: random byte sequences", function () { it("ChaChaPoly Encryption/Decryption: random byte sequences", function () {
const cipherState = randomChaChaPolyCipherState(rng); const cipherState = randomChaChaPolyCipherState(rng);
@ -241,7 +243,7 @@ describe("js-noise", () => {
it("Noise State Machine: Cipher State primitives", function () { it("Noise State Machine: Cipher State primitives", function () {
// We select one supported handshake pattern and we initialize a symmetric state // We select one supported handshake pattern and we initialize a symmetric state
const hsPattern = NoiseHandshakePatterns.XX; const hsPattern = NoiseHandshakePatterns.Noise_XX_25519_ChaChaPoly_SHA256;
let symmetricState = new SymmetricState(hsPattern); let symmetricState = new SymmetricState(hsPattern);
// We get all the Symmetric State field // We get all the Symmetric State field
@ -352,8 +354,8 @@ describe("js-noise", () => {
expect(uint8ArrayEquals(cs1.getKey(), cs2.getKey())).to.be.false; expect(uint8ArrayEquals(cs1.getKey(), cs2.getKey())).to.be.false;
}); });
it("Noise XX Handhshake and message encryption (extended test)", function () { it("Noise XX Handshake and message encryption (extended test)", function () {
const hsPattern = NoiseHandshakePatterns.XX; const hsPattern = NoiseHandshakePatterns.Noise_XX_25519_ChaChaPoly_SHA256;
// We initialize Alice's and Bob's Handshake State // We initialize Alice's and Bob's Handshake State
const aliceStaticKey = generateX25519KeyPair(); const aliceStaticKey = generateX25519KeyPair();
@ -464,7 +466,7 @@ describe("js-noise", () => {
}); });
it("Noise XXpsk0 Handhshake and message encryption (short test)", function () { it("Noise XXpsk0 Handhshake and message encryption (short test)", function () {
const hsPattern = NoiseHandshakePatterns.XXpsk0; const hsPattern = NoiseHandshakePatterns.Noise_XXpsk0_25519_ChaChaPoly_SHA256;
// We generate a random psk // We generate a random psk
const psk = randomBytes(32, rng); const psk = randomBytes(32, rng);
@ -559,7 +561,7 @@ describe("js-noise", () => {
}); });
it("Noise K1K1 Handhshake and message encryption (short test)", function () { it("Noise K1K1 Handhshake and message encryption (short test)", function () {
const hsPattern = NoiseHandshakePatterns.K1K1; const hsPattern = NoiseHandshakePatterns.Noise_K1K1_25519_ChaChaPoly_SHA256;
// We initialize Alice's and Bob's Handshake State // We initialize Alice's and Bob's Handshake State
const aliceStaticKey = generateX25519KeyPair(); const aliceStaticKey = generateX25519KeyPair();
@ -661,7 +663,7 @@ describe("js-noise", () => {
}); });
it("Noise XK1 Handhshake and message encryption (short test)", function () { it("Noise XK1 Handhshake and message encryption (short test)", function () {
const hsPattern = NoiseHandshakePatterns.XK1; const hsPattern = NoiseHandshakePatterns.Noise_XK1_25519_ChaChaPoly_SHA256;
// We initialize Alice's and Bob's Handshake State // We initialize Alice's and Bob's Handshake State
const aliceStaticKey = generateX25519KeyPair(); const aliceStaticKey = generateX25519KeyPair();

View File

@ -124,7 +124,7 @@ export class WakuPairing {
const preMessagePKs = [NoisePublicKey.fromPublicKey(this.qr.ephemeralKey)]; const preMessagePKs = [NoisePublicKey.fromPublicKey(this.qr.ephemeralKey)];
this.handshake = new Handshake({ this.handshake = new Handshake({
hsPattern: NoiseHandshakePatterns.WakuPairing, hsPattern: NoiseHandshakePatterns.Noise_WakuPairing_25519_ChaChaPoly_SHA256,
ephemeralKey: myEphemeralKey, ephemeralKey: myEphemeralKey,
staticKey: myStaticKey, staticKey: myStaticKey,
prologue: this.qr.toByteArray(), prologue: this.qr.toByteArray(),

View File

@ -1,3 +1,4 @@
import { TAG_LENGTH as ChaChaPolyTagLen } from "@stablelib/chacha20poly1305";
import { Hash } from "@stablelib/hash"; import { Hash } from "@stablelib/hash";
import { SHA256 } from "@stablelib/sha256"; import { SHA256 } from "@stablelib/sha256";
@ -74,6 +75,7 @@ export class HandshakePattern {
constructor( constructor(
public readonly name: string, public readonly name: string,
public readonly hash: new () => Hash, public readonly hash: new () => Hash,
public readonly tagLen: number,
public readonly preMessagePatterns: Array<PreMessagePattern>, public readonly preMessagePatterns: Array<PreMessagePattern>,
public readonly messagePatterns: Array<MessagePattern> public readonly messagePatterns: Array<MessagePattern>
) {} ) {}
@ -101,10 +103,11 @@ export class HandshakePattern {
/** /**
* Supported Noise handshake patterns as defined in https://rfc.vac.dev/spec/35/#specification * Supported Noise handshake patterns as defined in https://rfc.vac.dev/spec/35/#specification
*/ */
export const NoiseHandshakePatterns = { export const NoiseHandshakePatterns: Record<string, HandshakePattern> = {
K1K1: new HandshakePattern( Noise_K1K1_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_K1K1_25519_ChaChaPoly_SHA256", "Noise_K1K1_25519_ChaChaPoly_SHA256",
SHA256, SHA256,
ChaChaPolyTagLen,
[ [
new PreMessagePattern(MessageDirection.r, [NoiseTokens.s]), new PreMessagePattern(MessageDirection.r, [NoiseTokens.s]),
new PreMessagePattern(MessageDirection.l, [NoiseTokens.s]), new PreMessagePattern(MessageDirection.l, [NoiseTokens.s]),
@ -115,9 +118,10 @@ export const NoiseHandshakePatterns = {
new MessagePattern(MessageDirection.r, [NoiseTokens.se]), new MessagePattern(MessageDirection.r, [NoiseTokens.se]),
] ]
), ),
XK1: new HandshakePattern( Noise_XK1_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_XK1_25519_ChaChaPoly_SHA256", "Noise_XK1_25519_ChaChaPoly_SHA256",
SHA256, SHA256,
ChaChaPolyTagLen,
[new PreMessagePattern(MessageDirection.l, [NoiseTokens.s])], [new PreMessagePattern(MessageDirection.l, [NoiseTokens.s])],
[ [
new MessagePattern(MessageDirection.r, [NoiseTokens.e]), new MessagePattern(MessageDirection.r, [NoiseTokens.e]),
@ -125,9 +129,10 @@ export const NoiseHandshakePatterns = {
new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]), new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]),
] ]
), ),
XX: new HandshakePattern( Noise_XX_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_XX_25519_ChaChaPoly_SHA256", "Noise_XX_25519_ChaChaPoly_SHA256",
SHA256, SHA256,
ChaChaPolyTagLen,
[], [],
[ [
new MessagePattern(MessageDirection.r, [NoiseTokens.e]), new MessagePattern(MessageDirection.r, [NoiseTokens.e]),
@ -135,9 +140,10 @@ export const NoiseHandshakePatterns = {
new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]), new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]),
] ]
), ),
XXpsk0: new HandshakePattern( Noise_XXpsk0_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_XXpsk0_25519_ChaChaPoly_SHA256", "Noise_XXpsk0_25519_ChaChaPoly_SHA256",
SHA256, SHA256,
ChaChaPolyTagLen,
[], [],
[ [
new MessagePattern(MessageDirection.r, [NoiseTokens.psk, NoiseTokens.e]), new MessagePattern(MessageDirection.r, [NoiseTokens.psk, NoiseTokens.e]),
@ -145,9 +151,10 @@ export const NoiseHandshakePatterns = {
new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]), new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]),
] ]
), ),
WakuPairing: new HandshakePattern( Noise_WakuPairing_25519_ChaChaPoly_SHA256: new HandshakePattern(
"Noise_WakuPairing_25519_ChaChaPoly_SHA256", "Noise_WakuPairing_25519_ChaChaPoly_SHA256",
SHA256, SHA256,
ChaChaPolyTagLen,
[new PreMessagePattern(MessageDirection.l, [NoiseTokens.e])], [new PreMessagePattern(MessageDirection.l, [NoiseTokens.e])],
[ [
new MessagePattern(MessageDirection.r, [NoiseTokens.e, NoiseTokens.ee]), new MessagePattern(MessageDirection.r, [NoiseTokens.e, NoiseTokens.ee]),

View File

@ -2,9 +2,9 @@ import { concat as uint8ArrayConcat } from "uint8arrays/concat";
import { equals as uint8ArrayEquals } from "uint8arrays/equals"; import { equals as uint8ArrayEquals } from "uint8arrays/equals";
import { MessageNametag } from "./@types/handshake.js"; import { MessageNametag } from "./@types/handshake.js";
import { ChachaPolyTagLen, Curve25519KeySize } from "./crypto.js"; import { Curve25519KeySize } from "./crypto.js";
import { MessageNametagLength } from "./messagenametag.js"; import { MessageNametagLength } from "./messagenametag.js";
import { PayloadV2ProtocolIDs } from "./patterns.js"; import { NoiseHandshakePatterns, PayloadV2ProtocolIDs } from "./patterns.js";
import { NoisePublicKey } from "./publickey.js"; import { NoisePublicKey } from "./publickey.js";
import { readUIntLE, writeUIntLE } from "./utils.js"; import { readUIntLE, writeUIntLE } from "./utils.js";
@ -15,22 +15,13 @@ import { readUIntLE, writeUIntLE } from "./utils.js";
* and the transport message * and the transport message
*/ */
export class PayloadV2 { export class PayloadV2 {
messageNametag: MessageNametag;
protocolId: number;
handshakeMessage: Array<NoisePublicKey>;
transportMessage: Uint8Array;
constructor( constructor(
messageNametag: MessageNametag = new Uint8Array(MessageNametagLength), public messageNametag: MessageNametag = new Uint8Array(MessageNametagLength),
protocolId = 0, public protocolId = 0,
handshakeMessage: Array<NoisePublicKey> = [], public tagLen = 0,
transportMessage: Uint8Array = new Uint8Array() public handshakeMessage: Array<NoisePublicKey> = [],
) { public transportMessage: Uint8Array = new Uint8Array()
this.messageNametag = messageNametag; ) {}
this.protocolId = protocolId;
this.handshakeMessage = handshakeMessage;
this.transportMessage = transportMessage;
}
/** /**
* Create a copy of the PayloadV2 * Create a copy of the PayloadV2
@ -41,6 +32,7 @@ export class PayloadV2 {
r.protocolId = this.protocolId; r.protocolId = this.protocolId;
r.transportMessage = new Uint8Array(this.transportMessage); r.transportMessage = new Uint8Array(this.transportMessage);
r.messageNametag = new Uint8Array(this.messageNametag); r.messageNametag = new Uint8Array(this.messageNametag);
r.tagLen = this.tagLen;
for (let i = 0; i < this.handshakeMessage.length; i++) { for (let i = 0; i < this.handshakeMessage.length; i++) {
r.handshakeMessage.push(this.handshakeMessage[i].clone()); r.handshakeMessage.push(this.handshakeMessage[i].clone());
} }
@ -146,6 +138,9 @@ export class PayloadV2 {
throw new Error("protocolId not found"); throw new Error("protocolId not found");
} }
const pattern = NoiseHandshakePatterns[protocolName];
const tagLen = pattern ? pattern.tagLen : 0;
i++; i++;
// We read the Handshake Message length (1 byte) // We read the Handshake Message length (1 byte)
@ -174,7 +169,7 @@ export class PayloadV2 {
written += 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 // 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) { } else if (flag === 1) {
const pkLen = 1 + Curve25519KeySize + ChachaPolyTagLen; const pkLen = 1 + Curve25519KeySize + tagLen;
handshakeMessage.push(NoisePublicKey.deserialize(payload.subarray(i, i + pkLen))); handshakeMessage.push(NoisePublicKey.deserialize(payload.subarray(i, i + pkLen)));
i += pkLen; i += pkLen;
written += pkLen; written += pkLen;
@ -191,6 +186,6 @@ export class PayloadV2 {
const transportMessage = payload.subarray(i, i + transportMessageLen); const transportMessage = payload.subarray(i, i + transportMessageLen);
i += transportMessageLen; i += transportMessageLen;
return new PayloadV2(messageNametag, protocolId, handshakeMessage, transportMessage); return new PayloadV2(messageNametag, protocolId, tagLen, handshakeMessage, transportMessage);
} }
} }

View File

@ -27,7 +27,7 @@ describe("Waku Noise Sessions", () => {
// Pairing Phase // Pairing Phase
// ========== // ==========
const hsPattern = NoiseHandshakePatterns.WakuPairing; const hsPattern = NoiseHandshakePatterns.Noise_WakuPairing_25519_ChaChaPoly_SHA256;
// Alice static/ephemeral key initialization and commitment // Alice static/ephemeral key initialization and commitment
const aliceStaticKey = generateX25519KeyPair(); const aliceStaticKey = generateX25519KeyPair();