@javakha77/circomlibjs-hinkal-fork 0.0.11 → 0.0.13

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