Skip to content

Commit e7f172c

Browse files
authored
crypto: refactor ArrayBuffer to bigint conversion utils
PR-URL: #45567 Refs: nodejs/performance#16 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent fb91ee4 commit e7f172c

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

lib/internal/crypto/random.js

+31-4
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22

33
const {
44
Array,
5+
ArrayBufferPrototypeGetByteLength,
56
ArrayPrototypeForEach,
67
ArrayPrototypePush,
78
ArrayPrototypeShift,
89
ArrayPrototypeSplice,
910
BigInt,
11+
BigIntPrototypeToString,
12+
DataView,
13+
DataViewPrototypeGetUint8,
1014
FunctionPrototypeBind,
1115
FunctionPrototypeCall,
1216
MathMin,
1317
NumberIsNaN,
1418
NumberIsSafeInteger,
1519
NumberPrototypeToString,
20+
StringFromCharCodeApply,
1621
StringPrototypePadStart,
1722
} = primordials;
1823

@@ -493,17 +498,39 @@ function generatePrimeSync(size, options = kEmptyObject) {
493498
return job.result(prime);
494499
}
495500

496-
function arrayBufferToUnsignedBigInt(arrayBuffer) {
497-
return BigInt(`0x${Buffer.from(arrayBuffer).toString('hex')}`);
501+
/**
502+
* 48 is the ASCII code for '0', 97 is the ASCII code for 'a'.
503+
* @param {number} number An integer between 0 and 15.
504+
* @returns {number} corresponding to the ASCII code of the hex representation
505+
* of the parameter.
506+
*/
507+
const numberToHexCharCode = (number) => (number < 10 ? 48 : 87) + number;
508+
509+
/**
510+
* @param {ArrayBuffer} buf An ArrayBuffer.
511+
* @return {bigint}
512+
*/
513+
function arrayBufferToUnsignedBigInt(buf) {
514+
const length = ArrayBufferPrototypeGetByteLength(buf);
515+
const chars = Array(length * 2);
516+
const view = new DataView(buf);
517+
518+
for (let i = 0; i < length; i++) {
519+
const val = DataViewPrototypeGetUint8(view, i);
520+
chars[2 * i] = numberToHexCharCode(val >> 4);
521+
chars[2 * i + 1] = numberToHexCharCode(val & 0xf);
522+
}
523+
524+
return BigInt(`0x${StringFromCharCodeApply(chars)}`);
498525
}
499526

500527
function unsignedBigIntToBuffer(bigint, name) {
501528
if (bigint < 0) {
502529
throw new ERR_OUT_OF_RANGE(name, '>= 0', bigint);
503530
}
504531

505-
const hex = bigint.toString(16);
506-
const padded = hex.padStart(hex.length + (hex.length % 2), 0);
532+
const hex = BigIntPrototypeToString(bigint, 16);
533+
const padded = StringPrototypePadStart(hex, hex.length + (hex.length % 2), 0);
507534
return Buffer.from(padded, 'hex');
508535
}
509536

lib/internal/per_context/primordials.js

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ const varargsMethods = [
4545
'MathHypot',
4646
'MathMax',
4747
'MathMin',
48+
'StringFromCharCode',
49+
'StringFromCodePoint',
4850
'StringPrototypeConcat',
4951
'TypedArrayOf',
5052
];

typings/primordials.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,9 @@ declare namespace primordials {
422422
export const StringName: typeof String.name
423423
export const StringPrototype: typeof String.prototype
424424
export const StringFromCharCode: typeof String.fromCharCode
425+
export const StringFromCharCodeApply: StaticApply<typeof String.fromCharCode>
425426
export const StringFromCodePoint: typeof String.fromCodePoint
427+
export const StringFromCodePointApply: StaticApply<typeof String.fromCodePoint>
426428
export const StringRaw: typeof String.raw
427429
export const StringPrototypeAnchor: UncurryThis<typeof String.prototype.anchor>
428430
export const StringPrototypeBig: UncurryThis<typeof String.prototype.big>

0 commit comments

Comments
 (0)