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

81 lines 3.7 kB
import { decodeUint32, decodeUint64, decodeUint8, encodeUint32, encodeUint64, encodeUint8 } from "./codec/number"; import { flatMapDecoder, mapDecoder, mapDecoderOption, mapDecoders } from "./codec/tlsDecoder"; import { contramapEncoder, contramapEncoders } from "./codec/tlsEncoder"; import { decodeVarLenData, encodeVarLenData } from "./codec/variableLength"; import { decodeContentType, encodeContentType } from "./contentType"; import { expandWithLabel } from "./crypto/kdf"; import { enumNumberToKey } from "./util/enumHelpers"; const senderTypes = { member: 1, external: 2, new_member_proposal: 3, new_member_commit: 4, }; export const encodeSenderType = contramapEncoder(encodeUint8, (t) => senderTypes[t]); export const decodeSenderType = mapDecoderOption(decodeUint8, enumNumberToKey(senderTypes)); export const encodeSender = (s) => { switch (s.senderType) { case "member": return contramapEncoders([encodeSenderType, encodeUint32], (s) => [s.senderType, s.leafIndex])(s); case "external": return contramapEncoders([encodeSenderType, encodeUint32], (s) => [s.senderType, s.senderIndex])(s); case "new_member_proposal": case "new_member_commit": return encodeSenderType(s.senderType); } }; export const decodeSender = flatMapDecoder(decodeSenderType, (senderType) => { switch (senderType) { case "member": return mapDecoder(decodeUint32, (leafIndex) => ({ senderType, leafIndex, })); case "external": return mapDecoder(decodeUint32, (senderIndex) => ({ senderType, senderIndex, })); case "new_member_proposal": return mapDecoder(() => [undefined, 0], () => ({ senderType, })); case "new_member_commit": return mapDecoder(() => [undefined, 0], () => ({ senderType, })); } }); export function getSenderLeafNodeIndex(sender) { return sender.senderType === "member" ? sender.leafIndex : undefined; } export const encodeReuseGuard = (g) => g; export const decodeReuseGuard = (b, offset) => { return [b.subarray(offset, offset + 4), 4]; }; export const encodeSenderData = contramapEncoders([encodeUint32, encodeUint32, encodeReuseGuard], (s) => [s.leafIndex, s.generation, s.reuseGuard]); export const decodeSenderData = mapDecoders([decodeUint32, decodeUint32, decodeReuseGuard], (leafIndex, generation, reuseGuard) => ({ leafIndex, generation, reuseGuard, })); export const encodeSenderDataAAD = contramapEncoders([encodeVarLenData, encodeUint64, encodeContentType], (aad) => [aad.groupId, aad.epoch, aad.contentType]); export const decodeSenderDataAAD = mapDecoders([decodeVarLenData, decodeUint64, decodeContentType], (groupId, epoch, contentType) => ({ groupId, epoch, contentType, })); export function sampleCiphertext(cs, ciphertext) { return ciphertext.length < cs.kdf.size ? ciphertext : ciphertext.slice(0, cs.kdf.size); } export async function expandSenderDataKey(cs, senderDataSecret, ciphertext) { const ciphertextSample = sampleCiphertext(cs, ciphertext); const keyLength = cs.hpke.keyLength; return await expandWithLabel(senderDataSecret, "key", ciphertextSample, keyLength, cs.kdf); } export async function expandSenderDataNonce(cs, senderDataSecret, ciphertext) { const ciphertextSample = sampleCiphertext(cs, ciphertext); const keyLength = cs.hpke.nonceLength; return await expandWithLabel(senderDataSecret, "nonce", ciphertextSample, keyLength, cs.kdf); } //# sourceMappingURL=sender.js.map