@aztec/protocol-contracts 5.0.0-rc.2 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/ContractClassRegistry.json +71 -43
- package/artifacts/ContractInstanceRegistry.json +62 -38
- package/artifacts/FeeJuice.json +100 -56
- package/dest/protocol_contract_data.js +21 -21
- package/dest/tests/fixtures.js +2 -2
- package/package.json +4 -4
- package/src/protocol_contract_data.ts +20 -20
- package/src/tests/fixtures.ts +2 -2
|
@@ -348,11 +348,11 @@
|
|
|
348
348
|
},
|
|
349
349
|
{
|
|
350
350
|
"name": "to_address_point_invalid",
|
|
351
|
-
"start":
|
|
351
|
+
"start": 12908
|
|
352
352
|
}
|
|
353
353
|
],
|
|
354
354
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr",
|
|
355
|
-
"source": "use crate::{\n address::{\n partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash,\n },\n constants::{AZTEC_ADDRESS_LENGTH, DOM_SEP__CONTRACT_ADDRESS_V2, MAX_FIELD_VALUE},\n contract_class_id::ContractClassId,\n hash::poseidon2_hash_with_separator,\n public_keys::{hash_public_key, IvpkM, PublicKeys, ToPoint},\n traits::{Deserialize, Empty, FromField, Packable, Serialize, ToField},\n utils::field::sqrt,\n};\n\nuse crate::point::EmbeddedCurvePoint;\n\nuse crate::public_keys::AddressPoint;\nuse std::{\n embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key},\n ops::Add,\n};\nuse std::meta::derive;\n\n// Aztec address\n#[derive(Deserialize, Eq, Packable, Serialize)]\npub struct AztecAddress {\n pub inner: Field,\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self { inner: 0 }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl FromField for AztecAddress {\n fn from_field(value: Field) -> AztecAddress {\n AztecAddress { inner: value }\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n /// Returns `true` if the address is valid.\n ///\n /// An invalid address is one that can be proven to not be correctly derived, meaning it contains no contract code,\n /// public keys, etc., and can therefore not receive messages nor execute calls.\n pub fn is_valid(self) -> bool {\n self.get_y().is_some()\n }\n\n /// Returns an address's [`AddressPoint`].\n ///\n /// This can be used to create shared secrets with the owner of the address. If the address is invalid (see\n /// [`AztecAddress::is_valid`]) then this returns `Option::none()`, and no shared secrets can be created.\n pub fn to_address_point(self) -> Option<AddressPoint> {\n self.get_y().map(|y| {\n // If we get a negative y coordinate (y > (r - 1) / 2), we swap it to the\n // positive one (where y <= (r - 1) / 2) by negating it.\n let final_y = if Self::is_positive(y) { y } else { -y };\n\n AddressPoint { inner: EmbeddedCurvePoint { x: self.inner, y: final_y } }\n })\n }\n\n /// Determines whether a y-coordinate is in the lower (positive) or upper (negative) \"half\" of the field.\n /// I.e.\n /// y <= (r - 1)/2 => positive.\n /// y > (r - 1)/2 => negative.\n /// An AddressPoint always uses the \"positive\" y.\n fn is_positive(y: Field) -> bool {\n // Note: The field modulus r is MAX_FIELD_VALUE + 1.\n let MID = MAX_FIELD_VALUE / 2; // (r - 1) / 2\n let MID_PLUS_1 = MID + 1; // (r - 1)/2 + 1\n // Note: y <= m implies y < m + 1.\n y.lt(MID_PLUS_1)\n }\n\n /// Returns one of the two possible y-coordinates.\n ///\n /// Not all `AztecAddresses` are valid, in which case there is no corresponding y-coordinate. This returns\n /// `Option::none()` for invalid addresses.\n ///\n /// An `AztecAddress` is defined by an x-coordinate, for which two y-coordinates exist as solutions to the curve\n /// equation. This function returns either of them. Note that an [`AddressPoint`] must **always** have a positive\n /// y-coordinate - if trying to obtain the underlying point use [`AztecAddress::to_address_point`] instead.\n fn get_y(self) -> Option<Field> {\n // We compute the address point by taking our address as x, and then solving for y in the\n // equation which defines the grumpkin curve:\n // y^2 = x^3 - 17; x = address\n let x = self.inner;\n let y_squared = x * x * x - 17;\n\n sqrt(y_squared)\n }\n\n pub fn compute(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {\n //\n // address = address_point.x\n // |\n // address_point = pre_address * G + Ivpk_m (always choose \"positive\" y-coord)\n // | ^\n // | |.....................\n // pre_address .\n // / \\ .\n // / \\ .\n // partial_address public_keys_hash .\n // / \\ / / | | | \\ .\n // / \\ / / | | | \\ .\n // npk_m_hash Ivpk_m ovpk_m_hash tpk_m_hash mspk_m_hash fbpk_m_hash\n // contract_class_id \\ |.........................\n // / | \\ \\\n // artifact_hash | public_bytecode_commitment salted_initialization_hash\n // | / / \\ \\\n // private_function_tree_root salt initialization_hash deployer_address immutables_hash\n // / \\ / \\\n // ... ... constructor_fn_selector constructor_args_hash\n // / \\\n // / \\ / \\\n // leaf leaf leaf leaf\n // ^\n // |\n // |---h(function_selector, vk_hash)\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // Each of these represents a private function of the contract.\n\n let public_keys_hash = public_keys.hash();\n\n let pre_address = poseidon2_hash_with_separator(\n [public_keys_hash.to_field(), partial_address.to_field()],\n DOM_SEP__CONTRACT_ADDRESS_V2,\n );\n\n // Note: `.add()` will fail within the blackbox fn if either of the points are not on the curve. (See tests below).\n let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add(\n public_keys.ivpk_m.to_point(),\n );\n\n // Note that our address is only the x-coordinate of the full address_point. This is okay because when people want to encrypt something and send it to us\n // they can recover our full point using the x-coordinate (our address itself). To do this, they recompute the y-coordinate according to the equation y^2 = x^3 - 17.\n // When they do this, they may get a positive y-coordinate (a value that is less than or equal to MAX_FIELD_VALUE / 2) or\n // a negative y-coordinate (a value that is more than MAX_FIELD_VALUE), and we cannot dictate which one they get and hence the recovered point may sometimes be different than the one\n // our secret can decrypt. Regardless though, they should and will always encrypt using point with the positive y-coordinate by convention.\n // This ensures that everyone encrypts to the same point given an arbitrary x-coordinate (address). This is allowed because even though our original point may not have a positive y-coordinate,\n // with our original secret, we will be able to derive the secret to the point with the flipped (and now positive) y-coordinate that everyone encrypts to.\n AztecAddress::from_field(address_point.x)\n }\n\n pub fn compute_from_class_id(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash,\n public_keys: PublicKeys,\n ) -> Self {\n let partial_address = PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n salted_initialization_hash,\n );\n\n AztecAddress::compute(public_keys, partial_address)\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n#[test]\nfn check_max_field_value() {\n // Check that it is indeed r-1.\n assert_eq(MAX_FIELD_VALUE + 1, 0);\n}\n\n#[test]\nfn check_is_positive() {\n assert(AztecAddress::is_positive(0));\n assert(AztecAddress::is_positive(1));\n assert(!AztecAddress::is_positive(-1));\n assert(AztecAddress::is_positive(MAX_FIELD_VALUE / 2));\n assert(!AztecAddress::is_positive((MAX_FIELD_VALUE / 2) + 1));\n}\n\n// Gives us confidence that we don't need to manually check that the input public keys need to be on the curve for `add`,\n// because the blackbox function does this check for us.\n#[test(should_fail_with = \"is not on curve\")]\nfn check_embedded_curve_point_add() {\n // Choose a point not on the curve in the 2nd position.\n let p1 = EmbeddedCurvePoint::generator();\n let key = IvpkM { inner: EmbeddedCurvePoint { x: 1, y: 1 } };\n let _ = p1 + key.to_point();\n}\n\n#[test]\nfn compute_address_from_partial_and_pub_keys() {\n let npk_m_point = EmbeddedCurvePoint {\n x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab,\n y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7,\n };\n let ovpk_m_point = EmbeddedCurvePoint {\n x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484,\n y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b,\n };\n let tpk_m_point = EmbeddedCurvePoint {\n x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762,\n y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a,\n };\n let mspk_m_point = EmbeddedCurvePoint {\n x: 0x1bd6cb13e0bc8c6e0c1a8b2c5d7f9e0a4b6c8d0e2f4a6c8e0a2c4e6f8a0b2c4d,\n y: 0x0a032ec7b21c2bdb35f8a13e594764e39ee786c4b275eef3f0435bf6ab2b9822,\n };\n let fbpk_m_point = EmbeddedCurvePoint {\n x: 0x2c8e0a2c4e6f8b0d2f4a6c8e0a2c4e6f8b0d2f4a6c8e0a2c4e6f8b0d2f4a6c90,\n y: 0x2ef338da3a77e65f90b6d48ac686fc9ff3a95de0c39e0426fc443377425e6634,\n };\n\n let public_keys = PublicKeys {\n npk_m_hash: hash_public_key(npk_m_point),\n ivpk_m: IvpkM {\n inner: EmbeddedCurvePoint {\n x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e,\n y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95,\n },\n },\n ovpk_m_hash: hash_public_key(ovpk_m_point),\n tpk_m_hash: hash_public_key(tpk_m_point),\n mspk_m_hash: hash_public_key(mspk_m_point),\n fbpk_m_hash: hash_public_key(fbpk_m_point),\n };\n\n let partial_address = PartialAddress::from_field(\n 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de,\n );\n\n let address = AztecAddress::compute(public_keys, partial_address).to_field();\n\n let expected_computed_address_from_partial_and_pubkeys =\n 0x303ffc8bd456d132463b1fc3a633aeb718a7883c268f3956c05e6fe09b5a5424;\n assert_eq(address, expected_computed_address_from_partial_and_pubkeys);\n}\n\n#[test]\nfn compute_preaddress_from_partial_and_pub_keys() {\n let pre_address = poseidon2_hash_with_separator([1, 2], DOM_SEP__CONTRACT_ADDRESS_V2);\n let expected_computed_preaddress_from_partial_and_pubkey =\n 0x0fa1c698858df1a99170cd39d5f4bfad6d0d60f1f8afa3dc92281ee60b36f3bb;\n assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey);\n}\n\n#[test]\nfn from_field_to_field() {\n let address = AztecAddress { inner: 37 };\n assert_eq(FromField::from_field(address.to_field()), address);\n}\n\n#[test]\nfn serde() {\n let address = AztecAddress { inner: 37 };\n // We use the AZTEC_ADDRESS_LENGTH constant to ensure that there is a match between the derived trait\n // implementation and the constant.\n let serialized: [Field; AZTEC_ADDRESS_LENGTH] = address.serialize();\n let deserialized = AztecAddress::deserialize(serialized);\n assert_eq(address, deserialized);\n}\n\n#[test]\nfn to_address_point_valid() {\n // x = 8 where x^3 - 17 = 512 - 17 = 495, which is a residue in this field\n let address = AztecAddress { inner: 8 };\n\n assert(address.get_y().is_some()); // We don't bother checking the result of get_y as it is only used internally\n assert(address.is_valid());\n\n let maybe_point = address.to_address_point();\n assert(maybe_point.is_some());\n\n let point = maybe_point.unwrap().inner;\n // check that x is preserved\n assert_eq(point.x, Field::from(8));\n\n // check that the curve equation holds: y^2 == x^3 - 17\n assert_eq(point.y * point.y, point.x * point.x * point.x - 17);\n}\n\n#[test]\nunconstrained fn to_address_point_invalid() {\n // x = 3 where x^3 - 17 = 27 - 17 = 10, which is a non-residue in this field\n let address = AztecAddress { inner: 3 };\n\n assert(address.get_y().is_none());\n assert(!address.is_valid());\n\n assert(address.to_address_point().is_none());\n}\n"
|
|
355
|
+
"source": "use crate::{\n address::{\n partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash,\n },\n constants::{AZTEC_ADDRESS_LENGTH, DOM_SEP__CONTRACT_ADDRESS_V2, MAX_FIELD_VALUE},\n contract_class_id::ContractClassId,\n hash::poseidon2_hash_with_separator,\n public_keys::{hash_public_key, IvpkM, PublicKeys, ToPoint},\n traits::{Deserialize, Empty, FromField, Packable, Serialize, ToField},\n utils::field::sqrt,\n};\n\nuse crate::point::EmbeddedCurvePoint;\n\nuse crate::public_keys::AddressPoint;\nuse std::{\n embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key},\n ops::Add,\n};\nuse std::meta::derive;\n\n// Aztec address\n#[derive(Deserialize, Eq, Packable, Serialize)]\npub struct AztecAddress {\n pub inner: Field,\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self { inner: 0 }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl FromField for AztecAddress {\n fn from_field(value: Field) -> AztecAddress {\n AztecAddress { inner: value }\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n /// Returns `true` if the address is valid.\n ///\n /// An invalid address is one that can be proven to not be correctly derived, meaning it contains no contract code,\n /// public keys, etc., and can therefore not receive messages nor execute calls.\n pub fn is_valid(self) -> bool {\n self.get_y().is_some()\n }\n\n /// Returns an address's [`AddressPoint`].\n ///\n /// This can be used to create shared secrets with the owner of the address. If the address is invalid (see\n /// [`AztecAddress::is_valid`]) then this returns `Option::none()`, and no shared secrets can be created.\n pub fn to_address_point(self) -> Option<AddressPoint> {\n self.get_y().map(|y| {\n // If we get a negative y coordinate (y > (r - 1) / 2), we swap it to the\n // positive one (where y <= (r - 1) / 2) by negating it.\n let final_y = if Self::is_positive(y) { y } else { -y };\n\n AddressPoint { inner: EmbeddedCurvePoint { x: self.inner, y: final_y } }\n })\n }\n\n /// Determines whether a y-coordinate is in the lower (positive) or upper (negative) \"half\" of the field.\n /// I.e.\n /// y <= (r - 1)/2 => positive.\n /// y > (r - 1)/2 => negative.\n /// An AddressPoint always uses the \"positive\" y.\n fn is_positive(y: Field) -> bool {\n // Note: The field modulus r is MAX_FIELD_VALUE + 1.\n let MID = MAX_FIELD_VALUE / 2; // (r - 1) / 2\n let MID_PLUS_1 = MID + 1; // (r - 1)/2 + 1\n // Note: y <= m implies y < m + 1.\n y.lt(MID_PLUS_1)\n }\n\n /// Returns one of the two possible y-coordinates.\n ///\n /// Not all `AztecAddresses` are valid, in which case there is no corresponding y-coordinate. This returns\n /// `Option::none()` for invalid addresses.\n ///\n /// An `AztecAddress` is defined by an x-coordinate, for which two y-coordinates exist as solutions to the curve\n /// equation. This function returns either of them. Note that an [`AddressPoint`] must **always** have a positive\n /// y-coordinate - if trying to obtain the underlying point use [`AztecAddress::to_address_point`] instead.\n fn get_y(self) -> Option<Field> {\n // We compute the address point by taking our address as x, and then solving for y in the\n // equation which defines the grumpkin curve:\n // y^2 = x^3 - 17; x = address\n let x = self.inner;\n let y_squared = x * x * x - 17;\n\n sqrt(y_squared)\n }\n\n pub fn compute(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {\n //\n // address = address_point.x\n // |\n // address_point = pre_address * G + Ivpk_m (always choose \"positive\" y-coord)\n // | ^\n // | |.....................\n // pre_address .\n // / \\ .\n // / \\ .\n // partial_address public_keys_hash .\n // / \\ / / | | | \\ .\n // / \\ / / | | | \\ .\n // npk_m_hash Ivpk_m ovpk_m_hash tpk_m_hash mspk_m_hash fbpk_m_hash\n // contract_class_id \\ |.........................\n // / | \\ \\\n // artifact_hash | public_bytecode_commitment salted_initialization_hash\n // | / / \\ \\\n // private_function_tree_root salt initialization_hash deployer_address immutables_hash\n // / \\ / \\\n // ... ... constructor_fn_selector constructor_args_hash\n // / \\\n // / \\ / \\\n // leaf leaf leaf leaf\n // ^\n // |\n // |---h(function_selector, vk_hash)\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // Each of these represents a private function of the contract.\n\n let public_keys_hash = public_keys.hash();\n\n let pre_address = poseidon2_hash_with_separator(\n [public_keys_hash.to_field(), partial_address.to_field()],\n DOM_SEP__CONTRACT_ADDRESS_V2,\n );\n\n // Note: `.add()` will fail within the blackbox fn if either of the points are not on the curve. (See tests below).\n let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add(\n public_keys.ivpk_m.to_point(),\n );\n\n // Note that our address is only the x-coordinate of the full address_point. This is okay because when people want to encrypt something and send it to us\n // they can recover our full point using the x-coordinate (our address itself). To do this, they recompute the y-coordinate according to the equation y^2 = x^3 - 17.\n // When they do this, they may get a positive y-coordinate (a value that is less than or equal to MAX_FIELD_VALUE / 2) or\n // a negative y-coordinate (a value that is more than MAX_FIELD_VALUE), and we cannot dictate which one they get and hence the recovered point may sometimes be different than the one\n // our secret can decrypt. Regardless though, they should and will always encrypt using point with the positive y-coordinate by convention.\n // This ensures that everyone encrypts to the same point given an arbitrary x-coordinate (address). This is allowed because even though our original point may not have a positive y-coordinate,\n // with our original secret, we will be able to derive the secret to the point with the flipped (and now positive) y-coordinate that everyone encrypts to.\n AztecAddress::from_field(address_point.x)\n }\n\n pub fn compute_from_class_id(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash,\n public_keys: PublicKeys,\n ) -> Self {\n let partial_address = PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n salted_initialization_hash,\n );\n\n AztecAddress::compute(public_keys, partial_address)\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n#[test]\nfn check_max_field_value() {\n // Check that it is indeed r-1.\n assert_eq(MAX_FIELD_VALUE + 1, 0);\n}\n\n#[test]\nfn check_is_positive() {\n assert(AztecAddress::is_positive(0));\n assert(AztecAddress::is_positive(1));\n assert(!AztecAddress::is_positive(-1));\n assert(AztecAddress::is_positive(MAX_FIELD_VALUE / 2));\n assert(!AztecAddress::is_positive((MAX_FIELD_VALUE / 2) + 1));\n}\n\n// Gives us confidence that we don't need to manually check that the input public keys need to be on the curve for `add`,\n// because the blackbox function does this check for us.\n#[test(should_fail_with = \"is not on curve\")]\nfn check_embedded_curve_point_add() {\n // Choose a point not on the curve in the 2nd position.\n let p1 = EmbeddedCurvePoint::generator();\n let key = IvpkM { inner: EmbeddedCurvePoint { x: 1, y: 1 } };\n let _ = p1 + key.to_point();\n}\n\n#[test]\nfn compute_address_from_partial_and_pub_keys() {\n let npk_m_point = EmbeddedCurvePoint {\n x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab,\n y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7,\n };\n let ovpk_m_point = EmbeddedCurvePoint {\n x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484,\n y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b,\n };\n let tpk_m_point = EmbeddedCurvePoint {\n x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762,\n y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a,\n };\n let mspk_m_point = EmbeddedCurvePoint {\n x: 0x1bd6cb13e0bc8c6e0c1a8b2c5d7f9e0a4b6c8d0e2f4a6c8e0a2c4e6f8a0b2c4d,\n y: 0x0a032ec7b21c2bdb35f8a13e594764e39ee786c4b275eef3f0435bf6ab2b9822,\n };\n let fbpk_m_point = EmbeddedCurvePoint {\n x: 0x2c8e0a2c4e6f8b0d2f4a6c8e0a2c4e6f8b0d2f4a6c8e0a2c4e6f8b0d2f4a6c90,\n y: 0x2ef338da3a77e65f90b6d48ac686fc9ff3a95de0c39e0426fc443377425e6634,\n };\n\n let public_keys = PublicKeys {\n npk_m_hash: hash_public_key(npk_m_point),\n ivpk_m: IvpkM {\n inner: EmbeddedCurvePoint {\n x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e,\n y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95,\n },\n },\n ovpk_m_hash: hash_public_key(ovpk_m_point),\n tpk_m_hash: hash_public_key(tpk_m_point),\n mspk_m_hash: hash_public_key(mspk_m_point),\n fbpk_m_hash: hash_public_key(fbpk_m_point),\n };\n\n let partial_address = PartialAddress::from_field(\n 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de,\n );\n\n let address = AztecAddress::compute(public_keys, partial_address).to_field();\n\n let expected_computed_address_from_partial_and_pubkeys =\n 0x303ffc8bd456d132463b1fc3a633aeb718a7883c268f3956c05e6fe09b5a5424;\n assert_eq(address, expected_computed_address_from_partial_and_pubkeys);\n}\n\n#[test]\nfn compute_preaddress_from_partial_and_pub_keys() {\n let pre_address = poseidon2_hash_with_separator([1, 2], DOM_SEP__CONTRACT_ADDRESS_V2);\n let expected_computed_preaddress_from_partial_and_pubkey =\n 0x0fa1c698858df1a99170cd39d5f4bfad6d0d60f1f8afa3dc92281ee60b36f3bb;\n assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey);\n}\n\n#[test]\nfn from_field_to_field() {\n let address = AztecAddress { inner: 37 };\n assert_eq(FromField::from_field(address.to_field()), address);\n}\n\n#[test]\nfn serde() {\n let address = AztecAddress { inner: 37 };\n // We use the AZTEC_ADDRESS_LENGTH constant to ensure that there is a match between the derived trait\n // implementation and the constant.\n let serialized: [Field; AZTEC_ADDRESS_LENGTH] = address.serialize();\n let deserialized = AztecAddress::deserialize(serialized);\n assert_eq(address, deserialized);\n}\n\n#[test]\nfn to_address_point_valid() {\n // x = 8 where x^3 - 17 = 512 - 17 = 495, which is a residue in this field\n let address = AztecAddress { inner: 8 };\n\n assert(address.get_y().is_some()); // We don't bother checking the result of get_y as it is only used internally\n assert(address.is_valid());\n\n let maybe_point = address.to_address_point();\n assert(maybe_point.is_some());\n\n let point = maybe_point.unwrap().inner;\n // check that x is preserved\n assert_eq(point.x, Field::from(8));\n\n // check that the curve equation holds: y^2 == x^3 - 17\n assert_eq(point.y * point.y, point.x * point.x * point.x - 17);\n}\n\n#[test]\nfn to_address_point_invalid() {\n // x = 3 where x^3 - 17 = 27 - 17 = 10, which is a non-residue in this field\n let address = AztecAddress { inner: 3 };\n\n assert(address.get_y().is_none());\n assert(!address.is_valid());\n\n assert(address.to_address_point().is_none());\n}\n"
|
|
356
356
|
},
|
|
357
357
|
"15": {
|
|
358
358
|
"function_locations": [
|
|
@@ -956,15 +956,15 @@
|
|
|
956
956
|
},
|
|
957
957
|
{
|
|
958
958
|
"name": "<impl Packable for DelayedPublicMutableValues<T, INITIAL_DELAY>>::unpack",
|
|
959
|
-
"start":
|
|
959
|
+
"start": 6457
|
|
960
960
|
},
|
|
961
961
|
{
|
|
962
962
|
"name": "<impl Hash for DelayedPublicMutableValues<T, INITIAL_DELAY>>::hash",
|
|
963
|
-
"start":
|
|
963
|
+
"start": 6756
|
|
964
964
|
}
|
|
965
965
|
],
|
|
966
966
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/delayed_public_mutable/delayed_public_mutable_values.nr",
|
|
967
|
-
"source": "use crate::{\n delayed_public_mutable::{\n scheduled_delay_change::ScheduledDelayChange, scheduled_value_change::ScheduledValueChange,\n },\n hash::poseidon2_hash,\n traits::{Hash, Packable},\n utils::arrays,\n};\nuse std::meta::derive;\n\nmod test;\n\n/// DelayedPublicMutableValues is just a wrapper around ScheduledValueChange and ScheduledDelayChange that then allows us\n/// to wrap both of these values in WithHash. WithHash allows for efficient read of values in private.\n///\n/// Note that the WithHash optimization does not work in public (due to there being no unconstrained). But we also want\n/// to be able to read the values efficiently in public and we want to be able to read each value separately. Reading\n/// the values separately is tricky because ScheduledValueChange and ScheduledDelayChange are packed together (sdc and\n/// svc.timestamp_of_change are stored in the same slot). For that reason we expose `unpack_value_change` and\n/// `unpack_delay_change` functions that can be used to extract the values from the packed representation. This\n/// is \"hacky\" but there is no way around it.\n#[derive(Eq)]\npub struct DelayedPublicMutableValues<T, let INITIAL_DELAY: u64> {\n pub svc: ScheduledValueChange<T>,\n pub sdc: ScheduledDelayChange<INITIAL_DELAY>,\n}\n\nimpl<T, let INITIAL_DELAY: u64> DelayedPublicMutableValues<T, INITIAL_DELAY> {\n pub fn new(svc: ScheduledValueChange<T>, sdc: ScheduledDelayChange<INITIAL_DELAY>) -> Self {\n DelayedPublicMutableValues { svc, sdc }\n }\n}\n\n/// Extracts a ScheduledValueChange struct from the packed representation of the full DelayedPublicMutable.\n/// TODO: impl the packable trait for ScheduledValueChange.\npub fn unpack_value_change<T, let M: u32>(packed: [Field; 2 * M + 1]) -> ScheduledValueChange<T>\nwhere\n T: Packable<N = M>,\n{\n let svc_pre_packed = arrays::subarray(packed, 1);\n let svc_post_packed = arrays::subarray(packed, M + 1);\n\n // We first cast to u32 as the timestamp_of_change is packed into the same field as the delay change and it\n // occupies the first 32 bits of the field.\n let timestamp_of_change = (packed[0] as u32) as u64;\n ScheduledValueChange::new(\n T::unpack(svc_pre_packed),\n T::unpack(svc_post_packed),\n timestamp_of_change,\n )\n}\n\n/// Extracts a ScheduledDelayChange struct from 0th field of the packed representation of the full DelayedPublicMutable.\n/// This function expects to be called with just the first field of the packed representation, which contains sdc\n/// and svc timestamp_of_change. We'll discard the svc component.\npub fn unpack_delay_change<let INITIAL_DELAY: u64>(\n packed: Field,\n) -> ScheduledDelayChange<INITIAL_DELAY> {\n // This function expects to be called with just the first field of the packed representation, which contains sdc\n // and svc timestamp_of_change. We'll discard the svc component.\n let svc_timestamp_of_change = packed as u32;\n\n let mut tmp = (packed - svc_timestamp_of_change as Field) / TWO_POW_32;\n let sdc_timestamp_of_change = tmp as u32;\n\n tmp = (tmp - sdc_timestamp_of_change as Field) / TWO_POW_32;\n let sdc_post_is_some = (tmp as u8) % 2 != 0;\n\n tmp = (tmp - sdc_post_is_some as Field) / TWO_POW_8;\n let sdc_post_inner = tmp as u32;\n\n tmp = (tmp - sdc_post_inner as Field) / TWO_POW_32;\n let sdc_pre_is_some = (tmp as u8) % 2 != 0;\n\n tmp = (tmp - sdc_pre_is_some as Field) / TWO_POW_8;\n let sdc_pre_inner = tmp as u32;\n\n // Note that below we cast the values to u64 as that is the default type of timestamp in the system. Us packing\n // the values as u32 is a tech debt that is not worth tackling.\n ScheduledDelayChange {\n pre: if sdc_pre_is_some {\n Option::some(sdc_pre_inner as u64)\n } else {\n Option::none()\n },\n post: if sdc_post_is_some {\n Option::some(sdc_post_inner as u64)\n } else {\n Option::none()\n },\n timestamp_of_change: sdc_timestamp_of_change as u64,\n }\n}\n\n// Q: do these evaluate at comptime or runtime?\nglobal TWO_POW_32: Field = 2.pow_32(32);\nglobal TWO_POW_8: Field = 2.pow_32(8);\n\n// We pack to `2 * N + 1` fields because ScheduledValueChange contains T twice (hence `2 * N`) and we need one extra\n// field to store ScheduledDelayChange and the timestamp_of_change of ScheduledValueChange.\nimpl<T, let INITIAL_DELAY: u64> Packable for DelayedPublicMutableValues<T, INITIAL_DELAY>\nwhere\n T: Packable,\n{\n let N: u32 = 2 * <T as Packable>::N + 1;\n\n fn pack(self) -> [Field; Self::N] {\n let mut result = [0; Self::N];\n\n // We pack sdc.pre, sdc.post, sdc.timestamp_of_change and svc.timestamp_of_change into a single field
|
|
967
|
+
"source": "use crate::{\n delayed_public_mutable::{\n scheduled_delay_change::ScheduledDelayChange, scheduled_value_change::ScheduledValueChange,\n },\n hash::poseidon2_hash,\n traits::{Hash, Packable},\n utils::arrays,\n};\nuse std::meta::derive;\n\nmod test;\n\n/// DelayedPublicMutableValues is just a wrapper around ScheduledValueChange and ScheduledDelayChange that then allows us\n/// to wrap both of these values in WithHash. WithHash allows for efficient read of values in private.\n///\n/// Note that the WithHash optimization does not work in public (due to there being no unconstrained). But we also want\n/// to be able to read the values efficiently in public and we want to be able to read each value separately. Reading\n/// the values separately is tricky because ScheduledValueChange and ScheduledDelayChange are packed together (sdc and\n/// svc.timestamp_of_change are stored in the same slot). For that reason we expose `unpack_value_change` and\n/// `unpack_delay_change` functions that can be used to extract the values from the packed representation. This\n/// is \"hacky\" but there is no way around it.\n#[derive(Eq)]\npub struct DelayedPublicMutableValues<T, let INITIAL_DELAY: u64> {\n pub svc: ScheduledValueChange<T>,\n pub sdc: ScheduledDelayChange<INITIAL_DELAY>,\n}\n\nimpl<T, let INITIAL_DELAY: u64> DelayedPublicMutableValues<T, INITIAL_DELAY> {\n pub fn new(svc: ScheduledValueChange<T>, sdc: ScheduledDelayChange<INITIAL_DELAY>) -> Self {\n DelayedPublicMutableValues { svc, sdc }\n }\n}\n\n/// Extracts a ScheduledValueChange struct from the packed representation of the full DelayedPublicMutable.\n/// TODO: impl the packable trait for ScheduledValueChange.\npub fn unpack_value_change<T, let M: u32>(packed: [Field; 2 * M + 1]) -> ScheduledValueChange<T>\nwhere\n T: Packable<N = M>,\n{\n let svc_pre_packed = arrays::subarray(packed, 1);\n let svc_post_packed = arrays::subarray(packed, M + 1);\n\n // We first cast to u32 as the timestamp_of_change is packed into the same field as the delay change and it\n // occupies the first 32 bits of the field.\n let timestamp_of_change = (packed[0] as u32) as u64;\n ScheduledValueChange::new(\n T::unpack(svc_pre_packed),\n T::unpack(svc_post_packed),\n timestamp_of_change,\n )\n}\n\n/// Extracts a ScheduledDelayChange struct from 0th field of the packed representation of the full DelayedPublicMutable.\n/// This function expects to be called with just the first field of the packed representation, which contains sdc\n/// and svc timestamp_of_change. We'll discard the svc component.\npub fn unpack_delay_change<let INITIAL_DELAY: u64>(\n packed: Field,\n) -> ScheduledDelayChange<INITIAL_DELAY> {\n // This function expects to be called with just the first field of the packed representation, which contains sdc\n // and svc timestamp_of_change. We'll discard the svc component.\n let svc_timestamp_of_change = packed as u32;\n\n let mut tmp = (packed - svc_timestamp_of_change as Field) / TWO_POW_32;\n let sdc_timestamp_of_change = tmp as u32;\n\n tmp = (tmp - sdc_timestamp_of_change as Field) / TWO_POW_32;\n let sdc_post_is_some = (tmp as u8) % 2 != 0;\n\n tmp = (tmp - sdc_post_is_some as Field) / TWO_POW_8;\n let sdc_post_inner = tmp as u32;\n\n tmp = (tmp - sdc_post_inner as Field) / TWO_POW_32;\n let sdc_pre_is_some = (tmp as u8) % 2 != 0;\n\n tmp = (tmp - sdc_pre_is_some as Field) / TWO_POW_8;\n let sdc_pre_inner = tmp as u32;\n\n // Note that below we cast the values to u64 as that is the default type of timestamp in the system. Us packing\n // the values as u32 is a tech debt that is not worth tackling.\n ScheduledDelayChange {\n pre: if sdc_pre_is_some {\n Option::some(sdc_pre_inner as u64)\n } else {\n Option::none()\n },\n post: if sdc_post_is_some {\n Option::some(sdc_post_inner as u64)\n } else {\n Option::none()\n },\n timestamp_of_change: sdc_timestamp_of_change as u64,\n }\n}\n\n// Q: do these evaluate at comptime or runtime?\nglobal TWO_POW_32: Field = 2.pow_32(32);\nglobal TWO_POW_8: Field = 2.pow_32(8);\n\n// We pack to `2 * N + 1` fields because ScheduledValueChange contains T twice (hence `2 * N`) and we need one extra\n// field to store ScheduledDelayChange and the timestamp_of_change of ScheduledValueChange.\nimpl<T, let INITIAL_DELAY: u64> Packable for DelayedPublicMutableValues<T, INITIAL_DELAY>\nwhere\n T: Packable,\n{\n let N: u32 = 2 * <T as Packable>::N + 1;\n\n fn pack(self) -> [Field; Self::N] {\n let mut result = [0; Self::N];\n\n // We pack sdc.pre, sdc.post, sdc.timestamp_of_change and svc.timestamp_of_change into a single field:\n // [ sdc.pre_inner: u32 | sdc.pre_is_some: u8 | sdc.post_inner: u32 | sdc.post_is_some: u8 |\n // sdc.timestamp_of_change: u32 | svc.timestamp_of_change: u32 ]\n // Note that this layout stores timestamps and delays in 32-bit slots. The 2106 timestamp overflow is accepted\n // tech debt, but any value that exceeds its assigned slot would spill into adjacent fields and unpack to\n // different data. Enforce the layout here so every persistence and hash path fails closed.\n (self.svc.timestamp_of_change as Field).assert_max_bit_size::<32>();\n (self.sdc.timestamp_of_change as Field).assert_max_bit_size::<32>();\n (self.sdc.post.unwrap_unchecked() as Field).assert_max_bit_size::<32>();\n (self.sdc.pre.unwrap_unchecked() as Field).assert_max_bit_size::<32>();\n\n result[0] = self.svc.timestamp_of_change as Field\n + ((self.sdc.timestamp_of_change as Field) * 2.pow_32(32))\n + ((self.sdc.post.is_some() as Field) * 2.pow_32(64))\n + ((self.sdc.post.unwrap_unchecked() as Field) * 2.pow_32(72))\n + ((self.sdc.pre.is_some() as Field) * 2.pow_32(104))\n + ((self.sdc.pre.unwrap_unchecked() as Field) * 2.pow_32(112));\n\n // Pack the pre and post values from ScheduledValueChange\n let svc_pre_packed = self.svc.pre.pack();\n let svc_post_packed = self.svc.post.pack();\n for i in 0..<T as Packable>::N {\n result[i + 1] = svc_pre_packed[i];\n result[i + 1 + <T as Packable>::N] = svc_post_packed[i];\n }\n result\n }\n\n // Note: inefficient if all you want to unpack is the svc; use unpack_value_change instead.\n fn unpack(fields: [Field; Self::N]) -> Self {\n let svc = unpack_value_change::<T, _>(fields);\n let sdc = unpack_delay_change::<INITIAL_DELAY>(fields[0]);\n Self::new(svc, sdc)\n }\n}\n\nimpl<T, let INITIAL_DELAY: u64> Hash for DelayedPublicMutableValues<T, INITIAL_DELAY>\nwhere\n T: Packable,\n{\n fn hash(self) -> Field {\n poseidon2_hash(self.pack())\n }\n}\n"
|
|
968
968
|
},
|
|
969
969
|
"173": {
|
|
970
970
|
"function_locations": [
|
|
@@ -1280,39 +1280,39 @@
|
|
|
1280
1280
|
},
|
|
1281
1281
|
{
|
|
1282
1282
|
"name": "test::default_hashes_match_default_points",
|
|
1283
|
-
"start":
|
|
1283
|
+
"start": 4538
|
|
1284
1284
|
},
|
|
1285
1285
|
{
|
|
1286
1286
|
"name": "test::compute_public_keys_hash",
|
|
1287
|
-
"start":
|
|
1287
|
+
"start": 5437
|
|
1288
1288
|
},
|
|
1289
1289
|
{
|
|
1290
1290
|
"name": "test::test_validate_on_curve",
|
|
1291
|
-
"start":
|
|
1291
|
+
"start": 5970
|
|
1292
1292
|
},
|
|
1293
1293
|
{
|
|
1294
1294
|
"name": "test::test_validate_not_on_curve",
|
|
1295
|
-
"start":
|
|
1295
|
+
"start": 6363
|
|
1296
1296
|
},
|
|
1297
1297
|
{
|
|
1298
1298
|
"name": "test::test_validate_non_infinity",
|
|
1299
|
-
"start":
|
|
1299
|
+
"start": 6708
|
|
1300
1300
|
},
|
|
1301
1301
|
{
|
|
1302
1302
|
"name": "test::test_validate_infinity",
|
|
1303
|
-
"start":
|
|
1303
|
+
"start": 7113
|
|
1304
1304
|
},
|
|
1305
1305
|
{
|
|
1306
1306
|
"name": "test::compute_default_hash",
|
|
1307
|
-
"start":
|
|
1307
|
+
"start": 7462
|
|
1308
1308
|
},
|
|
1309
1309
|
{
|
|
1310
1310
|
"name": "test::serde",
|
|
1311
|
-
"start":
|
|
1311
|
+
"start": 7756
|
|
1312
1312
|
}
|
|
1313
1313
|
],
|
|
1314
1314
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr",
|
|
1315
|
-
"source": "use crate::{\n address::public_keys_hash::PublicKeysHash,\n constants::{\n DEFAULT_FBPK_M_HASH, DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, DEFAULT_MSPK_M_HASH,\n DEFAULT_NPK_M_HASH, DEFAULT_OVPK_M_HASH, DEFAULT_TPK_M_HASH, DOM_SEP__PUBLIC_KEYS_HASH,\n DOM_SEP__SINGLE_PUBLIC_KEY_HASH,\n },\n hash::poseidon2_hash_with_separator,\n point::{EmbeddedCurvePoint, validate_on_curve},\n traits::{Deserialize, Hash, Serialize},\n};\n\nuse std::{default::Default, meta::derive};\n\npub trait ToPoint {\n fn to_point(self) -> EmbeddedCurvePoint;\n}\n\n/// Hashes a public key point under the canonical single-public-key domain separator.\n///\n/// Defined as `Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, x, y)`.\npub fn hash_public_key(p: EmbeddedCurvePoint) -> Field {\n poseidon2_hash_with_separator([p.x, p.y], DOM_SEP__SINGLE_PUBLIC_KEY_HASH as Field)\n}\n\n#[derive(Deserialize, Eq, Serialize)]\npub struct IvpkM {\n pub inner: EmbeddedCurvePoint,\n}\n\nimpl ToPoint for IvpkM {\n fn to_point(self) -> EmbeddedCurvePoint {\n self.inner\n }\n}\n\nimpl Hash for IvpkM {\n fn hash(self) -> Field {\n hash_public_key(self.inner)\n }\n}\n\n/// A non-owner's view of an account's master public keys.\n///\n/// `npk_m_hash`, `ovpk_m_hash`, `tpk_m_hash`, `mspk_m_hash`, and `fbpk_m_hash` are the\n/// [`hash_public_key`] digests of the underlying points. The points themselves are not exposed\n/// here - they are only known to the owner. `ivpk_m` remains a point because address derivation\n/// (encrypt-to-address) requires the raw point in-circuit.\n#[derive(Deserialize, Eq, Serialize)]\npub struct PublicKeys {\n pub npk_m_hash: Field,\n pub ivpk_m: IvpkM,\n pub ovpk_m_hash: Field,\n pub tpk_m_hash: Field,\n pub mspk_m_hash: Field,\n pub fbpk_m_hash: Field,\n}\n\nimpl Default for PublicKeys {\n fn default() -> Self {\n PublicKeys {\n npk_m_hash: DEFAULT_NPK_M_HASH,\n ivpk_m: IvpkM {\n inner: EmbeddedCurvePoint { x: DEFAULT_IVPK_M_X, y: DEFAULT_IVPK_M_Y },\n },\n ovpk_m_hash: DEFAULT_OVPK_M_HASH,\n tpk_m_hash: DEFAULT_TPK_M_HASH,\n mspk_m_hash: DEFAULT_MSPK_M_HASH,\n fbpk_m_hash: DEFAULT_FBPK_M_HASH,\n }\n }\n}\n\nimpl PublicKeys {\n pub fn hash(self) -> PublicKeysHash {\n PublicKeysHash::from_field(poseidon2_hash_with_separator(\n [\n self.npk_m_hash,\n self.ivpk_m.hash(),\n self.ovpk_m_hash,\n self.tpk_m_hash,\n self.mspk_m_hash,\n self.fbpk_m_hash,\n ],\n DOM_SEP__PUBLIC_KEYS_HASH as Field,\n ))\n }\n\n /// Validates that the (only) point-form key, `ivpk_m`, lies on the Grumpkin curve.\n ///\n /// The other five keys are exposed only as hashes and are unverifiable on-circuit; the PXE\n /// is responsible for ensuring they were derived from on-curve points before persistence.\n pub fn validate_on_curve(self) {\n validate_on_curve(self.ivpk_m.inner);\n }\n\n /// Validates that `ivpk_m` is not the point at infinity.\n ///\n /// As with [`Self::validate_on_curve`], the other five keys are now exposed only as hashes\n /// and this property must be enforced PXE-side.\n pub fn validate_non_infinity(self) {\n assert_eq(self.ivpk_m.inner.is_infinite(), false, \"IvpkM is the point at infinity\");\n }\n}\n\npub struct AddressPoint {\n pub inner: EmbeddedCurvePoint,\n}\n\nimpl ToPoint for AddressPoint {\n fn to_point(self) -> EmbeddedCurvePoint {\n self.inner\n }\n}\n\nmod test {\n use crate::constants::{\n DEFAULT_FBPK_M_HASH, DEFAULT_FBPK_M_X, DEFAULT_FBPK_M_Y, DEFAULT_MSPK_M_HASH,\n DEFAULT_MSPK_M_X, DEFAULT_MSPK_M_Y, DEFAULT_NPK_M_HASH, DEFAULT_NPK_M_X, DEFAULT_NPK_M_Y,\n DEFAULT_OVPK_M_HASH, DEFAULT_OVPK_M_X, DEFAULT_OVPK_M_Y, DEFAULT_TPK_M_HASH,\n DEFAULT_TPK_M_X, DEFAULT_TPK_M_Y,\n };\n use crate::{\n point::EmbeddedCurvePoint,\n public_keys::{hash_public_key, IvpkM, PublicKeys},\n traits::{Deserialize, Serialize},\n };\n\n global PUBLIC_KEYS_LENGTH: u32 = 7;\n\n /// Catches drift between the precomputed `DEFAULT_*_M_HASH` constants and the\n /// `DEFAULT_*_M_X/Y` curve points they're derived from. If anyone updates the X/Y\n /// constants (or the hashing primitive) without also updating the *_HASH constants,\n /// this test fails and `PublicKeys::default()` would silently produce a stale value.\n #[test]\n
|
|
1315
|
+
"source": "use crate::{\n address::public_keys_hash::PublicKeysHash,\n constants::{\n DEFAULT_FBPK_M_HASH, DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, DEFAULT_MSPK_M_HASH,\n DEFAULT_NPK_M_HASH, DEFAULT_OVPK_M_HASH, DEFAULT_TPK_M_HASH, DOM_SEP__PUBLIC_KEYS_HASH,\n DOM_SEP__SINGLE_PUBLIC_KEY_HASH,\n },\n hash::poseidon2_hash_with_separator,\n point::{EmbeddedCurvePoint, validate_on_curve},\n traits::{Deserialize, Hash, Serialize},\n};\n\nuse std::{default::Default, meta::derive};\n\npub trait ToPoint {\n fn to_point(self) -> EmbeddedCurvePoint;\n}\n\n/// Hashes a public key point under the canonical single-public-key domain separator.\n///\n/// Defined as `Poseidon2(DOM_SEP__SINGLE_PUBLIC_KEY_HASH, x, y)`.\npub fn hash_public_key(p: EmbeddedCurvePoint) -> Field {\n poseidon2_hash_with_separator([p.x, p.y], DOM_SEP__SINGLE_PUBLIC_KEY_HASH as Field)\n}\n\n#[derive(Deserialize, Eq, Serialize)]\npub struct IvpkM {\n pub inner: EmbeddedCurvePoint,\n}\n\nimpl ToPoint for IvpkM {\n fn to_point(self) -> EmbeddedCurvePoint {\n self.inner\n }\n}\n\nimpl Hash for IvpkM {\n fn hash(self) -> Field {\n hash_public_key(self.inner)\n }\n}\n\n/// A non-owner's view of an account's master public keys.\n///\n/// `npk_m_hash`, `ovpk_m_hash`, `tpk_m_hash`, `mspk_m_hash`, and `fbpk_m_hash` are the\n/// [`hash_public_key`] digests of the underlying points. The points themselves are not exposed\n/// here - they are only known to the owner. `ivpk_m` remains a point because address derivation\n/// (encrypt-to-address) requires the raw point in-circuit.\n#[derive(Deserialize, Eq, Serialize)]\npub struct PublicKeys {\n pub npk_m_hash: Field,\n pub ivpk_m: IvpkM,\n pub ovpk_m_hash: Field,\n pub tpk_m_hash: Field,\n pub mspk_m_hash: Field,\n pub fbpk_m_hash: Field,\n}\n\nimpl Default for PublicKeys {\n fn default() -> Self {\n PublicKeys {\n npk_m_hash: DEFAULT_NPK_M_HASH,\n ivpk_m: IvpkM {\n inner: EmbeddedCurvePoint { x: DEFAULT_IVPK_M_X, y: DEFAULT_IVPK_M_Y },\n },\n ovpk_m_hash: DEFAULT_OVPK_M_HASH,\n tpk_m_hash: DEFAULT_TPK_M_HASH,\n mspk_m_hash: DEFAULT_MSPK_M_HASH,\n fbpk_m_hash: DEFAULT_FBPK_M_HASH,\n }\n }\n}\n\nimpl PublicKeys {\n pub fn hash(self) -> PublicKeysHash {\n PublicKeysHash::from_field(poseidon2_hash_with_separator(\n [\n self.npk_m_hash,\n self.ivpk_m.hash(),\n self.ovpk_m_hash,\n self.tpk_m_hash,\n self.mspk_m_hash,\n self.fbpk_m_hash,\n ],\n DOM_SEP__PUBLIC_KEYS_HASH as Field,\n ))\n }\n\n /// Validates that the (only) point-form key, `ivpk_m`, lies on the Grumpkin curve.\n ///\n /// The other five keys are exposed only as hashes and are unverifiable on-circuit; the PXE\n /// is responsible for ensuring they were derived from on-curve points before persistence.\n pub fn validate_on_curve(self) {\n validate_on_curve(self.ivpk_m.inner);\n }\n\n /// Validates that `ivpk_m` is not the point at infinity.\n ///\n /// As with [`Self::validate_on_curve`], the other five keys are now exposed only as hashes\n /// and this property must be enforced PXE-side.\n pub fn validate_non_infinity(self) {\n assert_eq(self.ivpk_m.inner.is_infinite(), false, \"IvpkM is the point at infinity\");\n }\n}\n\npub struct AddressPoint {\n pub inner: EmbeddedCurvePoint,\n}\n\nimpl ToPoint for AddressPoint {\n fn to_point(self) -> EmbeddedCurvePoint {\n self.inner\n }\n}\n\nmod test {\n use crate::constants::{\n DEFAULT_FBPK_M_HASH, DEFAULT_FBPK_M_X, DEFAULT_FBPK_M_Y, DEFAULT_MSPK_M_HASH,\n DEFAULT_MSPK_M_X, DEFAULT_MSPK_M_Y, DEFAULT_NPK_M_HASH, DEFAULT_NPK_M_X, DEFAULT_NPK_M_Y,\n DEFAULT_OVPK_M_HASH, DEFAULT_OVPK_M_X, DEFAULT_OVPK_M_Y, DEFAULT_TPK_M_HASH,\n DEFAULT_TPK_M_X, DEFAULT_TPK_M_Y,\n };\n use crate::{\n point::EmbeddedCurvePoint,\n public_keys::{hash_public_key, IvpkM, PublicKeys},\n traits::{Deserialize, Serialize},\n };\n\n global PUBLIC_KEYS_LENGTH: u32 = 7;\n\n /// Catches drift between the precomputed `DEFAULT_*_M_HASH` constants and the\n /// `DEFAULT_*_M_X/Y` curve points they're derived from. If anyone updates the X/Y\n /// constants (or the hashing primitive) without also updating the *_HASH constants,\n /// this test fails and `PublicKeys::default()` would silently produce a stale value.\n #[test]\n fn default_hashes_match_default_points() {\n let npk = hash_public_key(\n EmbeddedCurvePoint { x: DEFAULT_NPK_M_X, y: DEFAULT_NPK_M_Y },\n );\n assert_eq(npk, DEFAULT_NPK_M_HASH);\n\n let ovpk = hash_public_key(\n EmbeddedCurvePoint { x: DEFAULT_OVPK_M_X, y: DEFAULT_OVPK_M_Y },\n );\n assert_eq(ovpk, DEFAULT_OVPK_M_HASH);\n\n let tpk = hash_public_key(\n EmbeddedCurvePoint { x: DEFAULT_TPK_M_X, y: DEFAULT_TPK_M_Y },\n );\n assert_eq(tpk, DEFAULT_TPK_M_HASH);\n\n let mspk = hash_public_key(\n EmbeddedCurvePoint { x: DEFAULT_MSPK_M_X, y: DEFAULT_MSPK_M_Y },\n );\n assert_eq(mspk, DEFAULT_MSPK_M_HASH);\n\n let fbpk = hash_public_key(\n EmbeddedCurvePoint { x: DEFAULT_FBPK_M_X, y: DEFAULT_FBPK_M_Y },\n );\n assert_eq(fbpk, DEFAULT_FBPK_M_HASH);\n }\n\n #[test]\n fn compute_public_keys_hash() {\n let keys = PublicKeys {\n npk_m_hash: 11,\n ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } },\n ovpk_m_hash: 22,\n tpk_m_hash: 33,\n mspk_m_hash: 44,\n fbpk_m_hash: 55,\n };\n\n let actual = keys.hash().to_field();\n\n let expected_public_keys_hash =\n 0x1e57c605207e2b607720b8e3023f69f5af25683277db5ff3b99f7948213c7878;\n\n assert_eq(actual, expected_public_keys_hash);\n }\n\n #[test]\n fn test_validate_on_curve() {\n let keys = PublicKeys {\n npk_m_hash: 0,\n ivpk_m: IvpkM { inner: EmbeddedCurvePoint::generator().double() },\n ovpk_m_hash: 0,\n tpk_m_hash: 0,\n mspk_m_hash: 0,\n fbpk_m_hash: 0,\n };\n\n keys.validate_on_curve();\n }\n\n #[test(should_fail_with = \"Point not on curve\")]\n fn test_validate_not_on_curve() {\n let keys = PublicKeys {\n npk_m_hash: 0,\n ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } },\n ovpk_m_hash: 0,\n tpk_m_hash: 0,\n mspk_m_hash: 0,\n fbpk_m_hash: 0,\n };\n\n keys.validate_on_curve();\n }\n\n #[test]\n fn test_validate_non_infinity() {\n let keys = PublicKeys {\n npk_m_hash: 0,\n ivpk_m: IvpkM { inner: EmbeddedCurvePoint::generator().double() },\n ovpk_m_hash: 0,\n tpk_m_hash: 0,\n mspk_m_hash: 0,\n fbpk_m_hash: 0,\n };\n\n keys.validate_non_infinity();\n }\n\n #[test(should_fail_with = \"IvpkM is the point at infinity\")]\n fn test_validate_infinity() {\n let keys = PublicKeys {\n npk_m_hash: 0,\n ivpk_m: IvpkM { inner: EmbeddedCurvePoint::point_at_infinity() },\n ovpk_m_hash: 0,\n tpk_m_hash: 0,\n mspk_m_hash: 0,\n fbpk_m_hash: 0,\n };\n\n keys.validate_non_infinity();\n }\n\n #[test]\n fn compute_default_hash() {\n let keys = PublicKeys::default();\n\n let actual = keys.hash().to_field();\n\n let test_data_default_hash =\n 0x13c13fbec22a396f700180c621fb8c67b830b431fed47d4dd71a20d828829eaa;\n\n assert_eq(actual, test_data_default_hash);\n }\n\n #[test]\n fn serde() {\n let keys = PublicKeys {\n npk_m_hash: 11,\n ivpk_m: IvpkM { inner: EmbeddedCurvePoint { x: 3, y: 4 } },\n ovpk_m_hash: 22,\n tpk_m_hash: 33,\n mspk_m_hash: 44,\n fbpk_m_hash: 55,\n };\n\n let serialized: [Field; PUBLIC_KEYS_LENGTH] = keys.serialize();\n let deserialized = PublicKeys::deserialize(serialized);\n\n assert_eq(keys, deserialized);\n }\n}\n"
|
|
1316
1316
|
},
|
|
1317
1317
|
"211": {
|
|
1318
1318
|
"function_locations": [
|
|
@@ -2344,59 +2344,59 @@
|
|
|
2344
2344
|
},
|
|
2345
2345
|
{
|
|
2346
2346
|
"name": "PrivateContext::end_setup",
|
|
2347
|
-
"start":
|
|
2347
|
+
"start": 8235
|
|
2348
2348
|
},
|
|
2349
2349
|
{
|
|
2350
2350
|
"name": "PrivateContext::in_revertible_phase",
|
|
2351
|
-
"start":
|
|
2351
|
+
"start": 8484
|
|
2352
2352
|
},
|
|
2353
2353
|
{
|
|
2354
2354
|
"name": "PrivateContext::set_expiration_timestamp",
|
|
2355
|
-
"start":
|
|
2355
|
+
"start": 9369
|
|
2356
2356
|
},
|
|
2357
2357
|
{
|
|
2358
2358
|
"name": "PrivateContext::push_nullifier",
|
|
2359
|
-
"start":
|
|
2359
|
+
"start": 9611
|
|
2360
2360
|
},
|
|
2361
2361
|
{
|
|
2362
2362
|
"name": "PrivateContext::assert_nullifier_exists",
|
|
2363
|
-
"start":
|
|
2363
|
+
"start": 9971
|
|
2364
2364
|
},
|
|
2365
2365
|
{
|
|
2366
2366
|
"name": "PrivateContext::consume_l1_to_l2_message",
|
|
2367
|
-
"start":
|
|
2367
|
+
"start": 10611
|
|
2368
2368
|
},
|
|
2369
2369
|
{
|
|
2370
2370
|
"name": "PrivateContext::emit_private_log",
|
|
2371
|
-
"start":
|
|
2371
|
+
"start": 11203
|
|
2372
2372
|
},
|
|
2373
2373
|
{
|
|
2374
2374
|
"name": "PrivateContext::emit_contract_class_log",
|
|
2375
|
-
"start":
|
|
2375
|
+
"start": 11565
|
|
2376
2376
|
},
|
|
2377
2377
|
{
|
|
2378
2378
|
"name": "PrivateContext::static_call_private_function",
|
|
2379
|
-
"start":
|
|
2379
|
+
"start": 13063
|
|
2380
2380
|
},
|
|
2381
2381
|
{
|
|
2382
2382
|
"name": "PrivateContext::call_private_function_with_args_hash",
|
|
2383
|
-
"start":
|
|
2383
|
+
"start": 13551
|
|
2384
2384
|
},
|
|
2385
2385
|
{
|
|
2386
2386
|
"name": "PrivateContext::call_public_function_with_calldata_hash",
|
|
2387
|
-
"start":
|
|
2387
|
+
"start": 15055
|
|
2388
2388
|
},
|
|
2389
2389
|
{
|
|
2390
2390
|
"name": "PrivateContext::next_counter",
|
|
2391
|
-
"start":
|
|
2391
|
+
"start": 15636
|
|
2392
2392
|
},
|
|
2393
2393
|
{
|
|
2394
2394
|
"name": "<impl Empty for PrivateContext>::empty",
|
|
2395
|
-
"start":
|
|
2395
|
+
"start": 15805
|
|
2396
2396
|
}
|
|
2397
2397
|
],
|
|
2398
2398
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/context/private_context.nr",
|
|
2399
|
-
"source": "use crate::{\n context::{inputs::PrivateContextInputs, NullifierExistenceRequest, ReturnsHash},\n hash::hash_args,\n messaging::process_l1_to_l2_message,\n oracle::{\n call_private_function::call_private_function_internal,\n public_call::validate_public_calldata,\n tx_phase::{in_revertible_phase, notify_revertible_phase_start},\n execution_cache,\n logs::notify_created_contract_class_log,\n nullifiers::notify_created_nullifier,\n },\n};\nuse crate::protocol::{\n abis::{\n block_header::BlockHeader,\n call_context::CallContext,\n function_selector::FunctionSelector,\n gas_settings::GasSettings,\n log_hash::LogHash,\n nullifier::Nullifier,\n private_call_request::PrivateCallRequest,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n private_log::{PrivateLog, PrivateLogData},\n public_call_request::PublicCallRequest,\n },\n address::{AztecAddress, EthAddress},\n constants::{\n CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, MAX_CONTRACT_CLASS_LOGS_PER_CALL,\n MAX_ENQUEUED_CALLS_PER_CALL, MAX_TX_LIFETIME, MAX_L2_TO_L1_MSGS_PER_CALL,\n MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL,\n NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_SIZE_IN_FIELDS,\n },\n hash::poseidon2_hash,\n messaging::l2_to_l1_message::L2ToL1Message,\n side_effect::{Counted, scoped::Scoped},\n traits::Empty,\n utils::arrays::{ClaimedLengthArray, trimmed_array_length_hint},\n};\n\n/// Minimal PrivateContext for protocol contracts going to audit.\n/// Contains only the methods actually used by: fee_juice, auth_registry, contract_class_registry, contract_instance_registry\n#[derive(Eq)]\npub struct PrivateContext {\n pub inputs: PrivateContextInputs,\n pub side_effect_counter: u32,\n\n pub min_revertible_side_effect_counter: u32,\n pub is_fee_payer: bool,\n\n pub args_hash: Field,\n pub return_hash: Field,\n\n pub expiration_timestamp: u64,\n\n pub nullifier_read_requests: BoundedVec<Scoped<Counted<Field>>, MAX_NULLIFIER_READ_REQUESTS_PER_CALL>,\n\n pub nullifiers: BoundedVec<Counted<Nullifier>, MAX_NULLIFIERS_PER_CALL>,\n\n pub private_call_requests: BoundedVec<PrivateCallRequest, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL>,\n pub public_call_requests: BoundedVec<Counted<PublicCallRequest>, MAX_ENQUEUED_CALLS_PER_CALL>,\n pub public_teardown_call_request: PublicCallRequest,\n pub l2_to_l1_msgs: BoundedVec<Counted<L2ToL1Message>, MAX_L2_TO_L1_MSGS_PER_CALL>,\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n pub anchor_block_header: BlockHeader,\n\n pub private_logs: BoundedVec<Counted<PrivateLogData>, MAX_PRIVATE_LOGS_PER_CALL>,\n pub contract_class_logs_hashes: BoundedVec<Counted<LogHash>, MAX_CONTRACT_CLASS_LOGS_PER_CALL>,\n\n pub expected_non_revertible_side_effect_counter: u32,\n pub expected_revertible_side_effect_counter: u32,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.start_side_effect_counter + 1,\n min_revertible_side_effect_counter: 0,\n is_fee_payer: false,\n args_hash,\n return_hash: 0,\n expiration_timestamp: inputs.anchor_block_header.global_variables.timestamp\n + MAX_TX_LIFETIME,\n nullifier_read_requests: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n anchor_block_header: inputs.anchor_block_header,\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n\n /// Returns the contract address that initiated this function call (similar to msg.sender in Solidity).\n pub fn maybe_msg_sender(self) -> Option<AztecAddress> {\n let maybe_msg_sender = self.inputs.call_context.msg_sender;\n if maybe_msg_sender == NULL_MSG_SENDER_CONTRACT_ADDRESS {\n Option::none()\n } else {\n Option::some(maybe_msg_sender)\n }\n }\n\n /// Returns the contract address of the current function being executed.\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.contract_address\n }\n\n /// Returns the chain ID of the current network.\n pub fn chain_id(self) -> Field {\n self.inputs.tx_context.chain_id\n }\n\n /// Returns the protocol version.\n pub fn version(self) -> Field {\n self.inputs.tx_context.version\n }\n\n /// Returns the gas settings for the current transaction.\n pub fn gas_settings(self) -> GasSettings {\n self.inputs.tx_context.gas_settings\n }\n\n /// Returns the function selector of the currently executing function.\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n /// Returns the hash of the arguments passed to the current function.\n pub fn get_args_hash(self) -> Field {\n self.args_hash\n }\n\n /// Returns the anchor block header.\n pub fn get_anchor_block_header(self) -> BlockHeader {\n self.anchor_block_header\n }\n\n /// Sets the hash of the return values for this private function.\n pub fn set_return_hash<let N: u32>(&mut self, serialized_return_values: [Field; N]) {\n let return_hash = hash_args(serialized_return_values);\n self.return_hash = return_hash;\n execution_cache::store(serialized_return_values, return_hash);\n }\n\n /// Builds the PrivateCircuitPublicInputs for this private function.\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n returns_hash: self.return_hash,\n min_revertible_side_effect_counter: self.min_revertible_side_effect_counter,\n is_fee_payer: self.is_fee_payer,\n expiration_timestamp: self.expiration_timestamp,\n note_hash_read_requests: ClaimedLengthArray::empty(), // Not used by protocol contracts\n nullifier_read_requests: ClaimedLengthArray::from_bounded_vec(\n self.nullifier_read_requests,\n ),\n key_validation_requests_and_separators: ClaimedLengthArray::empty(), // Not used by protocol contracts\n note_hashes: ClaimedLengthArray::empty(), // Not used by protocol contracts\n nullifiers: ClaimedLengthArray::from_bounded_vec(self.nullifiers),\n private_call_requests: ClaimedLengthArray::from_bounded_vec(self.private_call_requests),\n public_call_requests: ClaimedLengthArray::from_bounded_vec(self.public_call_requests),\n public_teardown_call_request: self.public_teardown_call_request,\n l2_to_l1_msgs: ClaimedLengthArray::from_bounded_vec(self.l2_to_l1_msgs),\n start_side_effect_counter: self.inputs.start_side_effect_counter,\n end_side_effect_counter: self.side_effect_counter,\n private_logs: ClaimedLengthArray::from_bounded_vec(self.private_logs),\n contract_class_logs_hashes: ClaimedLengthArray::from_bounded_vec(\n self.contract_class_logs_hashes,\n ),\n anchor_block_header: self.anchor_block_header,\n tx_context: self.inputs.tx_context,\n expected_non_revertible_side_effect_counter: self\n .expected_non_revertible_side_effect_counter,\n expected_revertible_side_effect_counter: self.expected_revertible_side_effect_counter,\n }\n }\n\n /// Declares the end of the \"setup phase\" of this tx. Used by fee_juice.\n pub fn end_setup(&mut self) {\n self.side_effect_counter += 1;\n self.min_revertible_side_effect_counter = self.next_counter();\n notify_revertible_phase_start(self.min_revertible_side_effect_counter);\n }\n\n pub fn in_revertible_phase(&mut self) -> bool {\n let current_counter = self.side_effect_counter;\n\n // Safety: Kernel will validate that the claim is correct by validating the expected counters.\n let is_revertible =\n unsafe { in_revertible_phase(current_counter) };\n\n if is_revertible {\n if (self.expected_revertible_side_effect_counter == 0)\n | (current_counter < self.expected_revertible_side_effect_counter) {\n self.expected_revertible_side_effect_counter = current_counter;\n }\n } else if current_counter > self.expected_non_revertible_side_effect_counter {\n self.expected_non_revertible_side_effect_counter = current_counter;\n }\n\n is_revertible\n }\n\n /// Sets a deadline for when this transaction must be included in a block.\n pub fn set_expiration_timestamp(&mut self, expiration_timestamp: u64) {\n self.expiration_timestamp = std::cmp::min(self.expiration_timestamp, expiration_timestamp);\n }\n\n /// Pushes a new nullifier. Used by class_registry and instance_registry.\n pub fn push_nullifier(&mut self, nullifier: Field) {\n notify_created_nullifier(nullifier);\n self.nullifiers.push(Nullifier { value: nullifier, note_hash: 0 }.count(self.next_counter()));\n }\n\n /// Asserts that a nullifier has been emitted. Used by instance_registry.\n pub fn assert_nullifier_exists(\n &mut self,\n nullifier_existence_request: NullifierExistenceRequest,\n ) {\n let nullifier = nullifier_existence_request.nullifier();\n let contract_address =\n nullifier_existence_request.maybe_contract_address().unwrap_or(AztecAddress::zero());\n\n let request = Scoped::new(\n Counted::new(nullifier, self.next_counter()),\n contract_address,\n );\n\n self.nullifier_read_requests.push(request);\n }\n\n /// Consumes a message sent from Ethereum (L1) to Aztec (L2). Used by fee_juice.\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let nullifier = process_l1_to_l2_message(\n self.anchor_block_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n sender,\n self.chain_id(),\n self.version(),\n content,\n secret,\n leaf_index,\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_nullifier(nullifier)\n }\n\n /// Emits a private log. Used by instance_registry.\n pub fn emit_private_log(&mut self, log: [Field; PRIVATE_LOG_SIZE_IN_FIELDS], length: u32) {\n let counter = self.next_counter();\n let private_log = PrivateLogData { log: PrivateLog::new(log, length), note_hash_counter: 0 }\n .count(counter);\n self.private_logs.push(private_log);\n }\n\n /// Emits a contract class log. Used by class_registry.\n pub fn emit_contract_class_log<let N: u32>(&mut self, log: [Field; N]) {\n let contract_address = self.this_address();\n let counter = self.next_counter();\n\n let log_to_emit: [Field; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS] =\n log.concat([0; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS - N]);\n // Safety: The below length is constrained in the base rollup, which will make sure that all the fields beyond\n // length are zero. However, it won't be able to check that we didn't add extra padding (trailing zeroes) or\n // that we cut trailing zeroes from the end.\n let length = unsafe { trimmed_array_length_hint(log_to_emit) };\n // We hash the entire padded log to ensure a user cannot pass a shorter length and so emit incorrect shorter\n // bytecode.\n let log_hash = poseidon2_hash(log_to_emit);\n // Safety: the below only exists to broadcast the raw log, so we can provide it to the base rollup later to be\n // constrained.\n unsafe {\n notify_created_contract_class_log(contract_address, log_to_emit, length, counter);\n }\n\n self.contract_class_logs_hashes.push(LogHash { value: log_hash, length: length }.count(\n counter,\n ));\n }\n\n /// Makes a read-only call to a private function. Used by auth_registry for authwit.\n pub fn static_call_private_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n ) -> ReturnsHash {\n let args_hash = hash_args(args);\n execution_cache::store(args, args_hash);\n self.call_private_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n true,\n )\n }\n\n fn call_private_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> ReturnsHash {\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n let start_side_effect_counter = self.side_effect_counter;\n\n // Safety: The oracle simulates the private call and returns the value of the side effects counter after\n // execution of the call.\n let (end_side_effect_counter, returns_hash) = unsafe {\n call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n start_side_effect_counter,\n is_static_call,\n )\n };\n\n self.private_call_requests.push(\n PrivateCallRequest {\n call_context: CallContext {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n },\n args_hash,\n returns_hash,\n start_side_effect_counter,\n end_side_effect_counter,\n },\n );\n\n self.side_effect_counter = end_side_effect_counter + 1;\n ReturnsHash::new(returns_hash)\n }\n\n /// Enqueues a call to a public function with a calldata hash. Used by fee_juice and auth_registry.\n pub fn call_public_function_with_calldata_hash(\n &mut self,\n contract_address: AztecAddress,\n calldata_hash: Field,\n is_static_call: bool,\n hide_msg_sender: bool,\n ) {\n let counter = self.next_counter();\n\n let is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n\n validate_public_calldata(calldata_hash);\n\n let msg_sender = if hide_msg_sender {\n NULL_MSG_SENDER_CONTRACT_ADDRESS\n } else {\n self.this_address()\n };\n\n let call_request =\n PublicCallRequest { msg_sender, contract_address, is_static_call, calldata_hash };\n\n self.public_call_requests.push(Counted::new(call_request, counter));\n }\n\n fn next_counter(&mut self) -> u32 {\n let counter = self.side_effect_counter;\n self.side_effect_counter += 1;\n counter\n }\n}\n\nimpl Empty for PrivateContext {\n fn empty() -> Self {\n PrivateContext {\n inputs: PrivateContextInputs::empty(),\n side_effect_counter: 0 as u32,\n min_revertible_side_effect_counter: 0 as u32,\n is_fee_payer: false,\n args_hash: 0,\n return_hash: 0,\n expiration_timestamp: 0,\n nullifier_read_requests: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n anchor_block_header: BlockHeader::empty(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n}\n"
|
|
2399
|
+
"source": "use crate::{\n context::{inputs::PrivateContextInputs, NullifierExistenceRequest, ReturnsHash},\n hash::hash_args,\n messaging::process_l1_to_l2_message,\n oracle::{\n call_private_function::call_private_function_internal,\n public_call::validate_public_calldata,\n tx_phase::{in_revertible_phase, notify_revertible_phase_start},\n execution_cache,\n logs::notify_created_contract_class_log,\n nullifiers::notify_created_nullifier,\n },\n};\nuse crate::protocol::{\n abis::{\n block_header::BlockHeader,\n call_context::CallContext,\n function_selector::FunctionSelector,\n gas_settings::GasSettings,\n log_hash::LogHash,\n nullifier::Nullifier,\n private_call_request::PrivateCallRequest,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n private_log::{PrivateLog, PrivateLogData},\n public_call_request::PublicCallRequest,\n },\n address::{AztecAddress, EthAddress},\n constants::{\n CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, MAX_CONTRACT_CLASS_LOGS_PER_CALL,\n MAX_ENQUEUED_CALLS_PER_CALL, MAX_TX_LIFETIME, MAX_L2_TO_L1_MSGS_PER_CALL,\n MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL,\n NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_SIZE_IN_FIELDS,\n },\n hash::poseidon2_hash,\n messaging::l2_to_l1_message::L2ToL1Message,\n side_effect::{Counted, scoped::Scoped},\n traits::Empty,\n utils::arrays::{ClaimedLengthArray, trimmed_array_length_hint},\n};\n\n/// Minimal PrivateContext for protocol contracts going to audit.\n/// Contains only the methods actually used by: fee_juice, auth_registry, contract_class_registry, contract_instance_registry\n#[derive(Eq)]\npub struct PrivateContext {\n pub inputs: PrivateContextInputs,\n pub side_effect_counter: u32,\n\n pub min_revertible_side_effect_counter: u32,\n pub is_fee_payer: bool,\n\n pub args_hash: Field,\n pub return_hash: Field,\n\n pub expiration_timestamp: u64,\n\n pub nullifier_read_requests: BoundedVec<Scoped<Counted<Field>>, MAX_NULLIFIER_READ_REQUESTS_PER_CALL>,\n\n pub nullifiers: BoundedVec<Counted<Nullifier>, MAX_NULLIFIERS_PER_CALL>,\n\n pub private_call_requests: BoundedVec<PrivateCallRequest, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL>,\n pub public_call_requests: BoundedVec<Counted<PublicCallRequest>, MAX_ENQUEUED_CALLS_PER_CALL>,\n pub public_teardown_call_request: PublicCallRequest,\n pub l2_to_l1_msgs: BoundedVec<Counted<L2ToL1Message>, MAX_L2_TO_L1_MSGS_PER_CALL>,\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n pub anchor_block_header: BlockHeader,\n\n pub private_logs: BoundedVec<Counted<PrivateLogData>, MAX_PRIVATE_LOGS_PER_CALL>,\n pub contract_class_logs_hashes: BoundedVec<Counted<LogHash>, MAX_CONTRACT_CLASS_LOGS_PER_CALL>,\n\n pub expected_non_revertible_side_effect_counter: u32,\n pub expected_revertible_side_effect_counter: u32,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.start_side_effect_counter + 1,\n min_revertible_side_effect_counter: 0,\n is_fee_payer: false,\n args_hash,\n return_hash: 0,\n expiration_timestamp: inputs.anchor_block_header.global_variables.timestamp\n + MAX_TX_LIFETIME,\n nullifier_read_requests: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n anchor_block_header: inputs.anchor_block_header,\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n\n /// Returns the contract address that initiated this function call (similar to msg.sender in Solidity).\n pub fn maybe_msg_sender(self) -> Option<AztecAddress> {\n let maybe_msg_sender = self.inputs.call_context.msg_sender;\n if maybe_msg_sender == NULL_MSG_SENDER_CONTRACT_ADDRESS {\n Option::none()\n } else {\n Option::some(maybe_msg_sender)\n }\n }\n\n /// Returns the contract address of the current function being executed.\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.contract_address\n }\n\n /// Returns the chain ID of the current network.\n pub fn chain_id(self) -> Field {\n self.inputs.tx_context.chain_id\n }\n\n /// Returns the protocol version.\n pub fn version(self) -> Field {\n self.inputs.tx_context.version\n }\n\n /// Returns the gas settings for the current transaction.\n pub fn gas_settings(self) -> GasSettings {\n self.inputs.tx_context.gas_settings\n }\n\n /// Returns the function selector of the currently executing function.\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n /// Returns the hash of the arguments passed to the current function.\n pub fn get_args_hash(self) -> Field {\n self.args_hash\n }\n\n /// Returns the anchor block header.\n pub fn get_anchor_block_header(self) -> BlockHeader {\n self.anchor_block_header\n }\n\n /// Sets the hash of the return values for this private function.\n pub fn set_return_hash<let N: u32>(&mut self, serialized_return_values: [Field; N]) {\n let return_hash = hash_args(serialized_return_values);\n self.return_hash = return_hash;\n execution_cache::store(serialized_return_values, return_hash);\n }\n\n /// Builds the PrivateCircuitPublicInputs for this private function.\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n returns_hash: self.return_hash,\n min_revertible_side_effect_counter: self.min_revertible_side_effect_counter,\n is_fee_payer: self.is_fee_payer,\n expiration_timestamp: self.expiration_timestamp,\n note_hash_read_requests: ClaimedLengthArray::empty(), // Not used by protocol contracts\n nullifier_read_requests: ClaimedLengthArray::from_bounded_vec(\n self.nullifier_read_requests,\n ),\n key_validation_requests_and_separators: ClaimedLengthArray::empty(), // Not used by protocol contracts\n note_hashes: ClaimedLengthArray::empty(), // Not used by protocol contracts\n nullifiers: ClaimedLengthArray::from_bounded_vec(self.nullifiers),\n private_call_requests: ClaimedLengthArray::from_bounded_vec(self.private_call_requests),\n public_call_requests: ClaimedLengthArray::from_bounded_vec(self.public_call_requests),\n public_teardown_call_request: self.public_teardown_call_request,\n l2_to_l1_msgs: ClaimedLengthArray::from_bounded_vec(self.l2_to_l1_msgs),\n start_side_effect_counter: self.inputs.start_side_effect_counter,\n end_side_effect_counter: self.side_effect_counter,\n private_logs: ClaimedLengthArray::from_bounded_vec(self.private_logs),\n contract_class_logs_hashes: ClaimedLengthArray::from_bounded_vec(\n self.contract_class_logs_hashes,\n ),\n anchor_block_header: self.anchor_block_header,\n tx_context: self.inputs.tx_context,\n expected_non_revertible_side_effect_counter: self\n .expected_non_revertible_side_effect_counter,\n expected_revertible_side_effect_counter: self.expected_revertible_side_effect_counter,\n tx_request_salt: self.inputs.tx_request_salt,\n }\n }\n\n /// Declares the end of the \"setup phase\" of this tx. Used by fee_juice.\n pub fn end_setup(&mut self) {\n self.side_effect_counter += 1;\n self.min_revertible_side_effect_counter = self.next_counter();\n notify_revertible_phase_start(self.min_revertible_side_effect_counter);\n }\n\n pub fn in_revertible_phase(&mut self) -> bool {\n let current_counter = self.side_effect_counter;\n\n // Safety: Kernel will validate that the claim is correct by validating the expected counters.\n let is_revertible =\n unsafe { in_revertible_phase(current_counter) };\n\n if is_revertible {\n if (self.expected_revertible_side_effect_counter == 0)\n | (current_counter < self.expected_revertible_side_effect_counter) {\n self.expected_revertible_side_effect_counter = current_counter;\n }\n } else if current_counter > self.expected_non_revertible_side_effect_counter {\n self.expected_non_revertible_side_effect_counter = current_counter;\n }\n\n is_revertible\n }\n\n /// Sets a deadline for when this transaction must be included in a block.\n pub fn set_expiration_timestamp(&mut self, expiration_timestamp: u64) {\n self.expiration_timestamp = std::cmp::min(self.expiration_timestamp, expiration_timestamp);\n }\n\n /// Pushes a new nullifier. Used by class_registry and instance_registry.\n pub fn push_nullifier(&mut self, nullifier: Field) {\n notify_created_nullifier(nullifier);\n self.nullifiers.push(Nullifier { value: nullifier, note_hash: 0 }.count(self.next_counter()));\n }\n\n /// Asserts that a nullifier has been emitted. Used by instance_registry.\n pub fn assert_nullifier_exists(\n &mut self,\n nullifier_existence_request: NullifierExistenceRequest,\n ) {\n let nullifier = nullifier_existence_request.nullifier();\n let contract_address =\n nullifier_existence_request.maybe_contract_address().unwrap_or(AztecAddress::zero());\n\n let request = Scoped::new(\n Counted::new(nullifier, self.next_counter()),\n contract_address,\n );\n\n self.nullifier_read_requests.push(request);\n }\n\n /// Consumes a message sent from Ethereum (L1) to Aztec (L2). Used by fee_juice.\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let nullifier = process_l1_to_l2_message(\n self.anchor_block_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n sender,\n self.chain_id(),\n self.version(),\n content,\n secret,\n leaf_index,\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_nullifier(nullifier)\n }\n\n /// Emits a private log. Used by instance_registry.\n pub fn emit_private_log(&mut self, log: [Field; PRIVATE_LOG_SIZE_IN_FIELDS], length: u32) {\n let counter = self.next_counter();\n let private_log = PrivateLogData { log: PrivateLog::new(log, length), note_hash_counter: 0 }\n .count(counter);\n self.private_logs.push(private_log);\n }\n\n /// Emits a contract class log. Used by class_registry.\n pub fn emit_contract_class_log<let N: u32>(&mut self, log: [Field; N]) {\n let contract_address = self.this_address();\n let counter = self.next_counter();\n\n let log_to_emit: [Field; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS] =\n log.concat([0; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS - N]);\n // Safety: The below length is constrained in the base rollup, which will make sure that all the fields beyond\n // length are zero. However, it won't be able to check that we didn't add extra padding (trailing zeroes) or\n // that we cut trailing zeroes from the end.\n let length = unsafe { trimmed_array_length_hint(log_to_emit) };\n // We hash the entire padded log to ensure a user cannot pass a shorter length and so emit incorrect shorter\n // bytecode.\n let log_hash = poseidon2_hash(log_to_emit);\n // Safety: the below only exists to broadcast the raw log, so we can provide it to the base rollup later to be\n // constrained.\n unsafe {\n notify_created_contract_class_log(contract_address, log_to_emit, length, counter);\n }\n\n self.contract_class_logs_hashes.push(LogHash { value: log_hash, length: length }.count(\n counter,\n ));\n }\n\n /// Makes a read-only call to a private function. Used by auth_registry for authwit.\n pub fn static_call_private_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n ) -> ReturnsHash {\n let args_hash = hash_args(args);\n execution_cache::store(args, args_hash);\n self.call_private_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n true,\n )\n }\n\n fn call_private_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> ReturnsHash {\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n let start_side_effect_counter = self.side_effect_counter;\n\n // Safety: The oracle simulates the private call and returns the value of the side effects counter after\n // execution of the call.\n let (end_side_effect_counter, returns_hash) = unsafe {\n call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n start_side_effect_counter,\n is_static_call,\n )\n };\n\n self.private_call_requests.push(\n PrivateCallRequest {\n call_context: CallContext {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n },\n args_hash,\n returns_hash,\n start_side_effect_counter,\n end_side_effect_counter,\n },\n );\n\n self.side_effect_counter = end_side_effect_counter + 1;\n ReturnsHash::new(returns_hash)\n }\n\n /// Enqueues a call to a public function with a calldata hash. Used by fee_juice and auth_registry.\n pub fn call_public_function_with_calldata_hash(\n &mut self,\n contract_address: AztecAddress,\n calldata_hash: Field,\n is_static_call: bool,\n hide_msg_sender: bool,\n ) {\n let counter = self.next_counter();\n\n let is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n\n validate_public_calldata(calldata_hash);\n\n let msg_sender = if hide_msg_sender {\n NULL_MSG_SENDER_CONTRACT_ADDRESS\n } else {\n self.this_address()\n };\n\n let call_request =\n PublicCallRequest { msg_sender, contract_address, is_static_call, calldata_hash };\n\n self.public_call_requests.push(Counted::new(call_request, counter));\n }\n\n fn next_counter(&mut self) -> u32 {\n let counter = self.side_effect_counter;\n self.side_effect_counter += 1;\n counter\n }\n}\n\nimpl Empty for PrivateContext {\n fn empty() -> Self {\n PrivateContext {\n inputs: PrivateContextInputs::empty(),\n side_effect_counter: 0 as u32,\n min_revertible_side_effect_counter: 0 as u32,\n is_fee_payer: false,\n args_hash: 0,\n return_hash: 0,\n expiration_timestamp: 0,\n nullifier_read_requests: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n anchor_block_header: BlockHeader::empty(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n}\n"
|
|
2400
2400
|
},
|
|
2401
2401
|
"57": {
|
|
2402
2402
|
"function_locations": [
|
|
@@ -3029,6 +3029,10 @@
|
|
|
3029
3029
|
],
|
|
3030
3030
|
"length": 27
|
|
3031
3031
|
},
|
|
3032
|
+
"12469291177396340830": {
|
|
3033
|
+
"error_kind": "string",
|
|
3034
|
+
"string": "call to assert_max_bit_size"
|
|
3035
|
+
},
|
|
3032
3036
|
"12579274401768182412": {
|
|
3033
3037
|
"error_kind": "string",
|
|
3034
3038
|
"string": "New contract class is not registered"
|
|
@@ -3073,11 +3077,11 @@
|
|
|
3073
3077
|
],
|
|
3074
3078
|
"return_type": null
|
|
3075
3079
|
},
|
|
3076
|
-
"bytecode": "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
|
|
3080
|
+
"bytecode": "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",
|
|
3077
3081
|
"custom_attributes": [
|
|
3078
3082
|
"abi_public"
|
|
3079
3083
|
],
|
|
3080
|
-
"debug_symbols": "
|
|
3084
|
+
"debug_symbols": "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",
|
|
3081
3085
|
"is_unconstrained": true,
|
|
3082
3086
|
"name": "public_dispatch"
|
|
3083
3087
|
},
|
|
@@ -3553,6 +3557,12 @@
|
|
|
3553
3557
|
"sign": "unsigned",
|
|
3554
3558
|
"width": 32
|
|
3555
3559
|
}
|
|
3560
|
+
},
|
|
3561
|
+
{
|
|
3562
|
+
"name": "tx_request_salt",
|
|
3563
|
+
"type": {
|
|
3564
|
+
"kind": "field"
|
|
3565
|
+
}
|
|
3556
3566
|
}
|
|
3557
3567
|
],
|
|
3558
3568
|
"kind": "struct",
|
|
@@ -4950,6 +4960,12 @@
|
|
|
4950
4960
|
"kind": "struct",
|
|
4951
4961
|
"path": "aztec::protocol_types::utils::arrays::claimed_length_array::ClaimedLengthArray"
|
|
4952
4962
|
}
|
|
4963
|
+
},
|
|
4964
|
+
{
|
|
4965
|
+
"name": "tx_request_salt",
|
|
4966
|
+
"type": {
|
|
4967
|
+
"kind": "field"
|
|
4968
|
+
}
|
|
4953
4969
|
}
|
|
4954
4970
|
],
|
|
4955
4971
|
"kind": "struct",
|
|
@@ -4958,18 +4974,22 @@
|
|
|
4958
4974
|
"visibility": "databus"
|
|
4959
4975
|
}
|
|
4960
4976
|
},
|
|
4961
|
-
"bytecode": "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",
|
|
4977
|
+
"bytecode": "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",
|
|
4962
4978
|
"custom_attributes": [
|
|
4963
4979
|
"abi_private"
|
|
4964
4980
|
],
|
|
4965
|
-
"debug_symbols": "tVthbxstDP4v+
|
|
4981
|
+
"debug_symbols": "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",
|
|
4966
4982
|
"is_unconstrained": false,
|
|
4967
4983
|
"name": "publish_for_public_execution",
|
|
4968
|
-
"verification_key": "
|
|
4984
|
+
"verification_key": "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"
|
|
4969
4985
|
},
|
|
4970
4986
|
{
|
|
4971
4987
|
"abi": {
|
|
4972
4988
|
"error_types": {
|
|
4989
|
+
"12469291177396340830": {
|
|
4990
|
+
"error_kind": "string",
|
|
4991
|
+
"string": "call to assert_max_bit_size"
|
|
4992
|
+
},
|
|
4973
4993
|
"13455385521185560676": {
|
|
4974
4994
|
"error_kind": "string",
|
|
4975
4995
|
"string": "Storage slot 0 not allowed. Storage slots must start from 1."
|
|
@@ -5008,17 +5028,21 @@
|
|
|
5008
5028
|
],
|
|
5009
5029
|
"return_type": null
|
|
5010
5030
|
},
|
|
5011
|
-
"bytecode": "JwACBAEoAAABBIBJJwAABEklAAAARicCAwQBJwIEBAAfCgADAAQASBwASEgFLQhIAiUAAACCJwICBEknAgMEADsOAAMAAigAAEMFAlgsAABEADBkTnLhMaApuFBFtoGBWF0oM+hIeblwkUPh9ZPwAAAAJwBFAQEnAEYEAScARwABJh4CAAQBCiIERAUWCgUGHAoGBwAEKgcEBicCBAEACioFBAckAgAHAAAAtScCCAQAPAYIAR4CAAUAKQIABwADbVJ/
|
|
5031
|
+
"bytecode": "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",
|
|
5012
5032
|
"custom_attributes": [
|
|
5013
5033
|
"abi_public"
|
|
5014
5034
|
],
|
|
5015
|
-
"debug_symbols": "
|
|
5035
|
+
"debug_symbols": "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",
|
|
5016
5036
|
"is_unconstrained": true,
|
|
5017
5037
|
"name": "set_update_delay"
|
|
5018
5038
|
},
|
|
5019
5039
|
{
|
|
5020
5040
|
"abi": {
|
|
5021
5041
|
"error_types": {
|
|
5042
|
+
"12469291177396340830": {
|
|
5043
|
+
"error_kind": "string",
|
|
5044
|
+
"string": "call to assert_max_bit_size"
|
|
5045
|
+
},
|
|
5022
5046
|
"12579274401768182412": {
|
|
5023
5047
|
"error_kind": "string",
|
|
5024
5048
|
"string": "New contract class is not registered"
|
|
@@ -5064,11 +5088,11 @@
|
|
|
5064
5088
|
],
|
|
5065
5089
|
"return_type": null
|
|
5066
5090
|
},
|
|
5067
|
-
"bytecode": "JwACBAEoAAABBIBJJwAABEklAAAAQScCAwQBJwIEBAAfCgADAAQASC0ISAIlAAAAmycCAgRJJwIDBAA7DgADAAInAEMAASwAAEQALc/6U80Ocdp7SiJnezNCv8O5BD9Qgb6lg2itAI6qbzcsAABFADBkTnLhMaApuFBFtoGBWF0oM+hIeblwkUPh9ZPwAAAAJwBGAQEnAEcEASYeAgAEAQoiBEUFFgoFBhwKBgcABCoHBAYnAgQBAAoqBQQHJAIABwAAAM4nAggEADwGCAEeAgAFACkCAAcAA21SfysCAAgAAAAAAAAAAAMAAAAAAAAAAC0IAQknAgoEBQAIAQoBJwMJBAEAIgkCCi0KCgstDgcLACILAgstDgULACILAgstDgYLACILAgstDggLLQgBBScCCgQFAAgBCgEnAwUEAQAiCQIKACIFAgs/
|
|
5091
|
+
"bytecode": "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",
|
|
5068
5092
|
"custom_attributes": [
|
|
5069
5093
|
"abi_public"
|
|
5070
5094
|
],
|
|
5071
|
-
"debug_symbols": "
|
|
5095
|
+
"debug_symbols": "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",
|
|
5072
5096
|
"is_unconstrained": true,
|
|
5073
5097
|
"name": "update"
|
|
5074
5098
|
}
|
|
@@ -5500,5 +5524,5 @@
|
|
|
5500
5524
|
}
|
|
5501
5525
|
},
|
|
5502
5526
|
"transpiled": true,
|
|
5503
|
-
"aztec_version": "5.0.
|
|
5527
|
+
"aztec_version": "5.0.1"
|
|
5504
5528
|
}
|