@gjsify/crypto 0.3.12 → 0.3.14
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/lib/esm/asn1.js +576 -450
- package/lib/esm/bigint-math.js +37 -28
- package/lib/esm/cipher.js +1252 -1229
- package/lib/esm/constants.js +12 -13
- package/lib/esm/crypto-utils.js +54 -36
- package/lib/esm/dh.js +408 -368
- package/lib/esm/ecdh.js +403 -321
- package/lib/esm/ecdsa.js +138 -111
- package/lib/esm/hash.js +100 -89
- package/lib/esm/hkdf.js +65 -47
- package/lib/esm/hmac.js +95 -90
- package/lib/esm/index.js +75 -148
- package/lib/esm/key-object.js +348 -307
- package/lib/esm/mgf1.js +30 -24
- package/lib/esm/pbkdf2.js +66 -59
- package/lib/esm/public-encrypt.js +203 -156
- package/lib/esm/random.js +137 -124
- package/lib/esm/rsa-oaep.js +94 -87
- package/lib/esm/rsa-pss.js +95 -88
- package/lib/esm/scrypt.js +116 -115
- package/lib/esm/sign.js +267 -237
- package/lib/esm/timing-safe-equal.js +16 -11
- package/lib/esm/x509.js +215 -206
- package/package.json +7 -7
package/lib/esm/dh.js
CHANGED
|
@@ -1,411 +1,451 @@
|
|
|
1
|
-
import { Buffer } from "node:buffer";
|
|
2
|
-
import { randomBytes } from "./random.js";
|
|
3
1
|
import { modPow } from "./bigint-math.js";
|
|
2
|
+
import { randomBytes } from "./random.js";
|
|
3
|
+
import { Buffer } from "node:buffer";
|
|
4
|
+
|
|
5
|
+
//#region src/dh.ts
|
|
4
6
|
const PREDEFINED_GROUPS = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
gen: "02",
|
|
38
|
-
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"
|
|
39
|
-
},
|
|
40
|
-
// RFC 3526 Section 7 — 8192-bit MODP Group
|
|
41
|
-
modp18: {
|
|
42
|
-
gen: "02",
|
|
43
|
-
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"
|
|
44
|
-
}
|
|
7
|
+
modp1: {
|
|
8
|
+
gen: "02",
|
|
9
|
+
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1" + "29024e088a67cc74020bbea63b139b22514a08798e3404dd" + "ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245" + "e485b576625e7ec6f44c42e9a63a36" + "20ffffffffffffffff"
|
|
10
|
+
},
|
|
11
|
+
modp2: {
|
|
12
|
+
gen: "02",
|
|
13
|
+
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1" + "29024e088a67cc74020bbea63b139b22514a08798e3404dd" + "ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245" + "e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed" + "ee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381" + "ffffffffffffffff"
|
|
14
|
+
},
|
|
15
|
+
modp5: {
|
|
16
|
+
gen: "02",
|
|
17
|
+
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1" + "29024e088a67cc74020bbea63b139b22514a08798e3404dd" + "ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245" + "e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed" + "ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3d" + "c2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f" + "83655d23dca3ad961c62f356208552bb9ed529077096966d" + "670c354e4abc9804f1746c08ca237327" + "ffffffffffffffff"
|
|
18
|
+
},
|
|
19
|
+
modp14: {
|
|
20
|
+
gen: "02",
|
|
21
|
+
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1" + "29024e088a67cc74020bbea63b139b22514a08798e3404dd" + "ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245" + "e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed" + "ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3d" + "c2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f" + "83655d23dca3ad961c62f356208552bb9ed529077096966d" + "670c354e4abc9804f1746c08ca18217c32905e462e36ce3b" + "e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9" + "de2bcbf6955817183995497cea956ae515d2261898fa05101" + "5728e5a8aacaa68ffffffffffffffff"
|
|
22
|
+
},
|
|
23
|
+
modp15: {
|
|
24
|
+
gen: "02",
|
|
25
|
+
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1" + "29024e088a67cc74020bbea63b139b22514a08798e3404dd" + "ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245" + "e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed" + "ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3d" + "c2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f" + "83655d23dca3ad961c62f356208552bb9ed529077096966d" + "670c354e4abc9804f1746c08ca18217c32905e462e36ce3b" + "e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9" + "de2bcbf6955817183995497cea956ae515d2261898fa05101" + "5728e5a8aaac42dad33170d04507a33a85521abdf1cba64e" + "cfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7a" + "bf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf" + "12ffa06d98a0864d87602733ec86a64521f2b18177b200cb" + "be117577a615d6c770988c0bad946e208e24fa074e5ab314" + "3db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"
|
|
26
|
+
},
|
|
27
|
+
modp16: {
|
|
28
|
+
gen: "02",
|
|
29
|
+
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1" + "29024e088a67cc74020bbea63b139b22514a08798e3404dd" + "ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245" + "e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed" + "ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3d" + "c2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f" + "83655d23dca3ad961c62f356208552bb9ed529077096966d" + "670c354e4abc9804f1746c08ca18217c32905e462e36ce3b" + "e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9" + "de2bcbf6955817183995497cea956ae515d2261898fa05101" + "5728e5a8aaac42dad33170d04507a33a85521abdf1cba64e" + "cfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7a" + "bf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf" + "12ffa06d98a0864d87602733ec86a64521f2b18177b200cb" + "be117577a615d6c770988c0bad946e208e24fa074e5ab314" + "3db5bfce0fd108e4b82d120a92108011a723c12a787e6d78" + "8719a10bdba5b2699c327186af4e23c1a946834b6150bda2" + "583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa62" + "87c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1" + "f612970cee2d7afb81bdd762170481cd0069127d5b05aa99" + "3b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199" + "ffffffffffffffff"
|
|
30
|
+
},
|
|
31
|
+
modp17: {
|
|
32
|
+
gen: "02",
|
|
33
|
+
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1" + "29024e088a67cc74020bbea63b139b22514a08798e3404dd" + "ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245" + "e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed" + "ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3d" + "c2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f" + "83655d23dca3ad961c62f356208552bb9ed529077096966d" + "670c354e4abc9804f1746c08ca18217c32905e462e36ce3b" + "e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9" + "de2bcbf6955817183995497cea956ae515d2261898fa05101" + "5728e5a8aaac42dad33170d04507a33a85521abdf1cba64e" + "cfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7a" + "bf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf" + "12ffa06d98a0864d87602733ec86a64521f2b18177b200cb" + "be117577a615d6c770988c0bad946e208e24fa074e5ab314" + "3db5bfce0fd108e4b82d120a92108011a723c12a787e6d78" + "8719a10bdba5b2699c327186af4e23c1a946834b6150bda2" + "583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa62" + "87c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1" + "f612970cee2d7afb81bdd762170481cd0069127d5b05aa99" + "3b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"
|
|
34
|
+
},
|
|
35
|
+
modp18: {
|
|
36
|
+
gen: "02",
|
|
37
|
+
prime: "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd1" + "29024e088a67cc74020bbea63b139b22514a08798e3404dd" + "ef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245" + "e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7ed" + "ee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3d" + "c2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f" + "83655d23dca3ad961c62f356208552bb9ed529077096966d" + "670c354e4abc9804f1746c08ca18217c32905e462e36ce3b" + "e39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9" + "de2bcbf6955817183995497cea956ae515d2261898fa05101" + "5728e5a8aaac42dad33170d04507a33a85521abdf1cba64e" + "cfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7a" + "bf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf" + "12ffa06d98a0864d87602733ec86a64521f2b18177b200cb" + "be117577a615d6c770988c0bad946e208e24fa074e5ab314" + "3db5bfce0fd108e4b82d120a92108011a723c12a787e6d78" + "8719a10bdba5b2699c327186af4e23c1a946834b6150bda2" + "583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa62" + "87c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1" + "f612970cee2d7afb81bdd762170481cd0069127d5b05aa99" + "3b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"
|
|
38
|
+
}
|
|
45
39
|
};
|
|
40
|
+
/** Convert a hex string to BigInt. */
|
|
46
41
|
function hexToBigInt(hex) {
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
if (hex.length === 0) return 0n;
|
|
43
|
+
return BigInt("0x" + hex);
|
|
49
44
|
}
|
|
45
|
+
/** Convert a BigInt to a Buffer (big-endian, unsigned). */
|
|
50
46
|
function bigIntToBuffer(n) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
47
|
+
if (n === 0n) return Buffer.from([0]);
|
|
48
|
+
let hex = n.toString(16);
|
|
49
|
+
if (hex.length % 2 !== 0) {
|
|
50
|
+
hex = "0" + hex;
|
|
51
|
+
}
|
|
52
|
+
return Buffer.from(hex, "hex");
|
|
57
53
|
}
|
|
54
|
+
/** Convert a Buffer (big-endian, unsigned) to BigInt. */
|
|
58
55
|
function bufferToBigInt(buf) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
if (buf.length === 0) return 0n;
|
|
57
|
+
const hex = Buffer.from(buf).toString("hex");
|
|
58
|
+
if (hex.length === 0) return 0n;
|
|
59
|
+
return BigInt("0x" + hex);
|
|
63
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Count the bit length of a BigInt.
|
|
63
|
+
*/
|
|
64
64
|
function bitLength(n) {
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
if (n === 0n) return 0;
|
|
66
|
+
return n.toString(2).length;
|
|
67
67
|
}
|
|
68
68
|
const SMALL_PRIMES = [];
|
|
69
69
|
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
70
|
+
const limit = 1e3;
|
|
71
|
+
const sieve = new Uint8Array(limit + 1);
|
|
72
|
+
for (let i = 2; i * i <= limit; i++) {
|
|
73
|
+
if (!sieve[i]) {
|
|
74
|
+
for (let j = i * i; j <= limit; j += i) {
|
|
75
|
+
sieve[j] = 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (let i = 2; i <= limit; i++) {
|
|
80
|
+
if (!sieve[i]) SMALL_PRIMES.push(i);
|
|
81
|
+
}
|
|
82
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Simple sieve: check if n is divisible by any small prime.
|
|
85
|
+
* Returns true if n passes the sieve (might be prime), false if composite.
|
|
86
|
+
*/
|
|
83
87
|
function simpleSieve(n) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
for (const p of SMALL_PRIMES) {
|
|
89
|
+
const bp = BigInt(p);
|
|
90
|
+
if (n % bp === 0n) {
|
|
91
|
+
return n === bp;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
91
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Fermat primality test: 2^(n-1) mod n === 1
|
|
98
|
+
*/
|
|
92
99
|
function fermatTest(n) {
|
|
93
|
-
|
|
100
|
+
return modPow(2n, n - 1n, n) === 1n;
|
|
94
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Miller-Rabin primality test with a few fixed witnesses.
|
|
104
|
+
* Returns true if n is probably prime, false if definitely composite.
|
|
105
|
+
*/
|
|
95
106
|
function millerRabinTest(n) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
107
|
+
if (n < 2n) return false;
|
|
108
|
+
if (n === 2n || n === 3n) return true;
|
|
109
|
+
if (n % 2n === 0n) return false;
|
|
110
|
+
let d = n - 1n;
|
|
111
|
+
let r = 0;
|
|
112
|
+
while (d % 2n === 0n) {
|
|
113
|
+
d /= 2n;
|
|
114
|
+
r++;
|
|
115
|
+
}
|
|
116
|
+
const witnesses = [
|
|
117
|
+
2n,
|
|
118
|
+
3n,
|
|
119
|
+
5n,
|
|
120
|
+
7n,
|
|
121
|
+
11n,
|
|
122
|
+
13n
|
|
123
|
+
];
|
|
124
|
+
for (const a of witnesses) {
|
|
125
|
+
if (a >= n) continue;
|
|
126
|
+
let x = modPow(a, d, n);
|
|
127
|
+
if (x === 1n || x === n - 1n) continue;
|
|
128
|
+
let composite = true;
|
|
129
|
+
for (let i = 0; i < r - 1; i++) {
|
|
130
|
+
x = modPow(x, 2n, n);
|
|
131
|
+
if (x === n - 1n) {
|
|
132
|
+
composite = false;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (composite) return false;
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
121
139
|
}
|
|
122
140
|
const DH_CHECK_P_NOT_PRIME = 1;
|
|
123
141
|
const DH_CHECK_P_NOT_SAFE_PRIME = 2;
|
|
124
142
|
const DH_NOT_SUITABLE_GENERATOR = 8;
|
|
125
143
|
const DH_UNABLE_TO_CHECK_GENERATOR = 4;
|
|
144
|
+
/**
|
|
145
|
+
* Check the prime and generator for errors, matching OpenSSL/Node.js behavior.
|
|
146
|
+
* Returns a bitmask of DH_CHECK_* flags.
|
|
147
|
+
*/
|
|
126
148
|
function checkPrime(prime, generatorBuf) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return error;
|
|
149
|
+
const genHex = generatorBuf.toString("hex");
|
|
150
|
+
let error = 0;
|
|
151
|
+
if (prime % 2n === 0n || !simpleSieve(prime) || !fermatTest(prime) || !millerRabinTest(prime)) {
|
|
152
|
+
error += DH_CHECK_P_NOT_PRIME;
|
|
153
|
+
if (genHex === "02" || genHex === "05") {
|
|
154
|
+
error += DH_NOT_SUITABLE_GENERATOR;
|
|
155
|
+
} else {
|
|
156
|
+
error += DH_UNABLE_TO_CHECK_GENERATOR;
|
|
157
|
+
}
|
|
158
|
+
return error;
|
|
159
|
+
}
|
|
160
|
+
const halfPrime = prime >> 1n;
|
|
161
|
+
if (!millerRabinTest(halfPrime)) {
|
|
162
|
+
error += DH_CHECK_P_NOT_SAFE_PRIME;
|
|
163
|
+
}
|
|
164
|
+
switch (genHex) {
|
|
165
|
+
case "02":
|
|
166
|
+
if (prime % 24n !== 11n) {
|
|
167
|
+
error += DH_NOT_SUITABLE_GENERATOR;
|
|
168
|
+
}
|
|
169
|
+
break;
|
|
170
|
+
case "05":
|
|
171
|
+
{
|
|
172
|
+
const rem = prime % 10n;
|
|
173
|
+
if (rem !== 3n && rem !== 7n) {
|
|
174
|
+
error += DH_NOT_SUITABLE_GENERATOR;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
default: error += DH_UNABLE_TO_CHECK_GENERATOR;
|
|
179
|
+
}
|
|
180
|
+
return error;
|
|
160
181
|
}
|
|
161
182
|
const primeCheckCache = {};
|
|
162
183
|
function getCachedCheckPrime(prime, generatorBuf) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
184
|
+
const key = generatorBuf.toString("hex") + "_" + prime.toString(16);
|
|
185
|
+
if (key in primeCheckCache) {
|
|
186
|
+
return primeCheckCache[key];
|
|
187
|
+
}
|
|
188
|
+
const result = checkPrime(prime, generatorBuf);
|
|
189
|
+
primeCheckCache[key] = result;
|
|
190
|
+
return result;
|
|
170
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Parse an input value to a Buffer, handling encoding parameters.
|
|
194
|
+
*/
|
|
171
195
|
function toBuffer(value, encoding) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
196
|
+
if (Buffer.isBuffer(value)) return value;
|
|
197
|
+
if (value instanceof Uint8Array) return Buffer.from(value);
|
|
198
|
+
if (value instanceof ArrayBuffer) return Buffer.from(value);
|
|
199
|
+
if (typeof value === "string") return Buffer.from(value, encoding || "utf8");
|
|
200
|
+
if (typeof value === "number") {
|
|
201
|
+
const buf = Buffer.alloc(1);
|
|
202
|
+
buf[0] = value;
|
|
203
|
+
return buf;
|
|
204
|
+
}
|
|
205
|
+
throw new TypeError("Invalid input type");
|
|
182
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Format a BigInt return value as Buffer or encoded string.
|
|
209
|
+
*/
|
|
183
210
|
function formatReturnValue(n, encoding) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
class DiffieHellman {
|
|
191
|
-
_prime;
|
|
192
|
-
_generator;
|
|
193
|
-
_generatorBuf;
|
|
194
|
-
_primeByteLength;
|
|
195
|
-
_pubKey;
|
|
196
|
-
_privKey;
|
|
197
|
-
_primeCode;
|
|
198
|
-
_malleable;
|
|
199
|
-
constructor(prime, generator, malleable = false) {
|
|
200
|
-
this._prime = bufferToBigInt(prime);
|
|
201
|
-
this._generatorBuf = generator;
|
|
202
|
-
this._generator = bufferToBigInt(generator);
|
|
203
|
-
this._primeByteLength = prime.length;
|
|
204
|
-
this._pubKey = void 0;
|
|
205
|
-
this._privKey = void 0;
|
|
206
|
-
this._primeCode = void 0;
|
|
207
|
-
this._malleable = malleable;
|
|
208
|
-
if (!malleable) {
|
|
209
|
-
this._primeCode = 0;
|
|
210
|
-
this.setPublicKey = void 0;
|
|
211
|
-
this.setPrivateKey = void 0;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Error code from prime/generator validation.
|
|
216
|
-
* Lazily computed on first access.
|
|
217
|
-
*/
|
|
218
|
-
get verifyError() {
|
|
219
|
-
if (typeof this._primeCode !== "number") {
|
|
220
|
-
this._primeCode = getCachedCheckPrime(this._prime, this._generatorBuf);
|
|
221
|
-
}
|
|
222
|
-
return this._primeCode;
|
|
223
|
-
}
|
|
224
|
-
generateKeys(encoding) {
|
|
225
|
-
if (!this._privKey) {
|
|
226
|
-
const randBuf = randomBytes(this._primeByteLength);
|
|
227
|
-
this._privKey = bufferToBigInt(randBuf);
|
|
228
|
-
}
|
|
229
|
-
this._pubKey = modPow(this._generator, this._privKey, this._prime);
|
|
230
|
-
return this.getPublicKey(encoding);
|
|
231
|
-
}
|
|
232
|
-
computeSecret(otherPublicKey, inputEncoding, outputEncoding) {
|
|
233
|
-
let otherBuf;
|
|
234
|
-
if (typeof otherPublicKey === "string") {
|
|
235
|
-
otherBuf = Buffer.from(otherPublicKey, inputEncoding || "utf8");
|
|
236
|
-
} else {
|
|
237
|
-
otherBuf = Buffer.from(otherPublicKey);
|
|
238
|
-
}
|
|
239
|
-
const other = bufferToBigInt(otherBuf);
|
|
240
|
-
if (!this._privKey) {
|
|
241
|
-
throw new Error("You must generate keys before computing a secret");
|
|
242
|
-
}
|
|
243
|
-
if (other <= 0n || other >= this._prime) {
|
|
244
|
-
throw new Error("Supplied key is too large");
|
|
245
|
-
}
|
|
246
|
-
const secret = modPow(other, this._privKey, this._prime);
|
|
247
|
-
let out = bigIntToBuffer(secret);
|
|
248
|
-
const primeLen = this._primeByteLength;
|
|
249
|
-
if (out.length < primeLen) {
|
|
250
|
-
const padded = Buffer.alloc(primeLen);
|
|
251
|
-
out.copy(padded, primeLen - out.length);
|
|
252
|
-
out = padded;
|
|
253
|
-
}
|
|
254
|
-
if (outputEncoding) {
|
|
255
|
-
return out.toString(outputEncoding);
|
|
256
|
-
}
|
|
257
|
-
return out;
|
|
258
|
-
}
|
|
259
|
-
getPrime(encoding) {
|
|
260
|
-
return formatReturnValue(this._prime, encoding);
|
|
261
|
-
}
|
|
262
|
-
getGenerator(encoding) {
|
|
263
|
-
return formatReturnValue(this._generator, encoding);
|
|
264
|
-
}
|
|
265
|
-
getPublicKey(encoding) {
|
|
266
|
-
if (!this._pubKey) {
|
|
267
|
-
throw new Error("No public key - call generateKeys() first");
|
|
268
|
-
}
|
|
269
|
-
return formatReturnValue(this._pubKey, encoding);
|
|
270
|
-
}
|
|
271
|
-
getPrivateKey(encoding) {
|
|
272
|
-
if (!this._privKey) {
|
|
273
|
-
throw new Error("No private key - call generateKeys() first");
|
|
274
|
-
}
|
|
275
|
-
return formatReturnValue(this._privKey, encoding);
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Set the public key. Only available for malleable DH instances
|
|
279
|
-
* (created via createDiffieHellman, not getDiffieHellman).
|
|
280
|
-
*/
|
|
281
|
-
setPublicKey(publicKey, encoding) {
|
|
282
|
-
if (!this._malleable) {
|
|
283
|
-
throw new Error("setPublicKey is not available for predefined DH groups");
|
|
284
|
-
}
|
|
285
|
-
const buf = typeof publicKey === "string" ? Buffer.from(publicKey, encoding || "utf8") : Buffer.from(publicKey);
|
|
286
|
-
this._pubKey = bufferToBigInt(buf);
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Set the private key. Only available for malleable DH instances
|
|
290
|
-
* (created via createDiffieHellman, not getDiffieHellman).
|
|
291
|
-
*/
|
|
292
|
-
setPrivateKey(privateKey, encoding) {
|
|
293
|
-
if (!this._malleable) {
|
|
294
|
-
throw new Error("setPrivateKey is not available for predefined DH groups");
|
|
295
|
-
}
|
|
296
|
-
const buf = typeof privateKey === "string" ? Buffer.from(privateKey, encoding || "utf8") : Buffer.from(privateKey);
|
|
297
|
-
this._privKey = bufferToBigInt(buf);
|
|
298
|
-
}
|
|
211
|
+
const buf = bigIntToBuffer(n);
|
|
212
|
+
if (!encoding) {
|
|
213
|
+
return buf;
|
|
214
|
+
}
|
|
215
|
+
return buf.toString(encoding);
|
|
299
216
|
}
|
|
217
|
+
var DiffieHellman = class {
|
|
218
|
+
_prime;
|
|
219
|
+
_generator;
|
|
220
|
+
_generatorBuf;
|
|
221
|
+
_primeByteLength;
|
|
222
|
+
_pubKey;
|
|
223
|
+
_privKey;
|
|
224
|
+
_primeCode;
|
|
225
|
+
_malleable;
|
|
226
|
+
constructor(prime, generator, malleable = false) {
|
|
227
|
+
this._prime = bufferToBigInt(prime);
|
|
228
|
+
this._generatorBuf = generator;
|
|
229
|
+
this._generator = bufferToBigInt(generator);
|
|
230
|
+
this._primeByteLength = prime.length;
|
|
231
|
+
this._pubKey = undefined;
|
|
232
|
+
this._privKey = undefined;
|
|
233
|
+
this._primeCode = undefined;
|
|
234
|
+
this._malleable = malleable;
|
|
235
|
+
if (!malleable) {
|
|
236
|
+
this._primeCode = 0;
|
|
237
|
+
this.setPublicKey = undefined;
|
|
238
|
+
this.setPrivateKey = undefined;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Error code from prime/generator validation.
|
|
243
|
+
* Lazily computed on first access.
|
|
244
|
+
*/
|
|
245
|
+
get verifyError() {
|
|
246
|
+
if (typeof this._primeCode !== "number") {
|
|
247
|
+
this._primeCode = getCachedCheckPrime(this._prime, this._generatorBuf);
|
|
248
|
+
}
|
|
249
|
+
return this._primeCode;
|
|
250
|
+
}
|
|
251
|
+
generateKeys(encoding) {
|
|
252
|
+
if (!this._privKey) {
|
|
253
|
+
const randBuf = randomBytes(this._primeByteLength);
|
|
254
|
+
this._privKey = bufferToBigInt(randBuf);
|
|
255
|
+
}
|
|
256
|
+
this._pubKey = modPow(this._generator, this._privKey, this._prime);
|
|
257
|
+
return this.getPublicKey(encoding);
|
|
258
|
+
}
|
|
259
|
+
computeSecret(otherPublicKey, inputEncoding, outputEncoding) {
|
|
260
|
+
let otherBuf;
|
|
261
|
+
if (typeof otherPublicKey === "string") {
|
|
262
|
+
otherBuf = Buffer.from(otherPublicKey, inputEncoding || "utf8");
|
|
263
|
+
} else {
|
|
264
|
+
otherBuf = Buffer.from(otherPublicKey);
|
|
265
|
+
}
|
|
266
|
+
const other = bufferToBigInt(otherBuf);
|
|
267
|
+
if (!this._privKey) {
|
|
268
|
+
throw new Error("You must generate keys before computing a secret");
|
|
269
|
+
}
|
|
270
|
+
if (other <= 0n || other >= this._prime) {
|
|
271
|
+
throw new Error("Supplied key is too large");
|
|
272
|
+
}
|
|
273
|
+
const secret = modPow(other, this._privKey, this._prime);
|
|
274
|
+
let out = bigIntToBuffer(secret);
|
|
275
|
+
const primeLen = this._primeByteLength;
|
|
276
|
+
if (out.length < primeLen) {
|
|
277
|
+
const padded = Buffer.alloc(primeLen);
|
|
278
|
+
out.copy(padded, primeLen - out.length);
|
|
279
|
+
out = padded;
|
|
280
|
+
}
|
|
281
|
+
if (outputEncoding) {
|
|
282
|
+
return out.toString(outputEncoding);
|
|
283
|
+
}
|
|
284
|
+
return out;
|
|
285
|
+
}
|
|
286
|
+
getPrime(encoding) {
|
|
287
|
+
return formatReturnValue(this._prime, encoding);
|
|
288
|
+
}
|
|
289
|
+
getGenerator(encoding) {
|
|
290
|
+
return formatReturnValue(this._generator, encoding);
|
|
291
|
+
}
|
|
292
|
+
getPublicKey(encoding) {
|
|
293
|
+
if (!this._pubKey) {
|
|
294
|
+
throw new Error("No public key - call generateKeys() first");
|
|
295
|
+
}
|
|
296
|
+
return formatReturnValue(this._pubKey, encoding);
|
|
297
|
+
}
|
|
298
|
+
getPrivateKey(encoding) {
|
|
299
|
+
if (!this._privKey) {
|
|
300
|
+
throw new Error("No private key - call generateKeys() first");
|
|
301
|
+
}
|
|
302
|
+
return formatReturnValue(this._privKey, encoding);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Set the public key. Only available for malleable DH instances
|
|
306
|
+
* (created via createDiffieHellman, not getDiffieHellman).
|
|
307
|
+
*/
|
|
308
|
+
setPublicKey(publicKey, encoding) {
|
|
309
|
+
if (!this._malleable) {
|
|
310
|
+
throw new Error("setPublicKey is not available for predefined DH groups");
|
|
311
|
+
}
|
|
312
|
+
const buf = typeof publicKey === "string" ? Buffer.from(publicKey, encoding || "utf8") : Buffer.from(publicKey);
|
|
313
|
+
this._pubKey = bufferToBigInt(buf);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Set the private key. Only available for malleable DH instances
|
|
317
|
+
* (created via createDiffieHellman, not getDiffieHellman).
|
|
318
|
+
*/
|
|
319
|
+
setPrivateKey(privateKey, encoding) {
|
|
320
|
+
if (!this._malleable) {
|
|
321
|
+
throw new Error("setPrivateKey is not available for predefined DH groups");
|
|
322
|
+
}
|
|
323
|
+
const buf = typeof privateKey === "string" ? Buffer.from(privateKey, encoding || "utf8") : Buffer.from(privateKey);
|
|
324
|
+
this._privKey = bufferToBigInt(buf);
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Generate a random prime of the specified bit length suitable for DH.
|
|
329
|
+
* This matches OpenSSL's behavior: for generators 2 and 5 the prime
|
|
330
|
+
* must satisfy specific congruence conditions.
|
|
331
|
+
*/
|
|
300
332
|
function generatePrime(bits, generator) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
333
|
+
const gen = bufferToBigInt(generator);
|
|
334
|
+
if (bits < 16) {
|
|
335
|
+
if (gen === 2n || gen === 5n) {
|
|
336
|
+
return Buffer.from([140, 123]);
|
|
337
|
+
} else {
|
|
338
|
+
return Buffer.from([140, 39]);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const byteLen = Math.ceil(bits / 8);
|
|
342
|
+
const ONE = 1n;
|
|
343
|
+
const TWO = 2n;
|
|
344
|
+
const FOUR = 4n;
|
|
345
|
+
const TWENTYFOUR = 24n;
|
|
346
|
+
const ELEVEN = 11n;
|
|
347
|
+
const TEN = 10n;
|
|
348
|
+
const THREE = 3n;
|
|
349
|
+
while (true) {
|
|
350
|
+
const randBuf = randomBytes(byteLen);
|
|
351
|
+
let num = bufferToBigInt(randBuf);
|
|
352
|
+
while (bitLength(num) > bits) {
|
|
353
|
+
num >>= 1n;
|
|
354
|
+
}
|
|
355
|
+
if (num % TWO === 0n) {
|
|
356
|
+
num += ONE;
|
|
357
|
+
}
|
|
358
|
+
if (!(num & TWO)) {
|
|
359
|
+
num += TWO;
|
|
360
|
+
}
|
|
361
|
+
if (gen === TWO) {
|
|
362
|
+
while (num % TWENTYFOUR !== ELEVEN) {
|
|
363
|
+
num += FOUR;
|
|
364
|
+
}
|
|
365
|
+
} else if (gen === 5n) {
|
|
366
|
+
while (num % TEN !== THREE) {
|
|
367
|
+
num += FOUR;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
const n2 = num >> 1n;
|
|
371
|
+
if (simpleSieve(n2) && simpleSieve(num) && fermatTest(n2) && fermatTest(num) && millerRabinTest(n2) && millerRabinTest(num)) {
|
|
372
|
+
return bigIntToBuffer(num);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
343
375
|
}
|
|
344
376
|
const VALID_ENCODINGS = {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
377
|
+
binary: true,
|
|
378
|
+
hex: true,
|
|
379
|
+
base64: true,
|
|
380
|
+
latin1: true,
|
|
381
|
+
utf8: true,
|
|
382
|
+
"utf-8": true,
|
|
383
|
+
base64url: true,
|
|
384
|
+
ascii: true,
|
|
385
|
+
ucs2: true,
|
|
386
|
+
"ucs-2": true,
|
|
387
|
+
utf16le: true,
|
|
388
|
+
"utf-16le": true
|
|
357
389
|
};
|
|
390
|
+
/**
|
|
391
|
+
* Create a DiffieHellman key exchange object.
|
|
392
|
+
*
|
|
393
|
+
* Usage:
|
|
394
|
+
* createDiffieHellman(primeLength)
|
|
395
|
+
* createDiffieHellman(primeLength, generator)
|
|
396
|
+
* createDiffieHellman(prime, primeEncoding, generator, generatorEncoding)
|
|
397
|
+
* createDiffieHellman(prime, generator)
|
|
398
|
+
*/
|
|
358
399
|
function createDiffieHellman(prime, primeEncoding, generator, generatorEncoding) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
primeBuf = Buffer.from(prime);
|
|
389
|
-
} else {
|
|
390
|
-
primeBuf = Buffer.from(prime, enc);
|
|
391
|
-
}
|
|
392
|
-
return new DiffieHellman(primeBuf, genBuf, true);
|
|
400
|
+
if (primeEncoding !== undefined && typeof primeEncoding !== "number" && (Buffer.isBuffer(primeEncoding) || primeEncoding instanceof Uint8Array || typeof primeEncoding === "string" && !(primeEncoding in VALID_ENCODINGS))) {
|
|
401
|
+
return createDiffieHellman(prime, "binary", primeEncoding, generator);
|
|
402
|
+
}
|
|
403
|
+
const enc = primeEncoding || "binary";
|
|
404
|
+
const genc = generatorEncoding || "binary";
|
|
405
|
+
let genBuf = Buffer.from([2]);
|
|
406
|
+
if (generator !== undefined) {
|
|
407
|
+
if (typeof generator === "number") {
|
|
408
|
+
genBuf = Buffer.alloc(1);
|
|
409
|
+
genBuf[0] = generator;
|
|
410
|
+
} else if (!Buffer.isBuffer(generator)) {
|
|
411
|
+
genBuf = Buffer.from(generator, genc);
|
|
412
|
+
} else {
|
|
413
|
+
genBuf = generator;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (typeof prime === "number") {
|
|
417
|
+
const primeBuf = generatePrime(prime, genBuf);
|
|
418
|
+
return new DiffieHellman(primeBuf, genBuf, true);
|
|
419
|
+
}
|
|
420
|
+
let primeBuf;
|
|
421
|
+
if (Buffer.isBuffer(prime)) {
|
|
422
|
+
primeBuf = prime;
|
|
423
|
+
} else if (prime instanceof Uint8Array) {
|
|
424
|
+
primeBuf = Buffer.from(prime);
|
|
425
|
+
} else {
|
|
426
|
+
primeBuf = Buffer.from(prime, enc);
|
|
427
|
+
}
|
|
428
|
+
return new DiffieHellman(primeBuf, genBuf, true);
|
|
393
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* Create a DiffieHellman key exchange object using a predefined MODP group.
|
|
432
|
+
*
|
|
433
|
+
* Note: Instances from getDiffieHellman do NOT have setPublicKey/setPrivateKey,
|
|
434
|
+
* matching Node.js behavior where predefined group instances are not malleable.
|
|
435
|
+
*/
|
|
394
436
|
function getDiffieHellman(groupName) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
437
|
+
const group = PREDEFINED_GROUPS[groupName];
|
|
438
|
+
if (!group) {
|
|
439
|
+
throw new Error(`Unknown group: ${groupName}. Supported groups: ${Object.keys(PREDEFINED_GROUPS).join(", ")}`);
|
|
440
|
+
}
|
|
441
|
+
const primeBuf = Buffer.from(group.prime, "hex");
|
|
442
|
+
const genBuf = Buffer.from(group.gen, "hex");
|
|
443
|
+
return new DiffieHellman(primeBuf, genBuf, false);
|
|
402
444
|
}
|
|
445
|
+
/** Alias for getDiffieHellman. */
|
|
403
446
|
const createDiffieHellmanGroup = getDiffieHellman;
|
|
447
|
+
/** Alias for getDiffieHellman. */
|
|
404
448
|
const DiffieHellmanGroup = getDiffieHellman;
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
createDiffieHellman,
|
|
409
|
-
createDiffieHellmanGroup,
|
|
410
|
-
getDiffieHellman
|
|
411
|
-
};
|
|
449
|
+
|
|
450
|
+
//#endregion
|
|
451
|
+
export { DiffieHellman, DiffieHellmanGroup, createDiffieHellman, createDiffieHellmanGroup, getDiffieHellman };
|