ts-mls
Version:
[](https://github.com/LukaJCB/ts-mls/actions/workflows/ci.yml) [](https://badge.fury.io/js/ts-mls) [ {
return hpke.seal(publicKey, plaintext, new Uint8Array([...encodeVarLenData(new TextEncoder().encode(`MLS 1.0 ${label}`)), ...encodeVarLenData(context)]), new Uint8Array());
}
export function decryptWithLabel(privateKey, label, context, kemOutput, ciphertext, hpke) {
return hpke.open(privateKey, kemOutput, ciphertext, new Uint8Array([...encodeVarLenData(new TextEncoder().encode(`MLS 1.0 ${label}`)), ...encodeVarLenData(context)]));
}
export async function makeHpke(hpkealg) {
const aead = await makeAead(hpkealg.aead);
const cs = new CipherSuite({
kem: await makeDhKem(hpkealg.kem),
kdf: makeKdf(hpkealg.kdf),
aead: aead.hpkeInterface(),
});
return {
async open(privateKey, kemOutput, ciphertext, info, aad) {
try {
const result = await cs.open({ recipientKey: privateKey, enc: bytesToBuffer(kemOutput), info: bytesToBuffer(info) }, bytesToBuffer(ciphertext), aad ? bytesToBuffer(aad) : new ArrayBuffer());
return new Uint8Array(result);
}
catch (e) {
throw new CryptoError(`${e}`);
}
},
async seal(publicKey, plaintext, info, aad) {
const result = await cs.seal({ recipientPublicKey: publicKey, info: bytesToBuffer(info) }, bytesToBuffer(plaintext), aad ? bytesToBuffer(aad) : new ArrayBuffer());
return {
ct: new Uint8Array(result.ct),
enc: new Uint8Array(result.enc),
};
},
async exportSecret(publicKey, exporterContext, length, info) {
const context = await cs.createSenderContext({ recipientPublicKey: publicKey, info: bytesToBuffer(info) });
return {
enc: new Uint8Array(context.enc),
secret: new Uint8Array(await context.export(bytesToBuffer(exporterContext), length)),
};
},
async importSecret(privateKey, exporterContext, kemOutput, length, info) {
try {
const context = await cs.createRecipientContext({
recipientKey: privateKey,
info: bytesToBuffer(info),
enc: bytesToBuffer(kemOutput),
});
return new Uint8Array(await context.export(bytesToBuffer(exporterContext), length));
}
catch (e) {
throw new CryptoError(`${e}`);
}
},
async importPrivateKey(k) {
try {
// See https://github.com/mlswg/mls-implementations/issues/176#issuecomment-1817043142
const key = hpkealg.kem === "DHKEM-P521-HKDF-SHA512" ? prepadPrivateKeyP521(k) : k;
return (await cs.kem.deserializePrivateKey(bytesToBuffer(key)));
}
catch (e) {
throw new CryptoError(`${e}`);
}
},
async importPublicKey(k) {
try {
return (await cs.kem.deserializePublicKey(bytesToBuffer(k)));
}
catch (e) {
throw new CryptoError(`${e}`);
}
},
async exportPublicKey(k) {
return new Uint8Array(await cs.kem.serializePublicKey(k));
},
async exportPrivateKey(k) {
return new Uint8Array(await cs.kem.serializePrivateKey(k));
},
async encryptAead(key, nonce, aad, plaintext) {
return aead.encrypt(key, nonce, aad ? aad : new Uint8Array(), plaintext);
},
async decryptAead(key, nonce, aad, ciphertext) {
try {
return await aead.decrypt(key, nonce, aad ? aad : new Uint8Array(), ciphertext);
}
catch (e) {
throw new CryptoError(`${e}`);
}
},
async deriveKeyPair(ikm) {
const kp = await cs.kem.deriveKeyPair(bytesToBuffer(ikm));
return { privateKey: kp.privateKey, publicKey: kp.publicKey };
},
async generateKeyPair() {
const kp = await cs.kem.generateKeyPair();
return { privateKey: kp.privateKey, publicKey: kp.publicKey };
},
keyLength: cs.aead.keySize,
nonceLength: cs.aead.nonceSize,
};
}
function prepadPrivateKeyP521(k) {
const lengthDifference = 66 - k.byteLength;
return new Uint8Array([...new Uint8Array(lengthDifference), ...k]);
}
//# sourceMappingURL=hpke.js.map