@sebastienrousseau/crypto-lib 0.0.3 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +304 -314
- package/dist/accel/index.d.ts +11 -0
- package/dist/accel/index.d.ts.map +1 -0
- package/dist/accel/index.js +31 -0
- package/dist/accel/native-pqc-bridge.d.ts +18 -0
- package/dist/accel/native-pqc-bridge.d.ts.map +1 -0
- package/dist/accel/native-pqc-bridge.js +100 -0
- package/dist/accel/wasm-bridge.d.ts +35 -0
- package/dist/accel/wasm-bridge.d.ts.map +1 -0
- package/dist/accel/wasm-bridge.js +161 -0
- package/dist/accel/webcrypto-bridge.d.ts +32 -0
- package/dist/accel/webcrypto-bridge.d.ts.map +1 -0
- package/dist/accel/webcrypto-bridge.js +179 -0
- package/dist/accel/webcrypto-modern.d.ts +40 -0
- package/dist/accel/webcrypto-modern.d.ts.map +1 -0
- package/dist/accel/webcrypto-modern.js +213 -0
- package/dist/accel/worker-pool.d.ts +23 -0
- package/dist/accel/worker-pool.d.ts.map +1 -0
- package/dist/accel/worker-pool.js +119 -0
- package/dist/bin/cryptolib.d.ts +9 -7
- package/dist/bin/cryptolib.d.ts.map +1 -1
- package/dist/bin/cryptolib.js +25 -16
- package/dist/config/config.d.ts.map +1 -1
- package/dist/crypto.d.ts +43 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +107 -0
- package/dist/enums.d.ts +29 -29
- package/dist/enums.d.ts.map +1 -1
- package/dist/enums.js +54 -54
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +22 -0
- package/dist/high-level/index.d.ts +11 -0
- package/dist/high-level/index.d.ts.map +1 -0
- package/dist/high-level/index.js +53 -0
- package/dist/high-level/key-wrap.d.ts +16 -0
- package/dist/high-level/key-wrap.d.ts.map +1 -0
- package/dist/high-level/key-wrap.js +93 -0
- package/dist/high-level/multi-recipient.d.ts +25 -0
- package/dist/high-level/multi-recipient.d.ts.map +1 -0
- package/dist/high-level/multi-recipient.js +122 -0
- package/dist/high-level/password-encrypt.d.ts +14 -0
- package/dist/high-level/password-encrypt.d.ts.map +1 -0
- package/dist/high-level/password-encrypt.js +93 -0
- package/dist/high-level/sealedbox.d.ts +13 -0
- package/dist/high-level/sealedbox.d.ts.map +1 -0
- package/dist/high-level/sealedbox.js +119 -0
- package/dist/high-level/secretbox.d.ts +7 -0
- package/dist/high-level/secretbox.d.ts.map +1 -0
- package/dist/high-level/secretbox.js +54 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -0
- package/dist/key/key.d.ts +6 -13
- package/dist/key/key.d.ts.map +1 -1
- package/dist/key/key.js +20 -14
- package/dist/key/keystore.d.ts +11 -0
- package/dist/key/keystore.d.ts.map +1 -0
- package/dist/key/keystore.js +87 -0
- package/dist/keys/index.d.ts +7 -0
- package/dist/keys/index.d.ts.map +1 -0
- package/dist/keys/index.js +22 -0
- package/dist/keys/keygen.d.ts +16 -0
- package/dist/keys/keygen.d.ts.map +1 -0
- package/dist/keys/keygen.js +128 -0
- package/dist/keys/keyring.d.ts +35 -0
- package/dist/keys/keyring.d.ts.map +1 -0
- package/dist/keys/keyring.js +136 -0
- package/dist/keys/serialize.d.ts +30 -0
- package/dist/keys/serialize.d.ts.map +1 -0
- package/dist/keys/serialize.js +120 -0
- package/dist/lib/decrypt.d.ts +4 -1
- package/dist/lib/decrypt.d.ts.map +1 -1
- package/dist/lib/decrypt.js +43 -51
- package/dist/lib/encrypt.d.ts +1 -1
- package/dist/lib/encrypt.d.ts.map +1 -1
- package/dist/lib/encrypt.js +29 -45
- package/dist/lib/generate.d.ts.map +1 -1
- package/dist/lib/generate.js +56 -63
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +17 -7
- package/dist/lib/key-output.d.ts +7 -0
- package/dist/lib/key-output.d.ts.map +1 -0
- package/dist/lib/key-output.js +50 -0
- package/dist/lib/reformat.d.ts +6 -1
- package/dist/lib/reformat.d.ts.map +1 -1
- package/dist/lib/reformat.js +37 -61
- package/dist/lib/revoke.d.ts +2 -2
- package/dist/lib/revoke.d.ts.map +1 -1
- package/dist/lib/revoke.js +33 -50
- package/dist/lib/session.d.ts.map +1 -1
- package/dist/lib/session.js +21 -36
- package/dist/lib/sign.d.ts.map +1 -1
- package/dist/lib/sign.js +36 -43
- package/dist/lib/verify.d.ts +1 -3
- package/dist/lib/verify.d.ts.map +1 -1
- package/dist/lib/verify.js +25 -30
- package/dist/modern/aead.d.ts +17 -0
- package/dist/modern/aead.d.ts.map +1 -0
- package/dist/modern/aead.js +51 -0
- package/dist/modern/aes.d.ts +35 -0
- package/dist/modern/aes.d.ts.map +1 -0
- package/dist/modern/aes.js +82 -0
- package/dist/modern/cost-limits.d.ts +11 -0
- package/dist/modern/cost-limits.d.ts.map +1 -0
- package/dist/modern/cost-limits.js +35 -0
- package/dist/modern/curves.d.ts +86 -0
- package/dist/modern/curves.d.ts.map +1 -0
- package/dist/modern/curves.js +171 -0
- package/dist/modern/ecdh.d.ts +11 -0
- package/dist/modern/ecdh.d.ts.map +1 -0
- package/dist/modern/ecdh.js +28 -0
- package/dist/modern/fn-dsa.d.ts +19 -0
- package/dist/modern/fn-dsa.d.ts.map +1 -0
- package/dist/modern/fn-dsa.js +57 -0
- package/dist/modern/hash.d.ts +13 -0
- package/dist/modern/hash.d.ts.map +1 -0
- package/dist/modern/hash.js +45 -0
- package/dist/modern/hpke.d.ts +47 -0
- package/dist/modern/hpke.d.ts.map +1 -0
- package/dist/modern/hpke.js +207 -0
- package/dist/modern/index.d.ts +40 -0
- package/dist/modern/index.d.ts.map +1 -0
- package/dist/modern/index.js +194 -0
- package/dist/modern/kdf.d.ts +23 -0
- package/dist/modern/kdf.d.ts.map +1 -0
- package/dist/modern/kdf.js +67 -0
- package/dist/modern/mac.d.ts +51 -0
- package/dist/modern/mac.d.ts.map +1 -0
- package/dist/modern/mac.js +119 -0
- package/dist/modern/password.d.ts +40 -0
- package/dist/modern/password.d.ts.map +1 -0
- package/dist/modern/password.js +123 -0
- package/dist/modern/pq-hash-sign.d.ts +18 -0
- package/dist/modern/pq-hash-sign.d.ts.map +1 -0
- package/dist/modern/pq-hash-sign.js +73 -0
- package/dist/modern/pq-kem.d.ts +88 -0
- package/dist/modern/pq-kem.d.ts.map +1 -0
- package/dist/modern/pq-kem.js +270 -0
- package/dist/modern/pq-sign.d.ts +30 -0
- package/dist/modern/pq-sign.d.ts.map +1 -0
- package/dist/modern/pq-sign.js +94 -0
- package/dist/modern/pq.d.ts +38 -0
- package/dist/modern/pq.d.ts.map +1 -0
- package/dist/modern/pq.js +80 -0
- package/dist/modern/signing.d.ts +16 -0
- package/dist/modern/signing.d.ts.map +1 -0
- package/dist/modern/signing.js +34 -0
- package/dist/protocols/index.d.ts +7 -0
- package/dist/protocols/index.d.ts.map +1 -0
- package/dist/protocols/index.js +46 -0
- package/dist/protocols/iso20022.d.ts +51 -0
- package/dist/protocols/iso20022.d.ts.map +1 -0
- package/dist/protocols/iso20022.js +145 -0
- package/dist/protocols/opaque/ake.d.ts +51 -0
- package/dist/protocols/opaque/ake.d.ts.map +1 -0
- package/dist/protocols/opaque/ake.js +102 -0
- package/dist/protocols/opaque/client.d.ts +45 -0
- package/dist/protocols/opaque/client.d.ts.map +1 -0
- package/dist/protocols/opaque/client.js +63 -0
- package/dist/protocols/opaque/config.d.ts +14 -0
- package/dist/protocols/opaque/config.d.ts.map +1 -0
- package/dist/protocols/opaque/config.js +18 -0
- package/dist/protocols/opaque/credentials.d.ts +29 -0
- package/dist/protocols/opaque/credentials.d.ts.map +1 -0
- package/dist/protocols/opaque/credentials.js +61 -0
- package/dist/protocols/opaque/envelope.d.ts +36 -0
- package/dist/protocols/opaque/envelope.d.ts.map +1 -0
- package/dist/protocols/opaque/envelope.js +77 -0
- package/dist/protocols/opaque/ksf.d.ts +15 -0
- package/dist/protocols/opaque/ksf.d.ts.map +1 -0
- package/dist/protocols/opaque/ksf.js +27 -0
- package/dist/protocols/opaque/messages.d.ts +61 -0
- package/dist/protocols/opaque/messages.d.ts.map +1 -0
- package/dist/protocols/opaque/messages.js +94 -0
- package/dist/protocols/opaque/server.d.ts +33 -0
- package/dist/protocols/opaque/server.d.ts.map +1 -0
- package/dist/protocols/opaque/server.js +74 -0
- package/dist/protocols/opaque/suite.d.ts +58 -0
- package/dist/protocols/opaque/suite.d.ts.map +1 -0
- package/dist/protocols/opaque/suite.js +115 -0
- package/dist/protocols/pake.d.ts +14 -0
- package/dist/protocols/pake.d.ts.map +1 -0
- package/dist/protocols/pake.js +33 -0
- package/dist/protocols/pqxdh.d.ts +53 -0
- package/dist/protocols/pqxdh.d.ts.map +1 -0
- package/dist/protocols/pqxdh.js +143 -0
- package/dist/protocols/ratchet.d.ts +52 -0
- package/dist/protocols/ratchet.d.ts.map +1 -0
- package/dist/protocols/ratchet.js +187 -0
- package/dist/protocols/threshold.d.ts +23 -0
- package/dist/protocols/threshold.d.ts.map +1 -0
- package/dist/protocols/threshold.js +191 -0
- package/dist/registry.d.ts +20 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +399 -0
- package/dist/streaming/index.d.ts +7 -0
- package/dist/streaming/index.d.ts.map +1 -0
- package/dist/streaming/index.js +15 -0
- package/dist/streaming/stream-aead.d.ts +17 -0
- package/dist/streaming/stream-aead.d.ts.map +1 -0
- package/dist/streaming/stream-aead.js +125 -0
- package/dist/streaming/stream-hash.d.ts +9 -0
- package/dist/streaming/stream-hash.d.ts.map +1 -0
- package/dist/streaming/stream-hash.js +52 -0
- package/dist/streaming/web-streams.d.ts +17 -0
- package/dist/streaming/web-streams.d.ts.map +1 -0
- package/dist/streaming/web-streams.js +114 -0
- package/dist/tokens/index.d.ts +5 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +15 -0
- package/dist/tokens/key-rotation.d.ts +20 -0
- package/dist/tokens/key-rotation.d.ts.map +1 -0
- package/dist/tokens/key-rotation.js +76 -0
- package/dist/tokens/paseto.d.ts +46 -0
- package/dist/tokens/paseto.d.ts.map +1 -0
- package/dist/tokens/paseto.js +200 -0
- package/dist/types/types.d.ts +24 -16
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils.d.ts +13 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +56 -0
- package/package.json +77 -142
- package/dist/COPYRIGHT +0 -15
- package/dist/Report.txt +0 -160
- package/dist/bin/cryptolib.js.map +0 -1
- package/dist/config/config.js.map +0 -1
- package/dist/data/decrypted.txt +0 -1
- package/dist/data/detached.sig +0 -1
- package/dist/data/encrypted.txt +0 -1
- package/dist/data/signed.sig +0 -1
- package/dist/enums.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/key/key.js.map +0 -1
- package/dist/key/rsa-reformat.cert +0 -1
- package/dist/key/rsa-reformat.key +0 -1
- package/dist/key/rsa-reformat.pub +0 -1
- package/dist/key/rsa-revoke.key +0 -1
- package/dist/key/rsa-revoke.pub +0 -1
- package/dist/key/rsa.cert +0 -1
- package/dist/key/rsa.key +0 -1
- package/dist/key/rsa.pub +0 -1
- package/dist/lib/decrypt.js.map +0 -1
- package/dist/lib/encrypt.js.map +0 -1
- package/dist/lib/generate.js.map +0 -1
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/reformat.js.map +0 -1
- package/dist/lib/revoke.js.map +0 -1
- package/dist/lib/session.js.map +0 -1
- package/dist/lib/sign.js.map +0 -1
- package/dist/lib/verify.js.map +0 -1
- package/dist/package.json +0 -143
- package/dist/types/types.js.map +0 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type SlhDsaVariant = "sha2-128f" | "sha2-128s" | "sha2-192f" | "sha2-192s" | "sha2-256f" | "sha2-256s" | "shake-128f" | "shake-128s" | "shake-192f" | "shake-192s" | "shake-256f" | "shake-256s";
|
|
2
|
+
export interface SlhDsaKeyPairResult {
|
|
3
|
+
publicKey: string;
|
|
4
|
+
secretKey: string;
|
|
5
|
+
algorithm: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SlhDsaSignResult {
|
|
8
|
+
signature: string;
|
|
9
|
+
algorithm: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SlhDsaVerifyResult {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
algorithm: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function slhDsaKeygen(variant: SlhDsaVariant): SlhDsaKeyPairResult;
|
|
16
|
+
export declare function slhDsaSign(variant: SlhDsaVariant, secretKeyHex: string, message: string | Uint8Array): SlhDsaSignResult;
|
|
17
|
+
export declare function slhDsaVerify(variant: SlhDsaVariant, publicKeyHex: string, message: string | Uint8Array, signatureHex: string): SlhDsaVerifyResult;
|
|
18
|
+
//# sourceMappingURL=pq-hash-sign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pq-hash-sign.d.ts","sourceRoot":"","sources":["../../src/modern/pq-hash-sign.ts"],"names":[],"mappings":"AAqCA,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAGjB,MAAM,WAAW,mBAAmB;IAElC,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,gBAAgB;IAE/B,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,kBAAkB;IAEjC,KAAK,EAAE,OAAO,CAAC;IAEf,SAAS,EAAE,MAAM,CAAC;CACnB;AA0DD,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,mBAAmB,CAQxE;AAKD,wBAAgB,UAAU,CACxB,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GAAG,UAAU,GAC3B,gBAAgB,CASlB;AAKD,wBAAgB,YAAY,CAC1B,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,YAAY,EAAE,MAAM,GACnB,kBAAkB,CAUpB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.slhDsaKeygen = slhDsaKeygen;
|
|
4
|
+
exports.slhDsaSign = slhDsaSign;
|
|
5
|
+
exports.slhDsaVerify = slhDsaVerify;
|
|
6
|
+
const slh_dsa_js_1 = require("@noble/post-quantum/slh-dsa.js");
|
|
7
|
+
const HEX_RE = /^[0-9a-fA-F]*$/;
|
|
8
|
+
function assertHex(input, label) {
|
|
9
|
+
if (!HEX_RE.test(input)) {
|
|
10
|
+
throw new Error(`Invalid hex string for ${label}`);
|
|
11
|
+
}
|
|
12
|
+
return Buffer.from(input, "hex");
|
|
13
|
+
}
|
|
14
|
+
function toBytes(input) {
|
|
15
|
+
if (input instanceof Uint8Array)
|
|
16
|
+
return input;
|
|
17
|
+
return Buffer.from(input, "utf8");
|
|
18
|
+
}
|
|
19
|
+
const SLH_DSA_VARIANTS = {
|
|
20
|
+
"sha2-128f": slh_dsa_js_1.slh_dsa_sha2_128f,
|
|
21
|
+
"sha2-128s": slh_dsa_js_1.slh_dsa_sha2_128s,
|
|
22
|
+
"sha2-192f": slh_dsa_js_1.slh_dsa_sha2_192f,
|
|
23
|
+
"sha2-192s": slh_dsa_js_1.slh_dsa_sha2_192s,
|
|
24
|
+
"sha2-256f": slh_dsa_js_1.slh_dsa_sha2_256f,
|
|
25
|
+
"sha2-256s": slh_dsa_js_1.slh_dsa_sha2_256s,
|
|
26
|
+
"shake-128f": slh_dsa_js_1.slh_dsa_shake_128f,
|
|
27
|
+
"shake-128s": slh_dsa_js_1.slh_dsa_shake_128s,
|
|
28
|
+
"shake-192f": slh_dsa_js_1.slh_dsa_shake_192f,
|
|
29
|
+
"shake-192s": slh_dsa_js_1.slh_dsa_shake_192s,
|
|
30
|
+
"shake-256f": slh_dsa_js_1.slh_dsa_shake_256f,
|
|
31
|
+
"shake-256s": slh_dsa_js_1.slh_dsa_shake_256s,
|
|
32
|
+
};
|
|
33
|
+
function getVariant(variant) {
|
|
34
|
+
const impl = SLH_DSA_VARIANTS[variant];
|
|
35
|
+
if (!impl) {
|
|
36
|
+
throw new Error(`Unsupported SLH-DSA variant: ${variant}. Supported: ${Object.keys(SLH_DSA_VARIANTS).join(", ")}`);
|
|
37
|
+
}
|
|
38
|
+
return impl;
|
|
39
|
+
}
|
|
40
|
+
function algorithmName(variant) {
|
|
41
|
+
return `slh-dsa-${variant}`;
|
|
42
|
+
}
|
|
43
|
+
function slhDsaKeygen(variant) {
|
|
44
|
+
const dsa = getVariant(variant);
|
|
45
|
+
const { publicKey, secretKey } = dsa.keygen();
|
|
46
|
+
return {
|
|
47
|
+
publicKey: Buffer.from(publicKey).toString("hex"),
|
|
48
|
+
secretKey: Buffer.from(secretKey).toString("hex"),
|
|
49
|
+
algorithm: algorithmName(variant),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function slhDsaSign(variant, secretKeyHex, message) {
|
|
53
|
+
const dsa = getVariant(variant);
|
|
54
|
+
const secretKey = assertHex(secretKeyHex, "secretKey");
|
|
55
|
+
const msg = toBytes(message);
|
|
56
|
+
const signature = dsa.sign(msg, secretKey);
|
|
57
|
+
return {
|
|
58
|
+
signature: Buffer.from(signature).toString("hex"),
|
|
59
|
+
algorithm: algorithmName(variant),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function slhDsaVerify(variant, publicKeyHex, message, signatureHex) {
|
|
63
|
+
const dsa = getVariant(variant);
|
|
64
|
+
const publicKey = assertHex(publicKeyHex, "publicKey");
|
|
65
|
+
const msg = toBytes(message);
|
|
66
|
+
const signature = assertHex(signatureHex, "signature");
|
|
67
|
+
const valid = dsa.verify(signature, msg, publicKey);
|
|
68
|
+
return {
|
|
69
|
+
valid,
|
|
70
|
+
algorithm: algorithmName(variant),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=pq-hash-sign.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export type MlKemLevel = 512 | 768 | 1024;
|
|
2
|
+
export type MlKemAlgorithm = "ml-kem-512" | "ml-kem-768" | "ml-kem-1024";
|
|
3
|
+
export declare const RFC10024_X25519_MLKEM768: "X25519MLKEM768";
|
|
4
|
+
export declare const RFC10024_SECP256R1_MLKEM768: "SecP256r1MLKEM768";
|
|
5
|
+
export declare const RFC10024_CODEPOINTS: {
|
|
6
|
+
readonly SecP256r1MLKEM768: 4587;
|
|
7
|
+
readonly X25519MLKEM768: 4588;
|
|
8
|
+
};
|
|
9
|
+
export type HybridKemAlgorithm = "x25519-ml-kem-512" | "x25519-ml-kem-768" | "x25519-ml-kem-1024" | "p256-ml-kem-768" | "x448-ml-kem-1024";
|
|
10
|
+
export declare function normalizeHybridKemAlgorithm(name: HybridKemAlgorithm | string): string;
|
|
11
|
+
export interface MlKemKeyPairResult {
|
|
12
|
+
publicKey: string;
|
|
13
|
+
secretKey: string;
|
|
14
|
+
algorithm: MlKemAlgorithm;
|
|
15
|
+
}
|
|
16
|
+
export interface MlKemEncapsulateResult {
|
|
17
|
+
ciphertext: string;
|
|
18
|
+
sharedSecret: string;
|
|
19
|
+
algorithm: MlKemAlgorithm;
|
|
20
|
+
}
|
|
21
|
+
export interface MlKemDecapsulateResult {
|
|
22
|
+
sharedSecret: string;
|
|
23
|
+
algorithm: MlKemAlgorithm;
|
|
24
|
+
}
|
|
25
|
+
export interface HybridKemKeyPair {
|
|
26
|
+
x25519PrivateKey: string;
|
|
27
|
+
x25519PublicKey: string;
|
|
28
|
+
mlKemPublicKey: string;
|
|
29
|
+
mlKemSecretKey: string;
|
|
30
|
+
algorithm: HybridKemAlgorithm;
|
|
31
|
+
}
|
|
32
|
+
export interface HybridKemEncapsulateResult {
|
|
33
|
+
x25519EphemeralPublic: string;
|
|
34
|
+
mlKemCiphertext: string;
|
|
35
|
+
sharedSecret: string;
|
|
36
|
+
algorithm: HybridKemAlgorithm;
|
|
37
|
+
}
|
|
38
|
+
export interface HybridKemDecapsulateResult {
|
|
39
|
+
sharedSecret: string;
|
|
40
|
+
algorithm: HybridKemAlgorithm;
|
|
41
|
+
}
|
|
42
|
+
export declare function mlKemKeygen(level: MlKemLevel): MlKemKeyPairResult;
|
|
43
|
+
export declare function mlKemEncapsulate(level: MlKemLevel, publicKeyHex: string): MlKemEncapsulateResult;
|
|
44
|
+
export declare function mlKemDecapsulate(level: MlKemLevel, secretKeyHex: string, ciphertextHex: string): MlKemDecapsulateResult;
|
|
45
|
+
export declare function hybridKemKeygen(kemLevel?: MlKemLevel): HybridKemKeyPair;
|
|
46
|
+
export declare function hybridKemEncapsulate(kemLevel: MlKemLevel, theirX25519Public: string, theirMlKemPublic: string): HybridKemEncapsulateResult;
|
|
47
|
+
export declare function hybridKemDecapsulate(kemLevel: MlKemLevel, ourX25519Private: string, ourMlKemSecret: string, theirX25519Ephemeral: string, mlKemCiphertext: string): HybridKemDecapsulateResult;
|
|
48
|
+
export interface P256MlKemKeyPair {
|
|
49
|
+
p256PrivateKey: string;
|
|
50
|
+
p256PublicKey: string;
|
|
51
|
+
mlKemPublicKey: string;
|
|
52
|
+
mlKemSecretKey: string;
|
|
53
|
+
algorithm: "p256-ml-kem-768";
|
|
54
|
+
}
|
|
55
|
+
export interface P256MlKemEncapsulateResult {
|
|
56
|
+
p256EphemeralPublic: string;
|
|
57
|
+
mlKemCiphertext: string;
|
|
58
|
+
sharedSecret: string;
|
|
59
|
+
algorithm: "p256-ml-kem-768";
|
|
60
|
+
}
|
|
61
|
+
export interface P256MlKemDecapsulateResult {
|
|
62
|
+
sharedSecret: string;
|
|
63
|
+
algorithm: "p256-ml-kem-768";
|
|
64
|
+
}
|
|
65
|
+
export declare function p256MlKemKeygen(): P256MlKemKeyPair;
|
|
66
|
+
export declare function p256MlKemEncapsulate(theirP256Public: string, theirMlKemPublic: string): P256MlKemEncapsulateResult;
|
|
67
|
+
export declare function p256MlKemDecapsulate(ourP256Private: string, ourMlKemSecret: string, theirP256Ephemeral: string, mlKemCiphertext: string): P256MlKemDecapsulateResult;
|
|
68
|
+
export interface X448MlKemKeyPair {
|
|
69
|
+
x448PrivateKey: string;
|
|
70
|
+
x448PublicKey: string;
|
|
71
|
+
mlKemPublicKey: string;
|
|
72
|
+
mlKemSecretKey: string;
|
|
73
|
+
algorithm: "x448-ml-kem-1024";
|
|
74
|
+
}
|
|
75
|
+
export interface X448MlKemEncapsulateResult {
|
|
76
|
+
x448EphemeralPublic: string;
|
|
77
|
+
mlKemCiphertext: string;
|
|
78
|
+
sharedSecret: string;
|
|
79
|
+
algorithm: "x448-ml-kem-1024";
|
|
80
|
+
}
|
|
81
|
+
export interface X448MlKemDecapsulateResult {
|
|
82
|
+
sharedSecret: string;
|
|
83
|
+
algorithm: "x448-ml-kem-1024";
|
|
84
|
+
}
|
|
85
|
+
export declare function x448MlKemKeygen(): X448MlKemKeyPair;
|
|
86
|
+
export declare function x448MlKemEncapsulate(theirX448Public: string, theirMlKemPublic: string): X448MlKemEncapsulateResult;
|
|
87
|
+
export declare function x448MlKemDecapsulate(ourX448Private: string, ourMlKemSecret: string, theirX448Ephemeral: string, mlKemCiphertext: string): X448MlKemDecapsulateResult;
|
|
88
|
+
//# sourceMappingURL=pq-kem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pq-kem.d.ts","sourceRoot":"","sources":["../../src/modern/pq-kem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RFC10024_CODEPOINTS = exports.RFC10024_SECP256R1_MLKEM768 = exports.RFC10024_X25519_MLKEM768 = void 0;
|
|
4
|
+
exports.normalizeHybridKemAlgorithm = normalizeHybridKemAlgorithm;
|
|
5
|
+
exports.mlKemKeygen = mlKemKeygen;
|
|
6
|
+
exports.mlKemEncapsulate = mlKemEncapsulate;
|
|
7
|
+
exports.mlKemDecapsulate = mlKemDecapsulate;
|
|
8
|
+
exports.hybridKemKeygen = hybridKemKeygen;
|
|
9
|
+
exports.hybridKemEncapsulate = hybridKemEncapsulate;
|
|
10
|
+
exports.hybridKemDecapsulate = hybridKemDecapsulate;
|
|
11
|
+
exports.p256MlKemKeygen = p256MlKemKeygen;
|
|
12
|
+
exports.p256MlKemEncapsulate = p256MlKemEncapsulate;
|
|
13
|
+
exports.p256MlKemDecapsulate = p256MlKemDecapsulate;
|
|
14
|
+
exports.x448MlKemKeygen = x448MlKemKeygen;
|
|
15
|
+
exports.x448MlKemEncapsulate = x448MlKemEncapsulate;
|
|
16
|
+
exports.x448MlKemDecapsulate = x448MlKemDecapsulate;
|
|
17
|
+
const ml_kem_js_1 = require("@noble/post-quantum/ml-kem.js");
|
|
18
|
+
const ed25519_js_1 = require("@noble/curves/ed25519.js");
|
|
19
|
+
const ed448_js_1 = require("@noble/curves/ed448.js");
|
|
20
|
+
const nist_js_1 = require("@noble/curves/nist.js");
|
|
21
|
+
const hkdf_js_1 = require("@noble/hashes/hkdf.js");
|
|
22
|
+
const sha2_js_1 = require("@noble/hashes/sha2.js");
|
|
23
|
+
const utils_js_1 = require("@noble/ciphers/utils.js");
|
|
24
|
+
exports.RFC10024_X25519_MLKEM768 = "X25519MLKEM768";
|
|
25
|
+
exports.RFC10024_SECP256R1_MLKEM768 = "SecP256r1MLKEM768";
|
|
26
|
+
exports.RFC10024_CODEPOINTS = {
|
|
27
|
+
[exports.RFC10024_SECP256R1_MLKEM768]: 0x11eb,
|
|
28
|
+
[exports.RFC10024_X25519_MLKEM768]: 0x11ec,
|
|
29
|
+
};
|
|
30
|
+
function normalizeHybridKemAlgorithm(name) {
|
|
31
|
+
if (name === exports.RFC10024_X25519_MLKEM768 ||
|
|
32
|
+
name === exports.RFC10024_SECP256R1_MLKEM768) {
|
|
33
|
+
throw new Error(`${name} (RFC 10024 TLS group) is not implemented by this library; ` +
|
|
34
|
+
"its hybrid KEMs use a different combiner and do not interoperate");
|
|
35
|
+
}
|
|
36
|
+
return name;
|
|
37
|
+
}
|
|
38
|
+
const HEX_RE = /^[0-9a-fA-F]*$/;
|
|
39
|
+
function assertHex(input, label) {
|
|
40
|
+
if (!HEX_RE.test(input)) {
|
|
41
|
+
throw new Error(`Invalid hex string for ${label}`);
|
|
42
|
+
}
|
|
43
|
+
return Buffer.from(input, "hex");
|
|
44
|
+
}
|
|
45
|
+
function getKem(level) {
|
|
46
|
+
switch (level) {
|
|
47
|
+
case 512:
|
|
48
|
+
return ml_kem_js_1.ml_kem512;
|
|
49
|
+
case 768:
|
|
50
|
+
return ml_kem_js_1.ml_kem768;
|
|
51
|
+
case 1024:
|
|
52
|
+
return ml_kem_js_1.ml_kem1024;
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`Unsupported ML-KEM level: ${level}. Supported: 512, 768, 1024`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function algorithmName(level) {
|
|
58
|
+
return `ml-kem-${level}`;
|
|
59
|
+
}
|
|
60
|
+
function lengthPrefixed(bytes) {
|
|
61
|
+
const out = new Uint8Array(4 + bytes.length);
|
|
62
|
+
new DataView(out.buffer).setUint32(0, bytes.length, false);
|
|
63
|
+
out.set(bytes, 4);
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
function combineHybrid(t) {
|
|
67
|
+
const ikm = Buffer.concat([t.ssClassical, t.ssMlKem]);
|
|
68
|
+
const info = Buffer.concat([
|
|
69
|
+
lengthPrefixed(Buffer.from(`crypto-service/hybrid-kem/v2/${t.algorithm}`)),
|
|
70
|
+
lengthPrefixed(t.ctClassical),
|
|
71
|
+
lengthPrefixed(t.pkClassical),
|
|
72
|
+
lengthPrefixed(t.ctMlKem),
|
|
73
|
+
lengthPrefixed(t.pkMlKem),
|
|
74
|
+
]);
|
|
75
|
+
return (0, hkdf_js_1.hkdf)(sha2_js_1.sha256, ikm, undefined, info, 32);
|
|
76
|
+
}
|
|
77
|
+
function toHex(bytes) {
|
|
78
|
+
return Buffer.from(bytes).toString("hex");
|
|
79
|
+
}
|
|
80
|
+
function hybridAlgorithmName(level) {
|
|
81
|
+
return `x25519-ml-kem-${level}`;
|
|
82
|
+
}
|
|
83
|
+
function mlKemKeygen(level) {
|
|
84
|
+
const kem = getKem(level);
|
|
85
|
+
const { publicKey, secretKey } = kem.keygen();
|
|
86
|
+
return {
|
|
87
|
+
publicKey: Buffer.from(publicKey).toString("hex"),
|
|
88
|
+
secretKey: Buffer.from(secretKey).toString("hex"),
|
|
89
|
+
algorithm: algorithmName(level),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function mlKemEncapsulate(level, publicKeyHex) {
|
|
93
|
+
const kem = getKem(level);
|
|
94
|
+
const publicKey = assertHex(publicKeyHex, "publicKey");
|
|
95
|
+
const { cipherText, sharedSecret } = kem.encapsulate(publicKey);
|
|
96
|
+
return {
|
|
97
|
+
ciphertext: Buffer.from(cipherText).toString("hex"),
|
|
98
|
+
sharedSecret: Buffer.from(sharedSecret).toString("hex"),
|
|
99
|
+
algorithm: algorithmName(level),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function mlKemDecapsulate(level, secretKeyHex, ciphertextHex) {
|
|
103
|
+
const kem = getKem(level);
|
|
104
|
+
const secretKey = assertHex(secretKeyHex, "secretKey");
|
|
105
|
+
const cipherText = assertHex(ciphertextHex, "ciphertext");
|
|
106
|
+
const sharedSecret = kem.decapsulate(cipherText, secretKey);
|
|
107
|
+
return {
|
|
108
|
+
sharedSecret: Buffer.from(sharedSecret).toString("hex"),
|
|
109
|
+
algorithm: algorithmName(level),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function hybridKemKeygen(kemLevel = 768) {
|
|
113
|
+
const kem = getKem(kemLevel);
|
|
114
|
+
const x25519Priv = (0, utils_js_1.randomBytes)(32);
|
|
115
|
+
const x25519Pub = ed25519_js_1.x25519.getPublicKey(x25519Priv);
|
|
116
|
+
const { publicKey: mlKemPub, secretKey: mlKemSec } = kem.keygen();
|
|
117
|
+
return {
|
|
118
|
+
x25519PrivateKey: Buffer.from(x25519Priv).toString("hex"),
|
|
119
|
+
x25519PublicKey: Buffer.from(x25519Pub).toString("hex"),
|
|
120
|
+
mlKemPublicKey: Buffer.from(mlKemPub).toString("hex"),
|
|
121
|
+
mlKemSecretKey: Buffer.from(mlKemSec).toString("hex"),
|
|
122
|
+
algorithm: hybridAlgorithmName(kemLevel),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function hybridKemEncapsulate(kemLevel, theirX25519Public, theirMlKemPublic) {
|
|
126
|
+
const kem = getKem(kemLevel);
|
|
127
|
+
const pkClassical = assertHex(theirX25519Public, "theirX25519Public");
|
|
128
|
+
const pkMlKem = assertHex(theirMlKemPublic, "theirMlKemPublic");
|
|
129
|
+
const ephemeralPriv = (0, utils_js_1.randomBytes)(32);
|
|
130
|
+
const ephemeralPub = ed25519_js_1.x25519.getPublicKey(ephemeralPriv);
|
|
131
|
+
const ssClassical = ed25519_js_1.x25519.getSharedSecret(ephemeralPriv, pkClassical);
|
|
132
|
+
const { cipherText, sharedSecret: ssMlKem } = kem.encapsulate(pkMlKem);
|
|
133
|
+
const algorithm = hybridAlgorithmName(kemLevel);
|
|
134
|
+
const derived = combineHybrid({
|
|
135
|
+
algorithm,
|
|
136
|
+
ssClassical,
|
|
137
|
+
ssMlKem,
|
|
138
|
+
ctClassical: ephemeralPub,
|
|
139
|
+
pkClassical,
|
|
140
|
+
ctMlKem: cipherText,
|
|
141
|
+
pkMlKem,
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
x25519EphemeralPublic: toHex(ephemeralPub),
|
|
145
|
+
mlKemCiphertext: toHex(cipherText),
|
|
146
|
+
sharedSecret: toHex(derived),
|
|
147
|
+
algorithm,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function hybridKemDecapsulate(kemLevel, ourX25519Private, ourMlKemSecret, theirX25519Ephemeral, mlKemCiphertext) {
|
|
151
|
+
const kem = getKem(kemLevel);
|
|
152
|
+
const priv = assertHex(ourX25519Private, "ourX25519Private");
|
|
153
|
+
const ctClassical = assertHex(theirX25519Ephemeral, "theirX25519Ephemeral");
|
|
154
|
+
const ctMlKem = assertHex(mlKemCiphertext, "mlKemCiphertext");
|
|
155
|
+
const mlKemSecret = assertHex(ourMlKemSecret, "ourMlKemSecret");
|
|
156
|
+
const algorithm = hybridAlgorithmName(kemLevel);
|
|
157
|
+
const derived = combineHybrid({
|
|
158
|
+
algorithm,
|
|
159
|
+
ssClassical: ed25519_js_1.x25519.getSharedSecret(priv, ctClassical),
|
|
160
|
+
ssMlKem: kem.decapsulate(ctMlKem, mlKemSecret),
|
|
161
|
+
ctClassical,
|
|
162
|
+
pkClassical: ed25519_js_1.x25519.getPublicKey(priv),
|
|
163
|
+
ctMlKem,
|
|
164
|
+
pkMlKem: kem.getPublicKey(mlKemSecret),
|
|
165
|
+
});
|
|
166
|
+
return { sharedSecret: toHex(derived), algorithm };
|
|
167
|
+
}
|
|
168
|
+
function p256MlKemKeygen() {
|
|
169
|
+
const p256Priv = nist_js_1.p256.utils.randomSecretKey();
|
|
170
|
+
const p256Pub = nist_js_1.p256.getPublicKey(p256Priv, false);
|
|
171
|
+
const { publicKey: mlKemPub, secretKey: mlKemSec } = ml_kem_js_1.ml_kem768.keygen();
|
|
172
|
+
return {
|
|
173
|
+
p256PrivateKey: Buffer.from(p256Priv).toString("hex"),
|
|
174
|
+
p256PublicKey: Buffer.from(p256Pub).toString("hex"),
|
|
175
|
+
mlKemPublicKey: Buffer.from(mlKemPub).toString("hex"),
|
|
176
|
+
mlKemSecretKey: Buffer.from(mlKemSec).toString("hex"),
|
|
177
|
+
algorithm: "p256-ml-kem-768",
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function p256MlKemEncapsulate(theirP256Public, theirMlKemPublic) {
|
|
181
|
+
const pkClassical = nist_js_1.p256.Point.fromBytes(assertHex(theirP256Public, "theirP256Public")).toBytes(false);
|
|
182
|
+
const pkMlKem = assertHex(theirMlKemPublic, "theirMlKemPublic");
|
|
183
|
+
const ephemeralPriv = nist_js_1.p256.utils.randomSecretKey();
|
|
184
|
+
const ephemeralPub = nist_js_1.p256.getPublicKey(ephemeralPriv, false);
|
|
185
|
+
const ssClassical = nist_js_1.p256.getSharedSecret(ephemeralPriv, pkClassical);
|
|
186
|
+
const { cipherText, sharedSecret: ssMlKem } = ml_kem_js_1.ml_kem768.encapsulate(pkMlKem);
|
|
187
|
+
const derived = combineHybrid({
|
|
188
|
+
algorithm: "p256-ml-kem-768",
|
|
189
|
+
ssClassical,
|
|
190
|
+
ssMlKem,
|
|
191
|
+
ctClassical: ephemeralPub,
|
|
192
|
+
pkClassical,
|
|
193
|
+
ctMlKem: cipherText,
|
|
194
|
+
pkMlKem,
|
|
195
|
+
});
|
|
196
|
+
return {
|
|
197
|
+
p256EphemeralPublic: toHex(ephemeralPub),
|
|
198
|
+
mlKemCiphertext: toHex(cipherText),
|
|
199
|
+
sharedSecret: toHex(derived),
|
|
200
|
+
algorithm: "p256-ml-kem-768",
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function p256MlKemDecapsulate(ourP256Private, ourMlKemSecret, theirP256Ephemeral, mlKemCiphertext) {
|
|
204
|
+
const priv = assertHex(ourP256Private, "ourP256Private");
|
|
205
|
+
const ctClassical = assertHex(theirP256Ephemeral, "theirP256Ephemeral");
|
|
206
|
+
const ctMlKem = assertHex(mlKemCiphertext, "mlKemCiphertext");
|
|
207
|
+
const mlKemSecret = assertHex(ourMlKemSecret, "ourMlKemSecret");
|
|
208
|
+
const derived = combineHybrid({
|
|
209
|
+
algorithm: "p256-ml-kem-768",
|
|
210
|
+
ssClassical: nist_js_1.p256.getSharedSecret(priv, ctClassical),
|
|
211
|
+
ssMlKem: ml_kem_js_1.ml_kem768.decapsulate(ctMlKem, mlKemSecret),
|
|
212
|
+
ctClassical,
|
|
213
|
+
pkClassical: nist_js_1.p256.getPublicKey(priv, false),
|
|
214
|
+
ctMlKem,
|
|
215
|
+
pkMlKem: ml_kem_js_1.ml_kem768.getPublicKey(mlKemSecret),
|
|
216
|
+
});
|
|
217
|
+
return { sharedSecret: toHex(derived), algorithm: "p256-ml-kem-768" };
|
|
218
|
+
}
|
|
219
|
+
function x448MlKemKeygen() {
|
|
220
|
+
const x448Priv = ed448_js_1.x448.utils.randomSecretKey();
|
|
221
|
+
const x448Pub = ed448_js_1.x448.getPublicKey(x448Priv);
|
|
222
|
+
const { publicKey: mlKemPub, secretKey: mlKemSec } = ml_kem_js_1.ml_kem1024.keygen();
|
|
223
|
+
return {
|
|
224
|
+
x448PrivateKey: Buffer.from(x448Priv).toString("hex"),
|
|
225
|
+
x448PublicKey: Buffer.from(x448Pub).toString("hex"),
|
|
226
|
+
mlKemPublicKey: Buffer.from(mlKemPub).toString("hex"),
|
|
227
|
+
mlKemSecretKey: Buffer.from(mlKemSec).toString("hex"),
|
|
228
|
+
algorithm: "x448-ml-kem-1024",
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function x448MlKemEncapsulate(theirX448Public, theirMlKemPublic) {
|
|
232
|
+
const pkClassical = assertHex(theirX448Public, "theirX448Public");
|
|
233
|
+
const pkMlKem = assertHex(theirMlKemPublic, "theirMlKemPublic");
|
|
234
|
+
const ephemeralPriv = ed448_js_1.x448.utils.randomSecretKey();
|
|
235
|
+
const ephemeralPub = ed448_js_1.x448.getPublicKey(ephemeralPriv);
|
|
236
|
+
const ssClassical = ed448_js_1.x448.getSharedSecret(ephemeralPriv, pkClassical);
|
|
237
|
+
const { cipherText, sharedSecret: ssMlKem } = ml_kem_js_1.ml_kem1024.encapsulate(pkMlKem);
|
|
238
|
+
const derived = combineHybrid({
|
|
239
|
+
algorithm: "x448-ml-kem-1024",
|
|
240
|
+
ssClassical,
|
|
241
|
+
ssMlKem,
|
|
242
|
+
ctClassical: ephemeralPub,
|
|
243
|
+
pkClassical,
|
|
244
|
+
ctMlKem: cipherText,
|
|
245
|
+
pkMlKem,
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
x448EphemeralPublic: toHex(ephemeralPub),
|
|
249
|
+
mlKemCiphertext: toHex(cipherText),
|
|
250
|
+
sharedSecret: toHex(derived),
|
|
251
|
+
algorithm: "x448-ml-kem-1024",
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function x448MlKemDecapsulate(ourX448Private, ourMlKemSecret, theirX448Ephemeral, mlKemCiphertext) {
|
|
255
|
+
const priv = assertHex(ourX448Private, "ourX448Private");
|
|
256
|
+
const ctClassical = assertHex(theirX448Ephemeral, "theirX448Ephemeral");
|
|
257
|
+
const ctMlKem = assertHex(mlKemCiphertext, "mlKemCiphertext");
|
|
258
|
+
const mlKemSecret = assertHex(ourMlKemSecret, "ourMlKemSecret");
|
|
259
|
+
const derived = combineHybrid({
|
|
260
|
+
algorithm: "x448-ml-kem-1024",
|
|
261
|
+
ssClassical: ed448_js_1.x448.getSharedSecret(priv, ctClassical),
|
|
262
|
+
ssMlKem: ml_kem_js_1.ml_kem1024.decapsulate(ctMlKem, mlKemSecret),
|
|
263
|
+
ctClassical,
|
|
264
|
+
pkClassical: ed448_js_1.x448.getPublicKey(priv),
|
|
265
|
+
ctMlKem,
|
|
266
|
+
pkMlKem: ml_kem_js_1.ml_kem1024.getPublicKey(mlKemSecret),
|
|
267
|
+
});
|
|
268
|
+
return { sharedSecret: toHex(derived), algorithm: "x448-ml-kem-1024" };
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=pq-kem.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type MlDsaLevel = 44 | 65 | 87;
|
|
2
|
+
export type MlDsaAlgorithm = "ml-dsa-44" | "ml-dsa-65" | "ml-dsa-87";
|
|
3
|
+
export interface MlDsaKeyPairResult {
|
|
4
|
+
publicKey: string;
|
|
5
|
+
secretKey: string;
|
|
6
|
+
algorithm: MlDsaAlgorithm;
|
|
7
|
+
}
|
|
8
|
+
export interface MlDsaSignResult {
|
|
9
|
+
signature: string;
|
|
10
|
+
algorithm: MlDsaAlgorithm;
|
|
11
|
+
}
|
|
12
|
+
export interface MlDsaVerifyResult {
|
|
13
|
+
valid: boolean;
|
|
14
|
+
algorithm: MlDsaAlgorithm;
|
|
15
|
+
}
|
|
16
|
+
export interface HybridSignResult {
|
|
17
|
+
ed25519Signature: string;
|
|
18
|
+
mlDsaSignature: string;
|
|
19
|
+
algorithm: string;
|
|
20
|
+
}
|
|
21
|
+
export interface HybridVerifyResult {
|
|
22
|
+
valid: boolean;
|
|
23
|
+
algorithm: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function mlDsaKeygen(level: MlDsaLevel): MlDsaKeyPairResult;
|
|
26
|
+
export declare function mlDsaSign(level: MlDsaLevel, secretKeyHex: string, message: string | Uint8Array): MlDsaSignResult;
|
|
27
|
+
export declare function mlDsaVerify(level: MlDsaLevel, publicKeyHex: string, message: string | Uint8Array, signatureHex: string): MlDsaVerifyResult;
|
|
28
|
+
export declare function hybridSign(secretKeyEd25519Hex: string, secretKeyMlDsaHex: string, message: string | Uint8Array, mlDsaLevel?: MlDsaLevel): HybridSignResult;
|
|
29
|
+
export declare function hybridVerify(pubKeyEd25519Hex: string, pubKeyMlDsaHex: string, message: string | Uint8Array, sigEd25519Hex: string, sigMlDsaHex: string, mlDsaLevel?: MlDsaLevel): HybridVerifyResult;
|
|
30
|
+
//# sourceMappingURL=pq-sign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pq-sign.d.ts","sourceRoot":"","sources":["../../src/modern/pq-sign.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAGtC,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAGrE,MAAM,WAAW,kBAAkB;IAEjC,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAGD,MAAM,WAAW,eAAe;IAE9B,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAGD,MAAM,WAAW,iBAAiB;IAEhC,KAAK,EAAE,OAAO,CAAC;IAEf,SAAS,EAAE,cAAc,CAAC;CAC3B;AAGD,MAAM,WAAW,gBAAgB;IAE/B,gBAAgB,EAAE,MAAM,CAAC;IAEzB,cAAc,EAAE,MAAM,CAAC;IAEvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,kBAAkB;IAEjC,KAAK,EAAE,OAAO,CAAC;IAEf,SAAS,EAAE,MAAM,CAAC;CACnB;AA+CD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAQjE;AAKD,wBAAgB,SAAS,CACvB,KAAK,EAAE,UAAU,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GAAG,UAAU,GAC3B,eAAe,CASjB;AAKD,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,YAAY,EAAE,MAAM,GACnB,iBAAiB,CAUnB;AAYD,wBAAgB,UAAU,CACxB,mBAAmB,EAAE,MAAM,EAC3B,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,UAAU,GAAE,UAAe,GAC1B,gBAAgB,CAclB;AAaD,wBAAgB,YAAY,CAC1B,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,UAAU,GAAE,UAAe,GAC1B,kBAAkB,CAepB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mlDsaKeygen = mlDsaKeygen;
|
|
4
|
+
exports.mlDsaSign = mlDsaSign;
|
|
5
|
+
exports.mlDsaVerify = mlDsaVerify;
|
|
6
|
+
exports.hybridSign = hybridSign;
|
|
7
|
+
exports.hybridVerify = hybridVerify;
|
|
8
|
+
const ml_dsa_js_1 = require("@noble/post-quantum/ml-dsa.js");
|
|
9
|
+
const ed25519_js_1 = require("@noble/curves/ed25519.js");
|
|
10
|
+
const HEX_RE = /^[0-9a-fA-F]*$/;
|
|
11
|
+
function assertHex(input, label) {
|
|
12
|
+
if (!HEX_RE.test(input)) {
|
|
13
|
+
throw new Error(`Invalid hex string for ${label}`);
|
|
14
|
+
}
|
|
15
|
+
return Buffer.from(input, "hex");
|
|
16
|
+
}
|
|
17
|
+
function toBytes(input) {
|
|
18
|
+
if (input instanceof Uint8Array)
|
|
19
|
+
return input;
|
|
20
|
+
return Buffer.from(input, "utf8");
|
|
21
|
+
}
|
|
22
|
+
function getDsa(level) {
|
|
23
|
+
switch (level) {
|
|
24
|
+
case 44:
|
|
25
|
+
return ml_dsa_js_1.ml_dsa44;
|
|
26
|
+
case 65:
|
|
27
|
+
return ml_dsa_js_1.ml_dsa65;
|
|
28
|
+
case 87:
|
|
29
|
+
return ml_dsa_js_1.ml_dsa87;
|
|
30
|
+
default:
|
|
31
|
+
throw new Error(`Unsupported ML-DSA level: ${level}. Supported: 44, 65, 87`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function algorithmName(level) {
|
|
35
|
+
return `ml-dsa-${level}`;
|
|
36
|
+
}
|
|
37
|
+
function mlDsaKeygen(level) {
|
|
38
|
+
const dsa = getDsa(level);
|
|
39
|
+
const { publicKey, secretKey } = dsa.keygen();
|
|
40
|
+
return {
|
|
41
|
+
publicKey: Buffer.from(publicKey).toString("hex"),
|
|
42
|
+
secretKey: Buffer.from(secretKey).toString("hex"),
|
|
43
|
+
algorithm: algorithmName(level),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function mlDsaSign(level, secretKeyHex, message) {
|
|
47
|
+
const dsa = getDsa(level);
|
|
48
|
+
const secretKey = assertHex(secretKeyHex, "secretKey");
|
|
49
|
+
const msg = toBytes(message);
|
|
50
|
+
const signature = dsa.sign(msg, secretKey);
|
|
51
|
+
return {
|
|
52
|
+
signature: Buffer.from(signature).toString("hex"),
|
|
53
|
+
algorithm: algorithmName(level),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function mlDsaVerify(level, publicKeyHex, message, signatureHex) {
|
|
57
|
+
const dsa = getDsa(level);
|
|
58
|
+
const publicKey = assertHex(publicKeyHex, "publicKey");
|
|
59
|
+
const msg = toBytes(message);
|
|
60
|
+
const signature = assertHex(signatureHex, "signature");
|
|
61
|
+
const valid = dsa.verify(signature, msg, publicKey);
|
|
62
|
+
return {
|
|
63
|
+
valid,
|
|
64
|
+
algorithm: algorithmName(level),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function hybridSign(secretKeyEd25519Hex, secretKeyMlDsaHex, message, mlDsaLevel = 65) {
|
|
68
|
+
const dsa = getDsa(mlDsaLevel);
|
|
69
|
+
const ed25519Key = assertHex(secretKeyEd25519Hex, "secretKeyEd25519");
|
|
70
|
+
const mlDsaKey = assertHex(secretKeyMlDsaHex, "secretKeyMlDsa");
|
|
71
|
+
const msg = toBytes(message);
|
|
72
|
+
const ed25519Sig = ed25519_js_1.ed25519.sign(msg, ed25519Key);
|
|
73
|
+
const mlDsaSig = dsa.sign(msg, mlDsaKey);
|
|
74
|
+
return {
|
|
75
|
+
ed25519Signature: Buffer.from(ed25519Sig).toString("hex"),
|
|
76
|
+
mlDsaSignature: Buffer.from(mlDsaSig).toString("hex"),
|
|
77
|
+
algorithm: `ed25519-ml-dsa-${mlDsaLevel}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function hybridVerify(pubKeyEd25519Hex, pubKeyMlDsaHex, message, sigEd25519Hex, sigMlDsaHex, mlDsaLevel = 65) {
|
|
81
|
+
const dsa = getDsa(mlDsaLevel);
|
|
82
|
+
const ed25519Pub = assertHex(pubKeyEd25519Hex, "pubKeyEd25519");
|
|
83
|
+
const mlDsaPub = assertHex(pubKeyMlDsaHex, "pubKeyMlDsa");
|
|
84
|
+
const msg = toBytes(message);
|
|
85
|
+
const ed25519Sig = assertHex(sigEd25519Hex, "sigEd25519");
|
|
86
|
+
const mlDsaSig = assertHex(sigMlDsaHex, "sigMlDsa");
|
|
87
|
+
const ed25519Valid = ed25519_js_1.ed25519.verify(ed25519Sig, msg, ed25519Pub);
|
|
88
|
+
const mlDsaValid = dsa.verify(mlDsaSig, msg, mlDsaPub);
|
|
89
|
+
return {
|
|
90
|
+
valid: ed25519Valid && mlDsaValid,
|
|
91
|
+
algorithm: `ed25519-ml-dsa-${mlDsaLevel}`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=pq-sign.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface MlKemKeyPair {
|
|
2
|
+
publicKey: string;
|
|
3
|
+
secretKey: string;
|
|
4
|
+
algorithm: "ml-kem-768";
|
|
5
|
+
}
|
|
6
|
+
export interface MlKemEncapsulateResult {
|
|
7
|
+
ciphertext: string;
|
|
8
|
+
sharedSecret: string;
|
|
9
|
+
algorithm: "ml-kem-768";
|
|
10
|
+
}
|
|
11
|
+
export interface MlKemDecapsulateResult {
|
|
12
|
+
sharedSecret: string;
|
|
13
|
+
algorithm: "ml-kem-768";
|
|
14
|
+
}
|
|
15
|
+
export declare function mlKemGenerateKeyPair(): MlKemKeyPair;
|
|
16
|
+
export declare function mlKemEncapsulate(publicKeyHex: string): MlKemEncapsulateResult;
|
|
17
|
+
export declare function mlKemDecapsulate(secretKeyHex: string, ciphertextHex: string): MlKemDecapsulateResult;
|
|
18
|
+
export interface HybridKeyPair {
|
|
19
|
+
x25519PrivateKey: string;
|
|
20
|
+
x25519PublicKey: string;
|
|
21
|
+
mlKemPublicKey: string;
|
|
22
|
+
mlKemSecretKey: string;
|
|
23
|
+
algorithm: "x25519-ml-kem-768";
|
|
24
|
+
}
|
|
25
|
+
export interface HybridEncapsulateResult {
|
|
26
|
+
x25519EphemeralPublic: string;
|
|
27
|
+
mlKemCiphertext: string;
|
|
28
|
+
sharedSecret: string;
|
|
29
|
+
algorithm: "x25519-ml-kem-768";
|
|
30
|
+
}
|
|
31
|
+
export interface HybridDecapsulateResult {
|
|
32
|
+
sharedSecret: string;
|
|
33
|
+
algorithm: "x25519-ml-kem-768";
|
|
34
|
+
}
|
|
35
|
+
export declare function hybridGenerateKeyPair(): HybridKeyPair;
|
|
36
|
+
export declare function hybridEncapsulate(theirX25519Public: string, theirMlKemPublic: string): HybridEncapsulateResult;
|
|
37
|
+
export declare function hybridDecapsulate(ourX25519Private: string, ourMlKemSecret: string, theirX25519Ephemeral: string, mlKemCiphertext: string): HybridDecapsulateResult;
|
|
38
|
+
//# sourceMappingURL=pq.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pq.d.ts","sourceRoot":"","sources":["../../src/modern/pq.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,YAAY;IAE3B,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,YAAY,CAAC;CACzB;AAGD,MAAM,WAAW,sBAAsB;IAErC,UAAU,EAAE,MAAM,CAAC;IAEnB,YAAY,EAAE,MAAM,CAAC;IAErB,SAAS,EAAE,YAAY,CAAC;CACzB;AAGD,MAAM,WAAW,sBAAsB;IAErC,YAAY,EAAE,MAAM,CAAC;IAErB,SAAS,EAAE,YAAY,CAAC;CACzB;AAKD,wBAAgB,oBAAoB,IAAI,YAAY,CAOnD;AAKD,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,sBAAsB,CAQ7E;AAKD,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,sBAAsB,CAQxB;AAKD,MAAM,WAAW,aAAa;IAE5B,gBAAgB,EAAE,MAAM,CAAC;IAEzB,eAAe,EAAE,MAAM,CAAC;IAExB,cAAc,EAAE,MAAM,CAAC;IAEvB,cAAc,EAAE,MAAM,CAAC;IAEvB,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAGD,MAAM,WAAW,uBAAuB;IAEtC,qBAAqB,EAAE,MAAM,CAAC;IAE9B,eAAe,EAAE,MAAM,CAAC;IAExB,YAAY,EAAE,MAAM,CAAC;IAErB,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAGD,MAAM,WAAW,uBAAuB;IAEtC,YAAY,EAAE,MAAM,CAAC;IAErB,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAKD,wBAAgB,qBAAqB,IAAI,aAAa,CAYrD;AASD,wBAAgB,iBAAiB,CAC/B,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,EAAE,MAAM,GACvB,uBAAuB,CAiCzB;AAWD,wBAAgB,iBAAiB,CAC/B,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,oBAAoB,EAAE,MAAM,EAC5B,eAAe,EAAE,MAAM,GACtB,uBAAuB,CA8BzB"}
|