Skip to content

Commit

Permalink
feat: hashing output of serialize() in noir + more tests (#4365)
Browse files Browse the repository at this point in the history
1. Partially fixes #3595,
2. fixes PrivateCircuitPublicInputs serialization,
3. more tests of serialization lengths,
4. updated test data.
  • Loading branch information
benesjan authored Feb 2, 2024
1 parent 013891f commit 5a71bb9
Show file tree
Hide file tree
Showing 31 changed files with 958 additions and 830 deletions.
5 changes: 3 additions & 2 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ library Constants {
uint256 internal constant MAX_NOTES_PER_PAGE = 10;
uint256 internal constant VIEW_NOTE_ORACLE_RETURN_LENGTH = 212;
uint256 internal constant CALL_CONTEXT_LENGTH = 8;
uint256 internal constant GLOBAL_VARIABLES_LENGTH = 4;
uint256 internal constant PARTIAL_STATE_REFERENCE_LENGTH = 8;
uint256 internal constant STATE_REFERENCE_LENGTH = 10;
uint256 internal constant HEADER_LENGTH = 18;
uint256 internal constant FUNCTION_DATA_LENGTH = 4;
uint256 internal constant CONTRACT_DEPLOYMENT_DATA_LENGTH = 6;
Expand All @@ -79,8 +82,6 @@ library Constants {
uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 201;
uint256 internal constant GET_NOTES_ORACLE_RETURN_LENGTH = 674;
uint256 internal constant CALL_PRIVATE_FUNCTION_RETURN_SIZE = 210;
uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 98;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 188;
uint256 internal constant COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 2048;
uint256 internal constant NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048;
uint256 internal constant PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 1024;
Expand Down
126 changes: 62 additions & 64 deletions yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,52 +1,50 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`abis Computes a callstack item hash 1`] = `"0x06dc9c35290e1868f41fc9f45bca49482bf5d5c000c789d6c74e53bce0f686f8"`;
exports[`abis Computes a callstack item hash 1`] = `"0x037cb5ba672a7c461e23cf22ae618757ab4f1a912f3fdc93b2b2800cfe57bb91"`;

exports[`abis Computes a callstack item request hash 1`] = `"0x05c5d32c38f3de19dbfa92e25746e1db1a887d5b02b79dd915c0f50e9fc51dcd"`;
exports[`abis Computes a callstack item request hash 1`] = `"0x2c36008a759d932a3a1986429aa295e2c2d4e62c33197a7d259750d29347bf30"`;

exports[`abis Computes an empty nullifier hash 1`] = `"0x066e6cdc4a6ba5e4781deda650b0be6c12f975f064fc38df72c1060716759b17"`;

exports[`abis Computes an empty public inputs hash 1`] = `"0x2e2b79cee62cb99e9163a58daa37da8099a9eef49353d0cbbf85093dca66eca7"`;

exports[`abis Computes an empty sideeffect hash 1`] = `"0x27b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed"`;

exports[`abis compute private call stack item hash 1`] = `
Fr {
"asBigInt": 12187345511405217717040217531423286257305914329376428594135414078733109256018n,
"asBigInt": 20809484660315254497535468009354600907499263083154533860853878665971818104219n,
"asBuffer": {
"data": [
26,
241,
203,
9,
80,
135,
163,
233,
54,
161,
69,
247,
77,
223,
148,
99,
177,
7,
65,
132,
142,
175,
255,
49,
18,
190,
219,
83,
245,
46,
1,
192,
60,
242,
95,
82,
113,
243,
178,
218,
79,
199,
55,
206,
59,
194,
234,
24,
158,
215,
200,
157,
95,
167,
67,
42,
204,
172,
237,
37,
5,
155,
],
"type": "Buffer",
},
Expand All @@ -55,41 +53,41 @@ Fr {

exports[`abis compute public call stack item hash 1`] = `
Fr {
"asBigInt": 13521975876243055846900626787876592989336331137171592962170740576377717759471n,
"asBigInt": 4942803204430729321299247114280769628204291639882373728884145897482860239103n,
"asBuffer": {
"data": [
29,
229,
42,
200,
229,
101,
73,
10,
237,
135,
8,
121,
161,
111,
135,
149,
117,
252,
244,
207,
1,
155,
22,
194,
235,
62,
7,
199,
170,
23,
173,
20,
73,
240,
78,
59,
30,
113,
209,
176,
171,
136,
151,
117,
250,
42,
35,
248,
145,
157,
239,
186,
162,
159,
250,
242,
152,
210,
24,
255,
],
"type": "Buffer",
},
Expand Down
9 changes: 0 additions & 9 deletions yarn-project/circuits.js/src/abis/abis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
FunctionSelector,
NewContractData,
PublicCallStackItem,
PublicCircuitPublicInputs,
SideEffect,
SideEffectLinkedToNoteHash,
} from '../index.js';
Expand All @@ -32,7 +31,6 @@ import {
computePublicCallStackItemHash,
computePublicDataTreeLeafSlot,
computePublicDataTreeValue,
computePublicInputsHash,
computeSecretMessageHash,
computeTxHash,
computeUniqueCommitment,
Expand Down Expand Up @@ -190,13 +188,6 @@ describe('abis', () => {
expect(emptyHash).toMatchSnapshot();
});

it('Computes an empty public inputs hash ', () => {
const publicInputs = PublicCircuitPublicInputs.empty();
const emptyHash = computePublicInputsHash(publicInputs);

expect(Fr.fromBuffer(emptyHash).toString()).toMatchSnapshot();
});

it('Computes a callstack item request hash', () => {
const callStack = PublicCallStackItem.empty();

Expand Down
107 changes: 3 additions & 104 deletions yarn-project/circuits.js/src/abis/abis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,14 @@ import { boolToBuffer, numToUInt8, numToUInt16BE, numToUInt32BE } from '@aztec/f
import { Buffer } from 'buffer';
import chunk from 'lodash.chunk';

import {
FUNCTION_SELECTOR_NUM_BYTES,
FUNCTION_TREE_HEIGHT,
GeneratorIndex,
PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,
PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,
} from '../constants.gen.js';
import { FUNCTION_SELECTOR_NUM_BYTES, FUNCTION_TREE_HEIGHT, GeneratorIndex } from '../constants.gen.js';
import { MerkleTreeCalculator } from '../merkle/merkle_tree_calculator.js';
import {
CallContext,
ContractDeploymentData,
ContractStorageRead,
ContractStorageUpdateRequest,
FunctionData,
FunctionLeafPreimage,
NewContractData,
PrivateCallStackItem,
PrivateCircuitPublicInputs,
PublicCallStackItem,
PublicCircuitPublicInputs,
SideEffect,
Expand Down Expand Up @@ -356,60 +346,6 @@ function computeContractDeploymentDataHash(data: ContractDeploymentData): Fr {
);
}

function computeCallContextHash(input: CallContext) {
return pedersenHash(
[
input.msgSender.toBuffer(),
input.storageContractAddress.toBuffer(),
input.portalContractAddress.toBuffer(),
input.functionSelector.toBuffer(),
boolToBuffer(input.isDelegateCall, 32),
boolToBuffer(input.isStaticCall, 32),
boolToBuffer(input.isContractDeployment, 32),
numToUInt32BE(input.startSideEffectCounter, 32),
],
GeneratorIndex.CALL_CONTEXT,
);
}

function computePrivateInputsHash(input: PrivateCircuitPublicInputs) {
const toHash = [
computeCallContextHash(input.callContext),
input.argsHash.toBuffer(),
...input.returnValues.map(fr => fr.toBuffer()),
...input.readRequests
.map(rr => rr.toFields())
.flat()
.map(fr => fr.toBuffer()),
...input.newCommitments
.map(n => n.toFields())
.flat()
.map(fr => fr.toBuffer()),
...input.newNullifiers
.map(n => n.toFields())
.flat()
.map(fr => fr.toBuffer()),
...input.privateCallStackHashes.map(fr => fr.toBuffer()),
...input.publicCallStackHashes.map(fr => fr.toBuffer()),
...input.newL2ToL1Msgs.map(fr => fr.toBuffer()),
input.endSideEffectCounter.toBuffer(),
...input.encryptedLogsHash.map(fr => fr.toBuffer()),
...input.unencryptedLogsHash.map(fr => fr.toBuffer()),
input.encryptedLogPreimagesLength.toBuffer(),
input.unencryptedLogPreimagesLength.toBuffer(),
...(input.historicalHeader.toFields().map(fr => fr.toBuffer()) as Buffer[]),
computeContractDeploymentDataHash(input.contractDeploymentData).toBuffer(),
input.chainId.toBuffer(),
input.version.toBuffer(),
];
if (toHash.length != PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH) {
throw new Error(
`Incorrect number of input fields when hashing PrivateCircuitPublicInputs ${toHash.length}, ${PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH}`,
);
}
return pedersenHash(toHash, GeneratorIndex.PRIVATE_CIRCUIT_PUBLIC_INPUTS);
}

/**
* Computes a call stack item hash.
* @param callStackItem - The call stack item.
Expand All @@ -421,24 +357,13 @@ export function computePrivateCallStackItemHash(callStackItem: PrivateCallStackI
[
callStackItem.contractAddress.toBuffer(),
computeFunctionDataHash(callStackItem.functionData).toBuffer(),
computePrivateInputsHash(callStackItem.publicInputs),
callStackItem.publicInputs.hash().toBuffer(),
],
GeneratorIndex.CALL_STACK_ITEM,
),
);
}

function computeContractStorageUpdateRequestHash(input: ContractStorageUpdateRequest) {
return pedersenHash(
[input.storageSlot.toBuffer(), input.oldValue.toBuffer(), input.newValue.toBuffer()],
GeneratorIndex.PUBLIC_DATA_UPDATE_REQUEST,
);
}

function computeContractStorageReadsHash(input: ContractStorageRead) {
return pedersenHash([input.storageSlot.toBuffer(), input.currentValue.toBuffer()], GeneratorIndex.PUBLIC_DATA_READ);
}

export function computeCommitmentsHash(input: SideEffect) {
return pedersenHash([input.value.toBuffer(), input.counter.toBuffer()], GeneratorIndex.SIDE_EFFECT);
}
Expand All @@ -450,28 +375,6 @@ export function computeNullifierHash(input: SideEffectLinkedToNoteHash) {
);
}

export function computePublicInputsHash(input: PublicCircuitPublicInputs) {
const toHash = [
computeCallContextHash(input.callContext),
input.argsHash.toBuffer(),
...input.returnValues.map(fr => fr.toBuffer()),
...input.contractStorageUpdateRequests.map(computeContractStorageUpdateRequestHash),
...input.contractStorageReads.map(computeContractStorageReadsHash),
...input.publicCallStackHashes.map(fr => fr.toBuffer()),
...input.newCommitments.map(computeCommitmentsHash),
...input.newNullifiers.map(computeNullifierHash),
...input.newL2ToL1Msgs.map(fr => fr.toBuffer()),
...input.unencryptedLogsHash.map(fr => fr.toBuffer()),
input.unencryptedLogPreimagesLength.toBuffer(),
...input.historicalHeader.toFields().map(fr => fr.toBuffer()),
input.proverAddress.toBuffer(),
];
if (toHash.length != PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH) {
throw new Error('Incorrect number of input fields when hashing PublicCircuitPublicInputs');
}
return pedersenHash(toHash, GeneratorIndex.PUBLIC_CIRCUIT_PUBLIC_INPUTS);
}

/**
* Computes a call stack item hash.
* @param callStackItem - The call stack item.
Expand All @@ -492,11 +395,7 @@ export function computePublicCallStackItemHash({

return Fr.fromBuffer(
pedersenHash(
[
contractAddress.toBuffer(),
computeFunctionDataHash(functionData).toBuffer(),
computePublicInputsHash(publicInputs),
],
[contractAddress.toBuffer(), computeFunctionDataHash(functionData).toBuffer(), publicInputs.hash().toBuffer()],
GeneratorIndex.CALL_STACK_ITEM,
),
);
Expand Down
5 changes: 3 additions & 2 deletions yarn-project/circuits.js/src/constants.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ export const GET_NOTE_ORACLE_RETURN_LENGTH = 23;
export const MAX_NOTES_PER_PAGE = 10;
export const VIEW_NOTE_ORACLE_RETURN_LENGTH = 212;
export const CALL_CONTEXT_LENGTH = 8;
export const GLOBAL_VARIABLES_LENGTH = 4;
export const PARTIAL_STATE_REFERENCE_LENGTH = 8;
export const STATE_REFERENCE_LENGTH = 10;
export const HEADER_LENGTH = 18;
export const FUNCTION_DATA_LENGTH = 4;
export const CONTRACT_DEPLOYMENT_DATA_LENGTH = 6;
Expand All @@ -65,8 +68,6 @@ export const CONTRACT_STORAGE_READ_LENGTH = 2;
export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 201;
export const GET_NOTES_ORACLE_RETURN_LENGTH = 674;
export const CALL_PRIVATE_FUNCTION_RETURN_SIZE = 210;
export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 98;
export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 188;
export const COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 2048;
export const NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048;
export const PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 1024;
Expand Down
Loading

0 comments on commit 5a71bb9

Please sign in to comment.