@protontech/openpgp 6.0.0-beta.1 → 6.0.0-beta.2
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 +2 -2
- package/dist/lightweight/argon2id.min.mjs +1 -1
- package/dist/lightweight/argon2id.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.min.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.mjs +1 -1
- package/dist/lightweight/noble_curves.min.mjs +1 -1
- package/dist/lightweight/noble_curves.mjs +1 -1
- package/dist/lightweight/noble_hashes.min.mjs +1 -1
- package/dist/lightweight/noble_hashes.mjs +1 -1
- package/dist/lightweight/openpgp.min.mjs +3 -2
- package/dist/lightweight/openpgp.min.mjs.map +1 -1
- package/dist/lightweight/openpgp.mjs +1011 -168
- package/dist/lightweight/sha3.min.mjs +1 -1
- package/dist/lightweight/sha3.mjs +1 -1
- package/dist/node/openpgp.cjs +985 -134
- package/dist/node/openpgp.min.cjs +12 -11
- package/dist/node/openpgp.min.cjs.map +1 -1
- package/dist/node/openpgp.min.mjs +12 -11
- package/dist/node/openpgp.min.mjs.map +1 -1
- package/dist/node/openpgp.mjs +984 -134
- package/dist/openpgp.js +1011 -168
- package/dist/openpgp.min.js +12 -11
- package/dist/openpgp.min.js.map +1 -1
- package/dist/openpgp.min.mjs +12 -11
- package/dist/openpgp.min.mjs.map +1 -1
- package/dist/openpgp.mjs +1011 -168
- package/openpgp.d.ts +8 -1
- package/package.json +6 -5
package/dist/openpgp.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! OpenPGP.js v6.0.0-beta.
|
|
1
|
+
/*! OpenPGP.js v6.0.0-beta.2 - 2024-07-05 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
|
|
2
2
|
const globalThis = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
3
3
|
|
|
4
4
|
const doneWritingPromise = Symbol('doneWritingPromise');
|
|
@@ -543,9 +543,10 @@ function transformRaw(input, options) {
|
|
|
543
543
|
* @param {Function} cancel
|
|
544
544
|
* @returns {TransformStream}
|
|
545
545
|
*/
|
|
546
|
-
function transformWithCancel(
|
|
546
|
+
function transformWithCancel(customCancel) {
|
|
547
547
|
let pulled = false;
|
|
548
|
-
let
|
|
548
|
+
let cancelled = false;
|
|
549
|
+
let backpressureChangePromiseResolve, backpressureChangePromiseReject;
|
|
549
550
|
let outputController;
|
|
550
551
|
return {
|
|
551
552
|
readable: new ReadableStream({
|
|
@@ -559,16 +560,29 @@ function transformWithCancel(cancel) {
|
|
|
559
560
|
pulled = true;
|
|
560
561
|
}
|
|
561
562
|
},
|
|
562
|
-
cancel
|
|
563
|
+
async cancel(reason) {
|
|
564
|
+
cancelled = true;
|
|
565
|
+
if (customCancel) {
|
|
566
|
+
await customCancel(reason);
|
|
567
|
+
}
|
|
568
|
+
if (backpressureChangePromiseReject) {
|
|
569
|
+
backpressureChangePromiseReject(reason);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
563
572
|
}, {highWaterMark: 0}),
|
|
564
573
|
writable: new WritableStream({
|
|
565
574
|
write: async function(chunk) {
|
|
575
|
+
if (cancelled) {
|
|
576
|
+
throw new Error('Stream is cancelled');
|
|
577
|
+
}
|
|
566
578
|
outputController.enqueue(chunk);
|
|
567
579
|
if (!pulled) {
|
|
568
|
-
await new Promise(resolve => {
|
|
580
|
+
await new Promise((resolve, reject) => {
|
|
569
581
|
backpressureChangePromiseResolve = resolve;
|
|
582
|
+
backpressureChangePromiseReject = reject;
|
|
570
583
|
});
|
|
571
584
|
backpressureChangePromiseResolve = null;
|
|
585
|
+
backpressureChangePromiseReject = null;
|
|
572
586
|
} else {
|
|
573
587
|
pulled = false;
|
|
574
588
|
}
|
|
@@ -1504,6 +1518,14 @@ var config = {
|
|
|
1504
1518
|
* @property {Boolean} v6Keys
|
|
1505
1519
|
*/
|
|
1506
1520
|
v6Keys: false,
|
|
1521
|
+
/**
|
|
1522
|
+
* Enable parsing v5 keys and v5 signatures (which is different from the AEAD-encrypted SEIPDv2 packet).
|
|
1523
|
+
* These are non-standard entities, which in the crypto-refresh have been superseded
|
|
1524
|
+
* by v6 keys and v6 signatures, respectively.
|
|
1525
|
+
* However, generation of v5 entities was supported behind config flag in OpenPGP.js v5, and some other libraries,
|
|
1526
|
+
* hence parsing them might be necessary in some cases.
|
|
1527
|
+
*/
|
|
1528
|
+
enableParsingV5Entities: false,
|
|
1507
1529
|
/**
|
|
1508
1530
|
* S2K (String to Key) type, used for key derivation in the context of secret key encryption
|
|
1509
1531
|
* and password-encrypted data. Weaker s2k options are not allowed.
|
|
@@ -1660,7 +1682,7 @@ var config = {
|
|
|
1660
1682
|
* @memberof module:config
|
|
1661
1683
|
* @property {String} versionString A version string to be included in armored messages
|
|
1662
1684
|
*/
|
|
1663
|
-
versionString: 'OpenPGP.js 6.0.0-beta.
|
|
1685
|
+
versionString: 'OpenPGP.js 6.0.0-beta.2',
|
|
1664
1686
|
/**
|
|
1665
1687
|
* @memberof module:config
|
|
1666
1688
|
* @property {String} commentString A comment string to be included in armored messages
|
|
@@ -3188,15 +3210,15 @@ function add32(a, b) {
|
|
|
3188
3210
|
|
|
3189
3211
|
|
|
3190
3212
|
const webCrypto$b = util.getWebCrypto();
|
|
3191
|
-
const nodeCrypto$
|
|
3192
|
-
const nodeCryptoHashes = nodeCrypto$
|
|
3213
|
+
const nodeCrypto$b = util.getNodeCrypto();
|
|
3214
|
+
const nodeCryptoHashes = nodeCrypto$b && nodeCrypto$b.getHashes();
|
|
3193
3215
|
|
|
3194
3216
|
function nodeHash(type) {
|
|
3195
|
-
if (!nodeCrypto$
|
|
3217
|
+
if (!nodeCrypto$b || !nodeCryptoHashes.includes(type)) {
|
|
3196
3218
|
return;
|
|
3197
3219
|
}
|
|
3198
3220
|
return async function (data) {
|
|
3199
|
-
const shasum = nodeCrypto$
|
|
3221
|
+
const shasum = nodeCrypto$b.createHash(type);
|
|
3200
3222
|
return transform(data, value => {
|
|
3201
3223
|
shasum.update(value);
|
|
3202
3224
|
}, () => new Uint8Array(shasum.digest()));
|
|
@@ -4543,9 +4565,9 @@ class AES_CFB {
|
|
|
4543
4565
|
|
|
4544
4566
|
|
|
4545
4567
|
const webCrypto$a = util.getWebCrypto();
|
|
4546
|
-
const nodeCrypto$
|
|
4568
|
+
const nodeCrypto$a = util.getNodeCrypto();
|
|
4547
4569
|
|
|
4548
|
-
const knownAlgos = nodeCrypto$
|
|
4570
|
+
const knownAlgos = nodeCrypto$a ? nodeCrypto$a.getCiphers() : [];
|
|
4549
4571
|
const nodeAlgos = {
|
|
4550
4572
|
idea: knownAlgos.includes('idea-cfb') ? 'idea-cfb' : undefined, /* Unused, not implemented */
|
|
4551
4573
|
tripledes: knownAlgos.includes('des-ede3-cfb') ? 'des-ede3-cfb' : undefined,
|
|
@@ -4611,7 +4633,7 @@ async function encrypt$5(algo, key, plaintext, iv, config) {
|
|
|
4611
4633
|
*/
|
|
4612
4634
|
async function decrypt$5(algo, key, ciphertext, iv) {
|
|
4613
4635
|
const algoName = enums.read(enums.symmetric, algo);
|
|
4614
|
-
if (nodeCrypto$
|
|
4636
|
+
if (nodeCrypto$a && nodeAlgos[algoName]) { // Node crypto library.
|
|
4615
4637
|
return nodeDecrypt$1(algo, key, ciphertext, iv);
|
|
4616
4638
|
}
|
|
4617
4639
|
if (util.isAES(algo)) {
|
|
@@ -4779,13 +4801,13 @@ function xorMut$1(a, b) {
|
|
|
4779
4801
|
|
|
4780
4802
|
function nodeEncrypt$1(algo, key, pt, iv) {
|
|
4781
4803
|
const algoName = enums.read(enums.symmetric, algo);
|
|
4782
|
-
const cipherObj = new nodeCrypto$
|
|
4804
|
+
const cipherObj = new nodeCrypto$a.createCipheriv(nodeAlgos[algoName], key, iv);
|
|
4783
4805
|
return transform(pt, value => new Uint8Array(cipherObj.update(value)));
|
|
4784
4806
|
}
|
|
4785
4807
|
|
|
4786
4808
|
function nodeDecrypt$1(algo, key, ct, iv) {
|
|
4787
4809
|
const algoName = enums.read(enums.symmetric, algo);
|
|
4788
|
-
const decipherObj = new nodeCrypto$
|
|
4810
|
+
const decipherObj = new nodeCrypto$a.createDecipheriv(nodeAlgos[algoName], key, iv);
|
|
4789
4811
|
return transform(ct, value => new Uint8Array(decipherObj.update(value)));
|
|
4790
4812
|
}
|
|
4791
4813
|
|
|
@@ -4878,7 +4900,7 @@ class AES_CBC {
|
|
|
4878
4900
|
|
|
4879
4901
|
|
|
4880
4902
|
const webCrypto$9 = util.getWebCrypto();
|
|
4881
|
-
const nodeCrypto$
|
|
4903
|
+
const nodeCrypto$9 = util.getNodeCrypto();
|
|
4882
4904
|
|
|
4883
4905
|
|
|
4884
4906
|
/**
|
|
@@ -4944,7 +4966,7 @@ async function CMAC(key) {
|
|
|
4944
4966
|
async function CBC(key) {
|
|
4945
4967
|
if (util.getNodeCrypto()) { // Node crypto library
|
|
4946
4968
|
return async function(pt) {
|
|
4947
|
-
const en = new nodeCrypto$
|
|
4969
|
+
const en = new nodeCrypto$9.createCipheriv('aes-' + (key.length * 8) + '-cbc', key, zeroBlock$1);
|
|
4948
4970
|
const ct = en.update(pt);
|
|
4949
4971
|
return new Uint8Array(ct);
|
|
4950
4972
|
};
|
|
@@ -4992,7 +5014,7 @@ async function CBC(key) {
|
|
|
4992
5014
|
|
|
4993
5015
|
|
|
4994
5016
|
const webCrypto$8 = util.getWebCrypto();
|
|
4995
|
-
const nodeCrypto$
|
|
5017
|
+
const nodeCrypto$8 = util.getNodeCrypto();
|
|
4996
5018
|
const Buffer$1 = util.getNodeBuffer();
|
|
4997
5019
|
|
|
4998
5020
|
|
|
@@ -5014,7 +5036,7 @@ async function OMAC(key) {
|
|
|
5014
5036
|
async function CTR(key) {
|
|
5015
5037
|
if (util.getNodeCrypto()) { // Node crypto library
|
|
5016
5038
|
return async function(pt, iv) {
|
|
5017
|
-
const en = new nodeCrypto$
|
|
5039
|
+
const en = new nodeCrypto$8.createCipheriv('aes-' + (key.length * 8) + '-ctr', key, iv);
|
|
5018
5040
|
const ct = Buffer$1.concat([en.update(pt), en.final()]);
|
|
5019
5041
|
return new Uint8Array(ct);
|
|
5020
5042
|
};
|
|
@@ -5705,7 +5727,7 @@ class AES_GCM {
|
|
|
5705
5727
|
|
|
5706
5728
|
|
|
5707
5729
|
const webCrypto$7 = util.getWebCrypto();
|
|
5708
|
-
const nodeCrypto$
|
|
5730
|
+
const nodeCrypto$7 = util.getNodeCrypto();
|
|
5709
5731
|
const Buffer = util.getNodeBuffer();
|
|
5710
5732
|
|
|
5711
5733
|
const blockLength = 16;
|
|
@@ -5728,14 +5750,14 @@ async function GCM(cipher, key) {
|
|
|
5728
5750
|
if (util.getNodeCrypto()) { // Node crypto library
|
|
5729
5751
|
return {
|
|
5730
5752
|
encrypt: async function(pt, iv, adata = new Uint8Array()) {
|
|
5731
|
-
const en = new nodeCrypto$
|
|
5753
|
+
const en = new nodeCrypto$7.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
|
5732
5754
|
en.setAAD(adata);
|
|
5733
5755
|
const ct = Buffer.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
|
|
5734
5756
|
return new Uint8Array(ct);
|
|
5735
5757
|
},
|
|
5736
5758
|
|
|
5737
5759
|
decrypt: async function(ct, iv, adata = new Uint8Array()) {
|
|
5738
|
-
const de = new nodeCrypto$
|
|
5760
|
+
const de = new nodeCrypto$7.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
|
5739
5761
|
de.setAAD(adata);
|
|
5740
5762
|
de.setAuthTag(ct.slice(ct.length - tagLength, ct.length)); // read auth tag at end of ciphertext
|
|
5741
5763
|
const pt = Buffer.concat([de.update(ct.slice(0, ct.length - tagLength)), de.final()]);
|
|
@@ -5834,8 +5856,8 @@ var mode = {
|
|
|
5834
5856
|
};
|
|
5835
5857
|
|
|
5836
5858
|
// Operations are not constant time, but we try and limit timing leakage where we can
|
|
5837
|
-
const _0n$
|
|
5838
|
-
const _1n$
|
|
5859
|
+
const _0n$9 = BigInt(0);
|
|
5860
|
+
const _1n$e = BigInt(1);
|
|
5839
5861
|
function uint8ArrayToBigInt(bytes) {
|
|
5840
5862
|
const hexAlphabet = '0123456789ABCDEF';
|
|
5841
5863
|
let s = '';
|
|
@@ -5844,9 +5866,9 @@ function uint8ArrayToBigInt(bytes) {
|
|
|
5844
5866
|
});
|
|
5845
5867
|
return BigInt('0x0' + s);
|
|
5846
5868
|
}
|
|
5847
|
-
function mod$
|
|
5869
|
+
function mod$3(a, m) {
|
|
5848
5870
|
const reduced = a % m;
|
|
5849
|
-
return reduced < _0n$
|
|
5871
|
+
return reduced < _0n$9 ? reduced + m : reduced;
|
|
5850
5872
|
}
|
|
5851
5873
|
/**
|
|
5852
5874
|
* Compute modular exponentiation using square and multiply
|
|
@@ -5856,19 +5878,19 @@ function mod$2(a, m) {
|
|
|
5856
5878
|
* @returns {BigInt} b ** e mod n.
|
|
5857
5879
|
*/
|
|
5858
5880
|
function modExp(b, e, n) {
|
|
5859
|
-
if (n === _0n$
|
|
5881
|
+
if (n === _0n$9)
|
|
5860
5882
|
throw Error('Modulo cannot be zero');
|
|
5861
|
-
if (n === _1n$
|
|
5883
|
+
if (n === _1n$e)
|
|
5862
5884
|
return BigInt(0);
|
|
5863
|
-
if (e < _0n$
|
|
5885
|
+
if (e < _0n$9)
|
|
5864
5886
|
throw Error('Unsopported negative exponent');
|
|
5865
5887
|
let exp = e;
|
|
5866
5888
|
let x = b;
|
|
5867
5889
|
x %= n;
|
|
5868
5890
|
let r = BigInt(1);
|
|
5869
|
-
while (exp > _0n$
|
|
5870
|
-
const lsb = exp & _1n$
|
|
5871
|
-
exp >>= _1n$
|
|
5891
|
+
while (exp > _0n$9) {
|
|
5892
|
+
const lsb = exp & _1n$e;
|
|
5893
|
+
exp >>= _1n$e; // e / 2
|
|
5872
5894
|
// Always compute multiplication step, to reduce timing leakage
|
|
5873
5895
|
const rx = (r * x) % n;
|
|
5874
5896
|
// Update r only if lsb is 1 (odd exponent)
|
|
@@ -5878,7 +5900,7 @@ function modExp(b, e, n) {
|
|
|
5878
5900
|
return r;
|
|
5879
5901
|
}
|
|
5880
5902
|
function abs(x) {
|
|
5881
|
-
return x >= _0n$
|
|
5903
|
+
return x >= _0n$9 ? x : -x;
|
|
5882
5904
|
}
|
|
5883
5905
|
/**
|
|
5884
5906
|
* Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf)
|
|
@@ -5898,9 +5920,9 @@ function _egcd(aInput, bInput) {
|
|
|
5898
5920
|
// See https://math.stackexchange.com/questions/37806/extended-euclidean-algorithm-with-negative-numbers
|
|
5899
5921
|
let a = abs(aInput);
|
|
5900
5922
|
let b = abs(bInput);
|
|
5901
|
-
const aNegated = aInput < _0n$
|
|
5902
|
-
const bNegated = bInput < _0n$
|
|
5903
|
-
while (b !== _0n$
|
|
5923
|
+
const aNegated = aInput < _0n$9;
|
|
5924
|
+
const bNegated = bInput < _0n$9;
|
|
5925
|
+
while (b !== _0n$9) {
|
|
5904
5926
|
const q = a / b;
|
|
5905
5927
|
let tmp = x;
|
|
5906
5928
|
x = xPrev - q * x;
|
|
@@ -5928,10 +5950,10 @@ function _egcd(aInput, bInput) {
|
|
|
5928
5950
|
*/
|
|
5929
5951
|
function modInv(a, n) {
|
|
5930
5952
|
const { gcd, x } = _egcd(a, n);
|
|
5931
|
-
if (gcd !== _1n$
|
|
5953
|
+
if (gcd !== _1n$e) {
|
|
5932
5954
|
throw new Error('Inverse does not exist');
|
|
5933
5955
|
}
|
|
5934
|
-
return mod$
|
|
5956
|
+
return mod$3(x + n, n);
|
|
5935
5957
|
}
|
|
5936
5958
|
/**
|
|
5937
5959
|
* Compute greatest common divisor between this and n
|
|
@@ -5942,7 +5964,7 @@ function modInv(a, n) {
|
|
|
5942
5964
|
function gcd(aInput, bInput) {
|
|
5943
5965
|
let a = aInput;
|
|
5944
5966
|
let b = bInput;
|
|
5945
|
-
while (b !== _0n$
|
|
5967
|
+
while (b !== _0n$9) {
|
|
5946
5968
|
const tmp = b;
|
|
5947
5969
|
b = a % b;
|
|
5948
5970
|
a = tmp;
|
|
@@ -5969,8 +5991,8 @@ function bigIntToNumber(x) {
|
|
|
5969
5991
|
* @returns {Number} Bit value.
|
|
5970
5992
|
*/
|
|
5971
5993
|
function getBit(x, i) {
|
|
5972
|
-
const bit = (x >> BigInt(i)) & _1n$
|
|
5973
|
-
return bit === _0n$
|
|
5994
|
+
const bit = (x >> BigInt(i)) & _1n$e;
|
|
5995
|
+
return bit === _0n$9 ? 0 : 1;
|
|
5974
5996
|
}
|
|
5975
5997
|
/**
|
|
5976
5998
|
* Compute bit length
|
|
@@ -5978,11 +6000,11 @@ function getBit(x, i) {
|
|
|
5978
6000
|
function bitLength(x) {
|
|
5979
6001
|
// -1n >> -1n is -1n
|
|
5980
6002
|
// 1n >> 1n is 0n
|
|
5981
|
-
const target = x < _0n$
|
|
6003
|
+
const target = x < _0n$9 ? BigInt(-1) : _0n$9;
|
|
5982
6004
|
let bitlen = 1;
|
|
5983
6005
|
let tmp = x;
|
|
5984
6006
|
// eslint-disable-next-line no-cond-assign
|
|
5985
|
-
while ((tmp >>= _1n$
|
|
6007
|
+
while ((tmp >>= _1n$e) !== target) {
|
|
5986
6008
|
bitlen++;
|
|
5987
6009
|
}
|
|
5988
6010
|
return bitlen;
|
|
@@ -5991,7 +6013,7 @@ function bitLength(x) {
|
|
|
5991
6013
|
* Compute byte length
|
|
5992
6014
|
*/
|
|
5993
6015
|
function byteLength(x) {
|
|
5994
|
-
const target = x < _0n$
|
|
6016
|
+
const target = x < _0n$9 ? BigInt(-1) : _0n$9;
|
|
5995
6017
|
const _8n = BigInt(8);
|
|
5996
6018
|
let len = 1;
|
|
5997
6019
|
let tmp = x;
|
|
@@ -6047,7 +6069,7 @@ function bigIntToUint8Array(x, endian = 'be', length) {
|
|
|
6047
6069
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
6048
6070
|
|
|
6049
6071
|
|
|
6050
|
-
const nodeCrypto$
|
|
6072
|
+
const nodeCrypto$6 = util.getNodeCrypto();
|
|
6051
6073
|
|
|
6052
6074
|
/**
|
|
6053
6075
|
* Retrieve secure random byte array of the specified length
|
|
@@ -6056,8 +6078,8 @@ const nodeCrypto$5 = util.getNodeCrypto();
|
|
|
6056
6078
|
*/
|
|
6057
6079
|
function getRandomBytes(length) {
|
|
6058
6080
|
const buf = new Uint8Array(length);
|
|
6059
|
-
if (nodeCrypto$
|
|
6060
|
-
const bytes = nodeCrypto$
|
|
6081
|
+
if (nodeCrypto$6) {
|
|
6082
|
+
const bytes = nodeCrypto$6.randomBytes(buf.length);
|
|
6061
6083
|
buf.set(bytes);
|
|
6062
6084
|
} else if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
6063
6085
|
crypto.getRandomValues(buf);
|
|
@@ -6086,7 +6108,7 @@ function getRandomBigInteger(min, max) {
|
|
|
6086
6108
|
// However, we request 64 extra random bits so that the bias is negligible.
|
|
6087
6109
|
// Section B.1.1 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
|
|
6088
6110
|
const r = uint8ArrayToBigInt(getRandomBytes(bytes + 8));
|
|
6089
|
-
return mod$
|
|
6111
|
+
return mod$3(r, modulus) + min;
|
|
6090
6112
|
}
|
|
6091
6113
|
|
|
6092
6114
|
var random = /*#__PURE__*/Object.freeze({
|
|
@@ -6115,7 +6137,7 @@ var random = /*#__PURE__*/Object.freeze({
|
|
|
6115
6137
|
* @fileoverview Algorithms for probabilistic random prime generation
|
|
6116
6138
|
* @module crypto/public_key/prime
|
|
6117
6139
|
*/
|
|
6118
|
-
const _1n$
|
|
6140
|
+
const _1n$d = BigInt(1);
|
|
6119
6141
|
/**
|
|
6120
6142
|
* Generate a probably prime random number
|
|
6121
6143
|
* @param bits - Bit length of the prime
|
|
@@ -6124,7 +6146,7 @@ const _1n$c = BigInt(1);
|
|
|
6124
6146
|
*/
|
|
6125
6147
|
function randomProbablePrime(bits, e, k) {
|
|
6126
6148
|
const _30n = BigInt(30);
|
|
6127
|
-
const min = _1n$
|
|
6149
|
+
const min = _1n$d << BigInt(bits - 1);
|
|
6128
6150
|
/*
|
|
6129
6151
|
* We can avoid any multiples of 3 and 5 by looking at n mod 30
|
|
6130
6152
|
* n mod 30 = 0 1 2 3 4 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
|
|
@@ -6132,16 +6154,16 @@ function randomProbablePrime(bits, e, k) {
|
|
|
6132
6154
|
* 1 7 7 7 7 7 7 11 11 11 11 13 13 17 17 17 17 19 19 23 23 23 23 29 29 29 29 29 29 1
|
|
6133
6155
|
*/
|
|
6134
6156
|
const adds = [1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2];
|
|
6135
|
-
let n = getRandomBigInteger(min, min << _1n$
|
|
6136
|
-
let i = bigIntToNumber(mod$
|
|
6157
|
+
let n = getRandomBigInteger(min, min << _1n$d);
|
|
6158
|
+
let i = bigIntToNumber(mod$3(n, _30n));
|
|
6137
6159
|
do {
|
|
6138
6160
|
n += BigInt(adds[i]);
|
|
6139
6161
|
i = (i + adds[i]) % adds.length;
|
|
6140
6162
|
// If reached the maximum, go back to the minimum.
|
|
6141
6163
|
if (bitLength(n) > bits) {
|
|
6142
|
-
n = mod$
|
|
6164
|
+
n = mod$3(n, min << _1n$d);
|
|
6143
6165
|
n += min;
|
|
6144
|
-
i = bigIntToNumber(mod$
|
|
6166
|
+
i = bigIntToNumber(mod$3(n, _30n));
|
|
6145
6167
|
}
|
|
6146
6168
|
} while (!isProbablePrime(n, e, k));
|
|
6147
6169
|
return n;
|
|
@@ -6153,7 +6175,7 @@ function randomProbablePrime(bits, e, k) {
|
|
|
6153
6175
|
* @param k - Optional number of iterations of Miller-Rabin test
|
|
6154
6176
|
*/
|
|
6155
6177
|
function isProbablePrime(n, e, k) {
|
|
6156
|
-
if (e && gcd(n - _1n$
|
|
6178
|
+
if (e && gcd(n - _1n$d, e) !== _1n$d) {
|
|
6157
6179
|
return false;
|
|
6158
6180
|
}
|
|
6159
6181
|
if (!divisionTest(n)) {
|
|
@@ -6176,11 +6198,11 @@ function isProbablePrime(n, e, k) {
|
|
|
6176
6198
|
* @param b - Optional Fermat test base
|
|
6177
6199
|
*/
|
|
6178
6200
|
function fermat(n, b = BigInt(2)) {
|
|
6179
|
-
return modExp(b, n - _1n$
|
|
6201
|
+
return modExp(b, n - _1n$d, n) === _1n$d;
|
|
6180
6202
|
}
|
|
6181
6203
|
function divisionTest(n) {
|
|
6182
6204
|
const _0n = BigInt(0);
|
|
6183
|
-
return smallPrimes.every(m => mod$
|
|
6205
|
+
return smallPrimes.every(m => mod$3(n, m) !== _0n);
|
|
6184
6206
|
}
|
|
6185
6207
|
// https://github.com/gpg/libgcrypt/blob/master/cipher/primegen.c
|
|
6186
6208
|
const smallPrimes = [
|
|
@@ -6304,7 +6326,7 @@ function millerRabin(n, k, rand) {
|
|
|
6304
6326
|
if (!k) {
|
|
6305
6327
|
k = Math.max(1, (len / 48) | 0);
|
|
6306
6328
|
}
|
|
6307
|
-
const n1 = n - _1n$
|
|
6329
|
+
const n1 = n - _1n$d; // n - 1
|
|
6308
6330
|
// Find d and s, (n - 1) = (2 ^ s) * d;
|
|
6309
6331
|
let s = 0;
|
|
6310
6332
|
while (!getBit(n1, s)) {
|
|
@@ -6314,13 +6336,13 @@ function millerRabin(n, k, rand) {
|
|
|
6314
6336
|
for (; k > 0; k--) {
|
|
6315
6337
|
const a = getRandomBigInteger(BigInt(2), n1);
|
|
6316
6338
|
let x = modExp(a, d, n);
|
|
6317
|
-
if (x === _1n$
|
|
6339
|
+
if (x === _1n$d || x === n1) {
|
|
6318
6340
|
continue;
|
|
6319
6341
|
}
|
|
6320
6342
|
let i;
|
|
6321
6343
|
for (i = 1; i < s; i++) {
|
|
6322
|
-
x = mod$
|
|
6323
|
-
if (x === _1n$
|
|
6344
|
+
x = mod$3(x * x, n);
|
|
6345
|
+
if (x === _1n$d) {
|
|
6324
6346
|
return false;
|
|
6325
6347
|
}
|
|
6326
6348
|
if (x === n1) {
|
|
@@ -6513,8 +6535,8 @@ var pkcs1 = /*#__PURE__*/Object.freeze({
|
|
|
6513
6535
|
|
|
6514
6536
|
|
|
6515
6537
|
const webCrypto$6 = util.getWebCrypto();
|
|
6516
|
-
const nodeCrypto$
|
|
6517
|
-
const _1n$
|
|
6538
|
+
const nodeCrypto$5 = util.getNodeCrypto();
|
|
6539
|
+
const _1n$c = BigInt(1);
|
|
6518
6540
|
|
|
6519
6541
|
/** Create signature
|
|
6520
6542
|
* @param {module:enums.hash} hashAlgo - Hash algorithm
|
|
@@ -6555,7 +6577,7 @@ async function sign$7(hashAlgo, data, n, e, d, p, q, u, hashed) {
|
|
|
6555
6577
|
* @returns {Boolean}
|
|
6556
6578
|
* @async
|
|
6557
6579
|
*/
|
|
6558
|
-
async function verify$
|
|
6580
|
+
async function verify$8(hashAlgo, data, s, n, e, hashed) {
|
|
6559
6581
|
if (data && !util.isStream(data)) {
|
|
6560
6582
|
if (util.getWebCrypto()) {
|
|
6561
6583
|
try {
|
|
@@ -6655,7 +6677,7 @@ async function generate$5(bits, e) {
|
|
|
6655
6677
|
privateKeyEncoding: { type: 'pkcs1', format: 'jwk' }
|
|
6656
6678
|
};
|
|
6657
6679
|
const jwk = await new Promise((resolve, reject) => {
|
|
6658
|
-
nodeCrypto$
|
|
6680
|
+
nodeCrypto$5.generateKeyPair('rsa', opts, (err, _, jwkPrivateKey) => {
|
|
6659
6681
|
if (err) {
|
|
6660
6682
|
reject(err);
|
|
6661
6683
|
} else {
|
|
@@ -6678,7 +6700,7 @@ async function generate$5(bits, e) {
|
|
|
6678
6700
|
n = p * q;
|
|
6679
6701
|
} while (bitLength(n) !== bits);
|
|
6680
6702
|
|
|
6681
|
-
const phi = (p - _1n$
|
|
6703
|
+
const phi = (p - _1n$c) * (q - _1n$c);
|
|
6682
6704
|
|
|
6683
6705
|
if (q < p) {
|
|
6684
6706
|
[p, q] = [q, p];
|
|
@@ -6720,7 +6742,7 @@ async function validateParams$9(n, e, d, p, q, u) {
|
|
|
6720
6742
|
const _2n = BigInt(2);
|
|
6721
6743
|
// expect p*u = 1 mod q
|
|
6722
6744
|
u = uint8ArrayToBigInt(u);
|
|
6723
|
-
if (mod$
|
|
6745
|
+
if (mod$3(p * u, q) !== BigInt(1)) {
|
|
6724
6746
|
return false;
|
|
6725
6747
|
}
|
|
6726
6748
|
|
|
@@ -6737,7 +6759,7 @@ async function validateParams$9(n, e, d, p, q, u) {
|
|
|
6737
6759
|
const r = getRandomBigInteger(_2n, _2n << nSizeOver3); // r in [ 2, 2^{|n|/3} ) < p and q
|
|
6738
6760
|
const rde = r * d * e;
|
|
6739
6761
|
|
|
6740
|
-
const areInverses = mod$
|
|
6762
|
+
const areInverses = mod$3(rde, p - _1n$c) === r && mod$3(rde, q - _1n$c) === r;
|
|
6741
6763
|
if (!areInverses) {
|
|
6742
6764
|
return false;
|
|
6743
6765
|
}
|
|
@@ -6773,7 +6795,7 @@ async function webSign$1(hashName, data, n, e, d, p, q, u) {
|
|
|
6773
6795
|
}
|
|
6774
6796
|
|
|
6775
6797
|
async function nodeSign$1(hashAlgo, data, n, e, d, p, q, u) {
|
|
6776
|
-
const sign = nodeCrypto$
|
|
6798
|
+
const sign = nodeCrypto$5.createSign(enums.read(enums.hash, hashAlgo));
|
|
6777
6799
|
sign.write(data);
|
|
6778
6800
|
sign.end();
|
|
6779
6801
|
|
|
@@ -6806,7 +6828,7 @@ async function nodeVerify$1(hashAlgo, data, s, n, e) {
|
|
|
6806
6828
|
const jwk = publicToJWK(n, e);
|
|
6807
6829
|
const key = { key: jwk, format: 'jwk', type: 'pkcs1' };
|
|
6808
6830
|
|
|
6809
|
-
const verify = nodeCrypto$
|
|
6831
|
+
const verify = nodeCrypto$5.createVerify(enums.read(enums.hash, hashAlgo));
|
|
6810
6832
|
verify.write(data);
|
|
6811
6833
|
verify.end();
|
|
6812
6834
|
|
|
@@ -6819,9 +6841,9 @@ async function nodeVerify$1(hashAlgo, data, s, n, e) {
|
|
|
6819
6841
|
|
|
6820
6842
|
async function nodeEncrypt(data, n, e) {
|
|
6821
6843
|
const jwk = publicToJWK(n, e);
|
|
6822
|
-
const key = { key: jwk, format: 'jwk', type: 'pkcs1', padding: nodeCrypto$
|
|
6844
|
+
const key = { key: jwk, format: 'jwk', type: 'pkcs1', padding: nodeCrypto$5.constants.RSA_PKCS1_PADDING };
|
|
6823
6845
|
|
|
6824
|
-
return new Uint8Array(nodeCrypto$
|
|
6846
|
+
return new Uint8Array(nodeCrypto$5.publicEncrypt(key, data));
|
|
6825
6847
|
}
|
|
6826
6848
|
|
|
6827
6849
|
async function bnEncrypt(data, n, e) {
|
|
@@ -6836,10 +6858,10 @@ async function bnEncrypt(data, n, e) {
|
|
|
6836
6858
|
|
|
6837
6859
|
async function nodeDecrypt(data, n, e, d, p, q, u) {
|
|
6838
6860
|
const jwk = await privateToJWK$1(n, e, d, p, q, u);
|
|
6839
|
-
const key = { key: jwk, format: 'jwk' , type: 'pkcs1', padding: nodeCrypto$
|
|
6861
|
+
const key = { key: jwk, format: 'jwk' , type: 'pkcs1', padding: nodeCrypto$5.constants.RSA_PKCS1_PADDING };
|
|
6840
6862
|
|
|
6841
6863
|
try {
|
|
6842
|
-
return new Uint8Array(nodeCrypto$
|
|
6864
|
+
return new Uint8Array(nodeCrypto$5.privateDecrypt(key, data));
|
|
6843
6865
|
} catch (err) {
|
|
6844
6866
|
throw new Error('Decryption error');
|
|
6845
6867
|
}
|
|
@@ -6856,20 +6878,20 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) {
|
|
|
6856
6878
|
if (data >= n) {
|
|
6857
6879
|
throw new Error('Data too large.');
|
|
6858
6880
|
}
|
|
6859
|
-
const dq = mod$
|
|
6860
|
-
const dp = mod$
|
|
6881
|
+
const dq = mod$3(d, q - _1n$c); // d mod (q-1)
|
|
6882
|
+
const dp = mod$3(d, p - _1n$c); // d mod (p-1)
|
|
6861
6883
|
|
|
6862
6884
|
const unblinder = getRandomBigInteger(BigInt(2), n);
|
|
6863
6885
|
const blinder = modExp(modInv(unblinder, n), e, n);
|
|
6864
|
-
data = mod$
|
|
6886
|
+
data = mod$3(data * blinder, n);
|
|
6865
6887
|
|
|
6866
6888
|
const mp = modExp(data, dp, p); // data**{d mod (q-1)} mod p
|
|
6867
6889
|
const mq = modExp(data, dq, q); // data**{d mod (p-1)} mod q
|
|
6868
|
-
const h = mod$
|
|
6890
|
+
const h = mod$3(u * (mq - mp), q); // u * (mq-mp) mod q (operands already < q)
|
|
6869
6891
|
|
|
6870
6892
|
let result = h * p + mp; // result < n due to relations above
|
|
6871
6893
|
|
|
6872
|
-
result = mod$
|
|
6894
|
+
result = mod$3(result * unblinder, n);
|
|
6873
6895
|
|
|
6874
6896
|
return emeDecode(bigIntToUint8Array(result, 'be', byteLength(n)), randomPayload);
|
|
6875
6897
|
}
|
|
@@ -6889,8 +6911,8 @@ async function privateToJWK$1(n, e, d, p, q, u) {
|
|
|
6889
6911
|
const qNum = uint8ArrayToBigInt(q);
|
|
6890
6912
|
const dNum = uint8ArrayToBigInt(d);
|
|
6891
6913
|
|
|
6892
|
-
let dq = mod$
|
|
6893
|
-
let dp = mod$
|
|
6914
|
+
let dq = mod$3(dNum, qNum - _1n$c); // d mod (q-1)
|
|
6915
|
+
let dp = mod$3(dNum, pNum - _1n$c); // d mod (p-1)
|
|
6894
6916
|
dp = bigIntToUint8Array(dp);
|
|
6895
6917
|
dq = bigIntToUint8Array(dq);
|
|
6896
6918
|
return {
|
|
@@ -6945,7 +6967,7 @@ var rsa = /*#__PURE__*/Object.freeze({
|
|
|
6945
6967
|
generate: generate$5,
|
|
6946
6968
|
sign: sign$7,
|
|
6947
6969
|
validateParams: validateParams$9,
|
|
6948
|
-
verify: verify$
|
|
6970
|
+
verify: verify$8
|
|
6949
6971
|
});
|
|
6950
6972
|
|
|
6951
6973
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
@@ -6966,7 +6988,7 @@ var rsa = /*#__PURE__*/Object.freeze({
|
|
|
6966
6988
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
6967
6989
|
|
|
6968
6990
|
|
|
6969
|
-
const _1n$
|
|
6991
|
+
const _1n$b = BigInt(1);
|
|
6970
6992
|
|
|
6971
6993
|
/**
|
|
6972
6994
|
* ElGamal Encryption function
|
|
@@ -6988,10 +7010,10 @@ async function encrypt$3(data, p, g, y) {
|
|
|
6988
7010
|
|
|
6989
7011
|
// OpenPGP uses a "special" version of ElGamal where g is generator of the full group Z/pZ*
|
|
6990
7012
|
// hence g has order p-1, and to avoid that k = 0 mod p-1, we need to pick k in [1, p-2]
|
|
6991
|
-
const k = getRandomBigInteger(_1n$
|
|
7013
|
+
const k = getRandomBigInteger(_1n$b, p - _1n$b);
|
|
6992
7014
|
return {
|
|
6993
7015
|
c1: bigIntToUint8Array(modExp(g, k, p)),
|
|
6994
|
-
c2: bigIntToUint8Array(mod$
|
|
7016
|
+
c2: bigIntToUint8Array(mod$3(modExp(y, k, p) * m, p))
|
|
6995
7017
|
};
|
|
6996
7018
|
}
|
|
6997
7019
|
|
|
@@ -7013,7 +7035,7 @@ async function decrypt$3(c1, c2, p, x, randomPayload) {
|
|
|
7013
7035
|
p = uint8ArrayToBigInt(p);
|
|
7014
7036
|
x = uint8ArrayToBigInt(x);
|
|
7015
7037
|
|
|
7016
|
-
const padded = mod$
|
|
7038
|
+
const padded = mod$3(modInv(modExp(c1, x, p), p) * c2, p);
|
|
7017
7039
|
return emeDecode(bigIntToUint8Array(padded, 'be', byteLength(p)), randomPayload);
|
|
7018
7040
|
}
|
|
7019
7041
|
|
|
@@ -7032,7 +7054,7 @@ async function validateParams$8(p, g, y, x) {
|
|
|
7032
7054
|
y = uint8ArrayToBigInt(y);
|
|
7033
7055
|
|
|
7034
7056
|
// Check that 1 < g < p
|
|
7035
|
-
if (g <= _1n$
|
|
7057
|
+
if (g <= _1n$b || g >= p) {
|
|
7036
7058
|
return false;
|
|
7037
7059
|
}
|
|
7038
7060
|
|
|
@@ -7047,7 +7069,7 @@ async function validateParams$8(p, g, y, x) {
|
|
|
7047
7069
|
* g should have order p-1
|
|
7048
7070
|
* Check that g ** (p-1) = 1 mod p
|
|
7049
7071
|
*/
|
|
7050
|
-
if (modExp(g, p - _1n$
|
|
7072
|
+
if (modExp(g, p - _1n$b, p) !== _1n$b) {
|
|
7051
7073
|
return false;
|
|
7052
7074
|
}
|
|
7053
7075
|
|
|
@@ -7062,8 +7084,8 @@ async function validateParams$8(p, g, y, x) {
|
|
|
7062
7084
|
const _2n = BigInt(2);
|
|
7063
7085
|
const threshold = _2n << BigInt(17); // we want order > threshold
|
|
7064
7086
|
while (i < threshold) {
|
|
7065
|
-
res = mod$
|
|
7066
|
-
if (res === _1n$
|
|
7087
|
+
res = mod$3(res * g, p);
|
|
7088
|
+
if (res === _1n$b) {
|
|
7067
7089
|
return false;
|
|
7068
7090
|
}
|
|
7069
7091
|
i++;
|
|
@@ -7076,8 +7098,8 @@ async function validateParams$8(p, g, y, x) {
|
|
|
7076
7098
|
* Blinded exponentiation computes g**{r(p-1) + x} to compare to y
|
|
7077
7099
|
*/
|
|
7078
7100
|
x = uint8ArrayToBigInt(x);
|
|
7079
|
-
const r = getRandomBigInteger(_2n << (pSize - _1n$
|
|
7080
|
-
const rqx = (p - _1n$
|
|
7101
|
+
const r = getRandomBigInteger(_2n << (pSize - _1n$b), _2n << pSize); // draw r of same size as p-1
|
|
7102
|
+
const rqx = (p - _1n$b) * r + x;
|
|
7081
7103
|
if (y !== modExp(g, rqx, p)) {
|
|
7082
7104
|
return false;
|
|
7083
7105
|
}
|
|
@@ -7093,7 +7115,7 @@ var elgamal = /*#__PURE__*/Object.freeze({
|
|
|
7093
7115
|
});
|
|
7094
7116
|
|
|
7095
7117
|
// declare const globalThis: Record<string, any> | undefined;
|
|
7096
|
-
const crypto$
|
|
7118
|
+
const crypto$4 =
|
|
7097
7119
|
typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
|
7098
7120
|
|
|
7099
7121
|
const nacl = {};
|
|
@@ -8456,13 +8478,13 @@ nacl.setPRNG = function(fn) {
|
|
|
8456
8478
|
(function() {
|
|
8457
8479
|
// Initialize PRNG if environment provides CSPRNG.
|
|
8458
8480
|
// If not, methods calling randombytes will throw.
|
|
8459
|
-
if (crypto$
|
|
8481
|
+
if (crypto$4 && crypto$4.getRandomValues) {
|
|
8460
8482
|
// Browsers and Node v16+
|
|
8461
8483
|
var QUOTA = 65536;
|
|
8462
8484
|
nacl.setPRNG(function(x, n) {
|
|
8463
8485
|
var i, v = new Uint8Array(n);
|
|
8464
8486
|
for (i = 0; i < n; i += QUOTA) {
|
|
8465
|
-
crypto$
|
|
8487
|
+
crypto$4.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
|
|
8466
8488
|
}
|
|
8467
8489
|
for (i = 0; i < n; i++) x[i] = v[i];
|
|
8468
8490
|
cleanup(v);
|
|
@@ -8911,15 +8933,15 @@ class UnparseablePacket {
|
|
|
8911
8933
|
|
|
8912
8934
|
|
|
8913
8935
|
const webCrypto$5 = util.getWebCrypto();
|
|
8914
|
-
const nodeCrypto$
|
|
8936
|
+
const nodeCrypto$4 = util.getNodeCrypto();
|
|
8915
8937
|
|
|
8916
8938
|
const webCurves = {
|
|
8917
8939
|
[enums.curve.nistP256]: 'P-256',
|
|
8918
8940
|
[enums.curve.nistP384]: 'P-384',
|
|
8919
8941
|
[enums.curve.nistP521]: 'P-521'
|
|
8920
8942
|
};
|
|
8921
|
-
const knownCurves = nodeCrypto$
|
|
8922
|
-
const nodeCurves = nodeCrypto$
|
|
8943
|
+
const knownCurves = nodeCrypto$4 ? nodeCrypto$4.getCurves() : [];
|
|
8944
|
+
const nodeCurves = nodeCrypto$4 ? {
|
|
8923
8945
|
[enums.curve.secp256k1]: knownCurves.includes('secp256k1') ? 'secp256k1' : undefined,
|
|
8924
8946
|
[enums.curve.nistP256]: knownCurves.includes('prime256v1') ? 'prime256v1' : undefined,
|
|
8925
8947
|
[enums.curve.nistP384]: knownCurves.includes('secp384r1') ? 'secp384r1' : undefined,
|
|
@@ -8940,7 +8962,8 @@ const curves = {
|
|
|
8940
8962
|
node: nodeCurves[enums.curve.nistP256],
|
|
8941
8963
|
web: webCurves[enums.curve.nistP256],
|
|
8942
8964
|
payloadSize: 32,
|
|
8943
|
-
sharedSize: 256
|
|
8965
|
+
sharedSize: 256,
|
|
8966
|
+
wireFormatLeadingByte: 0x04
|
|
8944
8967
|
},
|
|
8945
8968
|
[enums.curve.nistP384]: {
|
|
8946
8969
|
oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22],
|
|
@@ -8950,7 +8973,8 @@ const curves = {
|
|
|
8950
8973
|
node: nodeCurves[enums.curve.nistP384],
|
|
8951
8974
|
web: webCurves[enums.curve.nistP384],
|
|
8952
8975
|
payloadSize: 48,
|
|
8953
|
-
sharedSize: 384
|
|
8976
|
+
sharedSize: 384,
|
|
8977
|
+
wireFormatLeadingByte: 0x04
|
|
8954
8978
|
},
|
|
8955
8979
|
[enums.curve.nistP521]: {
|
|
8956
8980
|
oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23],
|
|
@@ -8960,7 +8984,8 @@ const curves = {
|
|
|
8960
8984
|
node: nodeCurves[enums.curve.nistP521],
|
|
8961
8985
|
web: webCurves[enums.curve.nistP521],
|
|
8962
8986
|
payloadSize: 66,
|
|
8963
|
-
sharedSize: 528
|
|
8987
|
+
sharedSize: 528,
|
|
8988
|
+
wireFormatLeadingByte: 0x04
|
|
8964
8989
|
},
|
|
8965
8990
|
[enums.curve.secp256k1]: {
|
|
8966
8991
|
oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x0A],
|
|
@@ -8968,14 +8993,16 @@ const curves = {
|
|
|
8968
8993
|
hash: enums.hash.sha256,
|
|
8969
8994
|
cipher: enums.symmetric.aes128,
|
|
8970
8995
|
node: nodeCurves[enums.curve.secp256k1],
|
|
8971
|
-
payloadSize: 32
|
|
8996
|
+
payloadSize: 32,
|
|
8997
|
+
wireFormatLeadingByte: 0x04
|
|
8972
8998
|
},
|
|
8973
8999
|
[enums.curve.ed25519Legacy]: {
|
|
8974
9000
|
oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
|
|
8975
9001
|
keyType: enums.publicKey.eddsaLegacy,
|
|
8976
9002
|
hash: enums.hash.sha512,
|
|
8977
9003
|
node: false, // nodeCurves.ed25519 TODO
|
|
8978
|
-
payloadSize: 32
|
|
9004
|
+
payloadSize: 32,
|
|
9005
|
+
wireFormatLeadingByte: 0x40
|
|
8979
9006
|
},
|
|
8980
9007
|
[enums.curve.curve25519Legacy]: {
|
|
8981
9008
|
oid: [0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01],
|
|
@@ -8983,7 +9010,8 @@ const curves = {
|
|
|
8983
9010
|
hash: enums.hash.sha256,
|
|
8984
9011
|
cipher: enums.symmetric.aes128,
|
|
8985
9012
|
node: false, // nodeCurves.curve25519 TODO
|
|
8986
|
-
payloadSize: 32
|
|
9013
|
+
payloadSize: 32,
|
|
9014
|
+
wireFormatLeadingByte: 0x40
|
|
8987
9015
|
},
|
|
8988
9016
|
[enums.curve.brainpoolP256r1]: {
|
|
8989
9017
|
oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07],
|
|
@@ -8991,7 +9019,8 @@ const curves = {
|
|
|
8991
9019
|
hash: enums.hash.sha256,
|
|
8992
9020
|
cipher: enums.symmetric.aes128,
|
|
8993
9021
|
node: nodeCurves[enums.curve.brainpoolP256r1],
|
|
8994
|
-
payloadSize: 32
|
|
9022
|
+
payloadSize: 32,
|
|
9023
|
+
wireFormatLeadingByte: 0x04
|
|
8995
9024
|
},
|
|
8996
9025
|
[enums.curve.brainpoolP384r1]: {
|
|
8997
9026
|
oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B],
|
|
@@ -8999,7 +9028,8 @@ const curves = {
|
|
|
8999
9028
|
hash: enums.hash.sha384,
|
|
9000
9029
|
cipher: enums.symmetric.aes192,
|
|
9001
9030
|
node: nodeCurves[enums.curve.brainpoolP384r1],
|
|
9002
|
-
payloadSize: 48
|
|
9031
|
+
payloadSize: 48,
|
|
9032
|
+
wireFormatLeadingByte: 0x04
|
|
9003
9033
|
},
|
|
9004
9034
|
[enums.curve.brainpoolP512r1]: {
|
|
9005
9035
|
oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D],
|
|
@@ -9007,7 +9037,8 @@ const curves = {
|
|
|
9007
9037
|
hash: enums.hash.sha512,
|
|
9008
9038
|
cipher: enums.symmetric.aes256,
|
|
9009
9039
|
node: nodeCurves[enums.curve.brainpoolP512r1],
|
|
9010
|
-
payloadSize: 64
|
|
9040
|
+
payloadSize: 64,
|
|
9041
|
+
wireFormatLeadingByte: 0x04
|
|
9011
9042
|
}
|
|
9012
9043
|
};
|
|
9013
9044
|
|
|
@@ -9031,6 +9062,7 @@ class CurveWithOID {
|
|
|
9031
9062
|
this.web = params.web;
|
|
9032
9063
|
this.payloadSize = params.payloadSize;
|
|
9033
9064
|
this.sharedSize = params.sharedSize;
|
|
9065
|
+
this.wireFormatLeadingByte = params.wireFormatLeadingByte;
|
|
9034
9066
|
if (this.web && util.getWebCrypto()) {
|
|
9035
9067
|
this.type = 'web';
|
|
9036
9068
|
} else if (this.node && util.getNodeCrypto()) {
|
|
@@ -9046,7 +9078,7 @@ class CurveWithOID {
|
|
|
9046
9078
|
switch (this.type) {
|
|
9047
9079
|
case 'web':
|
|
9048
9080
|
try {
|
|
9049
|
-
return await webGenKeyPair(this.name);
|
|
9081
|
+
return await webGenKeyPair(this.name, this.wireFormatLeadingByte);
|
|
9050
9082
|
} catch (err) {
|
|
9051
9083
|
util.printDebugError('Browser did not support generating ec key ' + err.message);
|
|
9052
9084
|
return jsGenKeyPair(this.name);
|
|
@@ -9059,13 +9091,13 @@ class CurveWithOID {
|
|
|
9059
9091
|
privateKey[31] &= 248;
|
|
9060
9092
|
const secretKey = privateKey.slice().reverse();
|
|
9061
9093
|
const { publicKey: rawPublicKey } = nacl.box.keyPair.fromSecretKey(secretKey);
|
|
9062
|
-
const publicKey = util.concatUint8Array([new Uint8Array([
|
|
9094
|
+
const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), rawPublicKey]);
|
|
9063
9095
|
return { publicKey, privateKey };
|
|
9064
9096
|
}
|
|
9065
9097
|
case 'ed25519Legacy': {
|
|
9066
9098
|
const privateKey = getRandomBytes(32);
|
|
9067
9099
|
const keyPair = nacl.sign.keyPair.fromSeed(privateKey);
|
|
9068
|
-
const publicKey = util.concatUint8Array([new Uint8Array([
|
|
9100
|
+
const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), keyPair.publicKey]);
|
|
9069
9101
|
return { publicKey, privateKey };
|
|
9070
9102
|
}
|
|
9071
9103
|
default:
|
|
@@ -9151,6 +9183,20 @@ async function validateStandardParams(algo, oid, Q, d) {
|
|
|
9151
9183
|
return true;
|
|
9152
9184
|
}
|
|
9153
9185
|
|
|
9186
|
+
/**
|
|
9187
|
+
* Check whether the public point has a valid encoding.
|
|
9188
|
+
* NB: this function does not check e.g. whether the point belongs to the curve.
|
|
9189
|
+
*/
|
|
9190
|
+
function checkPublicPointEnconding(curve, V) {
|
|
9191
|
+
const { payloadSize, wireFormatLeadingByte, name: curveName } = curve;
|
|
9192
|
+
|
|
9193
|
+
const pointSize = (curveName === enums.curve.curve25519Legacy || curveName === enums.curve.ed25519Legacy) ? payloadSize : payloadSize * 2;
|
|
9194
|
+
|
|
9195
|
+
if (V[0] !== wireFormatLeadingByte || V.length !== pointSize + 1) {
|
|
9196
|
+
throw new Error('Invalid point encoding');
|
|
9197
|
+
}
|
|
9198
|
+
}
|
|
9199
|
+
|
|
9154
9200
|
//////////////////////////
|
|
9155
9201
|
// //
|
|
9156
9202
|
// Helper functions //
|
|
@@ -9163,7 +9209,7 @@ async function jsGenKeyPair(name) {
|
|
|
9163
9209
|
return { publicKey, privateKey };
|
|
9164
9210
|
}
|
|
9165
9211
|
|
|
9166
|
-
async function webGenKeyPair(name) {
|
|
9212
|
+
async function webGenKeyPair(name, wireFormatLeadingByte) {
|
|
9167
9213
|
// Note: keys generated with ECDSA and ECDH are structurally equivalent
|
|
9168
9214
|
const webCryptoKey = await webCrypto$5.generateKey({ name: 'ECDSA', namedCurve: webCurves[name] }, true, ['sign', 'verify']);
|
|
9169
9215
|
|
|
@@ -9171,14 +9217,14 @@ async function webGenKeyPair(name) {
|
|
|
9171
9217
|
const publicKey = await webCrypto$5.exportKey('jwk', webCryptoKey.publicKey);
|
|
9172
9218
|
|
|
9173
9219
|
return {
|
|
9174
|
-
publicKey: jwkToRawPublic(publicKey),
|
|
9220
|
+
publicKey: jwkToRawPublic(publicKey, wireFormatLeadingByte),
|
|
9175
9221
|
privateKey: b64ToUint8Array(privateKey.d)
|
|
9176
9222
|
};
|
|
9177
9223
|
}
|
|
9178
9224
|
|
|
9179
9225
|
async function nodeGenKeyPair(name) {
|
|
9180
9226
|
// Note: ECDSA and ECDH key generation is structurally equivalent
|
|
9181
|
-
const ecdh = nodeCrypto$
|
|
9227
|
+
const ecdh = nodeCrypto$4.createECDH(nodeCurves[name]);
|
|
9182
9228
|
await ecdh.generateKeys();
|
|
9183
9229
|
return {
|
|
9184
9230
|
publicKey: new Uint8Array(ecdh.getPublicKey()),
|
|
@@ -9197,11 +9243,11 @@ async function nodeGenKeyPair(name) {
|
|
|
9197
9243
|
*
|
|
9198
9244
|
* @returns {Uint8Array} Raw public key.
|
|
9199
9245
|
*/
|
|
9200
|
-
function jwkToRawPublic(jwk) {
|
|
9246
|
+
function jwkToRawPublic(jwk, wireFormatLeadingByte) {
|
|
9201
9247
|
const bufX = b64ToUint8Array(jwk.x);
|
|
9202
9248
|
const bufY = b64ToUint8Array(jwk.y);
|
|
9203
9249
|
const publicKey = new Uint8Array(bufX.length + bufY.length + 1);
|
|
9204
|
-
publicKey[0] =
|
|
9250
|
+
publicKey[0] = wireFormatLeadingByte;
|
|
9205
9251
|
publicKey.set(bufX, 1);
|
|
9206
9252
|
publicKey.set(bufY, bufX.length + 1);
|
|
9207
9253
|
return publicKey;
|
|
@@ -9262,7 +9308,7 @@ function privateToJWK(payloadSize, name, publicKey, privateKey) {
|
|
|
9262
9308
|
|
|
9263
9309
|
|
|
9264
9310
|
const webCrypto$4 = util.getWebCrypto();
|
|
9265
|
-
const nodeCrypto$
|
|
9311
|
+
const nodeCrypto$3 = util.getNodeCrypto();
|
|
9266
9312
|
|
|
9267
9313
|
/**
|
|
9268
9314
|
* Sign a message using the provided key
|
|
@@ -9280,6 +9326,7 @@ const nodeCrypto$2 = util.getNodeCrypto();
|
|
|
9280
9326
|
*/
|
|
9281
9327
|
async function sign$6(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
9282
9328
|
const curve = new CurveWithOID(oid);
|
|
9329
|
+
checkPublicPointEnconding(curve, publicKey);
|
|
9283
9330
|
if (message && !util.isStream(message)) {
|
|
9284
9331
|
const keyPair = { publicKey, privateKey };
|
|
9285
9332
|
switch (curve.type) {
|
|
@@ -9324,8 +9371,9 @@ async function sign$6(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
9324
9371
|
* @returns {Boolean}
|
|
9325
9372
|
* @async
|
|
9326
9373
|
*/
|
|
9327
|
-
async function verify$
|
|
9374
|
+
async function verify$7(oid, hashAlgo, signature, message, publicKey, hashed) {
|
|
9328
9375
|
const curve = new CurveWithOID(oid);
|
|
9376
|
+
checkPublicPointEnconding(curve, publicKey);
|
|
9329
9377
|
// See https://github.com/openpgpjs/openpgpjs/pull/948.
|
|
9330
9378
|
// NB: the impact was more likely limited to Brainpool curves, since thanks
|
|
9331
9379
|
// to WebCrypto availability, NIST curve should not have been affected.
|
|
@@ -9392,7 +9440,7 @@ async function validateParams$7(oid, Q, d) {
|
|
|
9392
9440
|
try {
|
|
9393
9441
|
const signature = await sign$6(oid, hashAlgo, message, Q, d, hashed);
|
|
9394
9442
|
// eslint-disable-next-line @typescript-eslint/return-await
|
|
9395
|
-
return await verify$
|
|
9443
|
+
return await verify$7(oid, hashAlgo, signature, message, Q, hashed);
|
|
9396
9444
|
} catch (err) {
|
|
9397
9445
|
return false;
|
|
9398
9446
|
}
|
|
@@ -9487,7 +9535,7 @@ async function nodeSign(curve, hashAlgo, message, privateKey) {
|
|
|
9487
9535
|
privateKey: nodeBuffer.from(privateKey)
|
|
9488
9536
|
});
|
|
9489
9537
|
|
|
9490
|
-
const sign = nodeCrypto$
|
|
9538
|
+
const sign = nodeCrypto$3.createSign(enums.read(enums.hash, hashAlgo));
|
|
9491
9539
|
sign.write(message);
|
|
9492
9540
|
sign.end();
|
|
9493
9541
|
|
|
@@ -9508,7 +9556,7 @@ async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) {
|
|
|
9508
9556
|
publicKey: nodeBuffer.from(publicKey)
|
|
9509
9557
|
});
|
|
9510
9558
|
|
|
9511
|
-
const verify = nodeCrypto$
|
|
9559
|
+
const verify = nodeCrypto$3.createVerify(enums.read(enums.hash, hashAlgo));
|
|
9512
9560
|
verify.write(message);
|
|
9513
9561
|
verify.end();
|
|
9514
9562
|
|
|
@@ -9525,7 +9573,760 @@ var ecdsa = /*#__PURE__*/Object.freeze({
|
|
|
9525
9573
|
__proto__: null,
|
|
9526
9574
|
sign: sign$6,
|
|
9527
9575
|
validateParams: validateParams$7,
|
|
9528
|
-
verify: verify$
|
|
9576
|
+
verify: verify$7
|
|
9577
|
+
});
|
|
9578
|
+
|
|
9579
|
+
/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
|
|
9580
|
+
const nodeCrypto$2 = null;
|
|
9581
|
+
const _0n$8 = BigInt(0);
|
|
9582
|
+
const _1n$a = BigInt(1);
|
|
9583
|
+
const _2n$6 = BigInt(2);
|
|
9584
|
+
const _8n$2 = BigInt(8);
|
|
9585
|
+
const CU_O = BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989');
|
|
9586
|
+
const CURVE$1 = Object.freeze({
|
|
9587
|
+
a: BigInt(-1),
|
|
9588
|
+
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
|
9589
|
+
P: BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949'),
|
|
9590
|
+
l: CU_O,
|
|
9591
|
+
n: CU_O,
|
|
9592
|
+
h: BigInt(8),
|
|
9593
|
+
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
|
9594
|
+
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
|
9595
|
+
});
|
|
9596
|
+
const POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000');
|
|
9597
|
+
const SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
|
9598
|
+
BigInt('6853475219497561581579357271197624642482790079785650197046958215289687604742');
|
|
9599
|
+
const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
|
9600
|
+
const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
|
9601
|
+
const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
|
9602
|
+
const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
|
9603
|
+
class ExtendedPoint {
|
|
9604
|
+
constructor(x, y, z, t) {
|
|
9605
|
+
this.x = x;
|
|
9606
|
+
this.y = y;
|
|
9607
|
+
this.z = z;
|
|
9608
|
+
this.t = t;
|
|
9609
|
+
}
|
|
9610
|
+
static fromAffine(p) {
|
|
9611
|
+
if (!(p instanceof Point)) {
|
|
9612
|
+
throw new TypeError('ExtendedPoint#fromAffine: expected Point');
|
|
9613
|
+
}
|
|
9614
|
+
if (p.equals(Point.ZERO))
|
|
9615
|
+
return ExtendedPoint.ZERO;
|
|
9616
|
+
return new ExtendedPoint(p.x, p.y, _1n$a, mod$2(p.x * p.y));
|
|
9617
|
+
}
|
|
9618
|
+
static toAffineBatch(points) {
|
|
9619
|
+
const toInv = invertBatch(points.map((p) => p.z));
|
|
9620
|
+
return points.map((p, i) => p.toAffine(toInv[i]));
|
|
9621
|
+
}
|
|
9622
|
+
static normalizeZ(points) {
|
|
9623
|
+
return this.toAffineBatch(points).map(this.fromAffine);
|
|
9624
|
+
}
|
|
9625
|
+
equals(other) {
|
|
9626
|
+
assertExtPoint(other);
|
|
9627
|
+
const { x: X1, y: Y1, z: Z1 } = this;
|
|
9628
|
+
const { x: X2, y: Y2, z: Z2 } = other;
|
|
9629
|
+
const X1Z2 = mod$2(X1 * Z2);
|
|
9630
|
+
const X2Z1 = mod$2(X2 * Z1);
|
|
9631
|
+
const Y1Z2 = mod$2(Y1 * Z2);
|
|
9632
|
+
const Y2Z1 = mod$2(Y2 * Z1);
|
|
9633
|
+
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
|
9634
|
+
}
|
|
9635
|
+
negate() {
|
|
9636
|
+
return new ExtendedPoint(mod$2(-this.x), this.y, this.z, mod$2(-this.t));
|
|
9637
|
+
}
|
|
9638
|
+
double() {
|
|
9639
|
+
const { x: X1, y: Y1, z: Z1 } = this;
|
|
9640
|
+
const { a } = CURVE$1;
|
|
9641
|
+
const A = mod$2(X1 * X1);
|
|
9642
|
+
const B = mod$2(Y1 * Y1);
|
|
9643
|
+
const C = mod$2(_2n$6 * mod$2(Z1 * Z1));
|
|
9644
|
+
const D = mod$2(a * A);
|
|
9645
|
+
const x1y1 = X1 + Y1;
|
|
9646
|
+
const E = mod$2(mod$2(x1y1 * x1y1) - A - B);
|
|
9647
|
+
const G = D + B;
|
|
9648
|
+
const F = G - C;
|
|
9649
|
+
const H = D - B;
|
|
9650
|
+
const X3 = mod$2(E * F);
|
|
9651
|
+
const Y3 = mod$2(G * H);
|
|
9652
|
+
const T3 = mod$2(E * H);
|
|
9653
|
+
const Z3 = mod$2(F * G);
|
|
9654
|
+
return new ExtendedPoint(X3, Y3, Z3, T3);
|
|
9655
|
+
}
|
|
9656
|
+
add(other) {
|
|
9657
|
+
assertExtPoint(other);
|
|
9658
|
+
const { x: X1, y: Y1, z: Z1, t: T1 } = this;
|
|
9659
|
+
const { x: X2, y: Y2, z: Z2, t: T2 } = other;
|
|
9660
|
+
const A = mod$2((Y1 - X1) * (Y2 + X2));
|
|
9661
|
+
const B = mod$2((Y1 + X1) * (Y2 - X2));
|
|
9662
|
+
const F = mod$2(B - A);
|
|
9663
|
+
if (F === _0n$8)
|
|
9664
|
+
return this.double();
|
|
9665
|
+
const C = mod$2(Z1 * _2n$6 * T2);
|
|
9666
|
+
const D = mod$2(T1 * _2n$6 * Z2);
|
|
9667
|
+
const E = D + C;
|
|
9668
|
+
const G = B + A;
|
|
9669
|
+
const H = D - C;
|
|
9670
|
+
const X3 = mod$2(E * F);
|
|
9671
|
+
const Y3 = mod$2(G * H);
|
|
9672
|
+
const T3 = mod$2(E * H);
|
|
9673
|
+
const Z3 = mod$2(F * G);
|
|
9674
|
+
return new ExtendedPoint(X3, Y3, Z3, T3);
|
|
9675
|
+
}
|
|
9676
|
+
subtract(other) {
|
|
9677
|
+
return this.add(other.negate());
|
|
9678
|
+
}
|
|
9679
|
+
precomputeWindow(W) {
|
|
9680
|
+
const windows = 1 + 256 / W;
|
|
9681
|
+
const points = [];
|
|
9682
|
+
let p = this;
|
|
9683
|
+
let base = p;
|
|
9684
|
+
for (let window = 0; window < windows; window++) {
|
|
9685
|
+
base = p;
|
|
9686
|
+
points.push(base);
|
|
9687
|
+
for (let i = 1; i < 2 ** (W - 1); i++) {
|
|
9688
|
+
base = base.add(p);
|
|
9689
|
+
points.push(base);
|
|
9690
|
+
}
|
|
9691
|
+
p = base.double();
|
|
9692
|
+
}
|
|
9693
|
+
return points;
|
|
9694
|
+
}
|
|
9695
|
+
wNAF(n, affinePoint) {
|
|
9696
|
+
if (!affinePoint && this.equals(ExtendedPoint.BASE))
|
|
9697
|
+
affinePoint = Point.BASE;
|
|
9698
|
+
const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1;
|
|
9699
|
+
if (256 % W) {
|
|
9700
|
+
throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
|
|
9701
|
+
}
|
|
9702
|
+
let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
|
|
9703
|
+
if (!precomputes) {
|
|
9704
|
+
precomputes = this.precomputeWindow(W);
|
|
9705
|
+
if (affinePoint && W !== 1) {
|
|
9706
|
+
precomputes = ExtendedPoint.normalizeZ(precomputes);
|
|
9707
|
+
pointPrecomputes.set(affinePoint, precomputes);
|
|
9708
|
+
}
|
|
9709
|
+
}
|
|
9710
|
+
let p = ExtendedPoint.ZERO;
|
|
9711
|
+
let f = ExtendedPoint.BASE;
|
|
9712
|
+
const windows = 1 + 256 / W;
|
|
9713
|
+
const windowSize = 2 ** (W - 1);
|
|
9714
|
+
const mask = BigInt(2 ** W - 1);
|
|
9715
|
+
const maxNumber = 2 ** W;
|
|
9716
|
+
const shiftBy = BigInt(W);
|
|
9717
|
+
for (let window = 0; window < windows; window++) {
|
|
9718
|
+
const offset = window * windowSize;
|
|
9719
|
+
let wbits = Number(n & mask);
|
|
9720
|
+
n >>= shiftBy;
|
|
9721
|
+
if (wbits > windowSize) {
|
|
9722
|
+
wbits -= maxNumber;
|
|
9723
|
+
n += _1n$a;
|
|
9724
|
+
}
|
|
9725
|
+
const offset1 = offset;
|
|
9726
|
+
const offset2 = offset + Math.abs(wbits) - 1;
|
|
9727
|
+
const cond1 = window % 2 !== 0;
|
|
9728
|
+
const cond2 = wbits < 0;
|
|
9729
|
+
if (wbits === 0) {
|
|
9730
|
+
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
|
9731
|
+
}
|
|
9732
|
+
else {
|
|
9733
|
+
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
|
9734
|
+
}
|
|
9735
|
+
}
|
|
9736
|
+
return ExtendedPoint.normalizeZ([p, f])[0];
|
|
9737
|
+
}
|
|
9738
|
+
multiply(scalar, affinePoint) {
|
|
9739
|
+
return this.wNAF(normalizeScalar(scalar, CURVE$1.l), affinePoint);
|
|
9740
|
+
}
|
|
9741
|
+
multiplyUnsafe(scalar) {
|
|
9742
|
+
let n = normalizeScalar(scalar, CURVE$1.l, false);
|
|
9743
|
+
const G = ExtendedPoint.BASE;
|
|
9744
|
+
const P0 = ExtendedPoint.ZERO;
|
|
9745
|
+
if (n === _0n$8)
|
|
9746
|
+
return P0;
|
|
9747
|
+
if (this.equals(P0) || n === _1n$a)
|
|
9748
|
+
return this;
|
|
9749
|
+
if (this.equals(G))
|
|
9750
|
+
return this.wNAF(n);
|
|
9751
|
+
let p = P0;
|
|
9752
|
+
let d = this;
|
|
9753
|
+
while (n > _0n$8) {
|
|
9754
|
+
if (n & _1n$a)
|
|
9755
|
+
p = p.add(d);
|
|
9756
|
+
d = d.double();
|
|
9757
|
+
n >>= _1n$a;
|
|
9758
|
+
}
|
|
9759
|
+
return p;
|
|
9760
|
+
}
|
|
9761
|
+
isSmallOrder() {
|
|
9762
|
+
return this.multiplyUnsafe(CURVE$1.h).equals(ExtendedPoint.ZERO);
|
|
9763
|
+
}
|
|
9764
|
+
isTorsionFree() {
|
|
9765
|
+
let p = this.multiplyUnsafe(CURVE$1.l / _2n$6).double();
|
|
9766
|
+
if (CURVE$1.l % _2n$6)
|
|
9767
|
+
p = p.add(this);
|
|
9768
|
+
return p.equals(ExtendedPoint.ZERO);
|
|
9769
|
+
}
|
|
9770
|
+
toAffine(invZ) {
|
|
9771
|
+
const { x, y, z } = this;
|
|
9772
|
+
const is0 = this.equals(ExtendedPoint.ZERO);
|
|
9773
|
+
if (invZ == null)
|
|
9774
|
+
invZ = is0 ? _8n$2 : invert$1(z);
|
|
9775
|
+
const ax = mod$2(x * invZ);
|
|
9776
|
+
const ay = mod$2(y * invZ);
|
|
9777
|
+
const zz = mod$2(z * invZ);
|
|
9778
|
+
if (is0)
|
|
9779
|
+
return Point.ZERO;
|
|
9780
|
+
if (zz !== _1n$a)
|
|
9781
|
+
throw new Error('invZ was invalid');
|
|
9782
|
+
return new Point(ax, ay);
|
|
9783
|
+
}
|
|
9784
|
+
fromRistrettoBytes() {
|
|
9785
|
+
legacyRist();
|
|
9786
|
+
}
|
|
9787
|
+
toRistrettoBytes() {
|
|
9788
|
+
legacyRist();
|
|
9789
|
+
}
|
|
9790
|
+
fromRistrettoHash() {
|
|
9791
|
+
legacyRist();
|
|
9792
|
+
}
|
|
9793
|
+
}
|
|
9794
|
+
ExtendedPoint.BASE = new ExtendedPoint(CURVE$1.Gx, CURVE$1.Gy, _1n$a, mod$2(CURVE$1.Gx * CURVE$1.Gy));
|
|
9795
|
+
ExtendedPoint.ZERO = new ExtendedPoint(_0n$8, _1n$a, _1n$a, _0n$8);
|
|
9796
|
+
function constTimeNegate(condition, item) {
|
|
9797
|
+
const neg = item.negate();
|
|
9798
|
+
return condition ? neg : item;
|
|
9799
|
+
}
|
|
9800
|
+
function assertExtPoint(other) {
|
|
9801
|
+
if (!(other instanceof ExtendedPoint))
|
|
9802
|
+
throw new TypeError('ExtendedPoint expected');
|
|
9803
|
+
}
|
|
9804
|
+
function assertRstPoint(other) {
|
|
9805
|
+
if (!(other instanceof RistrettoPoint))
|
|
9806
|
+
throw new TypeError('RistrettoPoint expected');
|
|
9807
|
+
}
|
|
9808
|
+
function legacyRist() {
|
|
9809
|
+
throw new Error('Legacy method: switch to RistrettoPoint');
|
|
9810
|
+
}
|
|
9811
|
+
class RistrettoPoint {
|
|
9812
|
+
constructor(ep) {
|
|
9813
|
+
this.ep = ep;
|
|
9814
|
+
}
|
|
9815
|
+
static calcElligatorRistrettoMap(r0) {
|
|
9816
|
+
const { d } = CURVE$1;
|
|
9817
|
+
const r = mod$2(SQRT_M1 * r0 * r0);
|
|
9818
|
+
const Ns = mod$2((r + _1n$a) * ONE_MINUS_D_SQ);
|
|
9819
|
+
let c = BigInt(-1);
|
|
9820
|
+
const D = mod$2((c - d * r) * mod$2(r + d));
|
|
9821
|
+
let { isValid: Ns_D_is_sq, value: s } = uvRatio$1(Ns, D);
|
|
9822
|
+
let s_ = mod$2(s * r0);
|
|
9823
|
+
if (!edIsNegative(s_))
|
|
9824
|
+
s_ = mod$2(-s_);
|
|
9825
|
+
if (!Ns_D_is_sq)
|
|
9826
|
+
s = s_;
|
|
9827
|
+
if (!Ns_D_is_sq)
|
|
9828
|
+
c = r;
|
|
9829
|
+
const Nt = mod$2(c * (r - _1n$a) * D_MINUS_ONE_SQ - D);
|
|
9830
|
+
const s2 = s * s;
|
|
9831
|
+
const W0 = mod$2((s + s) * D);
|
|
9832
|
+
const W1 = mod$2(Nt * SQRT_AD_MINUS_ONE);
|
|
9833
|
+
const W2 = mod$2(_1n$a - s2);
|
|
9834
|
+
const W3 = mod$2(_1n$a + s2);
|
|
9835
|
+
return new ExtendedPoint(mod$2(W0 * W3), mod$2(W2 * W1), mod$2(W1 * W3), mod$2(W0 * W2));
|
|
9836
|
+
}
|
|
9837
|
+
static hashToCurve(hex) {
|
|
9838
|
+
hex = ensureBytes$1(hex, 64);
|
|
9839
|
+
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
|
9840
|
+
const R1 = this.calcElligatorRistrettoMap(r1);
|
|
9841
|
+
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
|
9842
|
+
const R2 = this.calcElligatorRistrettoMap(r2);
|
|
9843
|
+
return new RistrettoPoint(R1.add(R2));
|
|
9844
|
+
}
|
|
9845
|
+
static fromHex(hex) {
|
|
9846
|
+
hex = ensureBytes$1(hex, 32);
|
|
9847
|
+
const { a, d } = CURVE$1;
|
|
9848
|
+
const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
|
|
9849
|
+
const s = bytes255ToNumberLE(hex);
|
|
9850
|
+
if (!equalBytes$1(numberTo32BytesLE(s), hex) || edIsNegative(s))
|
|
9851
|
+
throw new Error(emsg);
|
|
9852
|
+
const s2 = mod$2(s * s);
|
|
9853
|
+
const u1 = mod$2(_1n$a + a * s2);
|
|
9854
|
+
const u2 = mod$2(_1n$a - a * s2);
|
|
9855
|
+
const u1_2 = mod$2(u1 * u1);
|
|
9856
|
+
const u2_2 = mod$2(u2 * u2);
|
|
9857
|
+
const v = mod$2(a * d * u1_2 - u2_2);
|
|
9858
|
+
const { isValid, value: I } = invertSqrt(mod$2(v * u2_2));
|
|
9859
|
+
const Dx = mod$2(I * u2);
|
|
9860
|
+
const Dy = mod$2(I * Dx * v);
|
|
9861
|
+
let x = mod$2((s + s) * Dx);
|
|
9862
|
+
if (edIsNegative(x))
|
|
9863
|
+
x = mod$2(-x);
|
|
9864
|
+
const y = mod$2(u1 * Dy);
|
|
9865
|
+
const t = mod$2(x * y);
|
|
9866
|
+
if (!isValid || edIsNegative(t) || y === _0n$8)
|
|
9867
|
+
throw new Error(emsg);
|
|
9868
|
+
return new RistrettoPoint(new ExtendedPoint(x, y, _1n$a, t));
|
|
9869
|
+
}
|
|
9870
|
+
toRawBytes() {
|
|
9871
|
+
let { x, y, z, t } = this.ep;
|
|
9872
|
+
const u1 = mod$2(mod$2(z + y) * mod$2(z - y));
|
|
9873
|
+
const u2 = mod$2(x * y);
|
|
9874
|
+
const u2sq = mod$2(u2 * u2);
|
|
9875
|
+
const { value: invsqrt } = invertSqrt(mod$2(u1 * u2sq));
|
|
9876
|
+
const D1 = mod$2(invsqrt * u1);
|
|
9877
|
+
const D2 = mod$2(invsqrt * u2);
|
|
9878
|
+
const zInv = mod$2(D1 * D2 * t);
|
|
9879
|
+
let D;
|
|
9880
|
+
if (edIsNegative(t * zInv)) {
|
|
9881
|
+
let _x = mod$2(y * SQRT_M1);
|
|
9882
|
+
let _y = mod$2(x * SQRT_M1);
|
|
9883
|
+
x = _x;
|
|
9884
|
+
y = _y;
|
|
9885
|
+
D = mod$2(D1 * INVSQRT_A_MINUS_D);
|
|
9886
|
+
}
|
|
9887
|
+
else {
|
|
9888
|
+
D = D2;
|
|
9889
|
+
}
|
|
9890
|
+
if (edIsNegative(x * zInv))
|
|
9891
|
+
y = mod$2(-y);
|
|
9892
|
+
let s = mod$2((z - y) * D);
|
|
9893
|
+
if (edIsNegative(s))
|
|
9894
|
+
s = mod$2(-s);
|
|
9895
|
+
return numberTo32BytesLE(s);
|
|
9896
|
+
}
|
|
9897
|
+
toHex() {
|
|
9898
|
+
return bytesToHex$1(this.toRawBytes());
|
|
9899
|
+
}
|
|
9900
|
+
toString() {
|
|
9901
|
+
return this.toHex();
|
|
9902
|
+
}
|
|
9903
|
+
equals(other) {
|
|
9904
|
+
assertRstPoint(other);
|
|
9905
|
+
const a = this.ep;
|
|
9906
|
+
const b = other.ep;
|
|
9907
|
+
const one = mod$2(a.x * b.y) === mod$2(a.y * b.x);
|
|
9908
|
+
const two = mod$2(a.y * b.y) === mod$2(a.x * b.x);
|
|
9909
|
+
return one || two;
|
|
9910
|
+
}
|
|
9911
|
+
add(other) {
|
|
9912
|
+
assertRstPoint(other);
|
|
9913
|
+
return new RistrettoPoint(this.ep.add(other.ep));
|
|
9914
|
+
}
|
|
9915
|
+
subtract(other) {
|
|
9916
|
+
assertRstPoint(other);
|
|
9917
|
+
return new RistrettoPoint(this.ep.subtract(other.ep));
|
|
9918
|
+
}
|
|
9919
|
+
multiply(scalar) {
|
|
9920
|
+
return new RistrettoPoint(this.ep.multiply(scalar));
|
|
9921
|
+
}
|
|
9922
|
+
multiplyUnsafe(scalar) {
|
|
9923
|
+
return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
|
|
9924
|
+
}
|
|
9925
|
+
}
|
|
9926
|
+
RistrettoPoint.BASE = new RistrettoPoint(ExtendedPoint.BASE);
|
|
9927
|
+
RistrettoPoint.ZERO = new RistrettoPoint(ExtendedPoint.ZERO);
|
|
9928
|
+
const pointPrecomputes = new WeakMap();
|
|
9929
|
+
class Point {
|
|
9930
|
+
constructor(x, y) {
|
|
9931
|
+
this.x = x;
|
|
9932
|
+
this.y = y;
|
|
9933
|
+
}
|
|
9934
|
+
_setWindowSize(windowSize) {
|
|
9935
|
+
this._WINDOW_SIZE = windowSize;
|
|
9936
|
+
pointPrecomputes.delete(this);
|
|
9937
|
+
}
|
|
9938
|
+
static fromHex(hex, strict = true) {
|
|
9939
|
+
const { d, P } = CURVE$1;
|
|
9940
|
+
hex = ensureBytes$1(hex, 32);
|
|
9941
|
+
const normed = hex.slice();
|
|
9942
|
+
normed[31] = hex[31] & ~0x80;
|
|
9943
|
+
const y = bytesToNumberLE$1(normed);
|
|
9944
|
+
if (strict && y >= P)
|
|
9945
|
+
throw new Error('Expected 0 < hex < P');
|
|
9946
|
+
if (!strict && y >= POW_2_256)
|
|
9947
|
+
throw new Error('Expected 0 < hex < 2**256');
|
|
9948
|
+
const y2 = mod$2(y * y);
|
|
9949
|
+
const u = mod$2(y2 - _1n$a);
|
|
9950
|
+
const v = mod$2(d * y2 + _1n$a);
|
|
9951
|
+
let { isValid, value: x } = uvRatio$1(u, v);
|
|
9952
|
+
if (!isValid)
|
|
9953
|
+
throw new Error('Point.fromHex: invalid y coordinate');
|
|
9954
|
+
const isXOdd = (x & _1n$a) === _1n$a;
|
|
9955
|
+
const isLastByteOdd = (hex[31] & 0x80) !== 0;
|
|
9956
|
+
if (isLastByteOdd !== isXOdd) {
|
|
9957
|
+
x = mod$2(-x);
|
|
9958
|
+
}
|
|
9959
|
+
return new Point(x, y);
|
|
9960
|
+
}
|
|
9961
|
+
static async fromPrivateKey(privateKey) {
|
|
9962
|
+
return (await getExtendedPublicKey(privateKey)).point;
|
|
9963
|
+
}
|
|
9964
|
+
toRawBytes() {
|
|
9965
|
+
const bytes = numberTo32BytesLE(this.y);
|
|
9966
|
+
bytes[31] |= this.x & _1n$a ? 0x80 : 0;
|
|
9967
|
+
return bytes;
|
|
9968
|
+
}
|
|
9969
|
+
toHex() {
|
|
9970
|
+
return bytesToHex$1(this.toRawBytes());
|
|
9971
|
+
}
|
|
9972
|
+
toX25519() {
|
|
9973
|
+
const { y } = this;
|
|
9974
|
+
const u = mod$2((_1n$a + y) * invert$1(_1n$a - y));
|
|
9975
|
+
return numberTo32BytesLE(u);
|
|
9976
|
+
}
|
|
9977
|
+
isTorsionFree() {
|
|
9978
|
+
return ExtendedPoint.fromAffine(this).isTorsionFree();
|
|
9979
|
+
}
|
|
9980
|
+
equals(other) {
|
|
9981
|
+
return this.x === other.x && this.y === other.y;
|
|
9982
|
+
}
|
|
9983
|
+
negate() {
|
|
9984
|
+
return new Point(mod$2(-this.x), this.y);
|
|
9985
|
+
}
|
|
9986
|
+
add(other) {
|
|
9987
|
+
return ExtendedPoint.fromAffine(this).add(ExtendedPoint.fromAffine(other)).toAffine();
|
|
9988
|
+
}
|
|
9989
|
+
subtract(other) {
|
|
9990
|
+
return this.add(other.negate());
|
|
9991
|
+
}
|
|
9992
|
+
multiply(scalar) {
|
|
9993
|
+
return ExtendedPoint.fromAffine(this).multiply(scalar, this).toAffine();
|
|
9994
|
+
}
|
|
9995
|
+
}
|
|
9996
|
+
Point.BASE = new Point(CURVE$1.Gx, CURVE$1.Gy);
|
|
9997
|
+
Point.ZERO = new Point(_0n$8, _1n$a);
|
|
9998
|
+
let Signature$1 = class Signature {
|
|
9999
|
+
constructor(r, s) {
|
|
10000
|
+
this.r = r;
|
|
10001
|
+
this.s = s;
|
|
10002
|
+
this.assertValidity();
|
|
10003
|
+
}
|
|
10004
|
+
static fromHex(hex) {
|
|
10005
|
+
const bytes = ensureBytes$1(hex, 64);
|
|
10006
|
+
const r = Point.fromHex(bytes.slice(0, 32), false);
|
|
10007
|
+
const s = bytesToNumberLE$1(bytes.slice(32, 64));
|
|
10008
|
+
return new Signature(r, s);
|
|
10009
|
+
}
|
|
10010
|
+
assertValidity() {
|
|
10011
|
+
const { r, s } = this;
|
|
10012
|
+
if (!(r instanceof Point))
|
|
10013
|
+
throw new Error('Expected Point instance');
|
|
10014
|
+
normalizeScalar(s, CURVE$1.l, false);
|
|
10015
|
+
return this;
|
|
10016
|
+
}
|
|
10017
|
+
toRawBytes() {
|
|
10018
|
+
const u8 = new Uint8Array(64);
|
|
10019
|
+
u8.set(this.r.toRawBytes());
|
|
10020
|
+
u8.set(numberTo32BytesLE(this.s), 32);
|
|
10021
|
+
return u8;
|
|
10022
|
+
}
|
|
10023
|
+
toHex() {
|
|
10024
|
+
return bytesToHex$1(this.toRawBytes());
|
|
10025
|
+
}
|
|
10026
|
+
};
|
|
10027
|
+
function concatBytes$2(...arrays) {
|
|
10028
|
+
if (!arrays.every((a) => a instanceof Uint8Array))
|
|
10029
|
+
throw new Error('Expected Uint8Array list');
|
|
10030
|
+
if (arrays.length === 1)
|
|
10031
|
+
return arrays[0];
|
|
10032
|
+
const length = arrays.reduce((a, arr) => a + arr.length, 0);
|
|
10033
|
+
const result = new Uint8Array(length);
|
|
10034
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
10035
|
+
const arr = arrays[i];
|
|
10036
|
+
result.set(arr, pad);
|
|
10037
|
+
pad += arr.length;
|
|
10038
|
+
}
|
|
10039
|
+
return result;
|
|
10040
|
+
}
|
|
10041
|
+
const hexes$1 = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
|
|
10042
|
+
function bytesToHex$1(uint8a) {
|
|
10043
|
+
if (!(uint8a instanceof Uint8Array))
|
|
10044
|
+
throw new Error('Uint8Array expected');
|
|
10045
|
+
let hex = '';
|
|
10046
|
+
for (let i = 0; i < uint8a.length; i++) {
|
|
10047
|
+
hex += hexes$1[uint8a[i]];
|
|
10048
|
+
}
|
|
10049
|
+
return hex;
|
|
10050
|
+
}
|
|
10051
|
+
function hexToBytes$1(hex) {
|
|
10052
|
+
if (typeof hex !== 'string') {
|
|
10053
|
+
throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
|
|
10054
|
+
}
|
|
10055
|
+
if (hex.length % 2)
|
|
10056
|
+
throw new Error('hexToBytes: received invalid unpadded hex');
|
|
10057
|
+
const array = new Uint8Array(hex.length / 2);
|
|
10058
|
+
for (let i = 0; i < array.length; i++) {
|
|
10059
|
+
const j = i * 2;
|
|
10060
|
+
const hexByte = hex.slice(j, j + 2);
|
|
10061
|
+
const byte = Number.parseInt(hexByte, 16);
|
|
10062
|
+
if (Number.isNaN(byte) || byte < 0)
|
|
10063
|
+
throw new Error('Invalid byte sequence');
|
|
10064
|
+
array[i] = byte;
|
|
10065
|
+
}
|
|
10066
|
+
return array;
|
|
10067
|
+
}
|
|
10068
|
+
function numberTo32BytesBE(num) {
|
|
10069
|
+
const length = 32;
|
|
10070
|
+
const hex = num.toString(16).padStart(length * 2, '0');
|
|
10071
|
+
return hexToBytes$1(hex);
|
|
10072
|
+
}
|
|
10073
|
+
function numberTo32BytesLE(num) {
|
|
10074
|
+
return numberTo32BytesBE(num).reverse();
|
|
10075
|
+
}
|
|
10076
|
+
function edIsNegative(num) {
|
|
10077
|
+
return (mod$2(num) & _1n$a) === _1n$a;
|
|
10078
|
+
}
|
|
10079
|
+
function bytesToNumberLE$1(uint8a) {
|
|
10080
|
+
if (!(uint8a instanceof Uint8Array))
|
|
10081
|
+
throw new Error('Expected Uint8Array');
|
|
10082
|
+
return BigInt('0x' + bytesToHex$1(Uint8Array.from(uint8a).reverse()));
|
|
10083
|
+
}
|
|
10084
|
+
const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
|
10085
|
+
function bytes255ToNumberLE(bytes) {
|
|
10086
|
+
return mod$2(bytesToNumberLE$1(bytes) & MAX_255B);
|
|
10087
|
+
}
|
|
10088
|
+
function mod$2(a, b = CURVE$1.P) {
|
|
10089
|
+
const res = a % b;
|
|
10090
|
+
return res >= _0n$8 ? res : b + res;
|
|
10091
|
+
}
|
|
10092
|
+
function invert$1(number, modulo = CURVE$1.P) {
|
|
10093
|
+
if (number === _0n$8 || modulo <= _0n$8) {
|
|
10094
|
+
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
|
10095
|
+
}
|
|
10096
|
+
let a = mod$2(number, modulo);
|
|
10097
|
+
let b = modulo;
|
|
10098
|
+
let x = _0n$8, u = _1n$a;
|
|
10099
|
+
while (a !== _0n$8) {
|
|
10100
|
+
const q = b / a;
|
|
10101
|
+
const r = b % a;
|
|
10102
|
+
const m = x - u * q;
|
|
10103
|
+
b = a, a = r, x = u, u = m;
|
|
10104
|
+
}
|
|
10105
|
+
const gcd = b;
|
|
10106
|
+
if (gcd !== _1n$a)
|
|
10107
|
+
throw new Error('invert: does not exist');
|
|
10108
|
+
return mod$2(x, modulo);
|
|
10109
|
+
}
|
|
10110
|
+
function invertBatch(nums, p = CURVE$1.P) {
|
|
10111
|
+
const tmp = new Array(nums.length);
|
|
10112
|
+
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
10113
|
+
if (num === _0n$8)
|
|
10114
|
+
return acc;
|
|
10115
|
+
tmp[i] = acc;
|
|
10116
|
+
return mod$2(acc * num, p);
|
|
10117
|
+
}, _1n$a);
|
|
10118
|
+
const inverted = invert$1(lastMultiplied, p);
|
|
10119
|
+
nums.reduceRight((acc, num, i) => {
|
|
10120
|
+
if (num === _0n$8)
|
|
10121
|
+
return acc;
|
|
10122
|
+
tmp[i] = mod$2(acc * tmp[i], p);
|
|
10123
|
+
return mod$2(acc * num, p);
|
|
10124
|
+
}, inverted);
|
|
10125
|
+
return tmp;
|
|
10126
|
+
}
|
|
10127
|
+
function pow2$1(x, power) {
|
|
10128
|
+
const { P } = CURVE$1;
|
|
10129
|
+
let res = x;
|
|
10130
|
+
while (power-- > _0n$8) {
|
|
10131
|
+
res *= res;
|
|
10132
|
+
res %= P;
|
|
10133
|
+
}
|
|
10134
|
+
return res;
|
|
10135
|
+
}
|
|
10136
|
+
function pow_2_252_3(x) {
|
|
10137
|
+
const { P } = CURVE$1;
|
|
10138
|
+
const _5n = BigInt(5);
|
|
10139
|
+
const _10n = BigInt(10);
|
|
10140
|
+
const _20n = BigInt(20);
|
|
10141
|
+
const _40n = BigInt(40);
|
|
10142
|
+
const _80n = BigInt(80);
|
|
10143
|
+
const x2 = (x * x) % P;
|
|
10144
|
+
const b2 = (x2 * x) % P;
|
|
10145
|
+
const b4 = (pow2$1(b2, _2n$6) * b2) % P;
|
|
10146
|
+
const b5 = (pow2$1(b4, _1n$a) * x) % P;
|
|
10147
|
+
const b10 = (pow2$1(b5, _5n) * b5) % P;
|
|
10148
|
+
const b20 = (pow2$1(b10, _10n) * b10) % P;
|
|
10149
|
+
const b40 = (pow2$1(b20, _20n) * b20) % P;
|
|
10150
|
+
const b80 = (pow2$1(b40, _40n) * b40) % P;
|
|
10151
|
+
const b160 = (pow2$1(b80, _80n) * b80) % P;
|
|
10152
|
+
const b240 = (pow2$1(b160, _80n) * b80) % P;
|
|
10153
|
+
const b250 = (pow2$1(b240, _10n) * b10) % P;
|
|
10154
|
+
const pow_p_5_8 = (pow2$1(b250, _2n$6) * x) % P;
|
|
10155
|
+
return { pow_p_5_8, b2 };
|
|
10156
|
+
}
|
|
10157
|
+
function uvRatio$1(u, v) {
|
|
10158
|
+
const v3 = mod$2(v * v * v);
|
|
10159
|
+
const v7 = mod$2(v3 * v3 * v);
|
|
10160
|
+
const pow = pow_2_252_3(u * v7).pow_p_5_8;
|
|
10161
|
+
let x = mod$2(u * v3 * pow);
|
|
10162
|
+
const vx2 = mod$2(v * x * x);
|
|
10163
|
+
const root1 = x;
|
|
10164
|
+
const root2 = mod$2(x * SQRT_M1);
|
|
10165
|
+
const useRoot1 = vx2 === u;
|
|
10166
|
+
const useRoot2 = vx2 === mod$2(-u);
|
|
10167
|
+
const noRoot = vx2 === mod$2(-u * SQRT_M1);
|
|
10168
|
+
if (useRoot1)
|
|
10169
|
+
x = root1;
|
|
10170
|
+
if (useRoot2 || noRoot)
|
|
10171
|
+
x = root2;
|
|
10172
|
+
if (edIsNegative(x))
|
|
10173
|
+
x = mod$2(-x);
|
|
10174
|
+
return { isValid: useRoot1 || useRoot2, value: x };
|
|
10175
|
+
}
|
|
10176
|
+
function invertSqrt(number) {
|
|
10177
|
+
return uvRatio$1(_1n$a, number);
|
|
10178
|
+
}
|
|
10179
|
+
function modlLE(hash) {
|
|
10180
|
+
return mod$2(bytesToNumberLE$1(hash), CURVE$1.l);
|
|
10181
|
+
}
|
|
10182
|
+
function equalBytes$1(b1, b2) {
|
|
10183
|
+
if (b1.length !== b2.length) {
|
|
10184
|
+
return false;
|
|
10185
|
+
}
|
|
10186
|
+
for (let i = 0; i < b1.length; i++) {
|
|
10187
|
+
if (b1[i] !== b2[i]) {
|
|
10188
|
+
return false;
|
|
10189
|
+
}
|
|
10190
|
+
}
|
|
10191
|
+
return true;
|
|
10192
|
+
}
|
|
10193
|
+
function ensureBytes$1(hex, expectedLength) {
|
|
10194
|
+
const bytes = hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes$1(hex);
|
|
10195
|
+
if (typeof expectedLength === 'number' && bytes.length !== expectedLength)
|
|
10196
|
+
throw new Error(`Expected ${expectedLength} bytes`);
|
|
10197
|
+
return bytes;
|
|
10198
|
+
}
|
|
10199
|
+
function normalizeScalar(num, max, strict = true) {
|
|
10200
|
+
if (!max)
|
|
10201
|
+
throw new TypeError('Specify max value');
|
|
10202
|
+
if (typeof num === 'number' && Number.isSafeInteger(num))
|
|
10203
|
+
num = BigInt(num);
|
|
10204
|
+
if (typeof num === 'bigint' && num < max) {
|
|
10205
|
+
if (strict) {
|
|
10206
|
+
if (_0n$8 < num)
|
|
10207
|
+
return num;
|
|
10208
|
+
}
|
|
10209
|
+
else {
|
|
10210
|
+
if (_0n$8 <= num)
|
|
10211
|
+
return num;
|
|
10212
|
+
}
|
|
10213
|
+
}
|
|
10214
|
+
throw new TypeError('Expected valid scalar: 0 < scalar < max');
|
|
10215
|
+
}
|
|
10216
|
+
function adjustBytes25519(bytes) {
|
|
10217
|
+
bytes[0] &= 248;
|
|
10218
|
+
bytes[31] &= 127;
|
|
10219
|
+
bytes[31] |= 64;
|
|
10220
|
+
return bytes;
|
|
10221
|
+
}
|
|
10222
|
+
function checkPrivateKey(key) {
|
|
10223
|
+
key =
|
|
10224
|
+
typeof key === 'bigint' || typeof key === 'number'
|
|
10225
|
+
? numberTo32BytesBE(normalizeScalar(key, POW_2_256))
|
|
10226
|
+
: ensureBytes$1(key);
|
|
10227
|
+
if (key.length !== 32)
|
|
10228
|
+
throw new Error(`Expected 32 bytes`);
|
|
10229
|
+
return key;
|
|
10230
|
+
}
|
|
10231
|
+
function getKeyFromHash(hashed) {
|
|
10232
|
+
const head = adjustBytes25519(hashed.slice(0, 32));
|
|
10233
|
+
const prefix = hashed.slice(32, 64);
|
|
10234
|
+
const scalar = modlLE(head);
|
|
10235
|
+
const point = Point.BASE.multiply(scalar);
|
|
10236
|
+
const pointBytes = point.toRawBytes();
|
|
10237
|
+
return { head, prefix, scalar, point, pointBytes };
|
|
10238
|
+
}
|
|
10239
|
+
let _sha512Sync;
|
|
10240
|
+
async function getExtendedPublicKey(key) {
|
|
10241
|
+
return getKeyFromHash(await utils.sha512(checkPrivateKey(key)));
|
|
10242
|
+
}
|
|
10243
|
+
function prepareVerification(sig, message, publicKey) {
|
|
10244
|
+
message = ensureBytes$1(message);
|
|
10245
|
+
if (!(publicKey instanceof Point))
|
|
10246
|
+
publicKey = Point.fromHex(publicKey, false);
|
|
10247
|
+
const { r, s } = sig instanceof Signature$1 ? sig.assertValidity() : Signature$1.fromHex(sig);
|
|
10248
|
+
const SB = ExtendedPoint.BASE.multiplyUnsafe(s);
|
|
10249
|
+
return { r, s, SB, pub: publicKey, msg: message };
|
|
10250
|
+
}
|
|
10251
|
+
function finishVerification(publicKey, r, SB, hashed) {
|
|
10252
|
+
const k = modlLE(hashed);
|
|
10253
|
+
const kA = ExtendedPoint.fromAffine(publicKey).multiplyUnsafe(k);
|
|
10254
|
+
const RkA = ExtendedPoint.fromAffine(r).add(kA);
|
|
10255
|
+
return RkA.subtract(SB).multiplyUnsafe(CURVE$1.h).equals(ExtendedPoint.ZERO);
|
|
10256
|
+
}
|
|
10257
|
+
async function verify$6(sig, message, publicKey) {
|
|
10258
|
+
const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
|
|
10259
|
+
const hashed = await utils.sha512(r.toRawBytes(), pub.toRawBytes(), msg);
|
|
10260
|
+
return finishVerification(pub, r, SB, hashed);
|
|
10261
|
+
}
|
|
10262
|
+
Point.BASE._setWindowSize(8);
|
|
10263
|
+
const crypto$3 = {
|
|
10264
|
+
node: nodeCrypto$2,
|
|
10265
|
+
web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
|
|
10266
|
+
};
|
|
10267
|
+
const utils = {
|
|
10268
|
+
bytesToHex: bytesToHex$1,
|
|
10269
|
+
hexToBytes: hexToBytes$1,
|
|
10270
|
+
concatBytes: concatBytes$2,
|
|
10271
|
+
getExtendedPublicKey,
|
|
10272
|
+
mod: mod$2,
|
|
10273
|
+
invert: invert$1,
|
|
10274
|
+
TORSION_SUBGROUP: [
|
|
10275
|
+
'0100000000000000000000000000000000000000000000000000000000000000',
|
|
10276
|
+
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',
|
|
10277
|
+
'0000000000000000000000000000000000000000000000000000000000000080',
|
|
10278
|
+
'26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',
|
|
10279
|
+
'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
|
10280
|
+
'26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',
|
|
10281
|
+
'0000000000000000000000000000000000000000000000000000000000000000',
|
|
10282
|
+
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
|
|
10283
|
+
],
|
|
10284
|
+
hashToPrivateScalar: (hash) => {
|
|
10285
|
+
hash = ensureBytes$1(hash);
|
|
10286
|
+
if (hash.length < 40 || hash.length > 1024)
|
|
10287
|
+
throw new Error('Expected 40-1024 bytes of private key as per FIPS 186');
|
|
10288
|
+
return mod$2(bytesToNumberLE$1(hash), CURVE$1.l - _1n$a) + _1n$a;
|
|
10289
|
+
},
|
|
10290
|
+
randomBytes: (bytesLength = 32) => {
|
|
10291
|
+
if (crypto$3.web) {
|
|
10292
|
+
return crypto$3.web.getRandomValues(new Uint8Array(bytesLength));
|
|
10293
|
+
}
|
|
10294
|
+
else {
|
|
10295
|
+
throw new Error("The environment doesn't have randomBytes function");
|
|
10296
|
+
}
|
|
10297
|
+
},
|
|
10298
|
+
randomPrivateKey: () => {
|
|
10299
|
+
return utils.randomBytes(32);
|
|
10300
|
+
},
|
|
10301
|
+
sha512: async (...messages) => {
|
|
10302
|
+
const message = concatBytes$2(...messages);
|
|
10303
|
+
if (crypto$3.web) {
|
|
10304
|
+
const buffer = await crypto$3.web.subtle.digest('SHA-512', message.buffer);
|
|
10305
|
+
return new Uint8Array(buffer);
|
|
10306
|
+
}
|
|
10307
|
+
else {
|
|
10308
|
+
throw new Error("The environment doesn't have sha512 function");
|
|
10309
|
+
}
|
|
10310
|
+
},
|
|
10311
|
+
precompute(windowSize = 8, point = Point.BASE) {
|
|
10312
|
+
const cached = point.equals(Point.BASE) ? point : new Point(point.x, point.y);
|
|
10313
|
+
cached._setWindowSize(windowSize);
|
|
10314
|
+
cached.multiply(_2n$6);
|
|
10315
|
+
return cached;
|
|
10316
|
+
},
|
|
10317
|
+
sha512Sync: undefined,
|
|
10318
|
+
};
|
|
10319
|
+
Object.defineProperties(utils, {
|
|
10320
|
+
sha512Sync: {
|
|
10321
|
+
configurable: false,
|
|
10322
|
+
get() {
|
|
10323
|
+
return _sha512Sync;
|
|
10324
|
+
},
|
|
10325
|
+
set(val) {
|
|
10326
|
+
if (!_sha512Sync)
|
|
10327
|
+
_sha512Sync = val;
|
|
10328
|
+
},
|
|
10329
|
+
},
|
|
9529
10330
|
});
|
|
9530
10331
|
|
|
9531
10332
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -9561,6 +10362,8 @@ var ecdsa = /*#__PURE__*/Object.freeze({
|
|
|
9561
10362
|
* @async
|
|
9562
10363
|
*/
|
|
9563
10364
|
async function sign$5(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
10365
|
+
const curve = new CurveWithOID(oid);
|
|
10366
|
+
checkPublicPointEnconding(curve, publicKey);
|
|
9564
10367
|
if (hash$1.getHashByteLength(hashAlgo) < hash$1.getHashByteLength(enums.hash.sha256)) {
|
|
9565
10368
|
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
9566
10369
|
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
@@ -9587,11 +10390,13 @@ async function sign$5(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
9587
10390
|
* @async
|
|
9588
10391
|
*/
|
|
9589
10392
|
async function verify$5(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
|
10393
|
+
const curve = new CurveWithOID(oid);
|
|
10394
|
+
checkPublicPointEnconding(curve, publicKey);
|
|
9590
10395
|
if (hash$1.getHashByteLength(hashAlgo) < hash$1.getHashByteLength(enums.hash.sha256)) {
|
|
9591
10396
|
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
9592
10397
|
}
|
|
9593
10398
|
const signature = util.concatUint8Array([r, s]);
|
|
9594
|
-
return
|
|
10399
|
+
return verify$6(signature, hashed, publicKey.subarray(1));
|
|
9595
10400
|
}
|
|
9596
10401
|
/**
|
|
9597
10402
|
* Validate legacy EdDSA parameters
|
|
@@ -9717,7 +10522,7 @@ async function verify$4(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
|
9717
10522
|
}
|
|
9718
10523
|
switch (algo) {
|
|
9719
10524
|
case enums.publicKey.ed25519:
|
|
9720
|
-
return
|
|
10525
|
+
return verify$6(RS, hashed, publicKey);
|
|
9721
10526
|
case enums.publicKey.ed448: {
|
|
9722
10527
|
const ed448 = await util.getNobleCurve(enums.publicKey.ed448);
|
|
9723
10528
|
return ed448.verify(RS, hashed, publicKey);
|
|
@@ -10081,7 +10886,7 @@ function buildEcdhParam(public_algo, oid, kdfParams, fingerprint) {
|
|
|
10081
10886
|
new Uint8Array([public_algo]),
|
|
10082
10887
|
kdfParams.write(true),
|
|
10083
10888
|
util.stringToUint8Array('Anonymous Sender '),
|
|
10084
|
-
kdfParams.replacementFingerprint || fingerprint
|
|
10889
|
+
kdfParams.replacementFingerprint || fingerprint
|
|
10085
10890
|
]);
|
|
10086
10891
|
}
|
|
10087
10892
|
|
|
@@ -10123,7 +10928,7 @@ async function genPublicEphemeralKey(curve, Q) {
|
|
|
10123
10928
|
const d = getRandomBytes(32);
|
|
10124
10929
|
const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d);
|
|
10125
10930
|
let { publicKey } = nacl.box.keyPair.fromSecretKey(secretKey);
|
|
10126
|
-
publicKey = util.concatUint8Array([new Uint8Array([
|
|
10931
|
+
publicKey = util.concatUint8Array([new Uint8Array([curve.wireFormatLeadingByte]), publicKey]);
|
|
10127
10932
|
return { publicKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
|
|
10128
10933
|
}
|
|
10129
10934
|
case 'web':
|
|
@@ -10151,7 +10956,7 @@ async function genPublicEphemeralKey(curve, Q) {
|
|
|
10151
10956
|
* @param {module:type/kdf_params} kdfParams - KDF params including cipher and algorithm to use
|
|
10152
10957
|
* @param {Uint8Array} data - Unpadded session key data
|
|
10153
10958
|
* @param {Uint8Array} Q - Recipient public key
|
|
10154
|
-
* @param {Uint8Array} fingerprint - Recipient fingerprint
|
|
10959
|
+
* @param {Uint8Array} fingerprint - Recipient fingerprint, already truncated depending on the key version
|
|
10155
10960
|
* @returns {Promise<{publicKey: Uint8Array, wrappedKey: Uint8Array}>}
|
|
10156
10961
|
* @async
|
|
10157
10962
|
*/
|
|
@@ -10159,6 +10964,7 @@ async function encrypt$2(oid, kdfParams, data, Q, fingerprint) {
|
|
|
10159
10964
|
const m = encode(data);
|
|
10160
10965
|
|
|
10161
10966
|
const curve = new CurveWithOID(oid);
|
|
10967
|
+
checkPublicPointEnconding(curve, Q);
|
|
10162
10968
|
const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
|
|
10163
10969
|
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
|
|
10164
10970
|
const { keySize } = getCipherParams(kdfParams.cipher);
|
|
@@ -10215,12 +11021,14 @@ async function genPrivateEphemeralKey(curve, V, Q, d) {
|
|
|
10215
11021
|
* @param {Uint8Array} C - Encrypted and wrapped value derived from session key
|
|
10216
11022
|
* @param {Uint8Array} Q - Recipient public key
|
|
10217
11023
|
* @param {Uint8Array} d - Recipient private key
|
|
10218
|
-
* @param {Uint8Array} fingerprint - Recipient fingerprint
|
|
11024
|
+
* @param {Uint8Array} fingerprint - Recipient fingerprint, already truncated depending on the key version
|
|
10219
11025
|
* @returns {Promise<Uint8Array>} Value derived from session key.
|
|
10220
11026
|
* @async
|
|
10221
11027
|
*/
|
|
10222
11028
|
async function decrypt$2(oid, kdfParams, V, C, Q, d, fingerprint) {
|
|
10223
11029
|
const curve = new CurveWithOID(oid);
|
|
11030
|
+
checkPublicPointEnconding(curve, Q);
|
|
11031
|
+
checkPublicPointEnconding(curve, V);
|
|
10224
11032
|
const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
|
|
10225
11033
|
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
|
|
10226
11034
|
const { keySize } = getCipherParams(kdfParams.cipher);
|
|
@@ -10352,7 +11160,7 @@ async function webPublicEphemeralKey(curve, Q) {
|
|
|
10352
11160
|
);
|
|
10353
11161
|
[s, p] = await Promise.all([s, p]);
|
|
10354
11162
|
const sharedKey = new Uint8Array(s);
|
|
10355
|
-
const publicKey = new Uint8Array(jwkToRawPublic(p));
|
|
11163
|
+
const publicKey = new Uint8Array(jwkToRawPublic(p, curve.wireFormatLeadingByte));
|
|
10356
11164
|
return { publicKey, sharedKey };
|
|
10357
11165
|
}
|
|
10358
11166
|
|
|
@@ -10675,14 +11483,14 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
|
|
|
10675
11483
|
let r;
|
|
10676
11484
|
let s;
|
|
10677
11485
|
let t;
|
|
10678
|
-
g = mod$
|
|
10679
|
-
x = mod$
|
|
11486
|
+
g = mod$3(g, p);
|
|
11487
|
+
x = mod$3(x, q);
|
|
10680
11488
|
// If the output size of the chosen hash is larger than the number of
|
|
10681
11489
|
// bits of q, the hash result is truncated to fit by taking the number
|
|
10682
11490
|
// of leftmost bits equal to the number of bits of q. This (possibly
|
|
10683
11491
|
// truncated) hash function result is treated as a number and used
|
|
10684
11492
|
// directly in the DSA signature algorithm.
|
|
10685
|
-
const h = mod$
|
|
11493
|
+
const h = mod$3(uint8ArrayToBigInt(hashed.subarray(0, byteLength(q))), q);
|
|
10686
11494
|
// FIPS-186-4, section 4.6:
|
|
10687
11495
|
// The values of r and s shall be checked to determine if r = 0 or s = 0.
|
|
10688
11496
|
// If either r = 0 or s = 0, a new value of k shall be generated, and the
|
|
@@ -10691,13 +11499,13 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
|
|
|
10691
11499
|
while (true) {
|
|
10692
11500
|
// See Appendix B here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
|
|
10693
11501
|
k = getRandomBigInteger(_1n$9, q); // returns in [1, q-1]
|
|
10694
|
-
r = mod$
|
|
11502
|
+
r = mod$3(modExp(g, k, p), q); // (g**k mod p) mod q
|
|
10695
11503
|
if (r === _0n) {
|
|
10696
11504
|
continue;
|
|
10697
11505
|
}
|
|
10698
|
-
const xr = mod$
|
|
10699
|
-
t = mod$
|
|
10700
|
-
s = mod$
|
|
11506
|
+
const xr = mod$3(x * r, q);
|
|
11507
|
+
t = mod$3(h + xr, q); // H(m) + x*r mod q
|
|
11508
|
+
s = mod$3(modInv(k, q) * t, q); // k**-1 * (H(m) + x*r) mod q
|
|
10701
11509
|
if (s === _0n) {
|
|
10702
11510
|
continue;
|
|
10703
11511
|
}
|
|
@@ -10736,20 +11544,20 @@ async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
|
|
|
10736
11544
|
util.printDebug('invalid DSA Signature');
|
|
10737
11545
|
return false;
|
|
10738
11546
|
}
|
|
10739
|
-
const h = mod$
|
|
11547
|
+
const h = mod$3(uint8ArrayToBigInt(hashed.subarray(0, byteLength(q))), q);
|
|
10740
11548
|
const w = modInv(s, q); // s**-1 mod q
|
|
10741
11549
|
if (w === _0n$7) {
|
|
10742
11550
|
util.printDebug('invalid DSA Signature');
|
|
10743
11551
|
return false;
|
|
10744
11552
|
}
|
|
10745
11553
|
|
|
10746
|
-
g = mod$
|
|
10747
|
-
y = mod$
|
|
10748
|
-
const u1 = mod$
|
|
10749
|
-
const u2 = mod$
|
|
11554
|
+
g = mod$3(g, p);
|
|
11555
|
+
y = mod$3(y, p);
|
|
11556
|
+
const u1 = mod$3(h * w, q); // H(m) * w mod q
|
|
11557
|
+
const u2 = mod$3(r * w, q); // r * w mod q
|
|
10750
11558
|
const t1 = modExp(g, u1, p); // g**u1 mod p
|
|
10751
11559
|
const t2 = modExp(y, u2, p); // y**u2 mod p
|
|
10752
|
-
const v = mod$
|
|
11560
|
+
const v = mod$3(mod$3(t1 * t2, p), q); // (g**u1 * y**u2 mod p) mod q
|
|
10753
11561
|
return v === r;
|
|
10754
11562
|
}
|
|
10755
11563
|
|
|
@@ -10776,7 +11584,7 @@ async function validateParams$2(p, q, g, y, x) {
|
|
|
10776
11584
|
/**
|
|
10777
11585
|
* Check that subgroup order q divides p-1
|
|
10778
11586
|
*/
|
|
10779
|
-
if (mod$
|
|
11587
|
+
if (mod$3(p - _1n$9, q) !== _0n$7) {
|
|
10780
11588
|
return false;
|
|
10781
11589
|
}
|
|
10782
11590
|
|
|
@@ -11573,6 +12381,9 @@ function parsePublicKeyParams(algo, bytes) {
|
|
|
11573
12381
|
case enums.publicKey.eddsaLegacy: {
|
|
11574
12382
|
const oid = new OID(); read += oid.read(bytes);
|
|
11575
12383
|
checkSupportedCurve(oid);
|
|
12384
|
+
if (oid.getName() !== enums.curve.ed25519Legacy) {
|
|
12385
|
+
throw new Error('Unexpected OID for eddsaLegacy');
|
|
12386
|
+
}
|
|
11576
12387
|
let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
|
|
11577
12388
|
Q = util.leftPad(Q, 33);
|
|
11578
12389
|
return { read: read, publicParams: { oid, Q } };
|
|
@@ -11636,6 +12447,9 @@ function parsePrivateKeyParams(algo, bytes, publicParams) {
|
|
|
11636
12447
|
}
|
|
11637
12448
|
case enums.publicKey.eddsaLegacy: {
|
|
11638
12449
|
const payloadSize = getCurvePayloadSize(algo, publicParams.oid);
|
|
12450
|
+
if (publicParams.oid.getName() !== enums.curve.ed25519Legacy) {
|
|
12451
|
+
throw new Error('Unexpected OID for eddsaLegacy');
|
|
12452
|
+
}
|
|
11639
12453
|
let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2;
|
|
11640
12454
|
seed = util.leftPad(seed, payloadSize);
|
|
11641
12455
|
return { read, privateParams: { seed } };
|
|
@@ -14466,6 +15280,7 @@ class SignaturePacket {
|
|
|
14466
15280
|
|
|
14467
15281
|
this.signatureData = null;
|
|
14468
15282
|
this.unhashedSubpackets = [];
|
|
15283
|
+
this.unknownSubpackets = [];
|
|
14469
15284
|
this.signedHashValue = null;
|
|
14470
15285
|
this.salt = null;
|
|
14471
15286
|
|
|
@@ -14515,9 +15330,12 @@ class SignaturePacket {
|
|
|
14515
15330
|
* @param {String} bytes - Payload of a tag 2 packet
|
|
14516
15331
|
* @returns {SignaturePacket} Object representation.
|
|
14517
15332
|
*/
|
|
14518
|
-
read(bytes) {
|
|
15333
|
+
read(bytes, config$1 = config) {
|
|
14519
15334
|
let i = 0;
|
|
14520
15335
|
this.version = bytes[i++];
|
|
15336
|
+
if (this.version === 5 && !config$1.enableParsingV5Entities) {
|
|
15337
|
+
throw new UnsupportedError('Support for v5 entities is disabled; turn on `config.enableParsingV5Entities` if needed');
|
|
15338
|
+
}
|
|
14521
15339
|
|
|
14522
15340
|
if (this.version !== 4 && this.version !== 5 && this.version !== 6) {
|
|
14523
15341
|
throw new UnsupportedError(`Version ${this.version} of the signature packet is unsupported.`);
|
|
@@ -14794,10 +15612,8 @@ class SignaturePacket {
|
|
|
14794
15612
|
* @returns {Uint8Array} Subpacket data.
|
|
14795
15613
|
*/
|
|
14796
15614
|
writeUnhashedSubPackets() {
|
|
14797
|
-
const arr =
|
|
14798
|
-
|
|
14799
|
-
arr.push(writeSimpleLength(data.length));
|
|
14800
|
-
arr.push(data);
|
|
15615
|
+
const arr = this.unhashedSubpackets.map(({ type, critical, body }) => {
|
|
15616
|
+
return writeSubPacket(type, critical, body);
|
|
14801
15617
|
});
|
|
14802
15618
|
|
|
14803
15619
|
const result = util.concat(arr);
|
|
@@ -14806,7 +15622,7 @@ class SignaturePacket {
|
|
|
14806
15622
|
return util.concat([length, result]);
|
|
14807
15623
|
}
|
|
14808
15624
|
|
|
14809
|
-
//
|
|
15625
|
+
// Signature subpackets
|
|
14810
15626
|
readSubPacket(bytes, hashed = true) {
|
|
14811
15627
|
let mypos = 0;
|
|
14812
15628
|
|
|
@@ -14814,15 +15630,19 @@ class SignaturePacket {
|
|
|
14814
15630
|
const critical = !!(bytes[mypos] & 0x80);
|
|
14815
15631
|
const type = bytes[mypos] & 0x7F;
|
|
14816
15632
|
|
|
15633
|
+
mypos++;
|
|
15634
|
+
|
|
14817
15635
|
if (!hashed) {
|
|
14818
|
-
this.unhashedSubpackets.push(
|
|
15636
|
+
this.unhashedSubpackets.push({
|
|
15637
|
+
type,
|
|
15638
|
+
critical,
|
|
15639
|
+
body: bytes.subarray(mypos, bytes.length)
|
|
15640
|
+
});
|
|
14819
15641
|
if (!allowedUnhashedSubpackets.has(type)) {
|
|
14820
15642
|
return;
|
|
14821
15643
|
}
|
|
14822
15644
|
}
|
|
14823
15645
|
|
|
14824
|
-
mypos++;
|
|
14825
|
-
|
|
14826
15646
|
// subpacket type
|
|
14827
15647
|
switch (type) {
|
|
14828
15648
|
case enums.signatureSubpacket.signatureCreationTime:
|
|
@@ -14994,14 +15814,13 @@ class SignaturePacket {
|
|
|
14994
15814
|
this.preferredCipherSuites.push([bytes[i], bytes[i + 1]]);
|
|
14995
15815
|
}
|
|
14996
15816
|
break;
|
|
14997
|
-
default:
|
|
14998
|
-
|
|
14999
|
-
|
|
15000
|
-
|
|
15001
|
-
|
|
15002
|
-
|
|
15003
|
-
|
|
15004
|
-
}
|
|
15817
|
+
default:
|
|
15818
|
+
this.unknownSubpackets.push({
|
|
15819
|
+
type,
|
|
15820
|
+
critical,
|
|
15821
|
+
body: bytes.subarray(mypos, bytes.length)
|
|
15822
|
+
});
|
|
15823
|
+
break;
|
|
15005
15824
|
}
|
|
15006
15825
|
}
|
|
15007
15826
|
|
|
@@ -15201,6 +16020,11 @@ class SignaturePacket {
|
|
|
15201
16020
|
[enums.signature.binary, enums.signature.text].includes(this.signatureType)) {
|
|
15202
16021
|
throw new Error('Insecure message hash algorithm: ' + enums.read(enums.hash, this.hashAlgorithm).toUpperCase());
|
|
15203
16022
|
}
|
|
16023
|
+
this.unknownSubpackets.forEach(({ type, critical }) => {
|
|
16024
|
+
if (critical) {
|
|
16025
|
+
throw new Error(`Unknown critical signature subpacket type ${type}`);
|
|
16026
|
+
}
|
|
16027
|
+
});
|
|
15204
16028
|
this.rawNotations.forEach(({ name, critical }) => {
|
|
15205
16029
|
if (critical && (config$1.knownNotations.indexOf(name) < 0)) {
|
|
15206
16030
|
throw new Error(`Unknown critical notation: ${name}`);
|
|
@@ -16500,10 +17324,11 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
16500
17324
|
// No symmetric encryption algorithm identifier is passed to the public-key algorithm for a
|
|
16501
17325
|
// v6 PKESK packet, as it is included in the v2 SEIPD packet.
|
|
16502
17326
|
const sessionKeyAlgorithm = this.version === 3 ? this.sessionKeyAlgorithm : null;
|
|
17327
|
+
const fingerprint = key.version === 5 ? key.getFingerprintBytes().subarray(0, 20) : key.getFingerprintBytes();
|
|
16503
17328
|
const encoded = encodeSessionKey(this.version, algo, sessionKeyAlgorithm, this.sessionKey);
|
|
16504
17329
|
const privateParams = algo === enums.publicKey.aead ? key.privateParams : null;
|
|
16505
17330
|
this.encrypted = await mod$1.publicKeyEncrypt(
|
|
16506
|
-
algo, sessionKeyAlgorithm, key.publicParams, privateParams, encoded,
|
|
17331
|
+
algo, sessionKeyAlgorithm, key.publicParams, privateParams, encoded, fingerprint);
|
|
16507
17332
|
}
|
|
16508
17333
|
|
|
16509
17334
|
/**
|
|
@@ -16523,7 +17348,8 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
16523
17348
|
const randomPayload = randomSessionKey ?
|
|
16524
17349
|
encodeSessionKey(this.version, this.publicKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKey) :
|
|
16525
17350
|
null;
|
|
16526
|
-
const
|
|
17351
|
+
const fingerprint = key.version === 5 ? key.getFingerprintBytes().subarray(0, 20) : key.getFingerprintBytes();
|
|
17352
|
+
const decryptedData = await mod$1.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, fingerprint, randomPayload);
|
|
16527
17353
|
|
|
16528
17354
|
const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
|
|
16529
17355
|
|
|
@@ -16928,10 +17754,13 @@ class PublicKeyPacket {
|
|
|
16928
17754
|
* @returns {Object} This object with attributes set by the parser
|
|
16929
17755
|
* @async
|
|
16930
17756
|
*/
|
|
16931
|
-
async read(bytes) {
|
|
17757
|
+
async read(bytes, config$1 = config) {
|
|
16932
17758
|
let pos = 0;
|
|
16933
17759
|
// A one-octet version number (4, 5 or 6).
|
|
16934
17760
|
this.version = bytes[pos++];
|
|
17761
|
+
if (this.version === 5 && !config$1.enableParsingV5Entities) {
|
|
17762
|
+
throw new UnsupportedError('Support for parsing v5 entities is disabled; turn on `config.enableParsingV5Entities` if needed');
|
|
17763
|
+
}
|
|
16935
17764
|
|
|
16936
17765
|
if (this.version === 4 || this.version === 5 || this.version === 6) {
|
|
16937
17766
|
// - A four-octet number denoting the time that the key was created.
|
|
@@ -17523,7 +18352,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
17523
18352
|
*/
|
|
17524
18353
|
async read(bytes, config$1 = config) {
|
|
17525
18354
|
// - A Public-Key or Public-Subkey packet, as described above.
|
|
17526
|
-
let i = await this.readPublicKey(bytes);
|
|
18355
|
+
let i = await this.readPublicKey(bytes, config$1);
|
|
17527
18356
|
const startOfSecretKeyData = i;
|
|
17528
18357
|
|
|
17529
18358
|
// - One octet indicating string-to-key usage conventions. Zero
|
|
@@ -17813,13 +18642,13 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
17813
18642
|
|
|
17814
18643
|
if (config$1.aeadProtect) {
|
|
17815
18644
|
this.s2kUsage = 253;
|
|
17816
|
-
this.aead =
|
|
18645
|
+
this.aead = config$1.preferredAEADAlgorithm;
|
|
17817
18646
|
const mode = mod$1.getAEADMode(this.aead);
|
|
17818
18647
|
this.isLegacyAEAD = this.version === 5; // v4 is always re-encrypted with standard format instead.
|
|
17819
18648
|
this.usedModernAEAD = !this.isLegacyAEAD; // legacy AEAD does not guarantee integrity of public key material
|
|
17820
18649
|
|
|
17821
18650
|
const serializedPacketTag = writeTag(this.constructor.tag);
|
|
17822
|
-
const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag);
|
|
18651
|
+
const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag, this.isLegacyAEAD);
|
|
17823
18652
|
|
|
17824
18653
|
const modeInstance = await mode(this.symmetric, key);
|
|
17825
18654
|
this.iv = this.isLegacyAEAD ? mod$1.random.getRandomBytes(blockSize) : mod$1.random.getRandomBytes(mode.ivLength);
|
|
@@ -17989,6 +18818,12 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
17989
18818
|
* @returns encryption key
|
|
17990
18819
|
*/
|
|
17991
18820
|
async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadMode, serializedPacketTag, isLegacyAEAD) {
|
|
18821
|
+
if (s2k.type === 'argon2' && !aeadMode) {
|
|
18822
|
+
throw new Error('Using Argon2 S2K without AEAD is not allowed');
|
|
18823
|
+
}
|
|
18824
|
+
if (s2k.type === 'simple' && keyVersion === 6) {
|
|
18825
|
+
throw new Error('Using Simple S2K with version 6 keys is not allowed');
|
|
18826
|
+
}
|
|
17992
18827
|
const { keySize } = mod$1.getCipherParams(cipherAlgo);
|
|
17993
18828
|
const derivedKey = await s2k.produceKey(passphrase, keySize);
|
|
17994
18829
|
if (!aeadMode || keyVersion === 5 || isLegacyAEAD) {
|
|
@@ -18367,6 +19202,8 @@ async function generateSecretKey(options, config) {
|
|
|
18367
19202
|
* Returns the valid and non-expired signature that has the latest creation date, while ignoring signatures created in the future.
|
|
18368
19203
|
* @param {Array<SignaturePacket>} signatures - List of signatures
|
|
18369
19204
|
* @param {PublicKeyPacket|PublicSubkeyPacket} publicKey - Public key packet to verify the signature
|
|
19205
|
+
* @param {module:enums.signature} signatureType - Signature type to determine how to hash the data (NB: for userID signatures,
|
|
19206
|
+
* `enums.signatures.certGeneric` should be given regardless of the actual trust level)
|
|
18370
19207
|
* @param {Date} date - Use the given date instead of the current time
|
|
18371
19208
|
* @param {Object} config - full configuration
|
|
18372
19209
|
* @returns {Promise<SignaturePacket>} The latest valid signature.
|
|
@@ -18615,8 +19452,14 @@ async function isDataRevoked(primaryKey, signatureType, dataToVerify, revocation
|
|
|
18615
19452
|
// `verifyAllCertifications`.)
|
|
18616
19453
|
!signature || revocationSignature.issuerKeyID.equals(signature.issuerKeyID)
|
|
18617
19454
|
) {
|
|
19455
|
+
const isHardRevocation = ![
|
|
19456
|
+
enums.reasonForRevocation.keyRetired,
|
|
19457
|
+
enums.reasonForRevocation.keySuperseded,
|
|
19458
|
+
enums.reasonForRevocation.userIDInvalid
|
|
19459
|
+
].includes(revocationSignature.reasonForRevocationFlag);
|
|
19460
|
+
|
|
18618
19461
|
await revocationSignature.verify(
|
|
18619
|
-
key, signatureType, dataToVerify, date, false, config
|
|
19462
|
+
key, signatureType, dataToVerify, isHardRevocation ? null : date, false, config
|
|
18620
19463
|
);
|
|
18621
19464
|
|
|
18622
19465
|
// TODO get an identifier of the revoked object instead
|
|
@@ -20603,7 +21446,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
|
|
|
20603
21446
|
key: secretKeyPacket
|
|
20604
21447
|
};
|
|
20605
21448
|
const signatureProperties = secretKeyPacket.version !== 6 ? getKeySignatureProperties() : {};
|
|
20606
|
-
signatureProperties.signatureType = enums.signature.
|
|
21449
|
+
signatureProperties.signatureType = enums.signature.certPositive;
|
|
20607
21450
|
if (index === 0) {
|
|
20608
21451
|
signatureProperties.isPrimaryUserID = true;
|
|
20609
21452
|
}
|
|
@@ -22428,7 +23271,7 @@ async function verify({ message, verificationKeys, expectSigned = false, format
|
|
|
22428
23271
|
result.signatures = await message.verify(verificationKeys, date, config$1);
|
|
22429
23272
|
}
|
|
22430
23273
|
result.data = format === 'binary' ? message.getLiteralData() : message.getText();
|
|
22431
|
-
if (message.fromStream) linkStreams(result, message);
|
|
23274
|
+
if (message.fromStream && !signature) linkStreams(result, message);
|
|
22432
23275
|
if (expectSigned) {
|
|
22433
23276
|
if (result.signatures.length === 0) {
|
|
22434
23277
|
throw new Error('Message is not signed');
|