@aztec/ivc-integration 3.0.3 → 3.9.9-nightly.20260312
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/artifacts/app_creator.json +99 -104
- package/artifacts/app_reader.json +99 -104
- package/artifacts/keys/mock_rollup_root_verifier.sol +379 -361
- package/artifacts/mock_hiding.json +100 -105
- package/artifacts/mock_private_kernel_init.json +101 -106
- package/artifacts/mock_private_kernel_inner.json +101 -106
- package/artifacts/mock_private_kernel_reset.json +107 -107
- package/artifacts/mock_private_kernel_tail.json +101 -106
- package/artifacts/mock_rollup_root.json +58 -63
- package/artifacts/mock_rollup_tx_base_private.json +106 -111
- package/artifacts/mock_rollup_tx_base_public.json +107 -112
- package/artifacts/mock_rollup_tx_merge.json +106 -111
- package/dest/prove_native.d.ts +4 -6
- package/dest/prove_native.d.ts.map +1 -1
- package/dest/prove_native.js +4 -24
- package/dest/types/index.d.ts +4 -4
- package/package.json +19 -19
- package/src/prove_native.ts +1 -28
- package/src/types/index.ts +4 -4
- package/artifacts/keys/mock_hiding.ivc.vk +0 -0
|
@@ -4,85 +4,85 @@ pragma solidity >=0.8.21;
|
|
|
4
4
|
|
|
5
5
|
uint256 constant N = 16777216;
|
|
6
6
|
uint256 constant LOG_N = 24;
|
|
7
|
-
uint256 constant NUMBER_OF_PUBLIC_INPUTS =
|
|
8
|
-
uint256 constant VK_HASH =
|
|
7
|
+
uint256 constant NUMBER_OF_PUBLIC_INPUTS = 9;
|
|
8
|
+
uint256 constant VK_HASH = 0x1a71c9c8e8d1fc37789326bbf84db5728e523d1663d64a3ee4d907db31280798;
|
|
9
9
|
library HonkVerificationKey {
|
|
10
10
|
function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {
|
|
11
11
|
Honk.VerificationKey memory vk = Honk.VerificationKey({
|
|
12
12
|
circuitSize: uint256(16777216),
|
|
13
13
|
logCircuitSize: uint256(24),
|
|
14
|
-
publicInputsSize: uint256(
|
|
14
|
+
publicInputsSize: uint256(9),
|
|
15
15
|
ql: Honk.G1Point({
|
|
16
|
-
x: uint256(
|
|
17
|
-
y: uint256(
|
|
16
|
+
x: uint256(0x288949ddd65c505eb5cc75f154e5758f88ffca8d2b27ecec1a8c18d64836555e),
|
|
17
|
+
y: uint256(0x16bdc5f6b2acfec698224a75fb369f408f10203d39d18c59f1e7fd2a06cd203e)
|
|
18
18
|
}),
|
|
19
19
|
qr: Honk.G1Point({
|
|
20
|
-
x: uint256(
|
|
21
|
-
y: uint256(
|
|
20
|
+
x: uint256(0x0f00e9b07cdc3cb5ec6c7f0c3f015d52b77d22309cb6ce0231a4969c4ac47488),
|
|
21
|
+
y: uint256(0x173daa0ad01139b438315c03c09114c7054ed90ff4562466afb6e2cc48d69eae)
|
|
22
22
|
}),
|
|
23
23
|
qo: Honk.G1Point({
|
|
24
|
-
x: uint256(
|
|
25
|
-
y: uint256(
|
|
24
|
+
x: uint256(0x2158a434ef091cbe48d362fda5c78de82eaaac1227a0c411ea21ad7c7d09bb89),
|
|
25
|
+
y: uint256(0x11e9f2ece557a9ab50b059decabaa2c3e102080b7389aa51335094c527a4399b)
|
|
26
26
|
}),
|
|
27
27
|
q4: Honk.G1Point({
|
|
28
|
-
x: uint256(
|
|
29
|
-
y: uint256(
|
|
28
|
+
x: uint256(0x0b4c24c473fadd17b6fc761b52fc51cabd6dfb6b93a889128f7d5443d76b4e37),
|
|
29
|
+
y: uint256(0x2bcbb260096016d41e7b099758e6c7a4b2487a30728fa877f64163da404d2aa6)
|
|
30
30
|
}),
|
|
31
31
|
qm: Honk.G1Point({
|
|
32
|
-
x: uint256(
|
|
33
|
-
y: uint256(
|
|
32
|
+
x: uint256(0x305785ae74b36fc97f5cfbfcd19e965f14c3cb5fc07a866b4da8c40dfa43ea09),
|
|
33
|
+
y: uint256(0x1c618b8fb74db18bb65237cd45de3060ae7abd8931f5d6fbc0a3d18019f9a34c)
|
|
34
34
|
}),
|
|
35
35
|
qc: Honk.G1Point({
|
|
36
|
-
x: uint256(
|
|
37
|
-
y: uint256(
|
|
36
|
+
x: uint256(0x1e7d370a010cbec0e4a7a5be0832a59a0ed151216aa2ef780e40945770f04256),
|
|
37
|
+
y: uint256(0x19645746fcec15c93f0b8f620fbaf63b2d973d174b52ac8dc006b0292bc4d75a)
|
|
38
38
|
}),
|
|
39
39
|
qLookup: Honk.G1Point({
|
|
40
|
-
x: uint256(
|
|
41
|
-
y: uint256(
|
|
40
|
+
x: uint256(0x22011c91613251ef53fd12a397e4bd6165b1ed309dcd94b33ac4226d34b68889),
|
|
41
|
+
y: uint256(0x1fb02875a3542a3a6f4426ad912b70cf32b444a8e439701da6e8e7b30029cfc7)
|
|
42
42
|
}),
|
|
43
43
|
qArith: Honk.G1Point({
|
|
44
|
-
x: uint256(
|
|
45
|
-
y: uint256(
|
|
44
|
+
x: uint256(0x1d87e7db98f2289def77fcd6917b3195a04c8ea4fba2fbecb4953d53e2a5fa5e),
|
|
45
|
+
y: uint256(0x1e747aa5ce9c23534fba30d6fb86e148f55ff741cdc40aa72669b48fae5e78da)
|
|
46
46
|
}),
|
|
47
47
|
qDeltaRange: Honk.G1Point({
|
|
48
|
-
x: uint256(
|
|
49
|
-
y: uint256(
|
|
48
|
+
x: uint256(0x197382111c5e19efd384fad7b441ab910eea06a90e613c0ac1d3558d5d1fe9bb),
|
|
49
|
+
y: uint256(0x2409d8e704a1df2a931db78f4b9eff415259f325e2c1d91752018ca1367bc813)
|
|
50
50
|
}),
|
|
51
51
|
qElliptic: Honk.G1Point({
|
|
52
|
-
x: uint256(
|
|
53
|
-
y: uint256(
|
|
52
|
+
x: uint256(0x2f7bf7a96beccc2dcb1c979e895a5cf553347e85d3f09ac4ad25968c48ee6c0f),
|
|
53
|
+
y: uint256(0x0b9eb2604a17d6ee22545ecefc418886ee29c45e1f367a73781af51b70b5e59a)
|
|
54
54
|
}),
|
|
55
55
|
qMemory: Honk.G1Point({
|
|
56
|
-
x: uint256(
|
|
57
|
-
y: uint256(
|
|
56
|
+
x: uint256(0x067081ee7301cf94893b575b8a4607a50631612578b3230b0f63434e6ec1dcf3),
|
|
57
|
+
y: uint256(0x12e2288cdb86fd9caa98689e3ad9926b0372d1e7afeeb1ec6f7b251a176eb3e1)
|
|
58
58
|
}),
|
|
59
59
|
qNnf: Honk.G1Point({
|
|
60
|
-
x: uint256(
|
|
61
|
-
y: uint256(
|
|
60
|
+
x: uint256(0x303e26adafa2a01b02f559580ab06f571fe0f80473552ea7f4a47255af7b25f3),
|
|
61
|
+
y: uint256(0x2f599def60b1f4640366dba9daaf25de7a311eed3243dd96004ef5cb76dd4eef)
|
|
62
62
|
}),
|
|
63
63
|
qPoseidon2External: Honk.G1Point({
|
|
64
|
-
x: uint256(
|
|
65
|
-
y: uint256(
|
|
64
|
+
x: uint256(0x26c42fb5290e1f109c68ae1aadb78005efbe391925d37ff2682eb2fb9f673d81),
|
|
65
|
+
y: uint256(0x23d32838bb651192c72a84f8d35ad9ed23bfc60bd6a95aafe5f400ac79bb91a6)
|
|
66
66
|
}),
|
|
67
67
|
qPoseidon2Internal: Honk.G1Point({
|
|
68
|
-
x: uint256(
|
|
69
|
-
y: uint256(
|
|
68
|
+
x: uint256(0x0e257562358c0fa333e2e92fb24893b10b6606582657ac902463c4125a8d76b4),
|
|
69
|
+
y: uint256(0x0a45aedd100c830266aa7501650f16d4c1a340da32528e2dc0ffcfe01de89c65)
|
|
70
70
|
}),
|
|
71
71
|
s1: Honk.G1Point({
|
|
72
|
-
x: uint256(
|
|
73
|
-
y: uint256(
|
|
72
|
+
x: uint256(0x157c4a46714f7cc4bd0065ac8726ead6d925e1c3e2cb03ec167bde135d933eeb),
|
|
73
|
+
y: uint256(0x191e130de881a7b6a3560a6dc7f8f517abcc324c5f16b8e4dc901d5079ec7387)
|
|
74
74
|
}),
|
|
75
75
|
s2: Honk.G1Point({
|
|
76
|
-
x: uint256(
|
|
77
|
-
y: uint256(
|
|
76
|
+
x: uint256(0x0d02a27696ba0a08b32422113dc489b15acc111cb2fcd7f674ef4b903adcbdb3),
|
|
77
|
+
y: uint256(0x03499c1fd603f04963deab2fdbb152e7d8f88267d6ca8c817eea2643e608de29)
|
|
78
78
|
}),
|
|
79
79
|
s3: Honk.G1Point({
|
|
80
|
-
x: uint256(
|
|
81
|
-
y: uint256(
|
|
80
|
+
x: uint256(0x19c00dd88d170187c1717dfa303fe1c20604decf14cc58c4d6fe9ab346ae3f67),
|
|
81
|
+
y: uint256(0x0e3991d6fd47060ba758b4ed58736ffd3f082af15af7b84fafe5041b568dcff2)
|
|
82
82
|
}),
|
|
83
83
|
s4: Honk.G1Point({
|
|
84
|
-
x: uint256(
|
|
85
|
-
y: uint256(
|
|
84
|
+
x: uint256(0x2ddedcc10b1b78151f4638978bc1ed9ceafa34911d7c8a2ffcdecc092f5f53bd),
|
|
85
|
+
y: uint256(0x2fee038cad71230c95a0497bd2a116171a431193a214d5a9677570fa45de2fda)
|
|
86
86
|
}),
|
|
87
87
|
t1: Honk.G1Point({
|
|
88
88
|
x: uint256(0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26),
|
|
@@ -93,36 +93,36 @@ library HonkVerificationKey {
|
|
|
93
93
|
y: uint256(0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19)
|
|
94
94
|
}),
|
|
95
95
|
t3: Honk.G1Point({
|
|
96
|
-
x: uint256(
|
|
97
|
-
y: uint256(
|
|
96
|
+
x: uint256(0x16465a5ccbb550cd2c63bd58116fe47c86847618681dc29d8a9363ab7c40e1c3),
|
|
97
|
+
y: uint256(0x2e24d420fbf9508ed31de692db477b439973ac12d7ca796d6fe98ca40e6ca6b7)
|
|
98
98
|
}),
|
|
99
99
|
t4: Honk.G1Point({
|
|
100
100
|
x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce),
|
|
101
101
|
y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854)
|
|
102
102
|
}),
|
|
103
103
|
id1: Honk.G1Point({
|
|
104
|
-
x: uint256(
|
|
105
|
-
y: uint256(
|
|
104
|
+
x: uint256(0x11a02b4dd65f30c8d3b70888267f766e6abaaa0a1a5ad0bfa8cb1b597fedc630),
|
|
105
|
+
y: uint256(0x195cb3d252708ee60a385f0a3a84167322910971be20715e2965a4d97c1d1084)
|
|
106
106
|
}),
|
|
107
107
|
id2: Honk.G1Point({
|
|
108
|
-
x: uint256(
|
|
109
|
-
y: uint256(
|
|
108
|
+
x: uint256(0x2a775e6191621460b6ae8f22d1cef5f92ec91bf820478d9619fc74d4e2956801),
|
|
109
|
+
y: uint256(0x057c47f7fa5fdfe685bd62595390454071e5749841dbabb0bcd45aee00ac9af7)
|
|
110
110
|
}),
|
|
111
111
|
id3: Honk.G1Point({
|
|
112
|
-
x: uint256(
|
|
113
|
-
y: uint256(
|
|
112
|
+
x: uint256(0x2ae753680356fd3211ca6b4210fe2682ebacc40d78c1ac3319be365682860bbd),
|
|
113
|
+
y: uint256(0x18aa3b045ae71c20a8b673b91ccf5ea61ba25bff9c958f9bad138e7e126a257a)
|
|
114
114
|
}),
|
|
115
115
|
id4: Honk.G1Point({
|
|
116
|
-
x: uint256(
|
|
117
|
-
y: uint256(
|
|
116
|
+
x: uint256(0x2e12e92c2de2ec043befd1cb502a2e48458c7ea1dc19243640df4f6ec699b0be),
|
|
117
|
+
y: uint256(0x12655a8e9a32a038c570a5c83aa5dabe77df900b5c78bab8a64a252de136cdfc)
|
|
118
118
|
}),
|
|
119
119
|
lagrangeFirst: Honk.G1Point({
|
|
120
120
|
x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),
|
|
121
121
|
y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)
|
|
122
122
|
}),
|
|
123
123
|
lagrangeLast: Honk.G1Point({
|
|
124
|
-
x: uint256(
|
|
125
|
-
y: uint256(
|
|
124
|
+
x: uint256(0x04a0bdd0751a2184a98670fd8df17f372fac62b55691c8232c1484f51282cd7e),
|
|
125
|
+
y: uint256(0x121349b0521c633e5b12c42ec4f8cb0c1a3bdadcafe6350d901ae7cf13e7b5bd)
|
|
126
126
|
})
|
|
127
127
|
});
|
|
128
128
|
return vk;
|
|
@@ -132,7 +132,32 @@ library HonkVerificationKey {
|
|
|
132
132
|
pragma solidity ^0.8.27;
|
|
133
133
|
|
|
134
134
|
interface IVerifier {
|
|
135
|
-
function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);
|
|
135
|
+
function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @notice Library of error codes
|
|
140
|
+
* @dev You can run `forge inspect Errors errors` to get the selectors for the optimised verifier
|
|
141
|
+
*/
|
|
142
|
+
library Errors {
|
|
143
|
+
error ValueGeLimbMax();
|
|
144
|
+
error ValueGeGroupOrder();
|
|
145
|
+
error ValueGeFieldOrder();
|
|
146
|
+
|
|
147
|
+
error InvertOfZero();
|
|
148
|
+
error NotPowerOfTwo();
|
|
149
|
+
error ModExpFailed();
|
|
150
|
+
|
|
151
|
+
error ProofLengthWrong();
|
|
152
|
+
error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);
|
|
153
|
+
error PublicInputsLengthWrong();
|
|
154
|
+
error SumcheckFailed();
|
|
155
|
+
error ShpleminiFailed();
|
|
156
|
+
|
|
157
|
+
error PointAtInfinity();
|
|
158
|
+
|
|
159
|
+
error ConsistencyCheckFailed();
|
|
160
|
+
error GeminiChallengeInSubgroup();
|
|
136
161
|
}
|
|
137
162
|
|
|
138
163
|
type Fr is uint256;
|
|
@@ -141,7 +166,6 @@ using {add as +} for Fr global;
|
|
|
141
166
|
using {sub as -} for Fr global;
|
|
142
167
|
using {mul as *} for Fr global;
|
|
143
168
|
|
|
144
|
-
using {exp as ^} for Fr global;
|
|
145
169
|
using {notEqual as !=} for Fr global;
|
|
146
170
|
using {equal as ==} for Fr global;
|
|
147
171
|
|
|
@@ -156,26 +180,12 @@ Fr constant ZERO = Fr.wrap(0);
|
|
|
156
180
|
// Instantiation
|
|
157
181
|
|
|
158
182
|
library FrLib {
|
|
159
|
-
|
|
160
|
-
unchecked {
|
|
161
|
-
return Fr.wrap(value % MODULUS);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function fromBytes32(bytes32 value) internal pure returns (Fr) {
|
|
166
|
-
unchecked {
|
|
167
|
-
return Fr.wrap(uint256(value) % MODULUS);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function toBytes32(Fr value) internal pure returns (bytes32) {
|
|
172
|
-
unchecked {
|
|
173
|
-
return bytes32(Fr.unwrap(value));
|
|
174
|
-
}
|
|
175
|
-
}
|
|
183
|
+
bytes4 internal constant FRLIB_MODEXP_FAILED_SELECTOR = 0xf8d61709;
|
|
176
184
|
|
|
177
185
|
function invert(Fr value) internal view returns (Fr) {
|
|
178
186
|
uint256 v = Fr.unwrap(value);
|
|
187
|
+
require(v != 0, Errors.InvertOfZero());
|
|
188
|
+
|
|
179
189
|
uint256 result;
|
|
180
190
|
|
|
181
191
|
// Call the modexp precompile to invert in the field
|
|
@@ -185,14 +195,15 @@ library FrLib {
|
|
|
185
195
|
mstore(add(free, 0x20), 0x20)
|
|
186
196
|
mstore(add(free, 0x40), 0x20)
|
|
187
197
|
mstore(add(free, 0x60), v)
|
|
188
|
-
mstore(add(free, 0x80), sub(MODULUS, 2))
|
|
198
|
+
mstore(add(free, 0x80), sub(MODULUS, 2))
|
|
189
199
|
mstore(add(free, 0xa0), MODULUS)
|
|
190
200
|
let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)
|
|
191
201
|
if iszero(success) {
|
|
192
|
-
|
|
202
|
+
mstore(0x00, FRLIB_MODEXP_FAILED_SELECTOR)
|
|
203
|
+
revert(0, 0x04)
|
|
193
204
|
}
|
|
194
205
|
result := mload(0x00)
|
|
195
|
-
mstore(0x40, add(free,
|
|
206
|
+
mstore(0x40, add(free, 0xc0))
|
|
196
207
|
}
|
|
197
208
|
|
|
198
209
|
return Fr.wrap(result);
|
|
@@ -200,6 +211,8 @@ library FrLib {
|
|
|
200
211
|
|
|
201
212
|
function pow(Fr base, uint256 v) internal view returns (Fr) {
|
|
202
213
|
uint256 b = Fr.unwrap(base);
|
|
214
|
+
// Only works for power of 2
|
|
215
|
+
require(v > 0 && (v & (v - 1)) == 0, Errors.NotPowerOfTwo());
|
|
203
216
|
uint256 result;
|
|
204
217
|
|
|
205
218
|
// Call the modexp precompile to invert in the field
|
|
@@ -209,14 +222,15 @@ library FrLib {
|
|
|
209
222
|
mstore(add(free, 0x20), 0x20)
|
|
210
223
|
mstore(add(free, 0x40), 0x20)
|
|
211
224
|
mstore(add(free, 0x60), b)
|
|
212
|
-
mstore(add(free, 0x80), v)
|
|
225
|
+
mstore(add(free, 0x80), v)
|
|
213
226
|
mstore(add(free, 0xa0), MODULUS)
|
|
214
227
|
let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)
|
|
215
228
|
if iszero(success) {
|
|
216
|
-
|
|
229
|
+
mstore(0x00, FRLIB_MODEXP_FAILED_SELECTOR)
|
|
230
|
+
revert(0, 0x04)
|
|
217
231
|
}
|
|
218
232
|
result := mload(0x00)
|
|
219
|
-
mstore(0x40, add(free,
|
|
233
|
+
mstore(0x40, add(free, 0xc0))
|
|
220
234
|
}
|
|
221
235
|
|
|
222
236
|
return Fr.wrap(result);
|
|
@@ -245,6 +259,27 @@ library FrLib {
|
|
|
245
259
|
return Fr.wrap(MODULUS - Fr.unwrap(value));
|
|
246
260
|
}
|
|
247
261
|
}
|
|
262
|
+
|
|
263
|
+
function from(uint256 value) internal pure returns (Fr) {
|
|
264
|
+
unchecked {
|
|
265
|
+
require(value < MODULUS, Errors.ValueGeFieldOrder());
|
|
266
|
+
return Fr.wrap(value);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function fromBytes32(bytes32 value) internal pure returns (Fr) {
|
|
271
|
+
unchecked {
|
|
272
|
+
uint256 v = uint256(value);
|
|
273
|
+
require(v < MODULUS, Errors.ValueGeFieldOrder());
|
|
274
|
+
return Fr.wrap(v);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function toBytes32(Fr value) internal pure returns (bytes32) {
|
|
279
|
+
unchecked {
|
|
280
|
+
return bytes32(Fr.unwrap(value));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
248
283
|
}
|
|
249
284
|
|
|
250
285
|
// Free functions
|
|
@@ -266,15 +301,6 @@ function sub(Fr a, Fr b) pure returns (Fr) {
|
|
|
266
301
|
}
|
|
267
302
|
}
|
|
268
303
|
|
|
269
|
-
function exp(Fr base, Fr exponent) pure returns (Fr) {
|
|
270
|
-
if (Fr.unwrap(exponent) == 0) return Fr.wrap(1);
|
|
271
|
-
// Implement exponent with a loop as we will overflow otherwise
|
|
272
|
-
for (uint256 i = 1; i < Fr.unwrap(exponent); i += i) {
|
|
273
|
-
base = base * base;
|
|
274
|
-
}
|
|
275
|
-
return base;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
304
|
function notEqual(Fr a, Fr b) pure returns (bool) {
|
|
279
305
|
unchecked {
|
|
280
306
|
return Fr.unwrap(a) != Fr.unwrap(b);
|
|
@@ -299,7 +325,7 @@ uint256 constant NUMBER_OF_ENTITIES_ZK = NUMBER_OF_ENTITIES + NUM_MASKING_POLYNO
|
|
|
299
325
|
uint256 constant NUMBER_UNSHIFTED = 36;
|
|
300
326
|
uint256 constant NUMBER_UNSHIFTED_ZK = NUMBER_UNSHIFTED + NUM_MASKING_POLYNOMIALS;
|
|
301
327
|
uint256 constant NUMBER_TO_BE_SHIFTED = 5;
|
|
302
|
-
uint256 constant PAIRING_POINTS_SIZE =
|
|
328
|
+
uint256 constant PAIRING_POINTS_SIZE = 8;
|
|
303
329
|
|
|
304
330
|
uint256 constant FIELD_ELEMENT_SIZE = 0x20;
|
|
305
331
|
uint256 constant GROUP_ELEMENT_SIZE = 0x40;
|
|
@@ -401,8 +427,6 @@ library Honk {
|
|
|
401
427
|
struct RelationParameters {
|
|
402
428
|
// challenges
|
|
403
429
|
Fr eta;
|
|
404
|
-
Fr etaTwo;
|
|
405
|
-
Fr etaThree;
|
|
406
430
|
Fr beta;
|
|
407
431
|
Fr gamma;
|
|
408
432
|
// derived
|
|
@@ -488,7 +512,7 @@ library TranscriptLib {
|
|
|
488
512
|
uint256 vkHash,
|
|
489
513
|
uint256 publicInputsSize,
|
|
490
514
|
uint256 logN
|
|
491
|
-
) internal
|
|
515
|
+
) internal pure returns (Transcript memory t) {
|
|
492
516
|
Fr previousChallenge;
|
|
493
517
|
(t.relationParameters, previousChallenge) =
|
|
494
518
|
generateRelationParametersChallenges(proof, publicInputs, vkHash, publicInputsSize, previousChallenge);
|
|
@@ -515,8 +539,8 @@ library TranscriptLib {
|
|
|
515
539
|
// Split into two equal 127-bit chunks (254/2)
|
|
516
540
|
uint256 lo = challengeU256 & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // 127 bits
|
|
517
541
|
uint256 hi = challengeU256 >> 127;
|
|
518
|
-
first = FrLib.
|
|
519
|
-
second = FrLib.
|
|
542
|
+
first = FrLib.from(lo);
|
|
543
|
+
second = FrLib.from(hi);
|
|
520
544
|
}
|
|
521
545
|
|
|
522
546
|
function generateRelationParametersChallenges(
|
|
@@ -526,10 +550,9 @@ library TranscriptLib {
|
|
|
526
550
|
uint256 publicInputsSize,
|
|
527
551
|
Fr previousChallenge
|
|
528
552
|
) internal pure returns (Honk.RelationParameters memory rp, Fr nextPreviousChallenge) {
|
|
529
|
-
(rp.eta,
|
|
530
|
-
generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);
|
|
553
|
+
(rp.eta, previousChallenge) = generateEtaChallenge(proof, publicInputs, vkHash, publicInputsSize);
|
|
531
554
|
|
|
532
|
-
(rp.beta, rp.gamma, nextPreviousChallenge) =
|
|
555
|
+
(rp.beta, rp.gamma, nextPreviousChallenge) = generateBetaGammaChallenges(previousChallenge, proof);
|
|
533
556
|
}
|
|
534
557
|
|
|
535
558
|
function generateEtaChallenge(
|
|
@@ -537,12 +560,13 @@ library TranscriptLib {
|
|
|
537
560
|
bytes32[] calldata publicInputs,
|
|
538
561
|
uint256 vkHash,
|
|
539
562
|
uint256 publicInputsSize
|
|
540
|
-
) internal pure returns (Fr eta, Fr
|
|
563
|
+
) internal pure returns (Fr eta, Fr previousChallenge) {
|
|
541
564
|
bytes32[] memory round0 = new bytes32[](1 + publicInputsSize + 6);
|
|
542
565
|
round0[0] = bytes32(vkHash);
|
|
543
566
|
|
|
544
567
|
for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {
|
|
545
|
-
|
|
568
|
+
require(uint256(publicInputs[i]) < P, Errors.ValueGeFieldOrder());
|
|
569
|
+
round0[1 + i] = publicInputs[i];
|
|
546
570
|
}
|
|
547
571
|
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
548
572
|
round0[1 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);
|
|
@@ -557,15 +581,11 @@ library TranscriptLib {
|
|
|
557
581
|
round0[1 + publicInputsSize + 4] = bytes32(proof.w3.x);
|
|
558
582
|
round0[1 + publicInputsSize + 5] = bytes32(proof.w3.y);
|
|
559
583
|
|
|
560
|
-
previousChallenge = FrLib.
|
|
561
|
-
(eta,
|
|
562
|
-
|
|
563
|
-
previousChallenge = FrLib.fromBytes32(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge))));
|
|
564
|
-
Fr unused;
|
|
565
|
-
(etaThree, unused) = splitChallenge(previousChallenge);
|
|
584
|
+
previousChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(round0))) % P);
|
|
585
|
+
(eta,) = splitChallenge(previousChallenge);
|
|
566
586
|
}
|
|
567
587
|
|
|
568
|
-
function
|
|
588
|
+
function generateBetaGammaChallenges(Fr previousChallenge, Honk.Proof memory proof)
|
|
569
589
|
internal
|
|
570
590
|
pure
|
|
571
591
|
returns (Fr beta, Fr gamma, Fr nextPreviousChallenge)
|
|
@@ -579,7 +599,7 @@ library TranscriptLib {
|
|
|
579
599
|
round1[5] = bytes32(proof.w4.x);
|
|
580
600
|
round1[6] = bytes32(proof.w4.y);
|
|
581
601
|
|
|
582
|
-
nextPreviousChallenge = FrLib.
|
|
602
|
+
nextPreviousChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(round1))) % P);
|
|
583
603
|
(beta, gamma) = splitChallenge(nextPreviousChallenge);
|
|
584
604
|
}
|
|
585
605
|
|
|
@@ -597,7 +617,7 @@ library TranscriptLib {
|
|
|
597
617
|
alpha0[3] = proof.zPerm.x;
|
|
598
618
|
alpha0[4] = proof.zPerm.y;
|
|
599
619
|
|
|
600
|
-
nextPreviousChallenge = FrLib.
|
|
620
|
+
nextPreviousChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(alpha0))) % P);
|
|
601
621
|
Fr alpha;
|
|
602
622
|
(alpha,) = splitChallenge(nextPreviousChallenge);
|
|
603
623
|
|
|
@@ -613,7 +633,7 @@ library TranscriptLib {
|
|
|
613
633
|
pure
|
|
614
634
|
returns (Fr[CONST_PROOF_SIZE_LOG_N] memory gateChallenges, Fr nextPreviousChallenge)
|
|
615
635
|
{
|
|
616
|
-
previousChallenge = FrLib.
|
|
636
|
+
previousChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(Fr.unwrap(previousChallenge)))) % P);
|
|
617
637
|
(gateChallenges[0],) = splitChallenge(previousChallenge);
|
|
618
638
|
for (uint256 i = 1; i < logN; i++) {
|
|
619
639
|
gateChallenges[i] = gateChallenges[i - 1] * gateChallenges[i - 1];
|
|
@@ -633,7 +653,7 @@ library TranscriptLib {
|
|
|
633
653
|
for (uint256 j = 0; j < BATCHED_RELATION_PARTIAL_LENGTH; j++) {
|
|
634
654
|
univariateChal[j + 1] = proof.sumcheckUnivariates[i][j];
|
|
635
655
|
}
|
|
636
|
-
prevChallenge = FrLib.
|
|
656
|
+
prevChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(univariateChal))) % P);
|
|
637
657
|
Fr unused;
|
|
638
658
|
(sumcheckChallenges[i], unused) = splitChallenge(prevChallenge);
|
|
639
659
|
}
|
|
@@ -652,7 +672,7 @@ library TranscriptLib {
|
|
|
652
672
|
rhoChallengeElements[i + 1] = proof.sumcheckEvaluations[i];
|
|
653
673
|
}
|
|
654
674
|
|
|
655
|
-
nextPreviousChallenge = FrLib.
|
|
675
|
+
nextPreviousChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(rhoChallengeElements))) % P);
|
|
656
676
|
Fr unused;
|
|
657
677
|
(rho, unused) = splitChallenge(nextPreviousChallenge);
|
|
658
678
|
}
|
|
@@ -670,7 +690,7 @@ library TranscriptLib {
|
|
|
670
690
|
gR[2 + i * 2] = proof.geminiFoldComms[i].y;
|
|
671
691
|
}
|
|
672
692
|
|
|
673
|
-
nextPreviousChallenge = FrLib.
|
|
693
|
+
nextPreviousChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(gR))) % P);
|
|
674
694
|
Fr unused;
|
|
675
695
|
(geminiR, unused) = splitChallenge(nextPreviousChallenge);
|
|
676
696
|
}
|
|
@@ -687,14 +707,14 @@ library TranscriptLib {
|
|
|
687
707
|
shplonkNuChallengeElements[i + 1] = Fr.unwrap(proof.geminiAEvaluations[i]);
|
|
688
708
|
}
|
|
689
709
|
|
|
690
|
-
nextPreviousChallenge = FrLib.
|
|
710
|
+
nextPreviousChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(shplonkNuChallengeElements))) % P);
|
|
691
711
|
Fr unused;
|
|
692
712
|
(shplonkNu, unused) = splitChallenge(nextPreviousChallenge);
|
|
693
713
|
}
|
|
694
714
|
|
|
695
715
|
function generateShplonkZChallenge(Honk.Proof memory proof, Fr prevChallenge)
|
|
696
716
|
internal
|
|
697
|
-
|
|
717
|
+
pure
|
|
698
718
|
returns (Fr shplonkZ, Fr nextPreviousChallenge)
|
|
699
719
|
{
|
|
700
720
|
uint256[3] memory shplonkZChallengeElements;
|
|
@@ -703,7 +723,7 @@ library TranscriptLib {
|
|
|
703
723
|
shplonkZChallengeElements[1] = proof.shplonkQ.x;
|
|
704
724
|
shplonkZChallengeElements[2] = proof.shplonkQ.y;
|
|
705
725
|
|
|
706
|
-
nextPreviousChallenge = FrLib.
|
|
726
|
+
nextPreviousChallenge = FrLib.from(uint256(keccak256(abi.encodePacked(shplonkZChallengeElements))) % P);
|
|
707
727
|
Fr unused;
|
|
708
728
|
(shplonkZ, unused) = splitChallenge(nextPreviousChallenge);
|
|
709
729
|
}
|
|
@@ -713,7 +733,10 @@ library TranscriptLib {
|
|
|
713
733
|
|
|
714
734
|
// Pairing point object
|
|
715
735
|
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
716
|
-
|
|
736
|
+
uint256 limb = uint256(bytes32(proof[boundary:boundary + FIELD_ELEMENT_SIZE]));
|
|
737
|
+
// lo limbs (even index) < 2^136, hi limbs (odd index) < 2^120
|
|
738
|
+
require(limb < 2 ** (i % 2 == 0 ? 136 : 120), Errors.ValueGeLimbMax());
|
|
739
|
+
p.pairingPointObject[i] = FrLib.from(limb);
|
|
717
740
|
boundary += FIELD_ELEMENT_SIZE;
|
|
718
741
|
}
|
|
719
742
|
// Commitments
|
|
@@ -770,10 +793,91 @@ library TranscriptLib {
|
|
|
770
793
|
}
|
|
771
794
|
}
|
|
772
795
|
|
|
773
|
-
// Field arithmetic libraries
|
|
774
|
-
|
|
775
796
|
library RelationsLib {
|
|
797
|
+
struct EllipticParams {
|
|
798
|
+
// Points
|
|
799
|
+
Fr x_1;
|
|
800
|
+
Fr y_1;
|
|
801
|
+
Fr x_2;
|
|
802
|
+
Fr y_2;
|
|
803
|
+
Fr y_3;
|
|
804
|
+
Fr x_3;
|
|
805
|
+
// push accumulators into memory
|
|
806
|
+
Fr x_double_identity;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
// Parameters used within the Memory Relation
|
|
810
|
+
// A struct is used to work around stack too deep. This relation has alot of variables
|
|
811
|
+
struct MemParams {
|
|
812
|
+
Fr memory_record_check;
|
|
813
|
+
Fr partial_record_check;
|
|
814
|
+
Fr next_gate_access_type;
|
|
815
|
+
Fr record_delta;
|
|
816
|
+
Fr index_delta;
|
|
817
|
+
Fr adjacent_values_match_if_adjacent_indices_match;
|
|
818
|
+
Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;
|
|
819
|
+
Fr access_check;
|
|
820
|
+
Fr next_gate_access_type_is_boolean;
|
|
821
|
+
Fr ROM_consistency_check_identity;
|
|
822
|
+
Fr RAM_consistency_check_identity;
|
|
823
|
+
Fr timestamp_delta;
|
|
824
|
+
Fr RAM_timestamp_check_identity;
|
|
825
|
+
Fr memory_identity;
|
|
826
|
+
Fr index_is_monotonically_increasing;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// Parameters used within the Non-Native Field Relation
|
|
830
|
+
// A struct is used to work around stack too deep. This relation has alot of variables
|
|
831
|
+
struct NnfParams {
|
|
832
|
+
Fr limb_subproduct;
|
|
833
|
+
Fr non_native_field_gate_1;
|
|
834
|
+
Fr non_native_field_gate_2;
|
|
835
|
+
Fr non_native_field_gate_3;
|
|
836
|
+
Fr limb_accumulator_1;
|
|
837
|
+
Fr limb_accumulator_2;
|
|
838
|
+
Fr nnf_identity;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
struct PoseidonExternalParams {
|
|
842
|
+
Fr s1;
|
|
843
|
+
Fr s2;
|
|
844
|
+
Fr s3;
|
|
845
|
+
Fr s4;
|
|
846
|
+
Fr u1;
|
|
847
|
+
Fr u2;
|
|
848
|
+
Fr u3;
|
|
849
|
+
Fr u4;
|
|
850
|
+
Fr t0;
|
|
851
|
+
Fr t1;
|
|
852
|
+
Fr t2;
|
|
853
|
+
Fr t3;
|
|
854
|
+
Fr v1;
|
|
855
|
+
Fr v2;
|
|
856
|
+
Fr v3;
|
|
857
|
+
Fr v4;
|
|
858
|
+
Fr q_pos_by_scaling;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
struct PoseidonInternalParams {
|
|
862
|
+
Fr u1;
|
|
863
|
+
Fr u2;
|
|
864
|
+
Fr u3;
|
|
865
|
+
Fr u4;
|
|
866
|
+
Fr u_sum;
|
|
867
|
+
Fr v1;
|
|
868
|
+
Fr v2;
|
|
869
|
+
Fr v3;
|
|
870
|
+
Fr v4;
|
|
871
|
+
Fr s1;
|
|
872
|
+
Fr q_pos_by_scaling;
|
|
873
|
+
}
|
|
874
|
+
|
|
776
875
|
Fr internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = Fr.wrap(17); // -(-17)
|
|
876
|
+
uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;
|
|
877
|
+
|
|
878
|
+
// Constants for the Non-native Field relation
|
|
879
|
+
Fr internal constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);
|
|
880
|
+
Fr internal constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);
|
|
777
881
|
|
|
778
882
|
function accumulateRelationEvaluations(
|
|
779
883
|
Fr[NUMBER_OF_ENTITIES] memory purportedEvaluations,
|
|
@@ -807,12 +911,10 @@ library RelationsLib {
|
|
|
807
911
|
return p[uint256(_wire)];
|
|
808
912
|
}
|
|
809
913
|
|
|
810
|
-
uint256 internal constant NEG_HALF_MODULO_P = 0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;
|
|
811
914
|
/**
|
|
812
915
|
* Ultra Arithmetic Relation
|
|
813
916
|
*
|
|
814
917
|
*/
|
|
815
|
-
|
|
816
918
|
function accumulateArithmeticRelation(
|
|
817
919
|
Fr[NUMBER_OF_ENTITIES] memory p,
|
|
818
920
|
Fr[NUMBER_OF_SUBRELATIONS] memory evals,
|
|
@@ -893,38 +995,42 @@ library RelationsLib {
|
|
|
893
995
|
Fr[NUMBER_OF_SUBRELATIONS] memory evals,
|
|
894
996
|
Fr domainSep
|
|
895
997
|
) internal pure {
|
|
896
|
-
Fr
|
|
897
|
-
Fr
|
|
998
|
+
Fr table_term;
|
|
999
|
+
Fr lookup_term;
|
|
898
1000
|
|
|
899
1001
|
// Calculate the write term (the table accumulation)
|
|
1002
|
+
// table_term = table_1 + γ + table_2 * β + table_3 * β² + table_4 * β³
|
|
900
1003
|
{
|
|
901
|
-
|
|
902
|
-
|
|
1004
|
+
Fr beta_sqr = rp.beta * rp.beta;
|
|
1005
|
+
table_term = wire(p, WIRE.TABLE_1) + rp.gamma + (wire(p, WIRE.TABLE_2) * rp.beta)
|
|
1006
|
+
+ (wire(p, WIRE.TABLE_3) * beta_sqr) + (wire(p, WIRE.TABLE_4) * beta_sqr * rp.beta);
|
|
903
1007
|
}
|
|
904
1008
|
|
|
905
|
-
// Calculate the
|
|
1009
|
+
// Calculate the read term
|
|
1010
|
+
// lookup_term = derived_entry_1 + γ + derived_entry_2 * β + derived_entry_3 * β² + q_index * β³
|
|
906
1011
|
{
|
|
1012
|
+
Fr beta_sqr = rp.beta * rp.beta;
|
|
907
1013
|
Fr derived_entry_1 = wire(p, WIRE.W_L) + rp.gamma + (wire(p, WIRE.Q_R) * wire(p, WIRE.W_L_SHIFT));
|
|
908
1014
|
Fr derived_entry_2 = wire(p, WIRE.W_R) + wire(p, WIRE.Q_M) * wire(p, WIRE.W_R_SHIFT);
|
|
909
1015
|
Fr derived_entry_3 = wire(p, WIRE.W_O) + wire(p, WIRE.Q_C) * wire(p, WIRE.W_O_SHIFT);
|
|
910
1016
|
|
|
911
|
-
|
|
912
|
-
+ (wire(p, WIRE.Q_O) * rp.
|
|
1017
|
+
lookup_term = derived_entry_1 + (derived_entry_2 * rp.beta) + (derived_entry_3 * beta_sqr)
|
|
1018
|
+
+ (wire(p, WIRE.Q_O) * beta_sqr * rp.beta);
|
|
913
1019
|
}
|
|
914
1020
|
|
|
915
|
-
Fr
|
|
916
|
-
Fr
|
|
1021
|
+
Fr lookup_inverse = wire(p, WIRE.LOOKUP_INVERSES) * table_term;
|
|
1022
|
+
Fr table_inverse = wire(p, WIRE.LOOKUP_INVERSES) * lookup_term;
|
|
917
1023
|
|
|
918
1024
|
Fr inverse_exists_xor =
|
|
919
1025
|
wire(p, WIRE.LOOKUP_READ_TAGS) + wire(p, WIRE.Q_LOOKUP)
|
|
920
1026
|
- (wire(p, WIRE.LOOKUP_READ_TAGS) * wire(p, WIRE.Q_LOOKUP));
|
|
921
1027
|
|
|
922
1028
|
// Inverse calculated correctly relation
|
|
923
|
-
Fr accumulatorNone =
|
|
1029
|
+
Fr accumulatorNone = lookup_term * table_term * wire(p, WIRE.LOOKUP_INVERSES) - inverse_exists_xor;
|
|
924
1030
|
accumulatorNone = accumulatorNone * domainSep;
|
|
925
1031
|
|
|
926
1032
|
// Inverse
|
|
927
|
-
Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) *
|
|
1033
|
+
Fr accumulatorOne = wire(p, WIRE.Q_LOOKUP) * lookup_inverse - wire(p, WIRE.LOOKUP_READ_COUNTS) * table_inverse;
|
|
928
1034
|
|
|
929
1035
|
Fr read_tag = wire(p, WIRE.LOOKUP_READ_TAGS);
|
|
930
1036
|
|
|
@@ -995,18 +1101,6 @@ library RelationsLib {
|
|
|
995
1101
|
}
|
|
996
1102
|
}
|
|
997
1103
|
|
|
998
|
-
struct EllipticParams {
|
|
999
|
-
// Points
|
|
1000
|
-
Fr x_1;
|
|
1001
|
-
Fr y_1;
|
|
1002
|
-
Fr x_2;
|
|
1003
|
-
Fr y_2;
|
|
1004
|
-
Fr y_3;
|
|
1005
|
-
Fr x_3;
|
|
1006
|
-
// push accumulators into memory
|
|
1007
|
-
Fr x_double_identity;
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
1104
|
function accumulateEllipticRelation(
|
|
1011
1105
|
Fr[NUMBER_OF_ENTITIES] memory p,
|
|
1012
1106
|
Fr[NUMBER_OF_SUBRELATIONS] memory evals,
|
|
@@ -1075,26 +1169,6 @@ library RelationsLib {
|
|
|
1075
1169
|
}
|
|
1076
1170
|
}
|
|
1077
1171
|
|
|
1078
|
-
// Parameters used within the Memory Relation
|
|
1079
|
-
// A struct is used to work around stack too deep. This relation has alot of variables
|
|
1080
|
-
struct MemParams {
|
|
1081
|
-
Fr memory_record_check;
|
|
1082
|
-
Fr partial_record_check;
|
|
1083
|
-
Fr next_gate_access_type;
|
|
1084
|
-
Fr record_delta;
|
|
1085
|
-
Fr index_delta;
|
|
1086
|
-
Fr adjacent_values_match_if_adjacent_indices_match;
|
|
1087
|
-
Fr adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation;
|
|
1088
|
-
Fr access_check;
|
|
1089
|
-
Fr next_gate_access_type_is_boolean;
|
|
1090
|
-
Fr ROM_consistency_check_identity;
|
|
1091
|
-
Fr RAM_consistency_check_identity;
|
|
1092
|
-
Fr timestamp_delta;
|
|
1093
|
-
Fr RAM_timestamp_check_identity;
|
|
1094
|
-
Fr memory_identity;
|
|
1095
|
-
Fr index_is_monotonically_increasing;
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
1172
|
function accumulateMemoryRelation(
|
|
1099
1173
|
Fr[NUMBER_OF_ENTITIES] memory p,
|
|
1100
1174
|
Honk.RelationParameters memory rp,
|
|
@@ -1103,6 +1177,10 @@ library RelationsLib {
|
|
|
1103
1177
|
) internal pure {
|
|
1104
1178
|
MemParams memory ap;
|
|
1105
1179
|
|
|
1180
|
+
// Compute eta powers locally
|
|
1181
|
+
Fr eta_two = rp.eta * rp.eta;
|
|
1182
|
+
Fr eta_three = eta_two * rp.eta;
|
|
1183
|
+
|
|
1106
1184
|
/**
|
|
1107
1185
|
* MEMORY
|
|
1108
1186
|
*
|
|
@@ -1144,8 +1222,8 @@ library RelationsLib {
|
|
|
1144
1222
|
*
|
|
1145
1223
|
* For ROM gates, qc = 0
|
|
1146
1224
|
*/
|
|
1147
|
-
ap.memory_record_check = wire(p, WIRE.W_O) *
|
|
1148
|
-
ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) *
|
|
1225
|
+
ap.memory_record_check = wire(p, WIRE.W_O) * eta_three;
|
|
1226
|
+
ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_R) * eta_two);
|
|
1149
1227
|
ap.memory_record_check = ap.memory_record_check + (wire(p, WIRE.W_L) * rp.eta);
|
|
1150
1228
|
ap.memory_record_check = ap.memory_record_check + wire(p, WIRE.Q_C);
|
|
1151
1229
|
ap.partial_record_check = ap.memory_record_check; // used in RAM consistency check; deg 1 or 4
|
|
@@ -1205,8 +1283,8 @@ library RelationsLib {
|
|
|
1205
1283
|
|
|
1206
1284
|
// reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta
|
|
1207
1285
|
// deg 1 or 4
|
|
1208
|
-
ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) *
|
|
1209
|
-
ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) *
|
|
1286
|
+
ap.next_gate_access_type = wire(p, WIRE.W_O_SHIFT) * eta_three;
|
|
1287
|
+
ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_R_SHIFT) * eta_two);
|
|
1210
1288
|
ap.next_gate_access_type = ap.next_gate_access_type + (wire(p, WIRE.W_L_SHIFT) * rp.eta);
|
|
1211
1289
|
ap.next_gate_access_type = wire(p, WIRE.W_4_SHIFT) - ap.next_gate_access_type;
|
|
1212
1290
|
|
|
@@ -1260,22 +1338,6 @@ library RelationsLib {
|
|
|
1260
1338
|
evals[13] = ap.memory_identity;
|
|
1261
1339
|
}
|
|
1262
1340
|
|
|
1263
|
-
// Constants for the Non-native Field relation
|
|
1264
|
-
Fr constant LIMB_SIZE = Fr.wrap(uint256(1) << 68);
|
|
1265
|
-
Fr constant SUBLIMB_SHIFT = Fr.wrap(uint256(1) << 14);
|
|
1266
|
-
|
|
1267
|
-
// Parameters used within the Non-Native Field Relation
|
|
1268
|
-
// A struct is used to work around stack too deep. This relation has alot of variables
|
|
1269
|
-
struct NnfParams {
|
|
1270
|
-
Fr limb_subproduct;
|
|
1271
|
-
Fr non_native_field_gate_1;
|
|
1272
|
-
Fr non_native_field_gate_2;
|
|
1273
|
-
Fr non_native_field_gate_3;
|
|
1274
|
-
Fr limb_accumulator_1;
|
|
1275
|
-
Fr limb_accumulator_2;
|
|
1276
|
-
Fr nnf_identity;
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
1341
|
function accumulateNnfRelation(
|
|
1280
1342
|
Fr[NUMBER_OF_ENTITIES] memory p,
|
|
1281
1343
|
Fr[NUMBER_OF_SUBRELATIONS] memory evals,
|
|
@@ -1352,26 +1414,6 @@ library RelationsLib {
|
|
|
1352
1414
|
evals[19] = ap.nnf_identity;
|
|
1353
1415
|
}
|
|
1354
1416
|
|
|
1355
|
-
struct PoseidonExternalParams {
|
|
1356
|
-
Fr s1;
|
|
1357
|
-
Fr s2;
|
|
1358
|
-
Fr s3;
|
|
1359
|
-
Fr s4;
|
|
1360
|
-
Fr u1;
|
|
1361
|
-
Fr u2;
|
|
1362
|
-
Fr u3;
|
|
1363
|
-
Fr u4;
|
|
1364
|
-
Fr t0;
|
|
1365
|
-
Fr t1;
|
|
1366
|
-
Fr t2;
|
|
1367
|
-
Fr t3;
|
|
1368
|
-
Fr v1;
|
|
1369
|
-
Fr v2;
|
|
1370
|
-
Fr v3;
|
|
1371
|
-
Fr v4;
|
|
1372
|
-
Fr q_pos_by_scaling;
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
1417
|
function accumulatePoseidonExternalRelation(
|
|
1376
1418
|
Fr[NUMBER_OF_ENTITIES] memory p,
|
|
1377
1419
|
Fr[NUMBER_OF_SUBRELATIONS] memory evals,
|
|
@@ -1414,20 +1456,6 @@ library RelationsLib {
|
|
|
1414
1456
|
evals[23] = evals[23] + ep.q_pos_by_scaling * (ep.v4 - wire(p, WIRE.W_4_SHIFT));
|
|
1415
1457
|
}
|
|
1416
1458
|
|
|
1417
|
-
struct PoseidonInternalParams {
|
|
1418
|
-
Fr u1;
|
|
1419
|
-
Fr u2;
|
|
1420
|
-
Fr u3;
|
|
1421
|
-
Fr u4;
|
|
1422
|
-
Fr u_sum;
|
|
1423
|
-
Fr v1;
|
|
1424
|
-
Fr v2;
|
|
1425
|
-
Fr v3;
|
|
1426
|
-
Fr v4;
|
|
1427
|
-
Fr s1;
|
|
1428
|
-
Fr q_pos_by_scaling;
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
1459
|
function accumulatePoseidonInternalRelation(
|
|
1432
1460
|
Fr[NUMBER_OF_ENTITIES] memory p,
|
|
1433
1461
|
Fr[NUMBER_OF_SUBRELATIONS] memory evals,
|
|
@@ -1483,8 +1511,6 @@ library RelationsLib {
|
|
|
1483
1511
|
}
|
|
1484
1512
|
}
|
|
1485
1513
|
|
|
1486
|
-
// Field arithmetic libraries - prevent littering the code with modmul / addmul
|
|
1487
|
-
|
|
1488
1514
|
library CommitmentSchemeLib {
|
|
1489
1515
|
using FrLib for Fr;
|
|
1490
1516
|
|
|
@@ -1514,16 +1540,7 @@ library CommitmentSchemeLib {
|
|
|
1514
1540
|
Fr[] foldPosEvaluations;
|
|
1515
1541
|
}
|
|
1516
1542
|
|
|
1517
|
-
function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {
|
|
1518
|
-
Fr[] memory squares = new Fr[](logN);
|
|
1519
|
-
squares[0] = r;
|
|
1520
|
-
for (uint256 i = 1; i < logN; ++i) {
|
|
1521
|
-
squares[i] = squares[i - 1].sqr();
|
|
1522
|
-
}
|
|
1523
|
-
return squares;
|
|
1524
|
-
}
|
|
1525
1543
|
// Compute the evaluations Aₗ(r^{2ˡ}) for l = 0, ..., m-1
|
|
1526
|
-
|
|
1527
1544
|
function computeFoldPosEvaluations(
|
|
1528
1545
|
Fr[CONST_PROOF_SIZE_LOG_N] memory sumcheckUChallenges,
|
|
1529
1546
|
Fr batchedEvalAccumulator,
|
|
@@ -1546,23 +1563,19 @@ library CommitmentSchemeLib {
|
|
|
1546
1563
|
}
|
|
1547
1564
|
return foldPosEvaluations;
|
|
1548
1565
|
}
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
uint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q
|
|
1552
|
-
|
|
1553
|
-
function bytes32ToString(bytes32 value) pure returns (string memory result) {
|
|
1554
|
-
bytes memory alphabet = "0123456789abcdef";
|
|
1555
1566
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1567
|
+
function computeSquares(Fr r, uint256 logN) internal pure returns (Fr[] memory) {
|
|
1568
|
+
Fr[] memory squares = new Fr[](logN);
|
|
1569
|
+
squares[0] = r;
|
|
1570
|
+
for (uint256 i = 1; i < logN; ++i) {
|
|
1571
|
+
squares[i] = squares[i - 1].sqr();
|
|
1572
|
+
}
|
|
1573
|
+
return squares;
|
|
1562
1574
|
}
|
|
1563
|
-
result = string(str);
|
|
1564
1575
|
}
|
|
1565
1576
|
|
|
1577
|
+
uint256 constant Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // EC group order. F_q
|
|
1578
|
+
|
|
1566
1579
|
// Fr utility
|
|
1567
1580
|
|
|
1568
1581
|
function bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {
|
|
@@ -1571,54 +1584,66 @@ function bytesToFr(bytes calldata proofSection) pure returns (Fr scalar) {
|
|
|
1571
1584
|
|
|
1572
1585
|
// EC Point utilities
|
|
1573
1586
|
function bytesToG1Point(bytes calldata proofSection) pure returns (Honk.G1Point memory point) {
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1587
|
+
uint256 x = uint256(bytes32(proofSection[0x00:0x20]));
|
|
1588
|
+
uint256 y = uint256(bytes32(proofSection[0x20:0x40]));
|
|
1589
|
+
require(x < Q && y < Q, Errors.ValueGeGroupOrder());
|
|
1590
|
+
|
|
1591
|
+
// Reject the point at infinity (0,0). EVM precompiles silently treat (0,0)
|
|
1592
|
+
// as the identity element, which could zero out commitments.
|
|
1593
|
+
// On-curve validation (y² = x³ + 3) is handled by the ecAdd/ecMul precompiles
|
|
1594
|
+
// per EIP-196, so we only need to catch this special case here.
|
|
1595
|
+
require((x | y) != 0, Errors.PointAtInfinity());
|
|
1596
|
+
|
|
1597
|
+
point = Honk.G1Point({x: x, y: y});
|
|
1577
1598
|
}
|
|
1578
1599
|
|
|
1579
1600
|
function negateInplace(Honk.G1Point memory point) pure returns (Honk.G1Point memory) {
|
|
1580
|
-
|
|
1601
|
+
// When y == 0 (order-2 point), negation is the same point. Q - 0 = Q which is >= Q.
|
|
1602
|
+
if (point.y != 0) {
|
|
1603
|
+
point.y = Q - point.y;
|
|
1604
|
+
}
|
|
1581
1605
|
return point;
|
|
1582
1606
|
}
|
|
1583
1607
|
|
|
1584
1608
|
/**
|
|
1585
1609
|
* Convert the pairing points to G1 points.
|
|
1586
1610
|
*
|
|
1587
|
-
* The pairing points are serialised as an array of
|
|
1588
|
-
*
|
|
1611
|
+
* The pairing points are serialised as an array of 2 limbs representing two points
|
|
1612
|
+
* (P0 and P1, used for lhs and rhs of pairing operation).
|
|
1589
1613
|
*
|
|
1590
|
-
* There are
|
|
1614
|
+
* There are 2 limbs (lo, hi) for each coordinate, so 4 limbs per point, 8 total.
|
|
1615
|
+
* Layout: [P0.x_lo, P0.x_hi, P0.y_lo, P0.y_hi, P1.x_lo, P1.x_hi, P1.y_lo, P1.y_hi]
|
|
1591
1616
|
*
|
|
1592
1617
|
* @param pairingPoints The pairing points to convert.
|
|
1593
|
-
* @return lhs
|
|
1594
|
-
* @return rhs
|
|
1618
|
+
* @return lhs P0 point
|
|
1619
|
+
* @return rhs P1 point
|
|
1595
1620
|
*/
|
|
1596
1621
|
function convertPairingPointsToG1(Fr[PAIRING_POINTS_SIZE] memory pairingPoints)
|
|
1597
1622
|
pure
|
|
1598
1623
|
returns (Honk.G1Point memory lhs, Honk.G1Point memory rhs)
|
|
1599
1624
|
{
|
|
1625
|
+
// P0 (lhs): x = lo | (hi << 136)
|
|
1600
1626
|
uint256 lhsX = Fr.unwrap(pairingPoints[0]);
|
|
1601
|
-
lhsX |= Fr.unwrap(pairingPoints[1]) <<
|
|
1602
|
-
lhsX |= Fr.unwrap(pairingPoints[2]) << 136;
|
|
1603
|
-
lhsX |= Fr.unwrap(pairingPoints[3]) << 204;
|
|
1604
|
-
lhs.x = lhsX;
|
|
1627
|
+
lhsX |= Fr.unwrap(pairingPoints[1]) << 136;
|
|
1605
1628
|
|
|
1606
|
-
uint256 lhsY = Fr.unwrap(pairingPoints[
|
|
1607
|
-
lhsY |= Fr.unwrap(pairingPoints[
|
|
1608
|
-
lhsY |= Fr.unwrap(pairingPoints[6]) << 136;
|
|
1609
|
-
lhsY |= Fr.unwrap(pairingPoints[7]) << 204;
|
|
1610
|
-
lhs.y = lhsY;
|
|
1629
|
+
uint256 lhsY = Fr.unwrap(pairingPoints[2]);
|
|
1630
|
+
lhsY |= Fr.unwrap(pairingPoints[3]) << 136;
|
|
1611
1631
|
|
|
1612
|
-
|
|
1613
|
-
rhsX
|
|
1614
|
-
rhsX |= Fr.unwrap(pairingPoints[
|
|
1615
|
-
|
|
1616
|
-
|
|
1632
|
+
// P1 (rhs): x = lo | (hi << 136)
|
|
1633
|
+
uint256 rhsX = Fr.unwrap(pairingPoints[4]);
|
|
1634
|
+
rhsX |= Fr.unwrap(pairingPoints[5]) << 136;
|
|
1635
|
+
|
|
1636
|
+
uint256 rhsY = Fr.unwrap(pairingPoints[6]);
|
|
1637
|
+
rhsY |= Fr.unwrap(pairingPoints[7]) << 136;
|
|
1617
1638
|
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
rhsY
|
|
1639
|
+
// Reconstructed coordinates must be < Q to prevent malleability.
|
|
1640
|
+
// Without this, two different limb encodings could map to the same curve point
|
|
1641
|
+
// (via mulmod reduction in on-curve checks) but produce different transcript hashes.
|
|
1642
|
+
require(lhsX < Q && lhsY < Q && rhsX < Q && rhsY < Q, Errors.ValueGeGroupOrder());
|
|
1643
|
+
|
|
1644
|
+
lhs.x = lhsX;
|
|
1645
|
+
lhs.y = lhsY;
|
|
1646
|
+
rhs.x = rhsX;
|
|
1622
1647
|
rhs.y = rhsY;
|
|
1623
1648
|
}
|
|
1624
1649
|
|
|
@@ -1656,7 +1681,7 @@ function generateRecursionSeparator(
|
|
|
1656
1681
|
recursionSeparatorElements[6] = accRhs.x;
|
|
1657
1682
|
recursionSeparatorElements[7] = accRhs.y;
|
|
1658
1683
|
|
|
1659
|
-
recursionSeparator = FrLib.
|
|
1684
|
+
recursionSeparator = FrLib.from(uint256(keccak256(abi.encodePacked(recursionSeparatorElements))) % P);
|
|
1660
1685
|
}
|
|
1661
1686
|
|
|
1662
1687
|
/**
|
|
@@ -1774,17 +1799,20 @@ function ecAdd(Honk.G1Point memory lhs, Honk.G1Point memory rhs) view returns (H
|
|
|
1774
1799
|
return result;
|
|
1775
1800
|
}
|
|
1776
1801
|
|
|
1777
|
-
function
|
|
1778
|
-
|
|
1779
|
-
|
|
1802
|
+
function rejectPointAtInfinity(Honk.G1Point memory point) pure {
|
|
1803
|
+
require((point.x | point.y) != 0, Errors.PointAtInfinity());
|
|
1804
|
+
}
|
|
1780
1805
|
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1806
|
+
/**
|
|
1807
|
+
* Check if pairing point limbs are all zero (default/infinity).
|
|
1808
|
+
* Default pairing points indicate no recursive verification occurred.
|
|
1809
|
+
*/
|
|
1810
|
+
function arePairingPointsDefault(Fr[PAIRING_POINTS_SIZE] memory pairingPoints) pure returns (bool) {
|
|
1811
|
+
uint256 acc = 0;
|
|
1812
|
+
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
1813
|
+
acc |= Fr.unwrap(pairingPoints[i]);
|
|
1785
1814
|
}
|
|
1786
|
-
|
|
1787
|
-
require(success, "point is not on the curve");
|
|
1815
|
+
return acc == 0;
|
|
1788
1816
|
}
|
|
1789
1817
|
|
|
1790
1818
|
function pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns (bool decodedResult) {
|
|
@@ -1809,18 +1837,24 @@ function pairing(Honk.G1Point memory rhs, Honk.G1Point memory lhs) view returns
|
|
|
1809
1837
|
decodedResult = success && abi.decode(result, (bool));
|
|
1810
1838
|
}
|
|
1811
1839
|
|
|
1812
|
-
|
|
1813
|
-
|
|
1840
|
+
abstract contract BaseHonkVerifier is IVerifier {
|
|
1841
|
+
using FrLib for Fr;
|
|
1814
1842
|
|
|
1843
|
+
// Constants for proof length calculation (matching UltraKeccakFlavor)
|
|
1844
|
+
uint256 internal constant NUM_WITNESS_ENTITIES = 8;
|
|
1845
|
+
uint256 internal constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points
|
|
1846
|
+
uint256 internal constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements
|
|
1815
1847
|
|
|
1848
|
+
// Number of field elements in a ultra keccak honk proof for log_n = 25, including pairing point object.
|
|
1849
|
+
uint256 internal constant PROOF_SIZE = 350; // Legacy constant - will be replaced by calculateProofSize($LOG_N)
|
|
1850
|
+
uint256 internal constant SHIFTED_COMMITMENTS_START = 29;
|
|
1816
1851
|
|
|
1817
|
-
|
|
1818
|
-
using FrLib for Fr;
|
|
1852
|
+
uint256 internal constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;
|
|
1819
1853
|
|
|
1820
|
-
uint256 immutable $N;
|
|
1821
|
-
uint256 immutable $LOG_N;
|
|
1822
|
-
uint256 immutable $VK_HASH;
|
|
1823
|
-
uint256 immutable $NUM_PUBLIC_INPUTS;
|
|
1854
|
+
uint256 internal immutable $N;
|
|
1855
|
+
uint256 internal immutable $LOG_N;
|
|
1856
|
+
uint256 internal immutable $VK_HASH;
|
|
1857
|
+
uint256 internal immutable $NUM_PUBLIC_INPUTS;
|
|
1824
1858
|
|
|
1825
1859
|
constructor(uint256 _N, uint256 _logN, uint256 _vkHash, uint256 _numPublicInputs) {
|
|
1826
1860
|
$N = _N;
|
|
@@ -1829,59 +1863,19 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1829
1863
|
$NUM_PUBLIC_INPUTS = _numPublicInputs;
|
|
1830
1864
|
}
|
|
1831
1865
|
|
|
1832
|
-
// Errors
|
|
1833
|
-
error ProofLengthWrong();
|
|
1834
|
-
error ProofLengthWrongWithLogN(uint256 logN, uint256 actualLength, uint256 expectedLength);
|
|
1835
|
-
error PublicInputsLengthWrong();
|
|
1836
|
-
error SumcheckFailed();
|
|
1837
|
-
error ShpleminiFailed();
|
|
1838
|
-
|
|
1839
|
-
// Constants for proof length calculation (matching UltraKeccakFlavor)
|
|
1840
|
-
uint256 constant NUM_WITNESS_ENTITIES = 8;
|
|
1841
|
-
uint256 constant NUM_ELEMENTS_COMM = 2; // uint256 elements for curve points
|
|
1842
|
-
uint256 constant NUM_ELEMENTS_FR = 1; // uint256 elements for field elements
|
|
1843
|
-
|
|
1844
|
-
// Calculate proof size based on log_n (matching UltraKeccakFlavor formula)
|
|
1845
|
-
function calculateProofSize(uint256 logN) internal pure returns (uint256) {
|
|
1846
|
-
// Witness commitments
|
|
1847
|
-
uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments
|
|
1848
|
-
|
|
1849
|
-
// Sumcheck
|
|
1850
|
-
proofLength += logN * BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates
|
|
1851
|
-
proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations
|
|
1852
|
-
|
|
1853
|
-
// Gemini
|
|
1854
|
-
proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments
|
|
1855
|
-
proofLength += logN * NUM_ELEMENTS_FR; // Gemini evaluations
|
|
1856
|
-
|
|
1857
|
-
// Shplonk and KZG commitments
|
|
1858
|
-
proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments
|
|
1859
|
-
|
|
1860
|
-
// Pairing points
|
|
1861
|
-
proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs
|
|
1862
|
-
|
|
1863
|
-
return proofLength;
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
|
-
// Number of field elements in a ultra keccak honk proof for log_n = 25, including pairing point object.
|
|
1867
|
-
uint256 constant PROOF_SIZE = 350; // Legacy constant - will be replaced by calculateProofSize($LOG_N)
|
|
1868
|
-
uint256 constant SHIFTED_COMMITMENTS_START = 29;
|
|
1869
|
-
|
|
1870
|
-
function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);
|
|
1871
|
-
|
|
1872
1866
|
function verify(bytes calldata proof, bytes32[] calldata publicInputs) public view override returns (bool) {
|
|
1873
1867
|
// Calculate expected proof size based on $LOG_N
|
|
1874
1868
|
uint256 expectedProofSize = calculateProofSize($LOG_N);
|
|
1875
1869
|
|
|
1876
1870
|
// Check the received proof is the expected size where each field element is 32 bytes
|
|
1877
1871
|
if (proof.length != expectedProofSize * 32) {
|
|
1878
|
-
revert ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);
|
|
1872
|
+
revert Errors.ProofLengthWrongWithLogN($LOG_N, proof.length, expectedProofSize * 32);
|
|
1879
1873
|
}
|
|
1880
1874
|
|
|
1881
1875
|
Honk.VerificationKey memory vk = loadVerificationKey();
|
|
1882
1876
|
Honk.Proof memory p = TranscriptLib.loadProof(proof, $LOG_N);
|
|
1883
1877
|
if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {
|
|
1884
|
-
revert PublicInputsLengthWrong();
|
|
1878
|
+
revert Errors.PublicInputsLengthWrong();
|
|
1885
1879
|
}
|
|
1886
1880
|
|
|
1887
1881
|
// Generate the fiat shamir challenges for the whole protocol
|
|
@@ -1898,16 +1892,14 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1898
1892
|
|
|
1899
1893
|
// Sumcheck
|
|
1900
1894
|
bool sumcheckVerified = verifySumcheck(p, t);
|
|
1901
|
-
if (!sumcheckVerified) revert SumcheckFailed();
|
|
1895
|
+
if (!sumcheckVerified) revert Errors.SumcheckFailed();
|
|
1902
1896
|
|
|
1903
1897
|
bool shpleminiVerified = verifyShplemini(p, vk, t);
|
|
1904
|
-
if (!shpleminiVerified) revert ShpleminiFailed();
|
|
1898
|
+
if (!shpleminiVerified) revert Errors.ShpleminiFailed();
|
|
1905
1899
|
|
|
1906
1900
|
return sumcheckVerified && shpleminiVerified; // Boolean condition not required - nice for vanity :)
|
|
1907
1901
|
}
|
|
1908
1902
|
|
|
1909
|
-
uint256 constant PERMUTATION_ARGUMENT_VALUE_SEPARATOR = 1 << 28;
|
|
1910
|
-
|
|
1911
1903
|
function computePublicInputDelta(
|
|
1912
1904
|
bytes32[] memory publicInputs,
|
|
1913
1905
|
Fr[PAIRING_POINTS_SIZE] memory pairingPointObject,
|
|
@@ -1954,7 +1946,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1954
1946
|
for (uint256 round = 0; round < $LOG_N; ++round) {
|
|
1955
1947
|
Fr[BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate = proof.sumcheckUnivariates[round];
|
|
1956
1948
|
bool valid = checkSum(roundUnivariate, roundTarget);
|
|
1957
|
-
if (!valid) revert SumcheckFailed();
|
|
1949
|
+
if (!valid) revert Errors.SumcheckFailed();
|
|
1958
1950
|
|
|
1959
1951
|
Fr roundChallenge = tp.sumCheckUChallenges[round];
|
|
1960
1952
|
|
|
@@ -1970,15 +1962,6 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1970
1962
|
verified = (grandHonkRelationSum == roundTarget);
|
|
1971
1963
|
}
|
|
1972
1964
|
|
|
1973
|
-
function checkSum(Fr[BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate, Fr roundTarget)
|
|
1974
|
-
internal
|
|
1975
|
-
pure
|
|
1976
|
-
returns (bool checked)
|
|
1977
|
-
{
|
|
1978
|
-
Fr totalSum = roundUnivariate[0] + roundUnivariate[1];
|
|
1979
|
-
checked = totalSum == roundTarget;
|
|
1980
|
-
}
|
|
1981
|
-
|
|
1982
1965
|
// Return the new target sum for the next sumcheck round
|
|
1983
1966
|
function computeNextTargetSum(Fr[BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariates, Fr roundChallenge)
|
|
1984
1967
|
internal
|
|
@@ -2022,16 +2005,6 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
2022
2005
|
targetSum = targetSum * numeratorValue;
|
|
2023
2006
|
}
|
|
2024
2007
|
|
|
2025
|
-
// Univariate evaluation of the monomial ((1-X_l) + X_l.B_l) at the challenge point X_l=u_l
|
|
2026
|
-
function partiallyEvaluatePOW(Fr gateChallenge, Fr currentEvaluation, Fr roundChallenge)
|
|
2027
|
-
internal
|
|
2028
|
-
pure
|
|
2029
|
-
returns (Fr newEvaluation)
|
|
2030
|
-
{
|
|
2031
|
-
Fr univariateEval = ONE + (roundChallenge * (gateChallenge - ONE));
|
|
2032
|
-
newEvaluation = currentEvaluation * univariateEval;
|
|
2033
|
-
}
|
|
2034
|
-
|
|
2035
2008
|
function verifyShplemini(Honk.Proof memory proof, Honk.VerificationKey memory vk, Transcript memory tp)
|
|
2036
2009
|
internal
|
|
2037
2010
|
view
|
|
@@ -2224,18 +2197,20 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
2224
2197
|
Honk.G1Point memory P_0_agg = batchMul(commitments, scalars);
|
|
2225
2198
|
Honk.G1Point memory P_1_agg = negateInplace(quotient_commitment);
|
|
2226
2199
|
|
|
2227
|
-
// Aggregate pairing points
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2200
|
+
// Aggregate pairing points (skip if default/infinity — no recursive verification occurred)
|
|
2201
|
+
if (!arePairingPointsDefault(proof.pairingPointObject)) {
|
|
2202
|
+
Fr recursionSeparator = generateRecursionSeparator(proof.pairingPointObject, P_0_agg, P_1_agg);
|
|
2203
|
+
(Honk.G1Point memory P_0_other, Honk.G1Point memory P_1_other) =
|
|
2204
|
+
convertPairingPointsToG1(proof.pairingPointObject);
|
|
2231
2205
|
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2206
|
+
// Validate the points from the proof are on the curve
|
|
2207
|
+
rejectPointAtInfinity(P_0_other);
|
|
2208
|
+
rejectPointAtInfinity(P_1_other);
|
|
2235
2209
|
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2210
|
+
// accumulate with aggregate points in proof
|
|
2211
|
+
P_0_agg = mulWithSeperator(P_0_agg, P_0_other, recursionSeparator);
|
|
2212
|
+
P_1_agg = mulWithSeperator(P_1_agg, P_1_other, recursionSeparator);
|
|
2213
|
+
}
|
|
2239
2214
|
|
|
2240
2215
|
return pairing(P_0_agg, P_1_agg);
|
|
2241
2216
|
}
|
|
@@ -2249,7 +2224,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
2249
2224
|
|
|
2250
2225
|
// Validate all points are on the curve
|
|
2251
2226
|
for (uint256 i = 0; i < limit; ++i) {
|
|
2252
|
-
|
|
2227
|
+
rejectPointAtInfinity(base[i]);
|
|
2253
2228
|
}
|
|
2254
2229
|
|
|
2255
2230
|
bool success = true;
|
|
@@ -2277,8 +2252,51 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
2277
2252
|
mstore(add(result, 0x20), mload(add(free, 0x20)))
|
|
2278
2253
|
}
|
|
2279
2254
|
|
|
2280
|
-
require(success, ShpleminiFailed());
|
|
2255
|
+
require(success, Errors.ShpleminiFailed());
|
|
2281
2256
|
}
|
|
2257
|
+
|
|
2258
|
+
// Calculate proof size based on log_n (matching UltraKeccakFlavor formula)
|
|
2259
|
+
function calculateProofSize(uint256 logN) internal pure returns (uint256) {
|
|
2260
|
+
// Witness commitments
|
|
2261
|
+
uint256 proofLength = NUM_WITNESS_ENTITIES * NUM_ELEMENTS_COMM; // witness commitments
|
|
2262
|
+
|
|
2263
|
+
// Sumcheck
|
|
2264
|
+
proofLength += logN * BATCHED_RELATION_PARTIAL_LENGTH * NUM_ELEMENTS_FR; // sumcheck univariates
|
|
2265
|
+
proofLength += NUMBER_OF_ENTITIES * NUM_ELEMENTS_FR; // sumcheck evaluations
|
|
2266
|
+
|
|
2267
|
+
// Gemini
|
|
2268
|
+
proofLength += (logN - 1) * NUM_ELEMENTS_COMM; // Gemini Fold commitments
|
|
2269
|
+
proofLength += logN * NUM_ELEMENTS_FR; // Gemini evaluations
|
|
2270
|
+
|
|
2271
|
+
// Shplonk and KZG commitments
|
|
2272
|
+
proofLength += NUM_ELEMENTS_COMM * 2; // Shplonk Q and KZG W commitments
|
|
2273
|
+
|
|
2274
|
+
// Pairing points
|
|
2275
|
+
proofLength += PAIRING_POINTS_SIZE; // pairing inputs carried on public inputs
|
|
2276
|
+
|
|
2277
|
+
return proofLength;
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
function checkSum(Fr[BATCHED_RELATION_PARTIAL_LENGTH] memory roundUnivariate, Fr roundTarget)
|
|
2281
|
+
internal
|
|
2282
|
+
pure
|
|
2283
|
+
returns (bool checked)
|
|
2284
|
+
{
|
|
2285
|
+
Fr totalSum = roundUnivariate[0] + roundUnivariate[1];
|
|
2286
|
+
checked = totalSum == roundTarget;
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
// Univariate evaluation of the monomial ((1-X_l) + X_l.B_l) at the challenge point X_l=u_l
|
|
2290
|
+
function partiallyEvaluatePOW(Fr gateChallenge, Fr currentEvaluation, Fr roundChallenge)
|
|
2291
|
+
internal
|
|
2292
|
+
pure
|
|
2293
|
+
returns (Fr newEvaluation)
|
|
2294
|
+
{
|
|
2295
|
+
Fr univariateEval = ONE + (roundChallenge * (gateChallenge - ONE));
|
|
2296
|
+
newEvaluation = currentEvaluation * univariateEval;
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
function loadVerificationKey() internal pure virtual returns (Honk.VerificationKey memory);
|
|
2282
2300
|
}
|
|
2283
2301
|
|
|
2284
2302
|
contract HonkVerifier is BaseHonkVerifier(N, LOG_N, VK_HASH, NUMBER_OF_PUBLIC_INPUTS) {
|