/
big-number-utils.ts
84 lines (63 loc) · 2.37 KB
/
big-number-utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright 2022 @webb-tools/
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable sort-keys */
import crypto from 'crypto';
import { BigNumber, BigNumberish, ethers } from 'ethers';
import * as ffjavascript from 'ffjavascript';
const { leBuff2int } = ffjavascript.utils;
export const FIELD_SIZE = BigNumber.from(
'21888242871839275222246405745257275088548364400416034343698204186575808495617'
);
export const median = (arr: number[]): number => {
const s = [...arr].sort((a, b) => a - b);
const mid = Math.floor(s.length / 2);
return s.length % 2 === 0 ? ((s[mid - 1] + s[mid]) / 2) : s[mid];
};
export const mean = (arr: number[]) => arr.reduce((p, c) => p + c, 0) / arr.length;
export const max = (arr: number[]) => arr.reduce((a, b) => a > b ? a : b);
export const min = (arr: number[]) => arr.reduce((a, b) => a <= b ? a : b);
/** Generate random number of specified byte length */
export const randomBN = (nbytes = 31) => BigNumber.from(crypto.randomBytes(nbytes));
export const rbigint = (nbytes: number) => leBuff2int(crypto.randomBytes(nbytes));
export const toHex = (covertThis: ethers.utils.BytesLike | number | bigint, padding: number): string => {
return ethers.utils.hexZeroPad(ethers.utils.hexlify(covertThis), padding);
};
/** BigNumber to hex string of specified length */
export function toFixedHex (number: BigNumberish, length = 32): string {
let result =
'0x' +
(number instanceof Buffer
? number.toString('hex')
: BigNumber.from(number).toHexString().replace('0x', '')
).padStart(length * 2, '0');
if (result.indexOf('-') > -1) {
result = '-' + result.replace('-', '');
}
return result;
}
/** Pad the bigint to 256 bits (32 bytes) */
export function p256 (n: bigint) {
let nstr = BigInt(n).toString(16);
while (nstr.length < 64) {
nstr = '0' + nstr;
}
nstr = `"0x${nstr}"`;
return nstr;
}
/** Convert value into buffer of specified byte length */
export const toBuffer = (value: BigNumberish, length: number) => {
return Buffer.from(
BigNumber.from(value)
.toHexString()
.slice(2)
.padStart(length * 2, '0'),
'hex'
);
};
export function createRootsBytes (rootArray: string[] | BigNumberish[]) {
let rootsBytes = '0x';
for (let i = 0; i < rootArray.length; i++) {
rootsBytes += toFixedHex(rootArray[i]).slice(2);
}
return rootsBytes; // root byte string (32 * array.length bytes)
}