From e4496101b3e6c7830e18c494d4b7743d17c9accd Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 14 Jul 2023 15:18:01 -0300 Subject: [PATCH 1/9] Log nargo version when compiling --- yarn-project/noir-contracts/src/scripts/compile.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn-project/noir-contracts/src/scripts/compile.sh b/yarn-project/noir-contracts/src/scripts/compile.sh index 0e756263ce3..a81dff0ca83 100755 --- a/yarn-project/noir-contracts/src/scripts/compile.sh +++ b/yarn-project/noir-contracts/src/scripts/compile.sh @@ -2,6 +2,7 @@ set -euo pipefail; ROOT=$(pwd) +echo "Using $(nargo --version)" for CONTRACT_NAME in "$@"; do CONTRACT_FOLDER="${CONTRACT_NAME}_contract" echo "Compiling $CONTRACT_NAME..." From 91a2ef021bb4d0370df1e17abf40db4199333e38 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 14 Jul 2023 15:19:49 -0300 Subject: [PATCH 2/9] Fix get_note and emit encrypted log on initialisation --- .../cpp/src/aztec3/circuits/abis/packers.hpp | 3 +- circuits/cpp/src/aztec3/constants.hpp | 1 + yarn-project/acir-simulator/src/acvm/acvm.ts | 1 + .../src/client/private_execution.ts | 3 ++ .../src/client/unconstrained_execution.ts | 3 ++ .../src/abis/ecdsa_account_contract.json | 40 ++++++++++++++++ .../circuits.js/src/cbind/constants.gen.ts | 1 + .../src/ecdsa_public_key_note.nr | 42 ++++++++++++----- .../ecdsa_account_contract/src/main.nr | 26 ++++++++++- .../src/examples/ecdsa_account_contract.json | 46 ++++++++++++++++++- .../src/libs/noir-aztec/src/constants_gen.nr | 1 + .../libs/noir-aztec/src/note/note_getter.nr | 3 +- .../src/libs/noir-aztec/src/oracle/notes.nr | 28 +++++++---- .../noir-contracts/src/types/ecdsa_account.ts | 8 ++++ 14 files changed, 181 insertions(+), 25 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/abis/packers.hpp b/circuits/cpp/src/aztec3/circuits/abis/packers.hpp index e281ff78283..99e80056993 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/packers.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/packers.hpp @@ -76,7 +76,8 @@ struct ConstantsPacker { PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH, CONTRACT_STORAGE_READ_LENGTH, - PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH)); // <-- Add names of new constants here + PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH), + NVP(GET_SINGLE_NOTE_ORACLE_RETURN_LENGTH)); // <-- Add names of new constants here } }; diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index 2d327aba13d..7a0e2c06f2c 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -198,6 +198,7 @@ constexpr size_t L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH = L1_TO_L2_MESSAGE_LENGTH + constexpr size_t MAX_NOTE_FIELDS_LENGTH = 20; // + 2 for EXTRA_DATA: [number_of_return_notes, contract_address] constexpr size_t GET_NOTE_ORACLE_RETURN_LENGTH = MAX_READ_REQUESTS_PER_CALL * MAX_NOTE_FIELDS_LENGTH + 2; +constexpr size_t GET_SINGLE_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTE_FIELDS_LENGTH + 2; constexpr size_t MAX_NOTES_PER_PAGE = 10; // + 2 for EXTRA_DATA: [number_of_return_notes, contract_address] constexpr size_t VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * MAX_NOTE_FIELDS_LENGTH + 2; diff --git a/yarn-project/acir-simulator/src/acvm/acvm.ts b/yarn-project/acir-simulator/src/acvm/acvm.ts index 9af5fccf5a4..0aafa2291fb 100644 --- a/yarn-project/acir-simulator/src/acvm/acvm.ts +++ b/yarn-project/acir-simulator/src/acvm/acvm.ts @@ -23,6 +23,7 @@ export const ONE_ACVM_FIELD: ACVMField = `0x${'00'.repeat(Fr.SIZE_IN_BYTES - 1)} type ORACLE_NAMES = | 'packArguments' | 'getSecretKey' + | 'getNote' | 'getNotes' | 'getRandomField' | 'notifyCreatedNote' diff --git a/yarn-project/acir-simulator/src/client/private_execution.ts b/yarn-project/acir-simulator/src/client/private_execution.ts index 28e98eb08f6..64c598021c9 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.ts @@ -77,6 +77,9 @@ export class PrivateFunctionExecution { const [pubKey, partialContractAddress] = await this.context.db.getPublicKey(address); return [pubKey.x, pubKey.y, partialContractAddress].map(toACVMField); }, + getNote: async ([slot], [returnSize]) => { + return await this.context.getNotes(this.contractAddress, slot, [], [], '1', '0', returnSize); + }, getNotes: ([slot], sortBy, sortOrder, [limit], [offset], [returnSize]) => this.context.getNotes(this.contractAddress, slot, sortBy, sortOrder, limit, offset, returnSize), getRandomField: () => Promise.resolve(toACVMField(Fr.random())), diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts index 409cc2884fb..a139b2b1b78 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts @@ -47,6 +47,9 @@ export class UnconstrainedFunctionExecution { }, getNotes: ([slot], sortBy, sortOrder, [limit], [offset], [returnSize]) => this.context.getNotes(this.contractAddress, slot, sortBy, sortOrder, limit, offset, returnSize), + getNote: async ([slot], [returnSize]) => { + return await this.context.getNotes(this.contractAddress, slot, [], [], '1', '0', returnSize); + }, getRandomField: () => Promise.resolve(toACVMField(Fr.random())), debugLog: (...params) => { this.log(oracleDebugCallToFormattedStr(params)); diff --git a/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json b/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json index b7774ee7224..b77451892f8 100644 --- a/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json +++ b/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json @@ -98,6 +98,46 @@ } ], "returnTypes": [] + }, + { + "name": "stev", + "functionType": "unconstrained", + "parameters": [ + { + "name": "contract_address", + "type": { + "kind": "field" + }, + "visibility": "private" + }, + { + "name": "storage_slot", + "type": { + "kind": "field" + }, + "visibility": "private" + }, + { + "name": "preimage", + "type": { + "kind": "array", + "length": 20, + "type": { + "kind": "field" + } + }, + "visibility": "private" + } + ], + "returnTypes": [ + { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + ] } ] } diff --git a/yarn-project/circuits.js/src/cbind/constants.gen.ts b/yarn-project/circuits.js/src/cbind/constants.gen.ts index 2fbe18e1621..4620db74b5a 100644 --- a/yarn-project/circuits.js/src/cbind/constants.gen.ts +++ b/yarn-project/circuits.js/src/cbind/constants.gen.ts @@ -60,6 +60,7 @@ export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 49; export const CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH = 3; export const CONTRACT_STORAGE_READ_LENGTH = 2; export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 51; +export const GET_SINGLE_NOTE_ORACLE_RETURN_LENGTH = 22; export enum GeneratorIndex { COMMITMENT = 1, COMMITMENT_PLACEHOLDER = 2, diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr index 535158e3a98..bc2943894a0 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr @@ -5,7 +5,7 @@ use dep::aztec::oracle::get_secret_key::get_secret_key; use dep::aztec::oracle::get_public_key::get_public_key; use dep::custom_notes::utils::compute_siloed_note_hash; -global ECDSA_PUBLIC_KEY_NOTE_LEN: Field = 65; +global ECDSA_PUBLIC_KEY_NOTE_LEN: Field = 5; // Stores an ECDSA public key composed of two 32-byte elements // TODO: Do we need to include a nonce, in case we want to read/nullify/recreate with the same pubkey value? @@ -26,13 +26,29 @@ impl EcdsaPublicKeyNote { } } + // Serialise the note as 5 fields where: + // [0] = x[0..31] (upper bound excluded) + // [1] = x[31] + // [2] = y[0..31] + // [3] = y[31] + // [4] = owner fn serialise(self) -> [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] { - let mut res: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] = [0; ECDSA_PUBLIC_KEY_NOTE_LEN]; - for i in 0..32 { - res[i] = self.x[i] as Field; - res[i + 32] = self.y[i] as Field; + let mut x: Field = 0; + let mut y: Field = 0; + let mut mul: Field = 1; + + for i in 1..32 { + let bytex: Field = self.x[31 - i] as Field; + x = x + (bytex * mul); + let bytey: Field = self.y[31 - i] as Field; + y = y + (bytey * mul); + mul *= 256; } - res[64] = self.owner; + + let last_x = self.x[31] as Field; + let last_y = self.y[31] as Field; + + let res: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] = [x, last_x, y, last_y, self.owner]; res } @@ -68,15 +84,19 @@ impl EcdsaPublicKeyNote { fn deserialise(preimage: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN]) -> EcdsaPublicKeyNote { let mut x: [u8; 32] = [0;32]; let mut y: [u8; 32] = [0;32]; - for i in 0..32 { - x[i] = preimage[i] as u8; - y[i] = preimage[i + 32] as u8; - } + + let part_x = preimage[0].to_be_bytes(32); + for i in 0..31 { x[i] = part_x[i + 1]; } + x[31] = preimage[1].to_be_bytes(32)[31]; + + let part_y = preimage[2].to_be_bytes(32); + for i in 0..31 { y[i] = part_y[i + 1]; } + y[31] = preimage[3].to_be_bytes(32)[31]; EcdsaPublicKeyNote { x, y, - owner: preimage[64], + owner: preimage[4], header: NoteHeader::empty(), } } diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr index 2f223496db2..cef3736f432 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr @@ -10,14 +10,21 @@ contract EcdsaAccount { use dep::aztec::abi; use dep::aztec::abi::PrivateContextInputs; use dep::aztec::abi::CallContext; + use dep::aztec::context::Context; + use dep::aztec::log::emit_encrypted_log; + use dep::aztec::oracle::debug_log; + use dep::aztec::oracle::get_public_key::get_public_key; use dep::aztec::private_call_stack_item::PrivateCallStackItem; use dep::aztec::public_call_stack_item::PublicCallStackItem; - use dep::aztec::context::Context; use dep::aztec::types::vec::BoundedVec; use dep::aztec::types::point::Point; + use dep::aztec::constants_gen::MAX_NOTE_FIELDS_LENGTH; + use dep::custom_notes::utils::compute_note_hash_and_nullifier; + use crate::storage::Storage; use crate::ecdsa_public_key_note::EcdsaPublicKeyNote; + use crate::ecdsa_public_key_note::EcdsaPublicKeyNoteInterface; // All calls made by this account will be routed through this entrypoint fn entrypoint( @@ -61,9 +68,24 @@ contract EcdsaAccount { for byte in signing_pub_key_y { args = args.push(byte as Field); } let mut context = Context::new(inputs, abi::hash_args(args.storage)); - let pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, inputs.call_context.storage_contract_address); + let this = inputs.call_context.storage_contract_address; + let pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); context = storage.public_key.initialise(context, pub_key_note); + context = emit_encrypted_log( + context, + this, + storage.public_key.storage_slot, + get_public_key(this), + pub_key_note.serialise(), + ); + context.finish() } + + /// ABI stev type "unconstrained" + fn stev(contract_address: Field, storage_slot: Field, preimage: [Field; MAX_NOTE_FIELDS_LENGTH]) -> pub [Field; 2] { + assert(storage_slot == 1); + compute_note_hash_and_nullifier(contract_address, storage_slot, EcdsaPublicKeyNoteInterface, preimage) + } } diff --git a/yarn-project/noir-contracts/src/examples/ecdsa_account_contract.json b/yarn-project/noir-contracts/src/examples/ecdsa_account_contract.json index 46b3b961fae..3e78737edae 100644 --- a/yarn-project/noir-contracts/src/examples/ecdsa_account_contract.json +++ b/yarn-project/noir-contracts/src/examples/ecdsa_account_contract.json @@ -33,7 +33,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -100,7 +100,49 @@ } ], "returnTypes": [], - "bytecode": "H4sIAAAAAAAA/+1dCbhNZRfedzIPmed5nu++1zzPQyGJNJcxZI4QkuZJ81yKolIUQghRVJIkSZIpU+Z5nv71sU5t36/CfdfpW88953nW895F7fu971r73d/ZZ9nn65Sety+Fd/YVRRFNEcs/h/I4K09h5TkpUgXyXFae28rzWHleK89n5fmtvICVF7TyQlZe2MqLWHlRKy9m5cWtvISVl7TyUlZe2srLWHlZKy9n5eWtvIKVx1u5b+UJVp5o5RWtvJKVV7byKlZe1cqrWXl1K69h5TWtvJaV17byOlZe18rrWXl9K29g5Q2tvJGVN7byJlbe1MqbWfmVVn6VlTe38hZW3tLKr7byVlZ+jZW3tvJrrbyNlbe18uusvF0gN15Q0Dv3ykRxmiIzYxbGrIzZGLMz5mDMyZiLMTdjHsa8jPkY8zMWYCzIWIixMGMRxqKMxRiLM5ZgLMlYirE0YxnGsozlGMszVmCMD/x311PccAFtfP5vEhgTGSsyVmKszFiFsSpjNcbqjDUYazLWYqzNWIexLmM9xvqMDRgbMjZibMzYhLEpYzPGKxmvYmzO2IKxJePVjK0C2txIcZN3/iuKsS5jYnzlihU7V0no7Cf67eMTqnWoWim+YqUOlav6Vf1KVSt1SqiamNi5asWqVap1qFYlvppfMbGz36VStcQu8edeNweOFZ/El+Q6b1GyzluVrPM2Jeu8Xck62ytZZwcl6+yoZJ2dlKyzs5J1dlGyzjuUrLOrknV2U7LO7krWeaeSdfZQss6eStbZS8k6eytZZx8l6+yrZJ39lKzzLiXr7A9cp30PxtwXM/ciWjNey9iGsS3jdYztGG9mvIXxVsbbGG9nbM/YgbEjYyfGzoxdGO9g7MrYjbE7452MPRh7MvZi7M3Yh7EvYz/Guxj7e3/dgxlAcbd3/gtdw4Gejl4bpGSdg5Ws8x4l6xyiZJ1DlaxzmJJ13qtkncOVrPM+JescoWSd9ytZ5wMefo92BR/PfH5m9io3Mg5gHMg4iHEw4z2MQxiHMg5jvJdxOON9jCMY72d8wPtrj/QgxUPeX3MOf/eqi9HAjwrUqR7//DDFIxSPUjxG8TjFExRPUoykeIriaYpnKJ6leI7ieYoXKF6keIniZYpXKF6leI3idYo3KEZRvEnxFsVoijEUb1O8QzGWYhzFuxTvUbxPMZ7iA4oPKSZQTKT4iOJjikkUkymmUHxCMZViGsV0ik8pZlDMpJhF8RnFbIo5FHMpPqeYRzGf4guKLykWUCyk+CqgczrG1N65z5+DrxQevB7xZt4lLvA7Q6/Q787AvzcW+nsr+uZ3xVj87P6rG/g59PvNZ/Ep+ec7Ovdv2bt/52BLhQ5Z7wKHjA7QDFGOCfxZ6O9Df5fSu8ApUddD8I/3vQssDHXshz2c/30NPNbfeUwUmP/XHtazQ69vAj/HWrUzr1AzpRDg5Fm/x9YxgyfcrBJF+kbguIs8XMNK8V6Er1F8tNUA6HU/AlyrJ9Gnfnz8t3SMxSHyRhDzB4cDufnLVNYvj7EWkdSmgQnFhECi+4s9Pc32nud+s31Hx1gSbLbvrGZbEoZmgwnFhECi+0s8Pc32qOd+s31Px1gabLbvrWZbGoZmgwnFhECi+0s9Pc32vud+s/1Ax1gWbLYfrGZbFoZmgwnFhECi+8s8Pc32mOd+s/1Ix1gebLYfrWZbHoZmgwnFhECi+8s9Pc023nO/2X6iY6wINttPVrOtCEOzwYRiQiDR/RWenmZ73HO/2X6mY6wMNtvPVrOtDEOzwYRiQiDR/ZWenmb7wHO/2X6hY6wKNtsvVrOtCkOzwYRiQiDR/VWenmZ7wnO/2X6lY6wONtuvVrOtDkOzwYRiQiDR/dWenmb70HO/2X6jY6wJNttvVrOtCUOzwYRiQiDR/TWenmZ70nO/2dbSMdYFm22t1WzrwtBsMKGYEEh0f52np9kmeO4323o6xoZgs623mm1DGJoNJhQTAonub/D0NNtIz/1m+52OsTHYbL9bzbYxDM0GE4oJgUT3N3p6mm2i536zbaJjbA422yar2TaHodlgQjEhkOj+Zk9Psz3lud9sW+gYW4PNtsVqtq1haDaYUEwIJLq/1dPTbB957jfbH3SMbcFm+8Nqtm1haDaYUEwIJLq/zdPTbE977jfbdjrGjmCzbbeabUcYmg0mFBMCie7v8PQ028ee+822k46xK9hsO61m2xWGZoMJxYRAovu7PD3N9oznfrPtpmPsCTbbbqvZ9oSh2WBCMSGQ6P4eT0+zTfLcb7a9dIx9wWbbazXbvjA0G0woJgQS3d/n6Wm2Zz33m20/HeNAsNn2W812IAzNBhOKCYFE9w94epptsud+sx2kYxwKNttBq9kOhaHZYEIxIZDo/iFPT7M957nfbKavjgSb7bDVbEfC0GwwoZgQSHT/iKen2aZ47jfbUTrGsWCzHbWa7VgYmg0mFBMCie4f8/Q02/Oe+812nI5xIthsx61mOxGGZoMJxYRAovsnPD3N9onnfrOdpGOcCjbbSavZToWh2WBCMSGQ6P4pT0+zveC532zmMT9ngs122mq2M2FoNphQTAgkun/G09NsUz33m82QjooKNJf5Idhs5i+lmw0mFBNCFTAqSk+zvei532zRRDom2GzRVrPFhKHZYEIxIVQBYxQ12zTP/WaLJdJxwWaLtZotLgzNBhOKCaEKGKeo2V7y3G+2FEQ6ZbDZUljNljIMzQYTigmhCphSUbNN99xvtlREOnWw2VJZzZY6DM0GE4oJoQqYWlGzvey532xpiHTaYLOlsZotbRiaDSYUE0IVMK2iZvvUc7/Z0hHp9MFmS2c1W/owNBtMKCaEKmB6Rc32iud+s2Ug0hmDzZbBaraMYWg2mFBMCFXAjIqabYbnfrNdQaQzBZvtCqvZMoWh2WBCMSFUATMparZXPfebLTORzhJstsxWs2UJQ7PBhGJCqAJmUdRsMz33my0rkc4WbLasVrNlC0OzwYRiQqgCZlPUbK957jdbdiKdI9hs2a1myxGGZoMJxYRQBcyhqNlmee43W04inSvYbDmtZssVhmaDCcWEUAXMpajZXvfcb7bcRDpPsNlyW82WJwzNBhOKCaEKmEdRs33mud9seYl0vmCz5bWaLV8Ymg0mFBNCFTCfomZ7w3O/2fIT6QLBZstvNVuBMDQbTCgmhCpgAUXNNttzv9kKEulCwWYraDVboTA0G0woJoQqYCFFzTbKc7/ZChPpIsFmK2w1W5EwNBtMKCaEKmARRc02x3O/2YoS6WLBZitqNVuxMDQbTCgmhCpgMUXN9qbnfrMVJ9Ilgs1W3Gq2EmFoNphQTAhVwBKKmm2u536zlSTSpYLNVtJqtlJhaDaYUEwIVcBSiprtLc/9ZitNpMsEm6201WxlwtBsMKGYEKqAZRQ12+ee+81WlkiXCzZbWavZyoWh2WBCMSFUAcsparbRnvvNVp5IVwg2W3mr2SqEodlGgwmhClhBUbPN89xvtngi7QebLd5qNj8MzTYPTAgkuu8rarYxnvvNlkCkE4PNlmA1W2IYmg0mFBNCFTBRUbPN99xvtopEulKw2SpazVYpDM0GE4oJoQpYSVGzve2532yViXSVYLNVtpqtShiaDSYUE0IVsIqiZvvCc7/ZqhLpasFmq2o1W7UwNBtMKCaEKmA1Rc32jud+s1Un0jWCzVbdarYaYWg2mFBMCFXAGoqa7UvP/WarSaRrBZutptVstcLQbDChmBCqgLUUNdtYz/1mq02k6wSbrbbVbHXC0GwwoZgQqoB1FDXbAs/9ZqtLpOsFm62u1Wz1wtBsMKGYEKqA9RQ12zjP/WarT6QbBJutvtVsDcLQbDChmBCqgA0UNdtCz/1ma0ikGwWbraHVbI3C0GwwoZgQqoCNFDXbu577zdaYSDcJNltjq9mahKHZYEIxIVQBmyhqtq8895utKZFuFmy2plazNQtDs8GEYkKoAjaLwhYQ3WCL6BiLL3DcpNbjSiDvFN75J1nohdYCuebgeq8KJLGM0d7/nwspBDh51u+xdcxwgT+D/nKJIhlB0cdtHoVrfinezaPgNTrvqoA2gRZAIw2trQXXvjljy6gLrz0+aa+zxrhUQJOrFRrj1ULG2CpijNgitRIwxmscN0bD+xoBYwwdsiVreg1ja0HDWe7hDedahYZzrZDhtIkYDrZIbQQMp63jhmN4txU0nNasaVvG6wQNZ6WHN5x2Cg2nnZDhXB8xHGyRrhcwnBscNxzD+wZBw7mONb2B8UZBw1nt4Q3nJoWGc5OQ4dwcMRxskW4WMJxbHDccw/sWQcO5kTW9hfFWQcNZ5+EN5zaFhnObkOHcHjEcbJFuFzCc9o4bjuHdXtBwbmVN2zN2EDScjR7ecDoqNJyOQobTKWI42CJ1EjCczo4bjuHdWdBwOrCmnRm7CBrOVg9vOHcoNJw7hAyna8RwsEXqKmA43Rw3HMO7m6DhdGFNuzF2FzScHR7ecO5UaDh3ChlOj4jhYIvUQ8BwejpuOIZ3T0HD6c6a9mTsJWg4ezy84fRWaDi9hQynT8RwsEXqI2A4fR03HMO7r6Dh9GJN+zL2EzScAx7ecO5SaDh3CRlO/4jhYIvUX8BwBjhuOIb3AEHD6ceaDmC8W9Bwjnh4wxmo0HAGChnOoIjhYIs0SMBwBjtuOIb3YEHDuZs1Hcx4j6DhnPDwhjNEoeEMETKcoRHDwRZpqIDhDHPccAzvYYKGcw9rOozxXkHDOePhDWe4QsMZLmQ490UMB1uk+wQMZ4TjhmN4jxA0nHtZ0xGM9wsaTkwU3nAeUGg4DwgZzoMRw8EW6UEBw3nIccMxvB8SNJz7WdOHGB8WNJyUAobziELDeUTIcB6NGA62SI8KGM5jjhuO4f2YoOE8zJo+xvi4oOGkFTCcJxQazhNChvNkxHCwRXpSwHBGOm44hvdIQcN5nDUdyfiUoOFkFDCcpxUaztNChvNMxHCwRXpGwHCeddxwDO9nBQ3nKdb0WcbnBA0ni4DhPK/QcJ4XMpwXIoaDLdILAobzouOGY3i/KGg4z7GmLzK+JGg4OQQM52WFhvOykOG8EjEcbJFeETCcVx03HMP7VUHDeYk1fZXxNUHDySNgOK8rNJzXhQznjYjhYIv0hoDhjHLccAzvUYKG8xprOorxTUHDKSBgOG8pNJy3hAxndMRwsEUaLWA4Yxw3HMN7jKDhvMmajmF8W9BwiggYzjsKDecdIcMZGzEcbJHGChjOOMcNx/AeJ2g4b7Om4xjfFTScEgKG855Cw3lPyHDejxgOtkjvCxjOeMcNx/AeL2g477Km4xk/EDScMgKG86FCw/lQyHAmRAwHW6QJAoYz0XHDMbwnChrOB6zpRMaPBA2ngoDhfKzQcD4WMpxJEcPBFmmSgOFMdtxwDO/JgobzEWs6mXGKoOEkChjOJwoN5xMhw5kaMRxskaYKGM40xw3H8J4maDhTWNNpjNMFDaeKgOF8qtBwPhUynBkRw8EWaYaA4cx03HAM75mChjOdNZ3JOEvQcGoIGM5nCg3nMyHDmR0xHGyRZgsYzhzHDcfwniNoOLNY0zmMcwUNp46A4Xyu0HA+FzKceRHDwRZpnoDhzHfccAzv+YKGM5c1nc/4haDhNBAwnC8VGs6XQoazIGI42CItEDCchY4bjuG9UNBwvmBNFzJ+JWg4TQQM52uFhvO1kOF8EzEcbJG+ETCcRY4bjuG9SNBwvmJNFzF+K2g4Szy84SxWaDiLhQznu4jhYIv0nYDhLHHccAzvJQKG4wVeaBP4HndC+aG1fc+1X8K4VNAYlwlo8oNCY/xByBiXRYwRW6RlAsb4o+PGaHj/KLgTW8qa/si4XNBwVnh4w/lJoeH8JGQ4KyKGgy3SCgHD+dlxwzG8fxY0nOWs6c+MKwUNZ5WHN5xfFBrOL0KGsypiONgirRIwnF8dNxzD+1dBw1nJmv7KuFrQcNZ4eMP5TaHh/CZkOGsihoMt0hoBw1nruOEY3msFDWc1a7qWcZ2g4Wzw8IazXqHhrBcynA0Rw8EWaYOA4fzuuOEY3r8LGs461vR3xo2ChrPZwxvOJoWGs0nIcDZHDAdbpM0ChrPFccMxvLcIGs5G1nQL41ZBw9nm4Q3nD4WG84eQ4WyLGA62SNsEDGe744ZjeG8XNJytrOl2xh2ChrPLwxvOToWGs1PIcHZFDAdbpF0ChrPbccMxvHcLGs4O1nQ34x5Bw9nn4Q1nr0LD2StkOPsihoMt0j4Bw9nvuOEY3vsFDWcPa7qf8YCg4Rzy8IZzUKHhHBQynEMRw8EW6ZCA4Rx23HAM78OChnOANT3MeETQcI55eMM5qtBwjgoZzrGI4WCLdEzAcI47bjiG93FBwznCmh5nPCFoOKc8vOGcVGg4J4UM51TEcLBFOiVgOKcdNxzD+7Sg4ZxgTU8znhE0nKgovOGYMwqlSbgMB7nm4HqjAu4SMZykHjP6nKDo40ZHu204hnd0NLxGfzbqGTaBaNY2hn+XhOHECRhOrELDiRUynLiI4WCLFCdgOCkcNxzDO4Wg4cSwpikYUwoaTmoBw0ml0HBSCRlO6ojhYIuUWsBw0jhuOIZ3GkHDScmapmFMK2g46QUMJ51Cw0knZDjpI4aDLVJ6AcPJ4LjhGN4ZBA0nLWuagTGjoOFkEjCcKxQazhVChpMpYjjYImUSMJzMjhuO4Z1Z0HAysqaZGbMIGk42AcPJqtBwsgoZTraI4WCLlE3AcLI7bjiGd3ZBw8nCmmZnzCFoOLkEDCenQsPJKWQ4uSKGgy1SLgHDye244RjeuQUNJwdrmpsxj6Dh5BMwnLwKDSevkOHkixgOtkj5BAwnv+OGY3jnFzScPKxpfsYCgoZTSMBwCio0nIJChlMoYjjYIhUSMJzCjhuO4V1Y0HAKsKaFGYsIGk4xAcMpqtBwigoZTrGI4WCLVEzAcIo7bjiGd3FBwynCmhZnLCFoOKUEDKekQsMpKWQ4pSKGgy1SKQHDKe244RjepQUNpwRrWpqxjKDhlBMwnLIKDaeskOGUixgOtkjlBAynvOOGY3iXFzScMqxpecYKgobjCxhOvELDiRcyHD9iONgi+QKGk+C44RjeCYKGU4E1TWBMFDScSgKGU1Gh4VQUMpxKEcPBFqmSgOFUdtxwDO/KgoaTyJpWZqwiaDjVBAynqkLDqSpkONUihoMtUjUBw6nuuOEY3tUFDacKa1qdsYag4dQSMJyaCg2nppDh1IoYDrZItQQMp7bjhmN41xY0nBqsaW3GOoKGU0/AcOoqNJy6QoZTL2I42CLVEzCc+o4bjuFdX9Bw6rCm9RkbCBpOIwHDaajQcBoKGU6jiOFgi9RIwHAaO244hndjQcNpwJo2ZmwiaDjNBAynqULDaSpkOM0ihoMtUjMBw7nSccMxvK8UNJwmrOmVjFcFNP426vw/ax7sXg9vHi0UmkcLIfNoGTEPbJFaCpjH1Y6bh+F9taB5NGdNr2ZsFX1+QwZfaG6thE68ayInHrZI1wiceK0dP/EM79YCJ57EWs1bgcUe/mp+bbT7vJcK8G6jgPdyAd5tFfBeKcD7OgW8VwvwbqeA9zoB3tcr4L1RgPcNCnhvFeB9owLeOwR436SA9x4B3jcr4H1AgPctCngfEeB9qwLeJwR436aA9xkB3rcr4B0j8NFMewW8Uwrw7qCAd1oB3h0V8M4owLuTAt5ZBHh3VsA7hwDvLgp45xHgfYcC3gUEeHdVwLuIAO9uCniXEODdXQHvMgK871TAu4IA7x4KeCcK8O6pgHcVAd69FPCuIcC7twLedQR491HAu4EA774KeDcR4N1PAe8lHp73XQp4LxPg3V8B7xUCvAco4L1KgPfdCnivEeA9UAHvDQK8ByngvVmA92AFvLcJ8L5HAe9dAryHKOC9T4D3UAW8DwnwHqaA9zEB3vcq4H1KgPdwBbyjBN6P3aeAd5wA7xEKeKcW4H2/At4S35T+gALeEl/Y/KAC3hLfG/uQAt4SX1/5sALeEt+i94gC3hJf5vWoAt4S3yn0mALeEl9t8rgC3hLfsPCEAt4SD3p/UgFviedNj1TAW+Kxt08p4C3x9M2nFfCWeAjgMwp4SzyL7FkFvCUeifQcmHfohV7n88B1mrWZByTU4+OZfwt+mrANY1vG6xjbMV7PeAPjjYw3Md7MeAvjrYy3Md7O2J6xA2NHxk6MnRm7MN7B2JWxG2N3xjsZezD2ZOzF2JuxD2Nfxn6MdzH2ZxzAeDfjQMZBjIMZ72EcwjiUcRjjvYzDGe9jHMF4P+MDjA8yPsT4MOMjjI8yPsb4OOMTjE8yjmR8ivFpxmcYn2V8jvF5RvN6gX5+MdrzJHv5JVwv+6FeDi35JebyQoDTy/TzK9Hn/pvof+AVn7SXnwl3rPiCfJxXacGvUbxO8QbFKIo3Kd6iGE0xhuJtincoxlKMo3iX4j2K9ynGU3xA8SHFBIqJFB9RfEwxiWIyxRSKTyimUkyjmE7xKcWM6HMiRbFuZi2pvL/y16z8dSt/w8pHWfmbVv6WlY+28jFW/raVv2PlY618nJW/a+XvWfn7Vj7eyj+w8g+tfIKVT7Tyj6z8YyufZOWTrXyKlX9i5VOtfJqVT7fyT618BufBV+gBO3UZyQsSk+AF/qcBL0jokiRf8WdE4zzq7jiZfcEF9DPr9C+X8zSbc6fL1286UL+B4dXPrDP+cjh/ciHO8Zen31SgfoPCr59ZZ9VL5Tz5bzhX63Lp+k0B6jf4v9GP1lmxy6Vw/vifOFe5NP0mAfW75z/T7+w6K10s54n/xrnixev3EVC/If+tfmad8RfD+cOL4Rx/cfpNAOo39L/Xz6yz479xHn+xnKv8u34fAPUb5oZ+Zp0J/8T5vUvhXOWf9XsfqN+97uhn1lnl7ziPu1TOVf5ev3eB+g13Sz+zzqoX4vzO5XCuemH9xgL1u889/cw6423OYy6Tc+Uu/6/f20D9Rripn1lnfJDzW0nhnHC+fqOB+t3vrn5mnQkhzqOSyrniX/q9CdTvAbf1S+zcpYtZqv96NOJY5/R7A6jfg2HSLz5pLx9YZz/IOcnzdkr0A/q0fz9Qv4eV6AfcZ/n3AfV7RIl+wPdJ/r1A/R5Voh/wPoc/FKjfY0r0A96n9O8B6ve4Ev2AnzP4g4D6PaFg/0c7QP+1aJx+dwP1e1JJ/wHr7D8J1G+kEv2APu0/DtTvKSX6AfdZ/qNA/Z5Woh/wfZL/MFC/Z5ToB6yz/wxQv2eV6Af0af8poH7PKdEvOHOXVM6vAvdCzyvRD3ie+M8B+w+pH5X17Dxb6IWe+8yMO9afc58zacGzKD6jmE0xh2IuxecU8yjmU3xB8SXFAoqFFF9RfE3xDcUiim8pFlN8R7GE4nuKpRQ/UCyj+JFiOcVPFCsofqZYSfFLtHfe3KdZS3AucJaVf2bls618jpXPtfLPrXyelc+38i+s/EsrX2DlC638Kyv/2sq/sfJFVv6tlS+28u+sfImVf2/lS638BytfZuU/WvlyK//JyldY+c9WvtLKf4mWn/tcGfDapM59/hKN850pSuY+V9ickzD3+TNQv0+UzH0uvxDny5z7/Amo31Qlc5/L/obz5cx9/gjUb5qSuc+l/8T5Euc+fwDqN13J3OeSf+N8CXOf3wP1+1TJ3Ofii+F8kXOf3wH1m6Fk7nPRxXK+iLnPb4H6zVQy9/n1pXD+l7nPb4D6zVIy97nwUjn/w9znV0D9PlMy9/nl5XD+m7nPBUD9ZiuZ+5x/mZwvNPf5BVC/OUrmPj9PCmdr7nMeUL+5SuY+5ySVc2Ducy5Qv8+VzH1+Fo041jn9ZgP1m6fkvjmwzv484H3z+Ur0A/q0Pxeo3xdK9APus/zZQP2+VKIf8H2SPwuo3wIl+gHvc/gzgPotVKIf8D6lPx2o31dK9AN+zuBPBer3tZK5z1nROP2mAPX7Rkn/AevsfwPUb5ES/YA+7X8F1O9bJfoB91n+AqB+i5XoB3yf5H8B1O87JfoB6+x/B9RviRL9gD7tfwvU73sl+gVn7pL8mRlwL7RUiX7A88T/Hth/SP2orGfn2UIv9NxnFtyx/pz7XEUL/pViNcVvFGso1lKso1hPsYHid4qNFJsoNlNsodhK8QfFNortFDsodlLsothNsYdiL8U+iv0UBygOUhyiOExxJNrzjkZ75819mrUE5wJ/tfLVVv6bla+x8rVWvs7K11v5Biv/3co3WvkmK99s5VusfKuV/2Hl26x8u5XvsPKdVr7Lyndb+R4r32vl+6x8v5UfsPKDVn7Iyg9b+RErPxotP/d5JOC1SZ37PBqN853dSuY+D9mckzD3eRio3x4lc58HLsT5Muc+DwL126tk7nPf33C+nLnP/UD99imZ+9zzT5wvce5zL1C//UrmPnf9G+dLmPvcDdTvgJK5zx0Xw/ki5z53AvU7qGTuc9vFcr6Iuc/tQP0OKZn73HopnP9l7vMPoH6Hlcx9br5Uzv8w97kFqN8RJXOfGy+H89/MfW4C6ndUydznhsvkfKG5z9+B+h1TMve5LimcrbnP9UD9jiuZ+1yTVM6Buc+1QP1OKJn7XB2NONY5/X4D6ndSyX1zYJ39k8D75qeU6Af0af84UL/TSvQD7rP8o0D9zijRD/g+yT8M1M98iZ0G/YD3OfyDQP2ilOgHvE/p7wfqF61EP+DnDP5eoH4xKdzf/5m5z1+jcfrtBuoXq6T/gHX2g5yTql+cEv2APu1HA/VLoUQ/4D7L94D6pVSiH/B9kn8a6H+plOgHrLOfCth/qZXoB/RpPwVQvzRK9AvO3CWV8yrgXiitEv2A54mfBth/SP2orGfn2UIv9NxnVtyx/pz7PEYLPk5xguIkxSmK0xRnos81QRRFNEUMRSxFHEUKipQUqShSU6ShSEuRjiI9RQaKjBRXUGSiyEyRhSIrRTaK7BQ5KHLGeOfNfZq1BOcCj1v5CSs/aeWnrPy0lZ+xcsMvmEdZebSVx1h5rJXHWXkKK09p5amsPLWVp7HytFaezsrTW3kGK89o5VdYeSYrz2zlWaw8q5Vns/LsVp7DynPGyM99mt8ZOlZS5z5zxuB8p3R437df9txnNptzEuY+swP1KxP++x6XNfeZ5UKcL3PuMytQv7L/zX2jS577zPQ3nC9n7jMzUL9y/9l9t0ub+8z4T5wvce7zCqB+5f/b+5YXPfeZ/t84X8LcZwagfhX++/u+FzX3mfZiOF/k3Gc6oH7xbtw3/9e5z9QXy/ki5j7TAPXz3fnc4R/nPlNeCud/mftMBdQvwa3Pbf527jPuUjn/w9xnCqB+ie597nXBuc+Yy+H8N3OfsUD9Krr5ueH/zX1GXSbnC819RgP1q+Tu567nzX2eiU7Csay5Tw+oX2W3P7f+c+7zVHQSjxWY+zwdjdOvioLP/Q3nE9GIY53T7yRQv6pK7psD6+xXBd43r6ZEP6BP+5WB+lVXoh9wn+VXBOpXQ4l+wPdJfgJQv5pK9APe5/DjgfrVUqIf8D6lXx6oX20l+gE/Z/DLAvWro2Tu83g0Tr/SQP3qKuk/YJ39ukD96inRD+jTfm2gfvWV6AfcZ/k1gfo1UKIf8H2SXx2oX0Ml+gHr7DcE6tdIiX5An/brA/VrrES/4Mxdkp8VANwLNVGiH/A88RsD+w+pH5X17Dxb6IWe+8yGO9afc5+5qNC5KfJQ5KXIR5GfogBFQYpCFIUpilAUpShGUZyiBEVJilIUpSnKUJSlKEdRnqICRTyFT5FAkUhRkaISRWWKKhRVrbnPXNZcYG4rz2Plea08n5Xnt/ICVl7QygtZeWErL2LlRa28mJUXt/ISVl7SyktZeWkrL2PlZa28nJWXt/IKVh5v5b6VJ1h5opVXtPJKVl7ZyqtYedUY+bnPKsC5z6rAz726KJn7rASc+6wM1O8OJXOficC5z4pA/boqmfv0gXOfCUD9uimZ+6wAnPuMB+rXXcncZzng3Gd5oH53Kpn7LAOc+ywL1K+HkrnPUsC5z9JA/XoqmfssAZz7LAnUr5eSuc9iwLnP4kD9eiuZ+ywCnPssCtSvj5K5z0LAuc/CQP36Kpn7LJAUztbcZ0Ggfv2UzH3mSyrnwNxnfqB+dymZ+8wTgzjWOf3yAvXrr+S+ObDOfn/gffMBSvQD+rTfD6jf3Ur0A+6z/D5A/QYq0Q/4PsnvBdRvkBL9gPc5/B5A/QYr0Q94n9LvDtTvHiX6AT9n8LsC9RuiZO4zdwxOvy5A/YYq6T9gnf2hQP2GKdEP6NP+PUD97lWiH3Cf5Q8C6jdciX7A90n+3UD97lOiH7DO/n1A/UYo0Q/o0/69QP3uV6JfcOYuqZxzAfdCDyjRD3ie+PcD+w+pn5lliw5oiJ77zI471p9zn9Wo0NUpalDUpKhFUZuijulRinoU9SkaUDSkaETRmKIJRVOKZhRXUlxF0ZyiBUVLiqspWlFcQ9Ga4lqKNhRtKa6jaEdxfYx33txnNWsusLqV17DymlZey8prW3kdK69r5fWsvL6VN7DyhlbeyMobW3kTK29q5c2s/Eorv8rKm1t5CytvaeVXW3krK7/Gyltb+bVW3sbK21r5dVbezsqvj5Gf+2wHnPu8Hvi5w9tK5j7bAuc+rwPq946Suc9rgXOfbYD6jVUy93kNcO6zNVC/cUrmPq8Gzn22Aur3rpK5zxbAuc+WQP3eUzL3eRVw7rM5UL/3lcx9NgPOfV4J1G+8krnPJsC5z6ZA/T5QMvfZCDj32Rio34dK5j4bAOc+GwL1m6Bk7rMecO6zPlC/iUrmPuskhbM191kXqN9HSuY+awHnPmsD9ftYydxnDeDcZ02gfpOU3DcH1tmfBLxvPlmJfkCf9j8C6jdFiX7AfZY/AajfJ0r0A75P8j8A6jdViX7A+xz++0D9pinRD3if0n8XqN90JfoBP2fwxwL1+1TJ3Gd14KzD20D9ZijpP2Cd/RlA/WYq0Q/o0/50oH6zlOgH3Gf5U4H6faZEP+D7JH8KUL/ZSvQD1tmfDdRvjhL9gD7tzwLqN1eJfsGZu6RyrgbcC32uRD/geeLPBfYfUj8zyxYd0BA995kDd6w/5z5voELfSHETxc0Ut1DcSnEbxe0U7Sk6UHSk6ETRmaILxR0UXSm6UXSnuJOiB0VPil4UvSn6UPSl6EdxF0V/igEUd1MMpBgU450393mDNRd4o5XfZOU3W/ktVn6rld9m5bdbeXsr72DlHa28k5V3tvIuVn6HlXe18m5W3t3K77TyHlbe08p7WXlvK+9j5X2tvJ+V32Xl/a18gJXfbeUDrXxQjPzc50Dg3Ocg4OcOa5XMfQ4Azn3eDdRvnZK5z7uAc5/9gfqtVzL32Rc499kPqN8GJXOfvYFzn32A+v2uZO6zJ3DusxdQv41K5j7vBM599gDqt0nJ3Gc34Nxnd6B+m5XMfd4BnPvsCtRvi5K5z87Auc8uQP22Kpn77Aic++wE1O8PJXOf7YFznx2A+m1TMvd5G3Du83agftuVzH3eApz7vBWo3w4lc583Aec+bwbqt1PJfXNgnf2dwPvmu5ToB/RpfztQv91K9APus/w/gPrtUaIf8H2SvwWo314l+gHvc/ibgPrtU6If8D6l/ztQv/1K9AN+zuCvB+p3QMnc543AWYe1QP0OKuk/YJ39g0D9DinRD+jT/n6gfoeV6AfcZ/l7gfodUaIf8H2Svxuo31El+gHr7B8F6ndMiX5An/YPA/U7rkS/4MxdUjnfANwLnVCiH/A88Y8D+w+pXxTrtp6PNyP63Fzbp4zTGacxTmX8hHEK42TGSYwfM37EOJFxAuOHjB8wjmd8n/E9xncZxzGOZXyH8W3GMYyjGd9ifJNxFOMbjK8zvsb4KuMvjCsZf2ZcwfgT43LGHxmXMf7AuJTxe8YljN8xLmb8lnER4zeMXzN+xbiQcQHjl4xfMM5nnMf4OeNcxjmMsxk/Y5zFOJPxKOMRxsOMhxgPMh5g3M+4j3Ev4x7G3Yy7GHcy7mDczriN8Q/GrYxbGDczbmLcyPg74wbG9YzrGNcyrmH8jXE146+Mqxhz8lxnDsbsjNkYszJmYczMmInxCsaMjBkY0zOmY0zLmIYxNWMqxpSMKRjjGGMZYxijQ3OpjB7jGeZzmvEU40nGE4zHGY8xhr7HPvT99qHvva/EWJExkTGB0WeMZ6zAWJ6xHGNZxjKMpRlLMZZkLMFYnLEYY1HGIoyFGQsxFmQswJifMR9jXsY8jLkZczGGnucaes5r6PmvoefChp4XG3qObOj5sqHnzoaeRxt6Tm3o+bWh59qGnncbeg5u6Pm4oefmhp6nG3rObuj5u6Hn8oae1xt6jm/o+b6h5/7WZQw9Jzj0/ODQc4VDzxsOPYc49Hzi0HOLQ3PNoXnn0Bx0aD46NDcdmqcOzVmH5q9Dc9mhee3QHHdovjs09x2aBw/NiYfmx0Nz5aF589Acemg+PTS3HppnD825h+bfQ3PxoXn50Bx9aL4+NHcfmscPzemH5vcLeudegym/h2IIxVCKYRT3UgynuI9iBMX9FA9QPEjxEMXDFI9QPErxGMXjFE9QPEkxkuIpiqcpnqF4luI5iucpXqB4keIlipcpXok5twb0v8FYRMdYfIHjJnU/8moMdj8nwXupAO/XFPBeLsD7dQW8VwrwfkMB79UCvEcp4L1OgPebCnhvFOD9lgLeWwV4j1bAe4cA7zEKeO8R4P22At4HBHi/o4D3EQHeYxXwPiHAe5wC3mcEeL+rgHdMFJ73ewp4pxTg/b4C3mkFeI9XwDujAO8PFPDOIsD7QwW8cwjwnqCAdx4B3hMV8C4gwPsjBbyLCPD+WAHvEgK8JyngXUaA92QFvCsI8J6igHeiAO9PFPCuIsB7qgLeNQR4T1PAu44A7+kKeDcQ4P2pAt5NBHjPUMB7iYfnPVMB72UCvGcp4L1CgPdnCnivEuA9WwHvNQK85yjgvUGA91wFvDcL8P5cAe9tArznKeC9S4D3fAW89wnw/kIB70MCvL9UwPuYAO8FCnifEuC9UAHvKIH3Y18p4B0nwPtrBbxTC/D+RgHv9AK8FyngnUmA97cKeGcT4L1YAe9cAry/U8A7nwDvJQp4FxLg/b0C3sUEeC9VwLuUAO8fFPAuJ8B7mQLevgDvHxXwriTAe7kC3tUEeP+kgHctAd4rFPCuJ8D7ZwW8GwnwXqmAdzMB3r8AeZu1Bf89+qv879NfY3yd8Q3GUYxvMr7FOJpxDOPbjO8wjmUcx/gu43uM7zOOZ/yA8UPGCYwTGT9i/JhxEuNkximMnzBOZZzGOJ3xU8YZMefrMJPzWYyfMc5mnMM4l/FzxnmM8xm/YPyScQHjQsavGL9m/IZxEeO3jIsZv2Ncwvg941LGHxiXMf7IuJzxJ8YVjD8zrmT8hbEu65CT+yMXY27GPIx5GfMx5mcsEOgrg4UYCzMWYSzKWIyxOGMJxpKMpRhLM5ZhLMtYjrE8YwXGeEafMYExkbEiYyXGyoxVGKsyVmOszliDsSZjLcbajHW8v3Q0WI+xPmMDxoaMjRgbMzZhbMrYjPFKxqsYmzO2YGzJeDVjK8ZrGFszXsvYhrEt43WM7Tzv/55TYfJ7GIcwDmUcxngv43DG+xhHMN7P+ADjg4wPMT7M+Ajjo4yPMT7O+ATjk4wjGZ9ifJrxGcZnGZ9jfJ7xBcYXGV9ifJnxFcZVMd55r2jGuozxSXv5q2Jw14dfgcdK4f11/Qq+0NfKX8HXtNBrdaBusVbtzCv01ykEOHnW77F1zHCBP4P+cokiGUHRx/0N2LBSvH+LgdfovIcKuqxpuEwgmydjAmsiJoAt0hoBE1jruAkY3msFTCCF91cDBl8un1yS68yiZJ2ZPLxZGazMP6+jplhPsYHid4qNFJsoNlNsodhK8QfFNortFDsodlLsothNsYdiL8U+iv0UBygOUhyiOExxhOIoxTGK4xQnKE5SnKI4TXHGNCW5ZRRFNEUMRSxFHEUKipQUqShSU6ShSEuRjiI9RQaKjBRXUGSiyEyRhSJr7F/1yMCY2vt/U04dOCeiAn8WNG3zShH4uS6oFnF0jJSB3+lZa8vAvzcF9PcmVja/K87iZ18Y6l6Au3l3koV/7ti+R49W/brd3b5/58YDenXs3613r2BrhQ4farGYC9Cz/zw2IEVIlrjAn4X+v5QBjLLXX5cxqb6+FvcuwY/2ztcX7Q8bYmR8DLjGhGxU3eyxTN4IYv7gVCA3f2k3YQy4qEChzhJCFTA77ljx0s32u4Jmy0F65gw2Ww6r2XKGodmAQp0lhCpgTkXNtkVBs+UiPXMHmy2X1Wy5w9BsQKHOEkIVMLeiZtuqoNnykJ55g82Wx2q2vGFoNqBQZwmhCphXUbP9oaDZ8pGe+YPNls9qtvxhaDagUGcJoQqYX1GzZY11v9kK0BoLBputgNVsBcPQbEChzhJCFbCgUAFjsEU8785fUmuxDniXthBQv3B9RIFcc3C9hQN3xiIfUSTxmKZIhWPxxy0S6/ZHFIZ3kVh4jc4zJ3vwAXlLL6nHKhrrdl+a2hSNxd8WzZ1Sx4UIWetiyPfDKfV9Vl5M6EJUPHIhwhapuMCFqITjFyLDu4Twhch1Tb1AIyPXGfx8PKnrXA805JIKd/MlhUy0VMREsUUqJWCipR03UcO7dDLezZdxfDdvalNGYDefNxnu5ssiP3BQuJsvK3QhKhe5EGGLVE7gQlTe8QuR4V1e2W6+vJLdfHCKNKnr3AY05AoKd/MVhEw0PmKi2CLFC5io77iJGt5+Mt7NJzi+mze1SRDYzedPhrv5ROREh8LdfKLQhahi5EKELVJFgQtRJccvRIZ3JWW7eaSm4TKBgkImUDliAtgiVRYwgSqOm4DhXSUZ70arOr4bNbWpKrAbLZgMd6PVkCOfCnej1YQuRNUjFyJskaoLXIhqOH4hMrxrKNuN1lC4G80tZAI1IyaALVJNAROo5bgJGN61kvFutLbju1FTm9oCu9HCyXA3WgdY68IKd6N1hC5EdSMXInCRBC5E9Ry/EBne9ZTtRusp3I3mFTKB+hETwBapvoAJNHDcBAzvBsl4N9rQ8d2oqU1Dgd1o0WS4G20ErHVRhbvRRkIXosaRCxG2SI0FLkRNHL8QGd5NlO1GmyjcjeYXMoGmERPAFqmpgAk0c9wEDO9myXg3eqXju1FTmysFdqPFk+Fu9CpgrYsr3I1eJXQhah65EGGL1FzgQtTC8QuR4d1C2W4UqalZW/C7GsyzE0575x6RbTAno3m1pJ+v5h4x/0/oLNjI/88mxs2Mufn/zcuYn3Eb//12xh2MOxl3Me5m3MO4l3Ef437GA4wHGQ8xHmY8wniU8RjjccYTjCcZTzGeZjzD6PH6oxijGWMYYxnjGFMwpmRMxZiaMQ1jWsZ0jOkZMzBmZLyCMRNjZsYsgRq1op+vCdQoVNd1zKEl/7etAv9Pa/r52sA5YF4ub57axMoYucuc2zq+YWxN4r0cjd8wXheL9WQtvNvFylyLXO7x65PheX1DMuR8YzLkfFMy5HxzMuR8SzLkfGsy5HxbMuR8ezLk3D4Zcu6QDDl3TIacOyVDzp2TIecuyZDzHcmQc1cg53B9OJQdd6zzPhzqFvlwCFukbgIfDnV3/MMhw7u7wIdD4fpybOTJJbnOrErWmdnDm5XBtPzzndRrPSh6UvSi6E3Rh6IvRT+Kuyj6UwwI9GTkC6fPe3VIyhdO5+KfO/fqO6DzgM6tBnTo0a1j6CunG7Tv0SNYtNAvCRUv5gIk7T+PDQjyn3/tdHfgdiHaO19l9JnXU+jjEOAaE+6mNQ6MZfJGEPMHwW+VGxj7/62I/lY5oFBnCaEKOBBYQOlm66Wg2QbRGgcHm22Q1WyDw9BsQKHOEkIVcLCiZuunoNnuoTUOCTbbPVazDQlDswGFOksIVcAhiprtLgXNNpTWOCzYbEOtZhsWhmYDCnWWEKqAwxQ1W38FzXYvrXF4sNnutZpteBiaDSjUWUKoAg4XKiB6WD87sBZ3Am9J3QfUL1z3Y5FrDq53ROR+LLZIIwTux97v+P1Yw/t+4WF99Ac8yHvcDzg+BGxq80As/k5VSSX/agxZ6weBtS6p8F+NPSh0IXoociHCFukhgQvRw45fiAzvh4UvRK5r6gUaGbnO4IeBSV1nDyDnRxTu5h8RMtFHIyaKLdKjAib6mOMmang/lox38487vps3tXlcYDdfOhnu5p8A1rq0wt38E0IXoicjFyJskZ4UuBCNdPxCZHiPVLabH6lkNx8cmUvqOgcAOT+lcDf/lJCJPh0xUWyRnhYw0WccN1HD+5lkvJt/1vHdvKnNswK7+bLJcDf/HLDWZRXu5p8TuhA9H7kQYYv0vMCF6AXHL0SG9wvKdvNITcNlAkOETODFiAlgi/SigAm85LgJGN4vJePd6MuO70ZNbV4W2I2WT4a70VeAtS6vcDf6itCF6NXIhQhbpFcFLkSvOX4hMrxfU7YbfU3hbnSYkAm8HjEBbJFeFzCBNxw3AcP7jWS8Gx3l+G7U1GaUwG40PhnuRt8E1jpe4W70TaEL0VuRCxG2SG8JXIhGO34hMrxHK9uNjla4Gx0uZAJjIiaALdIYARN423ETMLzfTsa70Xcc342a2rwjsBtNSIa70bHAWico3I2OFboQjYtciLBFGidwIXrX8QuR4f2ust0oUlOztuCjQM2/VjPfyTWQcXDsX9/R9R79/H6s5/0Tt6SuZ3xseGqQ1HV+oGSdHypZ5wQl65yoZJ0fKVnnx0rWOUnJOicrWecUJev8RMk6pypZ5zQl65yuZJ2fKlnnDCXrnKlknbOUrPMzJeucrWSdc5Ssc66SdX6uZJ3zlKxzvpJ1fqFknV8qWecCJetcqGSdXylZ59dK1vmNknUuUrLOb5Wsc7GSdX6nZJ1LlKzzeyXrXKpknT8oWecyJev8Uck6lytZ50/gIQPzmWgiH683fwbah7Ev4xDGYYzDGQcwjmf8gPFDxgmMExk/YvyYcRLjZMYpjJ8wTmWcxjid8VPGGYwzGWcxfsY4m3EO41zGzxnnMc5n/ILxS8YFjAsZv2L8mvEbxkWM3zIuZvyOcQnj94xLGX9gXMb4I+Nyxp9i//pMegX9/DPPLQQ/x76T/5v3GFcE/p+V9PMv1ufYLg+LrXJ8WMx8a6D5DmH0OV0RPCwmwbtLLJ53pTANySV1nb8C+xJYa1+LfquTmX4ue+xvjnus8dd2Al5T1XGPbUucrxPgXU2JR6wB9iWw1r4W/dYmM/1c9th1jnus0U5iH1vTcY81vG8V8NhaSjxiPbAvgbX2tei3IZnp57LH/u64x7am9bUR8JqNsW57rBTvTbHJr8c3O97j5ngS+4i6ju8jzPFuFOjxekqug1uAfQmsta9Fv63JTD+XPfYPxz3WfNYj4bENHfdYw/tmAY9tpMQjtgH7ElhrX4t+25OZfi577A7HPZZKIuKxTR33WMO7s4DHNlPiETuBfQmsta9Fv13JTD+XPXa34x5rHhQj4bHNHfdYw/sWAY9tocQj9gD7ElhrX4t+e5OZfi577D7HPTaVJ+OxrRz3WMO7vYDHXqPEI/YD+xJYa1+LfgeSmX4ue+xBsMdq4HzI8euK+ScEEteVNo5fVwzvGwSuK22V+OJhYF8Ca+1r0e9IMtPPZY896rjHxnkyHnu94x5reF8v4LE3KPGIY8C+BNba16Lf8WSmn8see8Jxj03vyXjszY57rOHdUcBjb1HiESeBfQmsta9Fv1PJTD+XPfa04x57hSfjsbc77rGG9+0CHtteiUecAfYlsNa+Fv28uOSln8seGxXntsc+6Ml4bCfHPdbw7iDgsZ2VeEQ0sC+Btfa16BeTzPRz2WNjHffYNJ6Mx3Z13GMN79sEPLabEo+IA/YlsNa+Fv1SJDP9XPbYlI57rOk9CY/t4bjHGt6dBDy2pxKPSAXsS2CtfS36pU5m+rnssWkc99i0nozH9nHcYw3vOwQ8tq8Sj0gL7EtgrX0t+qVLZvq57LHpHffYdJ6Mx/Z33GMN764CHjtAiUdkAPYlsNa+Fv0yJjP9XPbYKxz32IyejMcOctxjDe+bBDx2sBKPyATsS2CtfS36ZU4m+qHPO+OtWwXOu6GO8zbPnNwiwHuYkvMlC/B8AdbaH6bgfNkg0Df3Oc7bPOt9vQDvEUrOl6zA8wVYa3+EgvPF3MdH982Drj9zjDinEuD9kJLzJRvwfAHW2n9IwflyRMBnH3Wct3k2wGEB3o8pOV+yA88XYK39xxScL8cF+uZJx3mbf+d9TID3SCXnSw7g+QKstT9SwfmyXaBvnnGct3n++TYB3s8qOV9yAs8XYK39ZxWcLzEC+/gXXP/uD+IcLcD7RSXnSy7g+QKstS+lH7rOueN0rDOPknXmVbLOfHHu+/lagX3AK477ufk+5DUCvF9V4uf5gX4OrLX/qhI/L6DEfwoqWWchJessrGSdRZSss6iSdRZTss7iStZZQsk6SypZZykF+8xNAvutNxzfZ5rvK94owHuUkn1maeA+E1hrf5SSfWYZJf5TVsk6yznukyvJKw4K+EV5JfWpoGSd8UrW6StZZ4KSdSYqWWdFJeuspGSdlZWss4qSdVZVss5qCt5X7RLYL4x2/H2V+W7hnQK8xyh5X1Ud+L4KWGt/jIL5hQMCfTPWcd7mOwz3C/Aep+R8qQE8X4C19scpOF9WC/TN+47zXkWcfxXgPV7J+VITeL4Aa+2PV3C+pBCYE5vg+nfmEec4Ad4TlZwvtYDnC7DW/kQF50s6gb6Z5PrzdolzWgHek5WcL7WB5wuw1v5kBedLRoG+mer6d1kR5wwCvKcpOV/qAM8XYK39aQrOl1MC+/gZjvM238l3UoD3TCXnS13g+QKstT9TwfmyV6BvZjvOezdx3iPAe46S86Ue8HwB1tqfo+B8ySywL5nn+vfeEedMArznKzlf6gPPF2Ct/fkKzhdPoG8WOM7bfH/nGYHry0Il50sD4PkCrLUvpV80uH+Cz6dLai0axungnBXIuZESztmAnBsr4ZwdyLmJEs45gJybKuGcE8i5mRLOuYCcr1TCOTeQ81VKOOcBcm6uhHNeIOcWSjjnA3JuqYRzfiDnq5VwLgDk3EoJ54JAztco4VwIyLm1Es6FgZyvVcK5CJBzGyWciwI5t1XCuRiQ83VKOBcHcm6nhHMJIOfrlXAuCeR8gxLOpYCcb1TCuTSQ801KOJcBcr5ZCeeyQM63KOFcDsj5ViWcywM536aEcwUg59uVcI4Hcm6vhLMP5NxBCecEIOeOSjgnAjl3UsK5IpBzZyWcKwE5d1HCuTKQ8x1KOFcBcu6qhHNVIOduSjhXA3LuroRzdSDnO5VwrgHk3EMJ55pAzj2VcK4F5NxLCefaQM69lXCuA+TcRwnnukDOfZVwrgfk3E8J5/pAzncp4dwAyLk/kHM7Pk4UczZz//xPNLwUFCkpUlGkpkhDkZYiHUV6igwUGSmuoMhEkZkiC0VWimwU2SlyUOSkyEWRmyIPRV6KfBT5KQpQFKQoRFGYoghFUYpiFMUpSlCUpChFUZqiDEVZinIU5SkqGA0ofIoEoy1FRYpKFJUpqlBUpahGUZ2iBkVNiloUtSnqcI3rUdSnaEDRkKIRRWOKJhRNKZpRXElxFUVzihYULSmupmhFcQ1Fa4prKdpQtKW4jqIdr828zNy9mUM3c9lmTtnM7Zo5VjPXaeYczdyfmYMzc2FmTsrMDZk5GjNXYuYszNyB+RzefC5tPqc1n1uaz/HM51rmcx7zuYf5HMDcFzf3ic19U3Mf0dxXM/eZzH0Xcx/CvC8371PN+zbzPsbs680+1+z7zD7I7AvMddJcN4yPGl8x55npu/8Bqkc0Oz14BQA=", + "bytecode": "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", + "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" + }, + { + "name": "stev", + "functionType": "unconstrained", + "parameters": [ + { + "name": "contract_address", + "type": { + "kind": "field" + }, + "visibility": "private" + }, + { + "name": "storage_slot", + "type": { + "kind": "field" + }, + "visibility": "private" + }, + { + "name": "preimage", + "type": { + "kind": "array", + "length": 20, + "type": { + "kind": "field" + } + }, + "visibility": "private" + } + ], + "returnTypes": [ + { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + ], + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ] diff --git a/yarn-project/noir-contracts/src/libs/noir-aztec/src/constants_gen.nr b/yarn-project/noir-contracts/src/libs/noir-aztec/src/constants_gen.nr index 9fb0a0477c9..0292b4489e1 100644 --- a/yarn-project/noir-contracts/src/libs/noir-aztec/src/constants_gen.nr +++ b/yarn-project/noir-contracts/src/libs/noir-aztec/src/constants_gen.nr @@ -59,6 +59,7 @@ global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: comptime Field = 49; global CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: comptime Field = 3; global CONTRACT_STORAGE_READ_LENGTH: comptime Field = 2; global PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: comptime Field = 51; +global GET_SINGLE_NOTE_ORACLE_RETURN_LENGTH: comptime Field = 22; global GENERATOR_INDEX__COMMITMENT = 1; global GENERATOR_INDEX__COMMITMENT_PLACEHOLDER = 2; global GENERATOR_INDEX__OUTER_COMMITMENT = 3; diff --git a/yarn-project/noir-contracts/src/libs/noir-aztec/src/note/note_getter.nr b/yarn-project/noir-contracts/src/libs/noir-aztec/src/note/note_getter.nr index 597edec5eb9..c711dddea80 100644 --- a/yarn-project/noir-contracts/src/libs/noir-aztec/src/note/note_getter.nr +++ b/yarn-project/noir-contracts/src/libs/noir-aztec/src/note/note_getter.nr @@ -5,6 +5,7 @@ use crate::note::note_interface::NoteInterface; use crate::oracle; use crate::constants_gen::MAX_READ_REQUESTS_PER_CALL; use crate::constants_gen::GET_NOTE_ORACLE_RETURN_LENGTH; +use crate::constants_gen::GET_SINGLE_NOTE_ORACLE_RETURN_LENGTH; use crate::constants_gen::MAX_NOTES_PER_PAGE; use crate::constants_gen::VIEW_NOTE_ORACLE_RETURN_LENGTH; @@ -28,7 +29,7 @@ fn get_note( storage_slot: Field, note_interface: NoteInterface, ) -> (Context, Note) { - let note = oracle::notes::get_note(storage_slot, note_interface); + let note = oracle::notes::get_note(storage_slot, note_interface, [0; GET_SINGLE_NOTE_ORACLE_RETURN_LENGTH]); context = ensure_note_exists(context, storage_slot, note_interface, note); (context, note) } diff --git a/yarn-project/noir-contracts/src/libs/noir-aztec/src/oracle/notes.nr b/yarn-project/noir-contracts/src/libs/noir-aztec/src/oracle/notes.nr index 457bd0de20f..0ee570eac6b 100644 --- a/yarn-project/noir-contracts/src/libs/noir-aztec/src/oracle/notes.nr +++ b/yarn-project/noir-contracts/src/libs/noir-aztec/src/oracle/notes.nr @@ -33,11 +33,11 @@ unconstrained fn notify_nullified_note( } #[oracle(getNote)] -fn get_note_oracle(_storage_slot: Field) -> [Field; S] {} - -unconstrained fn get_note_oracle_wrapper(storage_slot: Field) -> [Field; S] { - get_note_oracle(storage_slot) -} +fn get_note_oracle( + _storage_slot: Field, + _return_size: u32, + _zero_fields: [Field; S] +) -> [Field; S] {} #[oracle(getNotes)] fn get_notes_oracle( @@ -50,6 +50,13 @@ fn get_notes_oracle( _zero_fields: [Field; S], ) -> [Field; S] {} +unconstrained fn get_note_oracle_wrapper( + storage_slot: Field, + zero_fields: [Field; S] +) -> [Field; S] { + get_note_oracle(storage_slot, zero_fields.len() as u32, zero_fields) +} + unconstrained fn get_notes_oracle_wrapper( storage_slot: Field, sort_by: [u8; N], @@ -62,15 +69,20 @@ unconstrained fn get_notes_oracle_wrapper( get_notes_oracle(storage_slot, sort_by, sort_order, limit, offset, return_size, fields) } -fn get_note( +fn get_note( storage_slot: Field, note_interface: NoteInterface, + zero_fields: [Field; NS] ) -> Note { - let fields: [Field; N] = get_note_oracle_wrapper(storage_slot); + let fields: [Field; NS] = get_note_oracle_wrapper(storage_slot, zero_fields); let has_note = fields[0] == 1; + let contract_address = fields[1]; if (has_note) { let deserialise = note_interface.deserialise; - deserialise(arr_copy_slice(fields, [0; N], 1)) + let set_header = note_interface.set_header; + let header = NoteHeader { contract_address, storage_slot }; + let mut note = deserialise(arr_copy_slice(fields, [0; N], 2)); + set_header(note, header) } else { let dummy = note_interface.dummy; dummy() diff --git a/yarn-project/noir-contracts/src/types/ecdsa_account.ts b/yarn-project/noir-contracts/src/types/ecdsa_account.ts index 485c10a7209..6defc918b78 100644 --- a/yarn-project/noir-contracts/src/types/ecdsa_account.ts +++ b/yarn-project/noir-contracts/src/types/ecdsa_account.ts @@ -67,5 +67,13 @@ export class EcdsaAccountContract extends Contract { signature: (bigint | number)[], ) => ContractFunctionInteraction) & Pick; + + /** stev(contract_address: field, storage_slot: field, preimage: array) */ + stev: (( + contract_address: Fr | bigint | number | { toField: () => Fr }, + storage_slot: Fr | bigint | number | { toField: () => Fr }, + preimage: (Fr | bigint | number | { toField: () => Fr })[], + ) => ContractFunctionInteraction) & + Pick; }; } From d45bbd8cdbda95dff30571d7dd13c28eea37ea62 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 14 Jul 2023 15:20:42 -0300 Subject: [PATCH 3/9] Use ecdsa private key for signing instead of encryption key (d'oh!) --- .../src/e2e_account_contracts.test.ts | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index 959f5f4da41..a1dff8a5c3a 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -40,22 +40,22 @@ async function createNewAccount( aztecRpcServer: AztecRPCServer, abi: ContractAbi, args: any[], - privateKey: Buffer, + encryptionPrivateKey: Buffer, createWallet: CreateAccountImplFn, ) { const salt = Fr.random(); - const publicKey = await generatePublicKey(privateKey); + const publicKey = await generatePublicKey(encryptionPrivateKey); const { address, partialAddress } = await getContractDeploymentInfo(abi, args, salt, publicKey); - await aztecRpcServer.addAccount(privateKey, address, partialAddress); + await aztecRpcServer.addAccount(encryptionPrivateKey, address, partialAddress); await deployContract(aztecRpcServer, publicKey, abi, args, salt); - const wallet = new AccountWallet(aztecRpcServer, await createWallet(address, partialAddress, privateKey)); + const wallet = new AccountWallet(aztecRpcServer, await createWallet(address, partialAddress, encryptionPrivateKey)); return { wallet, address, partialAddress }; } type CreateAccountImplFn = ( address: AztecAddress, partialAddress: PartialContractAddress, - privateKey: Buffer, + encryptionPrivateKey: Buffer, ) => Promise; function itShouldBehaveLikeAnAccountContract(abi: ContractAbi, argsFn: () => any[], createWallet: CreateAccountImplFn) { @@ -68,13 +68,13 @@ function itShouldBehaveLikeAnAccountContract(abi: ContractAbi, argsFn: () => any beforeEach(async () => { context = await setup(); - const privateKey = randomBytes(32); + const encryptionPrivateKey = randomBytes(32); const { aztecRpcServer } = context; ({ wallet, address, partialAddress } = await createNewAccount( aztecRpcServer, abi, argsFn(), - privateKey, + encryptionPrivateKey, createWallet, )); @@ -117,15 +117,21 @@ function itShouldBehaveLikeAnAccountContract(abi: ContractAbi, argsFn: () => any describe('e2e_account_contracts', () => { describe('schnorr account', () => { - const createSchnorrWallet = async (address: AztecAddress, partial: PartialContractAddress, privateKey: Buffer) => - new SingleKeyAccountContract(address, partial, privateKey, await Schnorr.new()); + const createSchnorrWallet = async ( + address: AztecAddress, + partial: PartialContractAddress, + encryptionPrivateKey: Buffer, + ) => new SingleKeyAccountContract(address, partial, encryptionPrivateKey, await Schnorr.new()); itShouldBehaveLikeAnAccountContract(SchnorrAccountContractAbi, () => [], createSchnorrWallet); }); - describe.skip('ecdsa account', () => { - const createEcdsaWallet = async (address: AztecAddress, _partial: PartialContractAddress, privateKey: Buffer) => - new StoredKeyAccountContract(address, privateKey, await Ecdsa.new()); + describe('ecdsa account', () => { + const createEcdsaWallet = async ( + address: AztecAddress, + _partial: PartialContractAddress, + _encryptionPrivateKey: Buffer, + ) => new StoredKeyAccountContract(address, ecdsaPrivateKey, await Ecdsa.new()); let ecdsaPrivateKey: Buffer; let ecdsaPublicKey: Buffer; From bfbf031815971e4463d988b9a939e7a46738b731 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 14 Jul 2023 15:21:05 -0300 Subject: [PATCH 4/9] Add noir debug call for arrays with text --- yarn-project/acir-simulator/src/acvm/acvm.ts | 3 ++- yarn-project/acir-simulator/src/client/debug.ts | 6 +++--- .../acir-simulator/src/client/private_execution.ts | 6 +++++- .../src/account_impl/stored_key_account_contract.ts | 10 ++++++++-- .../src/contracts/ecdsa_account_contract/src/main.nr | 8 +++++++- .../src/libs/noir-aztec/src/oracle/debug_log.nr | 8 ++++++++ 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/acvm.ts b/yarn-project/acir-simulator/src/acvm/acvm.ts index 0aafa2291fb..e207a520241 100644 --- a/yarn-project/acir-simulator/src/acvm/acvm.ts +++ b/yarn-project/acir-simulator/src/acvm/acvm.ts @@ -41,7 +41,8 @@ type ORACLE_NAMES = | 'emitEncryptedLog' | 'emitUnencryptedLog' | 'getPublicKey' - | 'debugLog'; + | 'debugLog' + | 'debugLogWithPrefix'; /** * A type that does not require all keys to be present. diff --git a/yarn-project/acir-simulator/src/client/debug.ts b/yarn-project/acir-simulator/src/client/debug.ts index b1c38afbeef..f03a1f251c8 100644 --- a/yarn-project/acir-simulator/src/client/debug.ts +++ b/yarn-project/acir-simulator/src/client/debug.ts @@ -8,7 +8,7 @@ import { ACVMField } from '../acvm/index.js'; * @param msg - array of ACVMFields where each represents a single ascii character * @returns string representation of the message */ -function acvmFieldMessageToString(msg: ACVMField[]): string { +export function acvmFieldMessageToString(msg: ACVMField[]): string { let msgStr = ''; for (const msgChar of msg) { const asciiCode = Number(msgChar); @@ -81,10 +81,10 @@ function processFieldOrArray(fieldOrArray: string[]) { } // Check if all the elements start with 63 zero bytes - // --> if yes, we have an array of bytes and we print as decimal values + // --> if yes, we have an array of bytes and we print as hex if (onlyBytes(fieldOrArray)) { const decimalArray = fieldOrArray.map(element => parseInt(element, 16)); - return '[' + decimalArray.join(', ') + ']'; + return '0x' + Buffer.from(decimalArray).toString('hex'); } return '[' + fieldOrArray.join(', ') + ']'; diff --git a/yarn-project/acir-simulator/src/client/private_execution.ts b/yarn-project/acir-simulator/src/client/private_execution.ts index 64c598021c9..ce1910d7dac 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.ts @@ -30,7 +30,7 @@ import { } from '../acvm/index.js'; import { ExecutionResult, NewNoteData, NewNullifierData } from '../index.js'; import { ClientTxExecutionContext, PendingNoteData } from './client_execution_context.js'; -import { oracleDebugCallToFormattedStr } from './debug.js'; +import { acvmFieldMessageToString, oracleDebugCallToFormattedStr } from './debug.js'; /** * The private function execution class. @@ -135,6 +135,10 @@ export class PrivateFunctionExecution { this.log(oracleDebugCallToFormattedStr(args)); return Promise.resolve(ZERO_ACVM_FIELD); }, + debugLogWithPrefix: (arg0, ...args) => { + this.log(`${acvmFieldMessageToString(arg0)}: ${oracleDebugCallToFormattedStr(args)}`); + return Promise.resolve(ZERO_ACVM_FIELD); + }, enqueuePublicFunctionCall: async ([acvmContractAddress], [acvmFunctionSelector], [acvmArgsHash]) => { const enqueuedRequest = await this.enqueuePublicFunctionCall( frToAztecAddress(fromACVMField(acvmContractAddress)), diff --git a/yarn-project/aztec.js/src/account_impl/stored_key_account_contract.ts b/yarn-project/aztec.js/src/account_impl/stored_key_account_contract.ts index 12b99117a0d..0f2ce99b5ac 100644 --- a/yarn-project/aztec.js/src/account_impl/stored_key_account_contract.ts +++ b/yarn-project/aztec.js/src/account_impl/stored_key_account_contract.ts @@ -5,6 +5,7 @@ import { ExecutionRequest, PackedArguments, TxExecutionRequest } from '@aztec/ty import partition from 'lodash.partition'; +import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import EcdsaAccountContractAbi from '../abis/ecdsa_account_contract.json' assert { type: 'json' }; import { buildPayload, hashPayload } from './entrypoint_payload.js'; import { AccountImplementation } from './index.js'; @@ -14,7 +15,11 @@ import { AccountImplementation } from './index.js'; * every new request in order to validate the payload signature. */ export class StoredKeyAccountContract implements AccountImplementation { - constructor(private address: AztecAddress, private privateKey: Buffer, private signer: Signer) {} + private log: DebugLogger; + + constructor(private address: AztecAddress, private privateKey: Buffer, private signer: Signer) { + this.log = createDebugLogger('aztec:client:accounts:stored_key'); + } getAddress(): AztecAddress { return this.address; @@ -31,8 +36,9 @@ export class StoredKeyAccountContract implements AccountImplementation { const wasm = await CircuitsWasm.get(); const { payload, packedArguments: callsPackedArguments } = await buildPayload(privateCalls, publicCalls); const hash = hashPayload(payload); - const signature = this.signer.constructSignature(hash, this.privateKey).toBuffer(); + this.log(`Signed challenge ${hash.toString('hex')} as ${signature.toString('hex')}`); + const args = [payload, signature]; const abi = this.getEntrypointAbi(); const selector = generateFunctionSelector(abi.name, abi.parameters); diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr index cef3736f432..a5fb2c2f4ec 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr @@ -49,7 +49,13 @@ contract EcdsaAccount { let payload_bytes: [u8; entrypoint::ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = payload.to_be_bytes(); let challenge: [u8; 32] = std::hash::sha256(payload_bytes); let verification = std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, challenge); - assert(verification == true); + // assert(verification == true); + + debug_log::debug_log_format("Verification result is {0}", [verification as Field]); + debug_log::debug_log_array_with_prefix("public_key.x", public_key.x); + debug_log::debug_log_array_with_prefix("public_key.y", public_key.y); + debug_log::debug_log_array_with_prefix("challenge", challenge); + debug_log::debug_log_array_with_prefix("signature", signature); context = payload.execute_calls(context); context.finish() diff --git a/yarn-project/noir-contracts/src/libs/noir-aztec/src/oracle/debug_log.nr b/yarn-project/noir-contracts/src/libs/noir-aztec/src/oracle/debug_log.nr index 8f5b3f9b79b..5be0cc39ffc 100644 --- a/yarn-project/noir-contracts/src/libs/noir-aztec/src/oracle/debug_log.nr +++ b/yarn-project/noir-contracts/src/libs/noir-aztec/src/oracle/debug_log.nr @@ -9,6 +9,8 @@ fn debug_log_format_oracle(_msg: T, _args: [Field; N], _num_args: Field) - fn debug_log_field_oracle(_field: Field) -> Field {} #[oracle(debugLog)] fn debug_log_array_oracle(_arbitrary_array: [T;N]) -> Field {} +#[oracle(debugLogWithPrefix)] +fn debug_log_array_with_prefix_oracle(_prefix: S, _arbitrary_array: [T;N]) -> Field {} /// NOTE: call this with a str msg of length > 1 /// Example: @@ -38,3 +40,9 @@ unconstrained fn debug_log_field(field: Field) { unconstrained fn debug_log_array(arbitrary_array: [T; N]) { assert(debug_log_array_oracle(arbitrary_array) == 0); } + +/// Example: +/// `debug_log_array_with_prefix("Prefix", my_array);` +unconstrained fn debug_log_array_with_prefix(prefix: S, arbitrary_array: [T; N]) { + assert(debug_log_array_with_prefix_oracle(prefix, arbitrary_array) == 0); +} From 122deb63bb479de16f41fda2fe456a8ad55e9c21 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 14 Jul 2023 19:27:23 -0300 Subject: [PATCH 5/9] Revert "chore: using bb ecdsa (#954)" This reverts commit 0efa8f1575902a8a4e3ea72866a84602d3b84fa0. --- yarn-project/circuits.js/package.json | 1 + .../barretenberg/crypto/ecdsa/index.test.ts | 4 ++-- .../src/barretenberg/crypto/ecdsa/index.ts | 20 ++++++++++++++----- yarn-project/end-to-end/package.json | 1 + yarn-project/yarn.lock | 13 +++++++++++- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/yarn-project/circuits.js/package.json b/yarn-project/circuits.js/package.json index 5e8280a0faf..39dfd8edfa6 100644 --- a/yarn-project/circuits.js/package.json +++ b/yarn-project/circuits.js/package.json @@ -40,6 +40,7 @@ "dependencies": { "@aztec/foundation": "workspace:^", "@msgpack/msgpack": "^3.0.0-beta2", + "@noble/curves": "^1.0.0", "@types/lodash.camelcase": "^4.3.7", "@types/lodash.times": "^4.3.7", "cross-fetch": "^3.1.5", diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.test.ts b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.test.ts index a05f16f9b8c..681b1e63a9d 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.test.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.test.ts @@ -11,7 +11,7 @@ describe('ecdsa', () => { ecdsa = new Ecdsa(wasm); }); - it('should verify signature', () => { + it.skip('should verify signature', () => { // prettier-ignore const privateKey = Buffer.from([ 0x0b, 0x9b, 0x3a, 0xde, 0xe6, 0xb3, 0xd8, 0x1b, 0x28, 0xa0, 0x88, 0x6b, 0x2a, 0x84, 0x15, 0xc7, @@ -25,7 +25,7 @@ describe('ecdsa', () => { expect(verified).toBe(true); }); - it('should recover public key from signature', () => { + it.skip('should recover public key from signature', () => { // prettier-ignore const privateKey = Buffer.from([ 0x0b, 0x9b, 0x3a, 0xde, 0xe6, 0xb3, 0xd8, 0x1b, 0x28, 0xa0, 0x88, 0x6b, 0x2a, 0x84, 0x15, 0xc7, diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts index 9e8eb99d689..1007fe4da7b 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts @@ -1,8 +1,10 @@ import { IWasmModule } from '@aztec/foundation/wasm'; - +import { EcdsaSignature } from './signature.js'; import { CircuitsWasm } from '../../../index.js'; import { Signer } from '../index.js'; -import { EcdsaSignature } from './signature.js'; +import { secp256k1 } from '@noble/curves/secp256k1'; +import { toBufferBE } from '@aztec/foundation/bigint-buffer'; +import { numToUInt32BE } from '@aztec/foundation/serialize'; export * from './signature.js'; @@ -43,10 +45,18 @@ export class Ecdsa implements Signer { this.wasm.writeMemory(mem, msg); this.wasm.call('ecdsa__construct_signature', mem, msg.length, 0, 32, 64, 96); + // TODO(#913): Understand why this doesn't work + // const sig = new EcdsaSignature( + // Buffer.from(this.wasm.getMemorySlice(32, 64)), + // Buffer.from(this.wasm.getMemorySlice(64, 96)), + // Buffer.from(this.wasm.getMemorySlice(96, 97)), + // ); + + const signature = secp256k1.sign(msg, privateKey); return new EcdsaSignature( - Buffer.from(this.wasm.getMemorySlice(32, 64)), - Buffer.from(this.wasm.getMemorySlice(64, 96)), - Buffer.from(this.wasm.getMemorySlice(96, 97)), + toBufferBE(signature.r, 32), + toBufferBE(signature.s, 32), + numToUInt32BE(signature.recovery!).subarray(3, 4), ); } diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index 9f4ba51be52..c2b76067456 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -35,6 +35,7 @@ "@aztec/p2p": "workspace:^", "@aztec/types": "workspace:^", "@jest/globals": "^29.5.0", + "@noble/curves": "^1.0.0", "@types/jest": "^29.5.0", "@types/levelup": "^5.1.2", "@types/lodash.every": "^4.6.7", diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 23a2f40f0fe..db256f91951 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -235,6 +235,7 @@ __metadata: "@aztec/foundation": "workspace:^" "@jest/globals": ^29.5.0 "@msgpack/msgpack": ^3.0.0-beta2 + "@noble/curves": ^1.0.0 "@types/detect-node": ^2.0.0 "@types/jest": ^29.5.0 "@types/lodash.camelcase": ^4.3.7 @@ -309,6 +310,7 @@ __metadata: "@aztec/p2p": "workspace:^" "@aztec/types": "workspace:^" "@jest/globals": ^29.5.0 + "@noble/curves": ^1.0.0 "@rushstack/eslint-patch": ^1.1.4 "@types/jest": ^29.5.0 "@types/levelup": ^5.1.2 @@ -2439,6 +2441,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:^1.0.0": + version: 1.1.0 + resolution: "@noble/curves@npm:1.1.0" + dependencies: + "@noble/hashes": 1.3.1 + checksum: 2658cdd3f84f71079b4e3516c47559d22cf4b55c23ac8ee9d2b1f8e5b72916d9689e59820e0f9d9cb4a46a8423af5b56dc6bb7782405c88be06a015180508db5 + languageName: node + linkType: hard + "@noble/ed25519@npm:^1.6.0": version: 1.7.3 resolution: "@noble/ed25519@npm:1.7.3" @@ -2453,7 +2464,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.3.0, @noble/hashes@npm:~1.3.0": +"@noble/hashes@npm:1.3.1, @noble/hashes@npm:^1.3.0, @noble/hashes@npm:~1.3.0": version: 1.3.1 resolution: "@noble/hashes@npm:1.3.1" checksum: 7fdefc0f7a0c1ec27acc6ff88841793e3f93ec4ce6b8a6a12bfc0dd70ae6b7c4c82fe305fdfeda1735d5ad4a9eebe761e6693b3d355689c559e91242f4bc95b1 From e907f497631574c1577c71b40803576311e0fcaf Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 14 Jul 2023 19:48:38 -0300 Subject: [PATCH 6/9] Properly inject invalid signing key for failing test --- .../src/e2e_account_contracts.test.ts | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index a1dff8a5c3a..cf7eb448f18 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -41,14 +41,16 @@ async function createNewAccount( abi: ContractAbi, args: any[], encryptionPrivateKey: Buffer, - createWallet: CreateAccountImplFn, + useProperKey: boolean, + createAccountImpl: CreateAccountImplFn, ) { const salt = Fr.random(); const publicKey = await generatePublicKey(encryptionPrivateKey); const { address, partialAddress } = await getContractDeploymentInfo(abi, args, salt, publicKey); await aztecRpcServer.addAccount(encryptionPrivateKey, address, partialAddress); await deployContract(aztecRpcServer, publicKey, abi, args, salt); - const wallet = new AccountWallet(aztecRpcServer, await createWallet(address, partialAddress, encryptionPrivateKey)); + const account = await createAccountImpl(address, partialAddress, encryptionPrivateKey, useProperKey); + const wallet = new AccountWallet(aztecRpcServer, account); return { wallet, address, partialAddress }; } @@ -56,26 +58,33 @@ type CreateAccountImplFn = ( address: AztecAddress, partialAddress: PartialContractAddress, encryptionPrivateKey: Buffer, + useProperKey: boolean, ) => Promise; -function itShouldBehaveLikeAnAccountContract(abi: ContractAbi, argsFn: () => any[], createWallet: CreateAccountImplFn) { +function itShouldBehaveLikeAnAccountContract( + abi: ContractAbi, + argsFn: () => any[], + createAccountImpl: CreateAccountImplFn, +) { describe(`behaves like an account contract`, () => { let context: Awaited>; let child: ChildContract; let address: AztecAddress; let partialAddress: PartialContractAddress; let wallet: AccountWallet; + let encryptionPrivateKey: Buffer; beforeEach(async () => { context = await setup(); - const encryptionPrivateKey = randomBytes(32); + encryptionPrivateKey = randomBytes(32); const { aztecRpcServer } = context; ({ wallet, address, partialAddress } = await createNewAccount( aztecRpcServer, abi, argsFn(), encryptionPrivateKey, - createWallet, + true, + createAccountImpl, )); const { address: childAddress } = await deployContract(aztecRpcServer, Point.random(), ChildContract.abi, []); @@ -105,7 +114,7 @@ function itShouldBehaveLikeAnAccountContract(abi: ContractAbi, argsFn: () => any it('fails to call a function using an invalid signature', async () => { const invalidWallet = new AccountWallet( context.aztecRpcServer, - await createWallet(address, partialAddress, randomBytes(32)), + await createAccountImpl(address, partialAddress, encryptionPrivateKey, false), ); const childWithInvalidWallet = new ChildContract(child.address, invalidWallet); await expect(childWithInvalidWallet.methods.value(42).simulate()).rejects.toThrowError( @@ -121,7 +130,14 @@ describe('e2e_account_contracts', () => { address: AztecAddress, partial: PartialContractAddress, encryptionPrivateKey: Buffer, - ) => new SingleKeyAccountContract(address, partial, encryptionPrivateKey, await Schnorr.new()); + useProperKey: boolean, + ) => + new SingleKeyAccountContract( + address, + partial, + useProperKey ? encryptionPrivateKey : randomBytes(32), + await Schnorr.new(), + ); itShouldBehaveLikeAnAccountContract(SchnorrAccountContractAbi, () => [], createSchnorrWallet); }); @@ -131,7 +147,8 @@ describe('e2e_account_contracts', () => { address: AztecAddress, _partial: PartialContractAddress, _encryptionPrivateKey: Buffer, - ) => new StoredKeyAccountContract(address, ecdsaPrivateKey, await Ecdsa.new()); + useProperKey: boolean, + ) => new StoredKeyAccountContract(address, useProperKey ? ecdsaPrivateKey : randomBytes(32), await Ecdsa.new()); let ecdsaPrivateKey: Buffer; let ecdsaPublicKey: Buffer; From 4028f5f762907f43cec6b48d9a4620748bc9e10f Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 14 Jul 2023 19:48:49 -0300 Subject: [PATCH 7/9] Reenable signature verification in ecdsa contract --- .../src/contracts/ecdsa_account_contract/src/main.nr | 12 ++++++------ .../src/examples/ecdsa_account_contract.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr index a5fb2c2f4ec..7d0ab9e1d31 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr @@ -49,13 +49,13 @@ contract EcdsaAccount { let payload_bytes: [u8; entrypoint::ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = payload.to_be_bytes(); let challenge: [u8; 32] = std::hash::sha256(payload_bytes); let verification = std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, challenge); - // assert(verification == true); + assert(verification == true); - debug_log::debug_log_format("Verification result is {0}", [verification as Field]); - debug_log::debug_log_array_with_prefix("public_key.x", public_key.x); - debug_log::debug_log_array_with_prefix("public_key.y", public_key.y); - debug_log::debug_log_array_with_prefix("challenge", challenge); - debug_log::debug_log_array_with_prefix("signature", signature); + // debug_log::debug_log_format("Verification result is {0}", [verification as Field]); + // debug_log::debug_log_array_with_prefix("public_key.x", public_key.x); + // debug_log::debug_log_array_with_prefix("public_key.y", public_key.y); + // debug_log::debug_log_array_with_prefix("challenge", challenge); + // debug_log::debug_log_array_with_prefix("signature", signature); context = payload.execute_calls(context); context.finish() diff --git a/yarn-project/noir-contracts/src/examples/ecdsa_account_contract.json b/yarn-project/noir-contracts/src/examples/ecdsa_account_contract.json index 3e78737edae..f39989375ff 100644 --- a/yarn-project/noir-contracts/src/examples/ecdsa_account_contract.json +++ b/yarn-project/noir-contracts/src/examples/ecdsa_account_contract.json @@ -100,7 +100,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { From 7f33c26665b72609a569ee3bcbc4b134b0fe4f24 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 18 Jul 2023 14:22:01 -0300 Subject: [PATCH 8/9] Split SchnorrAccount into single and multi key flavours --- yarn-project/aztec-cli/src/index.ts | 12 +- .../examples/uniswap_trade_on_l1_from_l2.ts | 4 +- .../src/examples/zk_token_contract.ts | 4 +- .../schnorr_single_key_account_contract.json | 96 ++++++++++++ .../single_key_account_contract.ts | 6 +- .../stored_key_account_contract.ts | 2 +- .../src/barretenberg/crypto/ecdsa/index.ts | 10 +- .../src/e2e_account_contracts.test.ts | 59 +++++--- yarn-project/end-to-end/src/utils.ts | 6 +- .../Nargo.toml | 7 + .../src/main.nr | 93 ++++++++++++ .../src/public_key_note.nr | 109 ++++++++++++++ .../src/storage.nr | 21 +++ .../Nargo.toml | 0 .../src/main.nr | 2 +- .../noir-contracts/src/examples/index.ts | 6 +- .../examples/schnorr_account_contract.json | 100 ------------- .../schnorr_multi_key_account_contract.json | 137 ++++++++++++++++++ .../schnorr_single_key_account_contract.json | 100 +++++++++++++ .../noir-contracts/src/scripts/copy_output.ts | 2 +- .../noir-contracts/src/types/index.ts | 3 +- .../src/types/schnorr_multi_key_account.ts | 83 +++++++++++ ...count.ts => schnorr_single_key_account.ts} | 14 +- 23 files changed, 723 insertions(+), 153 deletions(-) create mode 100644 yarn-project/aztec.js/src/abis/schnorr_single_key_account_contract.json create mode 100644 yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/Nargo.toml create mode 100644 yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/main.nr create mode 100644 yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/public_key_note.nr create mode 100644 yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/storage.nr rename yarn-project/noir-contracts/src/contracts/{schnorr_account_contract => schnorr_single_key_account_contract}/Nargo.toml (100%) rename yarn-project/noir-contracts/src/contracts/{schnorr_account_contract => schnorr_single_key_account_contract}/src/main.nr (98%) delete mode 100644 yarn-project/noir-contracts/src/examples/schnorr_account_contract.json create mode 100644 yarn-project/noir-contracts/src/examples/schnorr_multi_key_account_contract.json create mode 100644 yarn-project/noir-contracts/src/examples/schnorr_single_key_account_contract.json create mode 100644 yarn-project/noir-contracts/src/types/schnorr_multi_key_account.ts rename yarn-project/noir-contracts/src/types/{schnorr_account.ts => schnorr_single_key_account.ts} (75%) diff --git a/yarn-project/aztec-cli/src/index.ts b/yarn-project/aztec-cli/src/index.ts index 9e3f1ad003f..bf1997484a1 100644 --- a/yarn-project/aztec-cli/src/index.ts +++ b/yarn-project/aztec-cli/src/index.ts @@ -14,7 +14,7 @@ import { randomBytes } from '@aztec/foundation/crypto'; import { JsonStringify } from '@aztec/foundation/json-rpc'; import { createLogger } from '@aztec/foundation/log'; import { createDebugLogger } from '@aztec/foundation/log'; -import { SchnorrAccountContractAbi } from '@aztec/noir-contracts/examples'; +import { SchnorrSingleKeyAccountContractAbi } from '@aztec/noir-contracts/examples'; import { ContractData, L2BlockL2Logs, TxHash } from '@aztec/types'; import { Command } from 'commander'; @@ -92,7 +92,13 @@ async function main() { .action(async options => { const client = createAztecRpcClient(options.rpcUrl); const privateKey = options.privateKey && Buffer.from(options.privateKey.replace(/^0x/i, ''), 'hex'); - const wallet = await createAccounts(client, SchnorrAccountContractAbi, privateKey, accountCreationSalt, 1); + const wallet = await createAccounts( + client, + SchnorrSingleKeyAccountContractAbi, + privateKey, + accountCreationSalt, + 1, + ); const accounts = await wallet.getAccounts(); const pubKeys = await Promise.all(accounts.map(acc => wallet.getAccountPublicKey(acc))); log(`\nCreated account(s).`); @@ -274,7 +280,7 @@ async function main() { const client = createAztecRpcClient(options.rpcUrl); const wallet = await getAccountWallet( client, - SchnorrAccountContractAbi, + SchnorrSingleKeyAccountContractAbi, Buffer.from(options.privateKey, 'hex'), accountCreationSalt, ); diff --git a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts index c1cd5254fa0..5a30aa006af 100644 --- a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts +++ b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts @@ -12,7 +12,7 @@ import { } from '@aztec/aztec.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-artifacts'; -import { SchnorrAccountContractAbi, UniswapContractAbi } from '@aztec/noir-contracts/examples'; +import { SchnorrSingleKeyAccountContractAbi, UniswapContractAbi } from '@aztec/noir-contracts/examples'; import { AztecRPC, TxStatus } from '@aztec/types'; import { createPublicClient, createWalletClient, getContract, http, parseEther } from 'viem'; @@ -186,7 +186,7 @@ const transferWethOnL2 = async ( async function main() { logger('Running L1/L2 messaging test on HTTP interface.'); - wallet = await createAccounts(aztecRpcClient, SchnorrAccountContractAbi, privateKey!, Fr.random(), 2); + wallet = await createAccounts(aztecRpcClient, SchnorrSingleKeyAccountContractAbi, privateKey!, Fr.random(), 2); const accounts = await wallet.getAccounts(); const [owner, receiver] = accounts; const ownerPub = (await aztecRpcClient.getAccountPublicKey(owner)).toBigInts(); diff --git a/yarn-project/aztec-sandbox/src/examples/zk_token_contract.ts b/yarn-project/aztec-sandbox/src/examples/zk_token_contract.ts index 794486b42a2..1d800ed1a9e 100644 --- a/yarn-project/aztec-sandbox/src/examples/zk_token_contract.ts +++ b/yarn-project/aztec-sandbox/src/examples/zk_token_contract.ts @@ -1,7 +1,7 @@ import { Contract, ContractDeployer, Wallet, createAccounts, createAztecRpcClient } from '@aztec/aztec.js'; import { AztecAddress, Fr, Point } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; -import { SchnorrAccountContractAbi, ZkTokenContractAbi } from '@aztec/noir-contracts/examples'; +import { SchnorrSingleKeyAccountContractAbi, ZkTokenContractAbi } from '@aztec/noir-contracts/examples'; const logger = createDebugLogger('aztec:http-rpc-client'); @@ -50,7 +50,7 @@ async function getBalance(contract: Contract, ownerKey: Point, ownerAddress: Azt async function main() { logger('Running ZK contract test on HTTP interface.'); - wallet = await createAccounts(aztecRpcClient, SchnorrAccountContractAbi, privateKey, Fr.random(), 2); + wallet = await createAccounts(aztecRpcClient, SchnorrSingleKeyAccountContractAbi, privateKey, Fr.random(), 2); const accounts = await aztecRpcClient.getAccounts(); const [ownerAddress, address2] = accounts; logger(`Created ${accounts.length} accounts`); diff --git a/yarn-project/aztec.js/src/abis/schnorr_single_key_account_contract.json b/yarn-project/aztec.js/src/abis/schnorr_single_key_account_contract.json new file mode 100644 index 00000000000..978f315e48d --- /dev/null +++ b/yarn-project/aztec.js/src/abis/schnorr_single_key_account_contract.json @@ -0,0 +1,96 @@ +{ + "name": "SchnorrSingleKeyAccount", + "functions": [ + { + "name": "constructor", + "functionType": "secret", + "parameters": [], + "returnTypes": [] + }, + { + "name": "entrypoint", + "functionType": "secret", + "parameters": [ + { + "name": "payload", + "type": { + "kind": "struct", + "fields": [ + { + "name": "flattened_args_hashes", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "flattened_selectors", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "flattened_targets", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "nonce", + "type": { + "kind": "field" + } + } + ] + }, + "visibility": "public" + }, + { + "name": "owner", + "type": { + "kind": "array", + "length": 64, + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 8 + } + }, + "visibility": "public" + }, + { + "name": "signature", + "type": { + "kind": "array", + "length": 64, + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 8 + } + }, + "visibility": "public" + }, + { + "name": "partial_address", + "type": { + "kind": "field" + }, + "visibility": "public" + } + ], + "returnTypes": [] + } + ] +} diff --git a/yarn-project/aztec.js/src/account_impl/single_key_account_contract.ts b/yarn-project/aztec.js/src/account_impl/single_key_account_contract.ts index 2a9c2346b5a..8abeaae3157 100644 --- a/yarn-project/aztec.js/src/account_impl/single_key_account_contract.ts +++ b/yarn-project/aztec.js/src/account_impl/single_key_account_contract.ts @@ -5,7 +5,7 @@ import { ExecutionRequest, PackedArguments, TxExecutionRequest } from '@aztec/ty import partition from 'lodash.partition'; -import SchnorrAccountContractAbi from '../abis/schnorr_account_contract.json' assert { type: 'json' }; +import SchnorrSingleKeyAccountContractAbi from '../abis/schnorr_account_contract.json' assert { type: 'json' }; import { generatePublicKey } from '../index.js'; import { buildPayload, hashPayload } from './entrypoint_payload.js'; import { AccountImplementation } from './index.js'; @@ -57,10 +57,10 @@ export class SingleKeyAccountContract implements AccountImplementation { } private getEntrypointAbi() { - // We use the SchnorrAccountContract because it implements the interface we need, but ideally + // We use the SchnorrSingleKeyAccountContract because it implements the interface we need, but ideally // we should have an interface that defines the entrypoint for SingleKeyAccountContracts and // load the abi from it. - const abi = (SchnorrAccountContractAbi as any as ContractAbi).functions.find(f => f.name === 'entrypoint'); + const abi = (SchnorrSingleKeyAccountContractAbi as any as ContractAbi).functions.find(f => f.name === 'entrypoint'); if (!abi) throw new Error(`Entrypoint abi for account contract not found`); return abi; } diff --git a/yarn-project/aztec.js/src/account_impl/stored_key_account_contract.ts b/yarn-project/aztec.js/src/account_impl/stored_key_account_contract.ts index 0f2ce99b5ac..2ad269223ab 100644 --- a/yarn-project/aztec.js/src/account_impl/stored_key_account_contract.ts +++ b/yarn-project/aztec.js/src/account_impl/stored_key_account_contract.ts @@ -1,11 +1,11 @@ import { AztecAddress, CircuitsWasm, FunctionData, TxContext } from '@aztec/circuits.js'; import { Signer } from '@aztec/circuits.js/barretenberg'; import { ContractAbi, encodeArguments, generateFunctionSelector } from '@aztec/foundation/abi'; +import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { ExecutionRequest, PackedArguments, TxExecutionRequest } from '@aztec/types'; import partition from 'lodash.partition'; -import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import EcdsaAccountContractAbi from '../abis/ecdsa_account_contract.json' assert { type: 'json' }; import { buildPayload, hashPayload } from './entrypoint_payload.js'; import { AccountImplementation } from './index.js'; diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts index 1007fe4da7b..e88a04e60ac 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts @@ -1,10 +1,12 @@ +import { toBufferBE } from '@aztec/foundation/bigint-buffer'; +import { numToUInt32BE } from '@aztec/foundation/serialize'; import { IWasmModule } from '@aztec/foundation/wasm'; -import { EcdsaSignature } from './signature.js'; + +import { secp256k1 } from '@noble/curves/secp256k1'; + import { CircuitsWasm } from '../../../index.js'; import { Signer } from '../index.js'; -import { secp256k1 } from '@noble/curves/secp256k1'; -import { toBufferBE } from '@aztec/foundation/bigint-buffer'; -import { numToUInt32BE } from '@aztec/foundation/serialize'; +import { EcdsaSignature } from './signature.js'; export * from './signature.js'; diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index cf7eb448f18..b502af06564 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -12,7 +12,11 @@ import { AztecAddress, PartialContractAddress, Point, getContractDeploymentInfo import { Ecdsa, Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; import { toBigInt } from '@aztec/foundation/serialize'; -import { EcdsaAccountContractAbi, SchnorrAccountContractAbi } from '@aztec/noir-contracts/examples'; +import { + EcdsaAccountContractAbi, + SchnorrMultiKeyAccountContractAbi, + SchnorrSingleKeyAccountContractAbi, +} from '@aztec/noir-contracts/examples'; import { ChildContract } from '@aztec/noir-contracts/types'; import { PublicKey } from '@aztec/types'; @@ -49,16 +53,16 @@ async function createNewAccount( const { address, partialAddress } = await getContractDeploymentInfo(abi, args, salt, publicKey); await aztecRpcServer.addAccount(encryptionPrivateKey, address, partialAddress); await deployContract(aztecRpcServer, publicKey, abi, args, salt); - const account = await createAccountImpl(address, partialAddress, encryptionPrivateKey, useProperKey); + const account = await createAccountImpl(address, useProperKey, partialAddress, encryptionPrivateKey); const wallet = new AccountWallet(aztecRpcServer, account); return { wallet, address, partialAddress }; } type CreateAccountImplFn = ( address: AztecAddress, + useProperKey: boolean, partialAddress: PartialContractAddress, encryptionPrivateKey: Buffer, - useProperKey: boolean, ) => Promise; function itShouldBehaveLikeAnAccountContract( @@ -114,7 +118,7 @@ function itShouldBehaveLikeAnAccountContract( it('fails to call a function using an invalid signature', async () => { const invalidWallet = new AccountWallet( context.aztecRpcServer, - await createAccountImpl(address, partialAddress, encryptionPrivateKey, false), + await createAccountImpl(address, false, partialAddress, encryptionPrivateKey), ); const childWithInvalidWallet = new ChildContract(child.address, invalidWallet); await expect(childWithInvalidWallet.methods.value(42).simulate()).rejects.toThrowError( @@ -125,35 +129,44 @@ function itShouldBehaveLikeAnAccountContract( } describe('e2e_account_contracts', () => { - describe('schnorr account', () => { - const createSchnorrWallet = async ( + describe('schnorr single-key account', () => { + const createWallet = async ( address: AztecAddress, - partial: PartialContractAddress, - encryptionPrivateKey: Buffer, useProperKey: boolean, + partial: PartialContractAddress, + privateKey: Buffer, ) => - new SingleKeyAccountContract( - address, - partial, - useProperKey ? encryptionPrivateKey : randomBytes(32), - await Schnorr.new(), - ); + new SingleKeyAccountContract(address, partial, useProperKey ? privateKey : randomBytes(32), await Schnorr.new()); - itShouldBehaveLikeAnAccountContract(SchnorrAccountContractAbi, () => [], createSchnorrWallet); + itShouldBehaveLikeAnAccountContract(SchnorrSingleKeyAccountContractAbi, () => [], createWallet); }); - describe('ecdsa account', () => { - const createEcdsaWallet = async ( - address: AztecAddress, - _partial: PartialContractAddress, - _encryptionPrivateKey: Buffer, - useProperKey: boolean, - ) => new StoredKeyAccountContract(address, useProperKey ? ecdsaPrivateKey : randomBytes(32), await Ecdsa.new()); + describe('schnorr multi-key account', () => { + let signingPrivateKey: Buffer; + let signingPublicKey: Buffer; + let createArgs: any[]; + const createWallet = async (address: AztecAddress, useProperKey: boolean) => + new StoredKeyAccountContract(address, useProperKey ? signingPrivateKey : randomBytes(32), await Schnorr.new()); + + beforeAll(async () => { + signingPrivateKey = randomBytes(32); + const schnorr = await Schnorr.new(); + signingPublicKey = schnorr.computePublicKey(signingPrivateKey); + createArgs = [Fr.fromBuffer(signingPublicKey.subarray(0, 32)), Fr.fromBuffer(signingPublicKey.subarray(32, 64))]; + }); + + itShouldBehaveLikeAnAccountContract(SchnorrMultiKeyAccountContractAbi, () => createArgs, createWallet); + }); + + describe('ecdsa stored-key account', () => { let ecdsaPrivateKey: Buffer; let ecdsaPublicKey: Buffer; let ecdsaCreateArgs: any[]; + const createWallet = async (address: AztecAddress, useProperKey: boolean) => + new StoredKeyAccountContract(address, useProperKey ? ecdsaPrivateKey : randomBytes(32), await Ecdsa.new()); + beforeAll(async () => { ecdsaPrivateKey = randomBytes(32); const ecdsa = await Ecdsa.new(); @@ -161,6 +174,6 @@ describe('e2e_account_contracts', () => { ecdsaCreateArgs = [ecdsaPublicKey.subarray(0, 32), ecdsaPublicKey.subarray(32, 64)]; }); - itShouldBehaveLikeAnAccountContract(EcdsaAccountContractAbi, () => ecdsaCreateArgs, createEcdsaWallet); + itShouldBehaveLikeAnAccountContract(EcdsaAccountContractAbi, () => ecdsaCreateArgs, createWallet); }); }); diff --git a/yarn-project/end-to-end/src/utils.ts b/yarn-project/end-to-end/src/utils.ts index 4a3579c3ea8..a410a77d609 100644 --- a/yarn-project/end-to-end/src/utils.ts +++ b/yarn-project/end-to-end/src/utils.ts @@ -22,7 +22,7 @@ import { randomBytes } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { DebugLogger, Logger, createDebugLogger } from '@aztec/foundation/log'; import { PortalERC20Abi, PortalERC20Bytecode, TokenPortalAbi, TokenPortalBytecode } from '@aztec/l1-artifacts'; -import { NonNativeTokenContractAbi, SchnorrAccountContractAbi } from '@aztec/noir-contracts/examples'; +import { NonNativeTokenContractAbi, SchnorrSingleKeyAccountContractAbi } from '@aztec/noir-contracts/examples'; import { NonNativeTokenContract } from '@aztec/noir-contracts/types'; import { TxStatus } from '@aztec/types'; @@ -120,10 +120,10 @@ export async function setup(numberOfAccounts = 1): Promise<{ const privateKey = i === 0 ? Buffer.from(privKey!) : randomBytes(32); const publicKey = await generatePublicKey(privateKey); const salt = Fr.random(); - const deploymentData = await getContractDeploymentInfo(SchnorrAccountContractAbi, [], salt, publicKey); + const deploymentData = await getContractDeploymentInfo(SchnorrSingleKeyAccountContractAbi, [], salt, publicKey); await aztecRpcServer.addAccount(privateKey, deploymentData.address, deploymentData.partialAddress); - const contractDeployer = new ContractDeployer(SchnorrAccountContractAbi, aztecRpcServer, publicKey); + const contractDeployer = new ContractDeployer(SchnorrSingleKeyAccountContractAbi, aztecRpcServer, publicKey); const deployMethod = contractDeployer.deploy(); await deployMethod.simulate({ contractAddressSalt: salt }); txContexts.push({ diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/Nargo.toml new file mode 100644 index 00000000000..25d5591d50d --- /dev/null +++ b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/Nargo.toml @@ -0,0 +1,7 @@ +[package] +authors = [""] +compiler_version = "0.1" + +[dependencies] +aztec = { path = "../../libs/noir-aztec" } +custom_notes = { path = "../../libs/custom-notes" } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/main.nr new file mode 100644 index 00000000000..9b0709df2cb --- /dev/null +++ b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/main.nr @@ -0,0 +1,93 @@ +mod storage; +mod public_key_note; + +// Account contract that uses Schnorr signatures for authentication. +// The signing key is stored in an immutable private note and should be different from the signing key. +contract SchnorrMultiKeyAccount { + use dep::std; + use dep::aztec::entrypoint; + use dep::aztec::entrypoint::EntrypointPayload; + use dep::aztec::abi; + use dep::aztec::abi::PrivateContextInputs; + use dep::aztec::abi::CallContext; + use dep::aztec::private_call_stack_item::PrivateCallStackItem; + use dep::aztec::public_call_stack_item::PublicCallStackItem; + use dep::aztec::context::Context; + use dep::aztec::log::emit_encrypted_log; + use dep::aztec::oracle::get_public_key::get_public_key; + use dep::aztec::types::vec::BoundedVec; + use dep::aztec::types::point::Point; + use dep::aztec::oracle::debug_log::debug_log_format; + + use dep::custom_notes::utils::compute_note_hash_and_nullifier; + + use dep::aztec::constants_gen::MAX_NOTE_FIELDS_LENGTH; + use dep::aztec::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS; + + use crate::storage::Storage; + use crate::public_key_note::PublicKeyNote; + use crate::public_key_note::PublicKeyNoteInterface; + + fn entrypoint( + inputs: pub PrivateContextInputs, + payload: pub EntrypointPayload, // contains a set of arguments, selectors, targets and a nonce + signature: pub [u8;64], // schnorr signature of the payload hash + ) -> distinct pub abi::PrivateCircuitPublicInputs { + // Initialize context + // 71 = ENTRYPOINT_PAYLOAD_SIZE(7) + 64 + let mut args: BoundedVec = BoundedVec::new(0); + args = args.push_array(payload.serialize()); + for byte in signature { args = args.push(byte as Field); } + let mut context = Context::new(inputs, abi::hash_args(args.storage)); + + // Load public key from storage + let storage = Storage::init(); + let (context_1, public_key) = storage.public_key.get_note(context); + context = context_1; + + // Verify payload signature + // TODO: Use pedersen to make the payload hash cheaper to compute + let payload_bytes: [u8; entrypoint::ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = payload.to_be_bytes(); + let payload_hash: [u8; 32] = std::hash::sha256(payload_bytes); + + // Verify signature of the payload hash + let verification = std::schnorr::verify_signature(public_key.x, public_key.y, signature, payload_hash); + assert(verification == true); + + // Execute calls + context = payload.execute_calls(context); + + context.finish() + } + + // Constructs the contract + fn constructor( + inputs: pub PrivateContextInputs, + signing_pub_key_x: pub Field, + signing_pub_key_y: pub Field, + ) -> distinct pub abi::PrivateCircuitPublicInputs { + let storage = Storage::init(); + + let mut context = Context::new(inputs, abi::hash_args([signing_pub_key_x, signing_pub_key_y])); + + let this = inputs.call_context.storage_contract_address; + let pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); + context = storage.public_key.initialise(context, pub_key_note); + + context = emit_encrypted_log( + context, + this, + storage.public_key.storage_slot, + get_public_key(this), + pub_key_note.serialise(), + ); + + context.finish() + } + + /// ABI stev type "unconstrained" + fn stev(contract_address: Field, storage_slot: Field, preimage: [Field; MAX_NOTE_FIELDS_LENGTH]) -> pub [Field; 2] { + assert(storage_slot == 1); + compute_note_hash_and_nullifier(contract_address, storage_slot, PublicKeyNoteInterface, preimage) + } +} diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/public_key_note.nr b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/public_key_note.nr new file mode 100644 index 00000000000..bd2e86d73d4 --- /dev/null +++ b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/public_key_note.nr @@ -0,0 +1,109 @@ +use dep::std::hash::pedersen; +use dep::aztec::note::note_interface::NoteInterface; +use dep::aztec::note::note_header::NoteHeader; +use dep::aztec::oracle::get_secret_key::get_secret_key; +use dep::aztec::oracle::get_public_key::get_public_key; +use dep::custom_notes::utils::compute_siloed_note_hash; + +global PUBLIC_KEY_NOTE_LEN: Field = 3; + +// Stores a public key composed of two fields +// TODO: Do we need to include a nonce, in case we want to read/nullify/recreate with the same pubkey value? +struct PublicKeyNote { + x: Field, + y: Field, + owner: Field, // We store the owner address only to get the secret key to compute the nullifier + header: NoteHeader, +} + +impl PublicKeyNote { + fn new(x: Field, y: Field, owner: Field) -> Self { + PublicKeyNote { + x, + y, + owner, + header: NoteHeader::empty(), + } + } + + // Serialise the note as 3 fields + fn serialise(self) -> [Field; PUBLIC_KEY_NOTE_LEN] { + [self.x, self.y, self.owner] + } + + fn compute_nullifier(self) -> Field { + let siloed_note_hash = compute_siloed_note_hash(PublicKeyNoteInterface, self); + let owner_nullifying_public_key = get_public_key(self.owner); + let secret = get_secret_key(owner_nullifying_public_key); + dep::std::hash::pedersen([ + siloed_note_hash, + secret, + ])[0] + } + + fn set_header(mut self: Self, header: NoteHeader) -> Self { + self.header = header; + self + } + + fn dummy() -> Self { + PublicKeyNote { + x: 0, + y: 0, + owner: 0, + header: NoteHeader::empty(), + } + } + + fn is_dummy(self) -> bool { + (self.x == 0) & (self.y == 0) & (self.owner == 0) + } +} + +fn deserialise(preimage: [Field; PUBLIC_KEY_NOTE_LEN]) -> PublicKeyNote { + PublicKeyNote { + x: preimage[0], + y: preimage[1], + owner: preimage[2], + header: NoteHeader::empty(), + } +} + +fn serialise(note: PublicKeyNote) -> [Field; PUBLIC_KEY_NOTE_LEN] { + note.serialise() +} + +fn compute_note_hash(note: PublicKeyNote) -> Field { + dep::std::hash::pedersen(note.serialise())[0] +} + +fn compute_nullifier(note: PublicKeyNote) -> Field { + note.compute_nullifier() +} + +fn dummy() -> PublicKeyNote { + PublicKeyNote::dummy() +} + +fn is_dummy(note: PublicKeyNote) -> bool { + note.is_dummy() +} + +fn get_header(note: PublicKeyNote) -> NoteHeader { + note.header +} + +fn set_header(note: PublicKeyNote, header: NoteHeader) -> PublicKeyNote { + note.set_header(header) +} + +global PublicKeyNoteInterface = NoteInterface { + deserialise, + serialise, + compute_note_hash, + compute_nullifier, + dummy, + is_dummy, + get_header, + set_header, +}; diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/storage.nr b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/storage.nr new file mode 100644 index 00000000000..666b18e4ba8 --- /dev/null +++ b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/storage.nr @@ -0,0 +1,21 @@ +use dep::aztec::state_vars::{ + immutable_singleton::ImmutableSingleton +}; + +use crate::public_key_note::{ + PublicKeyNote, + PublicKeyNoteInterface, + PUBLIC_KEY_NOTE_LEN, +}; + +struct Storage { + public_key: ImmutableSingleton, +} + +impl Storage { + fn init() -> Self { + Storage { + public_key: ImmutableSingleton::new(1, PublicKeyNoteInterface) + } + } +} \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/Nargo.toml similarity index 100% rename from yarn-project/noir-contracts/src/contracts/schnorr_account_contract/Nargo.toml rename to yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/Nargo.toml diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr similarity index 98% rename from yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr rename to yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr index 71f4a5a12fc..5b8d9c69277 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr @@ -1,7 +1,7 @@ // Account contract that uses Schnorr signatures for authentication. The signing key is the same as the // encryption key, and as such is not stored in the contract but part of the address preimage, so it can // be verified by passing in the partial contract address. -contract SchnorrAccount { +contract SchnorrSingleKeyAccount { use dep::std; use dep::aztec::entrypoint; use dep::aztec::entrypoint::EntrypointPayload; diff --git a/yarn-project/noir-contracts/src/examples/index.ts b/yarn-project/noir-contracts/src/examples/index.ts index 30f62133eb1..fc96f8d5596 100644 --- a/yarn-project/noir-contracts/src/examples/index.ts +++ b/yarn-project/noir-contracts/src/examples/index.ts @@ -7,7 +7,8 @@ import NonNativeTokenContractJson from './non_native_token_contract.json' assert import ParentJson from './parent_contract.json' assert { type: 'json' }; import PendingCommitmentsContractJson from './pending_commitments_contract.json' assert { type: 'json' }; import PublicTokenContractJson from './public_token_contract.json' assert { type: 'json' }; -import SchnorrAccountContractJson from './schnorr_account_contract.json' assert { type: 'json' }; +import SchnorrMultiKeyAccountContractJson from './schnorr_multi_key_account_contract.json' assert { type: 'json' }; +import SchnorrSingleKeyAccountContractJson from './schnorr_single_key_account_contract.json' assert { type: 'json' }; import TestContractJson from './test_contract.json' assert { type: 'json' }; import UniswapContractJson from './uniswap_contract.json' assert { type: 'json' }; import ZkTokenContractJson from './zk_token_contract.json' assert { type: 'json' }; @@ -19,6 +20,7 @@ export const ChildContractAbi = ChildJson as ContractAbi; export const PublicTokenContractAbi = PublicTokenContractJson as ContractAbi; export const NonNativeTokenContractAbi = NonNativeTokenContractJson as ContractAbi; export const EcdsaAccountContractAbi = EcdsaAccountContractJson as ContractAbi; -export const SchnorrAccountContractAbi = SchnorrAccountContractJson as ContractAbi; +export const SchnorrMultiKeyAccountContractAbi = SchnorrMultiKeyAccountContractJson as ContractAbi; +export const SchnorrSingleKeyAccountContractAbi = SchnorrSingleKeyAccountContractJson as ContractAbi; export const UniswapContractAbi = UniswapContractJson as ContractAbi; export const PendingCommitmentsContractAbi = PendingCommitmentsContractJson as ContractAbi; diff --git a/yarn-project/noir-contracts/src/examples/schnorr_account_contract.json b/yarn-project/noir-contracts/src/examples/schnorr_account_contract.json deleted file mode 100644 index efcd0ee45f1..00000000000 --- a/yarn-project/noir-contracts/src/examples/schnorr_account_contract.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "SchnorrAccount", - "functions": [ - { - "name": "constructor", - "functionType": "secret", - "parameters": [], - "returnTypes": [], - "bytecode": "H4sIAAAAAAAA/9XcV0/jQBiF4ZAFtu/Se+8dT2wn9laW7b2ynRYI//8nkCMcCXHL4eIdySK+sc5DEs/4m085KpVKO6Wz0dY8ys2jvXjdOu+4cN5ZvD4/Wudbxd84qiZJo1ZphDgcRpW8nqVRktarWchCmqXHlSyOG1mS1fJ6XovykMSNcJLm8Ul0NrrPXSu65LjKnD2QnL2QnH2QnP2QnAOQnIOQnEOQnMOQnCOQnKOQnGOQnOOQnBOQnJOQnFOQnNOQnDOQnLOQnHOQnPOQnAuQnIuQnEuQnMuQnCuQnKuQnGuQnOuQnBuQnJuQnBEkZ7iinOULOaPLjdBmNFcg5rLRHEPM14zmBGJuN5pTiLnDaK5CzJ1Gcw1i7jaaM4i5x2jOIeZeo/kBxNxnND+EmPuN5kcQ84DR/BhiHjSan0DMQ0bzU4h52GjegphHjOZnEPOo0bwNMY8Zzc8h5nGj+QXEPGE0v4SYJ43mVxDzlNH8GmKeNprfQMwzRvNbiHnWaH4HMc8Zze8h5nmj+QPEvGA0f4SYF43mTxDzktH8GWJeNpq/QMwrRvNXiHnVaP4GMa8Zzd8h5nWj+QfEvGE070DMm0bzT4g5Mpp/QczBaP4NMV83mv9AzDeM5r8Q802j+R/EfMto/g8x3zaadyHmO0bzHsR812jeh5jvGc0HEPN9o/kQYu4ymutGc1dxndZvjqj/WP246k9Vv6bWUlpbaK7V3KN7se5N+q7qs6v3UtcIxXXUW65ea/UeqxdXvanq1VTvonr51NumXi/1PqkXSL0xrV4R9RJsNw/tNWvvVXuR2pvTXpX2brSXodq+at2q/aoWqtqgamWqHamWotqCnrX17KlnMT2baK2utavWclrbaK7X3Ke5QPdG3SsOmoc+S/rfngJF2liFrEUAAA==", - "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" - }, - { - "name": "entrypoint", - "functionType": "secret", - "parameters": [ - { - "name": "payload", - "type": { - "kind": "struct", - "fields": [ - { - "name": "flattened_args_hashes", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "field" - } - } - }, - { - "name": "flattened_selectors", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "field" - } - } - }, - { - "name": "flattened_targets", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "field" - } - } - }, - { - "name": "nonce", - "type": { - "kind": "field" - } - } - ] - }, - "visibility": "public" - }, - { - "name": "owner", - "type": { - "kind": "array", - "length": 64, - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 8 - } - }, - "visibility": "public" - }, - { - "name": "signature", - "type": { - "kind": "array", - "length": 64, - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 8 - } - }, - "visibility": "public" - }, - { - "name": "partial_address", - "type": { - "kind": "field" - }, - "visibility": "public" - } - ], - "returnTypes": [], - "bytecode": "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", - "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" - } - ] -} diff --git a/yarn-project/noir-contracts/src/examples/schnorr_multi_key_account_contract.json b/yarn-project/noir-contracts/src/examples/schnorr_multi_key_account_contract.json new file mode 100644 index 00000000000..cd06bfccef0 --- /dev/null +++ b/yarn-project/noir-contracts/src/examples/schnorr_multi_key_account_contract.json @@ -0,0 +1,137 @@ +{ + "name": "SchnorrMultiKeyAccount", + "functions": [ + { + "name": "constructor", + "functionType": "secret", + "parameters": [ + { + "name": "signing_pub_key_x", + "type": { + "kind": "field" + }, + "visibility": "public" + }, + { + "name": "signing_pub_key_y", + "type": { + "kind": "field" + }, + "visibility": "public" + } + ], + "returnTypes": [], + "bytecode": "H4sIAAAAAAAA/+2dh3MTRxjFF9lywaaZ3ntvJ8tFppoaiIkpgRAI1fgEpthgRDG9QzrpPSGkF9LrJH9bJvfBd2Z90cBk7p2iN9HO7LyTo+y935a7b8uIP40xd8y91MvLMS8X67X/OR74XKLXdvI/N6omnbqaGre+2k0kE7ud6oaWVK1TU9tSl0qkErWp2tbqVDLppmpS9Q0tDfVOQ6Im6SbStQ3JtHMvDbTKckKmKH0OIvE5mMTnEBKfQ0l8DiPxOZzE5wgSnyNJfI4i8TmaxOcYEp9jSXyOI/E5nsTnBBKfE0l8TiLxOZnE5xQSn1NJfE4j8TmdxOcMEp8zSXzOIvE5m8TnHBKfc0l8OkCf4k3W7sZpeQO8/JeXq1QHqg5SHaw6RHWo6jDV4aojVEeqjlIdrTpGdazqONXxqhNUJ6pOUp2sOkV1quo01emqM1Rnqs5Sna06R3WuqmN9L+HlatMzodswaTj6Wg2Jz1oSn3UkPutJfKZIfDaQ+JxH4nM+ic8FJD4XkvhcROJzMYnPRhKfSww+5u2v5Um8J7FfUrVGtVa1TrVeNaXaoDpPdb7qAtWFqotUF6s2qi4x92POpV5eZnomdB0ux9VhXZQ+V+B8Jvy2jml5y7XOV6hKWunlR0z2MwzZ+JxwKTHAYPuyn1ZZ18WqMetvRaolETCZwH2C9dg3y9+gN4+ikVZFUO5qgxsoUXGvxreRk6vBVWWiGVyPWteFwRWyzCqtUHS5TSa/B5dwN+HbqLujrlbPTaprTO7eajETzcB7zLouDLyQZca0QtHlNpv8HnjC3Yxvo+6OukY9N6uuNbkbeGtNNANvnXVdGHghy1yrFYoud73J74En3OvxbdQ9h/c7YXDfKmbuz+82ePlx0zOh56wbgXUWnLNuVJYNFtMmLz8R+F621Aj0VPSQOnTCJei8OCqPyOlFVB6jisQ2W9e9VcutftHL+luwT5ZY140Yb8m4VW65Vb5/b3lJlJl7zwZJ7R2ZtnTXsk53d8Ztbe7IuDZctjdczALzIYusG8YD/68N7v+3UmO9qaJ8+jshU67Clc0mmt75pHVdCFdClrlZKxRd7haT3+GKcG/Bt1EkXterV3Qo84fBv+IkFYF9IkPfrcB2QdZfrh7KQP4eD+WnrOvCQzlkmVu1QtHlbjP5/VAW7m34NnrgfrUTLkHrlHkF1w6dt3t5h5d3WgyVqjmaMzgSlsete/rJnjPIfYux903a86Rg+wUZjXX/MquO9rqZdcdaDrbtaXK7stVvUZZyYxZrPPC9h05XgsaccCkRXLSRDiELGjtUd6r28/IuL+8O+EBHEMAOn9gF9NVi+CIIpGfb7x7ruhBBhCyzRSsUXW6rye8IQrhb8W0UaQSBrFMZHHHzz5TPEUQWu5EMbHQdbDcc/WuHwT6wC7sD/9/dAVH/pex6OW3up6GqEm36Eb29YJ4tKg2+6P/rXYZy654m4M3fZfBPE7uH2jIr2vd0dh32dhnWdOy1A4RS1XiWcuw6MFYd2N/3A2j7uyWWr0YMc3W5MtnpQbMVu378naEyy18F1l+iwrpPqeWvd8Cf/7nC8lKJ9eLYXir/hRepqz6BurL7dB+LL7IgM1ezA9fgHzqS9lrXhdlByDJdrVB0uftMfs8OhHsfvo1yNvVOm2gGV5t1XRhcIctMa4Wiy91v8ntwCfd+fBt1d9R96nm/6gHTM6F3Rw8CGaL0eYjEZzuJzw4Sn4dJfB4h8dlJ4vMo2GcUp1U2RcCdIWmfYyQ+j5P4PEHi8ySJzy4Sn6dIfJ4m8XmGxOdZEp/nSHyeJ/F5gcTnRRKfl0h8XibxeYXE51USn9ci8hkD+XTTd5N7AMh8HcecjLJtbuSobZxw6e45QxTz0yTMMSDzMyTMRUDmZ0mYi4HMz5Ewx4HMz5MwlwCZXyBhXgpkfpGE+SCQ+SYJ8yEg80skzO1A5pdJmDuAzK+QMB8GMr9KwnwEyPwaCXMnkPl1EuajQOY3SJgzQOY3SZiPAZnfImE+DmR+m4T5BJD5HRLmlUDmd0mYTwKZ3yNh7gIyv0/CfArI/AEJ82kg8y0S5jNA5g9JmM8CmW+TMJ8DMn9EwnweyPwxCfMFIPMnJMwXgcyfkjBfAjJ/RsJ8Gcj8OQnzFSDzFyTMLpD5SxLmNJD5KxLmq0Dmr0mYrwGZ75AwXwcyf0PCfAPI/C0JcymQ+TsS5jIg8/ckzOVA5h9ImHsDmX8kYa4AMv9EwlwJZP6ZhLkPkPkXEua+QOZfSZj7AZl/I2HuD2T+HchcpeX4P3cm54/lPK7/D5FILCWxhf8zWPIslmeTjFXpu9KWwiY/ZSdl+b9yImfM5cy1nEGWM7lyRlXObMoZxpteljNucuZLzkDJmSA5IyNnRuQMhZwpkD122XOWPVjZk5Q9Otmzkj2cW16WNf7bXpY1YFkTlTVCWTOTNSRZU5E1BplzyxxU5mQyR5GYXWJYiekkxpF3vrwD5Z0gz0h5ZsgYkj4ldfw37tFefzWYAAA=", + "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" + }, + { + "name": "entrypoint", + "functionType": "secret", + "parameters": [ + { + "name": "payload", + "type": { + "kind": "struct", + "fields": [ + { + "name": "flattened_args_hashes", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "flattened_selectors", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "flattened_targets", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "nonce", + "type": { + "kind": "field" + } + } + ] + }, + "visibility": "public" + }, + { + "name": "signature", + "type": { + "kind": "array", + "length": 64, + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 8 + } + }, + "visibility": "public" + } + ], + "returnTypes": [], + "bytecode": "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", + "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" + }, + { + "name": "stev", + "functionType": "unconstrained", + "parameters": [ + { + "name": "contract_address", + "type": { + "kind": "field" + }, + "visibility": "private" + }, + { + "name": "storage_slot", + "type": { + "kind": "field" + }, + "visibility": "private" + }, + { + "name": "preimage", + "type": { + "kind": "array", + "length": 20, + "type": { + "kind": "field" + } + }, + "visibility": "private" + } + ], + "returnTypes": [ + { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + ], + "bytecode": "H4sIAAAAAAAA/+1WS0/DMAx2t7U8hMaBwx6MMWAPxga0a7u1N+5ckPgFdGQIiRMaB/48IhGu5oUIIc2ZhoQly1Hr2v6cxP2uAeAAvksB7Q1afzUJCiRW6I+jSExGIgiDB3+UZknsR3E2ToIkiJP4cZSEoUiiZJJm6cRPgygUwSxOwxkGqzDG8mQMx4DfYcZf4Yvl03qrZF3S9k5JEa1nARNoefQ+lg3PWJPb2KSqhbg14DuwtnDX+PfIJyE3uqeqNg8Wl0XZD/i6UMq6aJXUpR4iHvVNftkK6FMnvg2pR8T3N/GbUo9/iN8kvi2pJwZfB31aaFW+U6lnsDwIqHDvjwv8A88hPWxL7UjtEgx7aHdgeQgC4gZejL7C6JKcueS5y5i3xJs33CF90PdPxwgk/zbp0ZOY371lL8/TW/Fu6m/RELdAsLqaH+15/m4LLP4A9EulDoQ67B20XbT7UntSz7U6ilo9qw4RxgMf9Bjr6vPVtTa2xFkzrfeCrP/Z0oox+9hQ7rgD2Gy2pHAP+PfIKlvi7CllGjZrbsPf6G0H7AyrIVnvoqV/foc8Wxfb8UjOXCjb0RjGvZi+ijlhGEpMg9c0hCnLKBmwrpVl5EkVjVasYggLGn4p9coApoHvPgGitrhNZBEAAA==", + "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" + } + ] +} diff --git a/yarn-project/noir-contracts/src/examples/schnorr_single_key_account_contract.json b/yarn-project/noir-contracts/src/examples/schnorr_single_key_account_contract.json new file mode 100644 index 00000000000..638fd74c58e --- /dev/null +++ b/yarn-project/noir-contracts/src/examples/schnorr_single_key_account_contract.json @@ -0,0 +1,100 @@ +{ + "name": "SchnorrSingleKeyAccount", + "functions": [ + { + "name": "constructor", + "functionType": "secret", + "parameters": [], + "returnTypes": [], + "bytecode": "H4sIAAAAAAAA/9XcV0/jQBiF4ZAFtu/Se+8dT2wn9laW7b2ynRYI//8nkCMcCXHL4eIdySK+sc5DEs/4m085KpVKO6Wz0dY8ys2jvXjdOu+4cN5ZvD4/Wudbxd84qiZJo1ZphDgcRpW8nqVRktarWchCmqXHlSyOG1mS1fJ6XovykMSNcJLm8Ul0NrrPXSu65LjKnD2QnL2QnH2QnP2QnAOQnIOQnEOQnMOQnCOQnKOQnGOQnOOQnBOQnJOQnFOQnNOQnDOQnLOQnHOQnPOQnAuQnIuQnEuQnMuQnCuQnKuQnGuQnOuQnBuQnJuQnBEkZ7iinOULOaPLjdBmNFcg5rLRHEPM14zmBGJuN5pTiLnDaK5CzJ1Gcw1i7jaaM4i5x2jOIeZeo/kBxNxnND+EmPuN5kcQ84DR/BhiHjSan0DMQ0bzU4h52GjegphHjOZnEPOo0bwNMY8Zzc8h5nGj+QXEPGE0v4SYJ43mVxDzlNH8GmKeNprfQMwzRvNbiHnWaH4HMc8Zze8h5nmj+QPEvGA0f4SYF43mTxDzktH8GWJeNpq/QMwrRvNXiHnVaP4GMa8Zzd8h5nWj+QfEvGE070DMm0bzT4g5Mpp/QczBaP4NMV83mv9AzDeM5r8Q802j+R/EfMto/g8x3zaadyHmO0bzHsR812jeh5jvGc0HEPN9o/kQYu4ymutGc1dxndZvjqj/WP246k9Vv6bWUlpbaK7V3KN7se5N+q7qs6v3UtcIxXXUW65ea/UeqxdXvanq1VTvonr51NumXi/1PqkXSL0xrV4R9RJsNw/tNWvvVXuR2pvTXpX2brSXodq+at2q/aoWqtqgamWqHamWotqCnrX17KlnMT2baK2utavWclrbaK7X3Ke5QPdG3SsOmoc+S/rfngJF2liFrEUAAA==", + "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" + }, + { + "name": "entrypoint", + "functionType": "secret", + "parameters": [ + { + "name": "payload", + "type": { + "kind": "struct", + "fields": [ + { + "name": "flattened_args_hashes", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "flattened_selectors", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "flattened_targets", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "field" + } + } + }, + { + "name": "nonce", + "type": { + "kind": "field" + } + } + ] + }, + "visibility": "public" + }, + { + "name": "owner", + "type": { + "kind": "array", + "length": 64, + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 8 + } + }, + "visibility": "public" + }, + { + "name": "signature", + "type": { + "kind": "array", + "length": 64, + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 8 + } + }, + "visibility": "public" + }, + { + "name": "partial_address", + "type": { + "kind": "field" + }, + "visibility": "public" + } + ], + "returnTypes": [], + "bytecode": "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", + "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" + } + ] +} diff --git a/yarn-project/noir-contracts/src/scripts/copy_output.ts b/yarn-project/noir-contracts/src/scripts/copy_output.ts index 2327ecfa8f2..83ffc39c83e 100644 --- a/yarn-project/noir-contracts/src/scripts/copy_output.ts +++ b/yarn-project/noir-contracts/src/scripts/copy_output.ts @@ -15,7 +15,7 @@ const STATEMENT_TYPES = ['type', 'params', 'return'] as const; const log = createLogger('aztec:noir-contracts'); const PROJECT_CONTRACTS = [ - { name: 'SchnorrAccount', target: '../aztec.js/src/abis/', exclude: ['bytecode', 'verificationKey'] }, + { name: 'SchnorrSingleKeyAccount', target: '../aztec.js/src/abis/', exclude: ['bytecode', 'verificationKey'] }, { name: 'EcdsaAccount', target: '../aztec.js/src/abis/', exclude: ['bytecode', 'verificationKey'] }, ]; diff --git a/yarn-project/noir-contracts/src/types/index.ts b/yarn-project/noir-contracts/src/types/index.ts index 6ee69ab7c37..38af159f882 100644 --- a/yarn-project/noir-contracts/src/types/index.ts +++ b/yarn-project/noir-contracts/src/types/index.ts @@ -4,7 +4,8 @@ export * from './non_native_token.js'; export * from './parent.js'; export * from './pending_commitments.js'; export * from './public_token.js'; -export * from './schnorr_account.js'; +export * from './schnorr_multi_key_account.js'; +export * from './schnorr_single_key_account.js'; export * from './test.js'; export * from './uniswap.js'; export * from './zk_token.js'; diff --git a/yarn-project/noir-contracts/src/types/schnorr_multi_key_account.ts b/yarn-project/noir-contracts/src/types/schnorr_multi_key_account.ts new file mode 100644 index 00000000000..71a9c558d41 --- /dev/null +++ b/yarn-project/noir-contracts/src/types/schnorr_multi_key_account.ts @@ -0,0 +1,83 @@ +/* Autogenerated file, do not edit! */ + +/* eslint-disable */ +import { + AztecAddress, + Contract, + ContractFunctionInteraction, + ContractMethod, + DeployMethod, + Wallet, +} from '@aztec/aztec.js'; +import { ContractAbi } from '@aztec/foundation/abi'; +import { Fr, Point } from '@aztec/foundation/fields'; +import { AztecRPC } from '@aztec/types'; + +import { SchnorrMultiKeyAccountContractAbi } from '../examples/index.js'; + +/** + * Type-safe interface for contract SchnorrMultiKeyAccount; + */ +export class SchnorrMultiKeyAccountContract extends Contract { + constructor( + /** The deployed contract's address. */ + address: AztecAddress, + /** The wallet. */ + wallet: Wallet, + ) { + super(address, SchnorrMultiKeyAccountContractAbi, wallet); + } + + /** + * Creates a tx to deploy a new instance of this contract. + */ + public static deploy( + rpc: AztecRPC, + signing_pub_key_x: Fr | bigint | number | { toField: () => Fr }, + signing_pub_key_y: Fr | bigint | number | { toField: () => Fr }, + ) { + return new DeployMethod(Point.ZERO, rpc, SchnorrMultiKeyAccountContractAbi, Array.from(arguments).slice(1)); + } + + /** + * Creates a tx to deploy a new instance of this contract using the specified public key to derive the address. + */ + public static deployWithPublicKey( + rpc: AztecRPC, + publicKey: Point, + signing_pub_key_x: Fr | bigint | number | { toField: () => Fr }, + signing_pub_key_y: Fr | bigint | number | { toField: () => Fr }, + ) { + return new DeployMethod(publicKey, rpc, SchnorrMultiKeyAccountContractAbi, Array.from(arguments).slice(2)); + } + + /** + * Returns this contract's ABI. + */ + public static get abi(): ContractAbi { + return SchnorrMultiKeyAccountContractAbi; + } + + /** Type-safe wrappers for the public methods exposed by the contract. */ + public methods!: { + /** entrypoint(payload: struct, signature: array) */ + entrypoint: (( + payload: { + flattened_args_hashes: (Fr | bigint | number | { toField: () => Fr })[]; + flattened_selectors: (Fr | bigint | number | { toField: () => Fr })[]; + flattened_targets: (Fr | bigint | number | { toField: () => Fr })[]; + nonce: Fr | bigint | number | { toField: () => Fr }; + }, + signature: (bigint | number)[], + ) => ContractFunctionInteraction) & + Pick; + + /** stev(contract_address: field, storage_slot: field, preimage: array) */ + stev: (( + contract_address: Fr | bigint | number | { toField: () => Fr }, + storage_slot: Fr | bigint | number | { toField: () => Fr }, + preimage: (Fr | bigint | number | { toField: () => Fr })[], + ) => ContractFunctionInteraction) & + Pick; + }; +} diff --git a/yarn-project/noir-contracts/src/types/schnorr_account.ts b/yarn-project/noir-contracts/src/types/schnorr_single_key_account.ts similarity index 75% rename from yarn-project/noir-contracts/src/types/schnorr_account.ts rename to yarn-project/noir-contracts/src/types/schnorr_single_key_account.ts index b6fd60852e6..f94c6b2bfc7 100644 --- a/yarn-project/noir-contracts/src/types/schnorr_account.ts +++ b/yarn-project/noir-contracts/src/types/schnorr_single_key_account.ts @@ -13,40 +13,40 @@ import { ContractAbi } from '@aztec/foundation/abi'; import { Fr, Point } from '@aztec/foundation/fields'; import { AztecRPC } from '@aztec/types'; -import { SchnorrAccountContractAbi } from '../examples/index.js'; +import { SchnorrSingleKeyAccountContractAbi } from '../examples/index.js'; /** - * Type-safe interface for contract SchnorrAccount; + * Type-safe interface for contract SchnorrSingleKeyAccount; */ -export class SchnorrAccountContract extends Contract { +export class SchnorrSingleKeyAccountContract extends Contract { constructor( /** The deployed contract's address. */ address: AztecAddress, /** The wallet. */ wallet: Wallet, ) { - super(address, SchnorrAccountContractAbi, wallet); + super(address, SchnorrSingleKeyAccountContractAbi, wallet); } /** * Creates a tx to deploy a new instance of this contract. */ public static deploy(rpc: AztecRPC) { - return new DeployMethod(Point.ZERO, rpc, SchnorrAccountContractAbi, Array.from(arguments).slice(1)); + return new DeployMethod(Point.ZERO, rpc, SchnorrSingleKeyAccountContractAbi, Array.from(arguments).slice(1)); } /** * Creates a tx to deploy a new instance of this contract using the specified public key to derive the address. */ public static deployWithPublicKey(rpc: AztecRPC, publicKey: Point) { - return new DeployMethod(publicKey, rpc, SchnorrAccountContractAbi, Array.from(arguments).slice(2)); + return new DeployMethod(publicKey, rpc, SchnorrSingleKeyAccountContractAbi, Array.from(arguments).slice(2)); } /** * Returns this contract's ABI. */ public static get abi(): ContractAbi { - return SchnorrAccountContractAbi; + return SchnorrSingleKeyAccountContractAbi; } /** Type-safe wrappers for the public methods exposed by the contract. */ From 2e914e242c5ecf98cbd71aac109a7cc70cedf24a Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 19 Jul 2023 11:05:21 -0300 Subject: [PATCH 9/9] Apply suggestions by @benesjan --- .../schnorr_multi_key_account_contract/src/main.nr | 8 ++++---- .../schnorr_multi_key_account_contract/src/storage.nr | 4 ++-- .../src/examples/schnorr_multi_key_account_contract.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/main.nr index 7a101afacd2..1cd6f71e207 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/main.nr @@ -2,7 +2,7 @@ mod storage; mod public_key_note; // Account contract that uses Schnorr signatures for authentication. -// The signing key is stored in an immutable private note and should be different from the signing key. +// The signing key is stored in an immutable private note and should be different from the encryption/nullifying key. contract SchnorrMultiKeyAccount { use dep::std; use dep::aztec::entrypoint; @@ -42,7 +42,7 @@ contract SchnorrMultiKeyAccount { // Load public key from storage let storage = Storage::init(); - let (context_1, public_key) = storage.public_key.get_note(context); + let (context_1, public_key) = storage.signing_public_key.get_note(context); context = context_1; // Verify payload signature @@ -72,12 +72,12 @@ contract SchnorrMultiKeyAccount { let this = inputs.call_context.storage_contract_address; let pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); - context = storage.public_key.initialise(context, pub_key_note); + context = storage.signing_public_key.initialise(context, pub_key_note); context = emit_encrypted_log( context, this, - storage.public_key.storage_slot, + storage.signing_public_key.storage_slot, get_public_key(this), pub_key_note.serialise(), ); diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/storage.nr b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/storage.nr index 666b18e4ba8..d69e88fc043 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/storage.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_multi_key_account_contract/src/storage.nr @@ -9,13 +9,13 @@ use crate::public_key_note::{ }; struct Storage { - public_key: ImmutableSingleton, + signing_public_key: ImmutableSingleton, } impl Storage { fn init() -> Self { Storage { - public_key: ImmutableSingleton::new(1, PublicKeyNoteInterface) + signing_public_key: ImmutableSingleton::new(1, PublicKeyNoteInterface) } } } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/examples/schnorr_multi_key_account_contract.json b/yarn-project/noir-contracts/src/examples/schnorr_multi_key_account_contract.json index 32b693630ea..653176faa2f 100644 --- a/yarn-project/noir-contracts/src/examples/schnorr_multi_key_account_contract.json +++ b/yarn-project/noir-contracts/src/examples/schnorr_multi_key_account_contract.json @@ -88,7 +88,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, {