UNPKG

19.2 kBJavaScriptView Raw
1import { BigInteger, SecureRandom } from 'jsbn';
2import Rusha from 'rusha';
3import * as CryptoJSlib from '@goodmind/node-cryptojs-aes';
4const { CryptoJS } = CryptoJSlib;
5
6import { inflate } from 'pako/lib/inflate';
7
8// import Int from 'big-integer'
9
10// import BN from 'bn.js'
11
12import { eGCD_, greater, divide_, str2bigInt, equalsInt, isZero, bigInt2str, copy_, copyInt_, rightShift_, sub_, add_, powMod, bpe, one } from './leemon';
13
14// import { bigInt2str } from 'BigInt'
15
16// const { BigInteger } = jsbn
17
18const rushaInstance = new Rusha(1024 * 1024);
19
20export function bigint(num) {
21 return new BigInteger(num.toString(16), 16);
22}
23
24export function bigStringInt(strNum) {
25 return new BigInteger(strNum, 10);
26}
27
28export function dHexDump(bytes) {
29 const arr = [];
30 for (let i = 0; i < bytes.length; i++) {
31 if (i && !(i % 2)) {
32 if (!(i % 16)) {
33 arr.push('\n');
34 } else if (!(i % 4)) {
35 arr.push(' ');
36 } else {
37 arr.push(' ');
38 }
39 }
40 arr.push((bytes[i] < 16 ? '0' : '') + bytes[i].toString(16));
41 }
42
43 console.log(arr.join(''));
44}
45
46export function bytesToHex(bytes = []) {
47 const arr = [];
48 for (let i = 0; i < bytes.length; i++) {
49 arr.push((bytes[i] < 16 ? '0' : '') + (bytes[i] || 0).toString(16));
50 }
51 return arr.join('');
52}
53
54export function bytesFromHex(hexString) {
55 const len = hexString.length;
56 let start = 0;
57 const bytes = [];
58
59 if (hexString.length % 2) {
60 bytes.push(parseInt(hexString.charAt(0), 16));
61 start++;
62 }
63
64 for (let i = start; i < len; i += 2) {
65 bytes.push(parseInt(hexString.substr(i, 2), 16));
66 }
67
68 return bytes;
69}
70
71export function bytesToBase64(bytes) {
72 let mod3;
73 let result = '';
74
75 for (let nLen = bytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
76 mod3 = nIdx % 3;
77 nUint24 |= bytes[nIdx] << (16 >>> mod3 & 24);
78 if (mod3 === 2 || nLen - nIdx === 1) {
79 result += String.fromCharCode(uint6ToBase64(nUint24 >>> 18 & 63), uint6ToBase64(nUint24 >>> 12 & 63), uint6ToBase64(nUint24 >>> 6 & 63), uint6ToBase64(nUint24 & 63));
80 nUint24 = 0;
81 }
82 }
83
84 return result.replace(/A(?=A$|$)/g, '=');
85}
86
87export function uint6ToBase64(nUint6) {
88 return nUint6 < 26 ? nUint6 + 65 : nUint6 < 52 ? nUint6 + 71 : nUint6 < 62 ? nUint6 - 4 : nUint6 === 62 ? 43 : nUint6 === 63 ? 47 : 65;
89}
90
91// export function base64ToBlob(base64str, mimeType) {
92// const sliceSize = 1024
93// const byteCharacters = atob(base64str)
94// const bytesLength = byteCharacters.length
95// const slicesCount = Math.ceil(bytesLength / sliceSize)
96// const byteArrays = new Array(slicesCount)
97
98// for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
99// const begin = sliceIndex * sliceSize
100// const end = Math.min(begin + sliceSize, bytesLength)
101
102// const bytes = new Array(end - begin)
103// for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
104// bytes[i] = byteCharacters[offset].charCodeAt(0)
105// }
106// byteArrays[sliceIndex] = new Uint8Array(bytes)
107// }
108
109// return blobConstruct(byteArrays, mimeType)
110// }
111
112// export function dataUrlToBlob(url) {
113// // var name = 'b64blob ' + url.length
114// // console.time(name)
115// const urlParts = url.split(',')
116// const base64str = urlParts[1]
117// const mimeType = urlParts[0].split(':')[1].split(';')[0]
118// const blob = base64ToBlob(base64str, mimeType)
119// // console.timeEnd(name)
120// return blob
121// }
122
123// export function blobConstruct(blobParts, mimeType) {
124// let blob
125// try {
126// blob = new Blob(blobParts, { type: mimeType })
127// } catch (e) {
128// const bb = new BlobBuilder
129// angular.forEach(blobParts, function(blobPart) {
130// bb.append(blobPart)
131// })
132// blob = bb.getBlob(mimeType)
133// }
134// return blob
135// }
136
137export function bytesCmp(bytes1, bytes2) {
138 const len = bytes1.length;
139 if (len !== bytes2.length) {
140 return false;
141 }
142
143 for (let i = 0; i < len; i++) {
144 if (bytes1[i] !== bytes2[i]) return false;
145 }
146 return true;
147}
148
149export function bytesXor(bytes1, bytes2) {
150 const len = bytes1.length;
151 const bytes = [];
152
153 for (let i = 0; i < len; ++i) {
154 bytes[i] = bytes1[i] ^ bytes2[i];
155 }
156
157 return bytes;
158}
159
160export function bytesToWords(bytes) {
161 if (bytes instanceof ArrayBuffer) {
162 bytes = new Uint8Array(bytes);
163 }
164 const len = bytes.length;
165 const words = [];
166 let i;
167 for (i = 0; i < len; i++) {
168 words[i >>> 2] |= bytes[i] << 24 - i % 4 * 8;
169 }
170
171 return new CryptoJS.lib.WordArray.init(words, len);
172}
173
174export function bytesFromWords(wordArray) {
175 const words = wordArray.words;
176 const sigBytes = wordArray.sigBytes;
177 const bytes = [];
178
179 for (let i = 0; i < sigBytes; i++) {
180 bytes.push(words[i >>> 2] >>> 24 - i % 4 * 8 & 0xff);
181 }
182
183 return bytes;
184}
185
186export function bytesFromBigInt(bigInt, len) {
187 let bytes = bigInt.toByteArray();
188
189 if (len && bytes.length < len) {
190 const padding = [];
191 for (let i = 0, needPadding = len - bytes.length; i < needPadding; i++) {
192 padding[i] = 0;
193 }
194 if (bytes instanceof ArrayBuffer) {
195 bytes = bufferConcat(padding, bytes);
196 } else {
197 bytes = padding.concat(bytes);
198 }
199 } else {
200 while (!bytes[0] && (!len || bytes.length > len)) {
201 bytes = bytes.slice(1);
202 }
203 }
204
205 return bytes;
206}
207
208export function bytesFromLeemonBigInt(bigInt, len) {
209 const str = bigInt2str(bigInt, 16);
210 return bytesFromHex(str);
211}
212
213export function bytesToArrayBuffer(b) {
214 return new Uint8Array(b).buffer;
215}
216
217export function convertToArrayBuffer(bytes) {
218 // Be careful with converting subarrays!!
219 if (bytes instanceof ArrayBuffer) {
220 return bytes;
221 }
222 if (bytes.buffer !== undefined && bytes.buffer.byteLength == bytes.length * bytes.BYTES_PER_ELEMENT) {
223 return bytes.buffer;
224 }
225 return bytesToArrayBuffer(bytes);
226}
227
228export function convertToUint8Array(bytes) {
229 if (bytes.buffer !== undefined) {
230 return bytes;
231 }
232 return new Uint8Array(bytes);
233}
234
235export function convertToByteArray(bytes) {
236 if (Array.isArray(bytes)) {
237 return bytes;
238 }
239 bytes = convertToUint8Array(bytes);
240 const newBytes = [];
241 for (let i = 0, len = bytes.length; i < len; i++) {
242 newBytes.push(bytes[i]);
243 }
244 return newBytes;
245}
246
247export function bytesFromArrayBuffer(buffer) {
248 const byteView = new Uint8Array(buffer);
249 const bytes = Array.from(byteView);
250 return bytes;
251}
252
253export function bufferConcat(buffer1, buffer2) {
254 const l1 = buffer1.byteLength || buffer1.length;
255 const l2 = buffer2.byteLength || buffer2.length;
256 const tmp = new Uint8Array(l1 + l2);
257 tmp.set(buffer1 instanceof ArrayBuffer ? new Uint8Array(buffer1) : buffer1, 0);
258 tmp.set(buffer2 instanceof ArrayBuffer ? new Uint8Array(buffer2) : buffer2, l1);
259
260 return tmp.buffer;
261}
262
263export function longToInts(sLong) {
264 const divRem = bigStringInt(sLong).divideAndRemainder(bigint(0x100000000));
265
266 return [divRem[0].intValue(), divRem[1].intValue()];
267}
268
269export function longToBytes(sLong) {
270 return bytesFromWords({ words: longToInts(sLong), sigBytes: 8 }).reverse();
271}
272
273export function longFromInts(high, low) {
274 return bigint(high).shiftLeft(32).add(bigint(low)).toString(10);
275}
276
277export function intToUint(val) {
278 val = parseInt(val);
279 if (val < 0) {
280 val = val + 4294967296;
281 }
282 return val;
283}
284
285export function uintToInt(val) {
286 if (val > 2147483647) {
287 val = val - 4294967296;
288 }
289 return val;
290}
291
292export function sha1HashSync(bytes) {
293 // console.log(dT(), 'SHA-1 hash start', bytes.byteLength || bytes.length)
294 const hashBytes = rushaInstance.rawDigest(bytes).buffer;
295 // console.log(dT(), 'SHA-1 hash finish')
296
297 return hashBytes;
298}
299
300export function sha1BytesSync(bytes) {
301 return bytesFromArrayBuffer(sha1HashSync(bytes));
302}
303
304export function sha256HashSync(bytes) {
305 // console.log(dT(), 'SHA-2 hash start', bytes.byteLength || bytes.length)
306 const hashWords = CryptoJS.SHA256(bytesToWords(bytes));
307 // console.log(dT(), 'SHA-2 hash finish')
308
309 const hashBytes = bytesFromWords(hashWords);
310
311 return hashBytes;
312}
313
314export function rsaEncrypt(publicKey, bytes) {
315 bytes = addPadding(bytes, 255);
316
317 // console.log('RSA encrypt start')
318 const N = new BigInteger(publicKey.modulus, 16);
319 const E = new BigInteger(publicKey.exponent, 16);
320 const X = new BigInteger(bytes);
321 const encryptedBigInt = X.modPowInt(E, N),
322 encryptedBytes = bytesFromBigInt(encryptedBigInt, 256);
323 // console.log('RSA encrypt finish')
324
325 return encryptedBytes;
326}
327
328export function addPadding(bytes, blockSize, zeroes) {
329 blockSize = blockSize || 16;
330 const len = bytes.byteLength || bytes.length;
331 const needPadding = blockSize - len % blockSize;
332 if (needPadding > 0 && needPadding < blockSize) {
333 const padding = new Array(needPadding);
334 if (zeroes) {
335 for (let i = 0; i < needPadding; i++) {
336 padding[i] = 0;
337 }
338 } else {
339 new SecureRandom().nextBytes(padding);
340 }
341
342 if (bytes instanceof ArrayBuffer) {
343 bytes = bufferConcat(bytes, padding);
344 } else {
345 bytes = bytes.concat(padding);
346 }
347 }
348
349 return bytes;
350}
351
352export function aesEncryptSync(bytes, keyBytes, ivBytes) {
353 const len = bytes.byteLength || bytes.length;
354
355 // console.log(dT(), 'AES encrypt start', len/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/)
356 bytes = addPadding(bytes);
357
358 const encryptedWords = CryptoJS.AES.encrypt(bytesToWords(bytes), bytesToWords(keyBytes), {
359 iv: bytesToWords(ivBytes),
360 padding: CryptoJS.pad.NoPadding,
361 mode: CryptoJS.mode.IGE
362 }).ciphertext;
363
364 const encryptedBytes = bytesFromWords(encryptedWords);
365 // console.log(dT(), 'AES encrypt finish')
366
367 return encryptedBytes;
368}
369
370export function aesDecryptSync(encryptedBytes, keyBytes, ivBytes) {
371
372 // console.log(dT(), 'AES decrypt start', encryptedBytes.length)
373 const decryptedWords = CryptoJS.AES.decrypt({ ciphertext: bytesToWords(encryptedBytes) }, bytesToWords(keyBytes), {
374 iv: bytesToWords(ivBytes),
375 padding: CryptoJS.pad.NoPadding,
376 mode: CryptoJS.mode.IGE
377 });
378
379 const bytes = bytesFromWords(decryptedWords);
380 // console.log(dT(), 'AES decrypt finish')
381
382 return bytes;
383}
384
385export function gzipUncompress(bytes) {
386 // console.log('Gzip uncompress start')
387 const result = inflate(bytes);
388 // console.log('Gzip uncompress finish')
389 return result;
390}
391
392export function nextRandomInt(maxValue) {
393 return Math.floor(Math.random() * maxValue);
394}
395
396// const bytesToInt = bytes => Int(bytesToHex(bytes), 16)
397// const bytesFromInt = int => bytesFromHex(int.toString(16))
398
399export function pqPrimeFactorization(pqBytes) {
400 const what = new BigInteger(pqBytes);
401 // const whatInt = bytesToInt(pqBytes)
402 // const whatBn = new BN(bytesToHex(pqBytes), 16)
403 let result = false;
404 // let intRes = []
405 // const bnRes = []
406 // console.log(dT(), 'PQ start', pqBytes, what.toString(16), what.bitLength())
407
408 // try {
409 // console.time('pq leemon')
410 // const toHex = bytesToHex(pqBytes)
411 result = pqPrimeLeemon(str2bigInt(what.toString(16), 16, Math.ceil(64 / bpe) + 1));
412 // console.timeEnd('pq leemon')
413 // } catch (e) {
414 // console.error('Pq leemon Exception', e)
415 // }
416
417 /*if (result === false && what.bitLength() <= 64) {
418 // console.time('PQ long')
419 try {
420 result = pqPrimeLong(goog.math.Long.fromString(what.toString(16), 16))
421 } catch (e) {
422 console.error('Pq long Exception', e)
423 }
424 // console.timeEnd('PQ long')
425 }*/
426 // console.log(result)
427
428 // if (result === false) {
429 // console.time('pq BigInt')
430 // intRes = pqPrimeJsbn(what)
431 // console.timeEnd('pq BigInt')
432
433 // console.time('pq bn')
434 // bnRes = pqPrimeBN(whatBn)
435 // console.timeEnd('pq bn')
436 // }
437 // console.log(...result, ...bnRes)
438 // console.log(dT(), 'PQ finish')
439
440 return result;
441 //intRes//result//bnRes
442}
443
444/*export function pqPrimeBN(what) {
445 let it = 0,
446 g
447 const nOne = new BN(1)
448 for (let i = 0; i < 3; i++) {
449 const q = (nextRandomInt(128) & 15) + 17
450 let x = new BN(nextRandomInt(1000000000) + 1)
451 let y = x.clone()
452 const lim = 1 << (i + 18)
453
454 for (let j = 1; j < lim; j++) {
455 ++it
456 let a = x.clone()
457 let b = x.clone()
458 let c = new BN(q)
459
460 while (!b.isZero()) {
461 if (!b.and(nOne).isZero()) {
462 c = c.add(a)
463 if (c.gt(what)) {
464 c = c.sub(what)
465 }
466 }
467 a = a.add(a)
468 if (a.gt(what)) {
469 a = a.sub(what)
470 }
471 b = b.shrn(1)
472 }
473
474 x = c.clone()
475 const z = x.lt(y)
476 ? y.sub(x)
477 : x.sub(y)
478 g = z.gcd(what)
479 if (!g.eq(nOne)) {
480 break
481 }
482 if ((j & (j - 1)) == 0) {
483 y = x.clone()
484 }
485 }
486 if (g.gt(nOne)) {
487 break
488 }
489 }
490
491 let f = what.div(g), P, Q
492
493 if (g.gt(f)) {
494 P = f
495 Q = g
496 } else {
497 P = g
498 Q = f
499 }
500
501 return [P.toArray(), Q.toArray(), it]
502}*/
503
504export function pqPrimeJsbn(what) {
505 let it = 0,
506 g;
507 for (let i = 0; i < 3; i++) {
508 const q = (nextRandomInt(128) & 15) + 17;
509 let x = bigint(nextRandomInt(1000000000) + 1);
510 let y = x.clone();
511 const lim = 1 << i + 18;
512
513 for (let j = 1; j < lim; j++) {
514 ++it;
515 let a = x.clone();
516 let b = x.clone();
517 let c = bigint(q);
518
519 while (!b.equals(BigInteger.ZERO)) {
520 if (!b.and(BigInteger.ONE).equals(BigInteger.ZERO)) {
521 c = c.add(a);
522 if (c.compareTo(what) > 0) {
523 c = c.subtract(what);
524 }
525 }
526 a = a.add(a);
527 if (a.compareTo(what) > 0) {
528 a = a.subtract(what);
529 }
530 b = b.shiftRight(1);
531 }
532
533 x = c.clone();
534 const z = x.compareTo(y) < 0 ? y.subtract(x) : x.subtract(y);
535 g = z.gcd(what);
536 if (!g.equals(BigInteger.ONE)) {
537 break;
538 }
539 if ((j & j - 1) == 0) {
540 y = x.clone();
541 }
542 }
543 if (g.compareTo(BigInteger.ONE) > 0) {
544 break;
545 }
546 }
547
548 let f = what.divide(g),
549 P,
550 Q;
551
552 if (g.compareTo(f) > 0) {
553 P = f;
554 Q = g;
555 } else {
556 P = g;
557 Q = f;
558 }
559
560 return [bytesFromBigInt(P), bytesFromBigInt(Q), it];
561}
562
563/*export function pqPrimeBigInteger(what) {
564 let it = 0,
565 g
566 for (let i = 0; i < 3; i++) {
567 const q = (nextRandomInt(128) & 15) + 17
568 let x = Int(nextRandomInt(1000000000) + 1)
569 let y = Int(x)
570 const lim = 1 << (i + 18)
571
572 for (let j = 1; j < lim; j++) {
573 ++it
574 let a = Int(x)
575 let b = Int(x)
576 let c = Int(q)
577
578 while (!b.isZero()) {
579 if (!b.and(Int.one).isZero()) {
580 c = c.add(a)
581 if (c.greater(what))
582 c = c.subtract(what)
583 }
584 a = a.add(a)
585 if (a.greater(what))
586 a = a.subtract(what)
587 b = b.shiftRight(1)
588 }
589
590 x = Int(c)
591 const z = x.lesser(y)
592 ? y.subtract(x)
593 : x.subtract(y)
594 g = Int.gcd(z, what)
595 if (g.notEquals(Int.one))
596 break
597 if ((j & (j - 1)) == 0)
598 y = Int(x)
599 }
600 if (g.greater(Int.one))
601 break
602 }
603
604 const f = what.divide(g)
605 let P, Q
606
607 if (g.greater(f)) {
608 P = f
609 Q = g
610 } else {
611 P = g
612 Q = f
613 }
614
615 return [bytesFromInt(P), bytesFromInt(Q), it]
616}*/
617
618/*export function gcdLong(a, b) {
619 while (a.notEquals(goog.math.Long.ZERO) && b.notEquals(goog.math.Long.ZERO)) {
620 while (b.and(goog.math.Long.ONE).equals(goog.math.Long.ZERO)) {
621 b = b.shiftRight(1)
622 }
623 while (a.and(goog.math.Long.ONE).equals(goog.math.Long.ZERO)) {
624 a = a.shiftRight(1)
625 }
626 if (a.compare(b) > 0) {
627 a = a.subtract(b)
628 } else {
629 b = b.subtract(a)
630 }
631 }
632 return b.equals(goog.math.Long.ZERO) ? a : b
633}
634
635export function pqPrimeLong(what) {
636 let it = 0,
637 g
638 for (let i = 0; i < 3; i++) {
639 const q = goog.math.Long.fromInt((nextRandomInt(128) & 15) + 17)
640 let x = goog.math.Long.fromInt(nextRandomInt(1000000000) + 1)
641 let y = x
642 const lim = 1 << (i + 18)
643
644 for (let j = 1; j < lim; j++) {
645 ++it
646 let a = x
647 let b = x
648 let c = q
649
650 while (b.notEquals(goog.math.Long.ZERO)) {
651 if (b.and(goog.math.Long.ONE).notEquals(goog.math.Long.ZERO)) {
652 c = c.add(a)
653 if (c.compare(what) > 0) {
654 c = c.subtract(what)
655 }
656 }
657 a = a.add(a)
658 if (a.compare(what) > 0) {
659 a = a.subtract(what)
660 }
661 b = b.shiftRight(1)
662 }
663
664 x = c
665 const z = x.compare(y) < 0 ? y.subtract(x) : x.subtract(y)
666 g = gcdLong(z, what)
667 if (g.notEquals(goog.math.Long.ONE)) {
668 break
669 }
670 if ((j & (j - 1)) == 0) {
671 y = x
672 }
673 }
674 if (g.compare(goog.math.Long.ONE) > 0) {
675 break
676 }
677 }
678
679 let f = what.div(g), P, Q
680
681 if (g.compare(f) > 0) {
682 P = f
683 Q = g
684 } else {
685 P = g
686 Q = f
687 }
688
689 return [bytesFromHex(P.toString(16)), bytesFromHex(Q.toString(16)), it]
690}*/
691
692/*//is bigint x equal to integer y?
693//y must have less than bpe bits
694function equalsInt(x,y) {
695 var i;
696 if (x[0]!=y)
697 return 0;
698 for (i=1;i<x.length;i++)
699 if (x[i])
700 return 0;
701 return 1;
702}*/
703
704export function pqPrimeLeemon(what) {
705 const minBits = 64;
706 const minLen = Math.ceil(minBits / bpe) + 1;
707 let it = 0;
708 let q, lim;
709 const a = new Array(minLen);
710 const b = new Array(minLen);
711 const c = new Array(minLen);
712 const g = new Array(minLen);
713 const z = new Array(minLen);
714 const x = new Array(minLen);
715 const y = new Array(minLen);
716
717 for (let i = 0; i < 3; i++) {
718 q = (nextRandomInt(128) & 15) + 17;
719 copyInt_(x, nextRandomInt(1000000000) + 1);
720 copy_(y, x);
721 lim = 1 << i + 18;
722
723 for (let j = 1; j < lim; j++) {
724 ++it;
725 copy_(a, x);
726 copy_(b, x);
727 copyInt_(c, q);
728
729 while (!isZero(b)) {
730 if (b[0] & 1) {
731 add_(c, a);
732 if (greater(c, what)) {
733 sub_(c, what);
734 }
735 }
736 add_(a, a);
737 if (greater(a, what)) {
738 sub_(a, what);
739 }
740 rightShift_(b, 1);
741 }
742
743 copy_(x, c);
744 if (greater(x, y)) {
745 copy_(z, x);
746 sub_(z, y);
747 } else {
748 copy_(z, y);
749 sub_(z, x);
750 }
751 eGCD_(z, what, g, a, b);
752 if (!equalsInt(g, 1)) {
753 break;
754 }
755 if ((j & j - 1) === 0) {
756 copy_(y, x);
757 }
758 }
759 if (greater(g, one)) {
760 break;
761 }
762 }
763
764 divide_(what, g, x, y);
765
766 const [P, Q] = greater(g, x) ? [x, g] : [g, x];
767
768 // console.log(dT(), 'done', bigInt2str(what, 10), bigInt2str(P, 10), bigInt2str(Q, 10))
769
770 return [bytesFromLeemonBigInt(P), bytesFromLeemonBigInt(Q), it];
771}
772
773export function bytesModPow(x, y, m) {
774 try {
775 const xBigInt = str2bigInt(bytesToHex(x), 16);
776 const yBigInt = str2bigInt(bytesToHex(y), 16);
777 const mBigInt = str2bigInt(bytesToHex(m), 16);
778 const resBigInt = powMod(xBigInt, yBigInt, mBigInt);
779
780 return bytesFromHex(bigInt2str(resBigInt, 16));
781 } catch (e) {
782 console.error('mod pow error', e);
783 }
784
785 return bytesFromBigInt(new BigInteger(x).modPow(new BigInteger(y), new BigInteger(m)), 256);
786}
787//# sourceMappingURL=bin.js.map
\No newline at end of file