Skip to content

Commit

Permalink
feat: hashing output of serialize() in noir
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Feb 1, 2024
1 parent 39f73f5 commit 9701a67
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 119 deletions.
1 change: 0 additions & 1 deletion l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,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;
Expand Down
64 changes: 31 additions & 33 deletions yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// 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`] = `
Expand Down Expand Up @@ -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
11 changes: 1 addition & 10 deletions yarn-project/circuits.js/src/abis/abis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import {
FunctionSelector,
NewContractData,
PublicCallStackItem,
PublicCircuitPublicInputs,
SideEffect,
SideEffectLinkedToNoteHash,
SideEffectLinkedToNoteHash
} from '../index.js';
import {
makeAztecAddress,
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
44 changes: 4 additions & 40 deletions yarn-project/circuits.js/src/abis/abis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address';
import { padArrayEnd } from '@aztec/foundation/collection';
import { keccak, pedersenHash, pedersenHashBuffer } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { boolToBuffer, numToUInt8, numToUInt16BE, numToUInt32BE } from '@aztec/foundation/serialize';
import { boolToBuffer, numToUInt16BE, numToUInt32BE, numToUInt8 } from '@aztec/foundation/serialize';

import { Buffer } from 'buffer';
import chunk from 'lodash.chunk';
Expand All @@ -11,15 +11,12 @@ import {
FUNCTION_SELECTOR_NUM_BYTES,
FUNCTION_TREE_HEIGHT,
GeneratorIndex,
PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,
PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,
PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH
} from '../constants.gen.js';
import { MerkleTreeCalculator } from '../merkle/merkle_tree_calculator.js';
import {
CallContext,
ContractDeploymentData,
ContractStorageRead,
ContractStorageUpdateRequest,
FunctionData,
FunctionLeafPreimage,
NewContractData,
Expand All @@ -31,7 +28,7 @@ import {
SideEffectLinkedToNoteHash,
TxContext,
TxRequest,
VerificationKey,
VerificationKey
} from '../structs/index.js';

/**
Expand Down Expand Up @@ -428,17 +425,6 @@ export function computePrivateCallStackItemHash(callStackItem: PrivateCallStackI
);
}

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 +436,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 @@ -495,7 +459,7 @@ export function computePublicCallStackItemHash({
[
contractAddress.toBuffer(),
computeFunctionDataHash(functionData).toBuffer(),
computePublicInputsHash(publicInputs),
publicInputs.hash().toBuffer(),
],
GeneratorIndex.CALL_STACK_ITEM,
),
Expand Down
1 change: 0 additions & 1 deletion yarn-project/circuits.js/src/constants.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,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;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PublicCircuitPublicInputs hash matches snapshot 1`] = `
Fr {
"asBigInt": 10987106036606499987406426170447920941391129891158672246363150499235953526428n,
"asBuffer": {
"data": [
24,
74,
123,
76,
228,
113,
134,
151,
63,
27,
17,
70,
189,
227,
135,
146,
250,
51,
192,
79,
251,
233,
86,
238,
0,
176,
100,
200,
210,
134,
70,
156,
],
"type": "Buffer",
},
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ describe('PublicCircuitPublicInputs', () => {
const fields = target.toFields();
expect(fields.length).toBe(PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH);
});

it('hash matches snapshot', () => {
const target = makePublicCircuitPublicInputs(327);
const hash = target.hash();
expect(hash).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { makeTuple } from '@aztec/foundation/array';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { isArrayEmpty } from '@aztec/foundation/collection';
import { pedersenHash } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { FieldReader, Tuple, serializeToBuffer, serializeToFieldArray } from '@aztec/foundation/serialize';
import { FieldsOf } from '@aztec/foundation/types';

import {
GeneratorIndex,
MAX_NEW_COMMITMENTS_PER_CALL,
MAX_NEW_L2_TO_L1_MSGS_PER_CALL,
MAX_NEW_NULLIFIERS_PER_CALL,
Expand Down Expand Up @@ -212,4 +214,13 @@ export class PublicCircuitPublicInputs {
proverAddress,
);
}

hash(): Fr {
return Fr.fromBuffer(
pedersenHash(
this.toFields().map(field => field.toBuffer()),
GeneratorIndex.PUBLIC_CIRCUIT_PUBLIC_INPUTS,
),
);
}
}
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_token_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ describe('e2e_token_contract', () => {

describe('Minting', () => {
describe('Public', () => {
it('as minter', async () => {
it.only('as minter', async () => {
const amount = 10000n;
const tx = asset.methods.mint_public(accounts[0].address, amount).send();
const receipt = await tx.wait();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::constants::{
NUM_FIELDS_PER_SHA256,
RETURN_VALUES_LENGTH,
GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,
PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,
PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,
};
use crate::{
Expand All @@ -21,6 +20,7 @@ use crate::{
storage_read::StorageRead,
storage_update_request::StorageUpdateRequest,
},
hash::pedersen_hash,
header::Header,
};

Expand Down Expand Up @@ -53,37 +53,6 @@ struct PublicCircuitPublicInputs{
}

impl PublicCircuitPublicInputs{
fn hash(self) -> Field {
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) have mercy por favor
let mut inputs: BoundedVec<Field, PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH> = BoundedVec::new(0);
inputs.push(self.call_context.hash());
inputs.push(self.args_hash);
inputs.extend_from_array(self.return_values);
for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {
inputs.push(self.contract_storage_update_requests[i].hash());
}
for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {
inputs.push(self.contract_storage_reads[i].hash());
}
inputs.extend_from_array(self.public_call_stack_hashes);

for i in 0..MAX_NEW_COMMITMENTS_PER_CALL{
inputs.push(self.new_commitments[i].hash());
}
for i in 0..MAX_NEW_NULLIFIERS_PER_CALL{
inputs.push(self.new_nullifiers[i].hash());
}
inputs.extend_from_array(self.new_l2_to_l1_msgs);
inputs.extend_from_array(self.unencrypted_logs_hash);
inputs.push(self.unencrypted_log_preimages_length);
inputs.extend_from_array(self.historical_header.serialize());
inputs.push(self.prover_address.to_field());

assert_eq(inputs.len(), PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, "Incorrect number of input fields when hashing PublicCircuitPublicInputs");

dep::std::hash::pedersen_hash_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)
}

pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {
let mut fields: BoundedVec<Field, PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH> = BoundedVec::new(0);
fields.extend_from_array(self.call_context.serialize());
Expand All @@ -110,4 +79,8 @@ impl PublicCircuitPublicInputs{
fields.push(self.prover_address.to_field());
fields.storage
}

fn hash(self) -> Field {
pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ global CONTRACT_STORAGE_READ_LENGTH: Field = 2;
global PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 201;
global GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674;
global CALL_PRIVATE_FUNCTION_RETURN_SIZE: Field = 210;
global PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 98;
global PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 188;
global COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;
global NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;
Expand Down

0 comments on commit 9701a67

Please sign in to comment.