@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
|
@@ -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
|
|
@@ -3182,15 +3204,15 @@ function add32(a, b) {
|
|
|
3182
3204
|
|
|
3183
3205
|
|
|
3184
3206
|
const webCrypto$b = util.getWebCrypto();
|
|
3185
|
-
const nodeCrypto$
|
|
3186
|
-
const nodeCryptoHashes = nodeCrypto$
|
|
3207
|
+
const nodeCrypto$b = util.getNodeCrypto();
|
|
3208
|
+
const nodeCryptoHashes = nodeCrypto$b && nodeCrypto$b.getHashes();
|
|
3187
3209
|
|
|
3188
3210
|
function nodeHash(type) {
|
|
3189
|
-
if (!nodeCrypto$
|
|
3211
|
+
if (!nodeCrypto$b || !nodeCryptoHashes.includes(type)) {
|
|
3190
3212
|
return;
|
|
3191
3213
|
}
|
|
3192
3214
|
return async function (data) {
|
|
3193
|
-
const shasum = nodeCrypto$
|
|
3215
|
+
const shasum = nodeCrypto$b.createHash(type);
|
|
3194
3216
|
return transform(data, value => {
|
|
3195
3217
|
shasum.update(value);
|
|
3196
3218
|
}, () => new Uint8Array(shasum.digest()));
|
|
@@ -4537,9 +4559,9 @@ class AES_CFB {
|
|
|
4537
4559
|
|
|
4538
4560
|
|
|
4539
4561
|
const webCrypto$a = util.getWebCrypto();
|
|
4540
|
-
const nodeCrypto$
|
|
4562
|
+
const nodeCrypto$a = util.getNodeCrypto();
|
|
4541
4563
|
|
|
4542
|
-
const knownAlgos = nodeCrypto$
|
|
4564
|
+
const knownAlgos = nodeCrypto$a ? nodeCrypto$a.getCiphers() : [];
|
|
4543
4565
|
const nodeAlgos = {
|
|
4544
4566
|
idea: knownAlgos.includes('idea-cfb') ? 'idea-cfb' : undefined, /* Unused, not implemented */
|
|
4545
4567
|
tripledes: knownAlgos.includes('des-ede3-cfb') ? 'des-ede3-cfb' : undefined,
|
|
@@ -4605,7 +4627,7 @@ async function encrypt$5(algo, key, plaintext, iv, config) {
|
|
|
4605
4627
|
*/
|
|
4606
4628
|
async function decrypt$5(algo, key, ciphertext, iv) {
|
|
4607
4629
|
const algoName = enums.read(enums.symmetric, algo);
|
|
4608
|
-
if (nodeCrypto$
|
|
4630
|
+
if (nodeCrypto$a && nodeAlgos[algoName]) { // Node crypto library.
|
|
4609
4631
|
return nodeDecrypt$1(algo, key, ciphertext, iv);
|
|
4610
4632
|
}
|
|
4611
4633
|
if (util.isAES(algo)) {
|
|
@@ -4773,13 +4795,13 @@ function xorMut$1(a, b) {
|
|
|
4773
4795
|
|
|
4774
4796
|
function nodeEncrypt$1(algo, key, pt, iv) {
|
|
4775
4797
|
const algoName = enums.read(enums.symmetric, algo);
|
|
4776
|
-
const cipherObj = new nodeCrypto$
|
|
4798
|
+
const cipherObj = new nodeCrypto$a.createCipheriv(nodeAlgos[algoName], key, iv);
|
|
4777
4799
|
return transform(pt, value => new Uint8Array(cipherObj.update(value)));
|
|
4778
4800
|
}
|
|
4779
4801
|
|
|
4780
4802
|
function nodeDecrypt$1(algo, key, ct, iv) {
|
|
4781
4803
|
const algoName = enums.read(enums.symmetric, algo);
|
|
4782
|
-
const decipherObj = new nodeCrypto$
|
|
4804
|
+
const decipherObj = new nodeCrypto$a.createDecipheriv(nodeAlgos[algoName], key, iv);
|
|
4783
4805
|
return transform(ct, value => new Uint8Array(decipherObj.update(value)));
|
|
4784
4806
|
}
|
|
4785
4807
|
|
|
@@ -4872,7 +4894,7 @@ class AES_CBC {
|
|
|
4872
4894
|
|
|
4873
4895
|
|
|
4874
4896
|
const webCrypto$9 = util.getWebCrypto();
|
|
4875
|
-
const nodeCrypto$
|
|
4897
|
+
const nodeCrypto$9 = util.getNodeCrypto();
|
|
4876
4898
|
|
|
4877
4899
|
|
|
4878
4900
|
/**
|
|
@@ -4938,7 +4960,7 @@ async function CMAC(key) {
|
|
|
4938
4960
|
async function CBC(key) {
|
|
4939
4961
|
if (util.getNodeCrypto()) { // Node crypto library
|
|
4940
4962
|
return async function(pt) {
|
|
4941
|
-
const en = new nodeCrypto$
|
|
4963
|
+
const en = new nodeCrypto$9.createCipheriv('aes-' + (key.length * 8) + '-cbc', key, zeroBlock$1);
|
|
4942
4964
|
const ct = en.update(pt);
|
|
4943
4965
|
return new Uint8Array(ct);
|
|
4944
4966
|
};
|
|
@@ -4986,7 +5008,7 @@ async function CBC(key) {
|
|
|
4986
5008
|
|
|
4987
5009
|
|
|
4988
5010
|
const webCrypto$8 = util.getWebCrypto();
|
|
4989
|
-
const nodeCrypto$
|
|
5011
|
+
const nodeCrypto$8 = util.getNodeCrypto();
|
|
4990
5012
|
const Buffer$1 = util.getNodeBuffer();
|
|
4991
5013
|
|
|
4992
5014
|
|
|
@@ -5008,7 +5030,7 @@ async function OMAC(key) {
|
|
|
5008
5030
|
async function CTR(key) {
|
|
5009
5031
|
if (util.getNodeCrypto()) { // Node crypto library
|
|
5010
5032
|
return async function(pt, iv) {
|
|
5011
|
-
const en = new nodeCrypto$
|
|
5033
|
+
const en = new nodeCrypto$8.createCipheriv('aes-' + (key.length * 8) + '-ctr', key, iv);
|
|
5012
5034
|
const ct = Buffer$1.concat([en.update(pt), en.final()]);
|
|
5013
5035
|
return new Uint8Array(ct);
|
|
5014
5036
|
};
|
|
@@ -5699,7 +5721,7 @@ class AES_GCM {
|
|
|
5699
5721
|
|
|
5700
5722
|
|
|
5701
5723
|
const webCrypto$7 = util.getWebCrypto();
|
|
5702
|
-
const nodeCrypto$
|
|
5724
|
+
const nodeCrypto$7 = util.getNodeCrypto();
|
|
5703
5725
|
const Buffer = util.getNodeBuffer();
|
|
5704
5726
|
|
|
5705
5727
|
const blockLength = 16;
|
|
@@ -5722,14 +5744,14 @@ async function GCM(cipher, key) {
|
|
|
5722
5744
|
if (util.getNodeCrypto()) { // Node crypto library
|
|
5723
5745
|
return {
|
|
5724
5746
|
encrypt: async function(pt, iv, adata = new Uint8Array()) {
|
|
5725
|
-
const en = new nodeCrypto$
|
|
5747
|
+
const en = new nodeCrypto$7.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
|
5726
5748
|
en.setAAD(adata);
|
|
5727
5749
|
const ct = Buffer.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
|
|
5728
5750
|
return new Uint8Array(ct);
|
|
5729
5751
|
},
|
|
5730
5752
|
|
|
5731
5753
|
decrypt: async function(ct, iv, adata = new Uint8Array()) {
|
|
5732
|
-
const de = new nodeCrypto$
|
|
5754
|
+
const de = new nodeCrypto$7.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
|
5733
5755
|
de.setAAD(adata);
|
|
5734
5756
|
de.setAuthTag(ct.slice(ct.length - tagLength, ct.length)); // read auth tag at end of ciphertext
|
|
5735
5757
|
const pt = Buffer.concat([de.update(ct.slice(0, ct.length - tagLength)), de.final()]);
|
|
@@ -5828,8 +5850,8 @@ var mode = {
|
|
|
5828
5850
|
};
|
|
5829
5851
|
|
|
5830
5852
|
// Operations are not constant time, but we try and limit timing leakage where we can
|
|
5831
|
-
const _0n$
|
|
5832
|
-
const _1n$
|
|
5853
|
+
const _0n$2 = BigInt(0);
|
|
5854
|
+
const _1n$5 = BigInt(1);
|
|
5833
5855
|
function uint8ArrayToBigInt(bytes) {
|
|
5834
5856
|
const hexAlphabet = '0123456789ABCDEF';
|
|
5835
5857
|
let s = '';
|
|
@@ -5838,9 +5860,9 @@ function uint8ArrayToBigInt(bytes) {
|
|
|
5838
5860
|
});
|
|
5839
5861
|
return BigInt('0x0' + s);
|
|
5840
5862
|
}
|
|
5841
|
-
function mod$
|
|
5863
|
+
function mod$2(a, m) {
|
|
5842
5864
|
const reduced = a % m;
|
|
5843
|
-
return reduced < _0n$
|
|
5865
|
+
return reduced < _0n$2 ? reduced + m : reduced;
|
|
5844
5866
|
}
|
|
5845
5867
|
/**
|
|
5846
5868
|
* Compute modular exponentiation using square and multiply
|
|
@@ -5850,19 +5872,19 @@ function mod$1(a, m) {
|
|
|
5850
5872
|
* @returns {BigInt} b ** e mod n.
|
|
5851
5873
|
*/
|
|
5852
5874
|
function modExp(b, e, n) {
|
|
5853
|
-
if (n === _0n$
|
|
5875
|
+
if (n === _0n$2)
|
|
5854
5876
|
throw Error('Modulo cannot be zero');
|
|
5855
|
-
if (n === _1n$
|
|
5877
|
+
if (n === _1n$5)
|
|
5856
5878
|
return BigInt(0);
|
|
5857
|
-
if (e < _0n$
|
|
5879
|
+
if (e < _0n$2)
|
|
5858
5880
|
throw Error('Unsopported negative exponent');
|
|
5859
5881
|
let exp = e;
|
|
5860
5882
|
let x = b;
|
|
5861
5883
|
x %= n;
|
|
5862
5884
|
let r = BigInt(1);
|
|
5863
|
-
while (exp > _0n$
|
|
5864
|
-
const lsb = exp & _1n$
|
|
5865
|
-
exp >>= _1n$
|
|
5885
|
+
while (exp > _0n$2) {
|
|
5886
|
+
const lsb = exp & _1n$5;
|
|
5887
|
+
exp >>= _1n$5; // e / 2
|
|
5866
5888
|
// Always compute multiplication step, to reduce timing leakage
|
|
5867
5889
|
const rx = (r * x) % n;
|
|
5868
5890
|
// Update r only if lsb is 1 (odd exponent)
|
|
@@ -5872,7 +5894,7 @@ function modExp(b, e, n) {
|
|
|
5872
5894
|
return r;
|
|
5873
5895
|
}
|
|
5874
5896
|
function abs(x) {
|
|
5875
|
-
return x >= _0n$
|
|
5897
|
+
return x >= _0n$2 ? x : -x;
|
|
5876
5898
|
}
|
|
5877
5899
|
/**
|
|
5878
5900
|
* Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf)
|
|
@@ -5892,9 +5914,9 @@ function _egcd(aInput, bInput) {
|
|
|
5892
5914
|
// See https://math.stackexchange.com/questions/37806/extended-euclidean-algorithm-with-negative-numbers
|
|
5893
5915
|
let a = abs(aInput);
|
|
5894
5916
|
let b = abs(bInput);
|
|
5895
|
-
const aNegated = aInput < _0n$
|
|
5896
|
-
const bNegated = bInput < _0n$
|
|
5897
|
-
while (b !== _0n$
|
|
5917
|
+
const aNegated = aInput < _0n$2;
|
|
5918
|
+
const bNegated = bInput < _0n$2;
|
|
5919
|
+
while (b !== _0n$2) {
|
|
5898
5920
|
const q = a / b;
|
|
5899
5921
|
let tmp = x;
|
|
5900
5922
|
x = xPrev - q * x;
|
|
@@ -5922,10 +5944,10 @@ function _egcd(aInput, bInput) {
|
|
|
5922
5944
|
*/
|
|
5923
5945
|
function modInv(a, n) {
|
|
5924
5946
|
const { gcd, x } = _egcd(a, n);
|
|
5925
|
-
if (gcd !== _1n$
|
|
5947
|
+
if (gcd !== _1n$5) {
|
|
5926
5948
|
throw new Error('Inverse does not exist');
|
|
5927
5949
|
}
|
|
5928
|
-
return mod$
|
|
5950
|
+
return mod$2(x + n, n);
|
|
5929
5951
|
}
|
|
5930
5952
|
/**
|
|
5931
5953
|
* Compute greatest common divisor between this and n
|
|
@@ -5936,7 +5958,7 @@ function modInv(a, n) {
|
|
|
5936
5958
|
function gcd(aInput, bInput) {
|
|
5937
5959
|
let a = aInput;
|
|
5938
5960
|
let b = bInput;
|
|
5939
|
-
while (b !== _0n$
|
|
5961
|
+
while (b !== _0n$2) {
|
|
5940
5962
|
const tmp = b;
|
|
5941
5963
|
b = a % b;
|
|
5942
5964
|
a = tmp;
|
|
@@ -5963,8 +5985,8 @@ function bigIntToNumber(x) {
|
|
|
5963
5985
|
* @returns {Number} Bit value.
|
|
5964
5986
|
*/
|
|
5965
5987
|
function getBit(x, i) {
|
|
5966
|
-
const bit = (x >> BigInt(i)) & _1n$
|
|
5967
|
-
return bit === _0n$
|
|
5988
|
+
const bit = (x >> BigInt(i)) & _1n$5;
|
|
5989
|
+
return bit === _0n$2 ? 0 : 1;
|
|
5968
5990
|
}
|
|
5969
5991
|
/**
|
|
5970
5992
|
* Compute bit length
|
|
@@ -5972,11 +5994,11 @@ function getBit(x, i) {
|
|
|
5972
5994
|
function bitLength(x) {
|
|
5973
5995
|
// -1n >> -1n is -1n
|
|
5974
5996
|
// 1n >> 1n is 0n
|
|
5975
|
-
const target = x < _0n$
|
|
5997
|
+
const target = x < _0n$2 ? BigInt(-1) : _0n$2;
|
|
5976
5998
|
let bitlen = 1;
|
|
5977
5999
|
let tmp = x;
|
|
5978
6000
|
// eslint-disable-next-line no-cond-assign
|
|
5979
|
-
while ((tmp >>= _1n$
|
|
6001
|
+
while ((tmp >>= _1n$5) !== target) {
|
|
5980
6002
|
bitlen++;
|
|
5981
6003
|
}
|
|
5982
6004
|
return bitlen;
|
|
@@ -5985,7 +6007,7 @@ function bitLength(x) {
|
|
|
5985
6007
|
* Compute byte length
|
|
5986
6008
|
*/
|
|
5987
6009
|
function byteLength(x) {
|
|
5988
|
-
const target = x < _0n$
|
|
6010
|
+
const target = x < _0n$2 ? BigInt(-1) : _0n$2;
|
|
5989
6011
|
const _8n = BigInt(8);
|
|
5990
6012
|
let len = 1;
|
|
5991
6013
|
let tmp = x;
|
|
@@ -6041,7 +6063,7 @@ function bigIntToUint8Array(x, endian = 'be', length) {
|
|
|
6041
6063
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
6042
6064
|
|
|
6043
6065
|
|
|
6044
|
-
const nodeCrypto$
|
|
6066
|
+
const nodeCrypto$6 = util.getNodeCrypto();
|
|
6045
6067
|
|
|
6046
6068
|
/**
|
|
6047
6069
|
* Retrieve secure random byte array of the specified length
|
|
@@ -6050,8 +6072,8 @@ const nodeCrypto$5 = util.getNodeCrypto();
|
|
|
6050
6072
|
*/
|
|
6051
6073
|
function getRandomBytes(length) {
|
|
6052
6074
|
const buf = new Uint8Array(length);
|
|
6053
|
-
if (nodeCrypto$
|
|
6054
|
-
const bytes = nodeCrypto$
|
|
6075
|
+
if (nodeCrypto$6) {
|
|
6076
|
+
const bytes = nodeCrypto$6.randomBytes(buf.length);
|
|
6055
6077
|
buf.set(bytes);
|
|
6056
6078
|
} else if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
6057
6079
|
crypto.getRandomValues(buf);
|
|
@@ -6080,7 +6102,7 @@ function getRandomBigInteger(min, max) {
|
|
|
6080
6102
|
// However, we request 64 extra random bits so that the bias is negligible.
|
|
6081
6103
|
// Section B.1.1 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
|
|
6082
6104
|
const r = uint8ArrayToBigInt(getRandomBytes(bytes + 8));
|
|
6083
|
-
return mod$
|
|
6105
|
+
return mod$2(r, modulus) + min;
|
|
6084
6106
|
}
|
|
6085
6107
|
|
|
6086
6108
|
var random = /*#__PURE__*/Object.freeze({
|
|
@@ -6109,7 +6131,7 @@ var random = /*#__PURE__*/Object.freeze({
|
|
|
6109
6131
|
* @fileoverview Algorithms for probabilistic random prime generation
|
|
6110
6132
|
* @module crypto/public_key/prime
|
|
6111
6133
|
*/
|
|
6112
|
-
const _1n$
|
|
6134
|
+
const _1n$4 = BigInt(1);
|
|
6113
6135
|
/**
|
|
6114
6136
|
* Generate a probably prime random number
|
|
6115
6137
|
* @param bits - Bit length of the prime
|
|
@@ -6118,7 +6140,7 @@ const _1n$3 = BigInt(1);
|
|
|
6118
6140
|
*/
|
|
6119
6141
|
function randomProbablePrime(bits, e, k) {
|
|
6120
6142
|
const _30n = BigInt(30);
|
|
6121
|
-
const min = _1n$
|
|
6143
|
+
const min = _1n$4 << BigInt(bits - 1);
|
|
6122
6144
|
/*
|
|
6123
6145
|
* We can avoid any multiples of 3 and 5 by looking at n mod 30
|
|
6124
6146
|
* 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
|
|
@@ -6126,16 +6148,16 @@ function randomProbablePrime(bits, e, k) {
|
|
|
6126
6148
|
* 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
|
|
6127
6149
|
*/
|
|
6128
6150
|
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];
|
|
6129
|
-
let n = getRandomBigInteger(min, min << _1n$
|
|
6130
|
-
let i = bigIntToNumber(mod$
|
|
6151
|
+
let n = getRandomBigInteger(min, min << _1n$4);
|
|
6152
|
+
let i = bigIntToNumber(mod$2(n, _30n));
|
|
6131
6153
|
do {
|
|
6132
6154
|
n += BigInt(adds[i]);
|
|
6133
6155
|
i = (i + adds[i]) % adds.length;
|
|
6134
6156
|
// If reached the maximum, go back to the minimum.
|
|
6135
6157
|
if (bitLength(n) > bits) {
|
|
6136
|
-
n = mod$
|
|
6158
|
+
n = mod$2(n, min << _1n$4);
|
|
6137
6159
|
n += min;
|
|
6138
|
-
i = bigIntToNumber(mod$
|
|
6160
|
+
i = bigIntToNumber(mod$2(n, _30n));
|
|
6139
6161
|
}
|
|
6140
6162
|
} while (!isProbablePrime(n, e, k));
|
|
6141
6163
|
return n;
|
|
@@ -6147,7 +6169,7 @@ function randomProbablePrime(bits, e, k) {
|
|
|
6147
6169
|
* @param k - Optional number of iterations of Miller-Rabin test
|
|
6148
6170
|
*/
|
|
6149
6171
|
function isProbablePrime(n, e, k) {
|
|
6150
|
-
if (e && gcd(n - _1n$
|
|
6172
|
+
if (e && gcd(n - _1n$4, e) !== _1n$4) {
|
|
6151
6173
|
return false;
|
|
6152
6174
|
}
|
|
6153
6175
|
if (!divisionTest(n)) {
|
|
@@ -6170,11 +6192,11 @@ function isProbablePrime(n, e, k) {
|
|
|
6170
6192
|
* @param b - Optional Fermat test base
|
|
6171
6193
|
*/
|
|
6172
6194
|
function fermat(n, b = BigInt(2)) {
|
|
6173
|
-
return modExp(b, n - _1n$
|
|
6195
|
+
return modExp(b, n - _1n$4, n) === _1n$4;
|
|
6174
6196
|
}
|
|
6175
6197
|
function divisionTest(n) {
|
|
6176
6198
|
const _0n = BigInt(0);
|
|
6177
|
-
return smallPrimes.every(m => mod$
|
|
6199
|
+
return smallPrimes.every(m => mod$2(n, m) !== _0n);
|
|
6178
6200
|
}
|
|
6179
6201
|
// https://github.com/gpg/libgcrypt/blob/master/cipher/primegen.c
|
|
6180
6202
|
const smallPrimes = [
|
|
@@ -6298,7 +6320,7 @@ function millerRabin(n, k, rand) {
|
|
|
6298
6320
|
if (!k) {
|
|
6299
6321
|
k = Math.max(1, (len / 48) | 0);
|
|
6300
6322
|
}
|
|
6301
|
-
const n1 = n - _1n$
|
|
6323
|
+
const n1 = n - _1n$4; // n - 1
|
|
6302
6324
|
// Find d and s, (n - 1) = (2 ^ s) * d;
|
|
6303
6325
|
let s = 0;
|
|
6304
6326
|
while (!getBit(n1, s)) {
|
|
@@ -6308,13 +6330,13 @@ function millerRabin(n, k, rand) {
|
|
|
6308
6330
|
for (; k > 0; k--) {
|
|
6309
6331
|
const a = getRandomBigInteger(BigInt(2), n1);
|
|
6310
6332
|
let x = modExp(a, d, n);
|
|
6311
|
-
if (x === _1n$
|
|
6333
|
+
if (x === _1n$4 || x === n1) {
|
|
6312
6334
|
continue;
|
|
6313
6335
|
}
|
|
6314
6336
|
let i;
|
|
6315
6337
|
for (i = 1; i < s; i++) {
|
|
6316
|
-
x = mod$
|
|
6317
|
-
if (x === _1n$
|
|
6338
|
+
x = mod$2(x * x, n);
|
|
6339
|
+
if (x === _1n$4) {
|
|
6318
6340
|
return false;
|
|
6319
6341
|
}
|
|
6320
6342
|
if (x === n1) {
|
|
@@ -6507,8 +6529,8 @@ var pkcs1 = /*#__PURE__*/Object.freeze({
|
|
|
6507
6529
|
|
|
6508
6530
|
|
|
6509
6531
|
const webCrypto$6 = util.getWebCrypto();
|
|
6510
|
-
const nodeCrypto$
|
|
6511
|
-
const _1n$
|
|
6532
|
+
const nodeCrypto$5 = util.getNodeCrypto();
|
|
6533
|
+
const _1n$3 = BigInt(1);
|
|
6512
6534
|
|
|
6513
6535
|
/** Create signature
|
|
6514
6536
|
* @param {module:enums.hash} hashAlgo - Hash algorithm
|
|
@@ -6549,7 +6571,7 @@ async function sign$7(hashAlgo, data, n, e, d, p, q, u, hashed) {
|
|
|
6549
6571
|
* @returns {Boolean}
|
|
6550
6572
|
* @async
|
|
6551
6573
|
*/
|
|
6552
|
-
async function verify$
|
|
6574
|
+
async function verify$8(hashAlgo, data, s, n, e, hashed) {
|
|
6553
6575
|
if (data && !util.isStream(data)) {
|
|
6554
6576
|
if (util.getWebCrypto()) {
|
|
6555
6577
|
try {
|
|
@@ -6649,7 +6671,7 @@ async function generate$5(bits, e) {
|
|
|
6649
6671
|
privateKeyEncoding: { type: 'pkcs1', format: 'jwk' }
|
|
6650
6672
|
};
|
|
6651
6673
|
const jwk = await new Promise((resolve, reject) => {
|
|
6652
|
-
nodeCrypto$
|
|
6674
|
+
nodeCrypto$5.generateKeyPair('rsa', opts, (err, _, jwkPrivateKey) => {
|
|
6653
6675
|
if (err) {
|
|
6654
6676
|
reject(err);
|
|
6655
6677
|
} else {
|
|
@@ -6672,7 +6694,7 @@ async function generate$5(bits, e) {
|
|
|
6672
6694
|
n = p * q;
|
|
6673
6695
|
} while (bitLength(n) !== bits);
|
|
6674
6696
|
|
|
6675
|
-
const phi = (p - _1n$
|
|
6697
|
+
const phi = (p - _1n$3) * (q - _1n$3);
|
|
6676
6698
|
|
|
6677
6699
|
if (q < p) {
|
|
6678
6700
|
[p, q] = [q, p];
|
|
@@ -6714,7 +6736,7 @@ async function validateParams$8(n, e, d, p, q, u) {
|
|
|
6714
6736
|
const _2n = BigInt(2);
|
|
6715
6737
|
// expect p*u = 1 mod q
|
|
6716
6738
|
u = uint8ArrayToBigInt(u);
|
|
6717
|
-
if (mod$
|
|
6739
|
+
if (mod$2(p * u, q) !== BigInt(1)) {
|
|
6718
6740
|
return false;
|
|
6719
6741
|
}
|
|
6720
6742
|
|
|
@@ -6731,7 +6753,7 @@ async function validateParams$8(n, e, d, p, q, u) {
|
|
|
6731
6753
|
const r = getRandomBigInteger(_2n, _2n << nSizeOver3); // r in [ 2, 2^{|n|/3} ) < p and q
|
|
6732
6754
|
const rde = r * d * e;
|
|
6733
6755
|
|
|
6734
|
-
const areInverses = mod$
|
|
6756
|
+
const areInverses = mod$2(rde, p - _1n$3) === r && mod$2(rde, q - _1n$3) === r;
|
|
6735
6757
|
if (!areInverses) {
|
|
6736
6758
|
return false;
|
|
6737
6759
|
}
|
|
@@ -6767,7 +6789,7 @@ async function webSign$1(hashName, data, n, e, d, p, q, u) {
|
|
|
6767
6789
|
}
|
|
6768
6790
|
|
|
6769
6791
|
async function nodeSign$1(hashAlgo, data, n, e, d, p, q, u) {
|
|
6770
|
-
const sign = nodeCrypto$
|
|
6792
|
+
const sign = nodeCrypto$5.createSign(enums.read(enums.hash, hashAlgo));
|
|
6771
6793
|
sign.write(data);
|
|
6772
6794
|
sign.end();
|
|
6773
6795
|
|
|
@@ -6800,7 +6822,7 @@ async function nodeVerify$1(hashAlgo, data, s, n, e) {
|
|
|
6800
6822
|
const jwk = publicToJWK(n, e);
|
|
6801
6823
|
const key = { key: jwk, format: 'jwk', type: 'pkcs1' };
|
|
6802
6824
|
|
|
6803
|
-
const verify = nodeCrypto$
|
|
6825
|
+
const verify = nodeCrypto$5.createVerify(enums.read(enums.hash, hashAlgo));
|
|
6804
6826
|
verify.write(data);
|
|
6805
6827
|
verify.end();
|
|
6806
6828
|
|
|
@@ -6813,9 +6835,9 @@ async function nodeVerify$1(hashAlgo, data, s, n, e) {
|
|
|
6813
6835
|
|
|
6814
6836
|
async function nodeEncrypt(data, n, e) {
|
|
6815
6837
|
const jwk = publicToJWK(n, e);
|
|
6816
|
-
const key = { key: jwk, format: 'jwk', type: 'pkcs1', padding: nodeCrypto$
|
|
6838
|
+
const key = { key: jwk, format: 'jwk', type: 'pkcs1', padding: nodeCrypto$5.constants.RSA_PKCS1_PADDING };
|
|
6817
6839
|
|
|
6818
|
-
return new Uint8Array(nodeCrypto$
|
|
6840
|
+
return new Uint8Array(nodeCrypto$5.publicEncrypt(key, data));
|
|
6819
6841
|
}
|
|
6820
6842
|
|
|
6821
6843
|
async function bnEncrypt(data, n, e) {
|
|
@@ -6830,10 +6852,10 @@ async function bnEncrypt(data, n, e) {
|
|
|
6830
6852
|
|
|
6831
6853
|
async function nodeDecrypt(data, n, e, d, p, q, u) {
|
|
6832
6854
|
const jwk = await privateToJWK$1(n, e, d, p, q, u);
|
|
6833
|
-
const key = { key: jwk, format: 'jwk' , type: 'pkcs1', padding: nodeCrypto$
|
|
6855
|
+
const key = { key: jwk, format: 'jwk' , type: 'pkcs1', padding: nodeCrypto$5.constants.RSA_PKCS1_PADDING };
|
|
6834
6856
|
|
|
6835
6857
|
try {
|
|
6836
|
-
return new Uint8Array(nodeCrypto$
|
|
6858
|
+
return new Uint8Array(nodeCrypto$5.privateDecrypt(key, data));
|
|
6837
6859
|
} catch (err) {
|
|
6838
6860
|
throw new Error('Decryption error');
|
|
6839
6861
|
}
|
|
@@ -6850,20 +6872,20 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) {
|
|
|
6850
6872
|
if (data >= n) {
|
|
6851
6873
|
throw new Error('Data too large.');
|
|
6852
6874
|
}
|
|
6853
|
-
const dq = mod$
|
|
6854
|
-
const dp = mod$
|
|
6875
|
+
const dq = mod$2(d, q - _1n$3); // d mod (q-1)
|
|
6876
|
+
const dp = mod$2(d, p - _1n$3); // d mod (p-1)
|
|
6855
6877
|
|
|
6856
6878
|
const unblinder = getRandomBigInteger(BigInt(2), n);
|
|
6857
6879
|
const blinder = modExp(modInv(unblinder, n), e, n);
|
|
6858
|
-
data = mod$
|
|
6880
|
+
data = mod$2(data * blinder, n);
|
|
6859
6881
|
|
|
6860
6882
|
const mp = modExp(data, dp, p); // data**{d mod (q-1)} mod p
|
|
6861
6883
|
const mq = modExp(data, dq, q); // data**{d mod (p-1)} mod q
|
|
6862
|
-
const h = mod$
|
|
6884
|
+
const h = mod$2(u * (mq - mp), q); // u * (mq-mp) mod q (operands already < q)
|
|
6863
6885
|
|
|
6864
6886
|
let result = h * p + mp; // result < n due to relations above
|
|
6865
6887
|
|
|
6866
|
-
result = mod$
|
|
6888
|
+
result = mod$2(result * unblinder, n);
|
|
6867
6889
|
|
|
6868
6890
|
return emeDecode(bigIntToUint8Array(result, 'be', byteLength(n)), randomPayload);
|
|
6869
6891
|
}
|
|
@@ -6883,8 +6905,8 @@ async function privateToJWK$1(n, e, d, p, q, u) {
|
|
|
6883
6905
|
const qNum = uint8ArrayToBigInt(q);
|
|
6884
6906
|
const dNum = uint8ArrayToBigInt(d);
|
|
6885
6907
|
|
|
6886
|
-
let dq = mod$
|
|
6887
|
-
let dp = mod$
|
|
6908
|
+
let dq = mod$2(dNum, qNum - _1n$3); // d mod (q-1)
|
|
6909
|
+
let dp = mod$2(dNum, pNum - _1n$3); // d mod (p-1)
|
|
6888
6910
|
dp = bigIntToUint8Array(dp);
|
|
6889
6911
|
dq = bigIntToUint8Array(dq);
|
|
6890
6912
|
return {
|
|
@@ -6939,7 +6961,7 @@ var rsa = /*#__PURE__*/Object.freeze({
|
|
|
6939
6961
|
generate: generate$5,
|
|
6940
6962
|
sign: sign$7,
|
|
6941
6963
|
validateParams: validateParams$8,
|
|
6942
|
-
verify: verify$
|
|
6964
|
+
verify: verify$8
|
|
6943
6965
|
});
|
|
6944
6966
|
|
|
6945
6967
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
@@ -6960,7 +6982,7 @@ var rsa = /*#__PURE__*/Object.freeze({
|
|
|
6960
6982
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
6961
6983
|
|
|
6962
6984
|
|
|
6963
|
-
const _1n$
|
|
6985
|
+
const _1n$2 = BigInt(1);
|
|
6964
6986
|
|
|
6965
6987
|
/**
|
|
6966
6988
|
* ElGamal Encryption function
|
|
@@ -6982,10 +7004,10 @@ async function encrypt$3(data, p, g, y) {
|
|
|
6982
7004
|
|
|
6983
7005
|
// OpenPGP uses a "special" version of ElGamal where g is generator of the full group Z/pZ*
|
|
6984
7006
|
// hence g has order p-1, and to avoid that k = 0 mod p-1, we need to pick k in [1, p-2]
|
|
6985
|
-
const k = getRandomBigInteger(_1n$
|
|
7007
|
+
const k = getRandomBigInteger(_1n$2, p - _1n$2);
|
|
6986
7008
|
return {
|
|
6987
7009
|
c1: bigIntToUint8Array(modExp(g, k, p)),
|
|
6988
|
-
c2: bigIntToUint8Array(mod$
|
|
7010
|
+
c2: bigIntToUint8Array(mod$2(modExp(y, k, p) * m, p))
|
|
6989
7011
|
};
|
|
6990
7012
|
}
|
|
6991
7013
|
|
|
@@ -7007,7 +7029,7 @@ async function decrypt$3(c1, c2, p, x, randomPayload) {
|
|
|
7007
7029
|
p = uint8ArrayToBigInt(p);
|
|
7008
7030
|
x = uint8ArrayToBigInt(x);
|
|
7009
7031
|
|
|
7010
|
-
const padded = mod$
|
|
7032
|
+
const padded = mod$2(modInv(modExp(c1, x, p), p) * c2, p);
|
|
7011
7033
|
return emeDecode(bigIntToUint8Array(padded, 'be', byteLength(p)), randomPayload);
|
|
7012
7034
|
}
|
|
7013
7035
|
|
|
@@ -7026,7 +7048,7 @@ async function validateParams$7(p, g, y, x) {
|
|
|
7026
7048
|
y = uint8ArrayToBigInt(y);
|
|
7027
7049
|
|
|
7028
7050
|
// Check that 1 < g < p
|
|
7029
|
-
if (g <= _1n$
|
|
7051
|
+
if (g <= _1n$2 || g >= p) {
|
|
7030
7052
|
return false;
|
|
7031
7053
|
}
|
|
7032
7054
|
|
|
@@ -7041,7 +7063,7 @@ async function validateParams$7(p, g, y, x) {
|
|
|
7041
7063
|
* g should have order p-1
|
|
7042
7064
|
* Check that g ** (p-1) = 1 mod p
|
|
7043
7065
|
*/
|
|
7044
|
-
if (modExp(g, p - _1n$
|
|
7066
|
+
if (modExp(g, p - _1n$2, p) !== _1n$2) {
|
|
7045
7067
|
return false;
|
|
7046
7068
|
}
|
|
7047
7069
|
|
|
@@ -7056,8 +7078,8 @@ async function validateParams$7(p, g, y, x) {
|
|
|
7056
7078
|
const _2n = BigInt(2);
|
|
7057
7079
|
const threshold = _2n << BigInt(17); // we want order > threshold
|
|
7058
7080
|
while (i < threshold) {
|
|
7059
|
-
res = mod$
|
|
7060
|
-
if (res === _1n$
|
|
7081
|
+
res = mod$2(res * g, p);
|
|
7082
|
+
if (res === _1n$2) {
|
|
7061
7083
|
return false;
|
|
7062
7084
|
}
|
|
7063
7085
|
i++;
|
|
@@ -7070,8 +7092,8 @@ async function validateParams$7(p, g, y, x) {
|
|
|
7070
7092
|
* Blinded exponentiation computes g**{r(p-1) + x} to compare to y
|
|
7071
7093
|
*/
|
|
7072
7094
|
x = uint8ArrayToBigInt(x);
|
|
7073
|
-
const r = getRandomBigInteger(_2n << (pSize - _1n$
|
|
7074
|
-
const rqx = (p - _1n$
|
|
7095
|
+
const r = getRandomBigInteger(_2n << (pSize - _1n$2), _2n << pSize); // draw r of same size as p-1
|
|
7096
|
+
const rqx = (p - _1n$2) * r + x;
|
|
7075
7097
|
if (y !== modExp(g, rqx, p)) {
|
|
7076
7098
|
return false;
|
|
7077
7099
|
}
|
|
@@ -7087,7 +7109,7 @@ var elgamal = /*#__PURE__*/Object.freeze({
|
|
|
7087
7109
|
});
|
|
7088
7110
|
|
|
7089
7111
|
// declare const globalThis: Record<string, any> | undefined;
|
|
7090
|
-
const crypto$
|
|
7112
|
+
const crypto$3 =
|
|
7091
7113
|
typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
|
7092
7114
|
|
|
7093
7115
|
const nacl = {};
|
|
@@ -8450,13 +8472,13 @@ nacl.setPRNG = function(fn) {
|
|
|
8450
8472
|
(function() {
|
|
8451
8473
|
// Initialize PRNG if environment provides CSPRNG.
|
|
8452
8474
|
// If not, methods calling randombytes will throw.
|
|
8453
|
-
if (crypto$
|
|
8475
|
+
if (crypto$3 && crypto$3.getRandomValues) {
|
|
8454
8476
|
// Browsers and Node v16+
|
|
8455
8477
|
var QUOTA = 65536;
|
|
8456
8478
|
nacl.setPRNG(function(x, n) {
|
|
8457
8479
|
var i, v = new Uint8Array(n);
|
|
8458
8480
|
for (i = 0; i < n; i += QUOTA) {
|
|
8459
|
-
crypto$
|
|
8481
|
+
crypto$3.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
|
|
8460
8482
|
}
|
|
8461
8483
|
for (i = 0; i < n; i++) x[i] = v[i];
|
|
8462
8484
|
cleanup(v);
|
|
@@ -8905,15 +8927,15 @@ class UnparseablePacket {
|
|
|
8905
8927
|
|
|
8906
8928
|
|
|
8907
8929
|
const webCrypto$5 = util.getWebCrypto();
|
|
8908
|
-
const nodeCrypto$
|
|
8930
|
+
const nodeCrypto$4 = util.getNodeCrypto();
|
|
8909
8931
|
|
|
8910
8932
|
const webCurves = {
|
|
8911
8933
|
[enums.curve.nistP256]: 'P-256',
|
|
8912
8934
|
[enums.curve.nistP384]: 'P-384',
|
|
8913
8935
|
[enums.curve.nistP521]: 'P-521'
|
|
8914
8936
|
};
|
|
8915
|
-
const knownCurves = nodeCrypto$
|
|
8916
|
-
const nodeCurves = nodeCrypto$
|
|
8937
|
+
const knownCurves = nodeCrypto$4 ? nodeCrypto$4.getCurves() : [];
|
|
8938
|
+
const nodeCurves = nodeCrypto$4 ? {
|
|
8917
8939
|
[enums.curve.secp256k1]: knownCurves.includes('secp256k1') ? 'secp256k1' : undefined,
|
|
8918
8940
|
[enums.curve.nistP256]: knownCurves.includes('prime256v1') ? 'prime256v1' : undefined,
|
|
8919
8941
|
[enums.curve.nistP384]: knownCurves.includes('secp384r1') ? 'secp384r1' : undefined,
|
|
@@ -8934,7 +8956,8 @@ const curves = {
|
|
|
8934
8956
|
node: nodeCurves[enums.curve.nistP256],
|
|
8935
8957
|
web: webCurves[enums.curve.nistP256],
|
|
8936
8958
|
payloadSize: 32,
|
|
8937
|
-
sharedSize: 256
|
|
8959
|
+
sharedSize: 256,
|
|
8960
|
+
wireFormatLeadingByte: 0x04
|
|
8938
8961
|
},
|
|
8939
8962
|
[enums.curve.nistP384]: {
|
|
8940
8963
|
oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22],
|
|
@@ -8944,7 +8967,8 @@ const curves = {
|
|
|
8944
8967
|
node: nodeCurves[enums.curve.nistP384],
|
|
8945
8968
|
web: webCurves[enums.curve.nistP384],
|
|
8946
8969
|
payloadSize: 48,
|
|
8947
|
-
sharedSize: 384
|
|
8970
|
+
sharedSize: 384,
|
|
8971
|
+
wireFormatLeadingByte: 0x04
|
|
8948
8972
|
},
|
|
8949
8973
|
[enums.curve.nistP521]: {
|
|
8950
8974
|
oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23],
|
|
@@ -8954,7 +8978,8 @@ const curves = {
|
|
|
8954
8978
|
node: nodeCurves[enums.curve.nistP521],
|
|
8955
8979
|
web: webCurves[enums.curve.nistP521],
|
|
8956
8980
|
payloadSize: 66,
|
|
8957
|
-
sharedSize: 528
|
|
8981
|
+
sharedSize: 528,
|
|
8982
|
+
wireFormatLeadingByte: 0x04
|
|
8958
8983
|
},
|
|
8959
8984
|
[enums.curve.secp256k1]: {
|
|
8960
8985
|
oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x0A],
|
|
@@ -8962,14 +8987,16 @@ const curves = {
|
|
|
8962
8987
|
hash: enums.hash.sha256,
|
|
8963
8988
|
cipher: enums.symmetric.aes128,
|
|
8964
8989
|
node: nodeCurves[enums.curve.secp256k1],
|
|
8965
|
-
payloadSize: 32
|
|
8990
|
+
payloadSize: 32,
|
|
8991
|
+
wireFormatLeadingByte: 0x04
|
|
8966
8992
|
},
|
|
8967
8993
|
[enums.curve.ed25519Legacy]: {
|
|
8968
8994
|
oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
|
|
8969
8995
|
keyType: enums.publicKey.eddsaLegacy,
|
|
8970
8996
|
hash: enums.hash.sha512,
|
|
8971
8997
|
node: false, // nodeCurves.ed25519 TODO
|
|
8972
|
-
payloadSize: 32
|
|
8998
|
+
payloadSize: 32,
|
|
8999
|
+
wireFormatLeadingByte: 0x40
|
|
8973
9000
|
},
|
|
8974
9001
|
[enums.curve.curve25519Legacy]: {
|
|
8975
9002
|
oid: [0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01],
|
|
@@ -8977,7 +9004,8 @@ const curves = {
|
|
|
8977
9004
|
hash: enums.hash.sha256,
|
|
8978
9005
|
cipher: enums.symmetric.aes128,
|
|
8979
9006
|
node: false, // nodeCurves.curve25519 TODO
|
|
8980
|
-
payloadSize: 32
|
|
9007
|
+
payloadSize: 32,
|
|
9008
|
+
wireFormatLeadingByte: 0x40
|
|
8981
9009
|
},
|
|
8982
9010
|
[enums.curve.brainpoolP256r1]: {
|
|
8983
9011
|
oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07],
|
|
@@ -8985,7 +9013,8 @@ const curves = {
|
|
|
8985
9013
|
hash: enums.hash.sha256,
|
|
8986
9014
|
cipher: enums.symmetric.aes128,
|
|
8987
9015
|
node: nodeCurves[enums.curve.brainpoolP256r1],
|
|
8988
|
-
payloadSize: 32
|
|
9016
|
+
payloadSize: 32,
|
|
9017
|
+
wireFormatLeadingByte: 0x04
|
|
8989
9018
|
},
|
|
8990
9019
|
[enums.curve.brainpoolP384r1]: {
|
|
8991
9020
|
oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B],
|
|
@@ -8993,7 +9022,8 @@ const curves = {
|
|
|
8993
9022
|
hash: enums.hash.sha384,
|
|
8994
9023
|
cipher: enums.symmetric.aes192,
|
|
8995
9024
|
node: nodeCurves[enums.curve.brainpoolP384r1],
|
|
8996
|
-
payloadSize: 48
|
|
9025
|
+
payloadSize: 48,
|
|
9026
|
+
wireFormatLeadingByte: 0x04
|
|
8997
9027
|
},
|
|
8998
9028
|
[enums.curve.brainpoolP512r1]: {
|
|
8999
9029
|
oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D],
|
|
@@ -9001,7 +9031,8 @@ const curves = {
|
|
|
9001
9031
|
hash: enums.hash.sha512,
|
|
9002
9032
|
cipher: enums.symmetric.aes256,
|
|
9003
9033
|
node: nodeCurves[enums.curve.brainpoolP512r1],
|
|
9004
|
-
payloadSize: 64
|
|
9034
|
+
payloadSize: 64,
|
|
9035
|
+
wireFormatLeadingByte: 0x04
|
|
9005
9036
|
}
|
|
9006
9037
|
};
|
|
9007
9038
|
|
|
@@ -9025,6 +9056,7 @@ class CurveWithOID {
|
|
|
9025
9056
|
this.web = params.web;
|
|
9026
9057
|
this.payloadSize = params.payloadSize;
|
|
9027
9058
|
this.sharedSize = params.sharedSize;
|
|
9059
|
+
this.wireFormatLeadingByte = params.wireFormatLeadingByte;
|
|
9028
9060
|
if (this.web && util.getWebCrypto()) {
|
|
9029
9061
|
this.type = 'web';
|
|
9030
9062
|
} else if (this.node && util.getNodeCrypto()) {
|
|
@@ -9040,7 +9072,7 @@ class CurveWithOID {
|
|
|
9040
9072
|
switch (this.type) {
|
|
9041
9073
|
case 'web':
|
|
9042
9074
|
try {
|
|
9043
|
-
return await webGenKeyPair(this.name);
|
|
9075
|
+
return await webGenKeyPair(this.name, this.wireFormatLeadingByte);
|
|
9044
9076
|
} catch (err) {
|
|
9045
9077
|
util.printDebugError('Browser did not support generating ec key ' + err.message);
|
|
9046
9078
|
return jsGenKeyPair(this.name);
|
|
@@ -9053,13 +9085,13 @@ class CurveWithOID {
|
|
|
9053
9085
|
privateKey[31] &= 248;
|
|
9054
9086
|
const secretKey = privateKey.slice().reverse();
|
|
9055
9087
|
const { publicKey: rawPublicKey } = nacl.box.keyPair.fromSecretKey(secretKey);
|
|
9056
|
-
const publicKey = util.concatUint8Array([new Uint8Array([
|
|
9088
|
+
const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), rawPublicKey]);
|
|
9057
9089
|
return { publicKey, privateKey };
|
|
9058
9090
|
}
|
|
9059
9091
|
case 'ed25519Legacy': {
|
|
9060
9092
|
const privateKey = getRandomBytes(32);
|
|
9061
9093
|
const keyPair = nacl.sign.keyPair.fromSeed(privateKey);
|
|
9062
|
-
const publicKey = util.concatUint8Array([new Uint8Array([
|
|
9094
|
+
const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), keyPair.publicKey]);
|
|
9063
9095
|
return { publicKey, privateKey };
|
|
9064
9096
|
}
|
|
9065
9097
|
default:
|
|
@@ -9145,6 +9177,20 @@ async function validateStandardParams(algo, oid, Q, d) {
|
|
|
9145
9177
|
return true;
|
|
9146
9178
|
}
|
|
9147
9179
|
|
|
9180
|
+
/**
|
|
9181
|
+
* Check whether the public point has a valid encoding.
|
|
9182
|
+
* NB: this function does not check e.g. whether the point belongs to the curve.
|
|
9183
|
+
*/
|
|
9184
|
+
function checkPublicPointEnconding(curve, V) {
|
|
9185
|
+
const { payloadSize, wireFormatLeadingByte, name: curveName } = curve;
|
|
9186
|
+
|
|
9187
|
+
const pointSize = (curveName === enums.curve.curve25519Legacy || curveName === enums.curve.ed25519Legacy) ? payloadSize : payloadSize * 2;
|
|
9188
|
+
|
|
9189
|
+
if (V[0] !== wireFormatLeadingByte || V.length !== pointSize + 1) {
|
|
9190
|
+
throw new Error('Invalid point encoding');
|
|
9191
|
+
}
|
|
9192
|
+
}
|
|
9193
|
+
|
|
9148
9194
|
//////////////////////////
|
|
9149
9195
|
// //
|
|
9150
9196
|
// Helper functions //
|
|
@@ -9157,7 +9203,7 @@ async function jsGenKeyPair(name) {
|
|
|
9157
9203
|
return { publicKey, privateKey };
|
|
9158
9204
|
}
|
|
9159
9205
|
|
|
9160
|
-
async function webGenKeyPair(name) {
|
|
9206
|
+
async function webGenKeyPair(name, wireFormatLeadingByte) {
|
|
9161
9207
|
// Note: keys generated with ECDSA and ECDH are structurally equivalent
|
|
9162
9208
|
const webCryptoKey = await webCrypto$5.generateKey({ name: 'ECDSA', namedCurve: webCurves[name] }, true, ['sign', 'verify']);
|
|
9163
9209
|
|
|
@@ -9165,14 +9211,14 @@ async function webGenKeyPair(name) {
|
|
|
9165
9211
|
const publicKey = await webCrypto$5.exportKey('jwk', webCryptoKey.publicKey);
|
|
9166
9212
|
|
|
9167
9213
|
return {
|
|
9168
|
-
publicKey: jwkToRawPublic(publicKey),
|
|
9214
|
+
publicKey: jwkToRawPublic(publicKey, wireFormatLeadingByte),
|
|
9169
9215
|
privateKey: b64ToUint8Array(privateKey.d)
|
|
9170
9216
|
};
|
|
9171
9217
|
}
|
|
9172
9218
|
|
|
9173
9219
|
async function nodeGenKeyPair(name) {
|
|
9174
9220
|
// Note: ECDSA and ECDH key generation is structurally equivalent
|
|
9175
|
-
const ecdh = nodeCrypto$
|
|
9221
|
+
const ecdh = nodeCrypto$4.createECDH(nodeCurves[name]);
|
|
9176
9222
|
await ecdh.generateKeys();
|
|
9177
9223
|
return {
|
|
9178
9224
|
publicKey: new Uint8Array(ecdh.getPublicKey()),
|
|
@@ -9191,11 +9237,11 @@ async function nodeGenKeyPair(name) {
|
|
|
9191
9237
|
*
|
|
9192
9238
|
* @returns {Uint8Array} Raw public key.
|
|
9193
9239
|
*/
|
|
9194
|
-
function jwkToRawPublic(jwk) {
|
|
9240
|
+
function jwkToRawPublic(jwk, wireFormatLeadingByte) {
|
|
9195
9241
|
const bufX = b64ToUint8Array(jwk.x);
|
|
9196
9242
|
const bufY = b64ToUint8Array(jwk.y);
|
|
9197
9243
|
const publicKey = new Uint8Array(bufX.length + bufY.length + 1);
|
|
9198
|
-
publicKey[0] =
|
|
9244
|
+
publicKey[0] = wireFormatLeadingByte;
|
|
9199
9245
|
publicKey.set(bufX, 1);
|
|
9200
9246
|
publicKey.set(bufY, bufX.length + 1);
|
|
9201
9247
|
return publicKey;
|
|
@@ -9256,7 +9302,7 @@ function privateToJWK(payloadSize, name, publicKey, privateKey) {
|
|
|
9256
9302
|
|
|
9257
9303
|
|
|
9258
9304
|
const webCrypto$4 = util.getWebCrypto();
|
|
9259
|
-
const nodeCrypto$
|
|
9305
|
+
const nodeCrypto$3 = util.getNodeCrypto();
|
|
9260
9306
|
|
|
9261
9307
|
/**
|
|
9262
9308
|
* Sign a message using the provided key
|
|
@@ -9274,6 +9320,7 @@ const nodeCrypto$2 = util.getNodeCrypto();
|
|
|
9274
9320
|
*/
|
|
9275
9321
|
async function sign$6(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
9276
9322
|
const curve = new CurveWithOID(oid);
|
|
9323
|
+
checkPublicPointEnconding(curve, publicKey);
|
|
9277
9324
|
if (message && !util.isStream(message)) {
|
|
9278
9325
|
const keyPair = { publicKey, privateKey };
|
|
9279
9326
|
switch (curve.type) {
|
|
@@ -9318,8 +9365,9 @@ async function sign$6(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
9318
9365
|
* @returns {Boolean}
|
|
9319
9366
|
* @async
|
|
9320
9367
|
*/
|
|
9321
|
-
async function verify$
|
|
9368
|
+
async function verify$7(oid, hashAlgo, signature, message, publicKey, hashed) {
|
|
9322
9369
|
const curve = new CurveWithOID(oid);
|
|
9370
|
+
checkPublicPointEnconding(curve, publicKey);
|
|
9323
9371
|
// See https://github.com/openpgpjs/openpgpjs/pull/948.
|
|
9324
9372
|
// NB: the impact was more likely limited to Brainpool curves, since thanks
|
|
9325
9373
|
// to WebCrypto availability, NIST curve should not have been affected.
|
|
@@ -9386,7 +9434,7 @@ async function validateParams$6(oid, Q, d) {
|
|
|
9386
9434
|
try {
|
|
9387
9435
|
const signature = await sign$6(oid, hashAlgo, message, Q, d, hashed);
|
|
9388
9436
|
// eslint-disable-next-line @typescript-eslint/return-await
|
|
9389
|
-
return await verify$
|
|
9437
|
+
return await verify$7(oid, hashAlgo, signature, message, Q, hashed);
|
|
9390
9438
|
} catch (err) {
|
|
9391
9439
|
return false;
|
|
9392
9440
|
}
|
|
@@ -9481,7 +9529,7 @@ async function nodeSign(curve, hashAlgo, message, privateKey) {
|
|
|
9481
9529
|
privateKey: nodeBuffer.from(privateKey)
|
|
9482
9530
|
});
|
|
9483
9531
|
|
|
9484
|
-
const sign = nodeCrypto$
|
|
9532
|
+
const sign = nodeCrypto$3.createSign(enums.read(enums.hash, hashAlgo));
|
|
9485
9533
|
sign.write(message);
|
|
9486
9534
|
sign.end();
|
|
9487
9535
|
|
|
@@ -9502,7 +9550,7 @@ async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) {
|
|
|
9502
9550
|
publicKey: nodeBuffer.from(publicKey)
|
|
9503
9551
|
});
|
|
9504
9552
|
|
|
9505
|
-
const verify = nodeCrypto$
|
|
9553
|
+
const verify = nodeCrypto$3.createVerify(enums.read(enums.hash, hashAlgo));
|
|
9506
9554
|
verify.write(message);
|
|
9507
9555
|
verify.end();
|
|
9508
9556
|
|
|
@@ -9519,7 +9567,760 @@ var ecdsa = /*#__PURE__*/Object.freeze({
|
|
|
9519
9567
|
__proto__: null,
|
|
9520
9568
|
sign: sign$6,
|
|
9521
9569
|
validateParams: validateParams$6,
|
|
9522
|
-
verify: verify$
|
|
9570
|
+
verify: verify$7
|
|
9571
|
+
});
|
|
9572
|
+
|
|
9573
|
+
/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
|
|
9574
|
+
const nodeCrypto$2 = null;
|
|
9575
|
+
const _0n$1 = BigInt(0);
|
|
9576
|
+
const _1n$1 = BigInt(1);
|
|
9577
|
+
const _2n = BigInt(2);
|
|
9578
|
+
const _8n = BigInt(8);
|
|
9579
|
+
const CU_O = BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989');
|
|
9580
|
+
const CURVE = Object.freeze({
|
|
9581
|
+
a: BigInt(-1),
|
|
9582
|
+
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
|
9583
|
+
P: BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949'),
|
|
9584
|
+
l: CU_O,
|
|
9585
|
+
n: CU_O,
|
|
9586
|
+
h: BigInt(8),
|
|
9587
|
+
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
|
9588
|
+
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
|
9589
|
+
});
|
|
9590
|
+
const POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000');
|
|
9591
|
+
const SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
|
9592
|
+
BigInt('6853475219497561581579357271197624642482790079785650197046958215289687604742');
|
|
9593
|
+
const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
|
9594
|
+
const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
|
9595
|
+
const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
|
9596
|
+
const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
|
9597
|
+
class ExtendedPoint {
|
|
9598
|
+
constructor(x, y, z, t) {
|
|
9599
|
+
this.x = x;
|
|
9600
|
+
this.y = y;
|
|
9601
|
+
this.z = z;
|
|
9602
|
+
this.t = t;
|
|
9603
|
+
}
|
|
9604
|
+
static fromAffine(p) {
|
|
9605
|
+
if (!(p instanceof Point)) {
|
|
9606
|
+
throw new TypeError('ExtendedPoint#fromAffine: expected Point');
|
|
9607
|
+
}
|
|
9608
|
+
if (p.equals(Point.ZERO))
|
|
9609
|
+
return ExtendedPoint.ZERO;
|
|
9610
|
+
return new ExtendedPoint(p.x, p.y, _1n$1, mod$1(p.x * p.y));
|
|
9611
|
+
}
|
|
9612
|
+
static toAffineBatch(points) {
|
|
9613
|
+
const toInv = invertBatch(points.map((p) => p.z));
|
|
9614
|
+
return points.map((p, i) => p.toAffine(toInv[i]));
|
|
9615
|
+
}
|
|
9616
|
+
static normalizeZ(points) {
|
|
9617
|
+
return this.toAffineBatch(points).map(this.fromAffine);
|
|
9618
|
+
}
|
|
9619
|
+
equals(other) {
|
|
9620
|
+
assertExtPoint(other);
|
|
9621
|
+
const { x: X1, y: Y1, z: Z1 } = this;
|
|
9622
|
+
const { x: X2, y: Y2, z: Z2 } = other;
|
|
9623
|
+
const X1Z2 = mod$1(X1 * Z2);
|
|
9624
|
+
const X2Z1 = mod$1(X2 * Z1);
|
|
9625
|
+
const Y1Z2 = mod$1(Y1 * Z2);
|
|
9626
|
+
const Y2Z1 = mod$1(Y2 * Z1);
|
|
9627
|
+
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
|
9628
|
+
}
|
|
9629
|
+
negate() {
|
|
9630
|
+
return new ExtendedPoint(mod$1(-this.x), this.y, this.z, mod$1(-this.t));
|
|
9631
|
+
}
|
|
9632
|
+
double() {
|
|
9633
|
+
const { x: X1, y: Y1, z: Z1 } = this;
|
|
9634
|
+
const { a } = CURVE;
|
|
9635
|
+
const A = mod$1(X1 * X1);
|
|
9636
|
+
const B = mod$1(Y1 * Y1);
|
|
9637
|
+
const C = mod$1(_2n * mod$1(Z1 * Z1));
|
|
9638
|
+
const D = mod$1(a * A);
|
|
9639
|
+
const x1y1 = X1 + Y1;
|
|
9640
|
+
const E = mod$1(mod$1(x1y1 * x1y1) - A - B);
|
|
9641
|
+
const G = D + B;
|
|
9642
|
+
const F = G - C;
|
|
9643
|
+
const H = D - B;
|
|
9644
|
+
const X3 = mod$1(E * F);
|
|
9645
|
+
const Y3 = mod$1(G * H);
|
|
9646
|
+
const T3 = mod$1(E * H);
|
|
9647
|
+
const Z3 = mod$1(F * G);
|
|
9648
|
+
return new ExtendedPoint(X3, Y3, Z3, T3);
|
|
9649
|
+
}
|
|
9650
|
+
add(other) {
|
|
9651
|
+
assertExtPoint(other);
|
|
9652
|
+
const { x: X1, y: Y1, z: Z1, t: T1 } = this;
|
|
9653
|
+
const { x: X2, y: Y2, z: Z2, t: T2 } = other;
|
|
9654
|
+
const A = mod$1((Y1 - X1) * (Y2 + X2));
|
|
9655
|
+
const B = mod$1((Y1 + X1) * (Y2 - X2));
|
|
9656
|
+
const F = mod$1(B - A);
|
|
9657
|
+
if (F === _0n$1)
|
|
9658
|
+
return this.double();
|
|
9659
|
+
const C = mod$1(Z1 * _2n * T2);
|
|
9660
|
+
const D = mod$1(T1 * _2n * Z2);
|
|
9661
|
+
const E = D + C;
|
|
9662
|
+
const G = B + A;
|
|
9663
|
+
const H = D - C;
|
|
9664
|
+
const X3 = mod$1(E * F);
|
|
9665
|
+
const Y3 = mod$1(G * H);
|
|
9666
|
+
const T3 = mod$1(E * H);
|
|
9667
|
+
const Z3 = mod$1(F * G);
|
|
9668
|
+
return new ExtendedPoint(X3, Y3, Z3, T3);
|
|
9669
|
+
}
|
|
9670
|
+
subtract(other) {
|
|
9671
|
+
return this.add(other.negate());
|
|
9672
|
+
}
|
|
9673
|
+
precomputeWindow(W) {
|
|
9674
|
+
const windows = 1 + 256 / W;
|
|
9675
|
+
const points = [];
|
|
9676
|
+
let p = this;
|
|
9677
|
+
let base = p;
|
|
9678
|
+
for (let window = 0; window < windows; window++) {
|
|
9679
|
+
base = p;
|
|
9680
|
+
points.push(base);
|
|
9681
|
+
for (let i = 1; i < 2 ** (W - 1); i++) {
|
|
9682
|
+
base = base.add(p);
|
|
9683
|
+
points.push(base);
|
|
9684
|
+
}
|
|
9685
|
+
p = base.double();
|
|
9686
|
+
}
|
|
9687
|
+
return points;
|
|
9688
|
+
}
|
|
9689
|
+
wNAF(n, affinePoint) {
|
|
9690
|
+
if (!affinePoint && this.equals(ExtendedPoint.BASE))
|
|
9691
|
+
affinePoint = Point.BASE;
|
|
9692
|
+
const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1;
|
|
9693
|
+
if (256 % W) {
|
|
9694
|
+
throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
|
|
9695
|
+
}
|
|
9696
|
+
let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
|
|
9697
|
+
if (!precomputes) {
|
|
9698
|
+
precomputes = this.precomputeWindow(W);
|
|
9699
|
+
if (affinePoint && W !== 1) {
|
|
9700
|
+
precomputes = ExtendedPoint.normalizeZ(precomputes);
|
|
9701
|
+
pointPrecomputes.set(affinePoint, precomputes);
|
|
9702
|
+
}
|
|
9703
|
+
}
|
|
9704
|
+
let p = ExtendedPoint.ZERO;
|
|
9705
|
+
let f = ExtendedPoint.BASE;
|
|
9706
|
+
const windows = 1 + 256 / W;
|
|
9707
|
+
const windowSize = 2 ** (W - 1);
|
|
9708
|
+
const mask = BigInt(2 ** W - 1);
|
|
9709
|
+
const maxNumber = 2 ** W;
|
|
9710
|
+
const shiftBy = BigInt(W);
|
|
9711
|
+
for (let window = 0; window < windows; window++) {
|
|
9712
|
+
const offset = window * windowSize;
|
|
9713
|
+
let wbits = Number(n & mask);
|
|
9714
|
+
n >>= shiftBy;
|
|
9715
|
+
if (wbits > windowSize) {
|
|
9716
|
+
wbits -= maxNumber;
|
|
9717
|
+
n += _1n$1;
|
|
9718
|
+
}
|
|
9719
|
+
const offset1 = offset;
|
|
9720
|
+
const offset2 = offset + Math.abs(wbits) - 1;
|
|
9721
|
+
const cond1 = window % 2 !== 0;
|
|
9722
|
+
const cond2 = wbits < 0;
|
|
9723
|
+
if (wbits === 0) {
|
|
9724
|
+
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
|
9725
|
+
}
|
|
9726
|
+
else {
|
|
9727
|
+
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
|
9728
|
+
}
|
|
9729
|
+
}
|
|
9730
|
+
return ExtendedPoint.normalizeZ([p, f])[0];
|
|
9731
|
+
}
|
|
9732
|
+
multiply(scalar, affinePoint) {
|
|
9733
|
+
return this.wNAF(normalizeScalar(scalar, CURVE.l), affinePoint);
|
|
9734
|
+
}
|
|
9735
|
+
multiplyUnsafe(scalar) {
|
|
9736
|
+
let n = normalizeScalar(scalar, CURVE.l, false);
|
|
9737
|
+
const G = ExtendedPoint.BASE;
|
|
9738
|
+
const P0 = ExtendedPoint.ZERO;
|
|
9739
|
+
if (n === _0n$1)
|
|
9740
|
+
return P0;
|
|
9741
|
+
if (this.equals(P0) || n === _1n$1)
|
|
9742
|
+
return this;
|
|
9743
|
+
if (this.equals(G))
|
|
9744
|
+
return this.wNAF(n);
|
|
9745
|
+
let p = P0;
|
|
9746
|
+
let d = this;
|
|
9747
|
+
while (n > _0n$1) {
|
|
9748
|
+
if (n & _1n$1)
|
|
9749
|
+
p = p.add(d);
|
|
9750
|
+
d = d.double();
|
|
9751
|
+
n >>= _1n$1;
|
|
9752
|
+
}
|
|
9753
|
+
return p;
|
|
9754
|
+
}
|
|
9755
|
+
isSmallOrder() {
|
|
9756
|
+
return this.multiplyUnsafe(CURVE.h).equals(ExtendedPoint.ZERO);
|
|
9757
|
+
}
|
|
9758
|
+
isTorsionFree() {
|
|
9759
|
+
let p = this.multiplyUnsafe(CURVE.l / _2n).double();
|
|
9760
|
+
if (CURVE.l % _2n)
|
|
9761
|
+
p = p.add(this);
|
|
9762
|
+
return p.equals(ExtendedPoint.ZERO);
|
|
9763
|
+
}
|
|
9764
|
+
toAffine(invZ) {
|
|
9765
|
+
const { x, y, z } = this;
|
|
9766
|
+
const is0 = this.equals(ExtendedPoint.ZERO);
|
|
9767
|
+
if (invZ == null)
|
|
9768
|
+
invZ = is0 ? _8n : invert(z);
|
|
9769
|
+
const ax = mod$1(x * invZ);
|
|
9770
|
+
const ay = mod$1(y * invZ);
|
|
9771
|
+
const zz = mod$1(z * invZ);
|
|
9772
|
+
if (is0)
|
|
9773
|
+
return Point.ZERO;
|
|
9774
|
+
if (zz !== _1n$1)
|
|
9775
|
+
throw new Error('invZ was invalid');
|
|
9776
|
+
return new Point(ax, ay);
|
|
9777
|
+
}
|
|
9778
|
+
fromRistrettoBytes() {
|
|
9779
|
+
legacyRist();
|
|
9780
|
+
}
|
|
9781
|
+
toRistrettoBytes() {
|
|
9782
|
+
legacyRist();
|
|
9783
|
+
}
|
|
9784
|
+
fromRistrettoHash() {
|
|
9785
|
+
legacyRist();
|
|
9786
|
+
}
|
|
9787
|
+
}
|
|
9788
|
+
ExtendedPoint.BASE = new ExtendedPoint(CURVE.Gx, CURVE.Gy, _1n$1, mod$1(CURVE.Gx * CURVE.Gy));
|
|
9789
|
+
ExtendedPoint.ZERO = new ExtendedPoint(_0n$1, _1n$1, _1n$1, _0n$1);
|
|
9790
|
+
function constTimeNegate(condition, item) {
|
|
9791
|
+
const neg = item.negate();
|
|
9792
|
+
return condition ? neg : item;
|
|
9793
|
+
}
|
|
9794
|
+
function assertExtPoint(other) {
|
|
9795
|
+
if (!(other instanceof ExtendedPoint))
|
|
9796
|
+
throw new TypeError('ExtendedPoint expected');
|
|
9797
|
+
}
|
|
9798
|
+
function assertRstPoint(other) {
|
|
9799
|
+
if (!(other instanceof RistrettoPoint))
|
|
9800
|
+
throw new TypeError('RistrettoPoint expected');
|
|
9801
|
+
}
|
|
9802
|
+
function legacyRist() {
|
|
9803
|
+
throw new Error('Legacy method: switch to RistrettoPoint');
|
|
9804
|
+
}
|
|
9805
|
+
class RistrettoPoint {
|
|
9806
|
+
constructor(ep) {
|
|
9807
|
+
this.ep = ep;
|
|
9808
|
+
}
|
|
9809
|
+
static calcElligatorRistrettoMap(r0) {
|
|
9810
|
+
const { d } = CURVE;
|
|
9811
|
+
const r = mod$1(SQRT_M1 * r0 * r0);
|
|
9812
|
+
const Ns = mod$1((r + _1n$1) * ONE_MINUS_D_SQ);
|
|
9813
|
+
let c = BigInt(-1);
|
|
9814
|
+
const D = mod$1((c - d * r) * mod$1(r + d));
|
|
9815
|
+
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D);
|
|
9816
|
+
let s_ = mod$1(s * r0);
|
|
9817
|
+
if (!edIsNegative(s_))
|
|
9818
|
+
s_ = mod$1(-s_);
|
|
9819
|
+
if (!Ns_D_is_sq)
|
|
9820
|
+
s = s_;
|
|
9821
|
+
if (!Ns_D_is_sq)
|
|
9822
|
+
c = r;
|
|
9823
|
+
const Nt = mod$1(c * (r - _1n$1) * D_MINUS_ONE_SQ - D);
|
|
9824
|
+
const s2 = s * s;
|
|
9825
|
+
const W0 = mod$1((s + s) * D);
|
|
9826
|
+
const W1 = mod$1(Nt * SQRT_AD_MINUS_ONE);
|
|
9827
|
+
const W2 = mod$1(_1n$1 - s2);
|
|
9828
|
+
const W3 = mod$1(_1n$1 + s2);
|
|
9829
|
+
return new ExtendedPoint(mod$1(W0 * W3), mod$1(W2 * W1), mod$1(W1 * W3), mod$1(W0 * W2));
|
|
9830
|
+
}
|
|
9831
|
+
static hashToCurve(hex) {
|
|
9832
|
+
hex = ensureBytes(hex, 64);
|
|
9833
|
+
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
|
9834
|
+
const R1 = this.calcElligatorRistrettoMap(r1);
|
|
9835
|
+
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
|
9836
|
+
const R2 = this.calcElligatorRistrettoMap(r2);
|
|
9837
|
+
return new RistrettoPoint(R1.add(R2));
|
|
9838
|
+
}
|
|
9839
|
+
static fromHex(hex) {
|
|
9840
|
+
hex = ensureBytes(hex, 32);
|
|
9841
|
+
const { a, d } = CURVE;
|
|
9842
|
+
const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
|
|
9843
|
+
const s = bytes255ToNumberLE(hex);
|
|
9844
|
+
if (!equalBytes(numberTo32BytesLE(s), hex) || edIsNegative(s))
|
|
9845
|
+
throw new Error(emsg);
|
|
9846
|
+
const s2 = mod$1(s * s);
|
|
9847
|
+
const u1 = mod$1(_1n$1 + a * s2);
|
|
9848
|
+
const u2 = mod$1(_1n$1 - a * s2);
|
|
9849
|
+
const u1_2 = mod$1(u1 * u1);
|
|
9850
|
+
const u2_2 = mod$1(u2 * u2);
|
|
9851
|
+
const v = mod$1(a * d * u1_2 - u2_2);
|
|
9852
|
+
const { isValid, value: I } = invertSqrt(mod$1(v * u2_2));
|
|
9853
|
+
const Dx = mod$1(I * u2);
|
|
9854
|
+
const Dy = mod$1(I * Dx * v);
|
|
9855
|
+
let x = mod$1((s + s) * Dx);
|
|
9856
|
+
if (edIsNegative(x))
|
|
9857
|
+
x = mod$1(-x);
|
|
9858
|
+
const y = mod$1(u1 * Dy);
|
|
9859
|
+
const t = mod$1(x * y);
|
|
9860
|
+
if (!isValid || edIsNegative(t) || y === _0n$1)
|
|
9861
|
+
throw new Error(emsg);
|
|
9862
|
+
return new RistrettoPoint(new ExtendedPoint(x, y, _1n$1, t));
|
|
9863
|
+
}
|
|
9864
|
+
toRawBytes() {
|
|
9865
|
+
let { x, y, z, t } = this.ep;
|
|
9866
|
+
const u1 = mod$1(mod$1(z + y) * mod$1(z - y));
|
|
9867
|
+
const u2 = mod$1(x * y);
|
|
9868
|
+
const u2sq = mod$1(u2 * u2);
|
|
9869
|
+
const { value: invsqrt } = invertSqrt(mod$1(u1 * u2sq));
|
|
9870
|
+
const D1 = mod$1(invsqrt * u1);
|
|
9871
|
+
const D2 = mod$1(invsqrt * u2);
|
|
9872
|
+
const zInv = mod$1(D1 * D2 * t);
|
|
9873
|
+
let D;
|
|
9874
|
+
if (edIsNegative(t * zInv)) {
|
|
9875
|
+
let _x = mod$1(y * SQRT_M1);
|
|
9876
|
+
let _y = mod$1(x * SQRT_M1);
|
|
9877
|
+
x = _x;
|
|
9878
|
+
y = _y;
|
|
9879
|
+
D = mod$1(D1 * INVSQRT_A_MINUS_D);
|
|
9880
|
+
}
|
|
9881
|
+
else {
|
|
9882
|
+
D = D2;
|
|
9883
|
+
}
|
|
9884
|
+
if (edIsNegative(x * zInv))
|
|
9885
|
+
y = mod$1(-y);
|
|
9886
|
+
let s = mod$1((z - y) * D);
|
|
9887
|
+
if (edIsNegative(s))
|
|
9888
|
+
s = mod$1(-s);
|
|
9889
|
+
return numberTo32BytesLE(s);
|
|
9890
|
+
}
|
|
9891
|
+
toHex() {
|
|
9892
|
+
return bytesToHex(this.toRawBytes());
|
|
9893
|
+
}
|
|
9894
|
+
toString() {
|
|
9895
|
+
return this.toHex();
|
|
9896
|
+
}
|
|
9897
|
+
equals(other) {
|
|
9898
|
+
assertRstPoint(other);
|
|
9899
|
+
const a = this.ep;
|
|
9900
|
+
const b = other.ep;
|
|
9901
|
+
const one = mod$1(a.x * b.y) === mod$1(a.y * b.x);
|
|
9902
|
+
const two = mod$1(a.y * b.y) === mod$1(a.x * b.x);
|
|
9903
|
+
return one || two;
|
|
9904
|
+
}
|
|
9905
|
+
add(other) {
|
|
9906
|
+
assertRstPoint(other);
|
|
9907
|
+
return new RistrettoPoint(this.ep.add(other.ep));
|
|
9908
|
+
}
|
|
9909
|
+
subtract(other) {
|
|
9910
|
+
assertRstPoint(other);
|
|
9911
|
+
return new RistrettoPoint(this.ep.subtract(other.ep));
|
|
9912
|
+
}
|
|
9913
|
+
multiply(scalar) {
|
|
9914
|
+
return new RistrettoPoint(this.ep.multiply(scalar));
|
|
9915
|
+
}
|
|
9916
|
+
multiplyUnsafe(scalar) {
|
|
9917
|
+
return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
|
|
9918
|
+
}
|
|
9919
|
+
}
|
|
9920
|
+
RistrettoPoint.BASE = new RistrettoPoint(ExtendedPoint.BASE);
|
|
9921
|
+
RistrettoPoint.ZERO = new RistrettoPoint(ExtendedPoint.ZERO);
|
|
9922
|
+
const pointPrecomputes = new WeakMap();
|
|
9923
|
+
class Point {
|
|
9924
|
+
constructor(x, y) {
|
|
9925
|
+
this.x = x;
|
|
9926
|
+
this.y = y;
|
|
9927
|
+
}
|
|
9928
|
+
_setWindowSize(windowSize) {
|
|
9929
|
+
this._WINDOW_SIZE = windowSize;
|
|
9930
|
+
pointPrecomputes.delete(this);
|
|
9931
|
+
}
|
|
9932
|
+
static fromHex(hex, strict = true) {
|
|
9933
|
+
const { d, P } = CURVE;
|
|
9934
|
+
hex = ensureBytes(hex, 32);
|
|
9935
|
+
const normed = hex.slice();
|
|
9936
|
+
normed[31] = hex[31] & ~0x80;
|
|
9937
|
+
const y = bytesToNumberLE(normed);
|
|
9938
|
+
if (strict && y >= P)
|
|
9939
|
+
throw new Error('Expected 0 < hex < P');
|
|
9940
|
+
if (!strict && y >= POW_2_256)
|
|
9941
|
+
throw new Error('Expected 0 < hex < 2**256');
|
|
9942
|
+
const y2 = mod$1(y * y);
|
|
9943
|
+
const u = mod$1(y2 - _1n$1);
|
|
9944
|
+
const v = mod$1(d * y2 + _1n$1);
|
|
9945
|
+
let { isValid, value: x } = uvRatio(u, v);
|
|
9946
|
+
if (!isValid)
|
|
9947
|
+
throw new Error('Point.fromHex: invalid y coordinate');
|
|
9948
|
+
const isXOdd = (x & _1n$1) === _1n$1;
|
|
9949
|
+
const isLastByteOdd = (hex[31] & 0x80) !== 0;
|
|
9950
|
+
if (isLastByteOdd !== isXOdd) {
|
|
9951
|
+
x = mod$1(-x);
|
|
9952
|
+
}
|
|
9953
|
+
return new Point(x, y);
|
|
9954
|
+
}
|
|
9955
|
+
static async fromPrivateKey(privateKey) {
|
|
9956
|
+
return (await getExtendedPublicKey(privateKey)).point;
|
|
9957
|
+
}
|
|
9958
|
+
toRawBytes() {
|
|
9959
|
+
const bytes = numberTo32BytesLE(this.y);
|
|
9960
|
+
bytes[31] |= this.x & _1n$1 ? 0x80 : 0;
|
|
9961
|
+
return bytes;
|
|
9962
|
+
}
|
|
9963
|
+
toHex() {
|
|
9964
|
+
return bytesToHex(this.toRawBytes());
|
|
9965
|
+
}
|
|
9966
|
+
toX25519() {
|
|
9967
|
+
const { y } = this;
|
|
9968
|
+
const u = mod$1((_1n$1 + y) * invert(_1n$1 - y));
|
|
9969
|
+
return numberTo32BytesLE(u);
|
|
9970
|
+
}
|
|
9971
|
+
isTorsionFree() {
|
|
9972
|
+
return ExtendedPoint.fromAffine(this).isTorsionFree();
|
|
9973
|
+
}
|
|
9974
|
+
equals(other) {
|
|
9975
|
+
return this.x === other.x && this.y === other.y;
|
|
9976
|
+
}
|
|
9977
|
+
negate() {
|
|
9978
|
+
return new Point(mod$1(-this.x), this.y);
|
|
9979
|
+
}
|
|
9980
|
+
add(other) {
|
|
9981
|
+
return ExtendedPoint.fromAffine(this).add(ExtendedPoint.fromAffine(other)).toAffine();
|
|
9982
|
+
}
|
|
9983
|
+
subtract(other) {
|
|
9984
|
+
return this.add(other.negate());
|
|
9985
|
+
}
|
|
9986
|
+
multiply(scalar) {
|
|
9987
|
+
return ExtendedPoint.fromAffine(this).multiply(scalar, this).toAffine();
|
|
9988
|
+
}
|
|
9989
|
+
}
|
|
9990
|
+
Point.BASE = new Point(CURVE.Gx, CURVE.Gy);
|
|
9991
|
+
Point.ZERO = new Point(_0n$1, _1n$1);
|
|
9992
|
+
let Signature$1 = class Signature {
|
|
9993
|
+
constructor(r, s) {
|
|
9994
|
+
this.r = r;
|
|
9995
|
+
this.s = s;
|
|
9996
|
+
this.assertValidity();
|
|
9997
|
+
}
|
|
9998
|
+
static fromHex(hex) {
|
|
9999
|
+
const bytes = ensureBytes(hex, 64);
|
|
10000
|
+
const r = Point.fromHex(bytes.slice(0, 32), false);
|
|
10001
|
+
const s = bytesToNumberLE(bytes.slice(32, 64));
|
|
10002
|
+
return new Signature(r, s);
|
|
10003
|
+
}
|
|
10004
|
+
assertValidity() {
|
|
10005
|
+
const { r, s } = this;
|
|
10006
|
+
if (!(r instanceof Point))
|
|
10007
|
+
throw new Error('Expected Point instance');
|
|
10008
|
+
normalizeScalar(s, CURVE.l, false);
|
|
10009
|
+
return this;
|
|
10010
|
+
}
|
|
10011
|
+
toRawBytes() {
|
|
10012
|
+
const u8 = new Uint8Array(64);
|
|
10013
|
+
u8.set(this.r.toRawBytes());
|
|
10014
|
+
u8.set(numberTo32BytesLE(this.s), 32);
|
|
10015
|
+
return u8;
|
|
10016
|
+
}
|
|
10017
|
+
toHex() {
|
|
10018
|
+
return bytesToHex(this.toRawBytes());
|
|
10019
|
+
}
|
|
10020
|
+
};
|
|
10021
|
+
function concatBytes(...arrays) {
|
|
10022
|
+
if (!arrays.every((a) => a instanceof Uint8Array))
|
|
10023
|
+
throw new Error('Expected Uint8Array list');
|
|
10024
|
+
if (arrays.length === 1)
|
|
10025
|
+
return arrays[0];
|
|
10026
|
+
const length = arrays.reduce((a, arr) => a + arr.length, 0);
|
|
10027
|
+
const result = new Uint8Array(length);
|
|
10028
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
10029
|
+
const arr = arrays[i];
|
|
10030
|
+
result.set(arr, pad);
|
|
10031
|
+
pad += arr.length;
|
|
10032
|
+
}
|
|
10033
|
+
return result;
|
|
10034
|
+
}
|
|
10035
|
+
const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
|
|
10036
|
+
function bytesToHex(uint8a) {
|
|
10037
|
+
if (!(uint8a instanceof Uint8Array))
|
|
10038
|
+
throw new Error('Uint8Array expected');
|
|
10039
|
+
let hex = '';
|
|
10040
|
+
for (let i = 0; i < uint8a.length; i++) {
|
|
10041
|
+
hex += hexes[uint8a[i]];
|
|
10042
|
+
}
|
|
10043
|
+
return hex;
|
|
10044
|
+
}
|
|
10045
|
+
function hexToBytes(hex) {
|
|
10046
|
+
if (typeof hex !== 'string') {
|
|
10047
|
+
throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
|
|
10048
|
+
}
|
|
10049
|
+
if (hex.length % 2)
|
|
10050
|
+
throw new Error('hexToBytes: received invalid unpadded hex');
|
|
10051
|
+
const array = new Uint8Array(hex.length / 2);
|
|
10052
|
+
for (let i = 0; i < array.length; i++) {
|
|
10053
|
+
const j = i * 2;
|
|
10054
|
+
const hexByte = hex.slice(j, j + 2);
|
|
10055
|
+
const byte = Number.parseInt(hexByte, 16);
|
|
10056
|
+
if (Number.isNaN(byte) || byte < 0)
|
|
10057
|
+
throw new Error('Invalid byte sequence');
|
|
10058
|
+
array[i] = byte;
|
|
10059
|
+
}
|
|
10060
|
+
return array;
|
|
10061
|
+
}
|
|
10062
|
+
function numberTo32BytesBE(num) {
|
|
10063
|
+
const length = 32;
|
|
10064
|
+
const hex = num.toString(16).padStart(length * 2, '0');
|
|
10065
|
+
return hexToBytes(hex);
|
|
10066
|
+
}
|
|
10067
|
+
function numberTo32BytesLE(num) {
|
|
10068
|
+
return numberTo32BytesBE(num).reverse();
|
|
10069
|
+
}
|
|
10070
|
+
function edIsNegative(num) {
|
|
10071
|
+
return (mod$1(num) & _1n$1) === _1n$1;
|
|
10072
|
+
}
|
|
10073
|
+
function bytesToNumberLE(uint8a) {
|
|
10074
|
+
if (!(uint8a instanceof Uint8Array))
|
|
10075
|
+
throw new Error('Expected Uint8Array');
|
|
10076
|
+
return BigInt('0x' + bytesToHex(Uint8Array.from(uint8a).reverse()));
|
|
10077
|
+
}
|
|
10078
|
+
const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
|
10079
|
+
function bytes255ToNumberLE(bytes) {
|
|
10080
|
+
return mod$1(bytesToNumberLE(bytes) & MAX_255B);
|
|
10081
|
+
}
|
|
10082
|
+
function mod$1(a, b = CURVE.P) {
|
|
10083
|
+
const res = a % b;
|
|
10084
|
+
return res >= _0n$1 ? res : b + res;
|
|
10085
|
+
}
|
|
10086
|
+
function invert(number, modulo = CURVE.P) {
|
|
10087
|
+
if (number === _0n$1 || modulo <= _0n$1) {
|
|
10088
|
+
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
|
10089
|
+
}
|
|
10090
|
+
let a = mod$1(number, modulo);
|
|
10091
|
+
let b = modulo;
|
|
10092
|
+
let x = _0n$1, u = _1n$1;
|
|
10093
|
+
while (a !== _0n$1) {
|
|
10094
|
+
const q = b / a;
|
|
10095
|
+
const r = b % a;
|
|
10096
|
+
const m = x - u * q;
|
|
10097
|
+
b = a, a = r, x = u, u = m;
|
|
10098
|
+
}
|
|
10099
|
+
const gcd = b;
|
|
10100
|
+
if (gcd !== _1n$1)
|
|
10101
|
+
throw new Error('invert: does not exist');
|
|
10102
|
+
return mod$1(x, modulo);
|
|
10103
|
+
}
|
|
10104
|
+
function invertBatch(nums, p = CURVE.P) {
|
|
10105
|
+
const tmp = new Array(nums.length);
|
|
10106
|
+
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
10107
|
+
if (num === _0n$1)
|
|
10108
|
+
return acc;
|
|
10109
|
+
tmp[i] = acc;
|
|
10110
|
+
return mod$1(acc * num, p);
|
|
10111
|
+
}, _1n$1);
|
|
10112
|
+
const inverted = invert(lastMultiplied, p);
|
|
10113
|
+
nums.reduceRight((acc, num, i) => {
|
|
10114
|
+
if (num === _0n$1)
|
|
10115
|
+
return acc;
|
|
10116
|
+
tmp[i] = mod$1(acc * tmp[i], p);
|
|
10117
|
+
return mod$1(acc * num, p);
|
|
10118
|
+
}, inverted);
|
|
10119
|
+
return tmp;
|
|
10120
|
+
}
|
|
10121
|
+
function pow2(x, power) {
|
|
10122
|
+
const { P } = CURVE;
|
|
10123
|
+
let res = x;
|
|
10124
|
+
while (power-- > _0n$1) {
|
|
10125
|
+
res *= res;
|
|
10126
|
+
res %= P;
|
|
10127
|
+
}
|
|
10128
|
+
return res;
|
|
10129
|
+
}
|
|
10130
|
+
function pow_2_252_3(x) {
|
|
10131
|
+
const { P } = CURVE;
|
|
10132
|
+
const _5n = BigInt(5);
|
|
10133
|
+
const _10n = BigInt(10);
|
|
10134
|
+
const _20n = BigInt(20);
|
|
10135
|
+
const _40n = BigInt(40);
|
|
10136
|
+
const _80n = BigInt(80);
|
|
10137
|
+
const x2 = (x * x) % P;
|
|
10138
|
+
const b2 = (x2 * x) % P;
|
|
10139
|
+
const b4 = (pow2(b2, _2n) * b2) % P;
|
|
10140
|
+
const b5 = (pow2(b4, _1n$1) * x) % P;
|
|
10141
|
+
const b10 = (pow2(b5, _5n) * b5) % P;
|
|
10142
|
+
const b20 = (pow2(b10, _10n) * b10) % P;
|
|
10143
|
+
const b40 = (pow2(b20, _20n) * b20) % P;
|
|
10144
|
+
const b80 = (pow2(b40, _40n) * b40) % P;
|
|
10145
|
+
const b160 = (pow2(b80, _80n) * b80) % P;
|
|
10146
|
+
const b240 = (pow2(b160, _80n) * b80) % P;
|
|
10147
|
+
const b250 = (pow2(b240, _10n) * b10) % P;
|
|
10148
|
+
const pow_p_5_8 = (pow2(b250, _2n) * x) % P;
|
|
10149
|
+
return { pow_p_5_8, b2 };
|
|
10150
|
+
}
|
|
10151
|
+
function uvRatio(u, v) {
|
|
10152
|
+
const v3 = mod$1(v * v * v);
|
|
10153
|
+
const v7 = mod$1(v3 * v3 * v);
|
|
10154
|
+
const pow = pow_2_252_3(u * v7).pow_p_5_8;
|
|
10155
|
+
let x = mod$1(u * v3 * pow);
|
|
10156
|
+
const vx2 = mod$1(v * x * x);
|
|
10157
|
+
const root1 = x;
|
|
10158
|
+
const root2 = mod$1(x * SQRT_M1);
|
|
10159
|
+
const useRoot1 = vx2 === u;
|
|
10160
|
+
const useRoot2 = vx2 === mod$1(-u);
|
|
10161
|
+
const noRoot = vx2 === mod$1(-u * SQRT_M1);
|
|
10162
|
+
if (useRoot1)
|
|
10163
|
+
x = root1;
|
|
10164
|
+
if (useRoot2 || noRoot)
|
|
10165
|
+
x = root2;
|
|
10166
|
+
if (edIsNegative(x))
|
|
10167
|
+
x = mod$1(-x);
|
|
10168
|
+
return { isValid: useRoot1 || useRoot2, value: x };
|
|
10169
|
+
}
|
|
10170
|
+
function invertSqrt(number) {
|
|
10171
|
+
return uvRatio(_1n$1, number);
|
|
10172
|
+
}
|
|
10173
|
+
function modlLE(hash) {
|
|
10174
|
+
return mod$1(bytesToNumberLE(hash), CURVE.l);
|
|
10175
|
+
}
|
|
10176
|
+
function equalBytes(b1, b2) {
|
|
10177
|
+
if (b1.length !== b2.length) {
|
|
10178
|
+
return false;
|
|
10179
|
+
}
|
|
10180
|
+
for (let i = 0; i < b1.length; i++) {
|
|
10181
|
+
if (b1[i] !== b2[i]) {
|
|
10182
|
+
return false;
|
|
10183
|
+
}
|
|
10184
|
+
}
|
|
10185
|
+
return true;
|
|
10186
|
+
}
|
|
10187
|
+
function ensureBytes(hex, expectedLength) {
|
|
10188
|
+
const bytes = hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes(hex);
|
|
10189
|
+
if (typeof expectedLength === 'number' && bytes.length !== expectedLength)
|
|
10190
|
+
throw new Error(`Expected ${expectedLength} bytes`);
|
|
10191
|
+
return bytes;
|
|
10192
|
+
}
|
|
10193
|
+
function normalizeScalar(num, max, strict = true) {
|
|
10194
|
+
if (!max)
|
|
10195
|
+
throw new TypeError('Specify max value');
|
|
10196
|
+
if (typeof num === 'number' && Number.isSafeInteger(num))
|
|
10197
|
+
num = BigInt(num);
|
|
10198
|
+
if (typeof num === 'bigint' && num < max) {
|
|
10199
|
+
if (strict) {
|
|
10200
|
+
if (_0n$1 < num)
|
|
10201
|
+
return num;
|
|
10202
|
+
}
|
|
10203
|
+
else {
|
|
10204
|
+
if (_0n$1 <= num)
|
|
10205
|
+
return num;
|
|
10206
|
+
}
|
|
10207
|
+
}
|
|
10208
|
+
throw new TypeError('Expected valid scalar: 0 < scalar < max');
|
|
10209
|
+
}
|
|
10210
|
+
function adjustBytes25519(bytes) {
|
|
10211
|
+
bytes[0] &= 248;
|
|
10212
|
+
bytes[31] &= 127;
|
|
10213
|
+
bytes[31] |= 64;
|
|
10214
|
+
return bytes;
|
|
10215
|
+
}
|
|
10216
|
+
function checkPrivateKey(key) {
|
|
10217
|
+
key =
|
|
10218
|
+
typeof key === 'bigint' || typeof key === 'number'
|
|
10219
|
+
? numberTo32BytesBE(normalizeScalar(key, POW_2_256))
|
|
10220
|
+
: ensureBytes(key);
|
|
10221
|
+
if (key.length !== 32)
|
|
10222
|
+
throw new Error(`Expected 32 bytes`);
|
|
10223
|
+
return key;
|
|
10224
|
+
}
|
|
10225
|
+
function getKeyFromHash(hashed) {
|
|
10226
|
+
const head = adjustBytes25519(hashed.slice(0, 32));
|
|
10227
|
+
const prefix = hashed.slice(32, 64);
|
|
10228
|
+
const scalar = modlLE(head);
|
|
10229
|
+
const point = Point.BASE.multiply(scalar);
|
|
10230
|
+
const pointBytes = point.toRawBytes();
|
|
10231
|
+
return { head, prefix, scalar, point, pointBytes };
|
|
10232
|
+
}
|
|
10233
|
+
let _sha512Sync;
|
|
10234
|
+
async function getExtendedPublicKey(key) {
|
|
10235
|
+
return getKeyFromHash(await utils.sha512(checkPrivateKey(key)));
|
|
10236
|
+
}
|
|
10237
|
+
function prepareVerification(sig, message, publicKey) {
|
|
10238
|
+
message = ensureBytes(message);
|
|
10239
|
+
if (!(publicKey instanceof Point))
|
|
10240
|
+
publicKey = Point.fromHex(publicKey, false);
|
|
10241
|
+
const { r, s } = sig instanceof Signature$1 ? sig.assertValidity() : Signature$1.fromHex(sig);
|
|
10242
|
+
const SB = ExtendedPoint.BASE.multiplyUnsafe(s);
|
|
10243
|
+
return { r, s, SB, pub: publicKey, msg: message };
|
|
10244
|
+
}
|
|
10245
|
+
function finishVerification(publicKey, r, SB, hashed) {
|
|
10246
|
+
const k = modlLE(hashed);
|
|
10247
|
+
const kA = ExtendedPoint.fromAffine(publicKey).multiplyUnsafe(k);
|
|
10248
|
+
const RkA = ExtendedPoint.fromAffine(r).add(kA);
|
|
10249
|
+
return RkA.subtract(SB).multiplyUnsafe(CURVE.h).equals(ExtendedPoint.ZERO);
|
|
10250
|
+
}
|
|
10251
|
+
async function verify$6(sig, message, publicKey) {
|
|
10252
|
+
const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
|
|
10253
|
+
const hashed = await utils.sha512(r.toRawBytes(), pub.toRawBytes(), msg);
|
|
10254
|
+
return finishVerification(pub, r, SB, hashed);
|
|
10255
|
+
}
|
|
10256
|
+
Point.BASE._setWindowSize(8);
|
|
10257
|
+
const crypto$2 = {
|
|
10258
|
+
node: nodeCrypto$2,
|
|
10259
|
+
web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
|
|
10260
|
+
};
|
|
10261
|
+
const utils = {
|
|
10262
|
+
bytesToHex,
|
|
10263
|
+
hexToBytes,
|
|
10264
|
+
concatBytes,
|
|
10265
|
+
getExtendedPublicKey,
|
|
10266
|
+
mod: mod$1,
|
|
10267
|
+
invert,
|
|
10268
|
+
TORSION_SUBGROUP: [
|
|
10269
|
+
'0100000000000000000000000000000000000000000000000000000000000000',
|
|
10270
|
+
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',
|
|
10271
|
+
'0000000000000000000000000000000000000000000000000000000000000080',
|
|
10272
|
+
'26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',
|
|
10273
|
+
'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
|
10274
|
+
'26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',
|
|
10275
|
+
'0000000000000000000000000000000000000000000000000000000000000000',
|
|
10276
|
+
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
|
|
10277
|
+
],
|
|
10278
|
+
hashToPrivateScalar: (hash) => {
|
|
10279
|
+
hash = ensureBytes(hash);
|
|
10280
|
+
if (hash.length < 40 || hash.length > 1024)
|
|
10281
|
+
throw new Error('Expected 40-1024 bytes of private key as per FIPS 186');
|
|
10282
|
+
return mod$1(bytesToNumberLE(hash), CURVE.l - _1n$1) + _1n$1;
|
|
10283
|
+
},
|
|
10284
|
+
randomBytes: (bytesLength = 32) => {
|
|
10285
|
+
if (crypto$2.web) {
|
|
10286
|
+
return crypto$2.web.getRandomValues(new Uint8Array(bytesLength));
|
|
10287
|
+
}
|
|
10288
|
+
else {
|
|
10289
|
+
throw new Error("The environment doesn't have randomBytes function");
|
|
10290
|
+
}
|
|
10291
|
+
},
|
|
10292
|
+
randomPrivateKey: () => {
|
|
10293
|
+
return utils.randomBytes(32);
|
|
10294
|
+
},
|
|
10295
|
+
sha512: async (...messages) => {
|
|
10296
|
+
const message = concatBytes(...messages);
|
|
10297
|
+
if (crypto$2.web) {
|
|
10298
|
+
const buffer = await crypto$2.web.subtle.digest('SHA-512', message.buffer);
|
|
10299
|
+
return new Uint8Array(buffer);
|
|
10300
|
+
}
|
|
10301
|
+
else {
|
|
10302
|
+
throw new Error("The environment doesn't have sha512 function");
|
|
10303
|
+
}
|
|
10304
|
+
},
|
|
10305
|
+
precompute(windowSize = 8, point = Point.BASE) {
|
|
10306
|
+
const cached = point.equals(Point.BASE) ? point : new Point(point.x, point.y);
|
|
10307
|
+
cached._setWindowSize(windowSize);
|
|
10308
|
+
cached.multiply(_2n);
|
|
10309
|
+
return cached;
|
|
10310
|
+
},
|
|
10311
|
+
sha512Sync: undefined,
|
|
10312
|
+
};
|
|
10313
|
+
Object.defineProperties(utils, {
|
|
10314
|
+
sha512Sync: {
|
|
10315
|
+
configurable: false,
|
|
10316
|
+
get() {
|
|
10317
|
+
return _sha512Sync;
|
|
10318
|
+
},
|
|
10319
|
+
set(val) {
|
|
10320
|
+
if (!_sha512Sync)
|
|
10321
|
+
_sha512Sync = val;
|
|
10322
|
+
},
|
|
10323
|
+
},
|
|
9523
10324
|
});
|
|
9524
10325
|
|
|
9525
10326
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -9555,6 +10356,8 @@ var ecdsa = /*#__PURE__*/Object.freeze({
|
|
|
9555
10356
|
* @async
|
|
9556
10357
|
*/
|
|
9557
10358
|
async function sign$5(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
10359
|
+
const curve = new CurveWithOID(oid);
|
|
10360
|
+
checkPublicPointEnconding(curve, publicKey);
|
|
9558
10361
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
|
9559
10362
|
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
9560
10363
|
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
@@ -9581,11 +10384,13 @@ async function sign$5(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
9581
10384
|
* @async
|
|
9582
10385
|
*/
|
|
9583
10386
|
async function verify$5(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
|
10387
|
+
const curve = new CurveWithOID(oid);
|
|
10388
|
+
checkPublicPointEnconding(curve, publicKey);
|
|
9584
10389
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
|
9585
10390
|
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
9586
10391
|
}
|
|
9587
10392
|
const signature = util.concatUint8Array([r, s]);
|
|
9588
|
-
return
|
|
10393
|
+
return verify$6(signature, hashed, publicKey.subarray(1));
|
|
9589
10394
|
}
|
|
9590
10395
|
/**
|
|
9591
10396
|
* Validate legacy EdDSA parameters
|
|
@@ -9711,7 +10516,7 @@ async function verify$4(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
|
9711
10516
|
}
|
|
9712
10517
|
switch (algo) {
|
|
9713
10518
|
case enums.publicKey.ed25519:
|
|
9714
|
-
return
|
|
10519
|
+
return verify$6(RS, hashed, publicKey);
|
|
9715
10520
|
case enums.publicKey.ed448: {
|
|
9716
10521
|
const ed448 = await util.getNobleCurve(enums.publicKey.ed448);
|
|
9717
10522
|
return ed448.verify(RS, hashed, publicKey);
|
|
@@ -10075,7 +10880,7 @@ function buildEcdhParam(public_algo, oid, kdfParams, fingerprint) {
|
|
|
10075
10880
|
new Uint8Array([public_algo]),
|
|
10076
10881
|
kdfParams.write(true),
|
|
10077
10882
|
util.stringToUint8Array('Anonymous Sender '),
|
|
10078
|
-
kdfParams.replacementFingerprint || fingerprint
|
|
10883
|
+
kdfParams.replacementFingerprint || fingerprint
|
|
10079
10884
|
]);
|
|
10080
10885
|
}
|
|
10081
10886
|
|
|
@@ -10117,7 +10922,7 @@ async function genPublicEphemeralKey(curve, Q) {
|
|
|
10117
10922
|
const d = getRandomBytes(32);
|
|
10118
10923
|
const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d);
|
|
10119
10924
|
let { publicKey } = nacl.box.keyPair.fromSecretKey(secretKey);
|
|
10120
|
-
publicKey = util.concatUint8Array([new Uint8Array([
|
|
10925
|
+
publicKey = util.concatUint8Array([new Uint8Array([curve.wireFormatLeadingByte]), publicKey]);
|
|
10121
10926
|
return { publicKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
|
|
10122
10927
|
}
|
|
10123
10928
|
case 'web':
|
|
@@ -10145,7 +10950,7 @@ async function genPublicEphemeralKey(curve, Q) {
|
|
|
10145
10950
|
* @param {module:type/kdf_params} kdfParams - KDF params including cipher and algorithm to use
|
|
10146
10951
|
* @param {Uint8Array} data - Unpadded session key data
|
|
10147
10952
|
* @param {Uint8Array} Q - Recipient public key
|
|
10148
|
-
* @param {Uint8Array} fingerprint - Recipient fingerprint
|
|
10953
|
+
* @param {Uint8Array} fingerprint - Recipient fingerprint, already truncated depending on the key version
|
|
10149
10954
|
* @returns {Promise<{publicKey: Uint8Array, wrappedKey: Uint8Array}>}
|
|
10150
10955
|
* @async
|
|
10151
10956
|
*/
|
|
@@ -10153,6 +10958,7 @@ async function encrypt$2(oid, kdfParams, data, Q, fingerprint) {
|
|
|
10153
10958
|
const m = encode(data);
|
|
10154
10959
|
|
|
10155
10960
|
const curve = new CurveWithOID(oid);
|
|
10961
|
+
checkPublicPointEnconding(curve, Q);
|
|
10156
10962
|
const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
|
|
10157
10963
|
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
|
|
10158
10964
|
const { keySize } = getCipherParams(kdfParams.cipher);
|
|
@@ -10209,12 +11015,14 @@ async function genPrivateEphemeralKey(curve, V, Q, d) {
|
|
|
10209
11015
|
* @param {Uint8Array} C - Encrypted and wrapped value derived from session key
|
|
10210
11016
|
* @param {Uint8Array} Q - Recipient public key
|
|
10211
11017
|
* @param {Uint8Array} d - Recipient private key
|
|
10212
|
-
* @param {Uint8Array} fingerprint - Recipient fingerprint
|
|
11018
|
+
* @param {Uint8Array} fingerprint - Recipient fingerprint, already truncated depending on the key version
|
|
10213
11019
|
* @returns {Promise<Uint8Array>} Value derived from session key.
|
|
10214
11020
|
* @async
|
|
10215
11021
|
*/
|
|
10216
11022
|
async function decrypt$2(oid, kdfParams, V, C, Q, d, fingerprint) {
|
|
10217
11023
|
const curve = new CurveWithOID(oid);
|
|
11024
|
+
checkPublicPointEnconding(curve, Q);
|
|
11025
|
+
checkPublicPointEnconding(curve, V);
|
|
10218
11026
|
const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
|
|
10219
11027
|
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
|
|
10220
11028
|
const { keySize } = getCipherParams(kdfParams.cipher);
|
|
@@ -10346,7 +11154,7 @@ async function webPublicEphemeralKey(curve, Q) {
|
|
|
10346
11154
|
);
|
|
10347
11155
|
[s, p] = await Promise.all([s, p]);
|
|
10348
11156
|
const sharedKey = new Uint8Array(s);
|
|
10349
|
-
const publicKey = new Uint8Array(jwkToRawPublic(p));
|
|
11157
|
+
const publicKey = new Uint8Array(jwkToRawPublic(p, curve.wireFormatLeadingByte));
|
|
10350
11158
|
return { publicKey, sharedKey };
|
|
10351
11159
|
}
|
|
10352
11160
|
|
|
@@ -10669,14 +11477,14 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
|
|
|
10669
11477
|
let r;
|
|
10670
11478
|
let s;
|
|
10671
11479
|
let t;
|
|
10672
|
-
g = mod$
|
|
10673
|
-
x = mod$
|
|
11480
|
+
g = mod$2(g, p);
|
|
11481
|
+
x = mod$2(x, q);
|
|
10674
11482
|
// If the output size of the chosen hash is larger than the number of
|
|
10675
11483
|
// bits of q, the hash result is truncated to fit by taking the number
|
|
10676
11484
|
// of leftmost bits equal to the number of bits of q. This (possibly
|
|
10677
11485
|
// truncated) hash function result is treated as a number and used
|
|
10678
11486
|
// directly in the DSA signature algorithm.
|
|
10679
|
-
const h = mod$
|
|
11487
|
+
const h = mod$2(uint8ArrayToBigInt(hashed.subarray(0, byteLength(q))), q);
|
|
10680
11488
|
// FIPS-186-4, section 4.6:
|
|
10681
11489
|
// The values of r and s shall be checked to determine if r = 0 or s = 0.
|
|
10682
11490
|
// If either r = 0 or s = 0, a new value of k shall be generated, and the
|
|
@@ -10685,13 +11493,13 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
|
|
|
10685
11493
|
while (true) {
|
|
10686
11494
|
// See Appendix B here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
|
|
10687
11495
|
k = getRandomBigInteger(_1n, q); // returns in [1, q-1]
|
|
10688
|
-
r = mod$
|
|
11496
|
+
r = mod$2(modExp(g, k, p), q); // (g**k mod p) mod q
|
|
10689
11497
|
if (r === _0n) {
|
|
10690
11498
|
continue;
|
|
10691
11499
|
}
|
|
10692
|
-
const xr = mod$
|
|
10693
|
-
t = mod$
|
|
10694
|
-
s = mod$
|
|
11500
|
+
const xr = mod$2(x * r, q);
|
|
11501
|
+
t = mod$2(h + xr, q); // H(m) + x*r mod q
|
|
11502
|
+
s = mod$2(modInv(k, q) * t, q); // k**-1 * (H(m) + x*r) mod q
|
|
10695
11503
|
if (s === _0n) {
|
|
10696
11504
|
continue;
|
|
10697
11505
|
}
|
|
@@ -10730,20 +11538,20 @@ async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
|
|
|
10730
11538
|
util.printDebug('invalid DSA Signature');
|
|
10731
11539
|
return false;
|
|
10732
11540
|
}
|
|
10733
|
-
const h = mod$
|
|
11541
|
+
const h = mod$2(uint8ArrayToBigInt(hashed.subarray(0, byteLength(q))), q);
|
|
10734
11542
|
const w = modInv(s, q); // s**-1 mod q
|
|
10735
11543
|
if (w === _0n) {
|
|
10736
11544
|
util.printDebug('invalid DSA Signature');
|
|
10737
11545
|
return false;
|
|
10738
11546
|
}
|
|
10739
11547
|
|
|
10740
|
-
g = mod$
|
|
10741
|
-
y = mod$
|
|
10742
|
-
const u1 = mod$
|
|
10743
|
-
const u2 = mod$
|
|
11548
|
+
g = mod$2(g, p);
|
|
11549
|
+
y = mod$2(y, p);
|
|
11550
|
+
const u1 = mod$2(h * w, q); // H(m) * w mod q
|
|
11551
|
+
const u2 = mod$2(r * w, q); // r * w mod q
|
|
10744
11552
|
const t1 = modExp(g, u1, p); // g**u1 mod p
|
|
10745
11553
|
const t2 = modExp(y, u2, p); // y**u2 mod p
|
|
10746
|
-
const v = mod$
|
|
11554
|
+
const v = mod$2(mod$2(t1 * t2, p), q); // (g**u1 * y**u2 mod p) mod q
|
|
10747
11555
|
return v === r;
|
|
10748
11556
|
}
|
|
10749
11557
|
|
|
@@ -10770,7 +11578,7 @@ async function validateParams$1(p, q, g, y, x) {
|
|
|
10770
11578
|
/**
|
|
10771
11579
|
* Check that subgroup order q divides p-1
|
|
10772
11580
|
*/
|
|
10773
|
-
if (mod$
|
|
11581
|
+
if (mod$2(p - _1n, q) !== _0n) {
|
|
10774
11582
|
return false;
|
|
10775
11583
|
}
|
|
10776
11584
|
|
|
@@ -11567,6 +12375,9 @@ function parsePublicKeyParams(algo, bytes) {
|
|
|
11567
12375
|
case enums.publicKey.eddsaLegacy: {
|
|
11568
12376
|
const oid = new OID(); read += oid.read(bytes);
|
|
11569
12377
|
checkSupportedCurve(oid);
|
|
12378
|
+
if (oid.getName() !== enums.curve.ed25519Legacy) {
|
|
12379
|
+
throw new Error('Unexpected OID for eddsaLegacy');
|
|
12380
|
+
}
|
|
11570
12381
|
let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
|
|
11571
12382
|
Q = util.leftPad(Q, 33);
|
|
11572
12383
|
return { read: read, publicParams: { oid, Q } };
|
|
@@ -11630,6 +12441,9 @@ function parsePrivateKeyParams(algo, bytes, publicParams) {
|
|
|
11630
12441
|
}
|
|
11631
12442
|
case enums.publicKey.eddsaLegacy: {
|
|
11632
12443
|
const payloadSize = getCurvePayloadSize(algo, publicParams.oid);
|
|
12444
|
+
if (publicParams.oid.getName() !== enums.curve.ed25519Legacy) {
|
|
12445
|
+
throw new Error('Unexpected OID for eddsaLegacy');
|
|
12446
|
+
}
|
|
11633
12447
|
let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2;
|
|
11634
12448
|
seed = util.leftPad(seed, payloadSize);
|
|
11635
12449
|
return { read, privateParams: { seed } };
|
|
@@ -14460,6 +15274,7 @@ class SignaturePacket {
|
|
|
14460
15274
|
|
|
14461
15275
|
this.signatureData = null;
|
|
14462
15276
|
this.unhashedSubpackets = [];
|
|
15277
|
+
this.unknownSubpackets = [];
|
|
14463
15278
|
this.signedHashValue = null;
|
|
14464
15279
|
this.salt = null;
|
|
14465
15280
|
|
|
@@ -14509,9 +15324,12 @@ class SignaturePacket {
|
|
|
14509
15324
|
* @param {String} bytes - Payload of a tag 2 packet
|
|
14510
15325
|
* @returns {SignaturePacket} Object representation.
|
|
14511
15326
|
*/
|
|
14512
|
-
read(bytes) {
|
|
15327
|
+
read(bytes, config$1 = config) {
|
|
14513
15328
|
let i = 0;
|
|
14514
15329
|
this.version = bytes[i++];
|
|
15330
|
+
if (this.version === 5 && !config$1.enableParsingV5Entities) {
|
|
15331
|
+
throw new UnsupportedError('Support for v5 entities is disabled; turn on `config.enableParsingV5Entities` if needed');
|
|
15332
|
+
}
|
|
14515
15333
|
|
|
14516
15334
|
if (this.version !== 4 && this.version !== 5 && this.version !== 6) {
|
|
14517
15335
|
throw new UnsupportedError(`Version ${this.version} of the signature packet is unsupported.`);
|
|
@@ -14788,10 +15606,8 @@ class SignaturePacket {
|
|
|
14788
15606
|
* @returns {Uint8Array} Subpacket data.
|
|
14789
15607
|
*/
|
|
14790
15608
|
writeUnhashedSubPackets() {
|
|
14791
|
-
const arr =
|
|
14792
|
-
|
|
14793
|
-
arr.push(writeSimpleLength(data.length));
|
|
14794
|
-
arr.push(data);
|
|
15609
|
+
const arr = this.unhashedSubpackets.map(({ type, critical, body }) => {
|
|
15610
|
+
return writeSubPacket(type, critical, body);
|
|
14795
15611
|
});
|
|
14796
15612
|
|
|
14797
15613
|
const result = util.concat(arr);
|
|
@@ -14800,7 +15616,7 @@ class SignaturePacket {
|
|
|
14800
15616
|
return util.concat([length, result]);
|
|
14801
15617
|
}
|
|
14802
15618
|
|
|
14803
|
-
//
|
|
15619
|
+
// Signature subpackets
|
|
14804
15620
|
readSubPacket(bytes, hashed = true) {
|
|
14805
15621
|
let mypos = 0;
|
|
14806
15622
|
|
|
@@ -14808,15 +15624,19 @@ class SignaturePacket {
|
|
|
14808
15624
|
const critical = !!(bytes[mypos] & 0x80);
|
|
14809
15625
|
const type = bytes[mypos] & 0x7F;
|
|
14810
15626
|
|
|
15627
|
+
mypos++;
|
|
15628
|
+
|
|
14811
15629
|
if (!hashed) {
|
|
14812
|
-
this.unhashedSubpackets.push(
|
|
15630
|
+
this.unhashedSubpackets.push({
|
|
15631
|
+
type,
|
|
15632
|
+
critical,
|
|
15633
|
+
body: bytes.subarray(mypos, bytes.length)
|
|
15634
|
+
});
|
|
14813
15635
|
if (!allowedUnhashedSubpackets.has(type)) {
|
|
14814
15636
|
return;
|
|
14815
15637
|
}
|
|
14816
15638
|
}
|
|
14817
15639
|
|
|
14818
|
-
mypos++;
|
|
14819
|
-
|
|
14820
15640
|
// subpacket type
|
|
14821
15641
|
switch (type) {
|
|
14822
15642
|
case enums.signatureSubpacket.signatureCreationTime:
|
|
@@ -14988,14 +15808,13 @@ class SignaturePacket {
|
|
|
14988
15808
|
this.preferredCipherSuites.push([bytes[i], bytes[i + 1]]);
|
|
14989
15809
|
}
|
|
14990
15810
|
break;
|
|
14991
|
-
default:
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
|
|
14996
|
-
|
|
14997
|
-
|
|
14998
|
-
}
|
|
15811
|
+
default:
|
|
15812
|
+
this.unknownSubpackets.push({
|
|
15813
|
+
type,
|
|
15814
|
+
critical,
|
|
15815
|
+
body: bytes.subarray(mypos, bytes.length)
|
|
15816
|
+
});
|
|
15817
|
+
break;
|
|
14999
15818
|
}
|
|
15000
15819
|
}
|
|
15001
15820
|
|
|
@@ -15195,6 +16014,11 @@ class SignaturePacket {
|
|
|
15195
16014
|
[enums.signature.binary, enums.signature.text].includes(this.signatureType)) {
|
|
15196
16015
|
throw new Error('Insecure message hash algorithm: ' + enums.read(enums.hash, this.hashAlgorithm).toUpperCase());
|
|
15197
16016
|
}
|
|
16017
|
+
this.unknownSubpackets.forEach(({ type, critical }) => {
|
|
16018
|
+
if (critical) {
|
|
16019
|
+
throw new Error(`Unknown critical signature subpacket type ${type}`);
|
|
16020
|
+
}
|
|
16021
|
+
});
|
|
15198
16022
|
this.rawNotations.forEach(({ name, critical }) => {
|
|
15199
16023
|
if (critical && (config$1.knownNotations.indexOf(name) < 0)) {
|
|
15200
16024
|
throw new Error(`Unknown critical notation: ${name}`);
|
|
@@ -16494,10 +17318,11 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
16494
17318
|
// No symmetric encryption algorithm identifier is passed to the public-key algorithm for a
|
|
16495
17319
|
// v6 PKESK packet, as it is included in the v2 SEIPD packet.
|
|
16496
17320
|
const sessionKeyAlgorithm = this.version === 3 ? this.sessionKeyAlgorithm : null;
|
|
17321
|
+
const fingerprint = key.version === 5 ? key.getFingerprintBytes().subarray(0, 20) : key.getFingerprintBytes();
|
|
16497
17322
|
const encoded = encodeSessionKey(this.version, algo, sessionKeyAlgorithm, this.sessionKey);
|
|
16498
17323
|
const privateParams = algo === enums.publicKey.aead ? key.privateParams : null;
|
|
16499
17324
|
this.encrypted = await mod.publicKeyEncrypt(
|
|
16500
|
-
algo, sessionKeyAlgorithm, key.publicParams, privateParams, encoded,
|
|
17325
|
+
algo, sessionKeyAlgorithm, key.publicParams, privateParams, encoded, fingerprint);
|
|
16501
17326
|
}
|
|
16502
17327
|
|
|
16503
17328
|
/**
|
|
@@ -16517,7 +17342,8 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
16517
17342
|
const randomPayload = randomSessionKey ?
|
|
16518
17343
|
encodeSessionKey(this.version, this.publicKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKey) :
|
|
16519
17344
|
null;
|
|
16520
|
-
const
|
|
17345
|
+
const fingerprint = key.version === 5 ? key.getFingerprintBytes().subarray(0, 20) : key.getFingerprintBytes();
|
|
17346
|
+
const decryptedData = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, fingerprint, randomPayload);
|
|
16521
17347
|
|
|
16522
17348
|
const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
|
|
16523
17349
|
|
|
@@ -16922,10 +17748,13 @@ class PublicKeyPacket {
|
|
|
16922
17748
|
* @returns {Object} This object with attributes set by the parser
|
|
16923
17749
|
* @async
|
|
16924
17750
|
*/
|
|
16925
|
-
async read(bytes) {
|
|
17751
|
+
async read(bytes, config$1 = config) {
|
|
16926
17752
|
let pos = 0;
|
|
16927
17753
|
// A one-octet version number (4, 5 or 6).
|
|
16928
17754
|
this.version = bytes[pos++];
|
|
17755
|
+
if (this.version === 5 && !config$1.enableParsingV5Entities) {
|
|
17756
|
+
throw new UnsupportedError('Support for parsing v5 entities is disabled; turn on `config.enableParsingV5Entities` if needed');
|
|
17757
|
+
}
|
|
16929
17758
|
|
|
16930
17759
|
if (this.version === 4 || this.version === 5 || this.version === 6) {
|
|
16931
17760
|
// - A four-octet number denoting the time that the key was created.
|
|
@@ -17517,7 +18346,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
17517
18346
|
*/
|
|
17518
18347
|
async read(bytes, config$1 = config) {
|
|
17519
18348
|
// - A Public-Key or Public-Subkey packet, as described above.
|
|
17520
|
-
let i = await this.readPublicKey(bytes);
|
|
18349
|
+
let i = await this.readPublicKey(bytes, config$1);
|
|
17521
18350
|
const startOfSecretKeyData = i;
|
|
17522
18351
|
|
|
17523
18352
|
// - One octet indicating string-to-key usage conventions. Zero
|
|
@@ -17807,13 +18636,13 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
17807
18636
|
|
|
17808
18637
|
if (config$1.aeadProtect) {
|
|
17809
18638
|
this.s2kUsage = 253;
|
|
17810
|
-
this.aead =
|
|
18639
|
+
this.aead = config$1.preferredAEADAlgorithm;
|
|
17811
18640
|
const mode = mod.getAEADMode(this.aead);
|
|
17812
18641
|
this.isLegacyAEAD = this.version === 5; // v4 is always re-encrypted with standard format instead.
|
|
17813
18642
|
this.usedModernAEAD = !this.isLegacyAEAD; // legacy AEAD does not guarantee integrity of public key material
|
|
17814
18643
|
|
|
17815
18644
|
const serializedPacketTag = writeTag(this.constructor.tag);
|
|
17816
|
-
const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag);
|
|
18645
|
+
const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag, this.isLegacyAEAD);
|
|
17817
18646
|
|
|
17818
18647
|
const modeInstance = await mode(this.symmetric, key);
|
|
17819
18648
|
this.iv = this.isLegacyAEAD ? mod.random.getRandomBytes(blockSize) : mod.random.getRandomBytes(mode.ivLength);
|
|
@@ -17983,6 +18812,12 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
17983
18812
|
* @returns encryption key
|
|
17984
18813
|
*/
|
|
17985
18814
|
async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadMode, serializedPacketTag, isLegacyAEAD) {
|
|
18815
|
+
if (s2k.type === 'argon2' && !aeadMode) {
|
|
18816
|
+
throw new Error('Using Argon2 S2K without AEAD is not allowed');
|
|
18817
|
+
}
|
|
18818
|
+
if (s2k.type === 'simple' && keyVersion === 6) {
|
|
18819
|
+
throw new Error('Using Simple S2K with version 6 keys is not allowed');
|
|
18820
|
+
}
|
|
17986
18821
|
const { keySize } = mod.getCipherParams(cipherAlgo);
|
|
17987
18822
|
const derivedKey = await s2k.produceKey(passphrase, keySize);
|
|
17988
18823
|
if (!aeadMode || keyVersion === 5 || isLegacyAEAD) {
|
|
@@ -18361,6 +19196,8 @@ async function generateSecretKey(options, config) {
|
|
|
18361
19196
|
* Returns the valid and non-expired signature that has the latest creation date, while ignoring signatures created in the future.
|
|
18362
19197
|
* @param {Array<SignaturePacket>} signatures - List of signatures
|
|
18363
19198
|
* @param {PublicKeyPacket|PublicSubkeyPacket} publicKey - Public key packet to verify the signature
|
|
19199
|
+
* @param {module:enums.signature} signatureType - Signature type to determine how to hash the data (NB: for userID signatures,
|
|
19200
|
+
* `enums.signatures.certGeneric` should be given regardless of the actual trust level)
|
|
18364
19201
|
* @param {Date} date - Use the given date instead of the current time
|
|
18365
19202
|
* @param {Object} config - full configuration
|
|
18366
19203
|
* @returns {Promise<SignaturePacket>} The latest valid signature.
|
|
@@ -18609,8 +19446,14 @@ async function isDataRevoked(primaryKey, signatureType, dataToVerify, revocation
|
|
|
18609
19446
|
// `verifyAllCertifications`.)
|
|
18610
19447
|
!signature || revocationSignature.issuerKeyID.equals(signature.issuerKeyID)
|
|
18611
19448
|
) {
|
|
19449
|
+
const isHardRevocation = ![
|
|
19450
|
+
enums.reasonForRevocation.keyRetired,
|
|
19451
|
+
enums.reasonForRevocation.keySuperseded,
|
|
19452
|
+
enums.reasonForRevocation.userIDInvalid
|
|
19453
|
+
].includes(revocationSignature.reasonForRevocationFlag);
|
|
19454
|
+
|
|
18612
19455
|
await revocationSignature.verify(
|
|
18613
|
-
key, signatureType, dataToVerify, date, false, config
|
|
19456
|
+
key, signatureType, dataToVerify, isHardRevocation ? null : date, false, config
|
|
18614
19457
|
);
|
|
18615
19458
|
|
|
18616
19459
|
// TODO get an identifier of the revoked object instead
|
|
@@ -20597,7 +21440,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
|
|
|
20597
21440
|
key: secretKeyPacket
|
|
20598
21441
|
};
|
|
20599
21442
|
const signatureProperties = secretKeyPacket.version !== 6 ? getKeySignatureProperties() : {};
|
|
20600
|
-
signatureProperties.signatureType = enums.signature.
|
|
21443
|
+
signatureProperties.signatureType = enums.signature.certPositive;
|
|
20601
21444
|
if (index === 0) {
|
|
20602
21445
|
signatureProperties.isPrimaryUserID = true;
|
|
20603
21446
|
}
|
|
@@ -22422,7 +23265,7 @@ async function verify({ message, verificationKeys, expectSigned = false, format
|
|
|
22422
23265
|
result.signatures = await message.verify(verificationKeys, date, config$1);
|
|
22423
23266
|
}
|
|
22424
23267
|
result.data = format === 'binary' ? message.getLiteralData() : message.getText();
|
|
22425
|
-
if (message.fromStream) linkStreams(result, message);
|
|
23268
|
+
if (message.fromStream && !signature) linkStreams(result, message);
|
|
22426
23269
|
if (expectSigned) {
|
|
22427
23270
|
if (result.signatures.length === 0) {
|
|
22428
23271
|
throw new Error('Message is not signed');
|