@silvana-one/mina-utils 1.0.22 → 1.0.24
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/dist/node/commitment/commitment.d.ts +11 -0
- package/dist/node/commitment/commitment.js +72 -0
- package/dist/node/commitment/commitment.js.map +1 -0
- package/dist/node/commitment/constants.d.ts +11 -0
- package/dist/node/commitment/constants.js +3125 -0
- package/dist/node/commitment/constants.js.map +1 -0
- package/dist/node/commitment/exp.d.ts +5 -0
- package/dist/node/commitment/exp.js +106 -0
- package/dist/node/commitment/exp.js.map +1 -0
- package/dist/node/commitment/index.d.ts +5 -0
- package/dist/node/commitment/index.js +6 -0
- package/dist/node/commitment/index.js.map +1 -0
- package/dist/node/commitment/tree.d.ts +6 -0
- package/dist/node/commitment/tree.js +17 -0
- package/dist/node/commitment/tree.js.map +1 -0
- package/dist/node/commitment/witnesses.d.ts +6 -0
- package/dist/node/commitment/witnesses.js +3085 -0
- package/dist/node/commitment/witnesses.js.map +1 -0
- package/dist/node/index.cjs +12518 -2
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +1 -0
- package/dist/node/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.web.tsbuildinfo +1 -1
- package/dist/web/commitment/commitment.d.ts +11 -0
- package/dist/web/commitment/commitment.js +72 -0
- package/dist/web/commitment/commitment.js.map +1 -0
- package/dist/web/commitment/constants.d.ts +11 -0
- package/dist/web/commitment/constants.js +3125 -0
- package/dist/web/commitment/constants.js.map +1 -0
- package/dist/web/commitment/exp.d.ts +5 -0
- package/dist/web/commitment/exp.js +106 -0
- package/dist/web/commitment/exp.js.map +1 -0
- package/dist/web/commitment/index.d.ts +5 -0
- package/dist/web/commitment/index.js +6 -0
- package/dist/web/commitment/index.js.map +1 -0
- package/dist/web/commitment/tree.d.ts +6 -0
- package/dist/web/commitment/tree.js +17 -0
- package/dist/web/commitment/tree.js.map +1 -0
- package/dist/web/commitment/witnesses.d.ts +6 -0
- package/dist/web/commitment/witnesses.js +3085 -0
- package/dist/web/commitment/witnesses.js.map +1 -0
- package/dist/web/index.d.ts +1 -0
- package/dist/web/index.js +1 -0
- package/dist/web/index.js.map +1 -1
- package/package.json +5 -5
- package/src/commitment/README.md +3 -0
- package/src/commitment/commitment.ts +149 -0
- package/src/commitment/constants.ts +3135 -0
- package/src/commitment/exp.ts +139 -0
- package/src/commitment/index.ts +5 -0
- package/src/commitment/tree.ts +18 -0
- package/src/commitment/witnesses.ts +3088 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/// Optimized scalar exponentiation using lookup tables
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getR,
|
|
5
|
+
getTable0Entry,
|
|
6
|
+
getTable1Entry,
|
|
7
|
+
getTable2Entry,
|
|
8
|
+
} from "./constants.js";
|
|
9
|
+
import { UInt32, Field, Gadgets, Provable, assert } from "o1js";
|
|
10
|
+
import {
|
|
11
|
+
WITNESSES0,
|
|
12
|
+
WITNESSES1,
|
|
13
|
+
WITNESSES2,
|
|
14
|
+
TABLE0_ROOT,
|
|
15
|
+
TABLE1_ROOT,
|
|
16
|
+
TABLE2_ROOT,
|
|
17
|
+
} from "./witnesses.js";
|
|
18
|
+
import { Witness } from "./tree.js";
|
|
19
|
+
import { deserializeFields } from "../utils/index.js";
|
|
20
|
+
import { blsCommitment, CanonicalElement } from "./commitment.js";
|
|
21
|
+
import { Fr } from "./constants.js";
|
|
22
|
+
|
|
23
|
+
/// Optimized exponentiation using three 1024-element lookup tables
|
|
24
|
+
/// Computes R^exp using base-1024 decomposition:
|
|
25
|
+
/// exp = i0 + 1024*i1 + 1024^2*i2
|
|
26
|
+
/// R^exp = TABLE2[i2] * TABLE1[i1] * TABLE0[i0]
|
|
27
|
+
///
|
|
28
|
+
/// Time complexity: O(1) - constant time with 3 table lookups + 2 multiplications
|
|
29
|
+
/// Space complexity: 3 * 1024 * 32 bytes = 96 KiB for all tables
|
|
30
|
+
/// Range: supports exponents up to 1024^3 - 1 = 1,073,741,823
|
|
31
|
+
export function rScalarPow(exp: number | bigint): CanonicalElement {
|
|
32
|
+
const expNum = typeof exp === "bigint" ? Number(exp) : exp;
|
|
33
|
+
|
|
34
|
+
if (expNum < 0 || expNum >= 1024 ** 3) {
|
|
35
|
+
throw new Error(`Exponent out of range: ${expNum}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Decompose exponent in base-1024 (10 bits per component)
|
|
39
|
+
const i0 = expNum & 0x3ff; // exp mod 1024 (lowest 10 bits)
|
|
40
|
+
const i1 = (expNum >> 10) & 0x3ff; // next 10 bits
|
|
41
|
+
const i2 = (expNum >> 20) & 0x3ff; // highest 10 bits
|
|
42
|
+
|
|
43
|
+
// Constant-time table lookups
|
|
44
|
+
const t0 = getTable0Entry(i0);
|
|
45
|
+
const t1 = getTable1Entry(i1);
|
|
46
|
+
const t2 = getTable2Entry(i2);
|
|
47
|
+
|
|
48
|
+
// Combine results with 2 field multiplications
|
|
49
|
+
let result = t2.mul(t1).assertCanonical(); // R^(1024^2*i2 + 1024*i1)
|
|
50
|
+
result = result.mul(t0).assertCanonical(); // + i0
|
|
51
|
+
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// Provable version of scalar exponentiation for use in ZkPrograms
|
|
56
|
+
/// Uses o1js gadgets for bitwise operations instead of JavaScript operators
|
|
57
|
+
export function rScalarPowProvable(exp: UInt32): CanonicalElement {
|
|
58
|
+
// Range check to ensure exponent is within valid bounds
|
|
59
|
+
assert(
|
|
60
|
+
exp.lessThan(UInt32.from(1024 * 1024 * 1024)),
|
|
61
|
+
"Exponent out of range (non-provable check)"
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Decompose exponent in base-1024 using provable bitwise operations
|
|
65
|
+
// Each component is 10 bits, so we extract 3 components of 10 bits each
|
|
66
|
+
|
|
67
|
+
// Create bitmask for 10 bits (0x3FF = 1023)
|
|
68
|
+
const mask = Field(0x3ff);
|
|
69
|
+
|
|
70
|
+
// Extract components using provable bitwise operations
|
|
71
|
+
const i0 = Gadgets.and(exp.value, mask, 10); // exp & 0x3FF (lowest 10 bits)
|
|
72
|
+
const shifted10 = Gadgets.rightShift64(exp.value, 10); // exp >> 10
|
|
73
|
+
const i1 = Gadgets.and(shifted10, mask, 10); // (exp >> 10) & 0x3FF
|
|
74
|
+
const shifted20 = Gadgets.rightShift64(exp.value, 20); // exp >> 20
|
|
75
|
+
const i2 = Gadgets.and(shifted20, mask, 10); // (exp >> 20) & 0x3FF
|
|
76
|
+
|
|
77
|
+
// Convert Field indices to witness values for table lookups
|
|
78
|
+
// TODO: use lookup tables instead of witness to make code fully provable
|
|
79
|
+
// or add all TABLEX to Merkle tree and check the value in the tree
|
|
80
|
+
const t0 = Provable.witness(Fr.Canonical.provable, () => {
|
|
81
|
+
const idx = Number(i0.toBigInt());
|
|
82
|
+
return getTable0Entry(idx);
|
|
83
|
+
});
|
|
84
|
+
const witness0 = Provable.witness(Witness, () => {
|
|
85
|
+
const idx = Number(i0.toBigInt());
|
|
86
|
+
return Witness.fromFields(deserializeFields(WITNESSES0[idx]));
|
|
87
|
+
});
|
|
88
|
+
const root0 = Field(TABLE0_ROOT);
|
|
89
|
+
const witness0root = witness0.calculateRoot(blsCommitment(t0));
|
|
90
|
+
const witness0index = witness0.calculateIndex();
|
|
91
|
+
witness0root.assertEquals(root0, "Witness0 root should match root0");
|
|
92
|
+
witness0index.assertEquals(i0, "Witness0 index should match i0");
|
|
93
|
+
|
|
94
|
+
const t1 = Provable.witness(Fr.Canonical.provable, () => {
|
|
95
|
+
const idx = Number(i1.toBigInt());
|
|
96
|
+
return getTable1Entry(idx);
|
|
97
|
+
});
|
|
98
|
+
const witness1 = Provable.witness(Witness, () => {
|
|
99
|
+
const idx = Number(i1.toBigInt());
|
|
100
|
+
return Witness.fromFields(deserializeFields(WITNESSES1[idx]));
|
|
101
|
+
});
|
|
102
|
+
const root1 = Field(TABLE1_ROOT);
|
|
103
|
+
const witness1root = witness1.calculateRoot(blsCommitment(t1));
|
|
104
|
+
const witness1index = witness1.calculateIndex();
|
|
105
|
+
witness1root.assertEquals(root1, "Witness1 root should match root1");
|
|
106
|
+
witness1index.assertEquals(i1, "Witness1 index should match i1");
|
|
107
|
+
|
|
108
|
+
const t2 = Provable.witness(Fr.Canonical.provable, () => {
|
|
109
|
+
const idx = Number(i2.toBigInt());
|
|
110
|
+
return getTable2Entry(idx);
|
|
111
|
+
});
|
|
112
|
+
const witness2 = Provable.witness(Witness, () => {
|
|
113
|
+
const idx = Number(i2.toBigInt());
|
|
114
|
+
return Witness.fromFields(deserializeFields(WITNESSES2[idx]));
|
|
115
|
+
});
|
|
116
|
+
const root2 = Field(TABLE2_ROOT);
|
|
117
|
+
const witness2root = witness2.calculateRoot(blsCommitment(t2));
|
|
118
|
+
const witness2index = witness2.calculateIndex();
|
|
119
|
+
witness2root.assertEquals(root2, "Witness2 root should match root2");
|
|
120
|
+
witness2index.assertEquals(i2, "Witness2 index should match i2");
|
|
121
|
+
|
|
122
|
+
// Combine results with 2 field multiplications
|
|
123
|
+
let result = t2.mul(t1).assertCanonical(); // R^(1024^2*i2 + 1024*i1)
|
|
124
|
+
result = result.mul(t0).assertCanonical(); // + i0
|
|
125
|
+
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/// Legacy function (inefficient, use rScalarPow instead)
|
|
130
|
+
export function rScalarPowLegacy(exp: number): CanonicalElement {
|
|
131
|
+
let acc = Fr.from(1n); // Start with 1
|
|
132
|
+
const r = getR(); // Get R when needed, not at startup
|
|
133
|
+
|
|
134
|
+
for (let i = 0; i < exp; i++) {
|
|
135
|
+
acc = acc.mul(r).assertCanonical();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return acc;
|
|
139
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MerkleTree, MerkleWitness, assert } from "o1js";
|
|
2
|
+
import { Fr } from "./constants.js";
|
|
3
|
+
import { blsCommitment } from "./commitment.js";
|
|
4
|
+
|
|
5
|
+
const TREE_DEPTH = 11;
|
|
6
|
+
const TABLE_SIZE = 1024;
|
|
7
|
+
export class Witness extends MerkleWitness(TREE_DEPTH) {}
|
|
8
|
+
|
|
9
|
+
export function createMerkleTree(table: bigint[]) {
|
|
10
|
+
assert(table.length === TABLE_SIZE, "Table size must be 1024");
|
|
11
|
+
const tree = new MerkleTree(TREE_DEPTH);
|
|
12
|
+
assert(tree.leafCount === BigInt(TABLE_SIZE), "Tree size must be 1024");
|
|
13
|
+
|
|
14
|
+
for (let i = 0; i < TABLE_SIZE; i++) {
|
|
15
|
+
tree.setLeaf(BigInt(i), blsCommitment(Fr.from(table[i])));
|
|
16
|
+
}
|
|
17
|
+
return tree;
|
|
18
|
+
}
|