@javakha77/circomlibjs-hinkal-fork 0.0.14 → 0.0.15
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/package.json +18 -30
- package/src/amounts.utils.js +27 -22
- package/src/babyjubRN.js +12 -8
- package/src/bigint-math.utils.js +3 -3
- package/src/poseidonRN.js +25 -16
- package/src/protocol.constants.js +2 -1
- package/src/serialize.utils.js +10 -7
package/package.json
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@javakha77/circomlibjs-hinkal-fork",
|
|
3
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"main": "./build/main.cjs",
|
|
5
|
+
"module": "./main.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
"import": "./main.js",
|
|
8
|
+
"require": "./build/main.cjs"
|
|
9
|
+
},
|
|
10
|
+
"version": "0.0.15",
|
|
4
11
|
"description": "Javascript library to work with circomlib",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "mocha",
|
|
14
|
+
"poseidonOptimizeConstants": "node tools/poseidon_optimize_constants.js",
|
|
15
|
+
"build": "rollup -c rollup.cjs.config.js"
|
|
16
|
+
},
|
|
5
17
|
"keywords": [
|
|
6
18
|
"circom",
|
|
7
19
|
"circomlib",
|
|
@@ -11,40 +23,16 @@
|
|
|
11
23
|
"zero",
|
|
12
24
|
"knowledge"
|
|
13
25
|
],
|
|
14
|
-
"homepage": "https://github.com/Hinkal-Protocol/circomlibjs#readme",
|
|
15
|
-
"bugs": {
|
|
16
|
-
"url": "https://github.com/Hinkal-Protocol/circomlibjs/issues"
|
|
17
|
-
},
|
|
18
|
-
"repository": {
|
|
19
|
-
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/Hinkal-Protocol/circomlibjs.git"
|
|
21
|
-
},
|
|
22
26
|
"license": "GPL-3.0",
|
|
23
|
-
"author": "javakha77",
|
|
24
|
-
"type": "module",
|
|
25
|
-
"exports": {
|
|
26
|
-
"import": "./main.js",
|
|
27
|
-
"require": "./build/main.cjs"
|
|
28
|
-
},
|
|
29
|
-
"main": "./build/main.cjs",
|
|
30
|
-
"directories": {
|
|
31
|
-
"test": "test"
|
|
32
|
-
},
|
|
33
|
-
"scripts": {
|
|
34
|
-
"test": "mocha",
|
|
35
|
-
"poseidonOptimizeConstants": "node tools/poseidon_optimize_constants.js",
|
|
36
|
-
"build": "rollup -c rollup.cjs.config.js"
|
|
37
|
-
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"@noble/hashes": "^2.2.0",
|
|
40
|
-
"ffjavascript": "^0.3.0",
|
|
41
|
-
"poseidon-lite": "^0.3.0"
|
|
42
|
-
},
|
|
43
27
|
"devDependencies": {
|
|
44
28
|
"chai": "^4.3.4",
|
|
45
29
|
"ganache": "^7.3.0",
|
|
46
30
|
"mocha": "^9.1.3",
|
|
47
31
|
"rollup": "^4.60.4"
|
|
48
32
|
},
|
|
49
|
-
"
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@noble/hashes": "^2.2.0",
|
|
35
|
+
"ffjavascript": "^0.3.0",
|
|
36
|
+
"poseidon-lite": "^0.3.0"
|
|
37
|
+
}
|
|
50
38
|
}
|
package/src/amounts.utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { safeJsonStringify } from
|
|
1
|
+
import { safeJsonStringify } from "./serialize.utils.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @typedef {string | number | boolean | bigint | { toBigInt: () => bigint }} BigIntable
|
|
@@ -7,10 +7,11 @@ import { safeJsonStringify } from './serialize.utils.js';
|
|
|
7
7
|
export const calculateSum = (arr) => arr.reduce((prev, item) => prev + item, 0);
|
|
8
8
|
|
|
9
9
|
export const beepsToPercentage = (beeps) => beeps / 100;
|
|
10
|
-
export const calculateAmountUsingBeeps = (beep, amount) =>
|
|
10
|
+
export const calculateAmountUsingBeeps = (beep, amount) =>
|
|
11
|
+
(amount * beep) / 10000n;
|
|
11
12
|
|
|
12
13
|
export function toBigInt(value) {
|
|
13
|
-
if (typeof value ===
|
|
14
|
+
if (typeof value === "object" && "toBigInt" in value) {
|
|
14
15
|
return value.toBigInt();
|
|
15
16
|
}
|
|
16
17
|
return BigInt(value);
|
|
@@ -28,15 +29,17 @@ export const advancedToBigInt = (value) => {
|
|
|
28
29
|
return result;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
if (typeof value ===
|
|
32
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
32
33
|
return BigInt(value);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
if (typeof value ===
|
|
36
|
+
if (typeof value === "bigint") {
|
|
36
37
|
return value;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
throw new Error(
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Cannot convert value to BigInt: ${typeof value}, value: ${safeJsonStringify(value)}`,
|
|
42
|
+
);
|
|
40
43
|
};
|
|
41
44
|
|
|
42
45
|
/** Converts the value to a BigInt or returns undefined if can't */
|
|
@@ -66,13 +69,13 @@ export function fixDecimalsAmount(n, decimals) {
|
|
|
66
69
|
if (n === 0) {
|
|
67
70
|
return 0;
|
|
68
71
|
}
|
|
69
|
-
return n < 0.00000099999 ?
|
|
72
|
+
return n < 0.00000099999 ? " < 0.000001" : +Number(n).toFixed(decimals ?? 6);
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
export const getValueFirstNDigit = (num, numberOfDigits) => {
|
|
73
76
|
const numStr = num.toFixed(20); // if num = 0.03232e-17 -> it will transform to 0.00...03232
|
|
74
77
|
|
|
75
|
-
const indexOfDecimal = numStr.indexOf(
|
|
78
|
+
const indexOfDecimal = numStr.indexOf(".");
|
|
76
79
|
// If there's no decimal point, return the original number (or handle this case as you need)
|
|
77
80
|
if (indexOfDecimal === -1) return numStr;
|
|
78
81
|
|
|
@@ -88,24 +91,27 @@ export const getValueFirstNDigit = (num, numberOfDigits) => {
|
|
|
88
91
|
export const trimLeadingZeros = (numberString) => {
|
|
89
92
|
// String of repeating 0's (e.g. '0000000') should be replaced with '0', not empty string
|
|
90
93
|
if (/^0+$/.test(numberString)) {
|
|
91
|
-
return
|
|
94
|
+
return "0";
|
|
92
95
|
}
|
|
93
96
|
// One leading zero before decimal point is valid
|
|
94
97
|
if (/^0\.\d+$/.test(numberString)) {
|
|
95
98
|
return numberString;
|
|
96
99
|
}
|
|
97
|
-
const trimmed = numberString.replace(/^0+/,
|
|
98
|
-
return trimmed.startsWith(
|
|
100
|
+
const trimmed = numberString.replace(/^0+/, "");
|
|
101
|
+
return trimmed.startsWith(".") ? `0${trimmed}` : trimmed;
|
|
99
102
|
};
|
|
100
103
|
|
|
101
104
|
export const toCommaSeparatedNumberString = (numberString) => {
|
|
102
|
-
const parts = numberString.split(
|
|
105
|
+
const parts = numberString.split(".");
|
|
103
106
|
const integerPart = parts[0];
|
|
104
107
|
// Only add the . and decimal part if exist
|
|
105
|
-
const decimalPart = parts.length > 1 ? `.${parts[1]}` :
|
|
108
|
+
const decimalPart = parts.length > 1 ? `.${parts[1]}` : "";
|
|
106
109
|
|
|
107
110
|
// Use a regular expression to format the integer part with commas
|
|
108
|
-
const formattedIntegerPart = trimLeadingZeros(integerPart).replace(
|
|
111
|
+
const formattedIntegerPart = trimLeadingZeros(integerPart).replace(
|
|
112
|
+
/\B(?=(\d{3})+(?!\d))/g,
|
|
113
|
+
",",
|
|
114
|
+
);
|
|
109
115
|
|
|
110
116
|
return `${formattedIntegerPart}${decimalPart}`;
|
|
111
117
|
};
|
|
@@ -114,20 +120,19 @@ export const truncateToDecimalPlaces = (numStr, decimalPlaces = 18) => {
|
|
|
114
120
|
const match = numStr.match(/^(\d+)(\.(\d+))?$/);
|
|
115
121
|
if (match) {
|
|
116
122
|
const integerPart = match[1];
|
|
117
|
-
const decimalPart = match[3]?.slice(0, decimalPlaces) ||
|
|
123
|
+
const decimalPart = match[3]?.slice(0, decimalPlaces) || "";
|
|
118
124
|
return decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
|
|
119
125
|
}
|
|
120
126
|
return numStr;
|
|
121
127
|
};
|
|
122
128
|
|
|
123
|
-
export const formatAmountInput = (
|
|
124
|
-
valueStr,
|
|
125
|
-
decimals,
|
|
126
|
-
inputEl,
|
|
127
|
-
) => {
|
|
129
|
+
export const formatAmountInput = (valueStr, decimals, inputEl) => {
|
|
128
130
|
if (!/^[0-9]*[.]?[0-9]*$/.test(valueStr)) return null;
|
|
129
131
|
|
|
130
|
-
const formatted = truncateToDecimalPlaces(
|
|
132
|
+
const formatted = truncateToDecimalPlaces(
|
|
133
|
+
trimLeadingZeros(valueStr),
|
|
134
|
+
decimals,
|
|
135
|
+
);
|
|
131
136
|
|
|
132
137
|
if (inputEl && formatted !== valueStr) {
|
|
133
138
|
const oldPos = inputEl.selectionStart ?? 0;
|
|
@@ -152,4 +157,4 @@ export const minBigInt = (a, b, c) => {
|
|
|
152
157
|
return minOne < c ? minOne : c;
|
|
153
158
|
};
|
|
154
159
|
|
|
155
|
-
export const maxBigInt = (a, b) => (a > b ? a : b);
|
|
160
|
+
export const maxBigInt = (a, b) => (a > b ? a : b);
|
package/src/babyjubRN.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CIRCOM_P } from
|
|
2
|
-
import { mod, modInverse } from
|
|
1
|
+
import { CIRCOM_P } from "./protocol.constants.js";
|
|
2
|
+
import { mod, modInverse } from "./bigint-math.utils.js";
|
|
3
3
|
|
|
4
4
|
const P = CIRCOM_P;
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ const F = {
|
|
|
13
13
|
sub: (a, b) => mod(a - b),
|
|
14
14
|
mul: (a, b) => mod(a * b),
|
|
15
15
|
div: (a, b) => {
|
|
16
|
-
if (b === 0n) throw new Error(
|
|
16
|
+
if (b === 0n) throw new Error("Division by zero in BabyJub field");
|
|
17
17
|
return mod(a * modInverse(b));
|
|
18
18
|
},
|
|
19
19
|
toString: (a) => mod(a).toString(),
|
|
@@ -39,8 +39,8 @@ const toAffine = (point) => {
|
|
|
39
39
|
return [F.mul(point.X, zInv), F.mul(point.Y, zInv)];
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const A = F.e(
|
|
43
|
-
const D = F.e(
|
|
42
|
+
const A = F.e("168700");
|
|
43
|
+
const D = F.e("168696");
|
|
44
44
|
|
|
45
45
|
// Add two extended points (add-2008-hwcd; no per-step field inversions).
|
|
46
46
|
const addExtended = (p1, p2) => {
|
|
@@ -92,8 +92,12 @@ export class BabyJubRN {
|
|
|
92
92
|
|
|
93
93
|
// Standard BabyJub generator used by EdDSA (matches circomlibjs Base8).
|
|
94
94
|
Base8 = [
|
|
95
|
-
F.e(
|
|
96
|
-
|
|
95
|
+
F.e(
|
|
96
|
+
"5299619240641551281634865583518297030282874472190772894086521144482721001553",
|
|
97
|
+
),
|
|
98
|
+
F.e(
|
|
99
|
+
"16950150798460657717958625567821834550301663161624707787222815936182638968203",
|
|
100
|
+
),
|
|
97
101
|
];
|
|
98
102
|
|
|
99
103
|
// Add two affine curve points.
|
|
@@ -115,4 +119,4 @@ export class BabyJubRN {
|
|
|
115
119
|
|
|
116
120
|
return toAffine(res);
|
|
117
121
|
}
|
|
118
|
-
}
|
|
122
|
+
}
|
package/src/bigint-math.utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CIRCOM_P } from
|
|
1
|
+
import { CIRCOM_P } from "./protocol.constants.js";
|
|
2
2
|
|
|
3
3
|
// Reduce value into [0, m); handles negative inputs.
|
|
4
4
|
export const mod = (value, m = CIRCOM_P) => {
|
|
@@ -13,7 +13,7 @@ export const modInverse = (value, m = CIRCOM_P) => {
|
|
|
13
13
|
let low = mod(value, m);
|
|
14
14
|
let high = m;
|
|
15
15
|
|
|
16
|
-
if (low === 0n) throw new Error(
|
|
16
|
+
if (low === 0n) throw new Error("Division by zero");
|
|
17
17
|
|
|
18
18
|
while (low > 1n) {
|
|
19
19
|
const remainder = high % low;
|
|
@@ -26,4 +26,4 @@ export const modInverse = (value, m = CIRCOM_P) => {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
return lm < 0n ? lm + m : lm;
|
|
29
|
-
};
|
|
29
|
+
};
|
package/src/poseidonRN.js
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
import * as poseidonLite from
|
|
1
|
+
import * as poseidonLite from "poseidon-lite";
|
|
2
2
|
|
|
3
3
|
const toBigInt = (v) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
switch (typeof v) {
|
|
5
|
+
case "bigint":
|
|
6
|
+
return v;
|
|
7
|
+
case "boolean":
|
|
8
|
+
return v ? 1n : 0n;
|
|
9
|
+
case "number":
|
|
10
|
+
if (!Number.isInteger(v))
|
|
11
|
+
throw new TypeError(`Poseidon: non-integer Number ${v}`);
|
|
12
|
+
return BigInt(v);
|
|
13
|
+
case "string": {
|
|
14
|
+
try {
|
|
15
|
+
return BigInt(v.trim());
|
|
16
|
+
} catch {
|
|
17
|
+
throw new TypeError(
|
|
18
|
+
`Poseidon: cannot parse string "${v}" as an integer`,
|
|
19
|
+
);
|
|
13
20
|
}
|
|
14
|
-
default:
|
|
15
|
-
throw new TypeError(`Poseidon.F: unsupported value of type ${typeof v}`);
|
|
16
21
|
}
|
|
17
|
-
|
|
22
|
+
default:
|
|
23
|
+
throw new TypeError(`Poseidon.F: unsupported value of type ${typeof v}`);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
18
26
|
|
|
19
27
|
// poseidon-lite exposes `poseidon1`..`poseidon16`; wrap them in a `buildPoseidon`-shaped
|
|
20
28
|
// factory (matching the WASM reference) so callers — and the existing
|
|
@@ -22,12 +30,13 @@ const toBigInt = (v) => {
|
|
|
22
30
|
export const buildPoseidon = () => {
|
|
23
31
|
const poseidon = (inputs, initState = 0, nOut = 1) => {
|
|
24
32
|
const fn = poseidonLite[`poseidon${inputs.length}`];
|
|
25
|
-
if (!fn)
|
|
33
|
+
if (!fn)
|
|
34
|
+
throw new Error(`Poseidon: arity ${inputs.length} not supported (1..16)`);
|
|
26
35
|
const formattedInputs = inputs.map((v) => toBigInt(v));
|
|
27
36
|
|
|
28
37
|
if (nOut > 1) {
|
|
29
38
|
const results = fn(formattedInputs, nOut);
|
|
30
|
-
return results.map(v => BigInt(v));
|
|
39
|
+
return results.map((v) => BigInt(v));
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
const res = fn(formattedInputs);
|
|
@@ -39,4 +48,4 @@ export const buildPoseidon = () => {
|
|
|
39
48
|
eq: (a, b) => toBigInt(a) === toBigInt(b),
|
|
40
49
|
};
|
|
41
50
|
return poseidon;
|
|
42
|
-
};
|
|
51
|
+
};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export const CIRCOM_P =
|
|
1
|
+
export const CIRCOM_P =
|
|
2
|
+
21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
package/src/serialize.utils.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {((key: string, value: any) => any) | null} JsonReplacer
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
|
|
5
|
+
// Safe JSON.stringify wrapper. Converts BigInt -> string so JSON serialization never throws.
|
|
6
|
+
export const safeJsonStringify = (value, replacer = null, space) =>
|
|
7
|
+
JSON.stringify(
|
|
8
8
|
value,
|
|
9
9
|
(key, nestedValue) => {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const next =
|
|
11
|
+
typeof replacer === "function"
|
|
12
|
+
? replacer(key, nestedValue)
|
|
13
|
+
: nestedValue;
|
|
14
|
+
return typeof next === "bigint" ? next.toString() : next;
|
|
12
15
|
},
|
|
13
16
|
space,
|
|
14
|
-
|
|
17
|
+
);
|