@javakha77/circomlibjs-hinkal-fork 0.0.12 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/main.cjs +286 -3
- package/main.js +1 -1
- package/package.json +1 -1
- package/src/EddsaRN.js +2 -3
- package/src/poseidonRN.js +23 -44
- package/src/protocol.constants.js +1 -3
- package/src/serialize.utils.js +5 -5
package/build/main.cjs
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
var ffjavascript = require('ffjavascript');
|
|
4
4
|
var blake1_js = require('@noble/hashes/blake1.js');
|
|
5
|
+
var poseidonLite = require('poseidon-lite');
|
|
6
|
+
|
|
7
|
+
function _interopNamespaceDefault(e) {
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var poseidonLite__namespace = /*#__PURE__*/_interopNamespaceDefault(poseidonLite);
|
|
5
25
|
|
|
6
26
|
async function buildBabyJub() {
|
|
7
27
|
const bn128 = await ffjavascript.getCurveFromName("bn128", true);
|
|
@@ -24948,7 +24968,7 @@ var poseidonConstants = {
|
|
|
24948
24968
|
]
|
|
24949
24969
|
};
|
|
24950
24970
|
|
|
24951
|
-
async function buildPoseidon() {
|
|
24971
|
+
async function buildPoseidon$1() {
|
|
24952
24972
|
const bn128 = await ffjavascript.getCurveFromName("bn128", true, buildPoseidonWasm);
|
|
24953
24973
|
|
|
24954
24974
|
const F = bn128.Fr;
|
|
@@ -25379,7 +25399,7 @@ function buildPoseidonWasm(module) {
|
|
|
25379
25399
|
|
|
25380
25400
|
async function buildEddsa() {
|
|
25381
25401
|
const babyJub = await buildBabyJub();
|
|
25382
|
-
const poseidon = await buildPoseidon();
|
|
25402
|
+
const poseidon = await buildPoseidon$1();
|
|
25383
25403
|
return new Eddsa(babyJub, poseidon);
|
|
25384
25404
|
}
|
|
25385
25405
|
|
|
@@ -25474,7 +25494,270 @@ class Eddsa {
|
|
|
25474
25494
|
}
|
|
25475
25495
|
}
|
|
25476
25496
|
|
|
25497
|
+
const CIRCOM_P = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
25498
|
+
|
|
25499
|
+
// Reduce value into [0, m); handles negative inputs.
|
|
25500
|
+
const mod = (value, m = CIRCOM_P) => {
|
|
25501
|
+
const result = value % m;
|
|
25502
|
+
return result >= 0n ? result : result + m;
|
|
25503
|
+
};
|
|
25504
|
+
|
|
25505
|
+
// Modular inverse via extended Euclidean algorithm (a^-1 mod m).
|
|
25506
|
+
const modInverse = (value, m = CIRCOM_P) => {
|
|
25507
|
+
let lm = 1n;
|
|
25508
|
+
let hm = 0n;
|
|
25509
|
+
let low = mod(value, m);
|
|
25510
|
+
let high = m;
|
|
25511
|
+
|
|
25512
|
+
if (low === 0n) throw new Error('Division by zero');
|
|
25513
|
+
|
|
25514
|
+
while (low > 1n) {
|
|
25515
|
+
const remainder = high % low;
|
|
25516
|
+
const quotient = high / low;
|
|
25517
|
+
high = low;
|
|
25518
|
+
low = remainder;
|
|
25519
|
+
const nm = hm - lm * quotient;
|
|
25520
|
+
hm = lm;
|
|
25521
|
+
lm = nm;
|
|
25522
|
+
}
|
|
25523
|
+
|
|
25524
|
+
return lm < 0n ? lm + m : lm;
|
|
25525
|
+
};
|
|
25526
|
+
|
|
25527
|
+
const P = CIRCOM_P;
|
|
25528
|
+
|
|
25529
|
+
// BabyJub base-field arithmetic over CIRCOM_P (same semantics as circomlibjs F).
|
|
25530
|
+
const F = {
|
|
25531
|
+
p: P,
|
|
25532
|
+
zero: 0n,
|
|
25533
|
+
one: 1n,
|
|
25534
|
+
e: (v) => mod(BigInt(v)),
|
|
25535
|
+
add: (a, b) => mod(a + b),
|
|
25536
|
+
sub: (a, b) => mod(a - b),
|
|
25537
|
+
mul: (a, b) => mod(a * b),
|
|
25538
|
+
div: (a, b) => {
|
|
25539
|
+
if (b === 0n) throw new Error('Division by zero in BabyJub field');
|
|
25540
|
+
return mod(a * modInverse(b));
|
|
25541
|
+
},
|
|
25542
|
+
toString: (a) => mod(a).toString(),
|
|
25543
|
+
};
|
|
25544
|
+
|
|
25545
|
+
/**
|
|
25546
|
+
* @typedef {{ X: bigint, Y: bigint, Z: bigint, T: bigint }} ExtPoint
|
|
25547
|
+
*/
|
|
25548
|
+
|
|
25549
|
+
// Neutral element in extended coordinates (affine identity 0, 1).
|
|
25550
|
+
const IDENTITY = { X: F.zero, Y: F.one, Z: F.one, T: F.zero };
|
|
25551
|
+
|
|
25552
|
+
// Embed an affine (x, y) point into extended twisted Edwards form.
|
|
25553
|
+
const toExtended = (affine) => {
|
|
25554
|
+
const x = F.e(affine[0]);
|
|
25555
|
+
const y = F.e(affine[1]);
|
|
25556
|
+
return { X: x, Y: y, Z: F.one, T: F.mul(x, y) };
|
|
25557
|
+
};
|
|
25558
|
+
|
|
25559
|
+
// Project an extended point back to affine (x, y) coordinates.
|
|
25560
|
+
const toAffine = (point) => {
|
|
25561
|
+
const zInv = modInverse(point.Z);
|
|
25562
|
+
return [F.mul(point.X, zInv), F.mul(point.Y, zInv)];
|
|
25563
|
+
};
|
|
25564
|
+
|
|
25565
|
+
const A = F.e('168700');
|
|
25566
|
+
const D = F.e('168696');
|
|
25567
|
+
|
|
25568
|
+
// Add two extended points (add-2008-hwcd; no per-step field inversions).
|
|
25569
|
+
const addExtended = (p1, p2) => {
|
|
25570
|
+
const a = F.mul(p1.X, p2.X);
|
|
25571
|
+
const b = F.mul(p1.Y, p2.Y);
|
|
25572
|
+
const c = F.mul(F.mul(p1.T, p2.T), D);
|
|
25573
|
+
const d = F.mul(p1.Z, p2.Z);
|
|
25574
|
+
const e = F.sub(F.mul(F.add(p1.X, p1.Y), F.add(p2.X, p2.Y)), F.add(a, b));
|
|
25575
|
+
const f = F.sub(d, c);
|
|
25576
|
+
const g = F.add(d, c);
|
|
25577
|
+
const h = F.sub(b, F.mul(A, a));
|
|
25578
|
+
return {
|
|
25579
|
+
X: F.mul(e, f),
|
|
25580
|
+
Y: F.mul(g, h),
|
|
25581
|
+
T: F.mul(e, h),
|
|
25582
|
+
Z: F.mul(f, g),
|
|
25583
|
+
};
|
|
25584
|
+
};
|
|
25585
|
+
|
|
25586
|
+
// Double an extended point (dbl-2008-hwcd; no per-step field inversions).
|
|
25587
|
+
const doubleExtended = (p) => {
|
|
25588
|
+
const a = F.mul(p.X, p.X);
|
|
25589
|
+
const b = F.mul(p.Y, p.Y);
|
|
25590
|
+
const c = F.mul(F.mul(p.Z, p.Z), 2n);
|
|
25591
|
+
const d = F.mul(A, a);
|
|
25592
|
+
const e = F.sub(F.mul(F.add(p.X, p.Y), F.add(p.X, p.Y)), F.add(a, b));
|
|
25593
|
+
const g = F.add(d, b);
|
|
25594
|
+
const f = F.sub(g, c);
|
|
25595
|
+
const h = F.sub(d, b);
|
|
25596
|
+
return {
|
|
25597
|
+
X: F.mul(e, f),
|
|
25598
|
+
Y: F.mul(g, h),
|
|
25599
|
+
T: F.mul(e, h),
|
|
25600
|
+
Z: F.mul(f, g),
|
|
25601
|
+
};
|
|
25602
|
+
};
|
|
25603
|
+
|
|
25604
|
+
// Pure-JS BabyJub curve used on React Native (circomlibjs uses WASM instead).
|
|
25605
|
+
class BabyJubRN {
|
|
25606
|
+
static A = A;
|
|
25607
|
+
|
|
25608
|
+
static D = D;
|
|
25609
|
+
|
|
25610
|
+
F = F;
|
|
25611
|
+
|
|
25612
|
+
A = A;
|
|
25613
|
+
|
|
25614
|
+
D = D;
|
|
25615
|
+
|
|
25616
|
+
// Standard BabyJub generator used by EdDSA (matches circomlibjs Base8).
|
|
25617
|
+
Base8 = [
|
|
25618
|
+
F.e('5299619240641551281634865583518297030282874472190772894086521144482721001553'),
|
|
25619
|
+
F.e('16950150798460657717958625567821834550301663161624707787222815936182638968203'),
|
|
25620
|
+
];
|
|
25621
|
+
|
|
25622
|
+
// Add two affine curve points.
|
|
25623
|
+
addPoint(a, b) {
|
|
25624
|
+
return toAffine(addExtended(toExtended(a), toExtended(b)));
|
|
25625
|
+
}
|
|
25626
|
+
|
|
25627
|
+
// Scalar multiplication: returns e * base (double-and-add in extended coords).
|
|
25628
|
+
mulPointEscalar(base, e) {
|
|
25629
|
+
let res = IDENTITY;
|
|
25630
|
+
let exp = toExtended(base);
|
|
25631
|
+
let rem = BigInt(e);
|
|
25632
|
+
|
|
25633
|
+
while (rem !== 0n) {
|
|
25634
|
+
if (rem % 2n === 1n) res = addExtended(res, exp);
|
|
25635
|
+
exp = doubleExtended(exp);
|
|
25636
|
+
rem /= 2n;
|
|
25637
|
+
}
|
|
25638
|
+
|
|
25639
|
+
return toAffine(res);
|
|
25640
|
+
}
|
|
25641
|
+
}
|
|
25642
|
+
|
|
25643
|
+
const toBigInt = (v) => {
|
|
25644
|
+
switch (typeof v) {
|
|
25645
|
+
case 'bigint': return v;
|
|
25646
|
+
case 'boolean': return v ? 1n : 0n;
|
|
25647
|
+
case 'number':
|
|
25648
|
+
if (!Number.isInteger(v)) throw new TypeError(`Poseidon: non-integer Number ${v}`);
|
|
25649
|
+
return BigInt(v);
|
|
25650
|
+
case 'string': {
|
|
25651
|
+
try { return BigInt(v.trim()); }
|
|
25652
|
+
catch { throw new TypeError(`Poseidon: cannot parse string "${v}" as an integer`); }
|
|
25653
|
+
}
|
|
25654
|
+
default:
|
|
25655
|
+
throw new TypeError(`Poseidon.F: unsupported value of type ${typeof v}`);
|
|
25656
|
+
}
|
|
25657
|
+
};
|
|
25658
|
+
|
|
25659
|
+
// poseidon-lite exposes `poseidon1`..`poseidon16`; wrap them in a `buildPoseidon`-shaped
|
|
25660
|
+
// factory (matching the WASM reference) so callers — and the existing
|
|
25661
|
+
// `poseidon.F.toString(...)` pattern — keep working on RN.
|
|
25662
|
+
const buildPoseidon = () => {
|
|
25663
|
+
const poseidon = (inputs, initState = 0, nOut = 1) => {
|
|
25664
|
+
const fn = poseidonLite__namespace[`poseidon${inputs.length}`];
|
|
25665
|
+
if (!fn) throw new Error(`Poseidon: arity ${inputs.length} not supported (1..16)`);
|
|
25666
|
+
const formattedInputs = inputs.map((v) => toBigInt(v));
|
|
25667
|
+
|
|
25668
|
+
if (nOut > 1) {
|
|
25669
|
+
const results = fn(formattedInputs, nOut);
|
|
25670
|
+
return results.map(v => BigInt(v));
|
|
25671
|
+
}
|
|
25672
|
+
|
|
25673
|
+
const res = fn(formattedInputs);
|
|
25674
|
+
return BigInt(res);
|
|
25675
|
+
};
|
|
25676
|
+
poseidon.F = {
|
|
25677
|
+
toString: (v) => toBigInt(v).toString(),
|
|
25678
|
+
e: (v) => toBigInt(v),
|
|
25679
|
+
eq: (a, b) => toBigInt(a) === toBigInt(b),
|
|
25680
|
+
};
|
|
25681
|
+
return poseidon;
|
|
25682
|
+
};
|
|
25683
|
+
|
|
25684
|
+
/* eslint-disable no-bitwise */
|
|
25685
|
+
// React Native port of circomlibjs-hinkal-fork/src/eddsa.js (Poseidon EdDSA over BabyJubJub).
|
|
25686
|
+
|
|
25687
|
+
const BABYJUB_ORDER = 21888242871839275222246405745257275088614511777268538073601725287587578984328n;
|
|
25688
|
+
const SUB_ORDER = BABYJUB_ORDER / 8n;
|
|
25689
|
+
|
|
25690
|
+
const leBuff2int = (buff, offset = 0, length = buff.length - offset) => {
|
|
25691
|
+
let result = 0n;
|
|
25692
|
+
for (let i = length - 1; i >= 0; i -= 1) {
|
|
25693
|
+
result = (result << 8n) + BigInt(buff[offset + i]);
|
|
25694
|
+
}
|
|
25695
|
+
return result;
|
|
25696
|
+
};
|
|
25697
|
+
|
|
25698
|
+
const toRprLE = (buff, offset, value, length) => {
|
|
25699
|
+
let v = mod(value);
|
|
25700
|
+
for (let i = 0; i < length; i += 1) {
|
|
25701
|
+
buff[offset + i] = Number(v & 0xffn);
|
|
25702
|
+
v >>= 8n;
|
|
25703
|
+
}
|
|
25704
|
+
};
|
|
25705
|
+
|
|
25706
|
+
const modSubOrder = (value) => mod(value, SUB_ORDER);
|
|
25707
|
+
|
|
25708
|
+
const pruneBuffer = (buff) => {
|
|
25709
|
+
const out = new Uint8Array(buff);
|
|
25710
|
+
out[0] = out[0] & 0xf8;
|
|
25711
|
+
out[31] = out[31] & 0x7f;
|
|
25712
|
+
out[31] = out[31] | 0x40;
|
|
25713
|
+
return out;
|
|
25714
|
+
};
|
|
25715
|
+
|
|
25716
|
+
/**
|
|
25717
|
+
* @typedef {((inputs: bigint[]) => bigint) & { F: { toString: (v: bigint | number | string) => string } }} PoseidonFn
|
|
25718
|
+
*/
|
|
25719
|
+
|
|
25720
|
+
class EddsaRN {
|
|
25721
|
+
constructor(babyJub, poseidon) {
|
|
25722
|
+
this.babyJub = babyJub;
|
|
25723
|
+
this.poseidon = poseidon;
|
|
25724
|
+
}
|
|
25725
|
+
|
|
25726
|
+
prv2pub(prv) {
|
|
25727
|
+
const sBuff = pruneBuffer(blake1_js.blake512(prv).slice(0, 32));
|
|
25728
|
+
const s = leBuff2int(sBuff, 0, 32);
|
|
25729
|
+
return this.babyJub.mulPointEscalar(this.babyJub.Base8, s / 8n);
|
|
25730
|
+
}
|
|
25731
|
+
|
|
25732
|
+
signPoseidon(prv, msg) {
|
|
25733
|
+
const sBuff = pruneBuffer(blake1_js.blake512(prv));
|
|
25734
|
+
const s = leBuff2int(sBuff, 0, 32);
|
|
25735
|
+
const A = this.babyJub.mulPointEscalar(this.babyJub.Base8, s / 8n);
|
|
25736
|
+
|
|
25737
|
+
const composeBuff = new Uint8Array(64);
|
|
25738
|
+
composeBuff.set(sBuff.slice(32), 0);
|
|
25739
|
+
toRprLE(composeBuff, 32, msg, 32);
|
|
25740
|
+
|
|
25741
|
+
const rBuff = blake1_js.blake512(composeBuff);
|
|
25742
|
+
const r = modSubOrder(leBuff2int(rBuff, 0, 64));
|
|
25743
|
+
const R8 = this.babyJub.mulPointEscalar(this.babyJub.Base8, r);
|
|
25744
|
+
|
|
25745
|
+
const hm = this.poseidon([R8[0], R8[1], A[0], A[1], msg]);
|
|
25746
|
+
const hms = mod(BigInt(this.poseidon.F.toString(hm)));
|
|
25747
|
+
const S = modSubOrder(r + modSubOrder(hms * s));
|
|
25748
|
+
|
|
25749
|
+
return { R8, S };
|
|
25750
|
+
}
|
|
25751
|
+
}
|
|
25752
|
+
|
|
25753
|
+
const buildEddsaRN = async () => {
|
|
25754
|
+
return new EddsaRN(new BabyJubRN(), buildPoseidon());
|
|
25755
|
+
};
|
|
25756
|
+
|
|
25757
|
+
exports.BabyJubRN = BabyJubRN;
|
|
25477
25758
|
exports.buildBabyjub = buildBabyJub;
|
|
25478
25759
|
exports.buildEddsa = buildEddsa;
|
|
25479
|
-
exports.
|
|
25760
|
+
exports.buildEddsaRN = buildEddsaRN;
|
|
25761
|
+
exports.buildPoseidon = buildPoseidon$1;
|
|
25762
|
+
exports.buildPoseidonRN = buildPoseidon;
|
|
25480
25763
|
exports.buildPoseidonWasm = buildPoseidonWasm;
|
package/main.js
CHANGED
package/package.json
CHANGED
package/src/EddsaRN.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// React Native port of circomlibjs-hinkal-fork/src/eddsa.js (Poseidon EdDSA over BabyJubJub).
|
|
3
3
|
import { blake512 } from '@noble/hashes/blake1.js';
|
|
4
4
|
import { BabyJubRN } from './babyjubRN.js';
|
|
5
|
-
import {
|
|
5
|
+
import { buildPoseidon as buildPoseidonRN } from './poseidonRN.js';
|
|
6
6
|
import { mod } from './bigint-math.utils.js';
|
|
7
7
|
|
|
8
8
|
const BABYJUB_ORDER = 21888242871839275222246405745257275088614511777268538073601725287587578984328n;
|
|
@@ -72,6 +72,5 @@ export class EddsaRN {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
export const buildEddsaRN = async () => {
|
|
75
|
-
|
|
76
|
-
return new EddsaRN(new BabyJubRN(), PoseidonRN.getPoseidon());
|
|
75
|
+
return new EddsaRN(new BabyJubRN(), buildPoseidonRN());
|
|
77
76
|
};
|
package/src/poseidonRN.js
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
import { ethers } from 'ethers';
|
|
2
1
|
import * as poseidonLite from 'poseidon-lite';
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
const toBigInt = (v) => {
|
|
4
|
+
switch (typeof v) {
|
|
5
|
+
case 'bigint': return v;
|
|
6
|
+
case 'boolean': return v ? 1n : 0n;
|
|
7
|
+
case 'number':
|
|
8
|
+
if (!Number.isInteger(v)) throw new TypeError(`Poseidon: non-integer Number ${v}`);
|
|
9
|
+
return BigInt(v);
|
|
10
|
+
case 'string': {
|
|
11
|
+
try { return BigInt(v.trim()); }
|
|
12
|
+
catch { throw new TypeError(`Poseidon: cannot parse string "${v}" as an integer`); }
|
|
13
|
+
}
|
|
14
|
+
default:
|
|
15
|
+
throw new TypeError(`Poseidon.F: unsupported value of type ${typeof v}`);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
4
18
|
|
|
5
19
|
// poseidon-lite exposes `poseidon1`..`poseidon16`; wrap them in a `buildPoseidon`-shaped
|
|
6
20
|
// factory (matching the WASM reference) so callers — and the existing
|
|
@@ -9,7 +23,7 @@ export const buildPoseidon = () => {
|
|
|
9
23
|
const poseidon = (inputs, initState = 0, nOut = 1) => {
|
|
10
24
|
const fn = poseidonLite[`poseidon${inputs.length}`];
|
|
11
25
|
if (!fn) throw new Error(`Poseidon: arity ${inputs.length} not supported (1..16)`);
|
|
12
|
-
const formattedInputs = inputs.map((v) =>
|
|
26
|
+
const formattedInputs = inputs.map((v) => toBigInt(v));
|
|
13
27
|
|
|
14
28
|
if (nOut > 1) {
|
|
15
29
|
const results = fn(formattedInputs, nOut);
|
|
@@ -19,45 +33,10 @@ export const buildPoseidon = () => {
|
|
|
19
33
|
const res = fn(formattedInputs);
|
|
20
34
|
return BigInt(res);
|
|
21
35
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
e: (v) =>
|
|
25
|
-
eq: (a, b) =>
|
|
26
|
-
|
|
36
|
+
poseidon.F = {
|
|
37
|
+
toString: (v) => toBigInt(v).toString(),
|
|
38
|
+
e: (v) => toBigInt(v),
|
|
39
|
+
eq: (a, b) => toBigInt(a) === toBigInt(b),
|
|
40
|
+
};
|
|
27
41
|
return poseidon;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
class PoseidonHolder {
|
|
31
|
-
poseidon = undefined;
|
|
32
|
-
|
|
33
|
-
async init() {
|
|
34
|
-
if (this.poseidon) return;
|
|
35
|
-
this.poseidon = buildPoseidon();
|
|
36
|
-
return this.poseidon;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
getPoseidon() {
|
|
40
|
-
return this.poseidon;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const PoseidonRN = new PoseidonHolder();
|
|
45
|
-
|
|
46
|
-
export function poseidonFunction(...args) {
|
|
47
|
-
const poseidon = PoseidonRN.getPoseidon();
|
|
48
|
-
return toBigInt(poseidon.F.toString(poseidon(args)));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* hashing algorithm implementation
|
|
53
|
-
* @param args rest parameter to take unlimited number of arguments
|
|
54
|
-
* @returns poseidon hash in base 16
|
|
55
|
-
*/
|
|
56
|
-
export const poseidonHash = (...args) => {
|
|
57
|
-
const poseidon = PoseidonRN.getPoseidon();
|
|
58
|
-
return ethers.toBeHex(poseidon.F.toString(poseidon([...args])));
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @typedef {(...args: unknown[]) => string} PoseidonHasher
|
|
63
|
-
*/
|
|
42
|
+
};
|
|
@@ -1,3 +1 @@
|
|
|
1
|
-
export const CIRCOM_P = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
2
|
-
export const CIRCOM_P_HALF = CIRCOM_P / 2n;
|
|
3
|
-
export const CIRCOM_MERKLE_LENGTH = 25;
|
|
1
|
+
export const CIRCOM_P = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
package/src/serialize.utils.js
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
// Safe JSON.stringify wrapper. Converts BigInt -> string so JSON serialization never throws.
|
|
6
|
-
|
|
6
|
+
export const safeJsonStringify = (value, replacer = null, space) =>
|
|
7
7
|
JSON.stringify(
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
value,
|
|
9
|
+
(key, nestedValue) => {
|
|
10
10
|
const next = typeof replacer === 'function' ? replacer(key, nestedValue) : nestedValue;
|
|
11
11
|
return typeof next === 'bigint' ? next.toString() : next;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
},
|
|
13
|
+
space,
|
|
14
14
|
);
|