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

131 lines 6.26 kB
import { decodeUint64, encodeUint64 } from "./codec/number.js"; import { flatMapDecoder, mapDecoder, mapDecoders } from "./codec/tlsDecoder.js"; import { contramapEncoder, contramapEncoders } from "./codec/tlsEncoder.js"; import { decodeVarLenData, encodeVarLenData } from "./codec/variableLength.js"; import { decodeCommit, encodeCommit } from "./commit.js"; import { decodeContentType, encodeContentType } from "./contentType.js"; import { signWithLabel, verifyWithLabel } from "./crypto/signature.js"; import { encodeGroupContext } from "./groupContext.js"; import { encodeWireformat } from "./wireformat.js"; import { decodeProposal, encodeProposal } from "./proposal.js"; import { encodeProtocolVersion } from "./protocolVersion.js"; import { decodeSender, encodeSender, } from "./sender.js"; export const encodeFramedContentApplicationData = contramapEncoders([encodeContentType, encodeVarLenData], (f) => [f.contentType, f.applicationData]); export const encodeFramedContentProposalData = contramapEncoders([encodeContentType, encodeProposal], (f) => [f.contentType, f.proposal]); export const encodeFramedContentCommitData = contramapEncoders([encodeContentType, encodeCommit], (f) => [f.contentType, f.commit]); export const encodeFramedContentInfo = (fc) => { switch (fc.contentType) { case "application": return encodeFramedContentApplicationData(fc); case "proposal": return encodeFramedContentProposalData(fc); case "commit": return encodeFramedContentCommitData(fc); } }; export const decodeFramedContentApplicationData = mapDecoder(decodeVarLenData, (applicationData) => ({ contentType: "application", applicationData })); export const decodeFramedContentProposalData = mapDecoder(decodeProposal, (proposal) => ({ contentType: "proposal", proposal })); export const decodeFramedContentCommitData = mapDecoder(decodeCommit, (commit) => ({ contentType: "commit", commit, })); export const decodeFramedContentInfo = flatMapDecoder(decodeContentType, (contentType) => { switch (contentType) { case "application": return decodeFramedContentApplicationData; case "proposal": return decodeFramedContentProposalData; case "commit": return decodeFramedContentCommitData; } }); export function toTbs(content, wireformat, context) { return { protocolVersion: context.version, wireformat, content, senderType: content.sender.senderType, context }; } export const encodeFramedContent = contramapEncoders([encodeVarLenData, encodeUint64, encodeSender, encodeVarLenData, encodeFramedContentInfo], (fc) => [fc.groupId, fc.epoch, fc.sender, fc.authenticatedData, fc]); export const decodeFramedContent = mapDecoders([decodeVarLenData, decodeUint64, decodeSender, decodeVarLenData, decodeFramedContentInfo], (groupId, epoch, sender, authenticatedData, info) => ({ groupId, epoch, sender, authenticatedData, ...info, })); export const encodeSenderInfo = (info) => { switch (info.senderType) { case "member": case "new_member_commit": return encodeGroupContext(info.context); case "external": case "new_member_proposal": return new Uint8Array(); } }; export const encodeFramedContentTBS = contramapEncoders([encodeProtocolVersion, encodeWireformat, encodeFramedContent, encodeSenderInfo], (f) => [f.protocolVersion, f.wireformat, f.content, f]); const encodeFramedContentAuthDataContent = (authData) => { switch (authData.contentType) { case "commit": return encodeFramedContentAuthDataCommit(authData); case "application": case "proposal": return new Uint8Array(); } }; const encodeFramedContentAuthDataCommit = contramapEncoder(encodeVarLenData, (data) => data.confirmationTag); export const encodeFramedContentAuthData = contramapEncoders([encodeVarLenData, encodeFramedContentAuthDataContent], (d) => [d.signature, d]); export const decodeFramedContentAuthDataCommit = mapDecoder(decodeVarLenData, (confirmationTag) => ({ contentType: "commit", confirmationTag, })); export function decodeFramedContentAuthData(contentType) { switch (contentType) { case "commit": return mapDecoders([decodeVarLenData, decodeFramedContentAuthDataCommit], (signature, commitData) => ({ signature, ...commitData, })); case "application": case "proposal": return mapDecoder(decodeVarLenData, (signature) => ({ signature, contentType, })); } } export async function verifyFramedContentSignature(signKey, wireformat, content, auth, context, s) { return verifyWithLabel(signKey, "FramedContentTBS", encodeFramedContentTBS(toTbs(content, wireformat, context)), auth.signature, s); } export function signFramedContentTBS(signKey, tbs, s) { return signWithLabel(signKey, "FramedContentTBS", encodeFramedContentTBS(tbs), s); } export async function signFramedContentApplicationOrProposal(signKey, tbs, cs) { const signature = await signFramedContentTBS(signKey, tbs, cs.signature); return { contentType: tbs.content.contentType, signature, }; } export function createConfirmationTag(confirmationKey, confirmedTranscriptHash, h) { return h.mac(confirmationKey, confirmedTranscriptHash); } export function verifyConfirmationTag(confirmationKey, tag, confirmedTranscriptHash, h) { return h.verifyMac(confirmationKey, tag, confirmedTranscriptHash); } export async function createContentCommitSignature(groupContext, wireformat, c, sender, authenticatedData, signKey, s) { const tbs = { protocolVersion: groupContext.version, wireformat, content: { contentType: "commit", commit: c, groupId: groupContext.groupId, epoch: groupContext.epoch, sender, authenticatedData, }, senderType: "member", context: groupContext, }; const signature = await signFramedContentTBS(signKey, tbs, s); return { framedContent: tbs.content, signature }; } //# sourceMappingURL=framedContent.js.map