From f6fc7f20dfe94c7be9d791d369750234b94c1bbd Mon Sep 17 00:00:00 2001 From: Dan Lee <142251406+dan-aztec@users.noreply.github.com> Date: Thu, 5 Oct 2023 09:24:41 -0700 Subject: [PATCH 1/8] chore: move { Fr } imports to foundation/fields (#2712) help avoid any possible import errors (like circular import) --- .../aztec.js/src/account/contract/ecdsa_account_contract.ts | 2 +- .../aztec.js/src/account/contract/schnorr_account_contract.ts | 2 +- .../src/account/contract/single_key_account_contract.ts | 3 ++- yarn-project/aztec.js/src/account/interface.ts | 2 +- yarn-project/aztec.js/src/account/manager/index.ts | 3 ++- yarn-project/aztec.js/src/sandbox/index.ts | 2 +- .../circuits.js/src/structs/kernel/previous_kernel_data.ts | 2 +- yarn-project/circuits.js/src/structs/kernel/private_kernel.ts | 2 +- yarn-project/circuits.js/src/types/partial_address.ts | 2 +- yarn-project/cli/src/encoding.ts | 2 +- yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts | 2 +- .../end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts | 2 +- yarn-project/end-to-end/src/e2e_ordering.test.ts | 3 ++- yarn-project/end-to-end/src/e2e_private_airdrop.test.ts | 3 ++- .../end-to-end/src/e2e_public_cross_chain_messaging.test.ts | 2 +- .../end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts | 2 +- .../src/global_variable_builder/global_builder.ts | 3 ++- yarn-project/types/src/auth_witness.ts | 3 ++- 18 files changed, 24 insertions(+), 18 deletions(-) diff --git a/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts b/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts index 3db403239a1..3d057db434f 100644 --- a/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts @@ -1,6 +1,6 @@ -import { Fr } from '@aztec/circuits.js'; import { Ecdsa } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/foundation/fields'; import { AuthWitness, CompleteAddress } from '@aztec/types'; import EcdsaAccountContractAbi from '../../abis/ecdsa_account_contract.json' assert { type: 'json' }; diff --git a/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts b/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts index 3b0f8728649..d185a5a70c4 100644 --- a/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts @@ -1,6 +1,6 @@ -import { Fr } from '@aztec/circuits.js'; import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/foundation/fields'; import { AuthWitness, CompleteAddress, GrumpkinPrivateKey } from '@aztec/types'; import SchnorrAccountContractAbi from '../../abis/schnorr_account_contract.json' assert { type: 'json' }; diff --git a/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts b/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts index d7bda8ce91e..5b8f8c9c199 100644 --- a/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts @@ -1,6 +1,7 @@ -import { Fr, PartialAddress } from '@aztec/circuits.js'; +import { PartialAddress } from '@aztec/circuits.js'; import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/foundation/fields'; import { AuthWitness, CompleteAddress, GrumpkinPrivateKey } from '@aztec/types'; import SchnorrSingleKeyAccountContractAbi from '../../abis/schnorr_single_key_account_contract.json' assert { type: 'json' }; diff --git a/yarn-project/aztec.js/src/account/interface.ts b/yarn-project/aztec.js/src/account/interface.ts index 03f74533008..c9926ff1053 100644 --- a/yarn-project/aztec.js/src/account/interface.ts +++ b/yarn-project/aztec.js/src/account/interface.ts @@ -1,4 +1,4 @@ -import { Fr } from '@aztec/circuits.js'; +import { Fr } from '@aztec/foundation/fields'; import { AuthWitness, CompleteAddress, FunctionCall, TxExecutionRequest } from '@aztec/types'; // docs:start:account-interface diff --git a/yarn-project/aztec.js/src/account/manager/index.ts b/yarn-project/aztec.js/src/account/manager/index.ts index f4c4255e56a..f82aafdb3fa 100644 --- a/yarn-project/aztec.js/src/account/manager/index.ts +++ b/yarn-project/aztec.js/src/account/manager/index.ts @@ -1,4 +1,5 @@ -import { Fr, PublicKey, getContractDeploymentInfo } from '@aztec/circuits.js'; +import { PublicKey, getContractDeploymentInfo } from '@aztec/circuits.js'; +import { Fr } from '@aztec/foundation/fields'; import { CompleteAddress, GrumpkinPrivateKey, PXE } from '@aztec/types'; import { AccountWallet, ContractDeployer, DeployMethod, WaitOpts, generatePublicKey } from '../../index.js'; diff --git a/yarn-project/aztec.js/src/sandbox/index.ts b/yarn-project/aztec.js/src/sandbox/index.ts index 73623f82798..a6494cd05d9 100644 --- a/yarn-project/aztec.js/src/sandbox/index.ts +++ b/yarn-project/aztec.js/src/sandbox/index.ts @@ -1,4 +1,4 @@ -import { Fr, GrumpkinScalar } from '@aztec/circuits.js'; +import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { sleep } from '@aztec/foundation/sleep'; import zip from 'lodash.zip'; diff --git a/yarn-project/circuits.js/src/structs/kernel/previous_kernel_data.ts b/yarn-project/circuits.js/src/structs/kernel/previous_kernel_data.ts index 0fb608900e4..8db9eb5be31 100644 --- a/yarn-project/circuits.js/src/structs/kernel/previous_kernel_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/previous_kernel_data.ts @@ -1,9 +1,9 @@ +import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple } from '@aztec/foundation/serialize'; import { privateKernelDummyPreviousKernel } from '../../cbind/circuits.gen.js'; import { CircuitsWasm, VK_TREE_HEIGHT, makeTuple } from '../../index.js'; import { serializeToBuffer } from '../../utils/serialize.js'; -import { Fr } from '../index.js'; import { Proof, makeEmptyProof } from '../proof.js'; import { UInt32 } from '../shared.js'; import { VerificationKey } from '../verification_key.js'; diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts index d68f3540ac4..f3bcda0e119 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts @@ -1,3 +1,4 @@ +import { Fr } from '@aztec/foundation/fields'; import { Tuple } from '@aztec/foundation/serialize'; import { @@ -11,7 +12,6 @@ import { import { FieldsOf } from '../../utils/jsUtils.js'; import { serializeToBuffer } from '../../utils/serialize.js'; import { PrivateCallStackItem } from '../call_stack_item.js'; -import { Fr } from '../index.js'; import { MembershipWitness } from '../membership_witness.js'; import { Proof } from '../proof.js'; import { ReadRequestMembershipWitness } from '../read_request_membership_witness.js'; diff --git a/yarn-project/circuits.js/src/types/partial_address.ts b/yarn-project/circuits.js/src/types/partial_address.ts index 37c3c42da69..e99d3786536 100644 --- a/yarn-project/circuits.js/src/types/partial_address.ts +++ b/yarn-project/circuits.js/src/types/partial_address.ts @@ -1,4 +1,4 @@ -import { Fr } from '../index.js'; +import { Fr } from '@aztec/foundation/fields'; /** * A type which along with public key forms a preimage of a contract address. See the link bellow for more details diff --git a/yarn-project/cli/src/encoding.ts b/yarn-project/cli/src/encoding.ts index a118c3b12b1..da824d68ea0 100644 --- a/yarn-project/cli/src/encoding.ts +++ b/yarn-project/cli/src/encoding.ts @@ -1,5 +1,5 @@ -import { Fr } from '@aztec/aztec.js'; import { ABIParameter, ABIType, StructType } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/foundation/fields'; /** * Parses a hex string into an ABI struct type. diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts index 463d1ac6c34..6a3bbacb7df 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts @@ -1,6 +1,6 @@ import { AccountWallet, AztecAddress, computeAuthWitMessageHash } from '@aztec/aztec.js'; -import { Fr } from '@aztec/circuits.js'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { Fr } from '@aztec/foundation/fields'; import { DebugLogger } from '@aztec/foundation/log'; import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; import { TxStatus } from '@aztec/types'; diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index 9b705481b78..69200cf54a1 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -6,7 +6,7 @@ import { generatePublicKey, getSchnorrAccount, } from '@aztec/aztec.js'; -import { Fr, GrumpkinScalar } from '@aztec/circuits.js'; +import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { DebugLogger } from '@aztec/foundation/log'; import { TokenContract } from '@aztec/noir-contracts/types'; import { AztecNode, PXE, TxStatus } from '@aztec/types'; diff --git a/yarn-project/end-to-end/src/e2e_ordering.test.ts b/yarn-project/end-to-end/src/e2e_ordering.test.ts index e1086fefec4..f53fa53d544 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -1,7 +1,8 @@ // Test suite for testing proper ordering of side effects import { Wallet } from '@aztec/aztec.js'; -import { Fr, FunctionSelector } from '@aztec/circuits.js'; +import { FunctionSelector } from '@aztec/circuits.js'; import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; +import { Fr } from '@aztec/foundation/fields'; import { toBigInt } from '@aztec/foundation/serialize'; import { ChildContract, ParentContract } from '@aztec/noir-contracts/types'; import { L2BlockL2Logs, PXE, TxStatus, UnencryptedL2Log } from '@aztec/types'; diff --git a/yarn-project/end-to-end/src/e2e_private_airdrop.test.ts b/yarn-project/end-to-end/src/e2e_private_airdrop.test.ts index b88428e81c0..2a81c41ddf3 100644 --- a/yarn-project/end-to-end/src/e2e_private_airdrop.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_airdrop.test.ts @@ -1,5 +1,6 @@ import { CompleteAddress, NotePreimage, TxHash, Wallet } from '@aztec/aztec.js'; -import { Fr, MAX_NEW_COMMITMENTS_PER_CALL } from '@aztec/circuits.js'; +import { MAX_NEW_COMMITMENTS_PER_CALL } from '@aztec/circuits.js'; +import { Fr } from '@aztec/foundation/fields'; import { DebugLogger } from '@aztec/foundation/log'; import { PrivateTokenAirdropContract } from '@aztec/noir-contracts/types'; diff --git a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts index 67dd9725de0..0111381d8d5 100644 --- a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts @@ -1,6 +1,6 @@ import { AccountWallet, AztecAddress, computeAuthWitMessageHash } from '@aztec/aztec.js'; -import { Fr } from '@aztec/circuits.js'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { Fr } from '@aztec/foundation/fields'; import { DebugLogger } from '@aztec/foundation/log'; import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; import { TxStatus } from '@aztec/types'; diff --git a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts index b1d70709416..f903468f16a 100644 --- a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts @@ -1,7 +1,7 @@ import { AccountWallet, AztecAddress, computeAuthWitMessageHash } from '@aztec/aztec.js'; -import { Fr } from '@aztec/circuits.js'; import { deployL1Contract } from '@aztec/ethereum'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { Fr } from '@aztec/foundation/fields'; import { DebugLogger } from '@aztec/foundation/log'; import { UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-artifacts'; import { UniswapContract } from '@aztec/noir-contracts/types'; diff --git a/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts b/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts index 1347c1eb69b..d50a8b8f83b 100644 --- a/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts +++ b/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts @@ -1,4 +1,5 @@ -import { Fr, GlobalVariables } from '@aztec/circuits.js'; +import { GlobalVariables } from '@aztec/circuits.js'; +import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; /** diff --git a/yarn-project/types/src/auth_witness.ts b/yarn-project/types/src/auth_witness.ts index 0917f50b59f..bd1f532eac3 100644 --- a/yarn-project/types/src/auth_witness.ts +++ b/yarn-project/types/src/auth_witness.ts @@ -1,5 +1,6 @@ -import { Fr, Vector } from '@aztec/circuits.js'; +import { Vector } from '@aztec/circuits.js'; import { BufferReader, serializeToBuffer } from '@aztec/circuits.js/utils'; +import { Fr } from '@aztec/foundation/fields'; /** * An authentication witness. Used to authorize an action by a user. From 93cc668d360ae1c599af5e347df7cd8341c59cda Mon Sep 17 00:00:00 2001 From: Lasse Herskind <16536249+LHerskind@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:52:39 +0100 Subject: [PATCH 2/8] refactor: Use `serialize` functions in `getInitialWitness` (#2713) Fixes #2625. Using the functions defined in `serialize` when applicable. --- .../acir-simulator/src/acvm/serialize.ts | 21 ++++++++++++++- .../src/client/client_execution_context.ts | 27 +++++++------------ .../src/public/public_execution_context.ts | 25 +++++++---------- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/serialize.ts b/yarn-project/acir-simulator/src/acvm/serialize.ts index 00b28a42e99..9f62b4b221d 100644 --- a/yarn-project/acir-simulator/src/acvm/serialize.ts +++ b/yarn-project/acir-simulator/src/acvm/serialize.ts @@ -2,6 +2,7 @@ import { CallContext, ContractDeploymentData, FunctionData, + GlobalVariables, HistoricBlockData, PrivateCallStackItem, PrivateCircuitPublicInputs, @@ -33,12 +34,16 @@ function adaptBufferSize(originalBuf: Buffer) { * @param value - The value to convert. * @returns The ACVM field. */ -export function toACVMField(value: AztecAddress | EthAddress | Fr | Buffer | boolean | number | bigint): ACVMField { +export function toACVMField( + value: AztecAddress | EthAddress | Fr | Buffer | boolean | number | bigint | ACVMField, +): ACVMField { let buffer; if (Buffer.isBuffer(value)) { buffer = value; } else if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'bigint') { buffer = new Fr(value).toBuffer(); + } else if (typeof value === 'string') { + buffer = Fr.fromString(value).toBuffer(); } else { buffer = value.toBuffer(); } @@ -112,6 +117,20 @@ export function toACVMHistoricBlockData(historicBlockData: HistoricBlockData): A ]; } +/** + * Converts global variables into ACVM fields + * @param globalVariables - The global variables object to convert. + * @returns The ACVM fields + */ +export function toACVMGlobalVariables(globalVariables: GlobalVariables): ACVMField[] { + return [ + toACVMField(globalVariables.chainId), + toACVMField(globalVariables.version), + toACVMField(globalVariables.blockNumber), + toACVMField(globalVariables.timestamp), + ]; +} + /** * Converts the public inputs structure to ACVM fields. * @param publicInputs - The public inputs to convert. diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 12e5df55bf4..2627802ef89 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -17,7 +17,13 @@ import { Fr, Point } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { AuthWitness, FunctionL2Logs, NotePreimage, NoteSpendingInfo, UnencryptedL2Log } from '@aztec/types'; -import { NoteData, toACVMWitness } from '../acvm/index.js'; +import { + NoteData, + toACVMCallContext, + toACVMContractDeploymentData, + toACVMHistoricBlockData, + toACVMWitness, +} from '../acvm/index.js'; import { SideEffectCounter } from '../common/index.js'; import { PackedArgsCache } from '../common/packed_args_cache.js'; import { DBOracle } from './db_oracle.js'; @@ -83,22 +89,9 @@ export class ClientExecutionContext extends ViewDataOracle { const contractDeploymentData = this.txContext.contractDeploymentData; const fields = [ - this.callContext.msgSender, - this.callContext.storageContractAddress, - this.callContext.portalContractAddress, - this.callContext.functionSelector.toField(), - this.callContext.isDelegateCall, - this.callContext.isStaticCall, - this.callContext.isContractDeployment, - - ...this.historicBlockData.toArray(), - - contractDeploymentData.deployerPublicKey.x, - contractDeploymentData.deployerPublicKey.y, - contractDeploymentData.constructorVkHash, - contractDeploymentData.functionTreeRoot, - contractDeploymentData.contractAddressSalt, - contractDeploymentData.portalContractAddress, + ...toACVMCallContext(this.callContext), + ...toACVMHistoricBlockData(this.historicBlockData), + ...toACVMContractDeploymentData(contractDeploymentData), this.txContext.chainId, this.txContext.version, diff --git a/yarn-project/acir-simulator/src/public/public_execution_context.ts b/yarn-project/acir-simulator/src/public/public_execution_context.ts index 5af2fbe76f0..4097087e19a 100644 --- a/yarn-project/acir-simulator/src/public/public_execution_context.ts +++ b/yarn-project/acir-simulator/src/public/public_execution_context.ts @@ -5,7 +5,13 @@ import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { FunctionL2Logs, UnencryptedL2Log } from '@aztec/types'; -import { TypedOracle, toACVMWitness } from '../acvm/index.js'; +import { + TypedOracle, + toACVMCallContext, + toACVMGlobalVariables, + toACVMHistoricBlockData, + toACVMWitness, +} from '../acvm/index.js'; import { PackedArgsCache, SideEffectCounter } from '../common/index.js'; import { CommitmentsDB, PublicContractsDB, PublicStateDB } from './db.js'; import { PublicExecution, PublicExecutionResult } from './execution.js'; @@ -50,20 +56,9 @@ export class PublicExecutionContext extends TypedOracle { public getInitialWitness(witnessStartIndex = 1) { const { callContext, args } = this.execution; const fields = [ - callContext.msgSender, - callContext.storageContractAddress, - callContext.portalContractAddress, - callContext.functionSelector.toField(), - callContext.isDelegateCall, - callContext.isStaticCall, - callContext.isContractDeployment, - - ...this.historicBlockData.toArray(), - - this.globalVariables.chainId, - this.globalVariables.version, - this.globalVariables.blockNumber, - this.globalVariables.timestamp, + ...toACVMCallContext(callContext), + ...toACVMHistoricBlockData(this.historicBlockData), + ...toACVMGlobalVariables(this.globalVariables), ...args, ]; From 68c1fab51e3a339032b719ce966ed34787f33dab Mon Sep 17 00:00:00 2001 From: Lucas Xia Date: Thu, 5 Oct 2023 18:21:39 -0400 Subject: [PATCH 3/8] fix: challenge generation update (#2628) This PR updates challenge generation to not be powers of each other, fixing https://github.com/AztecProtocol/barretenberg/issues/583. Before, we generated multiple challenges by generating one by hashing the round data and the previous challenge, and then taking powers of this challenge as the other challenges. Now, we generate challenges by taking a hash each time of the previous challenge (and the round data, which is only nonempty in the first iteration of get_next_challenge_buffer() in a round). Using powers of one challenge does not lead to soundness bugs in how we currently use challenges, but theoretically, we would want challenges to be "independent" of each other. Challenges are 128 bits. I truncate every 256-bit hash to 128 bits for 2 reasons. First, it is easier on the verifier to multiply with 128 challenges as opposed to 256 bits. Second, the 256-bit challenges were not actually uniformly distributed in a nice way because the challenges get modded by the 254-bit scalar field modulus. In this approach, the challenges should be distributed more uniformly (over 128-bit numbers). Optimization(https://github.com/AztecProtocol/barretenberg/issues/741) - I could split every hash into 2 challenges, so I use all 256 bits of a hash (when we need it), instead of throwing away 128 bits every time. # Checklist: Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge. - [x] If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag. - [x] I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code. - [x] Every change is related to the PR description. - [x] I have [linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this pull request to relevant issues (if any exist). --- .../honk/transcript/transcript.hpp | 65 ++++++++++++------- .../honk/transcript/transcript.test.cpp | 32 ++++++--- 2 files changed, 65 insertions(+), 32 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.hpp index 4b99ce00b56..042a0c561b5 100644 --- a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.hpp @@ -71,7 +71,8 @@ template class BaseTranscript { private: static constexpr size_t MIN_BYTES_PER_CHALLENGE = 128 / 8; // 128 bit challenges - size_t round_number = 0; + size_t round_number = 0; // current round for manifest + bool is_first_challenge = true; // indicates if this is the first challenge this transcript is generating std::array previous_challenge_buffer{}; // default-initialized to zeros std::vector current_round_data; @@ -79,24 +80,37 @@ template class BaseTranscript { TranscriptManifest manifest; /** - * @brief Compute c_next = H( Compress(c_prev || round_buffer) ) - * + * @brief Compute next challenge c_next = H( Compress(c_prev || round_buffer) ) + * @details This function computes a new challenge for the current round using the previous challenge + * and the current round data, if they are exist. It clears the current_round_data if nonempty after + * computing the challenge to minimize how much we compress. It also sets previous_challenge_buffer + * to the current challenge buffer to set up next function call. * @return std::array */ - [[nodiscard]] std::array get_next_challenge_buffer() const + [[nodiscard]] std::array get_next_challenge_buffer() { - // Prevent challenge generation if nothing was sent by the prover. - ASSERT(!current_round_data.empty()); + // Prevent challenge generation if this is the first challenge we're generating, + // AND nothing was sent by the prover. + if (is_first_challenge) { + ASSERT(!current_round_data.empty()); + } - // concatenate the hash of the previous round (if not the first round) with the current round data. + // concatenate the previous challenge (if this is not the first challenge) with the current round data. // TODO(Adrian): Do we want to use a domain separator as the initial challenge buffer? // We could be cheeky and use the hash of the manifest as domain separator, which would prevent us from having // to domain separate all the data. (See https://safe-hash.dev) std::vector full_buffer; - if (round_number > 0) { + if (!is_first_challenge) { + // if not the first challenge, we can use the previous_challenge_buffer full_buffer.insert(full_buffer.end(), previous_challenge_buffer.begin(), previous_challenge_buffer.end()); + } else { + // Update is_first_challenge for the future + is_first_challenge = false; + } + if (!current_round_data.empty()) { + full_buffer.insert(full_buffer.end(), current_round_data.begin(), current_round_data.end()); + current_round_data.clear(); // clear the round data buffer since it has been used } - full_buffer.insert(full_buffer.end(), current_round_data.begin(), current_round_data.end()); // Pre-hash the full buffer to minimize the amount of data passed to the cryptographic hash function. // Only a collision-resistant hash-function like Pedersen is required for this step. @@ -109,7 +123,8 @@ template class BaseTranscript { std::array new_challenge_buffer; std::copy_n(base_hash.begin(), HASH_OUTPUT_SIZE, new_challenge_buffer.begin()); - + // update previous challenge buffer for next time we call this function + previous_challenge_buffer = new_challenge_buffer; return new_challenge_buffer; }; @@ -131,8 +146,11 @@ template class BaseTranscript { public: /** * @brief After all the prover messages have been sent, finalize the round by hashing all the data and then create - * the number of requested challenges which will be increasing powers of the first challenge. Finally, reset the - * state in preparation for the next round. + * the number of requested challenges. + * @details Challenges are generated by iteratively hashing over the previous challenge, using + * get_next_challenge_buffer(). + * TODO(#741): Optimizations for this function include generalizing type of hash, splitting hashes into + * multiple challenges. * * @param labels human-readable names for the challenges for the manifest * @return std::array challenges for this round. @@ -145,26 +163,25 @@ template class BaseTranscript { manifest.add_challenge(round_number, labels...); // Compute the new challenge buffer from which we derive the challenges. - auto next_challenge_buffer = get_next_challenge_buffer(); // Create challenges from bytes. std::array challenges{}; - std::array field_element_buffer{}; - std::copy_n(next_challenge_buffer.begin(), HASH_OUTPUT_SIZE, field_element_buffer.begin()); - - challenges[0] = from_buffer(field_element_buffer); - - // TODO(#583): rework the transcript to have a better structure and be able to produce a variable amount of - // challenges that are not powers of each other - for (size_t i = 1; i < num_challenges; i++) { - challenges[i] = challenges[i - 1] * challenges[0]; + // Generate the challenges by iteratively hashing over the previous challenge. + for (size_t i = 0; i < num_challenges; i++) { + auto next_challenge_buffer = get_next_challenge_buffer(); // get next challenge buffer + std::array field_element_buffer{}; + // copy half of the hash to lower 128 bits of challenge + // Note: because of how read() from buffers to fields works (in field_declarations.hpp), + // we use the later half of the buffer + std::copy_n(next_challenge_buffer.begin(), + HASH_OUTPUT_SIZE / 2, + field_element_buffer.begin() + HASH_OUTPUT_SIZE / 2); + challenges[i] = from_buffer(field_element_buffer); } // Prepare for next round. ++round_number; - current_round_data.clear(); - previous_challenge_buffer = next_challenge_buffer; return challenges; } diff --git a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp index 8d9f55966da..df3ca8526dd 100644 --- a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp @@ -139,8 +139,6 @@ TEST_F(UltraTranscriptTests, ProverManifestConsistency) auto manifest_expected = construct_ultra_honk_manifest(instance->proving_key->circuit_size); auto prover_manifest = prover.transcript.get_manifest(); // Note: a manifest can be printed using manifest.print() - prover_manifest.print(); - manifest_expected.print(); for (size_t round = 0; round < manifest_expected.size(); ++round) { ASSERT_EQ(prover_manifest[round], manifest_expected[round]) << "Prover manifest discrepency in round " << round; } @@ -171,9 +169,6 @@ TEST_F(UltraTranscriptTests, VerifierManifestConsistency) auto verifier = composer.create_verifier(instance); verifier.verify_proof(proof); - prover.transcript.print(); - verifier.transcript.print(); - // Check consistency between the manifests generated by the prover and verifier auto prover_manifest = prover.transcript.get_manifest(); auto verifier_manifest = verifier.transcript.get_manifest(); @@ -185,6 +180,30 @@ TEST_F(UltraTranscriptTests, VerifierManifestConsistency) } } +/** + * @brief Check that multiple challenges can be generated and sanity check + * @details We generate 6 challenges that are each 128 bits, and check that they are not 0. + * + */ +TEST_F(UltraTranscriptTests, ChallengeGenerationTest) +{ + // initialized with random value sent to verifier + auto transcript = ProverTranscript::init_empty(); + // test a bunch of challenges + auto challenges = transcript.get_challenges("a", "b", "c", "d", "e", "f"); + // check they are not 0 + for (size_t i = 0; i < challenges.size(); ++i) { + ASSERT_NE(challenges[i], 0) << "Challenge " << i << " is 0"; + } + constexpr uint32_t random_val{ 17 }; // arbitrary + transcript.send_to_verifier("random val", random_val); + // test more challenges + auto [a, b, c] = transcript.get_challenges("a", "b", "c"); + ASSERT_NE(a, 0) << "Challenge a is 0"; + ASSERT_NE(b, 0) << "Challenge a is 0"; + ASSERT_NE(b, 0) << "Challenge a is 0"; +} + TEST_F(UltraTranscriptTests, FoldingManifestTest) { using Flavor = flavor::Ultra; @@ -216,9 +235,6 @@ TEST_F(UltraTranscriptTests, FoldingManifestTest) auto prover_res = prover.fold_instances(); verifier.fold_public_parameters(prover_res.folding_data); - prover.transcript.print(); - verifier.transcript.print(); - // Check consistency between the manifests generated by the prover and verifier auto prover_manifest = prover.transcript.get_manifest(); auto verifier_manifest = verifier.transcript.get_manifest(); From 1bfdc104a01528b7f96daae0d8c24396b92b1308 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 6 Oct 2023 02:11:01 +0000 Subject: [PATCH 4/8] git subrepo push --branch=main docs subrepo: subdir: "docs" merged: "2dcf08948" upstream: origin: "https://github.com/AztecProtocol/docs" branch: "main" commit: "2dcf08948" git-subrepo: version: "0.4.6" origin: "???" commit: "???" [skip ci] --- docs/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/.gitrepo b/docs/.gitrepo index e0cdbbf8e7a..bba05a9c588 100644 --- a/docs/.gitrepo +++ b/docs/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/docs branch = main - commit = 60cee89dc29293c6db4858e0751f7d8047ea82dc - parent = fe4484a8b9eeb3c997650e94794b0db3b4f4e404 + commit = 2dcf08948bd56fa6bb673604b1c47099a5b2e2a5 + parent = 68c1fab51e3a339032b719ce966ed34787f33dab method = merge cmdver = 0.4.6 From 95df9b77a5167e72f711403e8ae772505621addf Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 6 Oct 2023 02:11:28 +0000 Subject: [PATCH 5/8] git subrepo push --branch=master build-system subrepo: subdir: "build-system" merged: "31b355e78" upstream: origin: "https://github.com/AztecProtocol/build-system" branch: "master" commit: "31b355e78" git-subrepo: version: "0.4.6" origin: "???" commit: "???" [skip ci] --- build-system/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-system/.gitrepo b/build-system/.gitrepo index 43e2c5b0fd2..cf3c47d2f6a 100644 --- a/build-system/.gitrepo +++ b/build-system/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/build-system branch = master - commit = 983c2a6858bcb1607bd05b6de467f925f57567f1 - parent = fe4484a8b9eeb3c997650e94794b0db3b4f4e404 + commit = 31b355e78cceb1094f4fde67459d6cabdbc077e7 + parent = 68c1fab51e3a339032b719ce966ed34787f33dab method = merge cmdver = 0.4.6 From 389af2c2e744189cee8fa8a07d360b173ed9a1e1 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 6 Oct 2023 02:11:48 +0000 Subject: [PATCH 6/8] git_subrepo.sh: Fix parent in .gitrepo file. --- barretenberg/.gitrepo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/.gitrepo b/barretenberg/.gitrepo index 7b5b9c4476d..9562eb1a2a9 100644 --- a/barretenberg/.gitrepo +++ b/barretenberg/.gitrepo @@ -7,6 +7,6 @@ remote = https://github.com/AztecProtocol/barretenberg branch = master commit = 4c74b0e241523a4d9669fe96280a6d6f6adb1912 - parent = 5a1ad1f39c1bf9c3408bde6d9030113bf5bdd75e + parent = 10e825884e1ec1fbbf0baccbc2b00db8386263f8 method = merge cmdver = 0.4.6 From a23429312e3141c4b292c31cb207a862190ec3ea Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 6 Oct 2023 02:11:56 +0000 Subject: [PATCH 7/8] git subrepo push --branch=master barretenberg subrepo: subdir: "barretenberg" merged: "a635b1b79" upstream: origin: "https://github.com/AztecProtocol/barretenberg" branch: "master" commit: "a635b1b79" git-subrepo: version: "0.4.6" origin: "???" commit: "???" [skip ci] --- barretenberg/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/barretenberg/.gitrepo b/barretenberg/.gitrepo index 9562eb1a2a9..5ace97a5953 100644 --- a/barretenberg/.gitrepo +++ b/barretenberg/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/barretenberg branch = master - commit = 4c74b0e241523a4d9669fe96280a6d6f6adb1912 - parent = 10e825884e1ec1fbbf0baccbc2b00db8386263f8 + commit = a635b1b79a02a6c57c67ce7ea9c94a3de274961f + parent = a91e9f18eb6615b4616bcc50d0b73cebde4a901e method = merge cmdver = 0.4.6 From 891c1362160693f69bc6a843c7c41776b51b9f7c Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 6 Oct 2023 02:12:23 +0000 Subject: [PATCH 8/8] git subrepo push --branch=master yarn-project/aztec-nr subrepo: subdir: "yarn-project/aztec-nr" merged: "97da6f0e1" upstream: origin: "https://github.com/AztecProtocol/aztec-nr" branch: "master" commit: "97da6f0e1" git-subrepo: version: "0.4.6" origin: "???" commit: "???" [skip ci] --- yarn-project/aztec-nr/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/aztec-nr/.gitrepo b/yarn-project/aztec-nr/.gitrepo index 98b17adbf99..eed7d227f32 100644 --- a/yarn-project/aztec-nr/.gitrepo +++ b/yarn-project/aztec-nr/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/aztec-nr branch = master - commit = c1c4151cb49a43e936d3373425b2c9d9276fa3ac + commit = 97da6f0e117115b91bcfb685a7b1f3a16f0110d9 method = merge cmdver = 0.4.6 - parent = fe4484a8b9eeb3c997650e94794b0db3b4f4e404 + parent = 68c1fab51e3a339032b719ce966ed34787f33dab