UNPKG

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.

43 lines 2.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateKeyPair = generateKeyPair; exports.encapsulate = encapsulate; exports.decapsulate = decapsulate; 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"); function expandDecapsulationKey(seed) { const expanded = (0, sha3_1.shake256)(seed, { dkLen: 96 }); const { publicKey: pkM, secretKey: skM } = ml_kem_1.ml_kem768.keygen(expanded.subarray(0, 64)); const skX = expanded.subarray(64, 96); const pkX = ed25519_1.x25519.getPublicKey(skX); return [skM, skX, pkM, pkX]; } function generateKeyPair(seed = (0, utils_1.randomBytes)(32)) { const [, , pkM, pkX] = expandDecapsulationKey(seed); return { sk: seed, pk: new Uint8Array([...pkM, ...pkX]) }; } const xWingLabel = [0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c]; function combiner(ssM, ssX, ctX, pkX) { return (0, sha3_1.sha3_256)(new Uint8Array([...ssM, ...ssX, ...ctX, ...pkX, ...xWingLabel])); } function encapsulate(publicKey, eseed = (0, utils_1.randomBytes)(64)) { const pkM = publicKey.subarray(0, 1184); const pkX = publicKey.subarray(1184, 1216); const ekX = eseed.subarray(32, 64); const ctX = ed25519_1.x25519.getPublicKey(ekX); const ssX = ed25519_1.x25519.getSharedSecret(ekX, pkX); const { cipherText: ctM, sharedSecret: ssM } = ml_kem_1.ml_kem768.encapsulate(pkM, eseed.subarray(0, 32)); const ss = combiner(ssM, ssX, ctX, pkX); return { ss, ct: new Uint8Array([...ctM, ...ctX]) }; } function decapsulate(cipherText, secretKey) { const [skM, skX, , pkX] = expandDecapsulationKey(secretKey); const ctM = cipherText.subarray(0, 1088); const ctX = cipherText.subarray(1088, 1120); const ssM = ml_kem_1.ml_kem768.decapsulate(ctM, skM); const ssX = ed25519_1.x25519.getSharedSecret(skX, ctX); return combiner(ssM, ssX, ctX, pkX); } //# sourceMappingURL=xwingSparse.js.map