mirror of
https://github.com/logos-messaging/js-noise.git
synced 2026-01-02 13:43:08 +00:00
refactor: tagLen as parameter
This commit is contained in:
parent
5d54dc28be
commit
d9b8fdc98e
@ -1,4 +1,4 @@
|
||||
import { ChaCha20Poly1305, TAG_LENGTH } from "@stablelib/chacha20poly1305";
|
||||
import { ChaCha20Poly1305 } from "@stablelib/chacha20poly1305";
|
||||
import { Hash } from "@stablelib/hash";
|
||||
import { HKDF as hkdf } from "@stablelib/hkdf";
|
||||
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 ChachaPolyTagLen = TAG_LENGTH;
|
||||
|
||||
/**
|
||||
* Generate hash using SHA2-256
|
||||
* @param data data to hash
|
||||
|
||||
@ -8,7 +8,7 @@ import { Handshake, HandshakeStepResult } from "./handshake";
|
||||
import { MessageNametagBuffer, MessageNametagLength } from "./messagenametag";
|
||||
import { CipherState, createEmptyKey, SymmetricState } from "./noise";
|
||||
import { MAX_NONCE, Nonce } from "./nonce";
|
||||
import { NoiseHandshakePatterns } from "./patterns";
|
||||
import { NoiseHandshakePatterns, PayloadV2ProtocolIDs } from "./patterns";
|
||||
import { PayloadV2 } from "./payload";
|
||||
import { ChaChaPolyCipherState, NoisePublicKey } from "./publickey";
|
||||
|
||||
@ -38,13 +38,15 @@ function randomNoisePublicKey(): NoisePublicKey {
|
||||
function randomPayloadV2(rng: HMACDRBG): PayloadV2 {
|
||||
const messageNametag = randomBytes(MessageNametagLength, rng);
|
||||
const protocolId = 14;
|
||||
const protocolName = Object.keys(PayloadV2ProtocolIDs).find((key) => PayloadV2ProtocolIDs[key] === protocolId);
|
||||
const handshakePattern = NoiseHandshakePatterns[protocolName!];
|
||||
const handshakeMessage = [randomNoisePublicKey(), randomNoisePublicKey(), randomNoisePublicKey()];
|
||||
const transportMessage = randomBytes(128);
|
||||
return new PayloadV2(messageNametag, protocolId, handshakeMessage, transportMessage);
|
||||
return new PayloadV2(messageNametag, protocolId, handshakePattern.tagLen, handshakeMessage, transportMessage);
|
||||
}
|
||||
|
||||
describe("js-noise", () => {
|
||||
const rng = new HMACDRBG();
|
||||
const rng = new HMACDRBG(undefined);
|
||||
|
||||
it("ChaChaPoly Encryption/Decryption: random byte sequences", function () {
|
||||
const cipherState = randomChaChaPolyCipherState(rng);
|
||||
@ -241,7 +243,7 @@ describe("js-noise", () => {
|
||||
|
||||
it("Noise State Machine: Cipher State primitives", function () {
|
||||
// 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);
|
||||
|
||||
// We get all the Symmetric State field
|
||||
@ -352,8 +354,8 @@ describe("js-noise", () => {
|
||||
expect(uint8ArrayEquals(cs1.getKey(), cs2.getKey())).to.be.false;
|
||||
});
|
||||
|
||||
it("Noise XX Handhshake and message encryption (extended test)", function () {
|
||||
const hsPattern = NoiseHandshakePatterns.XX;
|
||||
it("Noise XX Handshake and message encryption (extended test)", function () {
|
||||
const hsPattern = NoiseHandshakePatterns.Noise_XX_25519_ChaChaPoly_SHA256;
|
||||
|
||||
// We initialize Alice's and Bob's Handshake State
|
||||
const aliceStaticKey = generateX25519KeyPair();
|
||||
@ -464,7 +466,7 @@ describe("js-noise", () => {
|
||||
});
|
||||
|
||||
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
|
||||
const psk = randomBytes(32, rng);
|
||||
@ -559,7 +561,7 @@ describe("js-noise", () => {
|
||||
});
|
||||
|
||||
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
|
||||
const aliceStaticKey = generateX25519KeyPair();
|
||||
@ -661,7 +663,7 @@ describe("js-noise", () => {
|
||||
});
|
||||
|
||||
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
|
||||
const aliceStaticKey = generateX25519KeyPair();
|
||||
|
||||
@ -124,7 +124,7 @@ export class WakuPairing {
|
||||
const preMessagePKs = [NoisePublicKey.fromPublicKey(this.qr.ephemeralKey)];
|
||||
|
||||
this.handshake = new Handshake({
|
||||
hsPattern: NoiseHandshakePatterns.WakuPairing,
|
||||
hsPattern: NoiseHandshakePatterns.Noise_WakuPairing_25519_ChaChaPoly_SHA256,
|
||||
ephemeralKey: myEphemeralKey,
|
||||
staticKey: myStaticKey,
|
||||
prologue: this.qr.toByteArray(),
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { TAG_LENGTH as ChaChaPolyTagLen } from "@stablelib/chacha20poly1305";
|
||||
import { Hash } from "@stablelib/hash";
|
||||
import { SHA256 } from "@stablelib/sha256";
|
||||
|
||||
@ -74,6 +75,7 @@ export class HandshakePattern {
|
||||
constructor(
|
||||
public readonly name: string,
|
||||
public readonly hash: new () => Hash,
|
||||
public readonly tagLen: number,
|
||||
public readonly preMessagePatterns: Array<PreMessagePattern>,
|
||||
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
|
||||
*/
|
||||
export const NoiseHandshakePatterns = {
|
||||
K1K1: new HandshakePattern(
|
||||
export const NoiseHandshakePatterns: Record<string, HandshakePattern> = {
|
||||
Noise_K1K1_25519_ChaChaPoly_SHA256: new HandshakePattern(
|
||||
"Noise_K1K1_25519_ChaChaPoly_SHA256",
|
||||
SHA256,
|
||||
ChaChaPolyTagLen,
|
||||
[
|
||||
new PreMessagePattern(MessageDirection.r, [NoiseTokens.s]),
|
||||
new PreMessagePattern(MessageDirection.l, [NoiseTokens.s]),
|
||||
@ -115,9 +118,10 @@ export const NoiseHandshakePatterns = {
|
||||
new MessagePattern(MessageDirection.r, [NoiseTokens.se]),
|
||||
]
|
||||
),
|
||||
XK1: new HandshakePattern(
|
||||
Noise_XK1_25519_ChaChaPoly_SHA256: new HandshakePattern(
|
||||
"Noise_XK1_25519_ChaChaPoly_SHA256",
|
||||
SHA256,
|
||||
ChaChaPolyTagLen,
|
||||
[new PreMessagePattern(MessageDirection.l, [NoiseTokens.s])],
|
||||
[
|
||||
new MessagePattern(MessageDirection.r, [NoiseTokens.e]),
|
||||
@ -125,9 +129,10 @@ export const NoiseHandshakePatterns = {
|
||||
new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]),
|
||||
]
|
||||
),
|
||||
XX: new HandshakePattern(
|
||||
Noise_XX_25519_ChaChaPoly_SHA256: new HandshakePattern(
|
||||
"Noise_XX_25519_ChaChaPoly_SHA256",
|
||||
SHA256,
|
||||
ChaChaPolyTagLen,
|
||||
[],
|
||||
[
|
||||
new MessagePattern(MessageDirection.r, [NoiseTokens.e]),
|
||||
@ -135,9 +140,10 @@ export const NoiseHandshakePatterns = {
|
||||
new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]),
|
||||
]
|
||||
),
|
||||
XXpsk0: new HandshakePattern(
|
||||
Noise_XXpsk0_25519_ChaChaPoly_SHA256: new HandshakePattern(
|
||||
"Noise_XXpsk0_25519_ChaChaPoly_SHA256",
|
||||
SHA256,
|
||||
ChaChaPolyTagLen,
|
||||
[],
|
||||
[
|
||||
new MessagePattern(MessageDirection.r, [NoiseTokens.psk, NoiseTokens.e]),
|
||||
@ -145,9 +151,10 @@ export const NoiseHandshakePatterns = {
|
||||
new MessagePattern(MessageDirection.r, [NoiseTokens.s, NoiseTokens.se]),
|
||||
]
|
||||
),
|
||||
WakuPairing: new HandshakePattern(
|
||||
Noise_WakuPairing_25519_ChaChaPoly_SHA256: new HandshakePattern(
|
||||
"Noise_WakuPairing_25519_ChaChaPoly_SHA256",
|
||||
SHA256,
|
||||
ChaChaPolyTagLen,
|
||||
[new PreMessagePattern(MessageDirection.l, [NoiseTokens.e])],
|
||||
[
|
||||
new MessagePattern(MessageDirection.r, [NoiseTokens.e, NoiseTokens.ee]),
|
||||
|
||||
@ -2,9 +2,9 @@ import { concat as uint8ArrayConcat } from "uint8arrays/concat";
|
||||
import { equals as uint8ArrayEquals } from "uint8arrays/equals";
|
||||
|
||||
import { MessageNametag } from "./@types/handshake.js";
|
||||
import { ChachaPolyTagLen, Curve25519KeySize } from "./crypto.js";
|
||||
import { Curve25519KeySize } from "./crypto.js";
|
||||
import { MessageNametagLength } from "./messagenametag.js";
|
||||
import { PayloadV2ProtocolIDs } from "./patterns.js";
|
||||
import { NoiseHandshakePatterns, PayloadV2ProtocolIDs } from "./patterns.js";
|
||||
import { NoisePublicKey } from "./publickey.js";
|
||||
import { readUIntLE, writeUIntLE } from "./utils.js";
|
||||
|
||||
@ -15,22 +15,13 @@ import { readUIntLE, writeUIntLE } from "./utils.js";
|
||||
* and the transport message
|
||||
*/
|
||||
export class PayloadV2 {
|
||||
messageNametag: MessageNametag;
|
||||
protocolId: number;
|
||||
handshakeMessage: Array<NoisePublicKey>;
|
||||
transportMessage: Uint8Array;
|
||||
|
||||
constructor(
|
||||
messageNametag: MessageNametag = new Uint8Array(MessageNametagLength),
|
||||
protocolId = 0,
|
||||
handshakeMessage: Array<NoisePublicKey> = [],
|
||||
transportMessage: Uint8Array = new Uint8Array()
|
||||
) {
|
||||
this.messageNametag = messageNametag;
|
||||
this.protocolId = protocolId;
|
||||
this.handshakeMessage = handshakeMessage;
|
||||
this.transportMessage = transportMessage;
|
||||
}
|
||||
public messageNametag: MessageNametag = new Uint8Array(MessageNametagLength),
|
||||
public protocolId = 0,
|
||||
public tagLen = 0,
|
||||
public handshakeMessage: Array<NoisePublicKey> = [],
|
||||
public transportMessage: Uint8Array = new Uint8Array()
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Create a copy of the PayloadV2
|
||||
@ -41,6 +32,7 @@ export class PayloadV2 {
|
||||
r.protocolId = this.protocolId;
|
||||
r.transportMessage = new Uint8Array(this.transportMessage);
|
||||
r.messageNametag = new Uint8Array(this.messageNametag);
|
||||
r.tagLen = this.tagLen;
|
||||
for (let i = 0; i < this.handshakeMessage.length; i++) {
|
||||
r.handshakeMessage.push(this.handshakeMessage[i].clone());
|
||||
}
|
||||
@ -146,6 +138,9 @@ export class PayloadV2 {
|
||||
throw new Error("protocolId not found");
|
||||
}
|
||||
|
||||
const pattern = NoiseHandshakePatterns[protocolName];
|
||||
const tagLen = pattern ? pattern.tagLen : 0;
|
||||
|
||||
i++;
|
||||
|
||||
// We read the Handshake Message length (1 byte)
|
||||
@ -174,7 +169,7 @@ export class PayloadV2 {
|
||||
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 + ChachaPolyTagLen;
|
||||
const pkLen = 1 + Curve25519KeySize + tagLen;
|
||||
handshakeMessage.push(NoisePublicKey.deserialize(payload.subarray(i, i + pkLen)));
|
||||
i += pkLen;
|
||||
written += pkLen;
|
||||
@ -191,6 +186,6 @@ export class PayloadV2 {
|
||||
const transportMessage = payload.subarray(i, i + transportMessageLen);
|
||||
i += transportMessageLen;
|
||||
|
||||
return new PayloadV2(messageNametag, protocolId, handshakeMessage, transportMessage);
|
||||
return new PayloadV2(messageNametag, protocolId, tagLen, handshakeMessage, transportMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ describe("Waku Noise Sessions", () => {
|
||||
// Pairing Phase
|
||||
// ==========
|
||||
|
||||
const hsPattern = NoiseHandshakePatterns.WakuPairing;
|
||||
const hsPattern = NoiseHandshakePatterns.Noise_WakuPairing_25519_ChaChaPoly_SHA256;
|
||||
|
||||
// Alice static/ephemeral key initialization and commitment
|
||||
const aliceStaticKey = generateX25519KeyPair();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user