UNPKG

ts-mls

Version:

[![CI](https://github.com/LukaJCB/ts-mls/actions/workflows/ci.yml/badge.svg)](https://github.com/LukaJCB/ts-mls/actions/workflows/ci.yml) [![npm version](https://badge.fury.io/js/ts-mls.svg)](https://badge.fury.io/js/ts-mls) [![Coverage Status](https://co

94 lines 3.82 kB
import { makePskIndex, createGroup, joinGroup } from "./clientState.js"; import { createCommit } from "./createCommit.js"; import { getCiphersuiteFromName } from "./crypto/ciphersuite.js"; import { getCiphersuiteImpl } from "./crypto/getCiphersuiteImpl.js"; import { defaultCryptoProvider } from "./crypto/implementation/default/provider.js"; import { UsageError } from "./mlsError.js"; export async function reinitGroup(state, groupId, version, cipherSuite, extensions, cs) { const reinitProposal = { proposalType: "reinit", reinit: { groupId, version, cipherSuite, extensions, }, }; return createCommit({ state, pskIndex: makePskIndex(state, {}), cipherSuite: cs, }, { extraProposals: [reinitProposal], }); } export async function reinitCreateNewGroup(state, keyPackage, privateKeyPackage, memberKeyPackages, groupId, cipherSuite, extensions, provider = defaultCryptoProvider) { const cs = await getCiphersuiteImpl(getCiphersuiteFromName(cipherSuite), provider); const newGroup = await createGroup(groupId, keyPackage, privateKeyPackage, extensions, cs); const addProposals = memberKeyPackages.map((kp) => ({ proposalType: "add", add: { keyPackage: kp }, })); const psk = makeResumptionPsk(state, "reinit", cs); const resumptionPsk = { proposalType: "psk", psk: { preSharedKeyId: psk.id, }, }; return createCommit({ state: newGroup, pskIndex: makePskIndex(state, {}), cipherSuite: cs, }, { extraProposals: [...addProposals, resumptionPsk], }); } export function makeResumptionPsk(state, usage, cs) { const secret = state.keySchedule.resumptionPsk; const pskNonce = cs.rng.randomBytes(cs.kdf.size); const psk = { pskEpoch: state.groupContext.epoch, pskGroupId: state.groupContext.groupId, psktype: "resumption", pskNonce, usage, }; return { id: psk, secret }; } export async function branchGroup(state, keyPackage, privateKeyPackage, memberKeyPackages, newGroupId, cs) { const resumptionPsk = makeResumptionPsk(state, "branch", cs); const pskSearch = makePskIndex(state, {}); const newGroup = await createGroup(newGroupId, keyPackage, privateKeyPackage, state.groupContext.extensions, cs); const addMemberProposals = memberKeyPackages.map((kp) => ({ proposalType: "add", add: { keyPackage: kp, }, })); const branchPskProposal = { proposalType: "psk", psk: { preSharedKeyId: resumptionPsk.id, }, }; return createCommit({ state: newGroup, pskIndex: pskSearch, cipherSuite: cs, }, { extraProposals: [...addMemberProposals, branchPskProposal], }); } export async function joinGroupFromBranch(oldState, welcome, keyPackage, privateKeyPackage, ratchetTree, cs) { const pskSearch = makePskIndex(oldState, {}); return await joinGroup(welcome, keyPackage, privateKeyPackage, pskSearch, cs, ratchetTree, oldState); } export async function joinGroupFromReinit(suspendedState, welcome, keyPackage, privateKeyPackage, ratchetTree, provider = defaultCryptoProvider) { const pskSearch = makePskIndex(suspendedState, {}); if (suspendedState.groupActiveState.kind !== "suspendedPendingReinit") throw new UsageError("Cannot reinit because no init proposal found in last commit"); const cs = await getCiphersuiteImpl(getCiphersuiteFromName(suspendedState.groupActiveState.reinit.cipherSuite), provider); return await joinGroup(welcome, keyPackage, privateKeyPackage, pskSearch, cs, ratchetTree, suspendedState); } //# sourceMappingURL=resumption.js.map