Skip to content

Commit

Permalink
crypto: refactor ArrayBuffer to bigint conversion utils
Browse files Browse the repository at this point in the history
PR-URL: #45567
Refs: nodejs/performance#16
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
aduh95 authored and danielleadams committed Jan 4, 2023
1 parent b97a2f4 commit 49ab8f0
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
35 changes: 31 additions & 4 deletions lib/internal/crypto/random.js
Expand Up @@ -2,17 +2,22 @@

const {
Array,
ArrayBufferPrototypeGetByteLength,
ArrayPrototypeForEach,
ArrayPrototypePush,
ArrayPrototypeShift,
ArrayPrototypeSplice,
BigInt,
BigIntPrototypeToString,
DataView,
DataViewPrototypeGetUint8,
FunctionPrototypeBind,
FunctionPrototypeCall,
MathMin,
NumberIsNaN,
NumberIsSafeInteger,
NumberPrototypeToString,
StringFromCharCodeApply,
StringPrototypePadStart,
} = primordials;

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

function arrayBufferToUnsignedBigInt(arrayBuffer) {
return BigInt(`0x${Buffer.from(arrayBuffer).toString('hex')}`);
/**
* 48 is the ASCII code for '0', 97 is the ASCII code for 'a'.
* @param {number} number An integer between 0 and 15.
* @returns {number} corresponding to the ASCII code of the hex representation
* of the parameter.
*/
const numberToHexCharCode = (number) => (number < 10 ? 48 : 87) + number;

/**
* @param {ArrayBuffer} buf An ArrayBuffer.
* @return {bigint}
*/
function arrayBufferToUnsignedBigInt(buf) {
const length = ArrayBufferPrototypeGetByteLength(buf);
const chars = Array(length * 2);
const view = new DataView(buf);

for (let i = 0; i < length; i++) {
const val = DataViewPrototypeGetUint8(view, i);
chars[2 * i] = numberToHexCharCode(val >> 4);
chars[2 * i + 1] = numberToHexCharCode(val & 0xf);
}

return BigInt(`0x${StringFromCharCodeApply(chars)}`);
}

function unsignedBigIntToBuffer(bigint, name) {
if (bigint < 0) {
throw new ERR_OUT_OF_RANGE(name, '>= 0', bigint);
}

const hex = bigint.toString(16);
const padded = hex.padStart(hex.length + (hex.length % 2), 0);
const hex = BigIntPrototypeToString(bigint, 16);
const padded = StringPrototypePadStart(hex, hex.length + (hex.length % 2), 0);
return Buffer.from(padded, 'hex');
}

Expand Down
2 changes: 2 additions & 0 deletions lib/internal/per_context/primordials.js
Expand Up @@ -45,6 +45,8 @@ const varargsMethods = [
'MathHypot',
'MathMax',
'MathMin',
'StringFromCharCode',
'StringFromCodePoint',
'StringPrototypeConcat',
'TypedArrayOf',
];
Expand Down
2 changes: 2 additions & 0 deletions typings/primordials.d.ts
Expand Up @@ -422,7 +422,9 @@ declare namespace primordials {
export const StringName: typeof String.name
export const StringPrototype: typeof String.prototype
export const StringFromCharCode: typeof String.fromCharCode
export const StringFromCharCodeApply: StaticApply<typeof String.fromCharCode>
export const StringFromCodePoint: typeof String.fromCodePoint
export const StringFromCodePointApply: StaticApply<typeof String.fromCodePoint>
export const StringRaw: typeof String.raw
export const StringPrototypeAnchor: UncurryThis<typeof String.prototype.anchor>
export const StringPrototypeBig: UncurryThis<typeof String.prototype.big>
Expand Down

0 comments on commit 49ab8f0

Please sign in to comment.