ts-mls
Version:
[](https://github.com/LukaJCB/ts-mls/actions/workflows/ci.yml) [](https://badge.fury.io/js/ts-mls) [) {
test(`passive-client-handling-commit test vectors ${index}`, async () => {
const impl = await getCiphersuiteImpl(getCiphersuiteFromId(x.cipher_suite));
await testPassiveClientScenario(x, impl);
});
}
for (const [index, x] of jsonRandom.entries()) {
test(`passive-client-random test vectors ${index}`, async () => {
const impl = await getCiphersuiteImpl(getCiphersuiteFromId(x.cipher_suite));
await testPassiveClientScenario(x, impl);
}, 40000);
}
for (const [index, x] of jsonWelcome.entries()) {
test(`passive-client-welcome test vectors ${index}`, async () => {
const impl = await getCiphersuiteImpl(getCiphersuiteFromId(x.cipher_suite));
await testPassiveClientScenario(x, impl);
});
}
async function testPassiveClientScenario(data, impl) {
const kp = decodeMlsMessage(hexToBytes(data.key_package), 0);
if (kp === undefined || kp[0].wireformat !== "mls_key_package")
throw new Error("Could not decode KeyPackage");
await verifyKeys(data, kp[0].keyPackage, impl);
const welcome = decodeMlsMessage(hexToBytes(data.welcome), 0);
if (welcome === undefined || welcome[0].wireformat !== "mls_welcome")
throw new Error("Could not decode Welcome");
const pks = {
hpkePrivateKey: hexToBytes(data.encryption_priv),
initPrivateKey: hexToBytes(data.init_priv),
signaturePrivateKey: hexToBytes(data.signature_priv),
};
const tree = data.ratchet_tree !== null ? decodeRatchetTree(hexToBytes(data.ratchet_tree), 0)?.[0] : undefined;
const psks = data.external_psks.reduce((acc, psk) => ({ ...acc, [bytesToBase64(hexToBytes(psk.psk_id))]: hexToBytes(psk.psk) }), {});
let state = await joinGroup(welcome[0].welcome, kp[0].keyPackage, pks, makePskIndex(undefined, psks), impl, tree);
expect(state.keySchedule.epochAuthenticator).toStrictEqual(hexToBytes(data.initial_epoch_authenticator));
for (const epoch of data.epochs) {
for (const proposal of epoch.proposals) {
const mlsProposal = decodeMlsMessage(hexToBytes(proposal), 0);
if (mlsProposal === undefined ||
(mlsProposal[0].wireformat !== "mls_private_message" && mlsProposal[0].wireformat !== "mls_public_message"))
throw new Error("Could not decode proposal message");
if (mlsProposal[0].wireformat === "mls_private_message") {
const res = await processPrivateMessage(state, mlsProposal[0].privateMessage, makePskIndex(state, psks), impl);
state = res.newState;
}
else {
const res = await processPublicMessage(state, mlsProposal[0].publicMessage, makePskIndex(state, psks), impl);
state = res.newState;
}
}
const mlsCommit = decodeMlsMessage(hexToBytes(epoch.commit), 0);
if (mlsCommit === undefined ||
(mlsCommit[0].wireformat !== "mls_private_message" && mlsCommit[0].wireformat !== "mls_public_message"))
throw new Error("Could not decode commit message");
if (mlsCommit[0].wireformat === "mls_private_message") {
const res = await processPrivateMessage(state, mlsCommit[0].privateMessage, makePskIndex(state, psks), impl);
state = res.newState;
}
else {
const res = await processPublicMessage(state, mlsCommit[0].publicMessage, makePskIndex(state, psks), impl);
state = res.newState;
}
expect(state.keySchedule.epochAuthenticator).toStrictEqual(hexToBytes(epoch.epoch_authenticator));
}
}
async function verifyKeys(data, kp, impl) {
const hpke = await hpkeKeysMatch(kp.leafNode.hpkePublicKey, hexToBytes(data.encryption_priv), impl.hpke);
expect(hpke).toBe(true);
const hpkeInit = await hpkeKeysMatch(kp.initKey, hexToBytes(data.init_priv), impl.hpke);
expect(hpkeInit).toBe(true);
const sig = await signatureKeysMatch(kp.leafNode.signaturePublicKey, hexToBytes(data.signature_priv), impl.signature);
expect(sig).toBe(true);
hexToBytes(data.init_priv);
}
//# sourceMappingURL=passiveClientScenarios.test.js.map