UNPKG

12.8 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.strDecToHex = undefined;
7exports.bigint = bigint;
8exports.bigStringInt = bigStringInt;
9exports.bytesToHex = bytesToHex;
10exports.bytesFromHex = bytesFromHex;
11exports.bytesCmp = bytesCmp;
12exports.bytesXor = bytesXor;
13exports.bytesToWords = bytesToWords;
14exports.bytesFromWords = bytesFromWords;
15exports.bytesFromLeemonBigInt = bytesFromLeemonBigInt;
16exports.bytesToArrayBuffer = bytesToArrayBuffer;
17exports.convertToArrayBuffer = convertToArrayBuffer;
18exports.convertToUint8Array = convertToUint8Array;
19exports.convertToByteArray = convertToByteArray;
20exports.bytesFromArrayBuffer = bytesFromArrayBuffer;
21exports.bufferConcat = bufferConcat;
22exports.longToInts = longToInts;
23exports.longToBytes = longToBytes;
24exports.lshift32 = lshift32;
25exports.intToUint = intToUint;
26exports.uintToInt = uintToInt;
27exports.sha1HashSync = sha1HashSync;
28exports.sha1BytesSync = sha1BytesSync;
29exports.sha256HashSync = sha256HashSync;
30exports.rsaEncrypt = rsaEncrypt;
31exports.addPadding = addPadding;
32exports.aesEncryptSync = aesEncryptSync;
33exports.aesDecryptSync = aesDecryptSync;
34exports.gzipUncompress = gzipUncompress;
35exports.nextRandomInt = nextRandomInt;
36exports.pqPrimeFactorization = pqPrimeFactorization;
37exports.pqPrimeLeemon = pqPrimeLeemon;
38exports.bytesModPow = bytesModPow;
39
40var _ramda = require('ramda');
41
42var _jsbn = require('jsbn');
43
44var _rusha = require('rusha');
45
46var _rusha2 = _interopRequireDefault(_rusha);
47
48var _nodeCryptojsAes = require('@goodmind/node-cryptojs-aes');
49
50var CryptoJSlib = _interopRequireWildcard(_nodeCryptojsAes);
51
52var _inflate = require('pako/lib/inflate');
53
54var _secureRandom = require('./service/secure-random');
55
56var _secureRandom2 = _interopRequireDefault(_secureRandom);
57
58var _leemon = require('./vendor/leemon');
59
60function _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
62function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
63
64const { CryptoJS } = CryptoJSlib;
65
66// import Timer from 'hirestime' //TODO remove in prod!
67
68const rushaInstance = new _rusha2.default(1024 * 1024);
69
70function bigint(num) {
71 return new _jsbn.BigInteger(num.toString(16), 16);
72}
73
74function bigStringInt(strNum) {
75 return new _jsbn.BigInteger(strNum, 10);
76}
77
78// export const rShift32 = str => {
79// const num = str2bigInt(str, 10, 0)
80// rightShift_(num, 32)
81// return bigInt2str(num, 10)
82// }
83const strDecToHex = exports.strDecToHex = str => (0, _ramda.toLower)((0, _leemon.bigInt2str)((0, _leemon.str2bigInt)(str, 10, 0), 16));
84
85function 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
93function 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
110function 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
122function 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
133function 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
147function 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
159function bytesFromLeemonBigInt(bigInt) {
160 const str = (0, _leemon.bigInt2str)(bigInt, 16);
161 return bytesFromHex(str);
162}
163
164function bytesToArrayBuffer(b) {
165 return new Uint8Array(b).buffer;
166}
167
168function convertToArrayBuffer(bytes) {
169 // Be careful with converting subarrays!!
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
179function convertToUint8Array(bytes) {
180 if (bytes.buffer !== undefined) return bytes;
181 return new Uint8Array(bytes);
182}
183
184function 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
192function bytesFromArrayBuffer(buffer) {
193 const byteView = new Uint8Array(buffer);
194 const bytes = Array.from(byteView);
195 return bytes;
196}
197
198function 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// const dividerBig = bigint(0x100000000)
209const dividerLem = (0, _leemon.str2bigInt)('100000000', 16, 4);
210
211// const printTimers = (timeL, timeB, a, b, n) => setTimeout(
212// () => console.log(`Timer L ${timeL} B ${timeB}`, ...a, ...b, n || ''),
213// 100)
214
215function longToInts(sLong) {
216 /*const bigTime = Timer()
217 const divRem = bigStringInt(sLong).divideAndRemainder(dividerBig)
218 const divIntB = divRem[0].intValue()
219 const remIntB = divRem[1].intValue()
220 const resB = [
221 intToUint(divIntB),
222 intToUint(remIntB)
223 ]
224 const timeB = bigTime()*/
225
226 // const lemTime = Timer()
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 // const timeL = lemTime()
233
234 // printTimers(timeL, timeB, resL, resB)
235 return resL;
236}
237
238function longToBytes(sLong) {
239 return bytesFromWords({ words: longToInts(sLong), sigBytes: 8 }).reverse();
240}
241
242function 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// export function longFromLem(high, low) {
252// const highNum = int2bigInt(high, 96, 0)
253// leftShift_(highNum, 32)
254
255// addInt_(highNum, low)
256// const res = bigInt2str(highNum, 10)
257// return res
258// }
259
260function intToUint(val) {
261 val = parseInt(val); //TODO PERF parseInt is a perfomance issue
262 if (val < 0) val = val + 4294967296;
263 return val;
264}
265
266function uintToInt(val) {
267 if (val > 2147483647) val = val - 4294967296;
268 return val;
269}
270
271function sha1HashSync(bytes) {
272 // console.log(dT(), 'SHA-1 hash start', bytes.byteLength || bytes.length)
273 const hashBytes = rushaInstance.rawDigest(bytes).buffer;
274 // console.log(dT(), 'SHA-1 hash finish')
275
276 return hashBytes;
277}
278
279function sha1BytesSync(bytes) {
280 return bytesFromArrayBuffer(sha1HashSync(bytes));
281}
282
283function sha256HashSync(bytes) {
284 // console.log(dT(), 'SHA-2 hash start', bytes.byteLength || bytes.length)
285 const hashWords = CryptoJS.SHA256(bytesToWords(bytes));
286 // console.log(dT(), 'SHA-2 hash finish')
287
288 const hashBytes = bytesFromWords(hashWords);
289
290 return hashBytes;
291}
292
293function 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
305function 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
321function aesEncryptSync(bytes, keyBytes, ivBytes) {
322 const len = bytes.byteLength || bytes.length;
323
324 // console.log(dT(), 'AES encrypt start', len/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/)
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 // console.log(dT(), 'AES encrypt finish')
335
336 return encryptedBytes;
337}
338
339function aesDecryptSync(encryptedBytes, keyBytes, ivBytes) {
340
341 // console.log(dT(), 'AES decrypt start', encryptedBytes.length)
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 // console.log(dT(), 'AES decrypt finish')
350
351 return bytes;
352}
353
354function gzipUncompress(bytes) {
355 // console.log('Gzip uncompress start')
356 const result = (0, _inflate.inflate)(bytes);
357 // console.log('Gzip uncompress finish')
358 return result;
359}
360
361function nextRandomInt(maxValue) {
362 return Math.floor(Math.random() * maxValue);
363}
364
365function pqPrimeFactorization(pqBytes) {
366 const minSize = Math.ceil(64 / _leemon.bpe) + 1;
367
368 // const what = new BigInteger(pqBytes)
369 const hex = bytesToHex(pqBytes);
370 const lWhat = (0, _leemon.str2bigInt)(hex, 16, minSize);
371 const result = pqPrimeLeemon(lWhat);
372 return result;
373}
374
375function 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 // console.log(dT(), 'done', bigInt2str(what, 10), bigInt2str(P, 10), bigInt2str(Q, 10))
440
441 return [bytesFromLeemonBigInt(P), bytesFromLeemonBigInt(Q), it];
442}
443
444function 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//# sourceMappingURL=bin.js.map
\No newline at end of file