From 8839fd5c24f9410b2c11850307d42ab28d23da1e Mon Sep 17 00:00:00 2001 From: sirasistant Date: Thu, 24 Aug 2023 09:42:08 +0000 Subject: [PATCH 1/3] fix: workaround for noir issue with slices --- .../src/abis/ecdsa_account_contract.json | 71 +------------------ .../src/abis/schnorr_account_contract.json | 69 +----------------- .../schnorr_single_key_account_contract.json | 40 +---------- .../ecdsa_account_contract/src/main.nr | 7 +- .../schnorr_account_contract/src/main.nr | 7 +- .../src/main.nr | 8 ++- .../noir-contracts/src/scripts/copy_output.ts | 2 + 7 files changed, 27 insertions(+), 177 deletions(-) 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 fbf73e265e2..1843041c885 100644 --- a/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json +++ b/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json @@ -48,7 +48,7 @@ } } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -153,73 +153,8 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } - ], - "debug": { - "debugSymbols": [ - "eJyrVsrJT04syczPK1ayqq6tBQAz9wY7", - "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" - ], - "fileMap": { - "0": { - "source": "mod storage;\nmod ecdsa_public_key_note;\n\n// Account contract that uses ECDSA signatures for authentication on the same curve as Ethereum.\n// The signing key is stored in an immutable private note and should be different from the signing key.\ncontract EcdsaAccount {\n use dep::std;\n use dep::aztec::entrypoint;\n use dep::aztec::entrypoint::EntrypointPayload;\n use dep::aztec::abi;\n use dep::aztec::abi::PrivateContextInputs;\n use dep::aztec::abi::CallContext;\n use dep::aztec::context::PrivateContext;\n use dep::aztec::log::emit_encrypted_log;\n use dep::aztec::oracle::get_public_key::get_public_key;\n use dep::aztec::types::vec::BoundedVec;\n use dep::aztec::types::point::Point;\n use dep::aztec::constants_gen::GENERATOR_INDEX__SIGNATURE_PAYLOAD;\n\n use dep::aztec::constants_gen::MAX_NOTE_FIELDS_LENGTH;\n use dep::aztec::note::{\n note_header::{NoteHeader},\n utils as note_utils,\n };\n\n use crate::storage::Storage;\n use crate::ecdsa_public_key_note::EcdsaPublicKeyNote;\n use crate::ecdsa_public_key_note::EcdsaPublicKeyNoteInterface;\n use crate::ecdsa_public_key_note::ECDSA_PUBLIC_KEY_NOTE_LEN;\n\n // All calls made by this account will be routed through this entrypoint\n fn entrypoint( \n inputs: pub PrivateContextInputs,\n payload: pub EntrypointPayload, // contains a set of arguments, selectors, targets and a nonce\n signature: pub [u8;64],\n ) -> distinct pub abi::PrivateCircuitPublicInputs {\n \n // Initialise context\n // ENTRYPOINT_PAYLOAD_SIZE(13) + 64\n let mut args: BoundedVec = BoundedVec::new(0);\n args.push_array(payload.serialize());\n for byte in signature { args.push(byte as Field); }\n let mut context = PrivateContext::new(inputs, abi::hash_args(args.storage));\n\n // Load public key from storage\n let storage = Storage::init();\n let public_key = storage.public_key.get_note(&mut context);\n\n // Verify payload signature using Ethereum's signing scheme\n // Note that noir expects the hash of the message/challenge as input to the ECDSA verification.\n let payload_fields: [Field; entrypoint::ENTRYPOINT_PAYLOAD_SIZE] = payload.serialize();\n let message_field: Field = std::hash::pedersen_with_separator(payload_fields, GENERATOR_INDEX__SIGNATURE_PAYLOAD)[0];\n let message_bytes = message_field.to_be_bytes(32);\n let hashed_message: [u8; 32] = std::hash::sha256(message_bytes);\n let verification = std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, hashed_message);\n assert(verification == true);\n\n payload.execute_calls(&mut context);\n\n context.finish()\n }\n\n // Creates a new account out of an ECDSA public key to use for signature verification\n fn constructor(\n inputs: pub PrivateContextInputs,\n signing_pub_key_x: pub [u8;32],\n signing_pub_key_y: pub [u8;32],\n ) -> distinct pub abi::PrivateCircuitPublicInputs {\n let storage = Storage::init();\n \n let mut args: BoundedVec = BoundedVec::new(0);\n for byte in signing_pub_key_x { args.push(byte as Field); }\n for byte in signing_pub_key_y { args.push(byte as Field); }\n let mut context = PrivateContext::new(inputs, abi::hash_args(args.storage));\n \n let this = context.this_address();\n let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this);\n storage.public_key.initialise(&mut context, &mut pub_key_note);\n \n emit_encrypted_log(\n &mut context,\n this,\n storage.public_key.storage_slot,\n get_public_key(this),\n pub_key_note.serialise(),\n );\n\n context.finish()\n }\n\n // Computes note hash and nullifier.\n // Note 1: Needs to be defined by every contract producing logs.\n // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes.\n unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN]) -> [Field; 4] {\n assert(storage_slot == 1);\n let note_header = NoteHeader { contract_address, nonce, storage_slot };\n note_utils::compute_note_hash_and_nullifier(EcdsaPublicKeyNoteInterface, note_header, preimage)\n }\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main" - }, - "3": { - "source": "mod poseidon;\n\n#[foreign(sha256)]\nfn sha256(_input : [u8; N]) -> [u8; 32] {}\n\n#[foreign(blake2s)]\nfn blake2s(_input : [u8; N]) -> [u8; 32] {}\n\nfn pedersen(input : [Field; N]) -> [Field; 2] {\n pedersen_with_separator(input, 0)\n}\n\n#[foreign(pedersen)]\nfn pedersen_with_separator(_input : [Field; N], _separator : u32) -> [Field; 2] {}\n\n#[foreign(hash_to_field_128_security)]\nfn hash_to_field(_input : [Field; N]) -> Field {}\n\n#[foreign(keccak256)]\nfn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] {}\n\n// mimc-p/p implementation\n// constants are (publicly generated) random numbers, for instance using keccak as a ROM.\n// You must use constants generated for the native field\n// Rounds number should be ~ log(p)/log(exp)\n// For 254 bit primes, exponent 7 and 91 rounds seems to be recommended\nfn mimc(x: Field, k: Field, constants: [Field; N], exp : Field) -> Field {\n //round 0\n let mut t = x + k;\n let mut h = t.pow_32(exp);\n //next rounds\n for i in 1 .. constants.len() {\n t = h + k + constants[i];\n h = t.pow_32(exp);\n };\n h + k\n}\n\nglobal MIMC_BN254_ROUNDS = 91;\n\n//mimc implementation with hardcoded parameters for BN254 curve.\nfn mimc_bn254(array: [Field; N]) -> Field {\n //mimc parameters\n let exponent = 7;\n //generated from seed \"mimc\" using keccak256 \n let constants: [Field; MIMC_BN254_ROUNDS] = [\n 0, \n 20888961410941983456478427210666206549300505294776164667214940546594746570981,\n 15265126113435022738560151911929040668591755459209400716467504685752745317193,\n 8334177627492981984476504167502758309043212251641796197711684499645635709656,\n 1374324219480165500871639364801692115397519265181803854177629327624133579404,\n 11442588683664344394633565859260176446561886575962616332903193988751292992472,\n 2558901189096558760448896669327086721003508630712968559048179091037845349145,\n 11189978595292752354820141775598510151189959177917284797737745690127318076389,\n 3262966573163560839685415914157855077211340576201936620532175028036746741754,\n 17029914891543225301403832095880481731551830725367286980611178737703889171730,\n 4614037031668406927330683909387957156531244689520944789503628527855167665518,\n 19647356996769918391113967168615123299113119185942498194367262335168397100658,\n 5040699236106090655289931820723926657076483236860546282406111821875672148900,\n 2632385916954580941368956176626336146806721642583847728103570779270161510514,\n 17691411851977575435597871505860208507285462834710151833948561098560743654671,\n 11482807709115676646560379017491661435505951727793345550942389701970904563183,\n 8360838254132998143349158726141014535383109403565779450210746881879715734773,\n 12663821244032248511491386323242575231591777785787269938928497649288048289525,\n 3067001377342968891237590775929219083706800062321980129409398033259904188058,\n 8536471869378957766675292398190944925664113548202769136103887479787957959589,\n 19825444354178182240559170937204690272111734703605805530888940813160705385792,\n 16703465144013840124940690347975638755097486902749048533167980887413919317592,\n 13061236261277650370863439564453267964462486225679643020432589226741411380501,\n 10864774797625152707517901967943775867717907803542223029967000416969007792571,\n 10035653564014594269791753415727486340557376923045841607746250017541686319774,\n 3446968588058668564420958894889124905706353937375068998436129414772610003289,\n 4653317306466493184743870159523234588955994456998076243468148492375236846006,\n 8486711143589723036499933521576871883500223198263343024003617825616410932026,\n 250710584458582618659378487568129931785810765264752039738223488321597070280,\n 2104159799604932521291371026105311735948154964200596636974609406977292675173,\n 16313562605837709339799839901240652934758303521543693857533755376563489378839,\n 6032365105133504724925793806318578936233045029919447519826248813478479197288,\n 14025118133847866722315446277964222215118620050302054655768867040006542798474,\n 7400123822125662712777833064081316757896757785777291653271747396958201309118,\n 1744432620323851751204287974553233986555641872755053103823939564833813704825,\n 8316378125659383262515151597439205374263247719876250938893842106722210729522,\n 6739722627047123650704294650168547689199576889424317598327664349670094847386,\n 21211457866117465531949733809706514799713333930924902519246949506964470524162,\n 13718112532745211817410303291774369209520657938741992779396229864894885156527,\n 5264534817993325015357427094323255342713527811596856940387954546330728068658,\n 18884137497114307927425084003812022333609937761793387700010402412840002189451,\n 5148596049900083984813839872929010525572543381981952060869301611018636120248,\n 19799686398774806587970184652860783461860993790013219899147141137827718662674,\n 19240878651604412704364448729659032944342952609050243268894572835672205984837,\n 10546185249390392695582524554167530669949955276893453512788278945742408153192,\n 5507959600969845538113649209272736011390582494851145043668969080335346810411,\n 18177751737739153338153217698774510185696788019377850245260475034576050820091,\n 19603444733183990109492724100282114612026332366576932662794133334264283907557,\n 10548274686824425401349248282213580046351514091431715597441736281987273193140,\n 1823201861560942974198127384034483127920205835821334101215923769688644479957,\n 11867589662193422187545516240823411225342068709600734253659804646934346124945,\n 18718569356736340558616379408444812528964066420519677106145092918482774343613,\n 10530777752259630125564678480897857853807637120039176813174150229243735996839,\n 20486583726592018813337145844457018474256372770211860618687961310422228379031,\n 12690713110714036569415168795200156516217175005650145422920562694422306200486,\n 17386427286863519095301372413760745749282643730629659997153085139065756667205,\n 2216432659854733047132347621569505613620980842043977268828076165669557467682,\n 6309765381643925252238633914530877025934201680691496500372265330505506717193,\n 20806323192073945401862788605803131761175139076694468214027227878952047793390,\n 4037040458505567977365391535756875199663510397600316887746139396052445718861,\n 19948974083684238245321361840704327952464170097132407924861169241740046562673,\n 845322671528508199439318170916419179535949348988022948153107378280175750024,\n 16222384601744433420585982239113457177459602187868460608565289920306145389382,\n 10232118865851112229330353999139005145127746617219324244541194256766741433339,\n 6699067738555349409504843460654299019000594109597429103342076743347235369120,\n 6220784880752427143725783746407285094967584864656399181815603544365010379208,\n 6129250029437675212264306655559561251995722990149771051304736001195288083309,\n 10773245783118750721454994239248013870822765715268323522295722350908043393604,\n 4490242021765793917495398271905043433053432245571325177153467194570741607167,\n 19596995117319480189066041930051006586888908165330319666010398892494684778526,\n 837850695495734270707668553360118467905109360511302468085569220634750561083,\n 11803922811376367215191737026157445294481406304781326649717082177394185903907,\n 10201298324909697255105265958780781450978049256931478989759448189112393506592,\n 13564695482314888817576351063608519127702411536552857463682060761575100923924,\n 9262808208636973454201420823766139682381973240743541030659775288508921362724,\n 173271062536305557219323722062711383294158572562695717740068656098441040230,\n 18120430890549410286417591505529104700901943324772175772035648111937818237369,\n 20484495168135072493552514219686101965206843697794133766912991150184337935627,\n 19155651295705203459475805213866664350848604323501251939850063308319753686505,\n 11971299749478202793661982361798418342615500543489781306376058267926437157297,\n 18285310723116790056148596536349375622245669010373674803854111592441823052978,\n 7069216248902547653615508023941692395371990416048967468982099270925308100727,\n 6465151453746412132599596984628739550147379072443683076388208843341824127379,\n 16143532858389170960690347742477978826830511669766530042104134302796355145785,\n 19362583304414853660976404410208489566967618125972377176980367224623492419647,\n 1702213613534733786921602839210290505213503664731919006932367875629005980493,\n 10781825404476535814285389902565833897646945212027592373510689209734812292327,\n 4212716923652881254737947578600828255798948993302968210248673545442808456151,\n 7594017890037021425366623750593200398174488805473151513558919864633711506220,\n 18979889247746272055963929241596362599320706910852082477600815822482192194401,\n 13602139229813231349386885113156901793661719180900395818909719758150455500533,\n ];\n\n let mut r = 0;\n for elem in array {\n let h = mimc(elem, r, constants, exponent);\n r = r + elem + h;\n }\n r\n}\n", - "path": "std/hash" - }, - "18": { - "source": "\nimpl Field {\n #[builtin(to_le_bits)]\n fn to_le_bits(_x : Field, _bit_size: u32) -> [u1] {}\n #[builtin(to_be_bits)]\n fn to_be_bits(_x : Field, _bit_size: u32) -> [u1] {}\n\n fn to_le_bytes(x : Field, byte_size: u32) -> [u8] {\n x.to_le_radix(256, byte_size)\n }\n fn to_be_bytes(x : Field, byte_size: u32) -> [u8] {\n x.to_be_radix(256, byte_size)\n }\n\n #[builtin(to_le_radix)]\n //decompose _x into a _result_len vector over the _radix basis\n //_radix must be less than 256\n fn to_le_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {}\n #[builtin(to_be_radix)]\n fn to_be_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {}\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b = exponent.to_le_bits(32);\n\n for i in 1..33 {\n r *= r;\n r = (b[32-i] as Field) * (r * self) + (1 - b[32-i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n fn sgn0(self) -> u1 {\n self as u1\n }\n}\n\n#[builtin(modulus_num_bits)]\nfn modulus_num_bits() -> Field {}\n\n#[builtin(modulus_be_bits)]\nfn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\nfn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\nfn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\nfn modulus_le_bytes() -> [u8] {}\n", - "path": "std/field" - }, - "31": { - "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n\n contract_deployment_data: ContractDeploymentData,\n\n private_global_variables: PrivateGlobalVariables,\n}\n\n// PublicContextInputs are expected to be provided to each public function\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n\n // TODO: include globals in here and check them elsewhere\n // https://github.com/AztecProtocol/aztec-packages/issues/1567\n}\n\nimpl PublicCircuitPublicInputs {\n \n fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n // We do not include block_data since it's not in the cpp hash\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize()); // see https://github.com/AztecProtocol/aztec-packages/issues/1473\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\nfn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/abi" - }, - "32": { - "source": "use crate::constants_gen::{\n EMPTY_NULLIFIED_COMMITMENT,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n};\n\nuse crate::abi;\n\nuse crate::abi::{\n hash_args,\n CallContext,\n ContractDeploymentData,\n HistoricBlockData,\n FunctionData,\n PrivateCircuitPublicInputs,\n PublicCircuitPublicInputs,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// l1 to l2 messaging\nuse crate::messaging::process_l1_to_l2_message;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem;\n\nuse crate::types::{\n vec::BoundedVec,\n point::Point,\n};\n\nuse crate::utils::arr_copy_slice;\n\nuse crate::oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n};\n\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n inputs: abi::PrivateContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n nullified_commitments: BoundedVec,\n\n private_call_stack : BoundedVec,\n public_call_stack : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n\n block_data: HistoricBlockData,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n fn new(inputs: abi::PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n nullified_commitments: BoundedVec::new(0),\n\n block_data: inputs.block_data,\n\n private_call_stack: BoundedVec::new(0),\n public_call_stack: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n fn finish(self) -> abi::PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = abi::PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n nullified_commitments: self.nullified_commitments.storage,\n private_call_stack: self.private_call_stack.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.block_data,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n fn push_read_request(&mut self, read_request: Field) {\n self.read_requests.push(read_request);\n }\n\n fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n self.nullified_commitments.push(nullified_commitment);\n }\n\n fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n fn consume_l1_to_l2_message(&mut self, inputs: abi::PrivateContextInputs, msg_key: Field, content: Field, secret: Field) {\n let nullifier = process_l1_to_l2_message(inputs.block_data.l1_to_l2_messages_tree_root, inputs.call_context.storage_contract_address, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn call_private_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n fn call_private_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n fn call_private_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PrivateCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n \n is_delegate_call : fields[8] as bool,\n is_static_call : fields[9] as bool,\n is_contract_deployment: fields[10] as bool,\n },\n // TODO handle the offsets as a variable incremented during extraction?\n args_hash: fields[11],\n return_values: arr_copy_slice(fields, [0; RETURN_VALUES_LENGTH], 12),\n read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 16),\n new_commitments: arr_copy_slice(fields, [0; MAX_NEW_COMMITMENTS_PER_CALL], 20),\n new_nullifiers: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 24),\n nullified_commitments: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 28),\n private_call_stack: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 32),\n public_call_stack: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 36),\n new_l2_to_l1_msgs: arr_copy_slice(fields, [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 40),\n encrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 42),\n unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 44),\n encrypted_log_preimages_length: fields[46],\n unencrypted_log_preimages_length: fields[47],\n block_data: HistoricBlockData {\n // Must match order in `private_circuit_public_inputs.hpp`\n private_data_tree_root : fields[48],\n nullifier_tree_root : fields[49],\n contract_tree_root : fields[50],\n l1_to_l2_messages_tree_root : fields[51],\n blocks_tree_root : fields[52],\n public_data_tree_root: fields[53],\n global_variables_hash: fields[54],\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: Point::new(fields[55], fields[56]),\n constructor_vk_hash : fields[57],\n function_tree_root : fields[58],\n contract_address_salt : fields[59],\n portal_contract_address : fields[60],\n },\n chain_id: fields[61],\n version: fields[62],\n },\n is_execution_request: fields[63] as bool,\n };\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.private_call_stack.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n fn call_public_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n fn call_public_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n fn call_public_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PublicCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n \n is_delegate_call : fields[8] as bool,\n is_static_call : fields[9] as bool,\n is_contract_deployment: fields[10] as bool,\n },\n args_hash: fields[11],\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [0; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [0; MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_data: HistoricBlockData::empty(),\n prover_address: 0,\n },\n is_execution_request: true,\n };\n\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.public_call_stack.push(item.hash());\n }\n}\n\nuse crate::abi::{\n ContractStorageRead,\n ContractStorageUpdateRequest\n};\n\nstruct PublicContext {\n inputs: abi::PublicContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_read: BoundedVec,\n public_call_stack: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicContext {\n fn new(inputs: abi::PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = ContractStorageRead::empty();\n let empty_storage_update = ContractStorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_read: BoundedVec::new(empty_storage_read),\n public_call_stack: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_data: inputs.block_data,\n prover_address: 0,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n fn finish(self) -> abi::PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = abi::PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_read: self.contract_storage_read.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.inputs.block_data,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n }\n\n fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, this, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn call_public_function(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = abi::hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n fn call_public_function_no_args(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/context" - }, - "33": { - "source": "use crate::context::PrivateContext;\nuse crate::oracle;\nuse crate::types::point::Point;\n\nfn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n log: [Field; N],\n) {\n let _ = oracle::logs::emit_encrypted_log(contract_address, storage_slot, encryption_pub_key, log);\n context.accumulate_encrypted_logs(log);\n}\n\nfn emit_unencrypted_log(\n context: &mut PrivateContext,\n log: T,\n) {\n let _ = oracle::logs::emit_unencrypted_log(log);\n context.accumulate_unencrypted_logs(log);\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/log" - }, - "39": { - "source": "use dep::std::option::Option;\nuse crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\nuse crate::constants_gen::EMPTY_NULLIFIED_COMMITMENT;\n\nfn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0 };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialise = note_interface.serialise;\n let preimage = serialise(*note);\n assert(notify_created_note(storage_slot, preimage, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\nfn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0 };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\nfn destroy_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: Note,\n note_interface: NoteInterface,\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = EMPTY_NULLIFIED_COMMITMENT;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note);\n\n let serialise = note_interface.serialise;\n let preimage = serialise(note);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // 0 nonce implies \"transient\" nullifier (must nullify a commitment in this TX).\n // `nullified_commitment` is used to inform the kernel which pending commitment\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullier to its output.\n if (header.nonce == 0) {\n // TODO(suyash): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(storage_slot, nullifier, preimage, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/note/lifecycle" - }, - "40": { - "source": "use dep::std::option::Option;\nuse crate::constants_gen::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort},\n note_interface::NoteInterface,\n note_header::NoteHeader,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n utils::compute_unique_siloed_note_hash,\n utils::compute_inner_note_hash,\n utils::compute_siloed_note_hash,\n};\nuse crate::messaging::get_commitment_getter_data::make_commitment_getter_data;\nuse crate::oracle;\nuse crate::types::vec::BoundedVec;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: Note,\n) {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n let contract_address = context.this_address();\n assert(header.contract_address == contract_address);\n assert(header.storage_slot == storage_slot);\n}\n\nfn ensure_note_exists(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: &mut Note,\n) {\n let saved_note = get_note_internal(storage_slot, note_interface);\n\n // Only copy over the header to the original note to make sure the preimage is the same.\n let get_header = note_interface.get_header;\n let set_header = note_interface.set_header;\n let note_header = get_header(saved_note);\n set_header(note, note_header);\n\n check_note_header(*context, storage_slot, note_interface, *note);\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, *note);\n context.push_read_request(note_hash_for_read_request);\n}\n\n// Ensure a note's hash exists in the tree without retrieving the entire\n// notes via the oracle.\n// Modifies the note by populating it with header info.\nfn ensure_note_hash_exists(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: &mut Note,\n) {\n // Initialize header of note. Must be done before computing note hashes as it initializes the:\n // - storage slot (used in inner note hash)\n // - the contract address (used in siloed note hash)\n // - and the nonce (used in the unique siloed note hash)\n let set_header = note_interface.set_header;\n let note_header = NoteHeader {\n contract_address: (*context).this_address(),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be\n // real nonce (once public kernel applies nonces).\n nonce: 0,\n storage_slot\n };\n set_header(note, note_header);\n\n // Get a note from oracle and early out if it doesn't exist.\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let raw_oracle_ret = oracle::get_commitment::get_commitment(inner_note_hash);\n let deserialized_oracle_ret = make_commitment_getter_data(raw_oracle_ret, 0);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be\n // unique_siloed_note_hash once public kernel applies nonces\n let saved_siloed_note_hash = deserialized_oracle_ret.message;\n\n assert(saved_siloed_note_hash != 0); // TODO(dbanks12): necessary?\n\n check_note_header(*context, storage_slot, note_interface, *note);\n\n // Ensure that the note hash retrieved from oracle matches the one computed from note.\n let computed_siloed_note_hash = compute_siloed_note_hash(note_interface, *note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be\n // compute_note_hash_for_read_or_nullify once public kernel applies nonces\n assert(computed_siloed_note_hash == saved_siloed_note_hash);\n\n context.push_read_request(computed_siloed_note_hash);\n}\n\nfn get_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let note = get_note_internal(storage_slot, note_interface);\n\n check_note_header(*context, storage_slot, note_interface, note);\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\nfn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let opt_notes = get_notes_internal(storage_slot, note_interface, options);\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n let mut note_hash_for_read_request = 0;\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n check_note_header(*context, storage_slot, note_interface, note);\n note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n };\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n };\n\n // TODO(#1660)\n // Move it back to get_notes_internal and only make read request for selected notes.\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained fn get_note_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n 0,\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n placeholder_note,\n placeholder_fields,\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n )\n}\n\nunconstrained fn view_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteViewerOptions,\n) -> [Option; MAX_NOTES_PER_PAGE] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>,\n) -> (u8, [u8; N], [Field; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n num_selects += 1;\n };\n };\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n };\n\n (num_selects, select_by, select_values, sort_by, sort_order)\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/note/note_getter" - }, - "42": { - "source": "use dep::std::hash::{pedersen, pedersen_with_separator};\nuse crate::constants_gen::{GENERATOR_INDEX__UNIQUE_COMMITMENT, GENERATOR_INDEX__SILOED_COMMITMENT};\n\nfn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen([storage_slot, note_hash])[0]\n}\n\nfn compute_siloed_hash(contract_address: Field, inner_note_hash: Field) -> Field {\n let inputs = [contract_address, inner_note_hash];\n pedersen_with_separator(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)[0]\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_with_separator(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)[0]\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/note/note_hash" - }, - "46": { - "source": "use crate::note::{\n note_hash::{compute_inner_hash, compute_siloed_hash, compute_unique_hash},\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\nfn compute_inner_note_hash(\n note_interface: NoteInterface,\n note: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n\n compute_inner_hash(header.storage_slot, note_hash)\n}\n\nfn compute_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let inner_note_hash = compute_inner_note_hash(note_interface, note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let siloed_note_hash = compute_siloed_note_hash(note_interface, note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\nfn compute_note_hash_for_read_or_nullify(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n if (header.nonce == 0) {\n // when nonce is zero, that means we are reading a pending note (doesn't have a nonce yet),\n // so we just read the inner_note_hash (kernel will silo by contract address)\n compute_inner_note_hash(note_interface, note_with_header)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note_interface, note_with_header)\n }\n\n}\n\nfn compute_note_hash_and_nullifier(\n note_interface: NoteInterface,\n note_header: NoteHeader,\n preimage: [Field; S],\n) -> [Field; 4] {\n let deserialise = note_interface.deserialise;\n let set_header = note_interface.set_header;\n let mut note = deserialise(arr_copy_slice(preimage, [0; N], 0));\n set_header(&mut note, note_header);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n let inner_note_hash = compute_inner_hash(note_header.storage_slot, note_hash);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let compute_nullifier = note_interface.compute_nullifier;\n let inner_nullifier = compute_nullifier(note);\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/note/utils" - }, - "48": { - "source": "use dep::std::hash::pedersen_with_separator;\nuse crate::context::PrivateContext;\nuse crate::note::{\n lifecycle::create_note,\n note_getter::{get_note, view_notes},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n};\nuse crate::oracle;\nuse crate::constants_gen::{\n GENERATOR_INDEX__INITIALISATION_NULLIFIER,\n EMPTY_NULLIFIED_COMMITMENT,\n};\n\nstruct ImmutableSingleton {\n storage_slot: Field,\n note_interface: NoteInterface,\n}\n\nimpl ImmutableSingleton {\n fn new(storage_slot: Field, note_interface: NoteInterface) -> Self {\n ImmutableSingleton { storage_slot, note_interface }\n }\n\n unconstrained fn is_initialised(self) -> bool {\n let nullifier = self.compute_initialisation_nullifier();\n oracle::notes::is_nullifier_emitted(nullifier)\n }\n\n fn initialise(self, context: &mut PrivateContext, note: &mut Note) {\n // Nullify the storage slot.\n let nullifier = self.compute_initialisation_nullifier();\n context.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT);\n\n create_note(context, self.storage_slot, note, self.note_interface);\n }\n\n fn compute_initialisation_nullifier(self) -> Field {\n pedersen_with_separator([self.storage_slot], GENERATOR_INDEX__INITIALISATION_NULLIFIER)[0]\n }\n \n fn get_note(self, context: &mut PrivateContext) -> Note {\n let storage_slot = self.storage_slot;\n get_note(context, storage_slot, self.note_interface)\n }\n\n unconstrained fn view_note(self) -> Note {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, self.note_interface, options)[0].unwrap()\n }\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/state_vars/immutable_singleton" - }, - "55": { - "source": "\nstruct BoundedVec {\n storage: [T; MaxLen],\n len: Field,\n}\n\nimpl BoundedVec {\n fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0 }\n }\n\n fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64);\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n fn push_array(&mut self, array: [T; Len]) {\n let newLen = self.len + array.len();\n assert(newLen as u64 <= MaxLen as u64);\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = newLen;\n }\n\n fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n\n let elem = self.storage[self.len - 1];\n self.len -= 1;\n elem\n }\n}\n\n// #[test]\n// fn test_vec() {\n// let vec: BoundedVec = BoundedVec::new(0);\n// assert(vec.len == 0);\n// let vec1 = vec.push(1);\n// assert(vec1.len == 1);\n// let vec2 = vec1.push(1);\n// assert(vec2.len == 2);\n// let vec3 = vec2.push(1);\n// assert(vec3.len == 3);\n// let x = vec3.pop();\n// assert(x == 1);\n// }", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/types/vec" - }, - "70": { - "source": "use crate::types::point::Point;\nuse dep::std::hash;\nuse crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n\n#[oracle(getPublicKey)]\nfn get_public_key_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_internal(address: Field) -> [Field; 3] {\n get_public_key_oracle(address)\n}\n\nfn get_public_key(address: Field) -> Point {\n let result = get_public_key_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = hash::pedersen_with_separator([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0];\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/oracle/get_public_key" - }, - "78": { - "source": "use crate::abi;\nuse crate::types::vec::BoundedVec;\nuse crate::context::PrivateContext;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem; \n\nglobal ACCOUNT_MAX_PRIVATE_CALLS: Field = 2;\nglobal ACCOUNT_MAX_PUBLIC_CALLS: Field = 2;\nglobal ACCOUNT_MAX_CALLS: Field = 4;\n// 1 (ARGS_HASH) + 1 (FUNCTION_SELECTOR) + 1 (TARGET_ADDRESS)\nglobal FUNCTION_CALL_SIZE: Field = 3;\n\nstruct FunctionCall {\n args_hash: Field,\n function_selector: Field,\n target_address: Field,\n}\n\nimpl FunctionCall {\n fn serialize(self) -> [Field; FUNCTION_CALL_SIZE] {\n [self.args_hash, self.function_selector, self.target_address]\n }\n}\n\n// FUNCTION_CALL_SIZE * (ACCOUNT_MAX_PUBLIC_CALLS + ACCOUNT_MAX_PRIVATE_CALLS) + 1\nglobal ENTRYPOINT_PAYLOAD_SIZE: Field = 13;\nglobal ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES: Field = 416;\n\nstruct EntrypointPayload {\n // Noir doesnt support nested arrays or structs yet so we flatten everything\n flattened_args_hashes: [Field; ACCOUNT_MAX_CALLS],\n flattened_selectors: [Field; ACCOUNT_MAX_CALLS],\n flattened_targets: [Field; ACCOUNT_MAX_CALLS],\n nonce: Field,\n}\n\nimpl EntrypointPayload {\n // TODO(#1207) Do we need a generator index?\n fn hash(self) -> Field {\n dep::std::hash::pedersen(self.serialize())[0]\n }\n\n // Serializes the entrypoint struct\n fn serialize(self) -> [Field; ENTRYPOINT_PAYLOAD_SIZE] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.flattened_args_hashes);\n fields.push_array(self.flattened_selectors);\n fields.push_array(self.flattened_targets);\n fields.push(self.nonce);\n fields.storage\n }\n\n // Serializes the payload as an array of bytes. Useful for hashing with sha256.\n fn to_be_bytes(self) -> [u8; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] {\n let mut bytes: [u8; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = [0; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES];\n\n let args_len = self.flattened_args_hashes.len();\n let selectors_len = self.flattened_selectors.len();\n let targets_len = self.flattened_targets.len();\n\n for i in 0..args_len {\n let item_bytes = self.flattened_args_hashes[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[i * 32 + j] = item_bytes[j];\n }\n }\n\n for i in 0..selectors_len {\n let item_bytes = self.flattened_selectors[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[args_len * 32 + i * 32 + j] = item_bytes[j];\n }\n }\n\n for i in 0..targets_len {\n let item_bytes = self.flattened_targets[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[(args_len + selectors_len) * 32 + i * 32 + j] = item_bytes[j];\n }\n }\n \n let item_bytes = self.nonce.to_be_bytes(32);\n for j in 0..32 { \n bytes[(args_len + selectors_len + targets_len) * 32 + j] = item_bytes[j];\n }\n\n bytes\n }\n\n // Executes all private and public calls \n fn execute_calls(self, context: &mut PrivateContext) {\n for i in 0..ACCOUNT_MAX_PRIVATE_CALLS {\n let target_address = self.flattened_targets[i];\n if target_address != 0 {\n let function_selector = self.flattened_selectors[i];\n let args_hash = self.flattened_args_hashes[i];\n let _callStackItem = context.call_private_function_with_packed_args(target_address, function_selector, args_hash);\n }\n }\n for i in ACCOUNT_MAX_PRIVATE_CALLS..ACCOUNT_MAX_CALLS {\n let target_address = self.flattened_targets[i];\n if target_address != 0 {\n let function_selector = self.flattened_selectors[i];\n let args_hash = self.flattened_args_hashes[i];\n let _callStackItem = context.call_public_function_with_packed_args(target_address, function_selector, args_hash);\n }\n }\n }\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/entrypoint" - } - } - } + ] } diff --git a/yarn-project/aztec.js/src/abis/schnorr_account_contract.json b/yarn-project/aztec.js/src/abis/schnorr_account_contract.json index 251a685cdcf..39a39cee158 100644 --- a/yarn-project/aztec.js/src/abis/schnorr_account_contract.json +++ b/yarn-project/aztec.js/src/abis/schnorr_account_contract.json @@ -141,73 +141,8 @@ } ], "returnTypes": [], - "bytecode": "H4sIAAAAAAAA/+1dB3QcRdKe3VVe5SxLspKzHHYULDnhdU5gG9tE2zghg8HYBJucc8455yPnnNMBBxxHOo7jOOA4DjjykTN/t1yNaltjgdnqdfW/M+/Vq+7e3e6vQlfXzvTMDEx1nNUpTucREBQUlAJlVU/V6mlQTl33Mwd+7pQKKhNULqgC/U593ktQpaAqQdXweRB93ltQjaBaQXVovAZBGajeR6v31er9tHp/rT5Aqw/U6oO0eqNWH6zVh2j1oVp9mFaPaHVXqzdp9Wat3qLVW7X6cK3eptXbtfoIrT5Sq4/S6qO1+hitvolWH6vVo1p9nFYfr9UnaPWJWn2SVp+s1ado9alafZpWn67VZ2j1TbX6Zlp9plafpdVna/XNtfocrT5Xq8/T6lto9S21+lZafWutvo1W31arz9fqC7T6Qq2+nVZfpNUXa/UlWn0p1GV8CDnr/EUeMg7IuS/nu5zjcl4PcNbNXzln5TyVc1PORzkH5byTc03OLzmn5DySc0fOFzlH5LyQc0H6v/R56efSt6U/Sx8eC2NL/5Q+Kf1Q+p70N+lj0q+kL0n/kT4j/UT6hvQH6QOzwNabg03ngu22ABttBbbYBnQ+H3S7EHS4CHS1BHQi9SNjby3oQ8bbn5x1MVfycuAVwHsBrwReBbwaeG/gNcBrgdcBrwfeALwP8L7A+wHvD3wA8IHABwFvBD4Y+BDgQ4EPAx4B7gJvAt4MvAV4K+pvmaDtPXQzHL7TBrwd+AjgI4GPAj4a+BjgmwAfCzwKfBzw8cAnAJ8IfBLwycCnAJ8KfBrw6cBnAN8U+GbAZwKfBXw28M2BzwE+F/g84Fsg3XQIWu7EHgHgUeDNkeEtLR1tTR1us7sk0jRiaXtrpKV16fB2t91tbW/dvqm9ubmjvaW9bcTSEW2REW5Lc4e7vHVE8/LIumMH1FckzsMkzh0twbnCEpw7WYJzZ0twrrQE5y6W4FxlCc7VluDc1RKcu1mCc3dLcO5hCc41luBcawnOPS3BuZclOPe2BOc+hDj1/2TyP6/8b7IV8K2BbwN8W+DzgS8AvhD4dsAXAV8MfAnwpcB3AL4j8BXAdwK+M/CVwHcBvgr4auC7At8N+O7A9wC+Bvha4HsC3wv43sD3cbr+k+0raD8n9qC24f6OHb52gCU4D7QE50GW4DzYEpyHWILzUEtwHmYJzsMtwXmEJTiPtATnUZbgPNqhz9HyoT95Pl3mKh3A9wW+P/ADgB8I/CDgBwM/BPihwA8DfjjwI4AfCfwo4Ec7XTnSMYKOddZd+0l31n9EaXTgmuu7pdlg3y0G+2412Pdwg323Gey7PQ31eRzw44GfAPxE4CcBPxn95rPwOp7prLu+KQ/Vp2xTvp6K2tTnKahNfR5CberzIGpTnwdQm/rc0caXRxR4JM4jzeke8yJxHlLmAiSH4yFvwEMvQQ/9qc9TPfSH7aE+V3bJFRT2GDsNYYrSyOsGnNgjispqLIwlxAhLCiMsqYywpDHCks4ISwYjLIGNjAXHMXVIHx4Z6vpc5Wo49qnYiGNfIZRx7CtCfaq2YiSzaiuBcjpqK4VyBmpTuPNRWxaUcbxWOi5EbdlQLkJtOVAuRm25UC5BbXlQLvXAh22ofhMFHonv6LQhHieK6mqsLIShlAGWDEZY0hlhSWOEJZURlhRGWEKMsATNY+nMnYuI+8Qx3kFy4iOKykVIvkID8hUYkK9wA+QrQPLlG5CvzIB8+RsgXxmSr9yAfBUG5CvfAPkqkHy9DMhH3Kcr+6w0gLOats82aYcq57fboRrZoTexfLKPGjSWwqXGCaPPMxGOGmLbBdCYql9Vx/h+K9Ysi7CGLcKabRHWHIuw5lqENW8jY6Uf1+2MyXhcefQUkzGWWlIs69acOuI+ZR/1CL+SVWEPo8/rkGz1tDg67VvrxOpU1evRuL78pOP68ju+/L78vvy+/L78vvy+/L78vvy+/L78tb78vvy+/L78vvy+/L78vvwM5F/f3t9aA1gcDYvjoRd1hBhhSWGEJZURljRGWNIZYclghCWTEZYsRljCjLBkM8KSwwhLLiMseYyw5DPCUsAISyEjLEWMsBQzwlLCCEspIyxljLCUM8JSwQhLL0ZYKhlhqWKEpZoRlt6MsBjcQ7fBWOoYYQlsZCxe90Zmos+DqE2ds8H3QzZAGd8P2QfK+H7IvkhO1dYPyvh+yP5QxvdDDoAyvldxIJTxPY2DoIzvh2yEMr6XcjCUy1HbECj3Qm1DoVyJ2oZBuQq1qQeT9EZtSm+1qE3prR61Kb01oDaltz6oTemtL2pTeuuH2pTe+qM29R98AGpT/4UHojbll4NQm/pv2Ija1H+0wahN/VcagtrUf5ahqE3ZYRhqUzm80qOUfza6N1d9F/tixKMfVcZzSo0dVWMQzCk8ThTV1Vj4XtVhDLDUMcJSwwhLb0ZYqhlhqWKEpZIRll6MsFQwwlLOCEsZIyyljLCUMMJSzAhLESMshYywFDDCks8ISx4jLLmMsOQwwpLNCEuYEZYsRlgyGWHJYIQlnRGWNEZYUhlhSWGEJcQIS9ADSx0tls7TPuocU2d/wOsQDoVpCMIxmFgnso9GDxyDEQ41fiPCMYgWh3yd3y/n8DCOQQiHGn8gwjGAFkfnM3n7e+AYgHCo8fsjHP1ocXQ+v7evB45+CIcaH5+T7kOLo/NZvw0eOPogHGr8BoSjnhZH53OBaz1w1CMcanz1PX9P5q9j8fdk+nsyNwSLvyfT35O5IVj8PZn+nswNweLvyfT3ZG4IFn9Ppr8nc0Ow+Hsy/T2ZG4LF35Pp78ncECx1jLDUM8LSwAhLH0ZY+jLC0o8Rlv6MsAxghGUgIyyDGGFpZIRlMCMsQxhhGcoIyzBGWCKMsAQ2MpZfu48D78FXL+fEe/WboIz3+asXbeJ7BNQLMvH9BerFlvjeBPVCSnxfQ9ADs7qm46I2dW2lCbWpaxzNqE1da2hBbeqcfytqU+feFSbZ101ZXZ/XQnsQ/Ua99BLf69IOZXyvywjUp2obCWV8r8soKON7XRSeWtSmcLehNiVfO2pTehiB2pS+RqI2pddRHliwz6rfRIFH4js6fRaPE0V1NRa+T2IUAywRRliGMcIylBGWIYywDGaEpZERlkGMsAxkhGUAIyz9GWHpxwhLX0ZY+jDC0sAISz0jLHWMsNQwwtKbEZZqRliqGGGpZISlFyMsFYywlDPCUsYISykjLCWMsBQzwlLECEshIywFjLDkM8KSxwhLLiMsOYywZDPCEmaEJYsRlkxGWDIYYUlnhCWNEZZURlhSGGEJMcIS1LDg60zDUZu6HoSvf6nrRvg6mbq+hK+n1UIZX3cbDWV8fS6o4cPX8fD1KGVLfN1K+Rq+vqXmQi1qU3NVjZ8O31NjR4FH4jzSEHa/z+TpEz8XD1/3Ves4vu4b9mjL9mjL8WjL9WjL82jDGBRXn2ehNjWnwqhNzals1KbmVA5qU3MqF7Wp9VlhUvNM/XeLAo/EdzTJsdR/MHX0tK+hCGFU/2nxvRwltPg643CxhkXV1VhhhCHfHJa28HrGVkcQjV1sQA+Opgd1FHtgCTHCksIISyojLGmMsKQzwpLBCEsmIyxZjLCEGWHJZoQlhxGWXEZY8hhhyWeEpYARlkJGWIoYYQlsZCzr20OsPsf/UfCz2BVX1+Tw/5UyTU7Zpq5p4v8r6por/r/SC8r4/0ollPNQm7qmXoDagh6yqVwVY1c5YylqU7lbGWpTORR+ZrzKZSpQm8op8HPklY4qUZvSkcIux3wwq7ucQQ85cT+qjH1HjR0FHonv6PQdPE4U1dVYeC9vJQMsRYywFDLCUsAISz4jLHmMsOQywpLDCEs2IyxhRliyGGHJZIQlgxGWdEZY0hhhSWWEJYURlhAjLEEPLBW0WDpvvVK5tTxUrluBcChM+Fk0ZcQ4AhqOWjQufh5PKbEtZB8lHvLj/1Rq/BLUpsr4PzW1bfB/QNW3nCsfh8zpw8B9tJ22VfvS5XEQkqsW6c/EuDXauKXauPI7+Dk1ByGs6rch9J3vQl12+ArKWag//A60Om0s/P9Yfaau+9UbkF2NoTAondcj2euR7LXoN+VIdvWdn5Hs12V1/c7kM3yDCDd+Dko/2jE7t17g5xer/vGzhAegsooT6jf43i78/A0T8QrjUOOXorZBHji9ngeNn4fRSIuz0/8wjgAaV40VQt/JgSRAsmuRb5mwc6PTXX/9kC6G0I7ZLOf9YCf26Om8IH4GBvEz5SOmcohhCL+SVWEPo8/xM+SG0eLozKuGOrE6VXX8/AxfftJxrZJ/ffs5TLy7wdGwOB56UUeIEZYURlhSGWFJY4QlnRGWDEZYMhlhyWKEJcwISzYjLDmMsOQywpLHCEs+IywFjLAUMsJSxAhLMSMsJYywlDLCUsYISzkjLBWMsPRihKWSEZYqRliqGWHpzQhLDSMstYyw1DHCUs8ISwMjLH0YYenLCEs/Rlj6M8IygBGWgYywDGKEpZERlsGMsBi81rXBWAIbGcv67gNQn1ehNnU9YzBqU89Rxs8SD3qMob+7Gu/HV33I8+4vZHUfL+gx3jAPXKZ1+Vveix3Q8G1MLEMYYRnMCEsjIyyDGGEZyAjLAEZY+jPC0o8Rlr6MsPRhhKWBEZZ6RljqGGGpZYSlhhGW3oywVDPCUsUISyUjLL0YYalghKWcEZYyRlhKGWEpYYSlmBGWIkZYChlhKWCEJZ8RljxGWHIZYclhhCWbEZYwIyxZjLBkMsKSwQhLOiMsaYywpDLCksIIS4gRlqCGxb8X5Nex+PeCeGPx7wXxxuLfC+KNxb8XxBuLfy+IN5ZcRljyGGHx7wXxxuLfC+KNxb8XxBuLfy+INxb/XhBvLP69IN5Y/HtBvLH494J4Y6llhKWOEZZ6Rlj8e0G8sfj3gnhj8e8F8cbi3wvijaWRERb/XhBvLKavV2wIlggjLIGNjOXX7pGJoLag9lt5/SA73PW5en9nEP1GvR8TvyNQvUczBbWNQH2qtpFQTkNto6Cc7oEVvz9UvecTv59TvQ8Uv8dTvTcUv++zBcr4vaDqPaSjPLBgG26s96oGNHwbE0uEEZZhjLAMYYRlMCMsjYywDGKEZSAjLAMYYenPCEs/Rlj6MsLShxGWBkZY6hlhqWOEpZYRlhpGWHozwlLNCEsVIyyVjLD0YoSlghGWckZYyhhhKWWEpYQRlmJGWIoYYSlkhKWAEZZ8RljyGGHJZYQlhxGWbEZYwoywZDHCkskISwYjLOmMsKQxwpLKCEsKIywhRliCHlhG0GJpwteuHIQJH1FUxtee2jXMEl+bAV21a1hUXY0VRhiGGsQS9hjbwDhNmZrM8ujJJvi6obqu2I7wjSbWQwCNo/pVdTUW1pVrEEvYY2wD4zRlajLLoyebqPHl78ZAeTjCtwmxHgJoHNWvqquxsK6aDGIJe4xtYJymTE1mefRkEzW+/N1YKI9B+KLEegigcVS/Y7UxsK6aDWIJe4xtYJwmrFt19GQTVZa/GwflsQjfeGI9BNA4ql9VV2NhXbUYxBL2GNvAOE2Zmszy6Mkmanz5uwlQHofwTSTWQwCNo/pVdTUW1lWrQSzh9YytjiAae4IBPTiaHtQxwQNLiBGWFEZYUhlhSWOEJZ0RlgxGWDIZYclihCXMCEs2Iyw5jLDkMsKSxwhLPiMsBYywFDLCUsQISzEjLCWMsJQywlLGCEs5IywVjLD0YoSlkhGWKkZYqhlh6c0ISw0jLLWMsNQxwlLPCEsDIyx9GGHpywhLP0ZY+jPCMoARloGMsAxihKWREZbBjLAMYYRlKCMswxhhiTDC4jLC0sQISzMjLC2MsLQywjKcEZY2RljaGWEZwQjLSEZYRjHCMpoRljGMsGzCCMtYRliijLCMY4RlPCMsgY2MZX3PI1Kf42fyqL1E+Hk+k6CMnwU0GcpjUNsUKI9FbVOhPA61TYNyGWqbDuX+qG0GlIOoLeghWwjKE1Gb2uczCbWp/TaTUZva9zIFtan9J1NRm9oHMg21qf0Y01Gb2hehsMsx54e7y4R9Qv0+CjwS39HpE3icKKqrsfDzjWYwwDKeEZZxjLBEGWEZywjLJoywjGGEZTQjLKMYYRnJCMsIRljaGWFpY4RlOCMsrYywtDDC0swISxMjLC4jLBFGWIYxwjKUEZYhjLAMZoSlkRGWQYywDGSEZQAjLP0ZYenHCEtfRlj6MMLSwAhLPSMsdYyw1DLCUsMIS29GWKoZYalihKWSEZZejLBUMMJSzghLGSMspYywlDDCUswISxEjLIWMsBQwwpLPCEseIyy5jLDkMMKSzQhLmBGWLEZYMhlhyWCEJZ0RljRGWFIZYUlhhCXECEtQw5KFPi9EbWr/EX7+ptqn1I7a1H6m4ahtMpTHoDa1P2osalP7qMYBV3HYcfznSq0Pi/9cKW8saYyw+M+V8sbiP1fKG0uYERb/uVLeWPznSnlj8Z8r5Y3Ff66UNxb/uVLeWPznSnlj8Z8r5Y3Ff66UNxb/uVLeWPznSnljqWWEpY4RlnpGWBoYYfGfK+WNpR8jLP5zpbyx+M+V8sbSyAiL/1wpbyz+c6W8sfjPlfLG4j9XyhuL/1wpbyz+c6W8sfjPlfLG4j9XyhuL/1wpbyz+c6W8sUQZYRnHCMt4RlgmMsIyiRGWyYywTGGEZSojLNMYYZnOCMsMRlgCGxnLrz23Dj+LbVMo42e2bQZl/Gy3mVCejNpmQRk/K242lPEz5YIe+EJQ3hS1qb2Am6E2tSdvJmpTe+NmoTa1R02NL393fbjr8znQHkS/mQvlEGqbB+UU1LYF6lO1bQnlNNS2FZTTUdvWUM5AbQrjHNSmZJmL2pTM81Cb0s0WqE3pcEvUpnS9FWrbHMpbe+DDPqt+EwUeie/o9Fk8ThTV1VhZCMPWDLDMYIRlOiMs0xhhmcoIyxRGWCYzwjKJEZaJjLCMZ4RlHCMsUUZYxjLCsgkjLGMYYRnNCMsoRlhGMsIyghGWdkZY2hhhGc4ISysjLC2MsDQzwtLECIvLCEuEEZZhjLAMZYRlCCMsgxlhaWSEZRAjLAMZYRnACEt/Rlj6McLSlxGWPoywNDDCUs8ISx0jLLWMsNQwwtKbEZZqRliqGGGpZISlFyMsFYywlDPCUsYISykjLCWMsBQzwlLECEshIywFjLDkM8KSxwhLLiMsOYywZDPCEmaEJYsRlkxGWDIYYUlnhCWNEZZURlhSGGEJMcIS9MCyJS2WNjymHE/lknjv5jziMfF+UQfpAR9RVJ6HsMyhxRKR426D+o+iMfC429KO6+JxA0BqDNUeQuWharFB35PHdOAKs/zaXI/v4fIW2m/C6PO5hmWeg3BEUV2NJWNBA5J1rgfurRBu9flshLuUGLfsYx7CocbHz+8i9ss2vPdaHT3NkTkIC7HdOufIfNR/FI2Bx11ArHc8rpojagzVHkLlcchvFnQVf/EbhVl+bRuP7+GyPofC6PNtDMuM52oU1dVYco4MR7Ju44F7HsKtPp+FcJuYI3huq/HxHCH2y845gmWXR09zZFuEhdhunXNkIeo/isbA425HrHc8rpojagzVHkLlechvtusq/uI3CrP82nyP7+GyPofC6PP5hmXGczWK6mosOUemIVnne+DG65/6fCbCbWKO4LmtxsdzhNgvO+cIll0ePc2RBQgLsd0658gi1H8UjYHHXUw7rovHVXNEjaHaQ6i8A/KbxV3FX/xGYZZfW+jxPVzW51AYfb7QsMx4rkZRXY0l58gCJOtCD9x4/VOfb4Zwm5gjeG6r8fEcIfbLzjmCZZdHT3NkO4RlMS2WzjmyBPUfRWPgcZfSjuvicdUcUWOo9hAq74v8ZmlX8Re/WQxcfm2Rx/dwWZ9DYfT5IsMyL0Y4oqiuxpJzZDWSdZEHbrz+qc83RbhNzBE8t9X4eI4sph2zc45g2eXR0xxZjLAQ261zjixD/UfRGHjc7WnHdfG4ao6oMVR7CJVPQH6zfVfxF79RmOXXlnh8D5f1ORRGny8xLDOeq1FUV2PJOXIoknWJB268/qnPJyDcJubIYoRDjY/nCLFfds4RLLs8epojSxEWYrt1zpEO1H8UjYHHXU47rovHVXNEjaHaQ6h8MfKb5V3FX/xGYZZfW+bxPVzW51AYfb7MsMx4rkZRXY0l58gZSNZlHrgXI9zq880RbhNzBM9tNb4aJxPhwO82MBlXVb+qjm1ZqOnLAJa2sMfY0nbXZnWVr8syaxOsi2IPm6i2ZQjfx3DhQjJ13eAWwJkDv1PXCEOoryzUh2pT11jxsxzwO2JUm7pGjZ/loK6h42c5BFFZcYUhC7UpDGHUpjBkozaFIQe1KQy5CFMa+l0UeCS+ownrRx09xXiMO0eTLw3hJcLXOZdyNCw5mm7CCEOWMSxu51zSx87y0EOWhk3hySPGI/ssIO5T2lXtp1FHT/6gxs9wuubIDh1rZq5e07FHAP1e9VmGdKSOICqH0G9SnO44Uj3a0jza0p3uRwYqZ6JyHvpdroZTfk/F6XzUpjCrz9T8VFiiwCPxHU04ZmD58BFFZRzPlA7wO+4yaPG5uq6jqK7GCiMMIXNYmsMeY2etRw+ZtGNHMp3YNUIeKYLeQGtrmFheA/G2M89WMV4eByG58PvDTIybo40b1sYNOLHx/SCEVf02hL7zAcpx3oUyjs04H8jTxsJzXH2W7sTu8cPzEsdMpa8U1FaIykHtN3g/Jc5L1d7TKPBIfEdzpoZDHj3FEvzOrRJaLJ32xv9do2gMPG4Z7bguHlf9n1NjqPYQKv+EFqqyruIvPqAw433L+Hu4XKj9Jow+LzYscwnCEUV1NZb01c+RrMUeuHE8V5/j99UVE+OWfRQhHBkatkwkB47t1P9hetJfKdJJqqYvA1g61zh9bFO6L/kV3as29T19vUuhxdR5mz2OuUE0rjzwfjfsD8Q5Wadu0j1wpCEcanz8Hl3ifKdJ2UHH4ZX7qO+t7/3UxPlQj8+s9MISYoQlhREWgznrBmNJY4QlnRGWDEZYAhsZi9dzaKUP34+ey6pydnweDefvqk3l4imoTY2Dz0OptAWfP9P/O+D+sI5yNFki8R1uQBsniupqLPzc01wGWDIYYUlnhCWNEZZURlhSGGEJMcIS1LCsL66p2OV1/gHna/h8o+IFaDzVpv5v4OsMQQ0fvkaBY6eyZR5qU7jw+GouFKA2hRWfA11ffkl87qvHtSiscceJzS83NpYURlhSGWFJY4QlnRGWDEZYMhlhyWKEJbCRsXjl3TgPxrm2iv94TVLrBM61ezpPjq8zqXUCr134uqBqK0RlxdX5PbyeBT1k62ntwmucnifhtQuvcQorXuMUVrzGKawYu8KqsMsxnwh3lwn7hPp9FHgkvqPTJ/A4UVRXY+H/GUUMsGQxwpLJCEsGIyzpjLCkMcKSyghLCiMsIUZYghoWtSeDes8DXhfw+qbiG15r1Rrm9f8Pr7VqDcNrLf5Pq9q8/ifi8RQ3vR8Nr5cYUxrCEwUeifOwpU+sz6CHPoMe+sRtqox9AP9vVW0pSN+K42fJqH7ws26wP+i5nteeCLzPAV/X6inXw//3TcQANY7qV98zEXa6544msIQ9xsZ6CDHQg54vbww9pDDQg/4fYWPoIZWBHhSGjI2ohzQGesBxdGPpIZ2BHhSGrATrQY6rn6cg3ZihjpDWd3NkeEtLR1tTh9vsLok0jVja3hppaV06vN1td1vbW7dvam9u7mhvaW8bsXREW2SE29Lc4S5vHdG8HDoPEuI8kRDXKXS4IiEv46A2KvkpMWO8p6KyCvxBD59IMyCTo42j6zHXMez4Jox0qoF+T3PonN+U3KfR2yiC7c5dp+og/ofknkyI83TCvhIV+E53zAS+M1DZD3xx9nk6KJS63zMd3oFPyn0mvY2MBj5KnSYqCJzkmAkCZ6GyHwTi7PMkUCh1v2c7vIOAlPtsehtF1H2aygmPE/SToOOBnwBcHucIOtfpurdTOfHJ8J1z0HfPE3Q++u5v6f8CQRf20P8F6LsXCbrY47snwncuAi4n3CWCLvX47knwnUuAS4yXCbrciT30bCte/6D0tSsc2nMUeJ9eKeilDHg58ArgvYBXAq8CXg28N/Aa4LXA64DXI36loD+ArnFwpJ5HV9L1FamFfq4SdLWgawRdK+g6QdcLukHQjYJuEnSzoFsE3SroNkG3C7pD0J2C7hJ0t6B7BN0r6D5B9wt6QNCDgh4S9LCgRwQ9KugxQX8U9LigJ0BJAdCbxJLhdNWv1urXaPVrtfp1Wv16rX6DVr9Rq9+k1W/W6rdo9Vu1+m1a/XatfodWv1Or36XV79bq92j1e7X6fVr9fq3+gFZ/UKs/pNUf1uqPaPVHtfpjWv2PWv1xrf6EE3v/vDz0U2yR+I6YORNvvLqKsK8jU8wkw1SnKDuWyyPiXk3Ul7TFNYT6O4q9/jq7dq+Nv68mkNm9jlB/R3PWX8svON3r4+srgmR2byDU3zFc9dcUg9O98ff3FdFkdm8i1N+xDPU3fHk3nO7Nv6+vdg+Z3VsI9XccN/21e+J0b93wvtrWI7N7G6H+juekv7b14nRv37C+mnqQ2b2DUH8ncNFfW4843Tt/e1/LfkVm9y5C/Z3IQX9tv4rTvfu39RX5DTK79xDq76SNrb/Ib8Lp3vvrfbX+Rpnd+wj1d/LG1F/Lb8bp3t9jXy3LN0Bm9wFC/Z2ysfTXtkE43QfX31f7BsrsPkSov1M3gv5GLN9gnO7D3n1FfofM7iOE+jst0fqL/C6c7qPd+3J/p8zuY4T6Oz2R+tv+d+N0/xjbV3McMruPE+rvjATpr2l5XDjdJxy6c4n4nF28+jszQfqLxHe4hOfZ3KMJ9XeWJfojPE/kHkuov7Mt0R/heQ73eEL9nWOJ/gj/p7snEurvXEv0R/g/0z2ZUH/nWaI/wv9J7qmE+jvfEv0R5vnu6YT6u8AS/RHmqe6ZhPq70BL9EeZZ7tmE+rvIEv0R5gnuuYT6u9gS/RGuc+75hPq7xBL9EcZp90JC/V1qif4I44x7MaH+LrNEf4TzxCX0GZdSf3I/m7wXWt8frPpvcNbtc+sDvC/wfsD7Ax8AfCDwQcAbgQ8GPgT4UODDgEeAu8CbgDcDbwHeCnw48Dbg7cBHAB8JfBTw0cDHAN8E+FjgUeDjgI8HPgH4ROCTgE8GPgX4VODTgE8HPgP4psA3Az4T+Czgs4FvDnwO8LnA5wHfAviWwLcCvjXwbYBvC3w+8AXAFwLfDvgi4IuBLwG+FHits+5Q+x3VPki1P/Ix4Go/5SPA1f7Lh4Cr/ZpqH6fa36n2far9oGqfqNo/qvaVqv2mah+q2p+q9q2q/axqn6va/6r2xar9smofrdpfq/bdqv24ap+u2r97FfAnndiDen/0kw5dfE3UjTu9Hdo4pI4/obJ/406cffYGhVL3+5RD57Cm5H6K3kadkyvkdD84Ty6TOHtZgrPUoQ9WAdTn04KeEfRnQc8K+oug5wQ9L+gFQS8KeknQXwW9LOhvgl4R9HdBrwr6h6DXBP1T0OuC3hD0pqB/CXpL0L8FvS3oP4LeEfSuoPcE/VfQ+4I+EPShoI8EfSzoE0GfCvqfoM8EfS7oC0FfCvpK0NeCvhH0raDvBH0v6AdBPzrrEsCfQcCAoKCgkKAUQamC0gSlC8oQlCkoC0VE/FBRPXjjB3gFUBsO7vJIQ+Uo8Eich4HFIiIT5wwkh6PJm+uYeOFOS8yD1RxNn7resD4lVvUwwGVLVq6cvfuKPZes6Zi8dtWyNStWr8Junap1E/IQT2/Hz+/T3zGIzYyf0xbQ8UeBx7um4PUpEt/hJirm/9kxE0sdWpxNBvt2sXOFQcHZyLnVPAs63V80FUB2ks74s9PdVgFUDsJ3Qj18J7CefvB8xy9dsCV2GU1k1V1y0oA/Ol13zWUHug9KfdYGT6L47iBbvlzij7cvFZCyA/Yloc86fkDCASkHFJzrByQ7A1KOFpByExCQ8CSKNyDlEAakXAsD0l8cPyDhgJQHCs73A5KdASlPC0j5CQhIeBLFG5DyCANSvoUB6UXHD0g4IBWAggv9gGRnQCrQAlJhAgISnkTxBqQCwoBUaGFAesnxAxIOSEWg4GI/INkZkIq0gFScgICEJ1G8AamIMCAVWxiQ/ur4AQkHpBJQcKkfkOwMSCVaQCpNQEDCkyjegFRCGJBKLQxIWQE/IOGAVAYKLvcDkp0BqUwLSOUJCEhZAbqAVEYYkMoNTW5q/eHtXfHK/DRhXxXEAb2b8zv0AZ0SM8bbC1X8fahx9imN1CtA328lYfAwJXdlgNxGPb6WhnLvVLx9VQV4+6W0TVWAfv/ZI5bc5ERp62pCWz9CeMNZohaiakMLUW9/IaI1Um8DC1EN84VIyl1jeCHirlMHOTIlTnwTRLw4nyHsq9bCbL7WUBCt84MorZHqDATReuZBVMpdn8TZfAPzbF7apsFANv9YEmbzfQht/ZiF2XwfQwtRX38hojVSXwMLUT/mC5GUu59l2Ty1Th3kyJQ48a3C8eJ8mbCv/hZm8/0NBdEBfhClNdIAA0F0IPMgKuUemMTZ/CDm2by0zSAD2fzjSZjNNxLa+nELs/lGQwvRYH8hojXSYAML0RDmC5GUe4hl2Ty1TtVBvWCWE+IcGjAzeTknCcOYJwnSJsMMJAlPJmGSECG09ZMWJgkRQ0mC6ycJtEZyDSQJTcyTBCl3k2VJQpMlSUIhIc7mJEwSWpgnCdImLQaShKeSMEloJbT1UxYmCa2GkoThfpJAa6ThBpKENuZJgpS7zbIkoc2SJKGYEGd7EiYJI5gnCdImIwwkCc8kYZIwktDWz1iYJIw0lCSM8pMEWiONMpAkjGaeJEi5R1uWJIy2JEkoJcQ5JgmThE2YJwnSJpsYSBKeTcIkYSyhrZ+1MEkYayhJiPpJArGRDCQJ45gnCVLucZYlCeMMJQl6EI237yChzM8R4hpPGJASFUTHGwqiE/wgSmukCQaC6ETmQVTKPdFwEOWczU9ins1L20wykM0/l4TZ/GRCWz9nYTY/2dBCNMVfiGiNNMXAQjSV+UIk5Z5qWTZPrVMHOTLGGW/fhK9qdZ8nxDXNwmx+mqEgOt0PorRGmm4giM5gHkSl3DOSOJvflHk2L22zqYFs/oUkzOY3I7T1CxZm85sZWohm+gsRrZFmGliIZjFfiKTcsyzL5il1KrHJCaImkHxmnnxpvXzHruS5wPOBZwmaLcqbg6/gl7I/B799HvgLwAvht8XAS4EXCJojynM9+grCd0LAU4CnAk8Dng48W9A8Ud4C9aWMMAe+8zLg+RvwV4D/HfirwP8B/DXg/wT+OvA3gL8J/F/A3wL+b+BvA/8P8HeAvwv8PeD/Bf4+8A+Afwj8I+AfA/8E+KfA/wf8M+CfA/8C+JfAvwL+NfBvgH8L/Dvg3wP/AfiPwBX9DNwBvQaAzwOeATwT+CBBW4ryVsg2Kjg/DX3Nhu9uCbxQ0NaivI0WRTknddsSLvSJWpxrHDOL83x/caY10nwDi/MC5ouzlHuBgcU5Ue/HoZxcJnFWWoKzzKEPVgHU50JR2U7QIkGLBS0RtFTQMkHbC+oQtFzQDoJ2FLRC0E6Cdha0UtAuglYJWi1oV0G7Cdpd0B6C1ghaK2hPQXsJ2lvQPoL2FbSfoP0FHSDoQEEHCTpY0CGCDhV0mKDDBR0h6EhBRwk6WtAxgo4VdJyg4wWdIOhEQScJOlnQKYJOFXSaoNMFnSHoTEFnCTpb0DmCzhV0nqDz0TzLAy7fGaQH70yn+/uHMp3Y4C4PW94rlCr6yEByOJq86h1JaaTjtkTkWKlO7KEvSlEPfUqsRVBetmTlytm7r9hzyZqOyWtXLVuzYvUq7NapWjchD/H09hSkinQop6I29bt0xAM6/ijweNeUBcQJVSJi/qKAmVjq0OJM2DvRLgAFX4ic238nGk2fCXknmjQgfifahYHug1Kffl1EkJiqd6JdQJjkXkg4uRMVkBb7ASkmIF0ECr7YD0h2BqSLtIB0cQIC0mLCgHQRYUC62MKAtMQPSDEB6RJQ8KV+QLIzIF2iBaRLExCQlhAGpEsIA9KlFgakDj8gxQSky0DBl/sByc6AdJkWkC5PQEDqIAxIlxEGpMstDEjL/YAUE5CuAAVf6QckOwPSFVpAujIBAWk5YUC6gjAgXWlhQNrBD0gxAekPoOCr/IBkZ0D6gxaQrkpAQNqBMCD9gTAgXWVhQDrfD0gxAelqUPA1fkCyMyBdrQWkaxIQkM4nDEhXEwakawxNbmr94e1d8cq8kFB/1xIH9G7O79AHdErMGO91qOLvQ42zT2mk6wL0/V5P6Pym5L4+QG4jo3crUu7tvSHA2y+lbW4I0O8/e8mSuxUpbX0joa1fsvBuxRsNLUQ3+QsRrZFuMrAQ3cx8IZJy32x4IeKuUwc5MiVOfBNEvDi3I5T5Fguz+VsMBdFb/SBKa6RbDQTR25gHUSn3bUmczd/OPJuXtrndQDb/chJm83cQ2vplC7P5OwwtRHf6CxGtke40sBDdxXwhknLfZVk2T61TBzkyJU58q3C8OHcklPluC7P5uw0F0Xv8IEprpHsMBNF7mQdRKfe9SZzN38c8m5e2uc9ANv9KEmbz9xPa+hULs/n7DS1ED/gLEa2RHjCwED3IfCGScj9oWTZPrVN1UC+Y1xDifChgZvJyThIeZp4kSJs8bCBJeDUJk4RHCG39qoVJwiOGkoRH/SSB1kiPGkgSHmOeJEi5H7MsSXjMkiThckKcf0zCJOFx5kmCtMnjBpKE15IwSXiC0NavWZgkPGEoSXjSTxJojfSkgSThT8yTBCn3nyxLEv5kSZJwJSHOp5IwSXiaeZIgbfK0gSTh9SRMEp4htPXrFiYJzxhKEv7sJwm0RvqzgSThWeZJgpT7WcuShGctSRKuIsT5lyRMEp5jniRImzxnIEl4MwmThOcJbf2mhUnC84aShBf8JIHWSC8YSBJeZJ4kSLlftCxJeNFQkkD9rvIgocxLCWV+iTAgJSqIvmQoiP7VD6K0RvqrgSD6MvMgKuV+2XAQ5ZzN/415Ni9t8zcD2fxbSZjNv0Jo67cszOZfMbQQ/d1fiGiN9HcDC9GrzBciKferlmXz1Dp1kCNjnPH2TfiqVncZocz/sDCb/4ehIPqaH0RpjfSagSD6T+ZBVMr9zyTO5l9nns1L27xuIJt/Owmz+TcIbf22hdn8G4YWojf9hYjWSG8aWIj+xXwhknL/y7JsnlKnEpucIGoCyWfm/eSse7+w5BcDvxR4lqC3RPnf4Cv4pexL4TvLgG8P/HLgVwK/CniBoLdF+T8efZ0O3zkD+JnAzwJ+NvBzgGcLekeU30V9KSO8Dd/ZEfgK4DsB3xn4SuC7AF8FfDXwXYHvBnx34HsAXwN8LfA9ge8FfG/g+wDfF/h+wPcHfgDwA4EfBPxg4IcAPxT4YcAPB34E8COBHwX8aODHAD8W+HHAjwd+AvATgZ8E/GTgpwA/FfhpwN8Bfi7w84APEvSeKP8X2UYF54XwnbeAvwe8UND7ovxBYN13f8vrLOLeSeqYWSAcDWdkww5XbyDsu9tYeAH9EBT8EYqP/ussaPpMyOsspAEfgIFk/SO0cOjKU+2Uk2gD+4pofbkfEi50HxFm4Yl6v048mJfHHss84BoJSNRBeUHATHD7GIB+8juD23gPmfXgNt759eDm1c//q+DG2SFUYPw40GUYWZdOMc6JPagDJaUcnxAGyk8DdIFB6fNTpE8T/vBRIG776ItPK6V9PiK0zzvEp9DinPzdbC71puYTpZ3f5SW3fnSeMvzEgNzvJeiUabzJ2seEPk4Zz/5rySlnwnntvkt4mvh9S/RHOE9cQp9x49FfT0k89eUtyvn7P8K106TMlJd5PiOWmXp9kjb5zMD69GkSXtL7nNDWn1p4SY9Q/phLel+gin9JL84+pZG+CND3+yXhRDIl95cBchsZvaTHXadbiw63NbB4fBVIjH3ixfm1JTi/sQTnt4Q4U511i4VaMKRPSXtJXXyrRWzqBPIpwr6+I0wqsD7wQdX/+vwiEt/hfmfAf6kxvm/JHPueEKdhfzJmq+8t8KcfDPkT5z/LPzL/s2wq3/nJktjxsz1rkbF5+bMFsUNOcmqM8uAcOwJB2tixPtvE/WgCOpxNts6hYJA/xlASzqEUS+ZQKh3OZlvnUKoFcygtCedQOuEcStSJ+1q6vmJO3GcEu8r+ifs4+6wFhVL3mxnkfZJZyp0ZJLdRJFHbdWsdM0GQGmeVJTjLHfpgJXk2lLOEr4UFZQvKEZQrKE9QvqACQYWCigQVCypBfpkHXG7T1YNdptN9y2+mExsM5WHLVl55cj0DyeFo8qptyWm04y6TY6U6sYcexKMe+pRYK6DcsWq3tR1rO2avXbpyxbLJa1ctW7Ni9aoJS1auxM6gBlFOEfIQUm9PQQpJh3IqalO/S0c8oEsRBR5vJM4kTkMSESmzDaWLDi3OJoN9x9yMUAqVMtTo32lF02dC7rSSBvzR6bqBoCzYfVDqDU3ZBOlcB+wsLCVMDcsIJ3eiAlKOH5BiAlI5VCr8gGRnQCrXAlJFAgJSDmFAKicMSBUWBqRcPyDFBKReUKn0A5KdAamXFpAqExCQcgkDUi/CgFRpYUAq9ANSTECqgkq1H5DsDEhVWkCqTkBAKiQMSFWEAanawoBU5AekmIDUGyo1fkCyMyD11gJSTQICUhFhQOpNGJBqLAxIxX5AiglItVCp8wOSnQGpVgtIdQkISMWEAamWMCDVGZrc1PqrdehkziLUXz1xQO/m/A59QKfEjPE2oIDob5aKs09ppIYgfb99CJ3flNx9guQ2Mrr7knIDWt8gb7+UtukbpN/u8Zklj9ugtHU/Qlt/ZuHjNgjlj1mI+vsLEa2R+htYiAYwX4ik3AMML0TcdeogR6bEiXfqxoszTCjzQAuz+YGGguggP4jSGmmQgSDayDyISrkbkzibH8w8m5e2GWwgm/8iCbP5IYS2/sLCbJ5Q/piFaKi/ENEaaaiBhWgY84VIyj3MsmyeWqcOcmRKnPh+tnhxlhDKHLEwm48YCqKuH0RpjeQaCKJNzIOolLspibP5ZubZvLRNs4Fs/qskzOZbCG39lYXZPKH8MQtRq78Q0Rqp1cBCNJz5QiTlHm5ZNk+tU3VQL5jVhDjbgmYmL+ckoZ15kiBt0m4gSfgmCZOEEYS2/sbCJIFQ/pgkYaSfJNAaaaSBJGEU8yRByj3KsiSBWqfqoF4wawhxjk7CJGEM8yRB2mSMgSThuyRMEjYhtPV3FiYJhPLHJAlj/SSB1khjDSQJUeZJQqdzWpYkUOtUHdQLZh0hznFJmCSMZ54kSJuMN5Ak/JCEScIEQlv/YGGSQCh/TJIw0U8SaI000UCSMIl5kiDlnmRZkkCtUwc5MsYZ99tkCGXOI5R5MmFASlQQnWwoiE7xgyitkaYYCKJTmQdRKfdUw0GUczY/jXk2L20zzUA2/1MSZvPTCW39k4XZPKH8MQvRDH8hojXSDAML0abMFyIp96aWZfPUOnWQI2Oc8fZdSyhzPqHMm1mYzW9mKIjO9IMorZFmGgiis5gHUSn3rCTO5mczz+albWYbyObl+6BM2JpzNr85pa1T7cvmCeWPWYjm+AsRrZHmGFiI5jJfiKTccy3L5il1KrHJCaImkHwczk/Oujd1SV4BvBJ4lqB5orwF+Ap+yWEefCcfeAHwauA1wOvU54K2FOWt8Kx16BedrYOJsWu8OLexBOe2xAFd+o8K1luDb2wDfFvg8snE80V5gWFfWWiJDbazBOcig76yEHxjO+CLkK8sFuUlhn1lqSU2WGYJzu0N+spS8I1lwLdHvtIhyssN+8oOlthgR0twrjDoKzuAb+wIfAXylZ1EeWfDvrLSEhvsYgnOVQZ9ZSX4xi7AVyFfWS3Kuxr2ld0sscHuluDcw6Cv7Aa+sTvwPZCvrBHltYZ9ZU9LbLCXJTj3Nugre4Jv7AV8b+Qr+4jyvoZ9ZT9LbLC/JTgPMOgr+4Fv7A/8AOQrB4ryQYZ95WBLbHCIJTgPNegrB4NvHAL8UOQrh4ny4YZ95QhLbHCkJTiPMugrR4BvHAn8KOQrR4vyMYZ95VhLbHCcJTiPN+grx4JvHAf8eOQrJ4jyiYZ95SRLbHCyJThPMegrJ4FvnAz8FOQrp4ryaYZ95XRLbHCGJTjPNOgrp4NvnAH8TOQrZ4ny2YZ95RxLbHCuJTjPM+gr54BvnAv8POQr54vyBYZ95UJLbHCRJTgvNugrF4JvXAT8YuQrl4jypYZ95TJLbHC5JTivMOgrl4FvXA78CuQrV4ryHwz7ylWW2OBqAzZQqr0KdH418AxB14jytYZ1f50lur/eoO6vA51fj3R/gyjfaFj3N1mi+5sN6v4m0PnNSPe3iPKthnV/myW6v92g7m8Dnd+OdH+HKN9pWPd3WaL7uw3q/i7Q+d1I9/eI8r2GdX+fJbq/36Du7wOd3490/4AoP2hY9w9ZovuHDer+IdD5w0j3j4jyo4Z1/5gluv+jQd0/Bjr/I9L946L8hGHdP2mJ7v9kUPdPgs7/hHT/lCg/bVj3z1ii+z8b1P0zoPM/I90/K8p/Maz75yzR/fMGdf8c6Px5pPsXRPlFw7p/yRLd/9Wg7l8Cnf8V6f5lUf6bYd2/Yonu/25Q96+Azv+OdP+qKP/DsO5fs0T3/zSo+9dA5/9Eun9dlN8wrPs3LdH9vwzq/k3Q+b+Q7t8S5X8b1v3bluj+PwZ1/zbo/D9I9++I8ruGdf+eJbr/ryU437cE5weW4PzQEpwfWYLzY0twfmIJzk8twfk/S3B+ZgnOzy3B+YUlOL+0BOdXluD82hKc31iC81tLcH5nCc7vLcH5gyU4f7QE50+W4PzZEpxyI6ANOAOW4AxagjNkCc4UQpzqnNlY6G9LOFdWAvw94P8F/j7wD4DPB74YeAfwnYCvBr4G+D7ADwR+GPCjgZ8A/FTgZwE/H/glwK8Efg3wG4DfAvwO4PcAfwD4I8AfB/4U8GeBvwD8ZeCvAn8d+FvA3wH+IfCPgH8M/BPgnwL/H/DPgH8O/AvgXwL/CvjXwL8B/i3w74B/D/wH4D8C/wn4z8BlLJM8ADwIPAQ8BXijoFRRTgt1PedP7YfOgr7mAU+F3xQKShfljJATcwSJ/Z3y4ayZdHPHTdQDVesc2vmujixkN/+BqnH2WQcKpe43HCJMbAzJHQ6R26jzacUhp/vBeXKZxFltCc4Khz5YSZ4N5WzhFDmCcgXlCcoXVCCoUFCRoGJBJYJKBZUhB8oDLm/i0YNdJvK1AGrDwVAeaagcJZLRQHCNpDrrLnYqORxN3lwn9kG+ROMuk2OlOrGHHsSjHvqUWCug3LFqt7Udaztmr126csWyyWtXLVuzYvWqCUtWrsTOoAZRThHyEFJvT0EKSYdyKmpTv0tHPKBLEQUebyQOE6chiYiUuYb+Hjm0OJsM9u1i5yoHpVcg5avZFnS6HCoN2UN9VTrjz053WwVQOQjfCfXwncB6+sGzXv1ezXpinRiJYEbTvwAoVxrwRxhI1itC3QelftFELkE617F83VFOmBpWEE7uRAWkPD8gxQSkXqD0Sj8g2RmQemkBqTIBASmPMCD1IgxIlRYGpHw/IMUEpCpQerUfkOwMSFVaQKpOQEDKJwxIVYQBqdrCgFTsB6SYgNQblF7jByQ7A1JvLSDVJCAgFRMGpN6EAanGwoBU4gekmIBUC0qv8wOSnQGpVgtIdQkISCWEAamWMCDVWRiQSv2AFBOQ6kHpDX5AsjMg1WsBqSEBAamUMCDVEwakBkOTm1p/dQ6dzNmE+utDHNC7Ob9DH9ApMWO8ff3NUrRG6mtgs1Q/5pulpNz9DGyWctAR1Pqm3KoQb1/9Q7z9Utqmf8jADvhUOxYiSlsPILQ11l/cu/ydxCxEAwwtRAP9hYjWSAMNLESDmC9EUu5Bhhci7jp1kCNT4sQ7dePFmUMoc6OF2XyjoSA62A+itEYabCCIDmEeRKXcQ5I4mx/KPJuXthlqIJtPScJsfhihrVMszOaHGVqIIv5CRGukiIGFyGW+EEm5XcuyedeSbB7fzxYvzjJCmZsszOabDAXRZj+I0hqp2UAQbWEeRKXcLUmczbcyz+albVoNZPNpSZjNDye0dZqF2fxwQwtRm78Q0RqpzcBC1M58IZJyt1uWzbcbyuapF8waQpwjQmYmL+ckYSTzJEHaZKSBJCEjCZOEUYS2zrAwSRhlKEkY7ScJtEYabSBJGMM8SZByj7EsSRhjSZJQR4hzkyRMEsYyTxKkTcYaSBKykjBJiBLaOsvCJCFqKEkY5ycJtEYaZyBJGM88SZByj7csSRhvSZLQQIhzQhImCROZJwnSJhMNJAnZSZgkTCK0dbaFScIkQ0nCZD9JoDXSZANJwhTmSYKUe4plScIUQ0mCHkTjvu+LUOYCQpmnWrh5aKqhIDrND6K0RppmIIhOZx5EpdzTk3jz0Azm2by0zQwD2XxuEmbzmxLaOtfCbH5TQwvRZv5CRGukzQwsRDOZL0RS7pmWZfMzLcnm6whlLiSUeZaF2fwsQ0F0th9EaY0020AQ3Zx5EJVyb57E2fwc5tm8tM0cA9l8fhJm83MJbZ1vYTY/19BCNM9fiGiNNM/AQrQF84VIyr2FZdk8pU4lNjlB1ASSj8ORbx6uAF4JvBp4lqAtRXkr8BX8ksMC+E4h8CLgNcDrgDcALxC0tShvE3KcnvQVr4zbhhJj13hxzrcE5wLigI7fhL0t+MZ84AuAyycTLxTl7Qz7yiJLbLDYEpxLDPrKIvCNxcCXIF9ZKsrLDPvK9pbYoMMSnMsN+sr24BsdwJcjX9lBlHc07CsrLLHBTpbg3Nmgr6wA39gJ+M7IV1aK8i6GfWWVJTZYbQnOXQ36yirwjdXAd0W+spso727YV/awxAZrLMG51qCv7AG+sQb4WuQre4ryXoZ9ZW9LbLCPJTj3Negre4Nv7AN8X+Qr+4ny/oZ95QBLbHCgJTgPMugrB4BvHAj8IOQrB4vyIYZ95VBLbHCYJTgPN+grh4JvHAb8cOQrR4jykYZ95ShLbHC0JTiPMegrR4FvHA38GOQrx4rycYZ95XhLbHCCJThPNOgrx4NvnAD8ROQrJ4nyyYZ95RRLbHCqJThPM+grp4BvnAr8NOQrp4vyGYZ95UxLbHCWJTjPNugrZ4JvnAX8bOQr54jyuYZ95TxLbHC+JTgvMOgr54FvnA/8AuQrF4ryRYZ95WJLbHCJJTgvNegrF4NvXAL8UuQrl4ny5YZ95QpLbHClJTj/YNBXrgDfuBL4H5CvXCXKVxv2lWssscG1BmygNvRdAzq/FniGoOtE+XrDur/BEt3faFD3N4DOb0S6v0mUbzas+1ss0f2tBnV/C+j8VqT720T5dsO6v8MS3d9pUPd3gM7vRLq/S5TvNqz7eyzR/b0GdX8P6PxepPv7RPl+w7p/wBLdP2hQ9w+Azh9Eun9IlB82rPtHLNH9owZ1/wjo/FGk+8dE+Y+Gdf+4Jbp/wqDuHwedP4F0/6Qo/8mw7p+yRPdPG9T9U6Dzp5HunxHlPxvW/bOW6P4vBnX/LOj8L0j3z4ny84Z1/4Ilun/RoO5fAJ2/iHT/kij/1bDuX7ZE938zqPuXQed/Q7p/RZT/blj3r1qi+38Y1P2roPN/IN2/Jsr/NKz71y3R/RsGdf866PwNpPs3RflfhnX/liW6/7dB3b8FOv830v3bovwfw7p/xxLdv2tQ9++Azt9Fun9PlP9rWPfvW6L7DyzB+aElOD+yBOfHluD8xBKcn1qC83+W4PzMEpyfW4LzC0twfmkJzq8swfm1JTi/sQTnt5bg/M4SnN9bgvMHS3D+aAnOnyzB+bMlOOXDnGzAGbAEZ9ASnCFLcKZYgjPVEpxphDjVObOx0N/WcK6sDPj7wD8A/iHwj4AvBL4U+A7AVwLfDfiewPcDfjDwI4AfC/wk4KcDPwf4hcAvA34V8OuA3wT8NuB3Ab8P+EPAHwP+JPBngD8H/CXgrwB/DfibwN8G/h7wj4F/AvxT4P8D/hnwz4F/AfxL4F8B/xr4N8C/Bf4d8O+B/wD8R+A/Af8ZuFwLJA8ADwIPAU8Bngo8DXijoHRRzkjpes6fOk2aDX1vCTwdflMoKFOUs1LWfVc7rWrE9zODZL7vesD9vX27egNh393GCqI+w/Agx+yUrrZM4EGn61x4GrKHspP8yc9Od1sFUDkI3wn18J3AevrJRG3q97kIC6FOIgYe+hox+lDXAChXGvABGEjWs1Fw15Wn2ikn0Qb2FdH6csMpdLiy6RY297cGpEh8hxsP5uWxxzIPuEYCEnVQDofMBLccCGq5vzO4jfeQWQ9u451fD25e/fy/Cm6cHUIFxpyULsPIunSKcU7sQR0oKeXIJQyUeSl0gUHpMw/p04Q/ZKfEbR998WmltE82oX0KiV97EOfk72ZzqTc1nyjtXMRLbv3ofM1DrgG5ixP0mot4k7UcQh+njGcllrwmhHBeu0WEr/YotUR/hPPEJfQZNx799ZTEB+Obv93sTDl/8wn/bJmUmfLVPAXEMlOvT9ImBQbWp6okfA1TIaGtqyx8DROh/DGvYSpCf8b91zDF2ac0UlEKfb/FhAuFKbmLU8htZPQ1TNx1mi5mRGaIfvEoseSyaKklOMsswVlOiFOsn44kNeWlT0l7SV2UpzgxB3UCGcfVjm59VRAmFSmgE/2g6n99fhGJ73ArDPgvNcZMS+ZYL0Kchv3JmK16WeBPlYb8ifOf5Srmf5ZN5TvVlsSO3vasRcbmZW8LYkdNEsaOWkMnF6nnUB0dziZb51CdBXOoPgnnUIMlc6gPHc5mW+dQHwvmUN8knEP9LJlD/S3JOQdYgnOgJTgHEeOkjhlniz7OMyB3b+YbhS4TfVxhQO4anhuFuuFsJIybhLZ2TemP2s6DLYk/QyzBOdQSnMMswRmxBKdrCc4mS3A2W4KzxRKcrZbgHG4JzjZLcLZbgnOEJThHMv8ftEB0+FOAXu565v+DfhAd/mhA7gZL/geNIvwfRGhrt4G538iTgoEgvd+MZh4nQkLmFANyj2Eud5qQOd2A3Jswl1ueq642sGG/H/P5LffDVBmQu78l68JYwnWB0NZuf+Z+I/dC1BrwmyjzOCGvXzcYkHscc7nlNcd+BuQeb8n/mgmW4JxoCc5JluCcbAnOKZbgnGoJzmmW4JyeoL0gkfiOzoe/UMk8wxKZg4Qyb2qJzCFCmTezROYUQplnWiJzKqHMsyyROY1Q5tmWyHwMocybWyJzf8L7g+dYIvMAQpnnWiLzQEKZ51ki8yBCmbewROZGQpm3tETmwYQyb2WJzEMIZd7aEpmHEsq8jSUyDyOUeVtLZI4QyjzfEpldQpkXWCJzE6HMCy2RuZlQ5u0skbmFUOZFlsjcSijzYktkHk4o8xJLZG4jlHmpJTK3E8q8zBKZRxDKvL0lMo8klLnDEplHEcq83BKZRxPKvIMlMo8hlHlHS2TehFDmFZbIPJZQ5p0skTlKKPPOlsg8jlDmlZbIPJ5Q5l0skXkCocyrLJF5IqHMqy2ReRKhzLtaIvNkQpl3s0TmKYQy726JzFMJZd7DEpmnEcq8xhKZpxPKvNYSmdMdOpn3tETmDEKZ97JE5kxCmfe2ROYsQpn3sUTmMKHM+1oiczahzPtZInMOocz7WyJzLqHMB1gicx6hzAdaInM+ocwHWSJzAaHMB1sicyGhzIdYInMRocyHWiJzMaHMh1kicwmhzIcbkHkpcPVibnlvlLxXSN47I+8lkf8L5f8k+b9B5tEyr5R5lsw75Dos1yUZp2XckvNY+rW0s5S7VFCZoHJBFYJ6CaoUVCWoWlBvQTWCagXVCaoX1CCoj6C+gvoJ6i9ogKCBggYJahQ0WNAQQUMFDZO6ECQfmNwkdSyoRVCroOGC2gS1CxohaKSgUYJGCxojaBNBY8E+4wSNFzRB0ERBkwRNFjRF0FRB0wRNFzRD0KaCNhM0U9AsQbMFbS5ojqC5guYJ2kLQloK2ErS1oG0EbStovqAFghYK2k7QIkGLBS0BW4wEe8j7B+X9dPL+Mnm/lbz/SN6PI+9PkfdryPsX5H5+ub9d7veW+5/lfmC5P1buF5X7J+V+Qrm/Tu43k/uv5H4kuT9H7leR+zfkfgZ5fV9e75bXf+X1UHl9UF4vk9eP5PUUeX1Bnm+X55/l+Vh5flKer5Pnr+T5HHl+Q/7fl/9/5f9B+f9I/l+Q+bPMJ2V+JfMNuf7K9UjGZxmv5PyV/vx/Mw708D6/BQA=", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } - ], - "debug": { - "debugSymbols": [ - "eJyrVsrJT04syczPK1ayqq6tBQAz9wY7", - "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" - ], - "fileMap": { - "0": { - "source": "mod storage;\nmod public_key_note;\n\n// Account contract that uses Schnorr signatures for authentication.\n// The signing key is stored in an immutable private note and should be different from the encryption/nullifying key.\ncontract SchnorrAccount {\n use dep::std;\n use dep::aztec::entrypoint;\n use dep::aztec::entrypoint::EntrypointPayload;\n use dep::aztec::abi;\n use dep::aztec::abi::PrivateContextInputs;\n use dep::aztec::abi::CallContext;\n use dep::aztec::private_call_stack_item::PrivateCallStackItem;\n use dep::aztec::public_call_stack_item::PublicCallStackItem;\n use dep::aztec::context::PrivateContext;\n use dep::aztec::log::emit_encrypted_log;\n use dep::aztec::oracle::get_public_key::get_public_key;\n use dep::aztec::types::vec::BoundedVec;\n use dep::aztec::types::point::Point;\n use dep::aztec::note::utils as note_utils;\n use dep::aztec::note::note_header::NoteHeader;\n use dep::aztec::constants_gen::MAX_NOTE_FIELDS_LENGTH;\n use dep::aztec::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n use dep::aztec::constants_gen::GENERATOR_INDEX__SIGNATURE_PAYLOAD;\n\n use crate::storage::Storage;\n use crate::public_key_note::PublicKeyNote;\n use crate::public_key_note::PublicKeyNoteMethods;\n use crate::public_key_note::PUBLIC_KEY_NOTE_LEN;\n\n // docs:start:entrypoint\n\n fn entrypoint(\n inputs: pub PrivateContextInputs,\n payload: pub EntrypointPayload, // contains a set of arguments, selectors, targets and a nonce\n signature: pub [u8;64], // schnorr signature of the payload hash\n ) -> distinct pub abi::PrivateCircuitPublicInputs {\n // Initialize context\n // ENTRYPOINT_PAYLOAD_SIZE(13) + 64\n let mut args: BoundedVec = BoundedVec::new(0);\n args.push_array(payload.serialize());\n for byte in signature { args.push(byte as Field); }\n let mut context = PrivateContext::new(inputs, abi::hash_args(args.storage));\n\n // Load public key from storage\n let storage = Storage::init();\n let public_key = storage.signing_public_key.get_note(&mut context);\n\n // Verify payload signature\n let payload_fields: [Field; entrypoint::ENTRYPOINT_PAYLOAD_SIZE] = payload.serialize();\n let message_field: Field = std::hash::pedersen_with_separator(payload_fields, GENERATOR_INDEX__SIGNATURE_PAYLOAD)[0];\n let message_bytes = message_field.to_be_bytes(32);\n\n // Verify signature of the payload bytes\n let verification = std::schnorr::verify_signature(public_key.x, public_key.y, signature, message_bytes);\n assert(verification == true);\n\n // docs:end:entrypoint\n\n // Execute calls\n payload.execute_calls(&mut context);\n\n context.finish()\n }\n\n // Constructs the contract\n fn constructor(\n inputs: pub PrivateContextInputs,\n signing_pub_key_x: pub Field,\n signing_pub_key_y: pub Field,\n ) -> distinct pub abi::PrivateCircuitPublicInputs {\n let storage = Storage::init();\n \n let mut context = PrivateContext::new(inputs, abi::hash_args([signing_pub_key_x, signing_pub_key_y]));\n \n let this = context.this_address();\n let mut pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this);\n storage.signing_public_key.initialise(&mut context, &mut pub_key_note);\n \n emit_encrypted_log(\n &mut context,\n this,\n storage.signing_public_key.storage_slot,\n get_public_key(this),\n pub_key_note.serialise(),\n );\n\n context.finish()\n }\n\n // Computes notes hash and nullifier.\n // Note 1: Needs to be defined by every contract producing logs.\n // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes.\n unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; PUBLIC_KEY_NOTE_LEN]) -> [Field; 4] {\n assert(storage_slot == 1);\n let note_header = NoteHeader { contract_address, nonce, storage_slot };\n note_utils::compute_note_hash_and_nullifier(PublicKeyNoteMethods, note_header, preimage)\n }\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main" - }, - "3": { - "source": "mod poseidon;\n\n#[foreign(sha256)]\nfn sha256(_input : [u8; N]) -> [u8; 32] {}\n\n#[foreign(blake2s)]\nfn blake2s(_input : [u8; N]) -> [u8; 32] {}\n\nfn pedersen(input : [Field; N]) -> [Field; 2] {\n pedersen_with_separator(input, 0)\n}\n\n#[foreign(pedersen)]\nfn pedersen_with_separator(_input : [Field; N], _separator : u32) -> [Field; 2] {}\n\n#[foreign(hash_to_field_128_security)]\nfn hash_to_field(_input : [Field; N]) -> Field {}\n\n#[foreign(keccak256)]\nfn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] {}\n\n// mimc-p/p implementation\n// constants are (publicly generated) random numbers, for instance using keccak as a ROM.\n// You must use constants generated for the native field\n// Rounds number should be ~ log(p)/log(exp)\n// For 254 bit primes, exponent 7 and 91 rounds seems to be recommended\nfn mimc(x: Field, k: Field, constants: [Field; N], exp : Field) -> Field {\n //round 0\n let mut t = x + k;\n let mut h = t.pow_32(exp);\n //next rounds\n for i in 1 .. constants.len() {\n t = h + k + constants[i];\n h = t.pow_32(exp);\n };\n h + k\n}\n\nglobal MIMC_BN254_ROUNDS = 91;\n\n//mimc implementation with hardcoded parameters for BN254 curve.\nfn mimc_bn254(array: [Field; N]) -> Field {\n //mimc parameters\n let exponent = 7;\n //generated from seed \"mimc\" using keccak256 \n let constants: [Field; MIMC_BN254_ROUNDS] = [\n 0, \n 20888961410941983456478427210666206549300505294776164667214940546594746570981,\n 15265126113435022738560151911929040668591755459209400716467504685752745317193,\n 8334177627492981984476504167502758309043212251641796197711684499645635709656,\n 1374324219480165500871639364801692115397519265181803854177629327624133579404,\n 11442588683664344394633565859260176446561886575962616332903193988751292992472,\n 2558901189096558760448896669327086721003508630712968559048179091037845349145,\n 11189978595292752354820141775598510151189959177917284797737745690127318076389,\n 3262966573163560839685415914157855077211340576201936620532175028036746741754,\n 17029914891543225301403832095880481731551830725367286980611178737703889171730,\n 4614037031668406927330683909387957156531244689520944789503628527855167665518,\n 19647356996769918391113967168615123299113119185942498194367262335168397100658,\n 5040699236106090655289931820723926657076483236860546282406111821875672148900,\n 2632385916954580941368956176626336146806721642583847728103570779270161510514,\n 17691411851977575435597871505860208507285462834710151833948561098560743654671,\n 11482807709115676646560379017491661435505951727793345550942389701970904563183,\n 8360838254132998143349158726141014535383109403565779450210746881879715734773,\n 12663821244032248511491386323242575231591777785787269938928497649288048289525,\n 3067001377342968891237590775929219083706800062321980129409398033259904188058,\n 8536471869378957766675292398190944925664113548202769136103887479787957959589,\n 19825444354178182240559170937204690272111734703605805530888940813160705385792,\n 16703465144013840124940690347975638755097486902749048533167980887413919317592,\n 13061236261277650370863439564453267964462486225679643020432589226741411380501,\n 10864774797625152707517901967943775867717907803542223029967000416969007792571,\n 10035653564014594269791753415727486340557376923045841607746250017541686319774,\n 3446968588058668564420958894889124905706353937375068998436129414772610003289,\n 4653317306466493184743870159523234588955994456998076243468148492375236846006,\n 8486711143589723036499933521576871883500223198263343024003617825616410932026,\n 250710584458582618659378487568129931785810765264752039738223488321597070280,\n 2104159799604932521291371026105311735948154964200596636974609406977292675173,\n 16313562605837709339799839901240652934758303521543693857533755376563489378839,\n 6032365105133504724925793806318578936233045029919447519826248813478479197288,\n 14025118133847866722315446277964222215118620050302054655768867040006542798474,\n 7400123822125662712777833064081316757896757785777291653271747396958201309118,\n 1744432620323851751204287974553233986555641872755053103823939564833813704825,\n 8316378125659383262515151597439205374263247719876250938893842106722210729522,\n 6739722627047123650704294650168547689199576889424317598327664349670094847386,\n 21211457866117465531949733809706514799713333930924902519246949506964470524162,\n 13718112532745211817410303291774369209520657938741992779396229864894885156527,\n 5264534817993325015357427094323255342713527811596856940387954546330728068658,\n 18884137497114307927425084003812022333609937761793387700010402412840002189451,\n 5148596049900083984813839872929010525572543381981952060869301611018636120248,\n 19799686398774806587970184652860783461860993790013219899147141137827718662674,\n 19240878651604412704364448729659032944342952609050243268894572835672205984837,\n 10546185249390392695582524554167530669949955276893453512788278945742408153192,\n 5507959600969845538113649209272736011390582494851145043668969080335346810411,\n 18177751737739153338153217698774510185696788019377850245260475034576050820091,\n 19603444733183990109492724100282114612026332366576932662794133334264283907557,\n 10548274686824425401349248282213580046351514091431715597441736281987273193140,\n 1823201861560942974198127384034483127920205835821334101215923769688644479957,\n 11867589662193422187545516240823411225342068709600734253659804646934346124945,\n 18718569356736340558616379408444812528964066420519677106145092918482774343613,\n 10530777752259630125564678480897857853807637120039176813174150229243735996839,\n 20486583726592018813337145844457018474256372770211860618687961310422228379031,\n 12690713110714036569415168795200156516217175005650145422920562694422306200486,\n 17386427286863519095301372413760745749282643730629659997153085139065756667205,\n 2216432659854733047132347621569505613620980842043977268828076165669557467682,\n 6309765381643925252238633914530877025934201680691496500372265330505506717193,\n 20806323192073945401862788605803131761175139076694468214027227878952047793390,\n 4037040458505567977365391535756875199663510397600316887746139396052445718861,\n 19948974083684238245321361840704327952464170097132407924861169241740046562673,\n 845322671528508199439318170916419179535949348988022948153107378280175750024,\n 16222384601744433420585982239113457177459602187868460608565289920306145389382,\n 10232118865851112229330353999139005145127746617219324244541194256766741433339,\n 6699067738555349409504843460654299019000594109597429103342076743347235369120,\n 6220784880752427143725783746407285094967584864656399181815603544365010379208,\n 6129250029437675212264306655559561251995722990149771051304736001195288083309,\n 10773245783118750721454994239248013870822765715268323522295722350908043393604,\n 4490242021765793917495398271905043433053432245571325177153467194570741607167,\n 19596995117319480189066041930051006586888908165330319666010398892494684778526,\n 837850695495734270707668553360118467905109360511302468085569220634750561083,\n 11803922811376367215191737026157445294481406304781326649717082177394185903907,\n 10201298324909697255105265958780781450978049256931478989759448189112393506592,\n 13564695482314888817576351063608519127702411536552857463682060761575100923924,\n 9262808208636973454201420823766139682381973240743541030659775288508921362724,\n 173271062536305557219323722062711383294158572562695717740068656098441040230,\n 18120430890549410286417591505529104700901943324772175772035648111937818237369,\n 20484495168135072493552514219686101965206843697794133766912991150184337935627,\n 19155651295705203459475805213866664350848604323501251939850063308319753686505,\n 11971299749478202793661982361798418342615500543489781306376058267926437157297,\n 18285310723116790056148596536349375622245669010373674803854111592441823052978,\n 7069216248902547653615508023941692395371990416048967468982099270925308100727,\n 6465151453746412132599596984628739550147379072443683076388208843341824127379,\n 16143532858389170960690347742477978826830511669766530042104134302796355145785,\n 19362583304414853660976404410208489566967618125972377176980367224623492419647,\n 1702213613534733786921602839210290505213503664731919006932367875629005980493,\n 10781825404476535814285389902565833897646945212027592373510689209734812292327,\n 4212716923652881254737947578600828255798948993302968210248673545442808456151,\n 7594017890037021425366623750593200398174488805473151513558919864633711506220,\n 18979889247746272055963929241596362599320706910852082477600815822482192194401,\n 13602139229813231349386885113156901793661719180900395818909719758150455500533,\n ];\n\n let mut r = 0;\n for elem in array {\n let h = mimc(elem, r, constants, exponent);\n r = r + elem + h;\n }\n r\n}\n", - "path": "std/hash" - }, - "18": { - "source": "\nimpl Field {\n #[builtin(to_le_bits)]\n fn to_le_bits(_x : Field, _bit_size: u32) -> [u1] {}\n #[builtin(to_be_bits)]\n fn to_be_bits(_x : Field, _bit_size: u32) -> [u1] {}\n\n fn to_le_bytes(x : Field, byte_size: u32) -> [u8] {\n x.to_le_radix(256, byte_size)\n }\n fn to_be_bytes(x : Field, byte_size: u32) -> [u8] {\n x.to_be_radix(256, byte_size)\n }\n\n #[builtin(to_le_radix)]\n //decompose _x into a _result_len vector over the _radix basis\n //_radix must be less than 256\n fn to_le_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {}\n #[builtin(to_be_radix)]\n fn to_be_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {}\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b = exponent.to_le_bits(32);\n\n for i in 1..33 {\n r *= r;\n r = (b[32-i] as Field) * (r * self) + (1 - b[32-i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n fn sgn0(self) -> u1 {\n self as u1\n }\n}\n\n#[builtin(modulus_num_bits)]\nfn modulus_num_bits() -> Field {}\n\n#[builtin(modulus_be_bits)]\nfn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\nfn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\nfn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\nfn modulus_le_bytes() -> [u8] {}\n", - "path": "std/field" - }, - "31": { - "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n\n contract_deployment_data: ContractDeploymentData,\n\n private_global_variables: PrivateGlobalVariables,\n}\n\n// PublicContextInputs are expected to be provided to each public function\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n\n // TODO: include globals in here and check them elsewhere\n // https://github.com/AztecProtocol/aztec-packages/issues/1567\n}\n\nimpl PublicCircuitPublicInputs {\n \n fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n // We do not include block_data since it's not in the cpp hash\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize()); // see https://github.com/AztecProtocol/aztec-packages/issues/1473\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\nfn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/abi" - }, - "32": { - "source": "use crate::constants_gen::{\n EMPTY_NULLIFIED_COMMITMENT,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n};\n\nuse crate::abi;\n\nuse crate::abi::{\n hash_args,\n CallContext,\n ContractDeploymentData,\n HistoricBlockData,\n FunctionData,\n PrivateCircuitPublicInputs,\n PublicCircuitPublicInputs,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// l1 to l2 messaging\nuse crate::messaging::process_l1_to_l2_message;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem;\n\nuse crate::types::{\n vec::BoundedVec,\n point::Point,\n};\n\nuse crate::utils::arr_copy_slice;\n\nuse crate::oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n};\n\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n inputs: abi::PrivateContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n nullified_commitments: BoundedVec,\n\n private_call_stack : BoundedVec,\n public_call_stack : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n\n block_data: HistoricBlockData,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n fn new(inputs: abi::PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n nullified_commitments: BoundedVec::new(0),\n\n block_data: inputs.block_data,\n\n private_call_stack: BoundedVec::new(0),\n public_call_stack: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n fn finish(self) -> abi::PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = abi::PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n nullified_commitments: self.nullified_commitments.storage,\n private_call_stack: self.private_call_stack.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.block_data,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n fn push_read_request(&mut self, read_request: Field) {\n self.read_requests.push(read_request);\n }\n\n fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n self.nullified_commitments.push(nullified_commitment);\n }\n\n fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n fn consume_l1_to_l2_message(&mut self, inputs: abi::PrivateContextInputs, msg_key: Field, content: Field, secret: Field) {\n let nullifier = process_l1_to_l2_message(inputs.block_data.l1_to_l2_messages_tree_root, inputs.call_context.storage_contract_address, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn call_private_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n fn call_private_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n fn call_private_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PrivateCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n \n is_delegate_call : fields[8] as bool,\n is_static_call : fields[9] as bool,\n is_contract_deployment: fields[10] as bool,\n },\n // TODO handle the offsets as a variable incremented during extraction?\n args_hash: fields[11],\n return_values: arr_copy_slice(fields, [0; RETURN_VALUES_LENGTH], 12),\n read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 16),\n new_commitments: arr_copy_slice(fields, [0; MAX_NEW_COMMITMENTS_PER_CALL], 20),\n new_nullifiers: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 24),\n nullified_commitments: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 28),\n private_call_stack: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 32),\n public_call_stack: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 36),\n new_l2_to_l1_msgs: arr_copy_slice(fields, [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 40),\n encrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 42),\n unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 44),\n encrypted_log_preimages_length: fields[46],\n unencrypted_log_preimages_length: fields[47],\n block_data: HistoricBlockData {\n // Must match order in `private_circuit_public_inputs.hpp`\n private_data_tree_root : fields[48],\n nullifier_tree_root : fields[49],\n contract_tree_root : fields[50],\n l1_to_l2_messages_tree_root : fields[51],\n blocks_tree_root : fields[52],\n public_data_tree_root: fields[53],\n global_variables_hash: fields[54],\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: Point::new(fields[55], fields[56]),\n constructor_vk_hash : fields[57],\n function_tree_root : fields[58],\n contract_address_salt : fields[59],\n portal_contract_address : fields[60],\n },\n chain_id: fields[61],\n version: fields[62],\n },\n is_execution_request: fields[63] as bool,\n };\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.private_call_stack.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n fn call_public_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n fn call_public_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n fn call_public_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PublicCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n \n is_delegate_call : fields[8] as bool,\n is_static_call : fields[9] as bool,\n is_contract_deployment: fields[10] as bool,\n },\n args_hash: fields[11],\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [0; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [0; MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_data: HistoricBlockData::empty(),\n prover_address: 0,\n },\n is_execution_request: true,\n };\n\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.public_call_stack.push(item.hash());\n }\n}\n\nuse crate::abi::{\n ContractStorageRead,\n ContractStorageUpdateRequest\n};\n\nstruct PublicContext {\n inputs: abi::PublicContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_read: BoundedVec,\n public_call_stack: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicContext {\n fn new(inputs: abi::PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = ContractStorageRead::empty();\n let empty_storage_update = ContractStorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_read: BoundedVec::new(empty_storage_read),\n public_call_stack: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_data: inputs.block_data,\n prover_address: 0,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n fn finish(self) -> abi::PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = abi::PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_read: self.contract_storage_read.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.inputs.block_data,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n }\n\n fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, this, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn call_public_function(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = abi::hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n fn call_public_function_no_args(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/context" - }, - "33": { - "source": "use crate::context::PrivateContext;\nuse crate::oracle;\nuse crate::types::point::Point;\n\nfn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n log: [Field; N],\n) {\n let _ = oracle::logs::emit_encrypted_log(contract_address, storage_slot, encryption_pub_key, log);\n context.accumulate_encrypted_logs(log);\n}\n\nfn emit_unencrypted_log(\n context: &mut PrivateContext,\n log: T,\n) {\n let _ = oracle::logs::emit_unencrypted_log(log);\n context.accumulate_unencrypted_logs(log);\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/log" - }, - "39": { - "source": "use dep::std::option::Option;\nuse crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\nuse crate::constants_gen::EMPTY_NULLIFIED_COMMITMENT;\n\nfn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0 };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialise = note_interface.serialise;\n let preimage = serialise(*note);\n assert(notify_created_note(storage_slot, preimage, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\nfn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0 };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\nfn destroy_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: Note,\n note_interface: NoteInterface,\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = EMPTY_NULLIFIED_COMMITMENT;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note);\n\n let serialise = note_interface.serialise;\n let preimage = serialise(note);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // 0 nonce implies \"transient\" nullifier (must nullify a commitment in this TX).\n // `nullified_commitment` is used to inform the kernel which pending commitment\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullier to its output.\n if (header.nonce == 0) {\n // TODO(suyash): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(storage_slot, nullifier, preimage, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/note/lifecycle" - }, - "40": { - "source": "use dep::std::option::Option;\nuse crate::constants_gen::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort},\n note_interface::NoteInterface,\n note_header::NoteHeader,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n utils::compute_unique_siloed_note_hash,\n utils::compute_inner_note_hash,\n utils::compute_siloed_note_hash,\n};\nuse crate::messaging::get_commitment_getter_data::make_commitment_getter_data;\nuse crate::oracle;\nuse crate::types::vec::BoundedVec;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: Note,\n) {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n let contract_address = context.this_address();\n assert(header.contract_address == contract_address);\n assert(header.storage_slot == storage_slot);\n}\n\nfn ensure_note_exists(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: &mut Note,\n) {\n let saved_note = get_note_internal(storage_slot, note_interface);\n\n // Only copy over the header to the original note to make sure the preimage is the same.\n let get_header = note_interface.get_header;\n let set_header = note_interface.set_header;\n let note_header = get_header(saved_note);\n set_header(note, note_header);\n\n check_note_header(*context, storage_slot, note_interface, *note);\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, *note);\n context.push_read_request(note_hash_for_read_request);\n}\n\n// Ensure a note's hash exists in the tree without retrieving the entire\n// notes via the oracle.\n// Modifies the note by populating it with header info.\nfn ensure_note_hash_exists(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: &mut Note,\n) {\n // Initialize header of note. Must be done before computing note hashes as it initializes the:\n // - storage slot (used in inner note hash)\n // - the contract address (used in siloed note hash)\n // - and the nonce (used in the unique siloed note hash)\n let set_header = note_interface.set_header;\n let note_header = NoteHeader {\n contract_address: (*context).this_address(),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be\n // real nonce (once public kernel applies nonces).\n nonce: 0,\n storage_slot\n };\n set_header(note, note_header);\n\n // Get a note from oracle and early out if it doesn't exist.\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let raw_oracle_ret = oracle::get_commitment::get_commitment(inner_note_hash);\n let deserialized_oracle_ret = make_commitment_getter_data(raw_oracle_ret, 0);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be\n // unique_siloed_note_hash once public kernel applies nonces\n let saved_siloed_note_hash = deserialized_oracle_ret.message;\n\n assert(saved_siloed_note_hash != 0); // TODO(dbanks12): necessary?\n\n check_note_header(*context, storage_slot, note_interface, *note);\n\n // Ensure that the note hash retrieved from oracle matches the one computed from note.\n let computed_siloed_note_hash = compute_siloed_note_hash(note_interface, *note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be\n // compute_note_hash_for_read_or_nullify once public kernel applies nonces\n assert(computed_siloed_note_hash == saved_siloed_note_hash);\n\n context.push_read_request(computed_siloed_note_hash);\n}\n\nfn get_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let note = get_note_internal(storage_slot, note_interface);\n\n check_note_header(*context, storage_slot, note_interface, note);\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\nfn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let opt_notes = get_notes_internal(storage_slot, note_interface, options);\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n let mut note_hash_for_read_request = 0;\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n check_note_header(*context, storage_slot, note_interface, note);\n note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n };\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n };\n\n // TODO(#1660)\n // Move it back to get_notes_internal and only make read request for selected notes.\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained fn get_note_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n 0,\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n placeholder_note,\n placeholder_fields,\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n )\n}\n\nunconstrained fn view_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteViewerOptions,\n) -> [Option; MAX_NOTES_PER_PAGE] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>,\n) -> (u8, [u8; N], [Field; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n num_selects += 1;\n };\n };\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n };\n\n (num_selects, select_by, select_values, sort_by, sort_order)\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/note/note_getter" - }, - "42": { - "source": "use dep::std::hash::{pedersen, pedersen_with_separator};\nuse crate::constants_gen::{GENERATOR_INDEX__UNIQUE_COMMITMENT, GENERATOR_INDEX__SILOED_COMMITMENT};\n\nfn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen([storage_slot, note_hash])[0]\n}\n\nfn compute_siloed_hash(contract_address: Field, inner_note_hash: Field) -> Field {\n let inputs = [contract_address, inner_note_hash];\n pedersen_with_separator(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)[0]\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_with_separator(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)[0]\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/note/note_hash" - }, - "46": { - "source": "use crate::note::{\n note_hash::{compute_inner_hash, compute_siloed_hash, compute_unique_hash},\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\nfn compute_inner_note_hash(\n note_interface: NoteInterface,\n note: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n\n compute_inner_hash(header.storage_slot, note_hash)\n}\n\nfn compute_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let inner_note_hash = compute_inner_note_hash(note_interface, note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let siloed_note_hash = compute_siloed_note_hash(note_interface, note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\nfn compute_note_hash_for_read_or_nullify(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n if (header.nonce == 0) {\n // when nonce is zero, that means we are reading a pending note (doesn't have a nonce yet),\n // so we just read the inner_note_hash (kernel will silo by contract address)\n compute_inner_note_hash(note_interface, note_with_header)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note_interface, note_with_header)\n }\n\n}\n\nfn compute_note_hash_and_nullifier(\n note_interface: NoteInterface,\n note_header: NoteHeader,\n preimage: [Field; S],\n) -> [Field; 4] {\n let deserialise = note_interface.deserialise;\n let set_header = note_interface.set_header;\n let mut note = deserialise(arr_copy_slice(preimage, [0; N], 0));\n set_header(&mut note, note_header);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n let inner_note_hash = compute_inner_hash(note_header.storage_slot, note_hash);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let compute_nullifier = note_interface.compute_nullifier;\n let inner_nullifier = compute_nullifier(note);\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/note/utils" - }, - "48": { - "source": "use dep::std::hash::pedersen_with_separator;\nuse crate::context::PrivateContext;\nuse crate::note::{\n lifecycle::create_note,\n note_getter::{get_note, view_notes},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n};\nuse crate::oracle;\nuse crate::constants_gen::{\n GENERATOR_INDEX__INITIALISATION_NULLIFIER,\n EMPTY_NULLIFIED_COMMITMENT,\n};\n\nstruct ImmutableSingleton {\n storage_slot: Field,\n note_interface: NoteInterface,\n}\n\nimpl ImmutableSingleton {\n fn new(storage_slot: Field, note_interface: NoteInterface) -> Self {\n ImmutableSingleton { storage_slot, note_interface }\n }\n\n unconstrained fn is_initialised(self) -> bool {\n let nullifier = self.compute_initialisation_nullifier();\n oracle::notes::is_nullifier_emitted(nullifier)\n }\n\n fn initialise(self, context: &mut PrivateContext, note: &mut Note) {\n // Nullify the storage slot.\n let nullifier = self.compute_initialisation_nullifier();\n context.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT);\n\n create_note(context, self.storage_slot, note, self.note_interface);\n }\n\n fn compute_initialisation_nullifier(self) -> Field {\n pedersen_with_separator([self.storage_slot], GENERATOR_INDEX__INITIALISATION_NULLIFIER)[0]\n }\n \n fn get_note(self, context: &mut PrivateContext) -> Note {\n let storage_slot = self.storage_slot;\n get_note(context, storage_slot, self.note_interface)\n }\n\n unconstrained fn view_note(self) -> Note {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, self.note_interface, options)[0].unwrap()\n }\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/state_vars/immutable_singleton" - }, - "55": { - "source": "\nstruct BoundedVec {\n storage: [T; MaxLen],\n len: Field,\n}\n\nimpl BoundedVec {\n fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0 }\n }\n\n fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64);\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n fn push_array(&mut self, array: [T; Len]) {\n let newLen = self.len + array.len();\n assert(newLen as u64 <= MaxLen as u64);\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = newLen;\n }\n\n fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n\n let elem = self.storage[self.len - 1];\n self.len -= 1;\n elem\n }\n}\n\n// #[test]\n// fn test_vec() {\n// let vec: BoundedVec = BoundedVec::new(0);\n// assert(vec.len == 0);\n// let vec1 = vec.push(1);\n// assert(vec1.len == 1);\n// let vec2 = vec1.push(1);\n// assert(vec2.len == 2);\n// let vec3 = vec2.push(1);\n// assert(vec3.len == 3);\n// let x = vec3.pop();\n// assert(x == 1);\n// }", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/types/vec" - }, - "70": { - "source": "use crate::types::point::Point;\nuse dep::std::hash;\nuse crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n\n#[oracle(getPublicKey)]\nfn get_public_key_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_internal(address: Field) -> [Field; 3] {\n get_public_key_oracle(address)\n}\n\nfn get_public_key(address: Field) -> Point {\n let result = get_public_key_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = hash::pedersen_with_separator([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0];\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/oracle/get_public_key" - }, - "78": { - "source": "use crate::abi;\nuse crate::types::vec::BoundedVec;\nuse crate::context::PrivateContext;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem; \n\nglobal ACCOUNT_MAX_PRIVATE_CALLS: Field = 2;\nglobal ACCOUNT_MAX_PUBLIC_CALLS: Field = 2;\nglobal ACCOUNT_MAX_CALLS: Field = 4;\n// 1 (ARGS_HASH) + 1 (FUNCTION_SELECTOR) + 1 (TARGET_ADDRESS)\nglobal FUNCTION_CALL_SIZE: Field = 3;\n\nstruct FunctionCall {\n args_hash: Field,\n function_selector: Field,\n target_address: Field,\n}\n\nimpl FunctionCall {\n fn serialize(self) -> [Field; FUNCTION_CALL_SIZE] {\n [self.args_hash, self.function_selector, self.target_address]\n }\n}\n\n// FUNCTION_CALL_SIZE * (ACCOUNT_MAX_PUBLIC_CALLS + ACCOUNT_MAX_PRIVATE_CALLS) + 1\nglobal ENTRYPOINT_PAYLOAD_SIZE: Field = 13;\nglobal ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES: Field = 416;\n\nstruct EntrypointPayload {\n // Noir doesnt support nested arrays or structs yet so we flatten everything\n flattened_args_hashes: [Field; ACCOUNT_MAX_CALLS],\n flattened_selectors: [Field; ACCOUNT_MAX_CALLS],\n flattened_targets: [Field; ACCOUNT_MAX_CALLS],\n nonce: Field,\n}\n\nimpl EntrypointPayload {\n // TODO(#1207) Do we need a generator index?\n fn hash(self) -> Field {\n dep::std::hash::pedersen(self.serialize())[0]\n }\n\n // Serializes the entrypoint struct\n fn serialize(self) -> [Field; ENTRYPOINT_PAYLOAD_SIZE] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.flattened_args_hashes);\n fields.push_array(self.flattened_selectors);\n fields.push_array(self.flattened_targets);\n fields.push(self.nonce);\n fields.storage\n }\n\n // Serializes the payload as an array of bytes. Useful for hashing with sha256.\n fn to_be_bytes(self) -> [u8; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] {\n let mut bytes: [u8; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = [0; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES];\n\n let args_len = self.flattened_args_hashes.len();\n let selectors_len = self.flattened_selectors.len();\n let targets_len = self.flattened_targets.len();\n\n for i in 0..args_len {\n let item_bytes = self.flattened_args_hashes[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[i * 32 + j] = item_bytes[j];\n }\n }\n\n for i in 0..selectors_len {\n let item_bytes = self.flattened_selectors[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[args_len * 32 + i * 32 + j] = item_bytes[j];\n }\n }\n\n for i in 0..targets_len {\n let item_bytes = self.flattened_targets[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[(args_len + selectors_len) * 32 + i * 32 + j] = item_bytes[j];\n }\n }\n \n let item_bytes = self.nonce.to_be_bytes(32);\n for j in 0..32 { \n bytes[(args_len + selectors_len + targets_len) * 32 + j] = item_bytes[j];\n }\n\n bytes\n }\n\n // Executes all private and public calls \n fn execute_calls(self, context: &mut PrivateContext) {\n for i in 0..ACCOUNT_MAX_PRIVATE_CALLS {\n let target_address = self.flattened_targets[i];\n if target_address != 0 {\n let function_selector = self.flattened_selectors[i];\n let args_hash = self.flattened_args_hashes[i];\n let _callStackItem = context.call_private_function_with_packed_args(target_address, function_selector, args_hash);\n }\n }\n for i in ACCOUNT_MAX_PRIVATE_CALLS..ACCOUNT_MAX_CALLS {\n let target_address = self.flattened_targets[i];\n if target_address != 0 {\n let function_selector = self.flattened_selectors[i];\n let args_hash = self.flattened_args_hashes[i];\n let _callStackItem = context.call_public_function_with_packed_args(target_address, function_selector, args_hash);\n }\n }\n }\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/entrypoint" - } - } - } + ] } 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 index 58309904282..43a4aa1e99e 100644 --- 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 @@ -96,44 +96,8 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } - ], - "debug": { - "debugSymbols": [ - "eJyrVsrJT04syczPK1ayqq6tBQAz9wY7", - "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" - ], - "fileMap": { - "0": { - "source": "// Account contract that uses Schnorr signatures for authentication. The signing key is the same as the\n// encryption key, and as such is not stored in the contract but part of the address preimage, so it can\n// be verified by passing in the partial address.\ncontract SchnorrSingleKeyAccount {\n use dep::std;\n use dep::aztec::entrypoint;\n use dep::aztec::entrypoint::EntrypointPayload;\n use dep::aztec::abi;\n use dep::aztec::abi::PrivateContextInputs;\n use dep::aztec::abi::CallContext;\n use dep::aztec::private_call_stack_item::PrivateCallStackItem;\n use dep::aztec::public_call_stack_item::PublicCallStackItem;\n use dep::aztec::context::PrivateContext;\n use dep::aztec::types::vec::BoundedVec;\n use dep::aztec::types::point::Point;\n use dep::aztec::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n use dep::aztec::constants_gen::GENERATOR_INDEX__SIGNATURE_PAYLOAD;\n\n fn entrypoint(\n inputs: pub PrivateContextInputs,\n payload: pub EntrypointPayload, // contains a set of arguments, selectors, targets and a nonce\n owner: pub [u8;64], // pubkey x and y coordinates concatenated\n signature: pub [u8;64], // schnorr signature of the payload hash\n partial_address: pub Field,\n ) -> distinct pub abi::PrivateCircuitPublicInputs {\n // Initialize context\n // ENTRYPOINT_PAYLOAD_SIZE(13) + 64 + 64 + 1\n let mut args: BoundedVec = BoundedVec::new(0);\n args.push_array(payload.serialize());\n for byte in owner { args.push(byte as Field); }\n for byte in signature { args.push(byte as Field); }\n args.push(partial_address);\n let mut context = PrivateContext::new(inputs, abi::hash_args(args.storage));\n\n // Verify payload signature\n let payload_fields: [Field; entrypoint::ENTRYPOINT_PAYLOAD_SIZE] = payload.serialize();\n let message_field: Field = std::hash::pedersen_with_separator(payload_fields, GENERATOR_INDEX__SIGNATURE_PAYLOAD)[0];\n let message_bytes = message_field.to_be_bytes(32);\n\n // Convert owner pubkey into fields\n let mut x: Field = 0;\n let mut y: Field = 0;\n let mut mul: Field = 1;\n for i in 0..32 {\n let bytex: Field = owner[31 - i] as Field;\n x = x + (bytex * mul);\n let bytey: Field = owner[63 - i] as Field;\n y = y + (bytey * mul);\n mul *= 256;\n }\n \n // Verify signature of the payload hash\n // TODO: Find out why this signature verification never fails\n let verification = std::schnorr::verify_signature(x, y, signature, message_bytes);\n assert(verification == true);\n\n // Verify public key against address\n let reproduced_address = dep::std::hash::pedersen_with_separator([x, y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0];\n assert(reproduced_address == context.this_address());\n\n // Execute calls\n payload.execute_calls(&mut context);\n\n context.finish()\n }\n\n // Constructs the contract\n fn constructor(\n inputs: pub PrivateContextInputs,\n ) -> distinct pub abi::PrivateCircuitPublicInputs {\n // Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.\n PrivateContext::new(inputs, 0).finish()\n }\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main" - }, - "18": { - "source": "\nimpl Field {\n #[builtin(to_le_bits)]\n fn to_le_bits(_x : Field, _bit_size: u32) -> [u1] {}\n #[builtin(to_be_bits)]\n fn to_be_bits(_x : Field, _bit_size: u32) -> [u1] {}\n\n fn to_le_bytes(x : Field, byte_size: u32) -> [u8] {\n x.to_le_radix(256, byte_size)\n }\n fn to_be_bytes(x : Field, byte_size: u32) -> [u8] {\n x.to_be_radix(256, byte_size)\n }\n\n #[builtin(to_le_radix)]\n //decompose _x into a _result_len vector over the _radix basis\n //_radix must be less than 256\n fn to_le_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {}\n #[builtin(to_be_radix)]\n fn to_be_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {}\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b = exponent.to_le_bits(32);\n\n for i in 1..33 {\n r *= r;\n r = (b[32-i] as Field) * (r * self) + (1 - b[32-i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n fn sgn0(self) -> u1 {\n self as u1\n }\n}\n\n#[builtin(modulus_num_bits)]\nfn modulus_num_bits() -> Field {}\n\n#[builtin(modulus_be_bits)]\nfn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\nfn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\nfn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\nfn modulus_le_bytes() -> [u8] {}\n", - "path": "std/field" - }, - "31": { - "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n\n contract_deployment_data: ContractDeploymentData,\n\n private_global_variables: PrivateGlobalVariables,\n}\n\n// PublicContextInputs are expected to be provided to each public function\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n\n // TODO: include globals in here and check them elsewhere\n // https://github.com/AztecProtocol/aztec-packages/issues/1567\n}\n\nimpl PublicCircuitPublicInputs {\n \n fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n // We do not include block_data since it's not in the cpp hash\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize()); // see https://github.com/AztecProtocol/aztec-packages/issues/1473\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\nfn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/abi" - }, - "32": { - "source": "use crate::constants_gen::{\n EMPTY_NULLIFIED_COMMITMENT,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n};\n\nuse crate::abi;\n\nuse crate::abi::{\n hash_args,\n CallContext,\n ContractDeploymentData,\n HistoricBlockData,\n FunctionData,\n PrivateCircuitPublicInputs,\n PublicCircuitPublicInputs,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// l1 to l2 messaging\nuse crate::messaging::process_l1_to_l2_message;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem;\n\nuse crate::types::{\n vec::BoundedVec,\n point::Point,\n};\n\nuse crate::utils::arr_copy_slice;\n\nuse crate::oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n};\n\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n inputs: abi::PrivateContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n nullified_commitments: BoundedVec,\n\n private_call_stack : BoundedVec,\n public_call_stack : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n\n block_data: HistoricBlockData,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n fn new(inputs: abi::PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n nullified_commitments: BoundedVec::new(0),\n\n block_data: inputs.block_data,\n\n private_call_stack: BoundedVec::new(0),\n public_call_stack: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n fn finish(self) -> abi::PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = abi::PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n nullified_commitments: self.nullified_commitments.storage,\n private_call_stack: self.private_call_stack.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.block_data,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n fn push_read_request(&mut self, read_request: Field) {\n self.read_requests.push(read_request);\n }\n\n fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n self.nullified_commitments.push(nullified_commitment);\n }\n\n fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n fn consume_l1_to_l2_message(&mut self, inputs: abi::PrivateContextInputs, msg_key: Field, content: Field, secret: Field) {\n let nullifier = process_l1_to_l2_message(inputs.block_data.l1_to_l2_messages_tree_root, inputs.call_context.storage_contract_address, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn call_private_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n fn call_private_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n fn call_private_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PrivateCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n \n is_delegate_call : fields[8] as bool,\n is_static_call : fields[9] as bool,\n is_contract_deployment: fields[10] as bool,\n },\n // TODO handle the offsets as a variable incremented during extraction?\n args_hash: fields[11],\n return_values: arr_copy_slice(fields, [0; RETURN_VALUES_LENGTH], 12),\n read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 16),\n new_commitments: arr_copy_slice(fields, [0; MAX_NEW_COMMITMENTS_PER_CALL], 20),\n new_nullifiers: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 24),\n nullified_commitments: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 28),\n private_call_stack: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 32),\n public_call_stack: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 36),\n new_l2_to_l1_msgs: arr_copy_slice(fields, [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 40),\n encrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 42),\n unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 44),\n encrypted_log_preimages_length: fields[46],\n unencrypted_log_preimages_length: fields[47],\n block_data: HistoricBlockData {\n // Must match order in `private_circuit_public_inputs.hpp`\n private_data_tree_root : fields[48],\n nullifier_tree_root : fields[49],\n contract_tree_root : fields[50],\n l1_to_l2_messages_tree_root : fields[51],\n blocks_tree_root : fields[52],\n public_data_tree_root: fields[53],\n global_variables_hash: fields[54],\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: Point::new(fields[55], fields[56]),\n constructor_vk_hash : fields[57],\n function_tree_root : fields[58],\n contract_address_salt : fields[59],\n portal_contract_address : fields[60],\n },\n chain_id: fields[61],\n version: fields[62],\n },\n is_execution_request: fields[63] as bool,\n };\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.private_call_stack.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n fn call_public_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n fn call_public_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n fn call_public_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PublicCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n \n is_delegate_call : fields[8] as bool,\n is_static_call : fields[9] as bool,\n is_contract_deployment: fields[10] as bool,\n },\n args_hash: fields[11],\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [0; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [0; MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_data: HistoricBlockData::empty(),\n prover_address: 0,\n },\n is_execution_request: true,\n };\n\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.public_call_stack.push(item.hash());\n }\n}\n\nuse crate::abi::{\n ContractStorageRead,\n ContractStorageUpdateRequest\n};\n\nstruct PublicContext {\n inputs: abi::PublicContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_read: BoundedVec,\n public_call_stack: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicContext {\n fn new(inputs: abi::PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = ContractStorageRead::empty();\n let empty_storage_update = ContractStorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_read: BoundedVec::new(empty_storage_read),\n public_call_stack: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_data: inputs.block_data,\n prover_address: 0,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n fn finish(self) -> abi::PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = abi::PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_read: self.contract_storage_read.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.inputs.block_data,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n }\n\n fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, this, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n fn call_public_function(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = abi::hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n fn call_public_function_no_args(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/context" - }, - "55": { - "source": "\nstruct BoundedVec {\n storage: [T; MaxLen],\n len: Field,\n}\n\nimpl BoundedVec {\n fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0 }\n }\n\n fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64);\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n fn push_array(&mut self, array: [T; Len]) {\n let newLen = self.len + array.len();\n assert(newLen as u64 <= MaxLen as u64);\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = newLen;\n }\n\n fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n\n let elem = self.storage[self.len - 1];\n self.len -= 1;\n elem\n }\n}\n\n// #[test]\n// fn test_vec() {\n// let vec: BoundedVec = BoundedVec::new(0);\n// assert(vec.len == 0);\n// let vec1 = vec.push(1);\n// assert(vec1.len == 1);\n// let vec2 = vec1.push(1);\n// assert(vec2.len == 2);\n// let vec3 = vec2.push(1);\n// assert(vec3.len == 3);\n// let x = vec3.pop();\n// assert(x == 1);\n// }", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/types/vec" - }, - "61": { - "source": "use crate::abi::FunctionData;\nuse crate::abi::PrivateCircuitPublicInputs;\nuse crate::constants_gen::GENERATOR_INDEX__CALL_STACK_ITEM;\n\nstruct PrivateCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PrivateCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PrivateCallStackItem {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)[0]\n }\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/private_call_stack_item" - }, - "78": { - "source": "use crate::abi;\nuse crate::types::vec::BoundedVec;\nuse crate::context::PrivateContext;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem; \n\nglobal ACCOUNT_MAX_PRIVATE_CALLS: Field = 2;\nglobal ACCOUNT_MAX_PUBLIC_CALLS: Field = 2;\nglobal ACCOUNT_MAX_CALLS: Field = 4;\n// 1 (ARGS_HASH) + 1 (FUNCTION_SELECTOR) + 1 (TARGET_ADDRESS)\nglobal FUNCTION_CALL_SIZE: Field = 3;\n\nstruct FunctionCall {\n args_hash: Field,\n function_selector: Field,\n target_address: Field,\n}\n\nimpl FunctionCall {\n fn serialize(self) -> [Field; FUNCTION_CALL_SIZE] {\n [self.args_hash, self.function_selector, self.target_address]\n }\n}\n\n// FUNCTION_CALL_SIZE * (ACCOUNT_MAX_PUBLIC_CALLS + ACCOUNT_MAX_PRIVATE_CALLS) + 1\nglobal ENTRYPOINT_PAYLOAD_SIZE: Field = 13;\nglobal ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES: Field = 416;\n\nstruct EntrypointPayload {\n // Noir doesnt support nested arrays or structs yet so we flatten everything\n flattened_args_hashes: [Field; ACCOUNT_MAX_CALLS],\n flattened_selectors: [Field; ACCOUNT_MAX_CALLS],\n flattened_targets: [Field; ACCOUNT_MAX_CALLS],\n nonce: Field,\n}\n\nimpl EntrypointPayload {\n // TODO(#1207) Do we need a generator index?\n fn hash(self) -> Field {\n dep::std::hash::pedersen(self.serialize())[0]\n }\n\n // Serializes the entrypoint struct\n fn serialize(self) -> [Field; ENTRYPOINT_PAYLOAD_SIZE] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.flattened_args_hashes);\n fields.push_array(self.flattened_selectors);\n fields.push_array(self.flattened_targets);\n fields.push(self.nonce);\n fields.storage\n }\n\n // Serializes the payload as an array of bytes. Useful for hashing with sha256.\n fn to_be_bytes(self) -> [u8; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] {\n let mut bytes: [u8; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = [0; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES];\n\n let args_len = self.flattened_args_hashes.len();\n let selectors_len = self.flattened_selectors.len();\n let targets_len = self.flattened_targets.len();\n\n for i in 0..args_len {\n let item_bytes = self.flattened_args_hashes[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[i * 32 + j] = item_bytes[j];\n }\n }\n\n for i in 0..selectors_len {\n let item_bytes = self.flattened_selectors[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[args_len * 32 + i * 32 + j] = item_bytes[j];\n }\n }\n\n for i in 0..targets_len {\n let item_bytes = self.flattened_targets[i].to_be_bytes(32);\n for j in 0..32 { \n bytes[(args_len + selectors_len) * 32 + i * 32 + j] = item_bytes[j];\n }\n }\n \n let item_bytes = self.nonce.to_be_bytes(32);\n for j in 0..32 { \n bytes[(args_len + selectors_len + targets_len) * 32 + j] = item_bytes[j];\n }\n\n bytes\n }\n\n // Executes all private and public calls \n fn execute_calls(self, context: &mut PrivateContext) {\n for i in 0..ACCOUNT_MAX_PRIVATE_CALLS {\n let target_address = self.flattened_targets[i];\n if target_address != 0 {\n let function_selector = self.flattened_selectors[i];\n let args_hash = self.flattened_args_hashes[i];\n let _callStackItem = context.call_private_function_with_packed_args(target_address, function_selector, args_hash);\n }\n }\n for i in ACCOUNT_MAX_PRIVATE_CALLS..ACCOUNT_MAX_CALLS {\n let target_address = self.flattened_targets[i];\n if target_address != 0 {\n let function_selector = self.flattened_selectors[i];\n let args_hash = self.flattened_args_hashes[i];\n let _callStackItem = context.call_public_function_with_packed_args(target_address, function_selector, args_hash);\n }\n }\n }\n}", - "path": "/mnt/user-data/lasse/aztec3-packages/yarn-project/noir-libs/noir-aztec/src/entrypoint" - } - } - } + ] } 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 3d04b868185..497b3c5a859 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 @@ -50,7 +50,12 @@ contract EcdsaAccount { // Note that noir expects the hash of the message/challenge as input to the ECDSA verification. let payload_fields: [Field; entrypoint::ENTRYPOINT_PAYLOAD_SIZE] = payload.serialize(); let message_field: Field = std::hash::pedersen_with_separator(payload_fields, GENERATOR_INDEX__SIGNATURE_PAYLOAD)[0]; - let message_bytes = message_field.to_be_bytes(32); + // TODO workaround for https://github.com/noir-lang/noir/issues/2421 + let message_bytes_slice = message_field.to_be_bytes(32); + let mut message_bytes: [u8; 32] = [0; 32]; + for i in 0..32 { + message_bytes[i] = message_bytes_slice[i]; + } let hashed_message: [u8; 32] = std::hash::sha256(message_bytes); let verification = std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, hashed_message); assert(verification == true); diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr index b45dcbd3bba..e1d3b5400a3 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr @@ -49,7 +49,12 @@ contract SchnorrAccount { // Verify payload signature let payload_fields: [Field; entrypoint::ENTRYPOINT_PAYLOAD_SIZE] = payload.serialize(); let message_field: Field = std::hash::pedersen_with_separator(payload_fields, GENERATOR_INDEX__SIGNATURE_PAYLOAD)[0]; - let message_bytes = message_field.to_be_bytes(32); + // TODO workaround for https://github.com/noir-lang/noir/issues/2421 + let message_bytes_slice = message_field.to_be_bytes(32); + let mut message_bytes: [u8; 32] = [0; 32]; + for i in 0..32 { + message_bytes[i] = message_bytes_slice[i]; + } // Verify signature of the payload bytes let verification = std::schnorr::verify_signature(public_key.x, public_key.y, signature, message_bytes); diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr index 74ba92023fd..466e1fba8ae 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr @@ -35,7 +35,12 @@ contract SchnorrSingleKeyAccount { // Verify payload signature let payload_fields: [Field; entrypoint::ENTRYPOINT_PAYLOAD_SIZE] = payload.serialize(); let message_field: Field = std::hash::pedersen_with_separator(payload_fields, GENERATOR_INDEX__SIGNATURE_PAYLOAD)[0]; - let message_bytes = message_field.to_be_bytes(32); + // TODO workaround for https://github.com/noir-lang/noir/issues/2421 + let message_bytes_slice = message_field.to_be_bytes(32); + let mut message_bytes: [u8; 32] = [0; 32]; + for i in 0..32 { + message_bytes[i] = message_bytes_slice[i]; + } // Convert owner pubkey into fields let mut x: Field = 0; @@ -50,7 +55,6 @@ contract SchnorrSingleKeyAccount { } // Verify signature of the payload hash - // TODO: Find out why this signature verification never fails let verification = std::schnorr::verify_signature(x, y, signature, message_bytes); assert(verification == true); diff --git a/yarn-project/noir-contracts/src/scripts/copy_output.ts b/yarn-project/noir-contracts/src/scripts/copy_output.ts index e25983f0424..3ef72f4c061 100644 --- a/yarn-project/noir-contracts/src/scripts/copy_output.ts +++ b/yarn-project/noir-contracts/src/scripts/copy_output.ts @@ -34,6 +34,8 @@ function writeToProject(abi: any) { const toWrite = { ...abi, functions: abi.functions.map((f: any) => omit(f, projectContract.exclude)), + // If we maintain debug symbols they will get commited to git. + debug: undefined, }; const targetFilename = pathJoin(projectContract.target, `${snakeCase(abi.name)}_contract.json`); writeFileSync(targetFilename, JSON.stringify(toWrite, null, 2) + '\n'); From 38f388a50cb319502bce6b8406213ff9286e8489 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Thu, 24 Aug 2023 09:54:41 +0000 Subject: [PATCH 2/3] test: update account contract test --- yarn-project/end-to-end/src/e2e_account_contracts.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 49fe2e62bdf..69f5630c5e9 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 @@ -61,7 +61,9 @@ function itShouldBehaveLikeAnAccountContract(getAccountContract: (encryptionKey: accountAddress, ).getWallet(); const childWithInvalidWallet = await ChildContract.at(child.address, invalidWallet); - await expect(childWithInvalidWallet.methods.value(42).simulate()).rejects.toThrowError(/Assertion failed: '.*'/); + await expect(childWithInvalidWallet.methods.value(42).simulate()).rejects.toThrowError( + /Cannot satisfy constraint.*/, + ); }); }); } From 3f70986add7adf412584b2d99a3e94e1fb59b300 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Thu, 24 Aug 2023 11:59:43 +0000 Subject: [PATCH 3/3] chore: update acvm js version --- yarn-project/acir-simulator/package.json | 2 +- yarn-project/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn-project/acir-simulator/package.json b/yarn-project/acir-simulator/package.json index 7bf68174b69..2e38aecdd45 100644 --- a/yarn-project/acir-simulator/package.json +++ b/yarn-project/acir-simulator/package.json @@ -35,7 +35,7 @@ "@aztec/circuits.js": "workspace:^", "@aztec/foundation": "workspace:^", "@aztec/types": "workspace:^", - "acvm_js": "github:noir-lang/acvm-js-wasm#arv/0.22+init-pedersen", + "acvm_js": "github:noir-lang/acvm-js-wasm#arv/0.23.0_prerelease", "levelup": "^5.1.1", "memdown": "^6.1.1", "tslib": "^2.4.0" diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index b5443c80b6e..df58c2269b0 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -80,7 +80,7 @@ __metadata: "@rushstack/eslint-patch": ^1.1.4 "@types/jest": ^29.5.0 "@types/node": ^18.7.23 - acvm_js: "github:noir-lang/acvm-js-wasm#arv/0.22+init-pedersen" + acvm_js: "github:noir-lang/acvm-js-wasm#arv/0.23.0_prerelease" jest: ^29.5.0 jest-mock-extended: ^3.0.4 levelup: ^5.1.1 @@ -4021,10 +4021,10 @@ __metadata: languageName: node linkType: hard -"acvm_js@github:noir-lang/acvm-js-wasm#arv/0.22+init-pedersen": - version: 0.22.0 - resolution: "acvm_js@https://github.com/noir-lang/acvm-js-wasm.git#commit=4ccaee804a9bbb5c8e3bb2adc74382a8fcff0d42" - checksum: 8f4802a4af520957a512266e3c7fb106af893209feb807d68991d374bc30d9899cdf09e3d9967d152a78e6bc8eb58e4ad397bff94f2e4b99d324b7fbfdcfbeab +"acvm_js@github:noir-lang/acvm-js-wasm#arv/0.23.0_prerelease": + version: 0.0.0-be7fafd + resolution: "acvm_js@https://github.com/noir-lang/acvm-js-wasm.git#commit=89b4ddef96ec4098d53be9d532952043502f53b9" + checksum: 469cfb1654781f928e203ebdde52e06e4633d5b319c5301a4f29a07961ef763059dd539ca37d179cbf5e786bdf114fa9767eea27d5f0c1af6bdb802360538297 languageName: node linkType: hard