1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.strDecToHex = undefined;
|
7 | exports.bigint = bigint;
|
8 | exports.bigStringInt = bigStringInt;
|
9 | exports.bytesToHex = bytesToHex;
|
10 | exports.bytesFromHex = bytesFromHex;
|
11 | exports.bytesCmp = bytesCmp;
|
12 | exports.bytesXor = bytesXor;
|
13 | exports.bytesToWords = bytesToWords;
|
14 | exports.bytesFromWords = bytesFromWords;
|
15 | exports.bytesFromLeemonBigInt = bytesFromLeemonBigInt;
|
16 | exports.bytesToArrayBuffer = bytesToArrayBuffer;
|
17 | exports.convertToArrayBuffer = convertToArrayBuffer;
|
18 | exports.convertToUint8Array = convertToUint8Array;
|
19 | exports.convertToByteArray = convertToByteArray;
|
20 | exports.bytesFromArrayBuffer = bytesFromArrayBuffer;
|
21 | exports.bufferConcat = bufferConcat;
|
22 | exports.longToInts = longToInts;
|
23 | exports.longToBytes = longToBytes;
|
24 | exports.lshift32 = lshift32;
|
25 | exports.intToUint = intToUint;
|
26 | exports.uintToInt = uintToInt;
|
27 | exports.sha1HashSync = sha1HashSync;
|
28 | exports.sha1BytesSync = sha1BytesSync;
|
29 | exports.sha256HashSync = sha256HashSync;
|
30 | exports.rsaEncrypt = rsaEncrypt;
|
31 | exports.addPadding = addPadding;
|
32 | exports.aesEncryptSync = aesEncryptSync;
|
33 | exports.aesDecryptSync = aesDecryptSync;
|
34 | exports.gzipUncompress = gzipUncompress;
|
35 | exports.nextRandomInt = nextRandomInt;
|
36 | exports.pqPrimeFactorization = pqPrimeFactorization;
|
37 | exports.pqPrimeLeemon = pqPrimeLeemon;
|
38 | exports.bytesModPow = bytesModPow;
|
39 |
|
40 | var _ramda = require('ramda');
|
41 |
|
42 | var _jsbn = require('jsbn');
|
43 |
|
44 | var _rusha = require('rusha');
|
45 |
|
46 | var _rusha2 = _interopRequireDefault(_rusha);
|
47 |
|
48 | var _nodeCryptojsAes = require('@goodmind/node-cryptojs-aes');
|
49 |
|
50 | var CryptoJSlib = _interopRequireWildcard(_nodeCryptojsAes);
|
51 |
|
52 | var _inflate = require('pako/lib/inflate');
|
53 |
|
54 | var _secureRandom = require('./service/secure-random');
|
55 |
|
56 | var _secureRandom2 = _interopRequireDefault(_secureRandom);
|
57 |
|
58 | var _leemon = require('./vendor/leemon');
|
59 |
|
60 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
61 |
|
62 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
63 |
|
64 | const { CryptoJS } = CryptoJSlib;
|
65 |
|
66 |
|
67 |
|
68 | const rushaInstance = new _rusha2.default(1024 * 1024);
|
69 |
|
70 | function bigint(num) {
|
71 | return new _jsbn.BigInteger(num.toString(16), 16);
|
72 | }
|
73 |
|
74 | function bigStringInt(strNum) {
|
75 | return new _jsbn.BigInteger(strNum, 10);
|
76 | }
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | const strDecToHex = exports.strDecToHex = str => (0, _ramda.toLower)((0, _leemon.bigInt2str)((0, _leemon.str2bigInt)(str, 10, 0), 16));
|
84 |
|
85 | function bytesToHex(bytes = []) {
|
86 | const arr = [];
|
87 | for (let i = 0; i < bytes.length; i++) {
|
88 | arr.push((bytes[i] < 16 ? '0' : '') + (bytes[i] || 0).toString(16));
|
89 | }
|
90 | return arr.join('');
|
91 | }
|
92 |
|
93 | function bytesFromHex(hexString) {
|
94 | const len = hexString.length;
|
95 | let start = 0;
|
96 | const bytes = [];
|
97 |
|
98 | if (hexString.length % 2) {
|
99 | bytes.push(parseInt(hexString.charAt(0), 16));
|
100 | start++;
|
101 | }
|
102 |
|
103 | for (let i = start; i < len; i += 2) {
|
104 | bytes.push(parseInt(hexString.substr(i, 2), 16));
|
105 | }
|
106 |
|
107 | return bytes;
|
108 | }
|
109 |
|
110 | function bytesCmp(bytes1, bytes2) {
|
111 | const len = bytes1.length;
|
112 | if (len !== bytes2.length) {
|
113 | return false;
|
114 | }
|
115 |
|
116 | for (let i = 0; i < len; i++) {
|
117 | if (bytes1[i] !== bytes2[i]) return false;
|
118 | }
|
119 | return true;
|
120 | }
|
121 |
|
122 | function bytesXor(bytes1, bytes2) {
|
123 | const len = bytes1.length;
|
124 | const bytes = [];
|
125 |
|
126 | for (let i = 0; i < len; ++i) {
|
127 | bytes[i] = bytes1[i] ^ bytes2[i];
|
128 | }
|
129 |
|
130 | return bytes;
|
131 | }
|
132 |
|
133 | function bytesToWords(bytes) {
|
134 | if (bytes instanceof ArrayBuffer) {
|
135 | bytes = new Uint8Array(bytes);
|
136 | }
|
137 | const len = bytes.length;
|
138 | const words = [];
|
139 | let i;
|
140 | for (i = 0; i < len; i++) {
|
141 | words[i >>> 2] |= bytes[i] << 24 - i % 4 * 8;
|
142 | }
|
143 |
|
144 | return new CryptoJS.lib.WordArray.init(words, len);
|
145 | }
|
146 |
|
147 | function bytesFromWords(wordArray) {
|
148 | const words = wordArray.words;
|
149 | const sigBytes = wordArray.sigBytes;
|
150 | const bytes = [];
|
151 |
|
152 | for (let i = 0; i < sigBytes; i++) {
|
153 | bytes.push(words[i >>> 2] >>> 24 - i % 4 * 8 & 0xff);
|
154 | }
|
155 |
|
156 | return bytes;
|
157 | }
|
158 |
|
159 | function bytesFromLeemonBigInt(bigInt) {
|
160 | const str = (0, _leemon.bigInt2str)(bigInt, 16);
|
161 | return bytesFromHex(str);
|
162 | }
|
163 |
|
164 | function bytesToArrayBuffer(b) {
|
165 | return new Uint8Array(b).buffer;
|
166 | }
|
167 |
|
168 | function convertToArrayBuffer(bytes) {
|
169 |
|
170 | if (bytes instanceof ArrayBuffer) {
|
171 | return bytes;
|
172 | }
|
173 | if (bytes.buffer !== undefined && bytes.buffer.byteLength == bytes.length * bytes.BYTES_PER_ELEMENT) {
|
174 | return bytes.buffer;
|
175 | }
|
176 | return bytesToArrayBuffer(bytes);
|
177 | }
|
178 |
|
179 | function convertToUint8Array(bytes) {
|
180 | if (bytes.buffer !== undefined) return bytes;
|
181 | return new Uint8Array(bytes);
|
182 | }
|
183 |
|
184 | function convertToByteArray(bytes) {
|
185 | if (Array.isArray(bytes)) return bytes;
|
186 | bytes = convertToUint8Array(bytes);
|
187 | const newBytes = [];
|
188 | for (let i = 0, len = bytes.length; i < len; i++) newBytes.push(bytes[i]);
|
189 | return newBytes;
|
190 | }
|
191 |
|
192 | function bytesFromArrayBuffer(buffer) {
|
193 | const byteView = new Uint8Array(buffer);
|
194 | const bytes = Array.from(byteView);
|
195 | return bytes;
|
196 | }
|
197 |
|
198 | function bufferConcat(buffer1, buffer2) {
|
199 | const l1 = buffer1.byteLength || buffer1.length;
|
200 | const l2 = buffer2.byteLength || buffer2.length;
|
201 | const tmp = new Uint8Array(l1 + l2);
|
202 | tmp.set(buffer1 instanceof ArrayBuffer ? new Uint8Array(buffer1) : buffer1, 0);
|
203 | tmp.set(buffer2 instanceof ArrayBuffer ? new Uint8Array(buffer2) : buffer2, l1);
|
204 |
|
205 | return tmp.buffer;
|
206 | }
|
207 |
|
208 |
|
209 | const dividerLem = (0, _leemon.str2bigInt)('100000000', 16, 4);
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 | function longToInts(sLong) {
|
216 | |
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 | const lemNum = (0, _leemon.str2bigInt)(sLong, 10, 6);
|
228 | const div = new Array(lemNum.length);
|
229 | const rem = new Array(lemNum.length);
|
230 | (0, _leemon.divide_)(lemNum, dividerLem, div, rem);
|
231 | const resL = [~~(0, _leemon.bigInt2str)(div, 10), ~~(0, _leemon.bigInt2str)(rem, 10)];
|
232 |
|
233 |
|
234 |
|
235 | return resL;
|
236 | }
|
237 |
|
238 | function longToBytes(sLong) {
|
239 | return bytesFromWords({ words: longToInts(sLong), sigBytes: 8 }).reverse();
|
240 | }
|
241 |
|
242 | function lshift32(high, low) {
|
243 | const highNum = (0, _leemon.int2bigInt)(high, 96, 0);
|
244 | (0, _leemon.leftShift_)(highNum, 32);
|
245 |
|
246 | (0, _leemon.addInt_)(highNum, low);
|
247 | const res = (0, _leemon.bigInt2str)(highNum, 10);
|
248 | return res;
|
249 | }
|
250 |
|
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 | function intToUint(val) {
|
261 | val = parseInt(val);
|
262 | if (val < 0) val = val + 4294967296;
|
263 | return val;
|
264 | }
|
265 |
|
266 | function uintToInt(val) {
|
267 | if (val > 2147483647) val = val - 4294967296;
|
268 | return val;
|
269 | }
|
270 |
|
271 | function sha1HashSync(bytes) {
|
272 |
|
273 | const hashBytes = rushaInstance.rawDigest(bytes).buffer;
|
274 |
|
275 |
|
276 | return hashBytes;
|
277 | }
|
278 |
|
279 | function sha1BytesSync(bytes) {
|
280 | return bytesFromArrayBuffer(sha1HashSync(bytes));
|
281 | }
|
282 |
|
283 | function sha256HashSync(bytes) {
|
284 |
|
285 | const hashWords = CryptoJS.SHA256(bytesToWords(bytes));
|
286 |
|
287 |
|
288 | const hashBytes = bytesFromWords(hashWords);
|
289 |
|
290 | return hashBytes;
|
291 | }
|
292 |
|
293 | function rsaEncrypt(publicKey, bytes) {
|
294 | bytes = addPadding(bytes, 255);
|
295 |
|
296 | const N = (0, _leemon.str2bigInt)(publicKey.modulus, 16, 256);
|
297 | const E = (0, _leemon.str2bigInt)(publicKey.exponent, 16, 256);
|
298 | const X = (0, _leemon.str2bigInt)(bytesToHex(bytes), 16, 256);
|
299 | const encryptedBigInt = (0, _leemon.powMod)(X, E, N),
|
300 | encryptedBytes = bytesFromHex((0, _leemon.bigInt2str)(encryptedBigInt, 16));
|
301 |
|
302 | return encryptedBytes;
|
303 | }
|
304 |
|
305 | function addPadding(bytes, blockSize, zeroes) {
|
306 | blockSize = blockSize || 16;
|
307 | const len = bytes.byteLength || bytes.length;
|
308 | const needPadding = blockSize - len % blockSize;
|
309 | if (needPadding > 0 && needPadding < blockSize) {
|
310 | const padding = new Array(needPadding);
|
311 | if (zeroes) {
|
312 | for (let i = 0; i < needPadding; i++) padding[i] = 0;
|
313 | } else _secureRandom2.default.nextBytes(padding);
|
314 |
|
315 | bytes = bytes instanceof ArrayBuffer ? bufferConcat(bytes, padding) : bytes.concat(padding);
|
316 | }
|
317 |
|
318 | return bytes;
|
319 | }
|
320 |
|
321 | function aesEncryptSync(bytes, keyBytes, ivBytes) {
|
322 | const len = bytes.byteLength || bytes.length;
|
323 |
|
324 |
|
325 | bytes = addPadding(bytes);
|
326 |
|
327 | const encryptedWords = CryptoJS.AES.encrypt(bytesToWords(bytes), bytesToWords(keyBytes), {
|
328 | iv: bytesToWords(ivBytes),
|
329 | padding: CryptoJS.pad.NoPadding,
|
330 | mode: CryptoJS.mode.IGE
|
331 | }).ciphertext;
|
332 |
|
333 | const encryptedBytes = bytesFromWords(encryptedWords);
|
334 |
|
335 |
|
336 | return encryptedBytes;
|
337 | }
|
338 |
|
339 | function aesDecryptSync(encryptedBytes, keyBytes, ivBytes) {
|
340 |
|
341 |
|
342 | const decryptedWords = CryptoJS.AES.decrypt({ ciphertext: bytesToWords(encryptedBytes) }, bytesToWords(keyBytes), {
|
343 | iv: bytesToWords(ivBytes),
|
344 | padding: CryptoJS.pad.NoPadding,
|
345 | mode: CryptoJS.mode.IGE
|
346 | });
|
347 |
|
348 | const bytes = bytesFromWords(decryptedWords);
|
349 |
|
350 |
|
351 | return bytes;
|
352 | }
|
353 |
|
354 | function gzipUncompress(bytes) {
|
355 |
|
356 | const result = (0, _inflate.inflate)(bytes);
|
357 |
|
358 | return result;
|
359 | }
|
360 |
|
361 | function nextRandomInt(maxValue) {
|
362 | return Math.floor(Math.random() * maxValue);
|
363 | }
|
364 |
|
365 | function pqPrimeFactorization(pqBytes) {
|
366 | const minSize = Math.ceil(64 / _leemon.bpe) + 1;
|
367 |
|
368 |
|
369 | const hex = bytesToHex(pqBytes);
|
370 | const lWhat = (0, _leemon.str2bigInt)(hex, 16, minSize);
|
371 | const result = pqPrimeLeemon(lWhat);
|
372 | return result;
|
373 | }
|
374 |
|
375 | function pqPrimeLeemon(what) {
|
376 | const minBits = 64;
|
377 | const minLen = Math.ceil(minBits / _leemon.bpe) + 1;
|
378 | let it = 0;
|
379 | let q, lim;
|
380 | const a = new Array(minLen);
|
381 | const b = new Array(minLen);
|
382 | const c = new Array(minLen);
|
383 | const g = new Array(minLen);
|
384 | const z = new Array(minLen);
|
385 | const x = new Array(minLen);
|
386 | const y = new Array(minLen);
|
387 |
|
388 | for (let i = 0; i < 3; i++) {
|
389 | q = (nextRandomInt(128) & 15) + 17;
|
390 | (0, _leemon.copyInt_)(x, nextRandomInt(1000000000) + 1);
|
391 | (0, _leemon.copy_)(y, x);
|
392 | lim = 1 << i + 18;
|
393 |
|
394 | for (let j = 1; j < lim; j++) {
|
395 | ++it;
|
396 | (0, _leemon.copy_)(a, x);
|
397 | (0, _leemon.copy_)(b, x);
|
398 | (0, _leemon.copyInt_)(c, q);
|
399 |
|
400 | while (!(0, _leemon.isZero)(b)) {
|
401 | if (b[0] & 1) {
|
402 | (0, _leemon.add_)(c, a);
|
403 | if ((0, _leemon.greater)(c, what)) {
|
404 | (0, _leemon.sub_)(c, what);
|
405 | }
|
406 | }
|
407 | (0, _leemon.add_)(a, a);
|
408 | if ((0, _leemon.greater)(a, what)) {
|
409 | (0, _leemon.sub_)(a, what);
|
410 | }
|
411 | (0, _leemon.rightShift_)(b, 1);
|
412 | }
|
413 |
|
414 | (0, _leemon.copy_)(x, c);
|
415 | if ((0, _leemon.greater)(x, y)) {
|
416 | (0, _leemon.copy_)(z, x);
|
417 | (0, _leemon.sub_)(z, y);
|
418 | } else {
|
419 | (0, _leemon.copy_)(z, y);
|
420 | (0, _leemon.sub_)(z, x);
|
421 | }
|
422 | (0, _leemon.eGCD_)(z, what, g, a, b);
|
423 | if (!(0, _leemon.equalsInt)(g, 1)) {
|
424 | break;
|
425 | }
|
426 | if ((j & j - 1) === 0) {
|
427 | (0, _leemon.copy_)(y, x);
|
428 | }
|
429 | }
|
430 | if ((0, _leemon.greater)(g, _leemon.one)) {
|
431 | break;
|
432 | }
|
433 | }
|
434 |
|
435 | (0, _leemon.divide_)(what, g, x, y);
|
436 |
|
437 | const [P, Q] = (0, _leemon.greater)(g, x) ? [x, g] : [g, x];
|
438 |
|
439 |
|
440 |
|
441 | return [bytesFromLeemonBigInt(P), bytesFromLeemonBigInt(Q), it];
|
442 | }
|
443 |
|
444 | function bytesModPow(x, y, m) {
|
445 | const xBigInt = (0, _leemon.str2bigInt)(bytesToHex(x), 16);
|
446 | const yBigInt = (0, _leemon.str2bigInt)(bytesToHex(y), 16);
|
447 | const mBigInt = (0, _leemon.str2bigInt)(bytesToHex(m), 16);
|
448 | const resBigInt = (0, _leemon.powMod)(xBigInt, yBigInt, mBigInt);
|
449 |
|
450 | return bytesFromHex((0, _leemon.bigInt2str)(resBigInt, 16));
|
451 | }
|
452 |
|
\ | No newline at end of file |