@aztec/ivc-integration 0.84.0 → 0.85.0
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 +1 -1
- package/artifacts/app_reader.json +1 -1
- package/artifacts/keys/app_creator.vk.data.json +69 -69
- package/artifacts/keys/app_reader.vk.data.json +69 -69
- package/artifacts/keys/mock_private_kernel_init.vk.data.json +69 -69
- package/artifacts/keys/mock_private_kernel_inner.vk.data.json +69 -69
- package/artifacts/keys/mock_private_kernel_reset.vk.data.json +69 -69
- package/artifacts/keys/mock_private_kernel_tail.vk.data.json +69 -69
- package/artifacts/keys/mock_rollup_base_private.vk.data.json +144 -0
- package/artifacts/keys/mock_rollup_base_public.vk.data.d.json.ts +2 -0
- package/artifacts/keys/mock_rollup_base_public.vk.data.json +144 -0
- package/artifacts/keys/mock_rollup_merge.vk.data.d.json.ts +2 -0
- package/artifacts/keys/mock_rollup_merge.vk.data.json +144 -0
- package/artifacts/keys/mock_rollup_root.vk.data.d.json.ts +2 -0
- package/artifacts/keys/mock_rollup_root.vk.data.json +133 -0
- package/artifacts/keys/mock_rollup_root_verifier.sol +1914 -0
- package/artifacts/mock_private_kernel_init.json +1 -1
- package/artifacts/mock_private_kernel_inner.json +1 -1
- package/artifacts/mock_private_kernel_reset.json +1 -1
- package/artifacts/mock_private_kernel_tail.json +1 -1
- package/artifacts/mock_rollup_base_private.json +1 -0
- package/artifacts/mock_rollup_base_public.d.json.ts +3 -0
- package/artifacts/mock_rollup_base_public.json +1 -0
- package/artifacts/mock_rollup_merge.d.json.ts +3 -0
- package/artifacts/mock_rollup_merge.json +1 -0
- package/artifacts/mock_rollup_root.d.json.ts +3 -0
- package/artifacts/mock_rollup_root.json +1 -0
- package/dest/index.d.ts +1 -35
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -227
- package/dest/prove_native.d.ts +15 -0
- package/dest/prove_native.d.ts.map +1 -0
- package/dest/prove_native.js +105 -0
- package/dest/prove_wasm.d.ts +2 -0
- package/dest/prove_wasm.d.ts.map +1 -0
- package/dest/prove_wasm.js +17 -0
- package/dest/scripts/generate_ts_from_abi.js +4 -1
- package/dest/serve.js +2 -1
- package/dest/types/index.d.ts +41 -7
- package/dest/types/index.d.ts.map +1 -1
- package/dest/types/index.js +29 -2
- package/dest/witgen.d.ts +60 -0
- package/dest/witgen.d.ts.map +1 -0
- package/dest/witgen.js +335 -0
- package/package.json +15 -17
- package/src/index.ts +1 -260
- package/src/prove_native.ts +238 -0
- package/src/prove_wasm.ts +24 -0
- package/src/scripts/generate_ts_from_abi.ts +4 -1
- package/src/serve.ts +2 -1
- package/src/types/index.ts +72 -10
- package/src/witgen.ts +373 -0
- package/artifacts/keys/mock_public_base.vk.data.json +0 -133
- package/artifacts/mock_public_base.json +0 -1
- /package/artifacts/keys/{mock_public_base.vk.data.d.json.ts → mock_rollup_base_private.vk.data.d.json.ts} +0 -0
- /package/artifacts/{mock_public_base.d.json.ts → mock_rollup_base_private.d.json.ts} +0 -0
package/src/witgen.ts
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED,
|
|
3
|
+
AVM_V2_PUBLIC_INPUTS_FLATTENED_SIZE,
|
|
4
|
+
AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED,
|
|
5
|
+
CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS,
|
|
6
|
+
} from '@aztec/constants';
|
|
7
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
8
|
+
import { type ForeignCallOutput, Noir } from '@aztec/noir-noir_js';
|
|
9
|
+
import type { PublicTxSimulationTester } from '@aztec/simulator/server';
|
|
10
|
+
import type { AvmCircuitPublicInputs } from '@aztec/stdlib/avm';
|
|
11
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
|
+
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
13
|
+
import type { RecursiveProof } from '@aztec/stdlib/proofs';
|
|
14
|
+
import type { VerificationKeyAsFields } from '@aztec/stdlib/vks';
|
|
15
|
+
|
|
16
|
+
import createDebug from 'debug';
|
|
17
|
+
|
|
18
|
+
import MockAppCreatorCircuit from '../artifacts/app_creator.json' assert { type: 'json' };
|
|
19
|
+
import MockAppReaderCircuit from '../artifacts/app_reader.json' assert { type: 'json' };
|
|
20
|
+
import MockAppCreatorVk from '../artifacts/keys/app_creator.vk.data.json' assert { type: 'json' };
|
|
21
|
+
import MockAppReaderVk from '../artifacts/keys/app_reader.vk.data.json' assert { type: 'json' };
|
|
22
|
+
import MockPrivateKernelInitVk from '../artifacts/keys/mock_private_kernel_init.vk.data.json' assert { type: 'json' };
|
|
23
|
+
import MockPrivateKernelInnerVk from '../artifacts/keys/mock_private_kernel_inner.vk.data.json' assert { type: 'json' };
|
|
24
|
+
import MockPrivateKernelResetVk from '../artifacts/keys/mock_private_kernel_reset.vk.data.json' assert { type: 'json' };
|
|
25
|
+
import MockPrivateKernelTailVk from '../artifacts/keys/mock_private_kernel_tail.vk.data.json' assert { type: 'json' };
|
|
26
|
+
import MockRollupBasePrivateVk from '../artifacts/keys/mock_rollup_base_private.vk.data.json' assert { type: 'json' };
|
|
27
|
+
import MockRollupBasePublicVk from '../artifacts/keys/mock_rollup_base_public.vk.data.json' assert { type: 'json' };
|
|
28
|
+
import MockRollupMergeVk from '../artifacts/keys/mock_rollup_merge.vk.data.json' assert { type: 'json' };
|
|
29
|
+
import MockRollupRootVk from '../artifacts/keys/mock_rollup_root.vk.data.json' assert { type: 'json' };
|
|
30
|
+
import MockPrivateKernelInitCircuit from '../artifacts/mock_private_kernel_init.json' assert { type: 'json' };
|
|
31
|
+
import MockPrivateKernelInnerCircuit from '../artifacts/mock_private_kernel_inner.json' assert { type: 'json' };
|
|
32
|
+
import MockPrivateKernelResetCircuit from '../artifacts/mock_private_kernel_reset.json' assert { type: 'json' };
|
|
33
|
+
import MockPrivateKernelTailCircuit from '../artifacts/mock_private_kernel_tail.json' assert { type: 'json' };
|
|
34
|
+
import MockRollupBasePrivateCircuit from '../artifacts/mock_rollup_base_private.json' assert { type: 'json' };
|
|
35
|
+
import MockRollupBasePublicCircuit from '../artifacts/mock_rollup_base_public.json' assert { type: 'json' };
|
|
36
|
+
import MockRollupMergeCircuit from '../artifacts/mock_rollup_merge.json' assert { type: 'json' };
|
|
37
|
+
import MockRollupRootCircuit from '../artifacts/mock_rollup_root.json' assert { type: 'json' };
|
|
38
|
+
import type {
|
|
39
|
+
AppCreatorInputType,
|
|
40
|
+
AppPublicInputs,
|
|
41
|
+
AppReaderInputType,
|
|
42
|
+
FixedLengthArray,
|
|
43
|
+
KernelPublicInputs,
|
|
44
|
+
MockPrivateKernelInitInputType,
|
|
45
|
+
MockPrivateKernelInnerInputType,
|
|
46
|
+
MockPrivateKernelResetInputType,
|
|
47
|
+
MockPrivateKernelTailInputType,
|
|
48
|
+
MockRollupBasePrivateInputType,
|
|
49
|
+
MockRollupBasePublicInputType,
|
|
50
|
+
MockRollupMergeInputType,
|
|
51
|
+
MockRollupRootInputType,
|
|
52
|
+
PrivateKernelPublicInputs,
|
|
53
|
+
RollupPublicInputs,
|
|
54
|
+
} from './types/index.js';
|
|
55
|
+
|
|
56
|
+
// Re export the circuit jsons
|
|
57
|
+
export {
|
|
58
|
+
MockAppCreatorCircuit,
|
|
59
|
+
MockAppReaderCircuit,
|
|
60
|
+
MockPrivateKernelInitCircuit,
|
|
61
|
+
MockPrivateKernelInnerCircuit,
|
|
62
|
+
MockPrivateKernelResetCircuit,
|
|
63
|
+
MockPrivateKernelTailCircuit,
|
|
64
|
+
MockRollupBasePublicCircuit,
|
|
65
|
+
MockRollupBasePrivateCircuit,
|
|
66
|
+
MockRollupMergeCircuit,
|
|
67
|
+
MockRollupRootCircuit,
|
|
68
|
+
MockAppCreatorVk,
|
|
69
|
+
MockAppReaderVk,
|
|
70
|
+
MockPrivateKernelInitVk,
|
|
71
|
+
MockPrivateKernelInnerVk,
|
|
72
|
+
MockPrivateKernelResetVk,
|
|
73
|
+
MockPrivateKernelTailVk,
|
|
74
|
+
MockRollupBasePublicVk,
|
|
75
|
+
MockRollupBasePrivateVk,
|
|
76
|
+
MockRollupMergeVk,
|
|
77
|
+
MockRollupRootVk,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/* eslint-disable camelcase */
|
|
81
|
+
|
|
82
|
+
const logger = createDebug('aztec:ivc-test');
|
|
83
|
+
|
|
84
|
+
export function getVkAsFields(vk: {
|
|
85
|
+
keyAsBytes: string;
|
|
86
|
+
keyAsFields: string[];
|
|
87
|
+
}): FixedLengthArray<string, typeof CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS> {
|
|
88
|
+
return vk.keyAsFields as FixedLengthArray<string, typeof CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const MOCK_MAX_COMMITMENTS_PER_TX = 4;
|
|
92
|
+
|
|
93
|
+
function foreignCallHandler(): Promise<ForeignCallOutput[]> {
|
|
94
|
+
throw new Error('Unexpected foreign call');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface WitnessGenResult<PublicInputsType> {
|
|
98
|
+
witness: Uint8Array;
|
|
99
|
+
publicInputs: PublicInputsType;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export async function witnessGenCreatorAppMockCircuit(
|
|
103
|
+
args: AppCreatorInputType,
|
|
104
|
+
): Promise<WitnessGenResult<AppPublicInputs>> {
|
|
105
|
+
const program = new Noir(MockAppCreatorCircuit);
|
|
106
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
107
|
+
return {
|
|
108
|
+
witness,
|
|
109
|
+
publicInputs: returnValue as AppPublicInputs,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export async function witnessGenReaderAppMockCircuit(
|
|
114
|
+
args: AppReaderInputType,
|
|
115
|
+
): Promise<WitnessGenResult<AppPublicInputs>> {
|
|
116
|
+
const program = new Noir(MockAppReaderCircuit);
|
|
117
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
118
|
+
return {
|
|
119
|
+
witness,
|
|
120
|
+
publicInputs: returnValue as AppPublicInputs,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function witnessGenMockPrivateKernelInitCircuit(
|
|
125
|
+
args: MockPrivateKernelInitInputType,
|
|
126
|
+
): Promise<WitnessGenResult<PrivateKernelPublicInputs>> {
|
|
127
|
+
const program = new Noir(MockPrivateKernelInitCircuit);
|
|
128
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
129
|
+
return {
|
|
130
|
+
witness,
|
|
131
|
+
publicInputs: returnValue as PrivateKernelPublicInputs,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export async function witnessGenMockPrivateKernelInnerCircuit(
|
|
136
|
+
args: MockPrivateKernelInnerInputType,
|
|
137
|
+
): Promise<WitnessGenResult<PrivateKernelPublicInputs>> {
|
|
138
|
+
const program = new Noir(MockPrivateKernelInnerCircuit);
|
|
139
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
140
|
+
return {
|
|
141
|
+
witness,
|
|
142
|
+
publicInputs: returnValue as PrivateKernelPublicInputs,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function witnessGenMockPrivateKernelResetCircuit(
|
|
147
|
+
args: MockPrivateKernelResetInputType,
|
|
148
|
+
): Promise<WitnessGenResult<PrivateKernelPublicInputs>> {
|
|
149
|
+
const program = new Noir(MockPrivateKernelResetCircuit);
|
|
150
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
151
|
+
return {
|
|
152
|
+
witness,
|
|
153
|
+
publicInputs: returnValue as PrivateKernelPublicInputs,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export async function witnessGenMockPrivateKernelTailCircuit(
|
|
158
|
+
args: MockPrivateKernelTailInputType,
|
|
159
|
+
): Promise<WitnessGenResult<KernelPublicInputs>> {
|
|
160
|
+
const program = new Noir(MockPrivateKernelTailCircuit);
|
|
161
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
162
|
+
return {
|
|
163
|
+
witness,
|
|
164
|
+
publicInputs: returnValue as KernelPublicInputs,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export async function witnessGenMockPublicBaseCircuit(
|
|
169
|
+
args: MockRollupBasePublicInputType,
|
|
170
|
+
): Promise<WitnessGenResult<RollupPublicInputs>> {
|
|
171
|
+
const program = new Noir(MockRollupBasePublicCircuit);
|
|
172
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
173
|
+
return {
|
|
174
|
+
witness,
|
|
175
|
+
publicInputs: returnValue as RollupPublicInputs,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function witnessGenMockRollupBasePrivateCircuit(
|
|
180
|
+
args: MockRollupBasePrivateInputType,
|
|
181
|
+
): Promise<WitnessGenResult<RollupPublicInputs>> {
|
|
182
|
+
const program = new Noir(MockRollupBasePrivateCircuit);
|
|
183
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
184
|
+
return {
|
|
185
|
+
witness,
|
|
186
|
+
publicInputs: returnValue as RollupPublicInputs,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export async function witnessGenMockRollupMergeCircuit(
|
|
191
|
+
args: MockRollupMergeInputType,
|
|
192
|
+
): Promise<WitnessGenResult<RollupPublicInputs>> {
|
|
193
|
+
const program = new Noir(MockRollupMergeCircuit);
|
|
194
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
195
|
+
return {
|
|
196
|
+
witness,
|
|
197
|
+
publicInputs: returnValue as RollupPublicInputs,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export async function witnessGenMockRollupRootCircuit(
|
|
202
|
+
args: MockRollupRootInputType,
|
|
203
|
+
): Promise<WitnessGenResult<RollupPublicInputs>> {
|
|
204
|
+
const program = new Noir(MockRollupRootCircuit);
|
|
205
|
+
const { witness, returnValue } = await program.execute(args, foreignCallHandler);
|
|
206
|
+
return {
|
|
207
|
+
witness,
|
|
208
|
+
publicInputs: returnValue as RollupPublicInputs,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export async function generate3FunctionTestingIVCStack(): Promise<[string[], Uint8Array[], KernelPublicInputs]> {
|
|
213
|
+
const tx = {
|
|
214
|
+
number_of_calls: '0x1',
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// Witness gen app and kernels
|
|
218
|
+
const appWitnessGenResult = await witnessGenCreatorAppMockCircuit({ commitments_to_create: ['0x1', '0x2'] });
|
|
219
|
+
logger('generated app mock circuit witness');
|
|
220
|
+
|
|
221
|
+
const initWitnessGenResult = await witnessGenMockPrivateKernelInitCircuit({
|
|
222
|
+
app_inputs: appWitnessGenResult.publicInputs,
|
|
223
|
+
tx,
|
|
224
|
+
app_vk: getVkAsFields(MockAppCreatorVk),
|
|
225
|
+
});
|
|
226
|
+
logger('generated mock private kernel init witness');
|
|
227
|
+
|
|
228
|
+
const tailWitnessGenResult = await witnessGenMockPrivateKernelTailCircuit({
|
|
229
|
+
prev_kernel_public_inputs: initWitnessGenResult.publicInputs,
|
|
230
|
+
kernel_vk: getVkAsFields(MockPrivateKernelResetVk),
|
|
231
|
+
});
|
|
232
|
+
logger('generated mock private kernel tail witness');
|
|
233
|
+
|
|
234
|
+
// Create client IVC proof
|
|
235
|
+
const bytecodes = [
|
|
236
|
+
MockAppCreatorCircuit.bytecode,
|
|
237
|
+
MockPrivateKernelInitCircuit.bytecode,
|
|
238
|
+
MockPrivateKernelTailCircuit.bytecode,
|
|
239
|
+
];
|
|
240
|
+
const witnessStack = [appWitnessGenResult.witness, initWitnessGenResult.witness, tailWitnessGenResult.witness];
|
|
241
|
+
|
|
242
|
+
return [bytecodes, witnessStack, tailWitnessGenResult.publicInputs];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export async function generate6FunctionTestingIVCStack(): Promise<[string[], Uint8Array[], KernelPublicInputs]> {
|
|
246
|
+
const tx = {
|
|
247
|
+
number_of_calls: '0x2',
|
|
248
|
+
};
|
|
249
|
+
// Witness gen app and kernels
|
|
250
|
+
const creatorAppWitnessGenResult = await witnessGenCreatorAppMockCircuit({ commitments_to_create: ['0x1', '0x2'] });
|
|
251
|
+
const readerAppWitnessGenResult = await witnessGenReaderAppMockCircuit({ commitments_to_read: ['0x2', '0x0'] });
|
|
252
|
+
|
|
253
|
+
const initWitnessGenResult = await witnessGenMockPrivateKernelInitCircuit({
|
|
254
|
+
app_inputs: creatorAppWitnessGenResult.publicInputs,
|
|
255
|
+
tx,
|
|
256
|
+
app_vk: getVkAsFields(MockAppCreatorVk),
|
|
257
|
+
});
|
|
258
|
+
const innerWitnessGenResult = await witnessGenMockPrivateKernelInnerCircuit({
|
|
259
|
+
prev_kernel_public_inputs: initWitnessGenResult.publicInputs,
|
|
260
|
+
app_inputs: readerAppWitnessGenResult.publicInputs,
|
|
261
|
+
app_vk: getVkAsFields(MockAppReaderVk),
|
|
262
|
+
kernel_vk: getVkAsFields(MockPrivateKernelInitVk),
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const resetWitnessGenResult = await witnessGenMockPrivateKernelResetCircuit({
|
|
266
|
+
prev_kernel_public_inputs: innerWitnessGenResult.publicInputs,
|
|
267
|
+
commitment_read_hints: [
|
|
268
|
+
'0x1', // Reader reads commitment 0x2, which is at index 1 of the created commitments
|
|
269
|
+
MOCK_MAX_COMMITMENTS_PER_TX.toString(), // Pad with no-ops
|
|
270
|
+
MOCK_MAX_COMMITMENTS_PER_TX.toString(),
|
|
271
|
+
MOCK_MAX_COMMITMENTS_PER_TX.toString(),
|
|
272
|
+
],
|
|
273
|
+
kernel_vk: getVkAsFields(MockPrivateKernelInnerVk),
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
const tailWitnessGenResult = await witnessGenMockPrivateKernelTailCircuit({
|
|
277
|
+
prev_kernel_public_inputs: resetWitnessGenResult.publicInputs,
|
|
278
|
+
kernel_vk: getVkAsFields(MockPrivateKernelResetVk),
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Create client IVC proof
|
|
282
|
+
const bytecodes = [
|
|
283
|
+
MockAppCreatorCircuit.bytecode,
|
|
284
|
+
MockPrivateKernelInitCircuit.bytecode,
|
|
285
|
+
MockAppReaderCircuit.bytecode,
|
|
286
|
+
MockPrivateKernelInnerCircuit.bytecode,
|
|
287
|
+
MockPrivateKernelResetCircuit.bytecode,
|
|
288
|
+
MockPrivateKernelTailCircuit.bytecode,
|
|
289
|
+
];
|
|
290
|
+
const witnessStack = [
|
|
291
|
+
creatorAppWitnessGenResult.witness,
|
|
292
|
+
initWitnessGenResult.witness,
|
|
293
|
+
readerAppWitnessGenResult.witness,
|
|
294
|
+
innerWitnessGenResult.witness,
|
|
295
|
+
resetWitnessGenResult.witness,
|
|
296
|
+
tailWitnessGenResult.witness,
|
|
297
|
+
];
|
|
298
|
+
|
|
299
|
+
return [bytecodes, witnessStack, tailWitnessGenResult.publicInputs];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export function mapRecursiveProofToNoir<N extends number>(proof: RecursiveProof<N>): FixedLengthArray<string, N> {
|
|
303
|
+
return proof.proof.map(field => field.toString()) as FixedLengthArray<string, N>;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export function mapAvmProofToNoir(proof: Fr[]): FixedLengthArray<string, typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED> {
|
|
307
|
+
if (proof.length != AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED) {
|
|
308
|
+
throw new Error('Invalid number of AVM proof fields');
|
|
309
|
+
}
|
|
310
|
+
return proof.map(field => field.toString()) as FixedLengthArray<string, typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function mapVerificationKeyToNoir<N extends number>(
|
|
314
|
+
vk: VerificationKeyAsFields,
|
|
315
|
+
len: N,
|
|
316
|
+
): {
|
|
317
|
+
key: FixedLengthArray<string, N>;
|
|
318
|
+
hash: string;
|
|
319
|
+
} {
|
|
320
|
+
if (len !== vk.key.length) {
|
|
321
|
+
throw new Error('Verification key length does not match expected length');
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
key: vk.key.map(field => field.toString()) as FixedLengthArray<string, N>,
|
|
325
|
+
hash: vk.hash.toString(),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export function mapAvmVerificationKeyToNoir(
|
|
330
|
+
vk: Fr[],
|
|
331
|
+
): FixedLengthArray<string, typeof AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED> {
|
|
332
|
+
if (vk.length != AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED) {
|
|
333
|
+
throw new Error('Invalid number of AVM verification key fields');
|
|
334
|
+
}
|
|
335
|
+
return vk.map(field => field.toString()) as FixedLengthArray<
|
|
336
|
+
string,
|
|
337
|
+
typeof AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED
|
|
338
|
+
>;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export function mapAvmPublicInputsToNoir(
|
|
342
|
+
publicInputs: AvmCircuitPublicInputs,
|
|
343
|
+
): FixedLengthArray<string, typeof AVM_V2_PUBLIC_INPUTS_FLATTENED_SIZE> {
|
|
344
|
+
// TODO: Currently the recursive verifier only expects a single public input, the reverted field.
|
|
345
|
+
const serialized = [new Fr(publicInputs.reverted)];
|
|
346
|
+
if (serialized.length != AVM_V2_PUBLIC_INPUTS_FLATTENED_SIZE) {
|
|
347
|
+
throw new Error('Invalid number of AVM public inputs');
|
|
348
|
+
}
|
|
349
|
+
return serialized.map(x => x.toString()) as FixedLengthArray<string, typeof AVM_V2_PUBLIC_INPUTS_FLATTENED_SIZE>;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export async function simulateAvmBulkTesting(
|
|
353
|
+
simTester: PublicTxSimulationTester,
|
|
354
|
+
contractInstance: ContractInstanceWithAddress,
|
|
355
|
+
) {
|
|
356
|
+
const argsField = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x));
|
|
357
|
+
const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x));
|
|
358
|
+
const args = [
|
|
359
|
+
argsField,
|
|
360
|
+
argsU8,
|
|
361
|
+
/*getInstanceForAddress=*/ contractInstance.address.toField(),
|
|
362
|
+
/*expectedDeployer=*/ contractInstance.deployer.toField(),
|
|
363
|
+
/*expectedClassId=*/ contractInstance.currentContractClassId.toField(),
|
|
364
|
+
/*expectedInitializationHash=*/ contractInstance.initializationHash.toField(),
|
|
365
|
+
];
|
|
366
|
+
|
|
367
|
+
return await simTester.simulateTx(
|
|
368
|
+
/*sender=*/ AztecAddress.fromNumber(42),
|
|
369
|
+
/*setupCalls=*/ [],
|
|
370
|
+
/*appCalls=*/ [{ address: contractInstance.address, fnName: 'bulk_testing', args }],
|
|
371
|
+
/*teardownCall=*/ undefined,
|
|
372
|
+
);
|
|
373
|
+
}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"keyAsBytes": "0000000000800000000000000000001700000000000000110000000000000001010000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100e15f90282bad5956c1b1596d3169bbc06011a213ba470d969dcc9aef5ece695171f99111101e072ee1d9a73d8e591d17adaf593ce7109211109ecb3717f3c330ecad0242fe68c8c36eafbafb560d42669f38ce954c2cdf32d8ab5edf7c227cb1b952a9ef2a90ed4e7ab02bd5c3d19db9e1b01a79f8c2d691510d52d0d068f6c086dcad952831a0d2baf73ffc5d49df04d7c98e1245cb58323727e3cccd0337f2b79031de312036d4d448da2555999f40241fb9a14d558f6ed51c657ffbfa2a923c93a8c1ae5f54b8fb0a7074c7c5403bb8b2fadbe07f2da14fb9dee0d928cc22d41736e9eb44f7e682609a457994f66ddc9d24b16122d9c239b81bb050392da2f0258eb107e0e35877dd0060d01994e3969a303887b061f7fb45dcdf171214b20cb3347e378ac650b26f65351c97fdd16afabd010cc22b6085b2cd64815ea2706dc316bd2ae9b3f98a2faa5f30c12c74e987c30c70095bf3ecd8f101f4b8389287408071ea1455dd09671e9f7ae7d84e6bf7b3bcc0e1c45f6b10cd851f33d8e0c4032c3079594eb75a8449d3d5ce8bc3661650d53f9b24d923d8f404cb0bbc91084d709650356d40f0158fd6da81f54eb5fe796a0ca89441369b7c24301f85122f64b2d31c41cc9d73f01152dee744402a1564dbfaf45e02e5635f8ee210b9410320d3c3248010e6aad86ed7bd61215663e8dc2e21824df83098a5fc40752b71f46d1b6c2113a7b97ccc960b6b8fd404534ecb8c5d91876fee2f0bda0579d4b0145e9f6cb53e3e1d0710683c1b414ec571801ce4b6330d258d6ae4f6070192c044425b4beb6ed7b2e2f0f3cf35c17c4f7b23ce40de1d052c6a1c3d66b5047a22ab3d2b9ad8af76effc0e9e4649671287a6cda61bfb420a5c33a5861629b87ac1e4a2e8913fceffd7cdd3981a23743bf277ff1aff85ea40813eb7359e840c2f52ae0b185e9a49c3326062e23e4dc4d0d3eeff65549a51ad0b5e5cb0556cede3407d42bef643ba1cb17ebeaaadda0f9c3e3d089c1cda327efdbea8074a1809b002d8c0a8848e0346ffeb2937cce6ba21f3713869472c1c58bba527de710f9a81f11832a6dcc0f85194df2fb8e4133c125b790edb2bf6b73e1bc86bdd0d13535740c3a9dd2693f5d1cdf119f215d3d1de5dfbf6f69de25990fa8d34279f3cb731e075e4f0f1e68337e24d3d0cb4b180d2b83c5e1703b9e28618098b4e8b235af2a06085fb77a35199a148620afaf228e41b01ef5dac89debae9f4b67495ed7a57911e5e9c73b111b39e5bd47ff81c6b65222df7ce71cfb167b74af2302aa35371622d92e3f6197ed0df3326d4d69f3daa4c2a7ba01794c1451a3cf7d283282e54b24bac0d5fbb831ecd665a3c331ddfcf50d7877461d9ecca7059c7d52cae80da72ffc5e89b02e79f2a3350f07284a1b1d1b858f1789beeebe6f94225a8f10474910d9d3d5b7374a72b56c6efa2edcdc7be87400ea6e330473663a6ab31138119c1521494462a72d64c88ac064c92d1eb43f6fad14119c2c5d6503f1ed92e128501f40bfdae9781fd80003cc3656fdfa8f8884029cf948ac239f93ad49f5874e69255a463e31eeb129e304f2556c33d9d12e74be8d2d66b9a151d19dbeb05988701a1db5d016373c5daf173bc71a7c1a3404eeac129a177b25adb7b81f4c0419c718f065447418eecd0e932b819988af45271fef4389a8c843c75ae5ced9fda5892924a996274144fa265c5d49bb50f998a219611b193b874d3e01181bef7e28b126b1b96b29a58441584ebe6e3c561644f2ef2eb86741e12411f32d9a3d54b2ae248b9c339f65309ca717660b1bfa116e3e6a69f9f483b77ffba1605066fb7bac2d47f9737778f3d40fdd7855389660a57611c7861d8aea48410585817019324a0450f8716810dff987300c3bc10a892b1c1c2637db3f8fecd9d8bb38442cc46810005567f9eb3d3a97098baa0d71c65db2bf83f8a194086a4cca39916b578faf103bcf2cf468d53c71d57b5c0ab31231e12e1ce3a444583203ea04c16ec69eb20c5d6e7a8b0b14d4ed8f51217ae8af4207277f4116e0af5a9268b38a5d34910b187b9371870f579be414054241d418f5689db2f6cbfabe968378fd68e9b280c00964ab30f99cb72cc59d0f621604926cfebfcff535f724f619bb0e7a4853dbdb132b76a71278e567595f3aaf837a72eb0ab515191143e5a3c8bd5875264866282c6b2a0de0a3fefdfc4fb4f3b8381d2c37ccc495848c2887f98bfbaca776ca390000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000218adb86f9736ab61069af15b53b24752d5d631427a9fd2e442a8bc18cf904507199b0ecadbac54fb89a8aa66e92cd4d92e57bab1ca7e9918f5e729107f329679",
|
|
3
|
-
"keyAsFields": [
|
|
4
|
-
"0x0000000000000000000000000000000000000000000000000000000000800000",
|
|
5
|
-
"0x0000000000000000000000000000000000000000000000000000000000000011",
|
|
6
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
7
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
8
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
9
|
-
"0x0000000000000000000000000000000000000000000000000000000000000002",
|
|
10
|
-
"0x0000000000000000000000000000000000000000000000000000000000000003",
|
|
11
|
-
"0x0000000000000000000000000000000000000000000000000000000000000004",
|
|
12
|
-
"0x0000000000000000000000000000000000000000000000000000000000000005",
|
|
13
|
-
"0x0000000000000000000000000000000000000000000000000000000000000006",
|
|
14
|
-
"0x0000000000000000000000000000000000000000000000000000000000000007",
|
|
15
|
-
"0x0000000000000000000000000000000000000000000000000000000000000008",
|
|
16
|
-
"0x0000000000000000000000000000000000000000000000000000000000000009",
|
|
17
|
-
"0x000000000000000000000000000000000000000000000000000000000000000a",
|
|
18
|
-
"0x000000000000000000000000000000000000000000000000000000000000000b",
|
|
19
|
-
"0x000000000000000000000000000000000000000000000000000000000000000c",
|
|
20
|
-
"0x000000000000000000000000000000000000000000000000000000000000000d",
|
|
21
|
-
"0x000000000000000000000000000000000000000000000000000000000000000e",
|
|
22
|
-
"0x000000000000000000000000000000000000000000000000000000000000000f",
|
|
23
|
-
"0x0000000000000000000000000000000000000000000000000000000000000010",
|
|
24
|
-
"0x000000000000000000000000000000bc06011a213ba470d969dcc9aef5ece695",
|
|
25
|
-
"0x00000000000000000000000000000000000e15f90282bad5956c1b1596d3169b",
|
|
26
|
-
"0x000000000000000000000000000000d17adaf593ce7109211109ecb3717f3c33",
|
|
27
|
-
"0x0000000000000000000000000000000000171f99111101e072ee1d9a73d8e591",
|
|
28
|
-
"0x0000000000000000000000000000002669f38ce954c2cdf32d8ab5edf7c227cb",
|
|
29
|
-
"0x00000000000000000000000000000000000ecad0242fe68c8c36eafbafb560d4",
|
|
30
|
-
"0x000000000000000000000000000000db9e1b01a79f8c2d691510d52d0d068f6c",
|
|
31
|
-
"0x00000000000000000000000000000000001b952a9ef2a90ed4e7ab02bd5c3d19",
|
|
32
|
-
"0x000000000000000000000000000000f04d7c98e1245cb58323727e3cccd0337f",
|
|
33
|
-
"0x0000000000000000000000000000000000086dcad952831a0d2baf73ffc5d49d",
|
|
34
|
-
"0x000000000000000000000000000000f40241fb9a14d558f6ed51c657ffbfa2a9",
|
|
35
|
-
"0x00000000000000000000000000000000002b79031de312036d4d448da2555999",
|
|
36
|
-
"0x00000000000000000000000000000003bb8b2fadbe07f2da14fb9dee0d928cc2",
|
|
37
|
-
"0x000000000000000000000000000000000023c93a8c1ae5f54b8fb0a7074c7c54",
|
|
38
|
-
"0x00000000000000000000000000000066ddc9d24b16122d9c239b81bb050392da",
|
|
39
|
-
"0x00000000000000000000000000000000002d41736e9eb44f7e682609a457994f",
|
|
40
|
-
"0x0000000000000000000000000000004e3969a303887b061f7fb45dcdf171214b",
|
|
41
|
-
"0x00000000000000000000000000000000002f0258eb107e0e35877dd0060d0199",
|
|
42
|
-
"0x000000000000000000000000000000dd16afabd010cc22b6085b2cd64815ea27",
|
|
43
|
-
"0x000000000000000000000000000000000020cb3347e378ac650b26f65351c97f",
|
|
44
|
-
"0x000000000000000000000000000000c74e987c30c70095bf3ecd8f101f4b8389",
|
|
45
|
-
"0x000000000000000000000000000000000006dc316bd2ae9b3f98a2faa5f30c12",
|
|
46
|
-
"0x00000000000000000000000000000084e6bf7b3bcc0e1c45f6b10cd851f33d8e",
|
|
47
|
-
"0x0000000000000000000000000000000000287408071ea1455dd09671e9f7ae7d",
|
|
48
|
-
"0x000000000000000000000000000000bc3661650d53f9b24d923d8f404cb0bbc9",
|
|
49
|
-
"0x00000000000000000000000000000000000c4032c3079594eb75a8449d3d5ce8",
|
|
50
|
-
"0x00000000000000000000000000000054eb5fe796a0ca89441369b7c24301f851",
|
|
51
|
-
"0x00000000000000000000000000000000001084d709650356d40f0158fd6da81f",
|
|
52
|
-
"0x0000000000000000000000000000004402a1564dbfaf45e02e5635f8ee210b94",
|
|
53
|
-
"0x000000000000000000000000000000000022f64b2d31c41cc9d73f01152dee74",
|
|
54
|
-
"0x00000000000000000000000000000015663e8dc2e21824df83098a5fc40752b7",
|
|
55
|
-
"0x000000000000000000000000000000000010320d3c3248010e6aad86ed7bd612",
|
|
56
|
-
"0x000000000000000000000000000000404534ecb8c5d91876fee2f0bda0579d4b",
|
|
57
|
-
"0x00000000000000000000000000000000001f46d1b6c2113a7b97ccc960b6b8fd",
|
|
58
|
-
"0x000000000000000000000000000000ec571801ce4b6330d258d6ae4f6070192c",
|
|
59
|
-
"0x00000000000000000000000000000000000145e9f6cb53e3e1d0710683c1b414",
|
|
60
|
-
"0x000000000000000000000000000000c4f7b23ce40de1d052c6a1c3d66b5047a2",
|
|
61
|
-
"0x0000000000000000000000000000000000044425b4beb6ed7b2e2f0f3cf35c17",
|
|
62
|
-
"0x000000000000000000000000000000287a6cda61bfb420a5c33a5861629b87ac",
|
|
63
|
-
"0x00000000000000000000000000000000002ab3d2b9ad8af76effc0e9e4649671",
|
|
64
|
-
"0x000000000000000000000000000000bf277ff1aff85ea40813eb7359e840c2f5",
|
|
65
|
-
"0x00000000000000000000000000000000001e4a2e8913fceffd7cdd3981a23743",
|
|
66
|
-
"0x0000000000000000000000000000000d3eeff65549a51ad0b5e5cb0556cede34",
|
|
67
|
-
"0x00000000000000000000000000000000002ae0b185e9a49c3326062e23e4dc4d",
|
|
68
|
-
"0x000000000000000000000000000000c3e3d089c1cda327efdbea8074a1809b00",
|
|
69
|
-
"0x000000000000000000000000000000000007d42bef643ba1cb17ebeaaadda0f9",
|
|
70
|
-
"0x0000000000000000000000000000001f3713869472c1c58bba527de710f9a81f",
|
|
71
|
-
"0x00000000000000000000000000000000002d8c0a8848e0346ffeb2937cce6ba2",
|
|
72
|
-
"0x00000000000000000000000000000025b790edb2bf6b73e1bc86bdd0d1353574",
|
|
73
|
-
"0x000000000000000000000000000000000011832a6dcc0f85194df2fb8e4133c1",
|
|
74
|
-
"0x000000000000000000000000000000e5dfbf6f69de25990fa8d34279f3cb731e",
|
|
75
|
-
"0x00000000000000000000000000000000000c3a9dd2693f5d1cdf119f215d3d1d",
|
|
76
|
-
"0x0000000000000000000000000000002b83c5e1703b9e28618098b4e8b235af2a",
|
|
77
|
-
"0x0000000000000000000000000000000000075e4f0f1e68337e24d3d0cb4b180d",
|
|
78
|
-
"0x00000000000000000000000000000041b01ef5dac89debae9f4b67495ed7a579",
|
|
79
|
-
"0x000000000000000000000000000000000006085fb77a35199a148620afaf228e",
|
|
80
|
-
"0x0000000000000000000000000000005222df7ce71cfb167b74af2302aa353716",
|
|
81
|
-
"0x000000000000000000000000000000000011e5e9c73b111b39e5bd47ff81c6b6",
|
|
82
|
-
"0x000000000000000000000000000000a4c2a7ba01794c1451a3cf7d283282e54b",
|
|
83
|
-
"0x000000000000000000000000000000000022d92e3f6197ed0df3326d4d69f3da",
|
|
84
|
-
"0x000000000000000000000000000000f50d7877461d9ecca7059c7d52cae80da7",
|
|
85
|
-
"0x000000000000000000000000000000000024bac0d5fbb831ecd665a3c331ddfc",
|
|
86
|
-
"0x0000000000000000000000000000001d1b858f1789beeebe6f94225a8f104749",
|
|
87
|
-
"0x00000000000000000000000000000000002ffc5e89b02e79f2a3350f07284a1b",
|
|
88
|
-
"0x0000000000000000000000000000007be87400ea6e330473663a6ab31138119c",
|
|
89
|
-
"0x000000000000000000000000000000000010d9d3d5b7374a72b56c6efa2edcdc",
|
|
90
|
-
"0x000000000000000000000000000000b43f6fad14119c2c5d6503f1ed92e12850",
|
|
91
|
-
"0x00000000000000000000000000000000001521494462a72d64c88ac064c92d1e",
|
|
92
|
-
"0x0000000000000000000000000000008f8884029cf948ac239f93ad49f5874e69",
|
|
93
|
-
"0x00000000000000000000000000000000001f40bfdae9781fd80003cc3656fdfa",
|
|
94
|
-
"0x000000000000000000000000000000d12e74be8d2d66b9a151d19dbeb0598870",
|
|
95
|
-
"0x0000000000000000000000000000000000255a463e31eeb129e304f2556c33d9",
|
|
96
|
-
"0x0000000000000000000000000000003404eeac129a177b25adb7b81f4c0419c7",
|
|
97
|
-
"0x00000000000000000000000000000000001a1db5d016373c5daf173bc71a7c1a",
|
|
98
|
-
"0x00000000000000000000000000000045271fef4389a8c843c75ae5ced9fda589",
|
|
99
|
-
"0x000000000000000000000000000000000018f065447418eecd0e932b819988af",
|
|
100
|
-
"0x00000000000000000000000000000098a219611b193b874d3e01181bef7e28b1",
|
|
101
|
-
"0x00000000000000000000000000000000002924a996274144fa265c5d49bb50f9",
|
|
102
|
-
"0x00000000000000000000000000000044f2ef2eb86741e12411f32d9a3d54b2ae",
|
|
103
|
-
"0x000000000000000000000000000000000026b1b96b29a58441584ebe6e3c5616",
|
|
104
|
-
"0x0000000000000000000000000000006e3e6a69f9f483b77ffba1605066fb7bac",
|
|
105
|
-
"0x0000000000000000000000000000000000248b9c339f65309ca717660b1bfa11",
|
|
106
|
-
"0x000000000000000000000000000000a57611c7861d8aea48410585817019324a",
|
|
107
|
-
"0x00000000000000000000000000000000002d47f9737778f3d40fdd7855389660",
|
|
108
|
-
"0x0000000000000000000000000000002b1c1c2637db3f8fecd9d8bb38442cc468",
|
|
109
|
-
"0x00000000000000000000000000000000000450f8716810dff987300c3bc10a89",
|
|
110
|
-
"0x0000000000000000000000000000005db2bf83f8a194086a4cca39916b578faf",
|
|
111
|
-
"0x000000000000000000000000000000000010005567f9eb3d3a97098baa0d71c6",
|
|
112
|
-
"0x00000000000000000000000000000031e12e1ce3a444583203ea04c16ec69eb2",
|
|
113
|
-
"0x0000000000000000000000000000000000103bcf2cf468d53c71d57b5c0ab312",
|
|
114
|
-
"0x0000000000000000000000000000004207277f4116e0af5a9268b38a5d34910b",
|
|
115
|
-
"0x00000000000000000000000000000000000c5d6e7a8b0b14d4ed8f51217ae8af",
|
|
116
|
-
"0x000000000000000000000000000000f5689db2f6cbfabe968378fd68e9b280c0",
|
|
117
|
-
"0x0000000000000000000000000000000000187b9371870f579be414054241d418",
|
|
118
|
-
"0x0000000000000000000000000000006cfebfcff535f724f619bb0e7a4853dbdb",
|
|
119
|
-
"0x00000000000000000000000000000000000964ab30f99cb72cc59d0f62160492",
|
|
120
|
-
"0x000000000000000000000000000000eb0ab515191143e5a3c8bd587526486628",
|
|
121
|
-
"0x0000000000000000000000000000000000132b76a71278e567595f3aaf837a72",
|
|
122
|
-
"0x0000000000000000000000000000002c37ccc495848c2887f98bfbaca776ca39",
|
|
123
|
-
"0x00000000000000000000000000000000002c6b2a0de0a3fefdfc4fb4f3b8381d",
|
|
124
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
125
|
-
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
126
|
-
"0x0000000000000000000000000000000000000000000000000000000000000002",
|
|
127
|
-
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
128
|
-
"0x00000000000000000000000000000052d5d631427a9fd2e442a8bc18cf904507",
|
|
129
|
-
"0x000000000000000000000000000000000018adb86f9736ab61069af15b53b247",
|
|
130
|
-
"0x000000000000000000000000000000d92e57bab1ca7e9918f5e729107f329679",
|
|
131
|
-
"0x0000000000000000000000000000000000199b0ecadbac54fb89a8aa66e92cd4"
|
|
132
|
-
]
|
|
133
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"noir_version":"1.0.0-beta.3+0000000000000000000000000000000000000000","hash":"5589014459541020790","abi":{"parameters":[{"name":"verification_key","type":{"kind":"array","length":86,"type":{"kind":"field"}},"visibility":"private"},{"name":"proof","type":{"kind":"array","length":4154,"type":{"kind":"field"}},"visibility":"private"},{"name":"pub_cols_flattened","type":{"kind":"array","length":2956,"type":{"kind":"field"}},"visibility":"private"}],"return_type":{"abi_type":{"kind":"integer","sign":"unsigned","width":8},"visibility":"public"},"error_types":{}},"bytecode":"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","debug_symbols":"tY/LCoMwFET/5a6zMLVqya+UInlKICQhj0IJ+fdGUSp07e6embkDU0BIlpdZW+UikGcB4zhN2tlGBbpNip7alWKiIQHppw6BtALI0D0qAqWNbPe9or8oHvthz+IJ/8K3sb4Q4AvbG7CgjdHLfF7U5DcNmjIjd1TZ8pObPv5wjn8fHJciB7k2bV6r/wI=","file_map":{"26":{"source":"pub mod hash;\npub mod aes128;\npub mod array;\npub mod slice;\npub mod ecdsa_secp256k1;\npub mod ecdsa_secp256r1;\npub mod embedded_curve_ops;\npub mod field;\npub mod collections;\npub mod compat;\npub mod convert;\npub mod option;\npub mod string;\npub mod test;\npub mod cmp;\npub mod ops;\npub mod default;\npub mod prelude;\npub mod runtime;\npub mod meta;\npub mod append;\npub mod mem;\npub mod panic;\npub mod hint;\n\nuse convert::AsPrimitive;\n\n// Oracle calls are required to be wrapped in an unconstrained function\n// Thus, the only argument to the `println` oracle is expected to always be an ident\n#[oracle(print)]\nunconstrained fn print_oracle<T>(with_newline: bool, input: T) {}\n\nunconstrained fn print_unconstrained<T>(with_newline: bool, input: T) {\n print_oracle(with_newline, input);\n}\n\npub fn println<T>(input: T) {\n // Safety: a print statement cannot be constrained\n unsafe {\n print_unconstrained(true, input);\n }\n}\n\npub fn print<T>(input: T) {\n // Safety: a print statement cannot be constrained\n unsafe {\n print_unconstrained(false, input);\n }\n}\n\npub fn verify_proof<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n) {\n verify_proof_internal(verification_key, proof, public_inputs, key_hash, 0);\n}\n\npub fn verify_proof_with_type<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n proof_type: u32,\n) {\n if !crate::runtime::is_unconstrained() {\n crate::assert_constant(proof_type);\n }\n verify_proof_internal(verification_key, proof, public_inputs, key_hash, proof_type);\n}\n\n#[foreign(recursive_aggregation)]\nfn verify_proof_internal<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n proof_type: u32,\n) {}\n\n// Asserts that the given value is known at compile-time.\n// Useful for debugging for-loop bounds.\n#[builtin(assert_constant)]\npub fn assert_constant<T>(x: T) {}\n\n// Asserts that the given value is both true and known at compile-time\n#[builtin(static_assert)]\npub fn static_assert<let N: u32>(predicate: bool, message: str<N>) {}\n\npub fn wrapping_add<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() + y.as_())\n}\n\npub fn wrapping_sub<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n AsPrimitive::as_(x.as_() + 340282366920938463463374607431768211456 - y.as_())\n}\n\npub fn wrapping_mul<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() * y.as_())\n}\n\n#[builtin(as_witness)]\npub fn as_witness(x: Field) {}\n\nmod tests {\n use super::wrapping_mul;\n\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n super::static_assert(1 == 2, \"custom message\");\n }\n\n #[test(should_fail)]\n fn test_wrapping_mul() {\n // This currently fails.\n // See: https://github.com/noir-lang/noir/issues/7528\n let zero: u128 = 0;\n let one: u128 = 1;\n let two_pow_64: u128 = 0x10000000000000000;\n let u128_max: u128 = 0xffffffffffffffffffffffffffffffff;\n\n // 1*0==0\n assert_eq(zero, wrapping_mul(zero, one));\n\n // 0*1==0\n assert_eq(zero, wrapping_mul(one, zero));\n\n // 1*1==1\n assert_eq(one, wrapping_mul(one, one));\n\n // 0 * ( 1 << 64 ) == 0\n assert_eq(zero, wrapping_mul(zero, two_pow_64));\n\n // ( 1 << 64 ) * 0 == 0\n assert_eq(zero, wrapping_mul(two_pow_64, zero));\n\n // 1 * ( 1 << 64 ) == 1 << 64\n assert_eq(two_pow_64, wrapping_mul(two_pow_64, one));\n\n // ( 1 << 64 ) * 1 == 1 << 64\n assert_eq(two_pow_64, wrapping_mul(one, two_pow_64));\n\n // ( 1 << 64 ) * ( 1 << 64 ) == 1 << 64\n assert_eq(zero, wrapping_mul(two_pow_64, two_pow_64));\n // -1 * -1 == 1\n assert_eq(one, wrapping_mul(u128_max, u128_max));\n }\n}\n","path":"std/lib.nr"},"54":{"source":"use dep::types::constants::{\n AVM_PROOF_LENGTH_IN_FIELDS, AVM_PUBLIC_INPUTS_FLATTENED_SIZE,\n AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS, PROOF_TYPE_AVM,\n};\n\nfn main(\n verification_key: [Field; AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS],\n proof: [Field; AVM_PROOF_LENGTH_IN_FIELDS],\n pub_cols_flattened: [Field; AVM_PUBLIC_INPUTS_FLATTENED_SIZE],\n) -> pub u8 {\n std::verify_proof_with_type(\n verification_key,\n proof,\n pub_cols_flattened,\n 0,\n PROOF_TYPE_AVM,\n );\n 1 // Dummy value to return for the mock kernel as void function creates some pain.\n}\n","path":"/home/aztec-dev/aztec-packages/noir-projects/mock-protocol-circuits/crates/mock-public-base/src/main.nr"}},"names":["main"],"brillig_names":[]}
|
|
File without changes
|
|
File without changes
|