noble-xwing
Version:
Typescript implementation of the X-Wing hybrid Post Quantum KEM using the noble library, as outlined in https://eprint.iacr.org/2024/039.
74 lines • 2.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.xwingKem = void 0;
const ml_kem_1 = require("@noble/post-quantum/ml-kem");
const utils_1 = require("@noble/post-quantum/utils");
const sha3_1 = require("@noble/hashes/sha3");
const ed25519_1 = require("@noble/curves/ed25519");
exports.xwingKem = {
keygen: keygen,
encapsulate: encapsulate,
decapsulate: decapsulate,
encodeSS: encodeSharedSecret,
encodeCT: encodeCipherText,
encodePK: encodePublicKey,
encodeSK: encodePrivateKey,
};
function encodeSharedSecret(sharedSecret) {
return (0, sha3_1.sha3_256)(new Uint8Array([
...[0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c],
...sharedSecret.mlKemSharedSecret,
...sharedSecret.ecdhSharedSecret,
...sharedSecret.ecdhCipherText,
...sharedSecret.ecdhPublicKey,
]));
}
function encodePrivateKey(privateKey) {
return new Uint8Array([...privateKey.mlKemPrivateKey, ...privateKey.ecdhPrivateKey, ...privateKey.ecdhPublicKey]);
}
function encodePublicKey(publicKey) {
return new Uint8Array([...publicKey.mlKemPublicKey, ...publicKey.ecdhPublicKey]);
}
function encodeCipherText(cipherText) {
return new Uint8Array([...cipherText.mlKemCipherText, ...cipherText.ecdhCipherText]);
}
function encapsulate(publicKey) {
const { cipherText: ct_m, sharedSecret: ss_m } = ml_kem_1.ml_kem768.encapsulate(publicKey.mlKemPublicKey);
const ek_x = ed25519_1.x25519.utils.randomPrivateKey();
const ct_x = ed25519_1.x25519.getPublicKey(ek_x);
const ss_x = ed25519_1.x25519.getSharedSecret(ek_x, publicKey.ecdhPublicKey);
const ct = { mlKemCipherText: ct_m, ecdhCipherText: ct_x };
const ss = {
mlKemSharedSecret: ss_m,
ecdhSharedSecret: ss_x,
ecdhCipherText: ct_x,
ecdhPublicKey: publicKey.ecdhPublicKey,
};
return { ct, ss };
}
function decapsulate(cipherText, privateKey) {
const [sk_m, sk_x, pk_x] = [privateKey.mlKemPrivateKey, privateKey.ecdhPrivateKey, privateKey.ecdhPublicKey];
const ss_m = ml_kem_1.ml_kem768.decapsulate(cipherText.mlKemCipherText, sk_m);
const ss_x = ed25519_1.x25519.getSharedSecret(sk_x, cipherText.ecdhCipherText);
return {
mlKemSharedSecret: ss_m,
ecdhSharedSecret: ss_x,
ecdhCipherText: cipherText.ecdhCipherText,
ecdhPublicKey: pk_x,
};
}
function keygen() {
const seed = (0, utils_1.randomBytes)(96);
const mlKemKeyPair = ml_kem_1.ml_kem768.keygen(seed.slice(0, 64));
const ecdhPrivateKey = seed.slice(64, 96);
const ecdhPublicKey = ed25519_1.x25519.getPublicKey(ecdhPrivateKey);
return {
pk: { ecdhPublicKey, mlKemPublicKey: mlKemKeyPair.publicKey },
sk: {
ecdhPublicKey,
ecdhPrivateKey,
mlKemPrivateKey: mlKemKeyPair.secretKey,
},
};
}
//# sourceMappingURL=xwing.js.map