@protontech/openpgp 4.10.5 → 5.3.1
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 +311 -239
- package/dist/lightweight/bn.interface.min.mjs +3 -0
- package/dist/lightweight/bn.interface.min.mjs.map +1 -0
- package/dist/lightweight/bn.interface.mjs +340 -0
- package/dist/lightweight/bn.min.mjs +3 -0
- package/dist/lightweight/bn.min.mjs.map +1 -0
- package/dist/lightweight/bn.mjs +3434 -0
- package/dist/lightweight/elliptic.min.mjs +3 -0
- package/dist/lightweight/elliptic.min.mjs.map +1 -0
- package/dist/lightweight/elliptic.mjs +4313 -0
- package/dist/lightweight/openpgp.min.mjs +3 -0
- package/dist/lightweight/openpgp.min.mjs.map +1 -0
- package/dist/lightweight/openpgp.mjs +31375 -0
- package/dist/lightweight/ponyfill.es6.min.mjs +3 -0
- package/dist/lightweight/ponyfill.es6.min.mjs.map +1 -0
- package/dist/lightweight/ponyfill.es6.mjs +3831 -0
- package/dist/lightweight/web-streams-adapter.min.mjs +17 -0
- package/dist/lightweight/web-streams-adapter.min.mjs.map +1 -0
- package/dist/lightweight/web-streams-adapter.mjs +561 -0
- package/dist/node/openpgp.js +43943 -0
- package/dist/node/openpgp.min.js +17 -0
- package/dist/node/openpgp.min.js.map +1 -0
- package/dist/node/openpgp.min.mjs +17 -0
- package/dist/node/openpgp.min.mjs.map +1 -0
- package/dist/node/openpgp.mjs +43880 -0
- package/dist/openpgp.js +41080 -41565
- package/dist/openpgp.min.js +17 -2
- package/dist/openpgp.min.js.map +1 -0
- package/dist/openpgp.min.mjs +17 -0
- package/dist/openpgp.min.mjs.map +1 -0
- package/dist/openpgp.mjs +43868 -0
- package/lightweight/package.json +5 -0
- package/openpgp.d.ts +889 -0
- package/package.json +63 -57
- package/dist/compat/openpgp.js +0 -61067
- package/dist/compat/openpgp.min.js +0 -2
- package/dist/compat/openpgp.worker.js +0 -173
- package/dist/compat/openpgp.worker.min.js +0 -2
- package/dist/lightweight/elliptic.min.js +0 -5
- package/dist/lightweight/openpgp.js +0 -40024
- package/dist/lightweight/openpgp.min.js +0 -2
- package/dist/lightweight/openpgp.worker.js +0 -173
- package/dist/lightweight/openpgp.worker.min.js +0 -2
- package/dist/openpgp.worker.js +0 -173
- package/dist/openpgp.worker.min.js +0 -2
- package/src/cleartext.js +0 -220
- package/src/config/config.js +0 -224
- package/src/config/index.js +0 -7
- package/src/config/localStorage.js +0 -35
- package/src/crypto/aes_kw.js +0 -153
- package/src/crypto/cfb.js +0 -169
- package/src/crypto/cipher/aes.js +0 -27
- package/src/crypto/cipher/blowfish.js +0 -398
- package/src/crypto/cipher/cast5.js +0 -610
- package/src/crypto/cipher/des.js +0 -476
- package/src/crypto/cipher/index.js +0 -91
- package/src/crypto/cipher/twofish.js +0 -346
- package/src/crypto/cmac.js +0 -98
- package/src/crypto/crypto.js +0 -394
- package/src/crypto/eax.js +0 -172
- package/src/crypto/gcm.js +0 -141
- package/src/crypto/hash/index.js +0 -163
- package/src/crypto/hash/md5.js +0 -205
- package/src/crypto/index.js +0 -57
- package/src/crypto/ocb.js +0 -274
- package/src/crypto/pkcs1.js +0 -170
- package/src/crypto/pkcs5.js +0 -55
- package/src/crypto/public_key/dsa.js +0 -188
- package/src/crypto/public_key/elgamal.js +0 -137
- package/src/crypto/public_key/elliptic/curves.js +0 -385
- package/src/crypto/public_key/elliptic/ecdh.js +0 -414
- package/src/crypto/public_key/elliptic/ecdsa.js +0 -348
- package/src/crypto/public_key/elliptic/eddsa.js +0 -119
- package/src/crypto/public_key/elliptic/index.js +0 -34
- package/src/crypto/public_key/elliptic/indutnyKey.js +0 -85
- package/src/crypto/public_key/index.js +0 -28
- package/src/crypto/public_key/prime.js +0 -275
- package/src/crypto/public_key/rsa.js +0 -597
- package/src/crypto/random.js +0 -145
- package/src/crypto/signature.js +0 -137
- package/src/encoding/armor.js +0 -433
- package/src/encoding/base64.js +0 -96
- package/src/enums.js +0 -493
- package/src/hkp.js +0 -89
- package/src/index.js +0 -161
- package/src/key/factory.js +0 -326
- package/src/key/helper.js +0 -363
- package/src/key/index.js +0 -32
- package/src/key/key.js +0 -890
- package/src/key/subkey.js +0 -187
- package/src/key/user.js +0 -230
- package/src/keyring/index.js +0 -12
- package/src/keyring/keyring.js +0 -229
- package/src/keyring/localstore.js +0 -119
- package/src/lightweight_helper.js +0 -26
- package/src/message.js +0 -825
- package/src/openpgp.js +0 -717
- package/src/packet/all_packets.js +0 -116
- package/src/packet/clone.js +0 -189
- package/src/packet/compressed.js +0 -194
- package/src/packet/index.js +0 -20
- package/src/packet/literal.js +0 -168
- package/src/packet/marker.js +0 -62
- package/src/packet/one_pass_signature.js +0 -156
- package/src/packet/packet.js +0 -300
- package/src/packet/packetlist.js +0 -232
- package/src/packet/public_key.js +0 -280
- package/src/packet/public_key_encrypted_session_key.js +0 -156
- package/src/packet/public_subkey.js +0 -44
- package/src/packet/secret_key.js +0 -448
- package/src/packet/secret_subkey.js +0 -41
- package/src/packet/signature.js +0 -782
- package/src/packet/sym_encrypted_aead_protected.js +0 -189
- package/src/packet/sym_encrypted_integrity_protected.js +0 -139
- package/src/packet/sym_encrypted_session_key.js +0 -204
- package/src/packet/symmetrically_encrypted.js +0 -118
- package/src/packet/trust.js +0 -35
- package/src/packet/user_attribute.js +0 -94
- package/src/packet/userid.js +0 -87
- package/src/polyfills.js +0 -64
- package/src/signature.js +0 -73
- package/src/type/ecdh_symkey.js +0 -69
- package/src/type/kdf_params.js +0 -114
- package/src/type/keyid.js +0 -110
- package/src/type/mpi.js +0 -138
- package/src/type/oid.js +0 -110
- package/src/type/s2k.js +0 -203
- package/src/util.js +0 -836
- package/src/wkd.js +0 -88
- package/src/worker/async_proxy.js +0 -190
- package/src/worker/worker.js +0 -167
- package/test/crypto/aes_kw.js +0 -57
- package/test/crypto/cipher/aes.js +0 -86
- package/test/crypto/cipher/blowfish.js +0 -58
- package/test/crypto/cipher/cast5.js +0 -25
- package/test/crypto/cipher/des.js +0 -143
- package/test/crypto/cipher/index.js +0 -7
- package/test/crypto/cipher/twofish.js +0 -71
- package/test/crypto/crypto.js +0 -383
- package/test/crypto/eax.js +0 -150
- package/test/crypto/ecdh.js +0 -359
- package/test/crypto/elliptic.js +0 -251
- package/test/crypto/elliptic_data.js +0 -102
- package/test/crypto/hash/index.js +0 -5
- package/test/crypto/hash/md5.js +0 -16
- package/test/crypto/hash/ripemd.js +0 -14
- package/test/crypto/hash/sha.js +0 -20
- package/test/crypto/index.js +0 -14
- package/test/crypto/ocb.js +0 -183
- package/test/crypto/pkcs5.js +0 -39
- package/test/crypto/random.js +0 -79
- package/test/crypto/rsa.js +0 -180
- package/test/crypto/validate.js +0 -387
- package/test/general/armor.js +0 -408
- package/test/general/brainpool.js +0 -360
- package/test/general/decompression.js +0 -60
- package/test/general/ecc_nist.js +0 -115
- package/test/general/ecc_secp256k1.js +0 -242
- package/test/general/forwarding.js +0 -43
- package/test/general/hkp.js +0 -165
- package/test/general/index.js +0 -20
- package/test/general/key.js +0 -3402
- package/test/general/keyring.js +0 -336
- package/test/general/oid.js +0 -39
- package/test/general/openpgp.js +0 -2542
- package/test/general/packet.js +0 -937
- package/test/general/signature.js +0 -1665
- package/test/general/streaming.js +0 -944
- package/test/general/testInputs.js +0 -18
- package/test/general/util.js +0 -183
- package/test/general/wkd.js +0 -48
- package/test/general/x25519.js +0 -556
- package/test/unittests.js +0 -64
package/src/crypto/ocb.js
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
2
|
-
// Copyright (C) 2018 ProtonTech AG
|
|
3
|
-
//
|
|
4
|
-
// This library is free software; you can redistribute it and/or
|
|
5
|
-
// modify it under the terms of the GNU Lesser General Public
|
|
6
|
-
// License as published by the Free Software Foundation; either
|
|
7
|
-
// version 3.0 of the License, or (at your option) any later version.
|
|
8
|
-
//
|
|
9
|
-
// This library is distributed in the hope that it will be useful,
|
|
10
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
-
// Lesser General Public License for more details.
|
|
13
|
-
//
|
|
14
|
-
// You should have received a copy of the GNU Lesser General Public
|
|
15
|
-
// License along with this library; if not, write to the Free Software
|
|
16
|
-
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @fileoverview This module implements AES-OCB en/decryption.
|
|
20
|
-
* @requires crypto/cipher
|
|
21
|
-
* @requires util
|
|
22
|
-
* @module crypto/ocb
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import ciphers from './cipher';
|
|
26
|
-
import util from '../util';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const blockLength = 16;
|
|
30
|
-
const ivLength = 15;
|
|
31
|
-
|
|
32
|
-
// https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.16.2:
|
|
33
|
-
// While OCB [RFC7253] allows the authentication tag length to be of any
|
|
34
|
-
// number up to 128 bits long, this document requires a fixed
|
|
35
|
-
// authentication tag length of 128 bits (16 octets) for simplicity.
|
|
36
|
-
const tagLength = 16;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
function ntz(n) {
|
|
40
|
-
let ntz = 0;
|
|
41
|
-
for (let i = 1; (n & i) === 0; i <<= 1) {
|
|
42
|
-
ntz++;
|
|
43
|
-
}
|
|
44
|
-
return ntz;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function xorMut(S, T) {
|
|
48
|
-
for (let i = 0; i < S.length; i++) {
|
|
49
|
-
S[i] ^= T[i];
|
|
50
|
-
}
|
|
51
|
-
return S;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function xor(S, T) {
|
|
55
|
-
return xorMut(S.slice(), T);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const zeroBlock = new Uint8Array(blockLength);
|
|
59
|
-
const one = new Uint8Array([1]);
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Class to en/decrypt using OCB mode.
|
|
63
|
-
* @param {String} cipher The symmetric cipher algorithm to use e.g. 'aes128'
|
|
64
|
-
* @param {Uint8Array} key The encryption key
|
|
65
|
-
*/
|
|
66
|
-
async function OCB(cipher, key) {
|
|
67
|
-
|
|
68
|
-
let maxNtz = 0;
|
|
69
|
-
let encipher;
|
|
70
|
-
let decipher;
|
|
71
|
-
let mask;
|
|
72
|
-
|
|
73
|
-
constructKeyVariables(cipher, key);
|
|
74
|
-
|
|
75
|
-
function constructKeyVariables(cipher, key) {
|
|
76
|
-
const aes = new ciphers[cipher](key);
|
|
77
|
-
encipher = aes.encrypt.bind(aes);
|
|
78
|
-
decipher = aes.decrypt.bind(aes);
|
|
79
|
-
|
|
80
|
-
const mask_x = encipher(zeroBlock);
|
|
81
|
-
const mask_$ = util.double(mask_x);
|
|
82
|
-
mask = [];
|
|
83
|
-
mask[0] = util.double(mask_$);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
mask.x = mask_x;
|
|
87
|
-
mask.$ = mask_$;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function extendKeyVariables(text, adata) {
|
|
91
|
-
const newMaxNtz = util.nbits(Math.max(text.length, adata.length) / blockLength | 0) - 1;
|
|
92
|
-
for (let i = maxNtz + 1; i <= newMaxNtz; i++) {
|
|
93
|
-
mask[i] = util.double(mask[i - 1]);
|
|
94
|
-
}
|
|
95
|
-
maxNtz = newMaxNtz;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function hash(adata) {
|
|
99
|
-
if (!adata.length) {
|
|
100
|
-
// Fast path
|
|
101
|
-
return zeroBlock;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
//
|
|
105
|
-
// Consider A as a sequence of 128-bit blocks
|
|
106
|
-
//
|
|
107
|
-
const m = adata.length / blockLength | 0;
|
|
108
|
-
|
|
109
|
-
const offset = new Uint8Array(blockLength);
|
|
110
|
-
const sum = new Uint8Array(blockLength);
|
|
111
|
-
for (let i = 0; i < m; i++) {
|
|
112
|
-
xorMut(offset, mask[ntz(i + 1)]);
|
|
113
|
-
xorMut(sum, encipher(xor(offset, adata)));
|
|
114
|
-
adata = adata.subarray(blockLength);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
//
|
|
118
|
-
// Process any final partial block; compute final hash value
|
|
119
|
-
//
|
|
120
|
-
if (adata.length) {
|
|
121
|
-
xorMut(offset, mask.x);
|
|
122
|
-
|
|
123
|
-
const cipherInput = new Uint8Array(blockLength);
|
|
124
|
-
cipherInput.set(adata, 0);
|
|
125
|
-
cipherInput[adata.length] = 0b10000000;
|
|
126
|
-
xorMut(cipherInput, offset);
|
|
127
|
-
|
|
128
|
-
xorMut(sum, encipher(cipherInput));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return sum;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Encrypt/decrypt data.
|
|
136
|
-
* @param {encipher|decipher} fn Encryption/decryption block cipher function
|
|
137
|
-
* @param {Uint8Array} text The cleartext or ciphertext (without tag) input
|
|
138
|
-
* @param {Uint8Array} nonce The nonce (15 bytes)
|
|
139
|
-
* @param {Uint8Array} adata Associated data to sign
|
|
140
|
-
* @returns {Promise<Uint8Array>} The ciphertext or plaintext output, with tag appended in both cases
|
|
141
|
-
*/
|
|
142
|
-
function crypt(fn, text, nonce, adata) {
|
|
143
|
-
//
|
|
144
|
-
// Consider P as a sequence of 128-bit blocks
|
|
145
|
-
//
|
|
146
|
-
const m = text.length / blockLength | 0;
|
|
147
|
-
|
|
148
|
-
//
|
|
149
|
-
// Key-dependent variables
|
|
150
|
-
//
|
|
151
|
-
extendKeyVariables(text, adata);
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
// Nonce-dependent and per-encryption variables
|
|
155
|
-
//
|
|
156
|
-
// Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N
|
|
157
|
-
// Note: We assume here that tagLength mod 16 == 0.
|
|
158
|
-
const paddedNonce = util.concatUint8Array([zeroBlock.subarray(0, ivLength - nonce.length), one, nonce]);
|
|
159
|
-
// bottom = str2num(Nonce[123..128])
|
|
160
|
-
const bottom = paddedNonce[blockLength - 1] & 0b111111;
|
|
161
|
-
// Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6))
|
|
162
|
-
paddedNonce[blockLength - 1] &= 0b11000000;
|
|
163
|
-
const kTop = encipher(paddedNonce);
|
|
164
|
-
// Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72])
|
|
165
|
-
const stretched = util.concatUint8Array([kTop, xor(kTop.subarray(0, 8), kTop.subarray(1, 9))]);
|
|
166
|
-
// Offset_0 = Stretch[1+bottom..128+bottom]
|
|
167
|
-
const offset = util.shiftRight(stretched.subarray(0 + (bottom >> 3), 17 + (bottom >> 3)), 8 - (bottom & 7)).subarray(1);
|
|
168
|
-
// Checksum_0 = zeros(128)
|
|
169
|
-
const checksum = new Uint8Array(blockLength);
|
|
170
|
-
|
|
171
|
-
const ct = new Uint8Array(text.length + tagLength);
|
|
172
|
-
|
|
173
|
-
//
|
|
174
|
-
// Process any whole blocks
|
|
175
|
-
//
|
|
176
|
-
let i;
|
|
177
|
-
let pos = 0;
|
|
178
|
-
for (i = 0; i < m; i++) {
|
|
179
|
-
// Offset_i = Offset_{i-1} xor L_{ntz(i)}
|
|
180
|
-
xorMut(offset, mask[ntz(i + 1)]);
|
|
181
|
-
// C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)
|
|
182
|
-
// P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)
|
|
183
|
-
ct.set(xorMut(fn(xor(offset, text)), offset), pos);
|
|
184
|
-
// Checksum_i = Checksum_{i-1} xor P_i
|
|
185
|
-
xorMut(checksum, fn === encipher ? text : ct.subarray(pos));
|
|
186
|
-
|
|
187
|
-
text = text.subarray(blockLength);
|
|
188
|
-
pos += blockLength;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
//
|
|
192
|
-
// Process any final partial block and compute raw tag
|
|
193
|
-
//
|
|
194
|
-
if (text.length) {
|
|
195
|
-
// Offset_* = Offset_m xor L_*
|
|
196
|
-
xorMut(offset, mask.x);
|
|
197
|
-
// Pad = ENCIPHER(K, Offset_*)
|
|
198
|
-
const padding = encipher(offset);
|
|
199
|
-
// C_* = P_* xor Pad[1..bitlen(P_*)]
|
|
200
|
-
ct.set(xor(text, padding), pos);
|
|
201
|
-
|
|
202
|
-
// Checksum_* = Checksum_m xor (P_* || 1 || new Uint8Array(127-bitlen(P_*)))
|
|
203
|
-
const xorInput = new Uint8Array(blockLength);
|
|
204
|
-
xorInput.set(fn === encipher ? text : ct.subarray(pos, -tagLength), 0);
|
|
205
|
-
xorInput[text.length] = 0b10000000;
|
|
206
|
-
xorMut(checksum, xorInput);
|
|
207
|
-
pos += text.length;
|
|
208
|
-
}
|
|
209
|
-
// Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A)
|
|
210
|
-
const tag = xorMut(encipher(xorMut(xorMut(checksum, offset), mask.$)), hash(adata));
|
|
211
|
-
|
|
212
|
-
//
|
|
213
|
-
// Assemble ciphertext
|
|
214
|
-
//
|
|
215
|
-
// C = C_1 || C_2 || ... || C_m || C_* || Tag[1..TAGLEN]
|
|
216
|
-
ct.set(tag, pos);
|
|
217
|
-
return ct;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return {
|
|
222
|
-
/**
|
|
223
|
-
* Encrypt plaintext input.
|
|
224
|
-
* @param {Uint8Array} plaintext The cleartext input to be encrypted
|
|
225
|
-
* @param {Uint8Array} nonce The nonce (15 bytes)
|
|
226
|
-
* @param {Uint8Array} adata Associated data to sign
|
|
227
|
-
* @returns {Promise<Uint8Array>} The ciphertext output
|
|
228
|
-
*/
|
|
229
|
-
encrypt: async function(plaintext, nonce, adata) {
|
|
230
|
-
return crypt(encipher, plaintext, nonce, adata);
|
|
231
|
-
},
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Decrypt ciphertext input.
|
|
235
|
-
* @param {Uint8Array} ciphertext The ciphertext input to be decrypted
|
|
236
|
-
* @param {Uint8Array} nonce The nonce (15 bytes)
|
|
237
|
-
* @param {Uint8Array} adata Associated data to sign
|
|
238
|
-
* @returns {Promise<Uint8Array>} The ciphertext output
|
|
239
|
-
*/
|
|
240
|
-
decrypt: async function(ciphertext, nonce, adata) {
|
|
241
|
-
if (ciphertext.length < tagLength) throw new Error('Invalid OCB ciphertext');
|
|
242
|
-
|
|
243
|
-
const tag = ciphertext.subarray(-tagLength);
|
|
244
|
-
ciphertext = ciphertext.subarray(0, -tagLength);
|
|
245
|
-
|
|
246
|
-
const crypted = crypt(decipher, ciphertext, nonce, adata);
|
|
247
|
-
// if (Tag[1..TAGLEN] == T)
|
|
248
|
-
if (util.equalsUint8Array(tag, crypted.subarray(-tagLength))) {
|
|
249
|
-
return crypted.subarray(0, -tagLength);
|
|
250
|
-
}
|
|
251
|
-
throw new Error('Authentication tag mismatch');
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Get OCB nonce as defined by {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.16.2|RFC4880bis-04, section 5.16.2}.
|
|
259
|
-
* @param {Uint8Array} iv The initialization vector (15 bytes)
|
|
260
|
-
* @param {Uint8Array} chunkIndex The chunk index (8 bytes)
|
|
261
|
-
*/
|
|
262
|
-
OCB.getNonce = function(iv, chunkIndex) {
|
|
263
|
-
const nonce = iv.slice();
|
|
264
|
-
for (let i = 0; i < chunkIndex.length; i++) {
|
|
265
|
-
nonce[7 + i] ^= chunkIndex[i];
|
|
266
|
-
}
|
|
267
|
-
return nonce;
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
OCB.blockLength = blockLength;
|
|
271
|
-
OCB.ivLength = ivLength;
|
|
272
|
-
OCB.tagLength = tagLength;
|
|
273
|
-
|
|
274
|
-
export default OCB;
|
package/src/crypto/pkcs1.js
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
2
|
-
// Copyright (C) 2011 Recurity Labs GmbH
|
|
3
|
-
//
|
|
4
|
-
// This library is free software; you can redistribute it and/or
|
|
5
|
-
// modify it under the terms of the GNU Lesser General Public
|
|
6
|
-
// License as published by the Free Software Foundation; either
|
|
7
|
-
// version 3.0 of the License, or (at your option) any later version.
|
|
8
|
-
//
|
|
9
|
-
// This library is distributed in the hope that it will be useful,
|
|
10
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
-
// Lesser General Public License for more details.
|
|
13
|
-
//
|
|
14
|
-
// You should have received a copy of the GNU Lesser General Public
|
|
15
|
-
// License along with this library; if not, write to the Free Software
|
|
16
|
-
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @fileoverview Provides EME-PKCS1-v1_5 encoding and decoding and EMSA-PKCS1-v1_5 encoding function
|
|
20
|
-
* @see module:crypto/public_key/rsa
|
|
21
|
-
* @see module:crypto/public_key/elliptic/ecdh
|
|
22
|
-
* @see module:packet.PublicKeyEncryptedSessionKey
|
|
23
|
-
* @requires crypto/random
|
|
24
|
-
* @requires crypto/hash
|
|
25
|
-
* @requires util
|
|
26
|
-
* @module crypto/pkcs1
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
import random from './random';
|
|
30
|
-
import hash from './hash';
|
|
31
|
-
import util from '../util';
|
|
32
|
-
|
|
33
|
-
/** @namespace */
|
|
34
|
-
const eme = {};
|
|
35
|
-
/** @namespace */
|
|
36
|
-
const emsa = {};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* ASN1 object identifiers for hashes
|
|
40
|
-
* @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.2}
|
|
41
|
-
*/
|
|
42
|
-
const hash_headers = [];
|
|
43
|
-
hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04,
|
|
44
|
-
0x10];
|
|
45
|
-
hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14];
|
|
46
|
-
hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14];
|
|
47
|
-
hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
|
|
48
|
-
0x04, 0x20];
|
|
49
|
-
hash_headers[9] = [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
|
|
50
|
-
0x04, 0x30];
|
|
51
|
-
hash_headers[10] = [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
|
|
52
|
-
0x00, 0x04, 0x40];
|
|
53
|
-
hash_headers[11] = [0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
|
|
54
|
-
0x00, 0x04, 0x1C];
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Create padding with secure random data
|
|
58
|
-
* @private
|
|
59
|
-
* @param {Integer} length Length of the padding in bytes
|
|
60
|
-
* @returns {String} Padding as string
|
|
61
|
-
* @async
|
|
62
|
-
*/
|
|
63
|
-
async function getPkcs1Padding(length) {
|
|
64
|
-
let result = '';
|
|
65
|
-
while (result.length < length) {
|
|
66
|
-
const randomBytes = await random.getRandomBytes(length - result.length);
|
|
67
|
-
for (let i = 0; i < randomBytes.length; i++) {
|
|
68
|
-
if (randomBytes[i] !== 0) {
|
|
69
|
-
result += String.fromCharCode(randomBytes[i]);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Create a EME-PKCS1-v1_5 padded message
|
|
78
|
-
* @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.1|RFC 4880 13.1.1}
|
|
79
|
-
* @param {String} M message to be encoded
|
|
80
|
-
* @param {Integer} k the length in octets of the key modulus
|
|
81
|
-
* @returns {Promise<String>} EME-PKCS1 padded message
|
|
82
|
-
* @async
|
|
83
|
-
*/
|
|
84
|
-
eme.encode = async function(M, k) {
|
|
85
|
-
const mLen = M.length;
|
|
86
|
-
// length checking
|
|
87
|
-
if (mLen > k - 11) {
|
|
88
|
-
throw new Error('Message too long');
|
|
89
|
-
}
|
|
90
|
-
// Generate an octet string PS of length k - mLen - 3 consisting of
|
|
91
|
-
// pseudo-randomly generated nonzero octets
|
|
92
|
-
const PS = await getPkcs1Padding(k - mLen - 3);
|
|
93
|
-
// Concatenate PS, the message M, and other padding to form an
|
|
94
|
-
// encoded message EM of length k octets as EM = 0x00 || 0x02 || PS || 0x00 || M.
|
|
95
|
-
return String.fromCharCode(0) +
|
|
96
|
-
String.fromCharCode(2) +
|
|
97
|
-
PS +
|
|
98
|
-
String.fromCharCode(0) +
|
|
99
|
-
M;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Decode a EME-PKCS1-v1_5 padded message
|
|
104
|
-
* @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.2|RFC 4880 13.1.2}
|
|
105
|
-
* @param {String} EM encoded message, an octet string
|
|
106
|
-
* @returns {String} message, an octet string
|
|
107
|
-
*/
|
|
108
|
-
eme.decode = function(EM) {
|
|
109
|
-
// leading zeros truncated by bn.js
|
|
110
|
-
if (EM.charCodeAt(0) !== 0) {
|
|
111
|
-
EM = String.fromCharCode(0) + EM;
|
|
112
|
-
}
|
|
113
|
-
const firstOct = EM.charCodeAt(0);
|
|
114
|
-
const secondOct = EM.charCodeAt(1);
|
|
115
|
-
let i = 2;
|
|
116
|
-
while (EM.charCodeAt(i) !== 0 && i < EM.length) {
|
|
117
|
-
i++;
|
|
118
|
-
}
|
|
119
|
-
const psLen = i - 2;
|
|
120
|
-
const separator = EM.charCodeAt(i++);
|
|
121
|
-
if (firstOct === 0 && secondOct === 2 && psLen >= 8 && separator === 0) {
|
|
122
|
-
return EM.substr(i);
|
|
123
|
-
}
|
|
124
|
-
throw new Error('Decryption error');
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Create a EMSA-PKCS1-v1_5 padded message
|
|
129
|
-
* @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.3|RFC 4880 13.1.3}
|
|
130
|
-
* @param {Integer} algo Hash algorithm type used
|
|
131
|
-
* @param {Uint8Array} hashed message to be encoded
|
|
132
|
-
* @param {Integer} emLen intended length in octets of the encoded message
|
|
133
|
-
* @returns {String} encoded message
|
|
134
|
-
*/
|
|
135
|
-
emsa.encode = async function(algo, hashed, emLen) {
|
|
136
|
-
let i;
|
|
137
|
-
const H = util.Uint8Array_to_str(hashed);
|
|
138
|
-
if (H.length !== hash.getHashByteLength(algo)) {
|
|
139
|
-
throw new Error('Invalid hash length');
|
|
140
|
-
}
|
|
141
|
-
// produce an ASN.1 DER value for the hash function used.
|
|
142
|
-
// Let T be the full hash prefix
|
|
143
|
-
let T = '';
|
|
144
|
-
for (i = 0; i < hash_headers[algo].length; i++) {
|
|
145
|
-
T += String.fromCharCode(hash_headers[algo][i]);
|
|
146
|
-
}
|
|
147
|
-
// add hash value to prefix
|
|
148
|
-
T += H;
|
|
149
|
-
// and let tLen be the length in octets of T
|
|
150
|
-
const tLen = T.length;
|
|
151
|
-
if (emLen < tLen + 11) {
|
|
152
|
-
throw new Error('Intended encoded message length too short');
|
|
153
|
-
}
|
|
154
|
-
// an octet string PS consisting of emLen - tLen - 3 octets with hexadecimal value 0xFF
|
|
155
|
-
// The length of PS will be at least 8 octets
|
|
156
|
-
let PS = '';
|
|
157
|
-
for (i = 0; i < (emLen - tLen - 3); i++) {
|
|
158
|
-
PS += String.fromCharCode(0xff);
|
|
159
|
-
}
|
|
160
|
-
// Concatenate PS, the hash prefix T, and other padding to form the
|
|
161
|
-
// encoded message EM as EM = 0x00 || 0x01 || PS || 0x00 || T.
|
|
162
|
-
const EM = String.fromCharCode(0x00) +
|
|
163
|
-
String.fromCharCode(0x01) +
|
|
164
|
-
PS +
|
|
165
|
-
String.fromCharCode(0x00) +
|
|
166
|
-
T;
|
|
167
|
-
return util.str_to_hex(EM);
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
export default { eme, emsa };
|
package/src/crypto/pkcs5.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
2
|
-
// Copyright (C) 2015-2016 Decentral
|
|
3
|
-
//
|
|
4
|
-
// This library is free software; you can redistribute it and/or
|
|
5
|
-
// modify it under the terms of the GNU Lesser General Public
|
|
6
|
-
// License as published by the Free Software Foundation; either
|
|
7
|
-
// version 3.0 of the License, or (at your option) any later version.
|
|
8
|
-
//
|
|
9
|
-
// This library is distributed in the hope that it will be useful,
|
|
10
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
-
// Lesser General Public License for more details.
|
|
13
|
-
//
|
|
14
|
-
// You should have received a copy of the GNU Lesser General Public
|
|
15
|
-
// License along with this library; if not, write to the Free Software
|
|
16
|
-
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @fileoverview Functions to add and remove PKCS5 padding
|
|
20
|
-
* @see module:packet.PublicKeyEncryptedSessionKey
|
|
21
|
-
* @module crypto/pkcs5
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Add pkcs5 padding to a text.
|
|
26
|
-
* @param {String} msg Text to add padding
|
|
27
|
-
* @returns {String} Text with padding added
|
|
28
|
-
*/
|
|
29
|
-
function encode(msg) {
|
|
30
|
-
const c = 8 - (msg.length % 8);
|
|
31
|
-
const padding = String.fromCharCode(c).repeat(c);
|
|
32
|
-
return msg + padding;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Remove pkcs5 padding from a string.
|
|
37
|
-
* @param {String} msg Text to remove padding from
|
|
38
|
-
* @returns {String} Text with padding removed
|
|
39
|
-
*/
|
|
40
|
-
function decode(msg) {
|
|
41
|
-
const len = msg.length;
|
|
42
|
-
if (len > 0) {
|
|
43
|
-
const c = msg.charCodeAt(len - 1);
|
|
44
|
-
if (c >= 1) {
|
|
45
|
-
const provided = msg.substr(len - c);
|
|
46
|
-
const computed = String.fromCharCode(c).repeat(c);
|
|
47
|
-
if (provided === computed) {
|
|
48
|
-
return msg.substr(0, len - c);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
throw new Error('Invalid padding');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export default { encode, decode };
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
2
|
-
// Copyright (C) 2011 Recurity Labs GmbH
|
|
3
|
-
//
|
|
4
|
-
// This library is free software; you can redistribute it and/or
|
|
5
|
-
// modify it under the terms of the GNU Lesser General Public
|
|
6
|
-
// License as published by the Free Software Foundation; either
|
|
7
|
-
// version 3.0 of the License, or (at your option) any later version.
|
|
8
|
-
//
|
|
9
|
-
// This library is distributed in the hope that it will be useful,
|
|
10
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
-
// Lesser General Public License for more details.
|
|
13
|
-
//
|
|
14
|
-
// You should have received a copy of the GNU Lesser General Public
|
|
15
|
-
// License along with this library; if not, write to the Free Software
|
|
16
|
-
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @fileoverview A Digital signature algorithm implementation
|
|
20
|
-
* @requires bn.js
|
|
21
|
-
* @requires crypto/random
|
|
22
|
-
* @requires util
|
|
23
|
-
* @module crypto/public_key/dsa
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import BN from 'bn.js';
|
|
27
|
-
import random from '../random';
|
|
28
|
-
import util from '../../util';
|
|
29
|
-
import prime from './prime';
|
|
30
|
-
|
|
31
|
-
const one = new BN(1);
|
|
32
|
-
const zero = new BN(0);
|
|
33
|
-
|
|
34
|
-
/*
|
|
35
|
-
TODO regarding the hash function, read:
|
|
36
|
-
https://tools.ietf.org/html/rfc4880#section-13.6
|
|
37
|
-
https://tools.ietf.org/html/rfc4880#section-14
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
export default {
|
|
41
|
-
/**
|
|
42
|
-
* DSA Sign function
|
|
43
|
-
* @param {Integer} hash_algo
|
|
44
|
-
* @param {Uint8Array} hashed
|
|
45
|
-
* @param {BN} g
|
|
46
|
-
* @param {BN} p
|
|
47
|
-
* @param {BN} q
|
|
48
|
-
* @param {BN} x
|
|
49
|
-
* @returns {{ r: BN, s: BN }}
|
|
50
|
-
* @async
|
|
51
|
-
*/
|
|
52
|
-
sign: async function(hash_algo, hashed, g, p, q, x) {
|
|
53
|
-
let k;
|
|
54
|
-
let r;
|
|
55
|
-
let s;
|
|
56
|
-
let t;
|
|
57
|
-
const redp = new BN.red(p);
|
|
58
|
-
const redq = new BN.red(q);
|
|
59
|
-
const gred = g.toRed(redp);
|
|
60
|
-
const xred = x.toRed(redq);
|
|
61
|
-
// If the output size of the chosen hash is larger than the number of
|
|
62
|
-
// bits of q, the hash result is truncated to fit by taking the number
|
|
63
|
-
// of leftmost bits equal to the number of bits of q. This (possibly
|
|
64
|
-
// truncated) hash function result is treated as a number and used
|
|
65
|
-
// directly in the DSA signature algorithm.
|
|
66
|
-
const h = new BN(hashed.subarray(0, q.byteLength())).toRed(redq);
|
|
67
|
-
// FIPS-186-4, section 4.6:
|
|
68
|
-
// The values of r and s shall be checked to determine if r = 0 or s = 0.
|
|
69
|
-
// If either r = 0 or s = 0, a new value of k shall be generated, and the
|
|
70
|
-
// signature shall be recalculated. It is extremely unlikely that r = 0
|
|
71
|
-
// or s = 0 if signatures are generated properly.
|
|
72
|
-
while (true) {
|
|
73
|
-
// See Appendix B here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
|
|
74
|
-
k = await random.getRandomBN(one, q); // returns in [1, q-1]
|
|
75
|
-
r = gred.redPow(k).fromRed().toRed(redq); // (g**k mod p) mod q
|
|
76
|
-
if (zero.cmp(r) === 0) {
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
t = h.redAdd(xred.redMul(r)); // H(m) + x*r mod q
|
|
80
|
-
s = k.toRed(redq).redInvm().redMul(t); // k**-1 * (H(m) + x*r) mod q
|
|
81
|
-
if (zero.cmp(s) === 0) {
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
r: r.toArrayLike(Uint8Array, 'be', q.byteLength()),
|
|
88
|
-
s: s.toArrayLike(Uint8Array, 'be', q.byteLength())
|
|
89
|
-
};
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* DSA Verify function
|
|
94
|
-
* @param {Integer} hash_algo
|
|
95
|
-
* @param {BN} r
|
|
96
|
-
* @param {BN} s
|
|
97
|
-
* @param {Uint8Array} hashed
|
|
98
|
-
* @param {BN} g
|
|
99
|
-
* @param {BN} p
|
|
100
|
-
* @param {BN} q
|
|
101
|
-
* @param {BN} y
|
|
102
|
-
* @returns {boolean}
|
|
103
|
-
* @async
|
|
104
|
-
*/
|
|
105
|
-
verify: async function(hash_algo, r, s, hashed, g, p, q, y) {
|
|
106
|
-
if (zero.ucmp(r) >= 0 || r.ucmp(q) >= 0 ||
|
|
107
|
-
zero.ucmp(s) >= 0 || s.ucmp(q) >= 0) {
|
|
108
|
-
util.print_debug("invalid DSA Signature");
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
const redp = new BN.red(p);
|
|
112
|
-
const redq = new BN.red(q);
|
|
113
|
-
const h = new BN(hashed.subarray(0, q.byteLength()));
|
|
114
|
-
const w = s.toRed(redq).redInvm(); // s**-1 mod q
|
|
115
|
-
if (zero.cmp(w) === 0) {
|
|
116
|
-
util.print_debug("invalid DSA Signature");
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
const u1 = h.toRed(redq).redMul(w); // H(m) * w mod q
|
|
120
|
-
const u2 = r.toRed(redq).redMul(w); // r * w mod q
|
|
121
|
-
const t1 = g.toRed(redp).redPow(u1.fromRed()); // g**u1 mod p
|
|
122
|
-
const t2 = y.toRed(redp).redPow(u2.fromRed()); // y**u2 mod p
|
|
123
|
-
const v = t1.redMul(t2).fromRed().mod(q); // (g**u1 * y**u2 mod p) mod q
|
|
124
|
-
return v.cmp(r) === 0;
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Validate DSA parameters
|
|
129
|
-
* @param {Uint8Array} p DSA prime
|
|
130
|
-
* @param {Uint8Array} q DSA group order
|
|
131
|
-
* @param {Uint8Array} g DSA sub-group generator
|
|
132
|
-
* @param {Uint8Array} y DSA public key
|
|
133
|
-
* @param {Uint8Array} x DSA private key
|
|
134
|
-
* @returns {Promise<Boolean>} whether params are valid
|
|
135
|
-
* @async
|
|
136
|
-
*/
|
|
137
|
-
validateParams: async function (p, q, g, y, x) {
|
|
138
|
-
p = new BN(p);
|
|
139
|
-
q = new BN(q);
|
|
140
|
-
g = new BN(g);
|
|
141
|
-
y = new BN(y);
|
|
142
|
-
const one = new BN(1);
|
|
143
|
-
// Check that 1 < g < p
|
|
144
|
-
if (g.lte(one) || g.gte(p)) {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Check that subgroup order q divides p-1
|
|
150
|
-
*/
|
|
151
|
-
if (!p.sub(one).mod(q).isZero()) {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const pred = new BN.red(p);
|
|
156
|
-
const gModP = g.toRed(pred);
|
|
157
|
-
/**
|
|
158
|
-
* g has order q
|
|
159
|
-
* Check that g ** q = 1 mod p
|
|
160
|
-
*/
|
|
161
|
-
if (!gModP.redPow(q).eq(one)) {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Check q is large and probably prime (we mainly want to avoid small factors)
|
|
167
|
-
*/
|
|
168
|
-
const qSize = q.bitLength();
|
|
169
|
-
if (qSize < 150 || !(await prime.isProbablePrime(q, null, 32))) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Re-derive public key y' = g ** x mod p
|
|
175
|
-
* Expect y == y'
|
|
176
|
-
*
|
|
177
|
-
* Blinded exponentiation computes g**{rq + x} to compare to y
|
|
178
|
-
*/
|
|
179
|
-
x = new BN(x);
|
|
180
|
-
const r = await random.getRandomBN(new BN(2).shln(qSize - 1), new BN(2).shln(qSize)); // draw r of same size as q
|
|
181
|
-
const rqx = q.mul(r).add(x);
|
|
182
|
-
if (!y.eq(gModP.redPow(rqx))) {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
};
|