@aztec/protocol-contracts 5.0.0-nightly.20260521 → 5.0.0-nightly.20260523

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.
@@ -1566,35 +1566,35 @@
1566
1566
  "function_locations": [
1567
1567
  {
1568
1568
  "name": "get_shared_secrets_oracle",
1569
- "start": 429
1569
+ "start": 438
1570
1570
  },
1571
1571
  {
1572
1572
  "name": "get_shared_secret",
1573
- "start": 655
1573
+ "start": 677
1574
1574
  },
1575
1575
  {
1576
1576
  "name": "get_shared_secrets",
1577
- "start": 1890
1577
+ "start": 1925
1578
1578
  },
1579
1579
  {
1580
1580
  "name": "test::preserves_ephemeral_key_ordering",
1581
- "start": 2975
1581
+ "start": 2992
1582
1582
  },
1583
1583
  {
1584
1584
  "name": "test::returns_secrets_in_order",
1585
- "start": 3862
1585
+ "start": 3863
1586
1586
  },
1587
1587
  {
1588
1588
  "name": "test::cannot_return_mismatched_length",
1589
- "start": 4570
1589
+ "start": 4571
1590
1590
  },
1591
1591
  {
1592
1592
  "name": "test::mock_get_shared_secrets",
1593
- "start": 5086
1593
+ "start": 5087
1594
1594
  }
1595
1595
  ],
1596
1596
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/oracle/shared_secret.nr",
1597
- "source": "use crate::ephemeral::EphemeralArray;\nuse crate::protocol::{address::AztecAddress, hash::sha256_to_field, point::Point};\n\nglobal GET_SHARED_SECRETS_REQUEST_SLOT: Field =\n sha256_to_field(\"AZTEC_NR::GET_SHARED_SECRETS_REQUEST_SLOT\".as_bytes());\n\n#[oracle(aztec_utl_getSharedSecrets)]\nunconstrained fn get_shared_secrets_oracle(\n address: AztecAddress,\n eph_pks_slot: Field,\n contract_address: AztecAddress,\n) -> Field {}\n\n/// Convenience wrapper around [`get_shared_secrets`] for a single ephemeral public key.\npub unconstrained fn get_shared_secret(\n address: AztecAddress,\n eph_pk: Point,\n contract_address: AztecAddress,\n) -> Field {\n get_shared_secrets::<1>(address, BoundedVec::from_array([eph_pk]), contract_address).get(0)\n}\n\n/// Returns app-siloed shared secrets between `address` and someone who knows the secret keys behind the given\n/// ephemeral public keys.\n///\n/// Each returned Field `s_app` is computed as:\n///\n/// ```text\n/// S = address_secret * ephPk (raw ECDH point)\n/// s_app = h(DOM_SEP, S.x, S.y, contract) (app-siloed scalar)\n/// ```\n///\n/// where `contract` is the address of the calling contract. The oracle host validates this matches its execution\n/// context.\n///\n/// Without app-siloing, a malicious contract could call this oracle with public information (address, ephPk) and\n/// obtain the same raw secret as the legitimate contract, enabling cross-contract decryption. By including the\n/// contract address in the hash, each contract receives a different `s_app`, preventing this attack.\n///\n/// Callers derive indexed subkeys from `s_app` via\n/// [`derive_shared_secret_subkey`](crate::keys::ecdh_shared_secret::derive_shared_secret_subkey).\npub unconstrained fn get_shared_secrets<let N: u32>(\n address: AztecAddress,\n eph_pks: BoundedVec<Point, N>,\n contract_address: AztecAddress,\n) -> BoundedVec<Field, N> {\n let request_array: EphemeralArray<Point> =\n EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT).clear();\n eph_pks.for_each(|pk| request_array.push(pk));\n\n let response_slot = get_shared_secrets_oracle(address, request_array.slot, contract_address);\n let response_array: EphemeralArray<Field> = EphemeralArray::at(response_slot);\n assert(\n response_array.len() == eph_pks.len(),\n \"get_shared_secrets: response length does not match request length\",\n );\n\n let mut results: BoundedVec<Field, N> = BoundedVec::new();\n for i in 0..eph_pks.len() {\n results.push(response_array.get(i));\n }\n results\n}\n\nmod test {\n use crate::ephemeral::EphemeralArray;\n use crate::oracle::shared_secret::{GET_SHARED_SECRETS_REQUEST_SLOT, get_shared_secrets};\n use crate::protocol::{address::AztecAddress, traits::FromField};\n use crate::test::helpers::test_environment::TestEnvironment;\n use crate::utils::point::point_from_x_coord;\n use std::test::OracleMock;\n\n #[test]\n unconstrained fn preserves_ephemeral_key_ordering() {\n let env = TestEnvironment::new();\n env.utility_context(|_| {\n let _ = mock_get_shared_secrets([100, 200, 300]);\n\n let pk_a = point_from_x_coord(1).unwrap();\n let pk_b = point_from_x_coord(2).unwrap();\n let pk_c = point_from_x_coord(8).unwrap();\n\n let _: BoundedVec<Field, 3> = get_shared_secrets(\n AztecAddress::from_field(1),\n BoundedVec::from_array([pk_a, pk_b, pk_c]),\n AztecAddress::from_field(2),\n );\n\n let request_array: EphemeralArray<_> =\n EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT);\n assert_eq(request_array.get(0), pk_a);\n assert_eq(request_array.get(1), pk_b);\n assert_eq(request_array.get(2), pk_c);\n });\n }\n\n #[test]\n unconstrained fn returns_secrets_in_order() {\n let env = TestEnvironment::new();\n env.utility_context(|_| {\n let _ = mock_get_shared_secrets([111, 222, 333]);\n\n let pk = point_from_x_coord(1).unwrap();\n let results: BoundedVec<Field, 3> = get_shared_secrets(\n AztecAddress::from_field(1),\n BoundedVec::from_array([pk, pk, pk]),\n AztecAddress::from_field(2),\n );\n\n assert_eq(results.get(0), 111);\n assert_eq(results.get(1), 222);\n assert_eq(results.get(2), 333);\n });\n }\n\n #[test(should_fail_with = \"response length does not match request length\")]\n unconstrained fn cannot_return_mismatched_length() {\n let env = TestEnvironment::new();\n env.utility_context(|_| {\n let _ = mock_get_shared_secrets([111, 222]);\n\n let pk = point_from_x_coord(1).unwrap();\n let _: BoundedVec<Field, 1> = get_shared_secrets(\n AztecAddress::from_field(1),\n BoundedVec::from_array([pk]),\n AztecAddress::from_field(2),\n );\n });\n }\n\n unconstrained fn mock_get_shared_secrets<let N: u32>(response_values: [Field; N]) -> Field {\n let response_slot: Field = 99;\n let response_array: EphemeralArray<Field> = EphemeralArray::at(response_slot);\n for value in response_values {\n response_array.push(value);\n }\n let _ = OracleMock::mock(\"aztec_utl_getSharedSecrets\").returns(response_slot);\n response_slot\n }\n}\n"
1597
+ "source": "use crate::ephemeral::EphemeralArray;\nuse crate::protocol::{address::AztecAddress, hash::sha256_to_field, point::EmbeddedCurvePoint};\n\nglobal GET_SHARED_SECRETS_REQUEST_SLOT: Field = sha256_to_field(\"AZTEC_NR::GET_SHARED_SECRETS_REQUEST_SLOT\".as_bytes());\n\n#[oracle(aztec_utl_getSharedSecrets)]\nunconstrained fn get_shared_secrets_oracle(\n address: AztecAddress,\n eph_pks_slot: Field,\n contract_address: AztecAddress,\n) -> Field {}\n\n/// Convenience wrapper around [`get_shared_secrets`] for a single ephemeral public key.\npub unconstrained fn get_shared_secret(\n address: AztecAddress,\n eph_pk: EmbeddedCurvePoint,\n contract_address: AztecAddress,\n) -> Field {\n get_shared_secrets::<1>(address, BoundedVec::from_array([eph_pk]), contract_address).get(0)\n}\n\n/// Returns app-siloed shared secrets between `address` and someone who knows the secret keys behind the given\n/// ephemeral public keys.\n///\n/// Each returned Field `s_app` is computed as:\n///\n/// ```text\n/// S = address_secret * ephPk (raw ECDH point)\n/// s_app = h(DOM_SEP, S.x, S.y, contract) (app-siloed scalar)\n/// ```\n///\n/// where `contract` is the address of the calling contract. The oracle host validates this matches its execution\n/// context.\n///\n/// Without app-siloing, a malicious contract could call this oracle with public information (address, ephPk) and\n/// obtain the same raw secret as the legitimate contract, enabling cross-contract decryption. By including the\n/// contract address in the hash, each contract receives a different `s_app`, preventing this attack.\n///\n/// Callers derive indexed subkeys from `s_app` via\n/// [`derive_shared_secret_subkey`](crate::keys::ecdh_shared_secret::derive_shared_secret_subkey).\npub unconstrained fn get_shared_secrets<let N: u32>(\n address: AztecAddress,\n eph_pks: BoundedVec<EmbeddedCurvePoint, N>,\n contract_address: AztecAddress,\n) -> BoundedVec<Field, N> {\n let request_array: EphemeralArray<EmbeddedCurvePoint> = EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT).clear();\n eph_pks.for_each(|pk| request_array.push(pk));\n\n let response_slot = get_shared_secrets_oracle(address, request_array.slot, contract_address);\n let response_array: EphemeralArray<Field> = EphemeralArray::at(response_slot);\n assert(response_array.len() == eph_pks.len(), \"get_shared_secrets: response length does not match request length\");\n\n let mut results: BoundedVec<Field, N> = BoundedVec::new();\n for i in 0..eph_pks.len() {\n results.push(response_array.get(i));\n }\n results\n}\n\nmod test {\n use crate::ephemeral::EphemeralArray;\n use crate::oracle::shared_secret::{get_shared_secrets, GET_SHARED_SECRETS_REQUEST_SLOT};\n use crate::protocol::{address::AztecAddress, traits::FromField};\n use crate::test::helpers::test_environment::TestEnvironment;\n use crate::utils::point::point_from_x_coord;\n use std::test::OracleMock;\n\n #[test]\n unconstrained fn preserves_ephemeral_key_ordering() {\n let env = TestEnvironment::new();\n env.utility_context(|_| {\n let _ = mock_get_shared_secrets([100, 200, 300]);\n\n let pk_a = point_from_x_coord(1).unwrap();\n let pk_b = point_from_x_coord(2).unwrap();\n let pk_c = point_from_x_coord(8).unwrap();\n\n let _: BoundedVec<Field, 3> = get_shared_secrets(\n AztecAddress::from_field(1),\n BoundedVec::from_array([pk_a, pk_b, pk_c]),\n AztecAddress::from_field(2),\n );\n\n let request_array: EphemeralArray<_> = EphemeralArray::at(GET_SHARED_SECRETS_REQUEST_SLOT);\n assert_eq(request_array.get(0), pk_a);\n assert_eq(request_array.get(1), pk_b);\n assert_eq(request_array.get(2), pk_c);\n });\n }\n\n #[test]\n unconstrained fn returns_secrets_in_order() {\n let env = TestEnvironment::new();\n env.utility_context(|_| {\n let _ = mock_get_shared_secrets([111, 222, 333]);\n\n let pk = point_from_x_coord(1).unwrap();\n let results: BoundedVec<Field, 3> = get_shared_secrets(\n AztecAddress::from_field(1),\n BoundedVec::from_array([pk, pk, pk]),\n AztecAddress::from_field(2),\n );\n\n assert_eq(results.get(0), 111);\n assert_eq(results.get(1), 222);\n assert_eq(results.get(2), 333);\n });\n }\n\n #[test(should_fail_with = \"response length does not match request length\")]\n unconstrained fn cannot_return_mismatched_length() {\n let env = TestEnvironment::new();\n env.utility_context(|_| {\n let _ = mock_get_shared_secrets([111, 222]);\n\n let pk = point_from_x_coord(1).unwrap();\n let _: BoundedVec<Field, 1> = get_shared_secrets(\n AztecAddress::from_field(1),\n BoundedVec::from_array([pk]),\n AztecAddress::from_field(2),\n );\n });\n }\n\n unconstrained fn mock_get_shared_secrets<let N: u32>(response_values: [Field; N]) -> Field {\n let response_slot: Field = 99;\n let response_array: EphemeralArray<Field> = EphemeralArray::at(response_slot);\n for value in response_values {\n response_array.push(value);\n }\n let _ = OracleMock::mock(\"aztec_utl_getSharedSecrets\").returns(response_slot);\n response_slot\n }\n}\n"
1598
1598
  },
1599
1599
  "198": {
1600
1600
  "function_locations": [
@@ -1884,51 +1884,51 @@
1884
1884
  "function_locations": [
1885
1885
  {
1886
1886
  "name": "get_sign_of_point",
1887
- "start": 488
1887
+ "start": 514
1888
1888
  },
1889
1889
  {
1890
1890
  "name": "point_from_x_coord",
1891
- "start": 1371
1891
+ "start": 1424
1892
1892
  },
1893
1893
  {
1894
1894
  "name": "point_from_x_coord_and_sign",
1895
- "start": 2088
1895
+ "start": 2161
1896
1896
  },
1897
1897
  {
1898
1898
  "name": "test::test_point_from_x_coord_and_sign",
1899
- "start": 2697
1899
+ "start": 2776
1900
1900
  },
1901
1901
  {
1902
1902
  "name": "test::test_point_from_x_coord_valid",
1903
- "start": 3524
1903
+ "start": 3607
1904
1904
  },
1905
1905
  {
1906
1906
  "name": "test::test_point_from_x_coord_invalid",
1907
- "start": 3966
1907
+ "start": 4049
1908
1908
  },
1909
1909
  {
1910
1910
  "name": "test::test_both_roots_satisfy_curve",
1911
- "start": 4228
1911
+ "start": 4311
1912
1912
  },
1913
1913
  {
1914
1914
  "name": "test::test_point_from_x_coord_and_sign_invalid",
1915
- "start": 4803
1915
+ "start": 4886
1916
1916
  },
1917
1917
  {
1918
1918
  "name": "test::test_get_sign_of_point",
1919
- "start": 5214
1919
+ "start": 5297
1920
1920
  },
1921
1921
  {
1922
1922
  "name": "test::test_point_from_x_coord_zero",
1923
- "start": 6328
1923
+ "start": 6383
1924
1924
  },
1925
1925
  {
1926
1926
  "name": "test::test_bn254_fr_modulus_div_2",
1927
- "start": 6573
1927
+ "start": 6628
1928
1928
  }
1929
1929
  ],
1930
1930
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/utils/point.nr",
1931
- "source": "use crate::protocol::{point::Point, utils::field::sqrt};\n\n// I am storing the modulus minus 1 divided by 2 here because full modulus would throw \"String literal too large\" error\n// Full modulus is 21888242871839275222246405745257275088548364400416034343698204186575808495617\nglobal BN254_FR_MODULUS_DIV_2: Field = 10944121435919637611123202872628637544274182200208017171849102093287904247808;\n\n/// Returns: true if p.y <= MOD_DIV_2, else false.\npub fn get_sign_of_point(p: Point) -> bool {\n // We store only a \"sign\" of the y coordinate because the rest can be derived from the x coordinate. To get the\n // sign we check if the y coordinate is less or equal than the field's modulus minus 1 divided by 2. Ideally we'd\n // do `y <= MOD_DIV_2`, but there's no `lte` function, so instead we do `!(y > MOD_DIV_2)`, which is equivalent,\n // and then rewrite that as `!(MOD_DIV_2 < y)`, since we also have no `gt` function.\n !BN254_FR_MODULUS_DIV_2.lt(p.y)\n}\n\n/// Returns a `Point` in the Grumpkin curve given its x coordinate.\n///\n/// Because not all values in the field are valid x coordinates of points in the curve (i.e. there is no corresponding\n/// y value in the field that satisfies the curve equation), it may not be possible to reconstruct a `Point`.\n/// `Option::none()` is returned in such cases.\npub fn point_from_x_coord(x: Field) -> Option<Point> {\n // y ^ 2 = x ^ 3 - 17\n let rhs = x * x * x - 17;\n sqrt(rhs).map(|y| Point { x, y, is_infinite: false })\n}\n\n/// Returns a `Point` in the Grumpkin curve given its x coordinate and sign for the y coordinate.\n///\n/// Because not all values in the field are valid x coordinates of points in the curve (i.e. there is no corresponding\n/// y value in the field that satisfies the curve equation), it may not be possible to reconstruct a `Point`.\n/// `Option::none()` is returned in such cases.\n///\n/// @param x - The x coordinate of the point @param sign - The \"sign\" of the y coordinate - determines whether y <=\n/// (Fr.MODULUS - 1) / 2\npub fn point_from_x_coord_and_sign(x: Field, sign: bool) -> Option<Point> {\n // y ^ 2 = x ^ 3 - 17\n let rhs = x * x * x - 17;\n\n sqrt(rhs).map(|y| {\n // If there is a square root, we need to ensure it has the correct \"sign\"\n let y_is_positive = !BN254_FR_MODULUS_DIV_2.lt(y);\n let final_y = if y_is_positive == sign { y } else { -y };\n Point { x, y: final_y, is_infinite: false }\n })\n}\n\nmod test {\n use crate::protocol::point::Point;\n use crate::utils::point::{\n BN254_FR_MODULUS_DIV_2, get_sign_of_point, point_from_x_coord, point_from_x_coord_and_sign,\n };\n\n #[test]\n unconstrained fn test_point_from_x_coord_and_sign() {\n // Test positive y coordinate\n let x = 0x1af41f5de96446dc3776a1eb2d98bb956b7acd9979a67854bec6fa7c2973bd73;\n let sign = true;\n let p = point_from_x_coord_and_sign(x, sign).unwrap();\n\n assert_eq(p.x, x);\n assert_eq(p.y, 0x07fc22c7f2c7057571f137fe46ea9c95114282bc95d37d71ec4bfb88de457d4a);\n assert_eq(p.is_infinite, false);\n\n // Test negative y coordinate\n let x2 = 0x247371652e55dd74c9af8dbe9fb44931ba29a9229994384bd7077796c14ee2b5;\n let sign2 = false;\n let p2 = point_from_x_coord_and_sign(x2, sign2).unwrap();\n\n assert_eq(p2.x, x2);\n assert_eq(p2.y, 0x26441aec112e1ae4cee374f42556932001507ad46e255ffb27369c7e3766e5c0);\n assert_eq(p2.is_infinite, false);\n }\n\n #[test]\n unconstrained fn test_point_from_x_coord_valid() {\n // x = 8 is a known quadratic residue - should give a valid point\n let result = point_from_x_coord(Field::from(8));\n assert(result.is_some());\n\n let point = result.unwrap();\n assert_eq(point.x, Field::from(8));\n // Check curve equation y^2 = x^3 - 17\n assert_eq(point.y * point.y, point.x * point.x * point.x - 17);\n }\n\n #[test]\n unconstrained fn test_point_from_x_coord_invalid() {\n // x = 3 is a non-residue for this curve - should give None\n let x = Field::from(3);\n let maybe_point = point_from_x_coord(x);\n assert(maybe_point.is_none());\n }\n\n #[test]\n unconstrained fn test_both_roots_satisfy_curve() {\n // Derive a point from x = 8 (known to be valid from test_point_from_x_coord_valid)\n let x: Field = 8;\n let point = point_from_x_coord(x).unwrap();\n\n // Check y satisfies curve equation\n assert_eq(point.y * point.y, x * x * x - 17);\n\n // Check -y also satisfies curve equation\n let neg_y = 0 - point.y;\n assert_eq(neg_y * neg_y, x * x * x - 17);\n\n // Verify they are different (unless y = 0)\n assert(point.y != neg_y);\n }\n\n #[test]\n unconstrained fn test_point_from_x_coord_and_sign_invalid() {\n // x = 3 has no valid point on the curve (from test_point_from_x_coord_invalid)\n let x = Field::from(3);\n let result_positive = point_from_x_coord_and_sign(x, true);\n let result_negative = point_from_x_coord_and_sign(x, false);\n\n assert(result_positive.is_none());\n assert(result_negative.is_none());\n }\n\n #[test]\n unconstrained fn test_get_sign_of_point() {\n // Derive a point from x = 8, then test both possible y values\n let point = point_from_x_coord(8).unwrap();\n let neg_point = Point { x: point.x, y: 0 - point.y, is_infinite: false };\n\n // One should be \"positive\" (y <= MOD_DIV_2) and one \"negative\"\n let sign1 = get_sign_of_point(point);\n let sign2 = get_sign_of_point(neg_point);\n assert(sign1 != sign2);\n\n // y = 0 should return true (0 <= MOD_DIV_2)\n let zero_y_point = Point { x: 0, y: 0, is_infinite: false };\n assert(get_sign_of_point(zero_y_point) == true);\n\n // y = MOD_DIV_2 should return true (exactly at boundary)\n let boundary_point = Point { x: 0, y: BN254_FR_MODULUS_DIV_2, is_infinite: false };\n assert(get_sign_of_point(boundary_point) == true);\n\n // y = MOD_DIV_2 + 1 should return false (just over boundary)\n let over_boundary_point = Point { x: 0, y: BN254_FR_MODULUS_DIV_2 + 1, is_infinite: false };\n assert(get_sign_of_point(over_boundary_point) == false);\n }\n\n #[test]\n unconstrained fn test_point_from_x_coord_zero() {\n // x = 0: y^2 = 0^3 - 17 = -17, which is not a quadratic residue in BN254 scalar field\n let result = point_from_x_coord(0);\n assert(result.is_none());\n }\n\n #[test]\n unconstrained fn test_bn254_fr_modulus_div_2() {\n // Verify that BN254_FR_MODULUS_DIV_2 == (p - 1) / 2 This means: 2 * BN254_FR_MODULUS_DIV_2 + 1 == p == 0 (in\n // the field)\n assert_eq(2 * BN254_FR_MODULUS_DIV_2 + 1, 0);\n }\n\n}\n"
1931
+ "source": "use crate::protocol::{point::EmbeddedCurvePoint, utils::field::sqrt};\n\n// I am storing the modulus minus 1 divided by 2 here because full modulus would throw \"String literal too large\" error\n// Full modulus is 21888242871839275222246405745257275088548364400416034343698204186575808495617\nglobal BN254_FR_MODULUS_DIV_2: Field = 10944121435919637611123202872628637544274182200208017171849102093287904247808;\n\n/// Returns: true if p.y <= MOD_DIV_2, else false.\npub fn get_sign_of_point(p: EmbeddedCurvePoint) -> bool {\n // We store only a \"sign\" of the y coordinate because the rest can be derived from the x coordinate. To get the\n // sign we check if the y coordinate is less or equal than the field's modulus minus 1 divided by 2. Ideally we'd\n // do `y <= MOD_DIV_2`, but there's no `lte` function, so instead we do `!(y > MOD_DIV_2)`, which is equivalent,\n // and then rewrite that as `!(MOD_DIV_2 < y)`, since we also have no `gt` function.\n !BN254_FR_MODULUS_DIV_2.lt(p.y)\n}\n\n/// Returns an `EmbeddedCurvePoint` in the Grumpkin curve given its x coordinate.\n///\n/// Because not all values in the field are valid x coordinates of points in the curve (i.e. there is no corresponding\n/// y value in the field that satisfies the curve equation), it may not be possible to reconstruct a `Point`.\n/// `Option::none()` is returned in such cases.\npub fn point_from_x_coord(x: Field) -> Option<EmbeddedCurvePoint> {\n // y ^ 2 = x ^ 3 - 17\n let rhs = x * x * x - 17;\n sqrt(rhs).map(|y| EmbeddedCurvePoint { x, y })\n}\n\n/// Returns an `EmbeddedCurvePoint` in the Grumpkin curve given its x coordinate and sign for the y coordinate.\n///\n/// Because not all values in the field are valid x coordinates of points in the curve (i.e. there is no corresponding\n/// y value in the field that satisfies the curve equation), it may not be possible to reconstruct a `Point`.\n/// `Option::none()` is returned in such cases.\n///\n/// @param x - The x coordinate of the point @param sign - The \"sign\" of the y coordinate - determines whether y <=\n/// (Fr.MODULUS - 1) / 2\npub fn point_from_x_coord_and_sign(x: Field, sign: bool) -> Option<EmbeddedCurvePoint> {\n // y ^ 2 = x ^ 3 - 17\n let rhs = x * x * x - 17;\n\n sqrt(rhs).map(|y| {\n // If there is a square root, we need to ensure it has the correct \"sign\"\n let y_is_positive = !BN254_FR_MODULUS_DIV_2.lt(y);\n let final_y = if y_is_positive == sign { y } else { -y };\n EmbeddedCurvePoint { x, y: final_y }\n })\n}\n\nmod test {\n use crate::protocol::point::EmbeddedCurvePoint;\n use crate::utils::point::{\n BN254_FR_MODULUS_DIV_2, get_sign_of_point, point_from_x_coord, point_from_x_coord_and_sign,\n };\n\n #[test]\n unconstrained fn test_point_from_x_coord_and_sign() {\n // Test positive y coordinate\n let x = 0x1af41f5de96446dc3776a1eb2d98bb956b7acd9979a67854bec6fa7c2973bd73;\n let sign = true;\n let p = point_from_x_coord_and_sign(x, sign).unwrap();\n\n assert_eq(p.x, x);\n assert_eq(p.y, 0x07fc22c7f2c7057571f137fe46ea9c95114282bc95d37d71ec4bfb88de457d4a);\n assert_eq(p.is_infinite(), false);\n\n // Test negative y coordinate\n let x2 = 0x247371652e55dd74c9af8dbe9fb44931ba29a9229994384bd7077796c14ee2b5;\n let sign2 = false;\n let p2 = point_from_x_coord_and_sign(x2, sign2).unwrap();\n\n assert_eq(p2.x, x2);\n assert_eq(p2.y, 0x26441aec112e1ae4cee374f42556932001507ad46e255ffb27369c7e3766e5c0);\n assert_eq(p2.is_infinite(), false);\n }\n\n #[test]\n unconstrained fn test_point_from_x_coord_valid() {\n // x = 8 is a known quadratic residue - should give a valid point\n let result = point_from_x_coord(Field::from(8));\n assert(result.is_some());\n\n let point = result.unwrap();\n assert_eq(point.x, Field::from(8));\n // Check curve equation y^2 = x^3 - 17\n assert_eq(point.y * point.y, point.x * point.x * point.x - 17);\n }\n\n #[test]\n unconstrained fn test_point_from_x_coord_invalid() {\n // x = 3 is a non-residue for this curve - should give None\n let x = Field::from(3);\n let maybe_point = point_from_x_coord(x);\n assert(maybe_point.is_none());\n }\n\n #[test]\n unconstrained fn test_both_roots_satisfy_curve() {\n // Derive a point from x = 8 (known to be valid from test_point_from_x_coord_valid)\n let x: Field = 8;\n let point = point_from_x_coord(x).unwrap();\n\n // Check y satisfies curve equation\n assert_eq(point.y * point.y, x * x * x - 17);\n\n // Check -y also satisfies curve equation\n let neg_y = 0 - point.y;\n assert_eq(neg_y * neg_y, x * x * x - 17);\n\n // Verify they are different (unless y = 0)\n assert(point.y != neg_y);\n }\n\n #[test]\n unconstrained fn test_point_from_x_coord_and_sign_invalid() {\n // x = 3 has no valid point on the curve (from test_point_from_x_coord_invalid)\n let x = Field::from(3);\n let result_positive = point_from_x_coord_and_sign(x, true);\n let result_negative = point_from_x_coord_and_sign(x, false);\n\n assert(result_positive.is_none());\n assert(result_negative.is_none());\n }\n\n #[test]\n unconstrained fn test_get_sign_of_point() {\n // Derive a point from x = 8, then test both possible y values\n let point = point_from_x_coord(8).unwrap();\n let neg_point = EmbeddedCurvePoint { x: point.x, y: 0 - point.y };\n\n // One should be \"positive\" (y <= MOD_DIV_2) and one \"negative\"\n let sign1 = get_sign_of_point(point);\n let sign2 = get_sign_of_point(neg_point);\n assert(sign1 != sign2);\n\n // y = 0 should return true (0 <= MOD_DIV_2)\n let zero_y_point = EmbeddedCurvePoint { x: 0, y: 0 };\n assert(get_sign_of_point(zero_y_point) == true);\n\n // y = MOD_DIV_2 should return true (exactly at boundary)\n let boundary_point = EmbeddedCurvePoint { x: 0, y: BN254_FR_MODULUS_DIV_2 };\n assert(get_sign_of_point(boundary_point) == true);\n\n // y = MOD_DIV_2 + 1 should return false (just over boundary)\n let over_boundary_point = EmbeddedCurvePoint { x: 0, y: BN254_FR_MODULUS_DIV_2 + 1 };\n assert(get_sign_of_point(over_boundary_point) == false);\n }\n\n #[test]\n unconstrained fn test_point_from_x_coord_zero() {\n // x = 0: y^2 = 0^3 - 17 = -17, which is not a quadratic residue in BN254 scalar field\n let result = point_from_x_coord(0);\n assert(result.is_none());\n }\n\n #[test]\n unconstrained fn test_bn254_fr_modulus_div_2() {\n // Verify that BN254_FR_MODULUS_DIV_2 == (p - 1) / 2 This means: 2 * BN254_FR_MODULUS_DIV_2 + 1 == p == 0 (in\n // the field)\n assert_eq(2 * BN254_FR_MODULUS_DIV_2 + 1, 0);\n }\n\n}\n"
1932
1932
  },
1933
1933
  "268": {
1934
1934
  "function_locations": [
@@ -2360,104 +2360,6 @@
2360
2360
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/logging.nr",
2361
2361
  "source": "// Log levels matching the JS logger:\n\n// global SILENT_LOG_LEVEL: u8 = 0;\nglobal FATAL_LOG_LEVEL: u8 = 1;\nglobal ERROR_LOG_LEVEL: u8 = 2;\nglobal WARN_LOG_LEVEL: u8 = 3;\nglobal INFO_LOG_LEVEL: u8 = 4;\nglobal VERBOSE_LOG_LEVEL: u8 = 5;\nglobal DEBUG_LOG_LEVEL: u8 = 6;\nglobal TRACE_LOG_LEVEL: u8 = 7;\n\n// --- Per-level log functions (no format args) ---\n\npub fn fatal_log<let N: u32>(msg: str<N>) {\n fatal_log_format(msg, []);\n}\n\npub fn error_log<let N: u32>(msg: str<N>) {\n error_log_format(msg, []);\n}\n\npub fn warn_log<let N: u32>(msg: str<N>) {\n warn_log_format(msg, []);\n}\n\npub fn info_log<let N: u32>(msg: str<N>) {\n info_log_format(msg, []);\n}\n\npub fn verbose_log<let N: u32>(msg: str<N>) {\n verbose_log_format(msg, []);\n}\n\npub fn debug_log<let N: u32>(msg: str<N>) {\n debug_log_format(msg, []);\n}\n\npub fn trace_log<let N: u32>(msg: str<N>) {\n trace_log_format(msg, []);\n}\n\n// --- Per-level log functions (with format args) ---\n\npub fn fatal_log_format<let M: u32, let N: u32>(msg: str<M>, args: [Field; N]) {\n log_format(FATAL_LOG_LEVEL, msg, args);\n}\n\npub fn error_log_format<let M: u32, let N: u32>(msg: str<M>, args: [Field; N]) {\n log_format(ERROR_LOG_LEVEL, msg, args);\n}\n\npub fn warn_log_format<let M: u32, let N: u32>(msg: str<M>, args: [Field; N]) {\n log_format(WARN_LOG_LEVEL, msg, args);\n}\n\npub fn info_log_format<let M: u32, let N: u32>(msg: str<M>, args: [Field; N]) {\n log_format(INFO_LOG_LEVEL, msg, args);\n}\n\npub fn verbose_log_format<let M: u32, let N: u32>(msg: str<M>, args: [Field; N]) {\n log_format(VERBOSE_LOG_LEVEL, msg, args);\n}\n\npub fn debug_log_format<let M: u32, let N: u32>(msg: str<M>, args: [Field; N]) {\n log_format(DEBUG_LOG_LEVEL, msg, args);\n}\n\npub fn trace_log_format<let M: u32, let N: u32>(msg: str<M>, args: [Field; N]) {\n log_format(TRACE_LOG_LEVEL, msg, args);\n}\n\nfn log_format<let M: u32, let N: u32>(log_level: u8, msg: str<M>, args: [Field; N]) {\n // Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n // to call.\n unsafe { log_oracle_wrapper(log_level, msg, args) };\n}\n\nunconstrained fn log_oracle_wrapper<let M: u32, let N: u32>(\n log_level: u8,\n msg: str<M>,\n args: [Field; N],\n) {\n log_oracle(log_level, msg, N, args);\n}\n\n// While the length parameter might seem unnecessary given that we have N, we keep it around because at the AVM\n// bytecode level we want to support non-comptime-known lengths for such opcodes, even if Noir code will not generally\n// take that route. The AVM transpiler maps this oracle to the DEBUGLOG opcode, which reads the fields size from memory.\n#[oracle(aztec_utl_log)]\nunconstrained fn log_oracle<let M: u32, let N: u32>(\n log_level: u8,\n msg: str<M>,\n length: u32,\n args: [Field; N],\n) {}\n"
2362
2362
  },
2363
- "377": {
2364
- "function_locations": [
2365
- {
2366
- "name": "Point::generator",
2367
- "start": 918
2368
- },
2369
- {
2370
- "name": "Point::point_at_infinity",
2371
- "start": 1068
2372
- },
2373
- {
2374
- "name": "Point::double",
2375
- "start": 1157
2376
- },
2377
- {
2378
- "name": "Point::to_embedded",
2379
- "start": 1260
2380
- },
2381
- {
2382
- "name": "<impl From<EmbeddedCurvePoint> for Point>::from",
2383
- "start": 1408
2384
- },
2385
- {
2386
- "name": "<impl std::ops::Add for Point>::add",
2387
- "start": 1553
2388
- },
2389
- {
2390
- "name": "<impl std::ops::Sub for Point>::sub",
2391
- "start": 1693
2392
- },
2393
- {
2394
- "name": "<impl std::ops::Neg for Point>::neg",
2395
- "start": 1819
2396
- },
2397
- {
2398
- "name": "<impl Eq for Point>::eq",
2399
- "start": 1959
2400
- },
2401
- {
2402
- "name": "<impl Hash for Point>::hash",
2403
- "start": 2111
2404
- },
2405
- {
2406
- "name": "<impl Empty for Point>::empty",
2407
- "start": 2381
2408
- },
2409
- {
2410
- "name": "<impl Serialize for Point>::serialize",
2411
- "start": 2543
2412
- },
2413
- {
2414
- "name": "<impl Serialize for Point>::stream_serialize",
2415
- "start": 2670
2416
- },
2417
- {
2418
- "name": "<impl Deserialize for Point>::deserialize",
2419
- "start": 2904
2420
- },
2421
- {
2422
- "name": "<impl Deserialize for Point>::stream_deserialize",
2423
- "start": 3078
2424
- },
2425
- {
2426
- "name": "validate_on_curve",
2427
- "start": 3210
2428
- },
2429
- {
2430
- "name": "<impl Packable for Point>::pack",
2431
- "start": 3761
2432
- },
2433
- {
2434
- "name": "<impl Packable for Point>::unpack",
2435
- "start": 3843
2436
- },
2437
- {
2438
- "name": "tests::test_validate_on_curve_generator",
2439
- "start": 4012
2440
- },
2441
- {
2442
- "name": "tests::test_validate_on_curve_infinity",
2443
- "start": 4224
2444
- },
2445
- {
2446
- "name": "tests::test_validate_on_curve_invalid_point",
2447
- "start": 4506
2448
- },
2449
- {
2450
- "name": "tests::test_validate_on_curve_infinity_non_canonical_x",
2451
- "start": 4829
2452
- },
2453
- {
2454
- "name": "tests::test_validate_on_curve_infinity_non_canonical_y",
2455
- "start": 5175
2456
- }
2457
- ],
2458
- "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/point.nr",
2459
- "source": "use crate::{\n hash::poseidon2_hash,\n traits::{Deserialize, Empty, Hash, Packable, Serialize},\n utils::{reader::Reader, writer::Writer},\n};\nuse std::embedded_curve_ops::EmbeddedCurvePoint;\n\npub global POINT_LENGTH: u32 = 3;\n\n// TODO(F-553): This custom `Point` struct is a temporary workaround. A newer version of Noir dropped the `is_infinite`\n// field from `EmbeddedCurvePoint` and changed its serialization from 3 fields to 2. To preserve backwards compatibility\n// of our onchain serialization format we re-introduced our own `Point` that wraps `EmbeddedCurvePoint` and keeps the\n// old 3-field layout. Once we're ready to take the breaking change (e.g. alongside the v5 oracle changes), delete this\n// struct, use `EmbeddedCurvePoint` directly and reduce `POINT_LENGTH` to 2.\npub struct Point {\n pub x: Field,\n pub y: Field,\n pub is_infinite: bool,\n}\n\nimpl Point {\n pub fn generator() -> Self {\n let g = EmbeddedCurvePoint::generator();\n Point { x: g.x, y: g.y, is_infinite: false }\n }\n\n pub fn point_at_infinity() -> Self {\n Point { x: 0, y: 0, is_infinite: true }\n }\n\n pub fn double(self) -> Self {\n self.to_embedded().double().into()\n }\n\n pub fn to_embedded(self) -> EmbeddedCurvePoint {\n EmbeddedCurvePoint { x: self.x, y: self.y }\n }\n}\n\nimpl From<EmbeddedCurvePoint> for Point {\n fn from(p: EmbeddedCurvePoint) -> Self {\n Point { x: p.x, y: p.y, is_infinite: p.is_infinite() }\n }\n}\n\nimpl std::ops::Add for Point {\n fn add(self, other: Point) -> Point {\n (self.to_embedded() + other.to_embedded()).into()\n }\n}\n\nimpl std::ops::Sub for Point {\n fn sub(self, other: Point) -> Point {\n (self.to_embedded() - other.to_embedded()).into()\n }\n}\n\nimpl std::ops::Neg for Point {\n fn neg(self) -> Point {\n Point { x: self.x, y: -self.y, is_infinite: self.is_infinite }\n }\n}\n\nimpl Eq for Point {\n fn eq(self, other: Point) -> bool {\n (self.x == other.x) & (self.y == other.y) & (self.is_infinite == other.is_infinite)\n }\n}\n\nimpl Hash for Point {\n fn hash(self) -> Field {\n poseidon2_hash(self.serialize())\n }\n}\n\nimpl Empty for Point {\n /// Note: Does not return a valid point on curve - instead represents an empty/\"unpopulated\" point struct (e.g.\n /// empty/unpopulated value in an array of points).\n fn empty() -> Self {\n Point { x: 0, y: 0, is_infinite: false }\n }\n}\n\nimpl Serialize for Point {\n let N: u32 = POINT_LENGTH;\n\n fn serialize(self) -> [Field; Self::N] {\n [self.x, self.y, self.is_infinite as Field]\n }\n\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self.x);\n writer.write(self.y);\n writer.write(self.is_infinite as Field);\n }\n}\n\nimpl Deserialize for Point {\n let N: u32 = POINT_LENGTH;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Point { x: fields[0], y: fields[1], is_infinite: fields[2] != 0 }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Point { x: reader.read(), y: reader.read(), is_infinite: reader.read_bool() }\n }\n}\n\npub fn validate_on_curve(p: Point) {\n // y^2 == x^3 - 17\n let x = p.x;\n let y = p.y;\n if p.is_infinite {\n // Assert the canonical representation of infinity\n assert_eq(x, 0, \"Point at infinity should have canonical representation (0 0)\");\n assert_eq(y, 0, \"Point at infinity should have canonical representation (0 0)\");\n } else {\n assert_eq(y * y, x * x * x - 17, \"Point not on curve\");\n }\n}\n\n// TODO(#11356): use compact representation here.\nimpl Packable for Point {\n let N: u32 = POINT_LENGTH;\n\n fn pack(self) -> [Field; Self::N] {\n self.serialize()\n }\n\n fn unpack(packed: [Field; Self::N]) -> Self {\n Self::deserialize(packed)\n }\n}\n\nmod tests {\n use super::{Point, validate_on_curve};\n\n #[test]\n unconstrained fn test_validate_on_curve_generator() {\n // The generator point should be on the curve\n let generator = Point::generator();\n validate_on_curve(generator);\n }\n\n #[test]\n unconstrained fn test_validate_on_curve_infinity() {\n // Canonical infinite point (x=0, y=0) should pass\n let infinity = Point { x: 0, y: 0, is_infinite: true };\n validate_on_curve(infinity);\n }\n\n #[test(should_fail_with = \"Point not on curve\")]\n unconstrained fn test_validate_on_curve_invalid_point() {\n // A point not on the curve should fail\n let invalid = Point { x: 1, y: 1, is_infinite: false };\n validate_on_curve(invalid);\n }\n\n #[test(should_fail_with = \"Point at infinity should have canonical representation (0 0)\")]\n unconstrained fn test_validate_on_curve_infinity_non_canonical_x() {\n // Infinite point with non-zero x should fail\n let invalid_infinity = Point { x: 1, y: 0, is_infinite: true };\n validate_on_curve(invalid_infinity);\n }\n\n #[test(should_fail_with = \"Point at infinity should have canonical representation (0 0)\")]\n unconstrained fn test_validate_on_curve_infinity_non_canonical_y() {\n // Infinite point with non-zero y should fail\n let invalid_infinity = Point { x: 0, y: 1, is_infinite: true };\n validate_on_curve(invalid_infinity);\n }\n}\n"
2460
- },
2461
2363
  "378": {
2462
2364
  "function_locations": [
2463
2365
  {
@@ -2544,123 +2446,131 @@
2544
2446
  "function_locations": [
2545
2447
  {
2546
2448
  "name": "<impl Packable for bool>::pack",
2547
- "start": 504
2449
+ "start": 564
2548
2450
  },
2549
2451
  {
2550
2452
  "name": "<impl Packable for bool>::unpack",
2551
- "start": 606
2453
+ "start": 666
2552
2454
  },
2553
2455
  {
2554
2456
  "name": "<impl Packable for u8>::pack",
2555
- "start": 767
2457
+ "start": 827
2556
2458
  },
2557
2459
  {
2558
2460
  "name": "<impl Packable for u8>::unpack",
2559
- "start": 869
2461
+ "start": 929
2560
2462
  },
2561
2463
  {
2562
2464
  "name": "<impl Packable for u16>::pack",
2563
- "start": 1021
2465
+ "start": 1081
2564
2466
  },
2565
2467
  {
2566
2468
  "name": "<impl Packable for u16>::unpack",
2567
- "start": 1123
2469
+ "start": 1183
2568
2470
  },
2569
2471
  {
2570
2472
  "name": "<impl Packable for u32>::pack",
2571
- "start": 1276
2473
+ "start": 1336
2572
2474
  },
2573
2475
  {
2574
2476
  "name": "<impl Packable for u32>::unpack",
2575
- "start": 1378
2477
+ "start": 1438
2576
2478
  },
2577
2479
  {
2578
2480
  "name": "<impl Packable for u64>::pack",
2579
- "start": 1531
2481
+ "start": 1591
2580
2482
  },
2581
2483
  {
2582
2484
  "name": "<impl Packable for u64>::unpack",
2583
- "start": 1633
2485
+ "start": 1693
2584
2486
  },
2585
2487
  {
2586
2488
  "name": "<impl Packable for u128>::pack",
2587
- "start": 1788
2489
+ "start": 1848
2588
2490
  },
2589
2491
  {
2590
2492
  "name": "<impl Packable for u128>::unpack",
2591
- "start": 1890
2493
+ "start": 1950
2592
2494
  },
2593
2495
  {
2594
2496
  "name": "<impl Packable for Field>::pack",
2595
- "start": 2048
2497
+ "start": 2108
2596
2498
  },
2597
2499
  {
2598
2500
  "name": "<impl Packable for Field>::unpack",
2599
- "start": 2141
2501
+ "start": 2201
2600
2502
  },
2601
2503
  {
2602
2504
  "name": "<impl Packable for i8>::pack",
2603
- "start": 2285
2505
+ "start": 2345
2604
2506
  },
2605
2507
  {
2606
2508
  "name": "<impl Packable for i8>::unpack",
2607
- "start": 2393
2509
+ "start": 2453
2608
2510
  },
2609
2511
  {
2610
2512
  "name": "<impl Packable for i16>::pack",
2611
- "start": 2551
2513
+ "start": 2611
2612
2514
  },
2613
2515
  {
2614
2516
  "name": "<impl Packable for i16>::unpack",
2615
- "start": 2660
2517
+ "start": 2720
2616
2518
  },
2617
2519
  {
2618
2520
  "name": "<impl Packable for i32>::pack",
2619
- "start": 2820
2521
+ "start": 2880
2620
2522
  },
2621
2523
  {
2622
2524
  "name": "<impl Packable for i32>::unpack",
2623
- "start": 2929
2525
+ "start": 2989
2624
2526
  },
2625
2527
  {
2626
2528
  "name": "<impl Packable for i64>::pack",
2627
- "start": 3089
2529
+ "start": 3149
2628
2530
  },
2629
2531
  {
2630
2532
  "name": "<impl Packable for i64>::unpack",
2631
- "start": 3198
2533
+ "start": 3258
2534
+ },
2535
+ {
2536
+ "name": "<impl Packable for super::point::EmbeddedCurvePoint>::pack",
2537
+ "start": 3427
2538
+ },
2539
+ {
2540
+ "name": "<impl Packable for super::point::EmbeddedCurvePoint>::unpack",
2541
+ "start": 3509
2632
2542
  },
2633
2543
  {
2634
2544
  "name": "<impl Packable for [T; M]>::pack",
2635
- "start": 3407
2545
+ "start": 3720
2636
2546
  },
2637
2547
  {
2638
2548
  "name": "<impl Packable for [T; M]>::unpack",
2639
- "start": 3769
2549
+ "start": 4082
2640
2550
  },
2641
2551
  {
2642
2552
  "name": "test_u16_packing",
2643
- "start": 4014
2553
+ "start": 4327
2644
2554
  },
2645
2555
  {
2646
2556
  "name": "test_i8_packing",
2647
- "start": 4110
2557
+ "start": 4423
2648
2558
  },
2649
2559
  {
2650
2560
  "name": "test_i16_packing",
2651
- "start": 4206
2561
+ "start": 4519
2652
2562
  },
2653
2563
  {
2654
2564
  "name": "test_i32_packing",
2655
- "start": 4304
2565
+ "start": 4617
2656
2566
  },
2657
2567
  {
2658
2568
  "name": "test_i64_packing",
2659
- "start": 4402
2569
+ "start": 4715
2660
2570
  }
2661
2571
  ],
2662
2572
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr",
2663
- "source": "use crate::traits::Packable;\n\nglobal BOOL_PACKED_LEN: u32 = 1;\nglobal U8_PACKED_LEN: u32 = 1;\nglobal U16_PACKED_LEN: u32 = 1;\nglobal U32_PACKED_LEN: u32 = 1;\nglobal U64_PACKED_LEN: u32 = 1;\nglobal U128_PACKED_LEN: u32 = 1;\nglobal FIELD_PACKED_LEN: u32 = 1;\nglobal I8_PACKED_LEN: u32 = 1;\nglobal I16_PACKED_LEN: u32 = 1;\nglobal I32_PACKED_LEN: u32 = 1;\nglobal I64_PACKED_LEN: u32 = 1;\n\nimpl Packable for bool {\n let N: u32 = BOOL_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> bool {\n (fields[0] as u8) % 2 != 0\n }\n}\n\nimpl Packable for u8 {\n let N: u32 = U8_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u8\n }\n}\n\nimpl Packable for u16 {\n let N: u32 = U16_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u16\n }\n}\n\nimpl Packable for u32 {\n let N: u32 = U32_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u32\n }\n}\n\nimpl Packable for u64 {\n let N: u32 = U64_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u64\n }\n}\n\nimpl Packable for u128 {\n let N: u32 = U128_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u128\n }\n}\n\nimpl Packable for Field {\n let N: u32 = FIELD_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0]\n }\n}\n\nimpl Packable for i8 {\n let N: u32 = I8_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u8 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u8 as i8\n }\n}\n\nimpl Packable for i16 {\n let N: u32 = I16_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u16 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u16 as i16\n }\n}\n\nimpl Packable for i32 {\n let N: u32 = I32_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u32 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u32 as i32\n }\n}\n\nimpl Packable for i64 {\n let N: u32 = I64_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u64 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u64 as i64\n }\n}\n\nimpl<T, let M: u32> Packable for [T; M]\nwhere\n T: Packable,\n{\n let N: u32 = M * <T as Packable>::N;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n let mut result: [Field; Self::N] = std::mem::zeroed();\n for i in 0..M {\n let serialized = self[i].pack();\n for j in 0..<T as Packable>::N {\n result[i * <T as Packable>::N + j] = serialized[j];\n }\n }\n result\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n let mut reader = crate::utils::reader::Reader::new(fields);\n let result: [T; M] = std::mem::zeroed();\n reader.read_struct_array::<T, <T as Packable>::N, M>(Packable::unpack, result)\n }\n}\n\n#[test]\nfn test_u16_packing() {\n let a: u16 = 10;\n assert_eq(a, u16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i8_packing() {\n let a: i8 = -10;\n assert_eq(a, i8::unpack(a.pack()));\n}\n\n#[test]\nfn test_i16_packing() {\n let a: i16 = -10;\n assert_eq(a, i16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i32_packing() {\n let a: i32 = -10;\n assert_eq(a, i32::unpack(a.pack()));\n}\n\n#[test]\nfn test_i64_packing() {\n let a: i64 = -10;\n assert_eq(a, i64::unpack(a.pack()));\n}\n"
2573
+ "source": "use crate::traits::{Deserialize, Packable, Serialize};\n\nglobal BOOL_PACKED_LEN: u32 = 1;\nglobal U8_PACKED_LEN: u32 = 1;\nglobal U16_PACKED_LEN: u32 = 1;\nglobal U32_PACKED_LEN: u32 = 1;\nglobal U64_PACKED_LEN: u32 = 1;\nglobal U128_PACKED_LEN: u32 = 1;\nglobal FIELD_PACKED_LEN: u32 = 1;\nglobal I8_PACKED_LEN: u32 = 1;\nglobal I16_PACKED_LEN: u32 = 1;\nglobal I32_PACKED_LEN: u32 = 1;\nglobal I64_PACKED_LEN: u32 = 1;\nglobal POINT_PACKED_LEN: u32 = 2;\n\nimpl Packable for bool {\n let N: u32 = BOOL_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> bool {\n (fields[0] as u8) % 2 != 0\n }\n}\n\nimpl Packable for u8 {\n let N: u32 = U8_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u8\n }\n}\n\nimpl Packable for u16 {\n let N: u32 = U16_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u16\n }\n}\n\nimpl Packable for u32 {\n let N: u32 = U32_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u32\n }\n}\n\nimpl Packable for u64 {\n let N: u32 = U64_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u64\n }\n}\n\nimpl Packable for u128 {\n let N: u32 = U128_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u128\n }\n}\n\nimpl Packable for Field {\n let N: u32 = FIELD_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0]\n }\n}\n\nimpl Packable for i8 {\n let N: u32 = I8_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u8 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u8 as i8\n }\n}\n\nimpl Packable for i16 {\n let N: u32 = I16_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u16 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u16 as i16\n }\n}\n\nimpl Packable for i32 {\n let N: u32 = I32_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u32 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u32 as i32\n }\n}\n\nimpl Packable for i64 {\n let N: u32 = I64_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u64 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u64 as i64\n }\n}\n\nimpl Packable for super::point::EmbeddedCurvePoint {\n let N: u32 = POINT_PACKED_LEN;\n fn pack(self) -> [Field; Self::N] {\n self.serialize()\n }\n\n fn unpack(packed: [Field; Self::N]) -> Self {\n Self::deserialize(packed)\n }\n}\n\nimpl<T, let M: u32> Packable for [T; M]\nwhere\n T: Packable,\n{\n let N: u32 = M * <T as Packable>::N;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n let mut result: [Field; Self::N] = std::mem::zeroed();\n for i in 0..M {\n let serialized = self[i].pack();\n for j in 0..<T as Packable>::N {\n result[i * <T as Packable>::N + j] = serialized[j];\n }\n }\n result\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n let mut reader = crate::utils::reader::Reader::new(fields);\n let result: [T; M] = std::mem::zeroed();\n reader.read_struct_array::<T, <T as Packable>::N, M>(Packable::unpack, result)\n }\n}\n\n#[test]\nfn test_u16_packing() {\n let a: u16 = 10;\n assert_eq(a, u16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i8_packing() {\n let a: i8 = -10;\n assert_eq(a, i8::unpack(a.pack()));\n}\n\n#[test]\nfn test_i16_packing() {\n let a: i16 = -10;\n assert_eq(a, i16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i32_packing() {\n let a: i32 = -10;\n assert_eq(a, i32::unpack(a.pack()));\n}\n\n#[test]\nfn test_i64_packing() {\n let a: i64 = -10;\n assert_eq(a, i64::unpack(a.pack()));\n}\n"
2664
2574
  },
2665
2575
  "40": {
2666
2576
  "function_locations": [
@@ -4138,187 +4048,179 @@
4138
4048
  "function_locations": [
4139
4049
  {
4140
4050
  "name": "PrivateContext::new",
4141
- "start": 10178
4051
+ "start": 10172
4142
4052
  },
4143
4053
  {
4144
4054
  "name": "PrivateContext::maybe_msg_sender",
4145
- "start": 12362
4055
+ "start": 12356
4146
4056
  },
4147
4057
  {
4148
4058
  "name": "PrivateContext::this_address",
4149
- "start": 13069
4059
+ "start": 13063
4150
4060
  },
4151
4061
  {
4152
4062
  "name": "PrivateContext::chain_id",
4153
- "start": 13574
4063
+ "start": 13568
4154
4064
  },
4155
4065
  {
4156
4066
  "name": "PrivateContext::version",
4157
- "start": 14157
4067
+ "start": 14151
4158
4068
  },
4159
4069
  {
4160
4070
  "name": "PrivateContext::gas_settings",
4161
- "start": 14710
4071
+ "start": 14704
4162
4072
  },
4163
4073
  {
4164
4074
  "name": "PrivateContext::selector",
4165
- "start": 15753
4075
+ "start": 15747
4166
4076
  },
4167
4077
  {
4168
4078
  "name": "PrivateContext::get_args_hash",
4169
- "start": 16475
4079
+ "start": 16469
4170
4080
  },
4171
4081
  {
4172
4082
  "name": "PrivateContext::push_note_hash",
4173
- "start": 18143
4083
+ "start": 18137
4174
4084
  },
4175
4085
  {
4176
4086
  "name": "PrivateContext::push_nullifier",
4177
- "start": 19319
4087
+ "start": 19313
4178
4088
  },
4179
4089
  {
4180
4090
  "name": "PrivateContext::push_nullifier_for_note_hash",
4181
- "start": 21088
4091
+ "start": 21082
4182
4092
  },
4183
4093
  {
4184
4094
  "name": "PrivateContext::get_anchor_block_header",
4185
- "start": 22384
4095
+ "start": 22378
4186
4096
  },
4187
4097
  {
4188
4098
  "name": "PrivateContext::get_block_header_at",
4189
- "start": 24445
4099
+ "start": 24439
4190
4100
  },
4191
4101
  {
4192
4102
  "name": "PrivateContext::set_return_hash",
4193
- "start": 24874
4103
+ "start": 24868
4194
4104
  },
4195
4105
  {
4196
4106
  "name": "PrivateContext::finish",
4197
- "start": 25369
4107
+ "start": 25363
4198
4108
  },
4199
4109
  {
4200
4110
  "name": "PrivateContext::set_as_fee_payer",
4201
- "start": 27988
4111
+ "start": 27982
4202
4112
  },
4203
4113
  {
4204
4114
  "name": "PrivateContext::in_revertible_phase",
4205
- "start": 28178
4115
+ "start": 28172
4206
4116
  },
4207
4117
  {
4208
4118
  "name": "PrivateContext::end_setup",
4209
- "start": 30490
4119
+ "start": 30484
4210
4120
  },
4211
4121
  {
4212
4122
  "name": "PrivateContext::set_expiration_timestamp",
4213
- "start": 33755
4123
+ "start": 33749
4214
4124
  },
4215
4125
  {
4216
4126
  "name": "PrivateContext::assert_note_exists",
4217
- "start": 35150
4127
+ "start": 35144
4218
4128
  },
4219
4129
  {
4220
4130
  "name": "PrivateContext::assert_nullifier_exists",
4221
- "start": 37786
4131
+ "start": 37780
4222
4132
  },
4223
4133
  {
4224
4134
  "name": "PrivateContext::request_nhk_app",
4225
- "start": 39883
4135
+ "start": 39877
4226
4136
  },
4227
4137
  {
4228
4138
  "name": "PrivateContext::request_ovsk_app",
4229
- "start": 41529
4139
+ "start": 41523
4230
4140
  },
4231
4141
  {
4232
4142
  "name": "PrivateContext::request_sk_app",
4233
- "start": 42943
4143
+ "start": 43244
4234
4144
  },
4235
4145
  {
4236
4146
  "name": "PrivateContext::message_portal",
4237
- "start": 46161
4147
+ "start": 46549
4238
4148
  },
4239
4149
  {
4240
4150
  "name": "PrivateContext::consume_l1_to_l2_message",
4241
- "start": 48043
4151
+ "start": 48431
4242
4152
  },
4243
4153
  {
4244
4154
  "name": "PrivateContext::emit_private_log_unsafe",
4245
- "start": 52601
4246
- },
4247
- {
4248
- "name": "PrivateContext::emit_private_log_vec_unsafe",
4249
- "start": 53321
4155
+ "start": 52551
4250
4156
  },
4251
4157
  {
4252
4158
  "name": "PrivateContext::emit_raw_note_log_unsafe",
4253
- "start": 54884
4254
- },
4255
- {
4256
- "name": "PrivateContext::emit_raw_note_log_vec_unsafe",
4257
- "start": 55706
4159
+ "start": 54008
4258
4160
  },
4259
4161
  {
4260
4162
  "name": "PrivateContext::emit_contract_class_log",
4261
- "start": 56314
4163
+ "start": 54616
4262
4164
  },
4263
4165
  {
4264
4166
  "name": "PrivateContext::call_private_function",
4265
- "start": 60873
4167
+ "start": 59175
4266
4168
  },
4267
4169
  {
4268
4170
  "name": "PrivateContext::static_call_private_function",
4269
- "start": 62075
4171
+ "start": 60377
4270
4172
  },
4271
4173
  {
4272
4174
  "name": "PrivateContext::call_private_function_no_args",
4273
- "start": 63090
4175
+ "start": 61392
4274
4176
  },
4275
4177
  {
4276
4178
  "name": "PrivateContext::static_call_private_function_no_args",
4277
- "start": 63943
4179
+ "start": 62245
4278
4180
  },
4279
4181
  {
4280
4182
  "name": "PrivateContext::call_private_function_with_args_hash",
4281
- "start": 64921
4183
+ "start": 63223
4282
4184
  },
4283
4185
  {
4284
4186
  "name": "PrivateContext::call_public_function",
4285
- "start": 68820
4187
+ "start": 67122
4286
4188
  },
4287
4189
  {
4288
4190
  "name": "PrivateContext::static_call_public_function",
4289
- "start": 70087
4191
+ "start": 68389
4290
4192
  },
4291
4193
  {
4292
4194
  "name": "PrivateContext::call_public_function_no_args",
4293
- "start": 71106
4195
+ "start": 69408
4294
4196
  },
4295
4197
  {
4296
4198
  "name": "PrivateContext::static_call_public_function_no_args",
4297
- "start": 72005
4199
+ "start": 70307
4298
4200
  },
4299
4201
  {
4300
4202
  "name": "PrivateContext::call_public_function_with_calldata_hash",
4301
- "start": 73194
4203
+ "start": 71496
4302
4204
  },
4303
4205
  {
4304
4206
  "name": "PrivateContext::set_public_teardown_function",
4305
- "start": 75722
4207
+ "start": 74024
4306
4208
  },
4307
4209
  {
4308
4210
  "name": "PrivateContext::set_public_teardown_function_with_calldata_hash",
4309
- "start": 76993
4211
+ "start": 75295
4310
4212
  },
4311
4213
  {
4312
4214
  "name": "PrivateContext::next_counter",
4313
- "start": 82397
4215
+ "start": 80699
4314
4216
  },
4315
4217
  {
4316
4218
  "name": "<impl Empty for PrivateContext>::empty",
4317
- "start": 82566
4219
+ "start": 80868
4318
4220
  }
4319
4221
  ],
4320
4222
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/context/private_context.nr",
4321
- "source": "use crate::{\n context::{inputs::PrivateContextInputs, NoteExistenceRequest, NullifierExistenceRequest, ReturnsHash},\n hash::{hash_args, hash_calldata_array},\n keys::constants::{NULLIFIER_INDEX, NUM_KEY_TYPES, OUTGOING_INDEX, public_key_domain_separators},\n messaging::process_l1_to_l2_message,\n oracle::{\n block_header::get_block_header_at,\n call_private_function::call_private_function_internal,\n execution_cache,\n key_validation_request::get_key_validation_request,\n logs::notify_created_contract_class_log,\n notes::notify_nullified_note,\n nullifiers::notify_created_nullifier,\n public_call::assert_valid_public_call_data,\n tx_phase::{is_execution_in_revertible_phase, notify_revertible_phase_start},\n },\n};\nuse crate::logging::aztecnr_trace_log_format;\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 note_hash::NoteHash,\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 validation_requests::{KeyValidationRequest, KeyValidationRequestAndSeparator},\n },\n address::{AztecAddress, EthAddress},\n constants::{\n CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, MAX_CONTRACT_CLASS_LOGS_PER_CALL, MAX_ENQUEUED_CALLS_PER_CALL,\n MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,\n MAX_NOTE_HASHES_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL, MAX_TX_LIFETIME,\n NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_CIPHERTEXT_LEN,\n },\n hash::compute_contract_class_log_hash,\n messaging::l2_to_l1_message::L2ToL1Message,\n side_effect::{Counted, scoped::Scoped},\n traits::{Empty, Hash, ToField},\n utils::arrays::{ClaimedLengthArray, trimmed_array_length_hint},\n};\n\n/// # PrivateContext\n///\n/// The **main interface** between an #[external(\"private\")] function and the Aztec blockchain.\n///\n/// An instance of the PrivateContext is initialized automatically at the outset of every private function, within the\n/// #[external(\"private\")] macro, so you'll never need to consciously instantiate this yourself.\n///\n/// The instance is always named `context`, and it is always be available within the body of every\n/// #[external(\"private\")] function in your smart contract.\n///\n/// > For those used to \"vanilla\" Noir, it might be jarring to have access to > `context` without seeing a declaration\n/// `let context = PrivateContext::new(...)` > within the body of your function. This is just a consequence of using >\n/// macros to tidy-up verbose boilerplate. You can use `nargo expand` to > expand all macros, if you dare.\n///\n/// Typical usage for a smart contract developer will be to call getter methods of the PrivateContext.\n///\n/// _Pushing_ data and requests to the context is mostly handled within aztec-nr's own functions, so typically a smart\n/// contract developer won't need to call any setter methods directly.\n///\n/// > Advanced users might occasionally wish to push data to the context > directly for lower-level control. If you\n/// find yourself doing this, please > open an issue on GitHub to describe your use case: it might be that > new\n/// functionality should be added to aztec-nr.\n///\n/// ## Responsibilities\n/// - Exposes contextual data to a private function:\n/// - Data relating to how this private function was called.\n/// - msg_sender\n/// - this_address - (the contract address of the private function being executed)\n/// - See `CallContext` for more data.\n/// - Data relating to the transaction in which this private function is being executed.\n/// - chain_id\n/// - version\n/// - gas_settings\n/// - Provides state access:\n/// - Access to the \"Anchor block\" header. Recall, a private function cannot read from the \"current\" block header, but\n/// must read from some historical block header, because as soon as private function execution begins (asynchronously,\n/// on a user's device), the public state of the chain (the \"current state\") will have progressed forward. We call this\n/// reference the \"Anchor block\". See `BlockHeader`.\n/// - Enables consumption of L1->L2 messages.\n/// - Enables calls to functions of other smart contracts:\n/// - Private function calls\n/// - Enqueueing of public function call requests (Since public functions are executed at a later time, by a block\n/// proposer, we say they are \"enqueued\").\n/// - Writes data to the blockchain:\n/// - New notes\n/// - New nullifiers\n/// - Private logs (for sending encrypted note contents or encrypted events)\n/// - New L2->L1 messages.\n/// - Provides args to the private function (handled by the #[external(\"private\")] macro).\n/// - Returns the return values of this private function (handled by the\n/// #[external(\"private\")] macro).\n/// - Makes Key Validation Requests.\n/// - Private functions are not allowed to see master secret keys, because we do not trust them. They are instead given\n/// \"app-siloed\" secret keys with a claim that they relate to a master public key. They can then request validation of\n/// this claim, by making a \"key validation request\" to the protocol's kernel circuits (which _are_ allowed to see\n/// certain master secret keys).\n///\n/// ## Advanced Responsibilities\n///\n/// - Ultimately, the PrivateContext is responsible for constructing the PrivateCircuitPublicInputs of the private\n/// function being executed. All private functions on Aztec must have public inputs which adhere to the rigid layout of\n/// the PrivateCircuitPublicInputs, in order to be compatible with the protocol's kernel circuits. A well-known\n/// misnomer:\n/// - \"public inputs\" contain both inputs and outputs of this function.\n/// - By \"outputs\" we mean a lot more side-effects than just the \"return values\" of the function.\n/// - Most of the so-called \"public inputs\" are kept _private_, and never leak to the outside world, because they are\n/// 'swallowed' by the protocol's kernel circuits before the tx is sent to the network. Only the following are exposed\n/// to the outside world:\n/// - New note_hashes\n/// - New nullifiers\n/// - New private logs\n/// - New L2->L1 messages\n/// - New enqueued public function call requests All the above-listed arrays of side-effects can be padded by the\n/// user's wallet (through instructions to the kernel circuits, via the PXE) to obscure their true lengths.\n///\n/// ## Syntax Justification\n///\n/// Both user-defined functions _and_ most functions in aztec-nr need access to the PrivateContext instance to\n/// read/write data. This is why you'll see the arguably-ugly pervasiveness of the \"context\" throughout your smart\n/// contract and the aztec-nr library. For example, `&mut context` is prevalent. In some languages, you can access and\n/// mutate a global variable (such as a PrivateContext instance) from a function without polluting the function's\n/// parameters. With Noir, a function must explicitly pass control of a mutable variable to another function, by\n/// reference. Since many functions in aztec-nr need to be able to push new data to the PrivateContext, they need to be\n/// handed a mutable reference _to_ the context as a parameter. For example, `Context` is prevalent as a generic\n/// parameter, to give better type safety at compile time. Many `aztec-nr` functions don't make sense if they're called\n/// in a particular runtime (private, public or utility), and so are intentionally only implemented over certain\n/// [Private|Public|Utility]Context structs. This gives smart contract developers a much faster feedback loop if\n/// they're making a mistake, as an error will be thrown by the LSP or when they compile their contract.\n///\n#[derive(Eq)]\npub struct PrivateContext {\n // docs:start:private-context\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(crate) note_hash_read_requests: BoundedVec<Scoped<Counted<Field>>, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>,\n pub(crate) nullifier_read_requests: BoundedVec<Scoped<Counted<Field>>, MAX_NULLIFIER_READ_REQUESTS_PER_CALL>,\n key_validation_requests_and_separators: BoundedVec<KeyValidationRequestAndSeparator, MAX_KEY_VALIDATION_REQUESTS_PER_CALL>,\n\n pub note_hashes: BoundedVec<Counted<NoteHash>, MAX_NOTE_HASHES_PER_CALL>,\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 // docs:end:private-context\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 // Contains the last key validation request for each key type. This is used to cache the last request and avoid\n // fetching the same request multiple times. The index of the array corresponds to the key type (0 nullifier, 1\n // incoming, 2 outgoing, 3 tagging).\n pub last_key_validation_requests: [Option<KeyValidationRequest>; NUM_KEY_TYPES],\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.timestamp() + MAX_TX_LIFETIME,\n note_hash_read_requests: BoundedVec::new(),\n nullifier_read_requests: BoundedVec::new(),\n key_validation_requests_and_separators: BoundedVec::new(),\n note_hashes: 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 last_key_validation_requests: [Option::none(); NUM_KEY_TYPES],\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.\n ///\n /// This is similar to `msg.sender` in Solidity (hence the name).\n ///\n /// Important Note: Since Aztec doesn't have a concept of an EoA (Externally-owned Account), the msg_sender is\n /// \"none\" for the first function call of every transaction. The first function call of a tx is likely to be a call\n /// to the user's account contract, so this quirk will most often be handled by account contract developers.\n ///\n /// # Returns\n /// * `Option<AztecAddress>` - The address of the smart contract that called this function (be it an app contract\n /// or a user's account contract). Returns `Option<AztecAddress>::none` for the first function call of the tx. No\n /// other _private_ function calls in the tx will have a `none` msg_sender, but _public_ function calls might (see\n /// the PublicContext).\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 ///\n /// This is equivalent to `address(this)` in Solidity (hence the name). Use this to identify the current contract's\n /// address, commonly needed for access control or when interacting with other contracts.\n ///\n /// # Returns\n /// * `AztecAddress` - The contract address of the current function being executed.\n ///\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 ///\n /// This is similar to `block.chainid` in Solidity. Returns the unique identifier for the blockchain network this\n /// transaction is executing on.\n ///\n /// Helps prevent cross-chain replay attacks. Useful if implementing multi-chain contract logic.\n ///\n /// # Returns\n /// * `Field` - The chain ID as a field element\n ///\n pub fn chain_id(self) -> Field {\n self.inputs.tx_context.chain_id\n }\n\n /// Returns the Aztec protocol version that this transaction is executing under. Different versions may have\n /// different rules, opcodes, or cryptographic primitives.\n ///\n /// This is similar to how Ethereum has different EVM versions.\n ///\n /// Useful for forward/backward compatibility checks\n ///\n /// Not to be confused with contract versions; this is the protocol version.\n ///\n /// # Returns\n /// * `Field` - The protocol version as a field element\n ///\n pub fn version(self) -> Field {\n self.inputs.tx_context.version\n }\n\n /// Returns the gas settings for the current transaction.\n ///\n /// This provides information about gas limits and pricing for the transaction, similar to `tx.gasprice` and gas\n /// limits in Ethereum. However, Aztec has a more sophisticated gas model with separate accounting for L2\n /// computation and data availability (DA) costs.\n ///\n /// # Returns\n /// * `GasSettings` - Struct containing gas limits and fee information\n ///\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 ///\n /// Low-level function: Ordinarily, smart contract developers will not need to access this.\n ///\n /// This is similar to `msg.sig` in Solidity, which returns the first 4 bytes of the function signature. In Aztec,\n /// the selector uniquely identifies which function within the contract is being called.\n ///\n /// # Returns\n /// * `FunctionSelector` - The 4-byte function identifier\n ///\n /// # Advanced\n /// Only #[external(\"private\")] functions have a function selector as a protocol- enshrined concept. The function\n /// selectors of private functions are baked into the preimage of the contract address, and are used by the\n /// protocol's kernel circuits to identify each private function and ensure the correct one is being executed.\n ///\n /// Used internally for function dispatch and call verification.\n ///\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 ///\n /// Very low-level function: You shouldn't need to call this. The #[external(\"private\")] macro calls this, and it\n /// makes the arguments neatly available to the body of your private function.\n ///\n /// # Returns\n /// * `Field` - Hash of the function arguments\n ///\n /// # Advanced\n /// * Arguments are hashed to reduce proof size and verification time\n /// * Enables efficient argument passing in recursive function calls\n /// * The hash can be used to retrieve the original arguments from the PXE.\n ///\n pub fn get_args_hash(self) -> Field {\n self.args_hash\n }\n\n /// Pushes a new note_hash to the Aztec blockchain's global Note Hash Tree (a state tree).\n ///\n /// A note_hash is a commitment to a piece of private state.\n ///\n /// Low-level function: Ordinarily, smart contract developers will not need to manually call this. Aztec-nr's state\n /// variables (see `../state_vars/`) are designed to understand when to create and push new note hashes.\n ///\n /// # Arguments\n /// * `note_hash` - The new note_hash.\n ///\n /// # Advanced\n /// From here, the protocol's kernel circuits will take over and insert the note_hash into the protocol's \"note\n /// hash tree\" (in the Base Rollup circuit). Before insertion, the protocol will:\n /// - \"Silo\" the `note_hash` with the contract address of this function, to yield a `siloed_note_hash`. This\n /// prevents state collisions between different smart contracts.\n /// - Ensure uniqueness of the `siloed_note_hash`, to prevent Faerie-Gold attacks, by hashing the\n /// `siloed_note_hash` with a unique value, to yield a `unique_siloed_note_hash` (see the protocol spec for more).\n ///\n /// In addition to calling this function, aztec-nr provides the contents of the newly-created note to the PXE, via\n /// the `notify_created_note` oracle.\n ///\n /// > Advanced users might occasionally wish to push data to the context > directly for lower-level control. If you\n /// find yourself doing this, > please open an issue on GitHub to describe your use case: it might be > that new\n /// functionality should be added to aztec-nr.\n ///\n pub fn push_note_hash(&mut self, note_hash: Field) {\n self.note_hashes.push(Counted::new(note_hash, self.next_counter()));\n }\n\n /// Creates a new [nullifier](crate::nullifier).\n ///\n /// ## Safety\n ///\n /// This is a low-level function that must be used with great care to avoid subtle corruption of contract state.\n /// Instead of calling this function, consider using the higher-level [`crate::state_vars::SingleUseClaim`].\n ///\n /// In particular, callers must ensure all nullifiers created by a contract are properly domain-separated, so that\n /// unrelated components don't interfere with one another (e.g. a transaction nullifier accidentally marking a\n /// variable as initialized). Only [`PrivateContext::push_nullifier_for_note_hash`] should be used for note\n /// nullifiers, never this one.\n ///\n /// ## Advanced\n ///\n /// The raw `nullifier` is not what is inserted into the Aztec state tree: it will be first siloed by contract\n /// address via [`crate::protocol::hash::compute_siloed_nullifier`] in order to prevent accidental or malicious\n /// interference of nullifiers from different contracts.\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 /// Creates a new [nullifier](crate::nullifier) associated with a note.\n ///\n /// This is a variant of [`PrivateContext::push_nullifier`] that is used for note nullifiers, i.e. nullifiers that\n /// correspond to a note. If a note and its nullifier are created in the same transaction, then the private kernels\n /// will 'squash' these values, deleting them both as if they never existed and reducing transaction fees.\n ///\n /// The `nullification_note_hash` must be the result of calling\n /// [`crate::note::utils::compute_confirmed_note_hash_for_nullification`] for pending notes, and `0` for settled\n /// notes (which cannot be squashed).\n ///\n /// ## Safety\n ///\n /// This is a low-level function that must be used with great care to avoid subtle corruption of contract state.\n /// Instead of calling this function, consider using the higher-level [`crate::note::lifecycle::destroy_note`].\n ///\n /// The precautions listed for [`PrivateContext::push_nullifier`] apply here as well, and callers should\n /// additionally ensure `nullification_note_hash` corresponds to a note emitted by this contract, with its hash\n /// computed in the same transaction execution phase as the call to this function. Finally, only this function\n /// should be used for note nullifiers, never [`PrivateContext::push_nullifier`].\n ///\n /// Failure to do these things can result in unprovable contexts, accidental deletion of notes, or double-spend\n /// attacks.\n pub fn push_nullifier_for_note_hash(&mut self, nullifier: Field, nullification_note_hash: Field) {\n let nullifier_counter = self.next_counter();\n notify_nullified_note(nullifier, nullification_note_hash, nullifier_counter);\n self.nullifiers.push(Nullifier { value: nullifier, note_hash: nullification_note_hash }.count(\n nullifier_counter,\n ));\n }\n\n /// Returns the anchor block header - the historical block header that this private function is reading from.\n ///\n /// A private function CANNOT read from the \"current\" block header, but must read from some older block header,\n /// because as soon as private function execution begins (asynchronously, on a user's device), the public state of\n /// the chain (the \"current state\") will have progressed forward.\n ///\n /// # Returns\n /// * `BlockHeader` - The anchor block header.\n ///\n /// # Advanced\n /// * All private functions of a tx read from the same anchor block header.\n /// * The protocol asserts that the `expiration_timestamp` of every tx is at most 24 hours beyond the timestamp of\n /// the tx's chosen anchor block header. This enables the network's nodes to safely prune old txs from the mempool.\n /// Therefore, the chosen block header _must_ be one from within the last 24 hours.\n ///\n pub fn get_anchor_block_header(self) -> BlockHeader {\n self.anchor_block_header\n }\n\n /// Returns the header of any historical block at or before the anchor block.\n ///\n /// This enables private contracts to access information from even older blocks than the anchor block header.\n ///\n /// Useful for time-based contract logic that needs to compare against multiple historical points.\n ///\n /// # Arguments\n /// * `block_number` - The block number to retrieve (must be <= anchor block number)\n ///\n /// # Returns\n /// * `BlockHeader` - The header of the requested historical block\n ///\n /// # Advanced\n /// This function uses an oracle to fetch block header data from the user's PXE. Depending on how much blockchain\n /// data the user's PXE has been set up to store, this might require a query from the PXE to another Aztec node to\n /// get the data. > This is generally true of all oracle getters (see `../oracle`).\n ///\n /// Each block header gets hashed and stored as a leaf in the protocol's Archive Tree. In fact, the i-th block\n /// header gets stored at the i-th leaf index of the Archive Tree. Behind the scenes, this `get_block_header_at`\n /// function will add Archive Tree merkle-membership constraints (~3k) to your smart contract function's circuit,\n /// to prove existence of the block header in the Archive Tree.\n ///\n /// Note: we don't do any caching, so avoid making duplicate calls for the same block header, because each call\n /// will add duplicate constraints.\n ///\n /// Calling this function is more expensive (constraint-wise) than getting the anchor block header (via\n /// `get_block_header`). This is because the anchor block's merkle membership proof is handled by Aztec's protocol\n /// circuits, and is only performed once for the entire tx because all private functions of a tx share a common\n /// anchor block header. Therefore, the cost (constraint-wise) of calling `get_block_header` is effectively free.\n ///\n pub fn get_block_header_at(self, block_number: u32) -> BlockHeader {\n get_block_header_at(block_number, self)\n }\n\n /// Sets the hash of the return values for this private function.\n ///\n /// Very low-level function: this is called by the #[external(\"private\")] macro.\n ///\n /// # Arguments\n /// * `serialized_return_values` - The serialized return values as a field array\n ///\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, to ensure compatibility with the protocol's\n /// kernel circuits.\n ///\n /// Very low-level function: This function is automatically called by the #[external(\"private\")] macro.\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::from_bounded_vec(self.note_hash_read_requests),\n nullifier_read_requests: ClaimedLengthArray::from_bounded_vec(self.nullifier_read_requests),\n key_validation_requests_and_separators: ClaimedLengthArray::from_bounded_vec(\n self.key_validation_requests_and_separators,\n ),\n note_hashes: ClaimedLengthArray::from_bounded_vec(self.note_hashes),\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(self.contract_class_logs_hashes),\n anchor_block_header: self.anchor_block_header,\n tx_context: self.inputs.tx_context,\n expected_non_revertible_side_effect_counter: self.expected_non_revertible_side_effect_counter,\n expected_revertible_side_effect_counter: self.expected_revertible_side_effect_counter,\n }\n }\n\n /// Designates this contract as the fee payer for the transaction.\n ///\n /// Unlike Ethereum, where the transaction sender always pays fees, Aztec allows any contract to voluntarily pay\n /// transaction fees. This enables patterns like sponsored transactions or fee abstraction where users don't need\n /// to hold fee-juice themselves. (Fee juice is a fee-paying asset for Aztec).\n ///\n /// Only one contract per transaction can declare itself as the fee payer, and it must have sufficient fee-juice\n /// balance (>= the gas limits specified in the TxContext) by the time we reach the public setup phase of the tx.\n ///\n pub fn set_as_fee_payer(&mut self) {\n aztecnr_trace_log_format!(\"Setting {0} as fee payer\")([self.this_address().to_field()]);\n self.is_fee_payer = true;\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 = unsafe { is_execution_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 /// Declares the end of the \"setup phase\" of this tx.\n ///\n /// Only one function per tx can declare the end of the setup phase.\n ///\n /// Niche function: Only wallet developers and paymaster contract developers (aka Fee-payment contracts) will need\n /// to make use of this function.\n ///\n /// Aztec supports a three-phase execution model: setup, app logic, teardown. The phases exist to enable a fee\n /// payer to take on the risk of paying a transaction fee, safe in the knowledge that their payment (in whatever\n /// token or method the user chooses) will succeed, regardless of whether the app logic will succeed. The \"setup\"\n /// phase enables such a payment to be made, because the setup phase _cannot revert_: a reverting function within\n /// the setup phase would result in an invalid block which cannot be proven. Any side-effects generated during that\n /// phase are guaranteed to be inserted into Aztec's state trees (except for squashed notes & nullifiers, of\n /// course).\n ///\n /// Even though the end of the setup phase is declared within a private function, you might have noticed that\n /// _public_ functions can also execute within the setup phase. This is because any public function calls which\n /// were enqueued _within the setup phase_ by a private function are considered part of the setup phase.\n ///\n /// # Advanced\n /// * Sets the minimum revertible side effect counter of this tx to be the PrivateContext's _current_ side effect\n /// counter.\n ///\n pub fn end_setup(&mut self) {\n // We bump the counter twice: once so that `min_revertible_side_effect_counter` sits strictly above any\n // non-revertible side effect counter (including queries made via `in_revertible_phase` before this call), and\n // once more so that the next revertible side effect counter is strictly greater than\n // `min_revertible_side_effect_counter`. This ensures `min_revertible_side_effect_counter` occupies a gap that\n // no side effect takes, which the kernel relies on when validating the phase split.\n self.side_effect_counter += 1;\n self.min_revertible_side_effect_counter = self.side_effect_counter;\n self.side_effect_counter += 1;\n\n aztecnr_trace_log_format!(\n \"Ending setup, minimum revertible side effect counter is {0}\",\n )(\n [self.min_revertible_side_effect_counter as Field],\n );\n notify_revertible_phase_start(self.min_revertible_side_effect_counter);\n }\n\n /// Sets a deadline (an \"include-by timestamp\") for when this transaction must be included in a block.\n ///\n /// Other functions in this tx might call this setter with differing values for the include-by timestamp. To ensure\n /// that all functions' deadlines are met, the _minimum_ of all these include-by timestamps will be exposed when\n /// this tx is submitted to the network.\n ///\n /// If the transaction is not included in a block by its include-by timestamp, it becomes invalid and it will never\n /// be included.\n ///\n /// This expiry timestamp is publicly visible. See the \"Advanced\" section for privacy concerns.\n ///\n /// # Arguments\n /// * `expiration_timestamp` - Unix timestamp (seconds) deadline for inclusion. The include-by timestamp of this tx\n /// will be _at most_ the timestamp specified.\n ///\n /// # Advanced\n /// * If multiple functions set differing `expiration_timestamp`s, the kernel circuits will set it to be the\n /// _minimum_ of the two. This ensures the tx expiry requirements of all functions in the tx are met.\n /// * Rollup circuits will reject expired txs.\n /// * The protocol enforces that all transactions must be included within 24 hours of their chosen anchor block's\n /// timestamp, to enable safe mempool pruning.\n /// * The DelayedPublicMutable design makes heavy use of this functionality, to enable private functions to read\n /// public state.\n /// * A sophisticated Wallet should cleverly set an include-by timestamp to improve the privacy of the user and the\n /// network as a whole. For example, if a contract interaction sets include-by to some publicly-known value (e.g.\n /// the time when a contract upgrades), then the wallet might wish to set an even lower one to avoid revealing that\n /// this tx is interacting with said contract. Ideally, all wallets should standardize on an approach in order to\n /// provide users with a large privacy set -- although the exact approach\n /// will need to be discussed. Wallets that deviate from a standard might accidentally reveal which wallet each\n /// transaction originates from.\n ///\n // docs:start:expiration-timestamp\n pub fn set_expiration_timestamp(&mut self, expiration_timestamp: u64) {\n // docs:end:expiration-timestamp\n self.expiration_timestamp = std::cmp::min(self.expiration_timestamp, expiration_timestamp);\n }\n\n /// Asserts that a note has been created.\n ///\n /// This function will cause the transaction to fail unless the requested note exists. This is the preferred\n /// mechanism for performing this check, and the only one that works for pending notes.\n ///\n /// ## Pending Notes\n ///\n /// Both settled notes (created in prior transactions) and pending notes (created in the current transaction) will\n /// be considered by this function. Pending notes must have been created **before** this call is made for the check\n /// to pass.\n ///\n /// ## Historical Notes\n ///\n /// If you need to assert that a note existed _by some specific block in the past_, instead of simply proving that\n /// it exists by the current anchor block, use [`crate::history::note::assert_note_existed_by`] instead.\n ///\n /// ## Cost\n ///\n /// This uses up one of the call's kernel note hash read requests, which are limited. Like all kernel requests,\n /// proving time costs are only incurred when the total number of requests exceeds the kernel's capacity, requiring\n /// an additional invocation of the kernel reset circuit.\n pub fn assert_note_exists(&mut self, note_existence_request: NoteExistenceRequest) {\n // Note that the `note_hash_read_requests` array does not hold `NoteExistenceRequest` objects, but rather a\n // custom kernel type. We convert from the aztec-nr type into it.\n\n let note_hash = note_existence_request.note_hash();\n let contract_address = note_existence_request.maybe_contract_address().unwrap_or(AztecAddress::zero());\n\n let side_effect = Scoped::new(\n Counted::new(note_hash, self.next_counter()),\n contract_address,\n );\n\n self.note_hash_read_requests.push(side_effect);\n }\n\n /// Asserts that a nullifier has been emitted.\n ///\n /// This function will cause the transaction to fail unless the requested nullifier exists. This is the preferred\n /// mechanism for performing this check, and the only one that works for pending nullifiers.\n ///\n /// ## Pending Nullifiers\n ///\n /// Both settled nullifiers (emitted in prior transactions) and pending nullifiers (emitted in the current\n /// transaction) will be considered by this function. Pending nullifiers must have been emitted **before** this\n /// call is made for the check to pass.\n ///\n /// ## Historical Nullifiers\n ///\n /// If you need to assert that a nullifier existed _by some specific block in the past_, instead of simply proving\n /// that it exists by the current anchor block, use [`crate::history::nullifier::assert_nullifier_existed_by`]\n /// instead.\n ///\n /// ## Public vs Private\n ///\n /// In general, it is unsafe to check for nullifier non-existence in private, as that will not consider the\n /// possibility of the nullifier having been emitted in any transaction between the anchor block and the inclusion\n /// block. Private functions instead prove existence via this function and 'prove' non-existence by _emitting_ the\n /// nullifer, which would cause the transaction to fail if the nullifier existed.\n ///\n /// This is not the case in public functions, which do have access to the tip of the blockchain and so can reliably\n /// prove whether a nullifier exists or not via\n /// [`crate::context::public_context::PublicContext::nullifier_exists_unsafe`].\n ///\n /// ## Cost\n ///\n /// This uses up one of the call's kernel nullifier read requests, which are limited. Like all kernel requests,\n /// proving time costs are only incurred when the total number of requests exceeds the kernel's capacity, requiring\n /// an additional invocation of the kernel reset circuit.\n pub fn assert_nullifier_exists(&mut self, nullifier_existence_request: NullifierExistenceRequest) {\n let nullifier = nullifier_existence_request.nullifier();\n let contract_address = 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 /// Requests the app-siloed nullifier hiding key (nhk_app) for the given (hashed) master nullifier public key\n /// (npk_m), from the user's PXE.\n ///\n /// Advanced function: Only needed if you're designing your own notes and/or nullifiers.\n ///\n /// Contracts are not allowed to compute nullifiers for other contracts, as that would let them read parts of their\n /// private state. Because of this, a contract is only given an \"app-siloed key\", which is constructed by\n /// hashing the user's master nullifier hiding key with the contract's address. However, because contracts cannot\n /// be trusted with a user's master nullifier hiding key (because we don't know which contracts are honest or\n /// malicious), the PXE refuses to provide any master secret keys to any app smart contract function. This means\n /// app functions are unable to prove that the derivation of an app-siloed nullifier hiding key has been computed\n /// correctly. Instead, an app function can request to the kernel (via `request_nhk_app`) that it validates the\n /// siloed derivation, since the kernel has been vetted to not leak any master secret keys.\n ///\n /// A common nullification scheme is to inject a nullifier hiding key into the preimage of a nullifier, to make the\n /// nullifier deterministic but random-looking. This function enables that flow.\n ///\n /// # Arguments\n /// * `npk_m_hash` - A hash of the master nullifier public key of the user whose PXE is executing this function.\n ///\n /// # Returns\n /// * The app-siloed nullifier hiding key that corresponds to the given `npk_m_hash`.\n ///\n pub fn request_nhk_app(&mut self, npk_m_hash: Field) -> Field {\n self.request_sk_app(npk_m_hash, NULLIFIER_INDEX)\n }\n\n /// Requests the app-siloed outgoing viewing secret key (ovsk_app) for the given (hashed) master outgoing\n /// viewing public key (ovpk_m), from the user's PXE.\n ///\n /// See `request_nhk_app` and `request_sk_app` for more info.\n ///\n /// The intention of the \"outgoing\" keypair is to provide a second secret key for all of a user's outgoing activity\n /// (i.e. for notes that a user creates, as opposed to notes that a user receives from others). The separation of\n /// incoming and outgoing data was a distinction made by zcash, with the intention of enabling a user to optionally\n /// share with a 3rd party a controlled view of only incoming or outgoing notes. Similar functionality of sharing\n /// select data can be achieved with offchain zero-knowledge proofs. It is up to an app developer whether they\n /// choose to make use of a user's outgoing keypair within their application logic, or instead simply use the same\n /// keypair (the address keypair (which is effectively the same as the \"incoming\" keypair)) for all incoming &\n /// outgoing messages to a user.\n ///\n /// Currently, all of the exposed encryption functions in aztec-nr ignore the outgoing viewing keys, and instead\n /// encrypt all note logs and event logs to a user's address public key.\n ///\n /// # Arguments\n /// * `ovpk_m_hash` - Hash of the outgoing viewing public key master\n ///\n /// # Returns\n /// * The application-specific outgoing viewing secret key\n ///\n pub fn request_ovsk_app(&mut self, ovpk_m_hash: Field) -> Field {\n self.request_sk_app(ovpk_m_hash, OUTGOING_INDEX)\n }\n\n /// Pushes a Key Validation Request to the kernel.\n ///\n /// Private functions are not allowed to see a user's master secret keys, because we do not trust them. They are\n /// instead given \"app-siloed\" secret keys with a claim that they relate to a master public key. They can then\n /// request validation of this claim, by making a \"key validation request\" to the protocol's kernel circuits (which\n /// _are_ allowed to see certain master secret keys).\n ///\n /// When a Key Validation Request tuple of (sk_app, Pk_m, app_address) is submitted to the kernel, it will perform\n /// the following derivations to validate the relationship between the claimed sk_app and the user's Pk_m:\n ///\n /// (sk_m) ----> * G ----> Pk_m\n /// | |\n /// v We use the kernel to prove this\n /// h(sk_m, app_address) | sk_app-Pk_m relationship, because app\n /// | circuits must not be trusted to see sk_m.\n /// v |\n /// sk_app - - - - - - - - -\n ///\n /// The function is named \"request_\" instead of \"get_\" to remind the user that a Key Validation Request will be\n /// emitted to the kernel.\n ///\n fn request_sk_app(&mut self, pk_m_hash: Field, key_index: Field) -> Field {\n let cached_request =\n self.last_key_validation_requests[key_index as u32].unwrap_or(KeyValidationRequest::empty());\n\n if cached_request.pk_m.hash() == pk_m_hash {\n // We get a match so the cached request is the latest one\n cached_request.sk_app\n } else {\n // We didn't get a match meaning the cached result is stale Typically we'd validate keys by showing that\n // they are the preimage of `pk_m_hash`, but that'd require the oracle returning the master secret keys,\n // which could cause malicious contracts to leak it or learn about secrets from other contracts. We\n // therefore silo secret keys, and rely on the private kernel to validate that we siloed secret key\n // corresponds to correct siloing of the master secret key that hashes to `pk_m_hash`.\n\n // Safety: Kernels verify that the key validation request is valid and below we verify that a request for\n // the correct public key has been received.\n let request = unsafe { get_key_validation_request(pk_m_hash, key_index) };\n assert(!request.pk_m.is_infinite, \"Infinite public key points are not allowed\");\n assert_eq(request.pk_m.hash(), pk_m_hash, \"Obtained invalid key validation request\");\n\n self.key_validation_requests_and_separators.push(\n KeyValidationRequestAndSeparator {\n request,\n key_type_domain_separator: public_key_domain_separators[key_index as u32],\n },\n );\n self.last_key_validation_requests[key_index as u32] = Option::some(request);\n request.sk_app\n }\n }\n\n /// Sends an \"L2 -> L1 message\" from this function (Aztec, L2) to a smart contract on Ethereum (L1). L1 contracts\n /// which are designed to send/receive messages to/from Aztec are called \"Portal Contracts\".\n ///\n /// Common use cases include withdrawals, cross-chain asset transfers, and triggering L1 actions based on L2 state\n /// changes.\n ///\n /// The message will be inserted into an Aztec \"Outbox\" contract on L1, when this transaction's block is proposed\n /// to L1. Sending the message will not result in any immediate state changes in the target portal contract. The\n /// message will need to be manually consumed from the Outbox through a separate Ethereum transaction: a user will\n /// need to call a function of the portal contract -- a function specifically designed to make a call to the Outbox\n /// to consume the message. The message will only be available for consumption once the _epoch_ proof has been\n /// submitted. Given that there are multiple Aztec blocks within an epoch, it might take some time for this epoch\n /// proof to be submitted -- especially if the block was near the start of an epoch.\n ///\n /// # Arguments\n /// * `recipient` - Ethereum address that will receive the message\n /// * `content` - Message content (32 bytes as a Field element). This content has a very\n /// specific layout. docs:start:context_message_portal\n pub fn message_portal(&mut self, recipient: EthAddress, content: Field) {\n let message = L2ToL1Message { recipient, content };\n self.l2_to_l1_msgs.push(message.count(self.next_counter()));\n }\n\n /// Consumes a message sent from Ethereum (L1) to Aztec (L2).\n ///\n /// Common use cases include token bridging, cross-chain governance, and triggering L2 actions based on L1 events.\n ///\n /// Use this function if you only want the message to ever be \"referred to\" once. Once consumed using this method,\n /// the message cannot be consumed again, because a nullifier is emitted. If your use case wants for the message to\n /// be read unlimited times, then you can always read any historic message from the L1-to-L2 messages tree;\n /// messages never technically get deleted from that tree.\n ///\n /// The message will first be inserted into an Aztec \"Inbox\" smart contract on L1. Sending the message will not\n /// result in any immediate state changes in the target L2 contract. The message will need to be manually consumed\n /// by the target contract through a separate Aztec transaction. The message will not be available for consumption\n /// immediately. Messages get copied over from the L1 Inbox to L2 by the next Proposer in batches. So you will need\n /// to wait until the messages are copied before you can consume them.\n ///\n /// # Arguments\n /// * `content` - The message content that was sent from L1\n /// * `secret` - Secret value used for message privacy (if needed)\n /// * `sender` - Ethereum address that sent the message\n /// * `leaf_index` - Index of the message in the L1-to-L2 message tree\n ///\n /// # Advanced\n /// Validates message existence in the L1-to-L2 message tree and nullifies the message to prevent\n /// double-consumption.\n pub fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress, leaf_index: Field) {\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 (an array of Fields) that will be published to an Ethereum blob.\n ///\n /// Private logs are intended for the broadcasting of ciphertexts: that is, encrypted events or encrypted note\n /// contents. Since the data in the logs is meant to be _encrypted_, private_logs are broadcast to publicly-visible\n /// Ethereum blobs. The intended recipients of such encrypted messages can then discover and decrypt these\n /// encrypted logs using their viewing secret key. (See `../messages/discovery` for more details).\n ///\n /// Important note: This function DOES NOT _do_ any encryption of the input `log` fields. This function blindly\n /// publishes whatever input `log` data is fed into it, so the caller of this function should have already\n /// performed the encryption, and the `log` should be the result of that encryption.\n ///\n /// The protocol does not dictate what encryption scheme should be used: a smart contract developer can choose\n /// whatever encryption scheme they like. Aztec-nr includes some off-the-shelf encryption libraries that developers\n /// might wish to use, for convenience. These libraries not only encrypt a plaintext (to produce a ciphertext);\n /// they also prepend the ciphertext with a `tag` and `ephemeral public key` for easier message discovery. This is\n /// a very dense topic, and we will be writing more libraries and docs soon.\n ///\n /// > Currently, AES128 CBC encryption is the main scheme included in > aztec.nr. > We are currently making\n /// significant changes to the interfaces of the > encryption library.\n ///\n /// In some niche use cases, an app might be tempted to publish _un-encrypted_ data via a private log, because\n /// _public logs_ are not available to private functions. Be warned that emitting public data via private logs is\n /// strongly discouraged, and is considered a \"privacy anti-pattern\", because it reveals identifiable information\n /// about _which_ function has been executed. A tx which leaks such information does not contribute to the privacy\n /// set of the network.\n ///\n /// * Unlike `emit_raw_note_log_unsafe`, this log is not tied to any specific note\n ///\n /// # Arguments\n /// * `tag` - A tag placed at `fields[0]` of the emitted log. Used by recipients and nodes to identify and\n /// filter for relevant logs without scanning all of them.\n /// * `log` - The log data that will be publicly broadcast (so make sure it's already been encrypted before you\n /// call this function). Private logs are bounded in size (`PRIVATE_LOG_CIPHERTEXT_LEN`), to encourage all logs\n /// from all smart contracts look identical.\n /// * `length` - The actual length of `log` (measured in number of Fields). Although the input log has a max\n /// size of `PRIVATE_LOG_CIPHERTEXT_LEN`, the latter values of the array might all be 0's for small logs. This\n /// `length` should reflect the trimmed length of the array. The protocol's kernel circuits can then append\n /// random fields as \"padding\" after the `length`, so that the logs of this smart contract look\n /// indistinguishable from (the same length as) the logs of all other applications. It's up to wallets how much\n /// padding to apply, so ideally all wallets should agree on standards for this.\n ///\n /// ## Safety\n ///\n /// The `tag` should be domain-separated (e.g. via [`crate::protocol::hash::compute_log_tag`]) to prevent\n /// collisions between logs from different sources. Without domain separation, two unrelated log types that\n /// happen to share a raw tag value become indistinguishable. Prefer the higher-level APIs\n /// ([`crate::messages::message_delivery::MessageDelivery`] for messages, `self.emit(event)` for events) which\n /// handle tagging automatically.\n // TODO(F-555): remove this function in favor of `emit_private_log_vec_unsafe`\n #[deprecated(\"use `emit_private_log_vec_unsafe` instead\")]\n pub fn emit_private_log_unsafe(&mut self, tag: Field, log: [Field; PRIVATE_LOG_CIPHERTEXT_LEN], length: u32) {\n let counter = self.next_counter();\n let full_log = [tag].concat(log);\n self.private_logs.push(PrivateLogData { log: PrivateLog::new(full_log, length + 1), note_hash_counter: 0 }\n .count(counter));\n }\n\n /// `BoundedVec`-based variant of [`emit_private_log_unsafe`](PrivateContext::emit_private_log_unsafe).\n ///\n /// See [`emit_private_log_unsafe`](PrivateContext::emit_private_log_unsafe) for the full description of private\n /// log semantics.\n // TODO(F-555): once `emit_private_log_unsafe` is removed, rename this function to drop the `_vec` suffix.\n pub fn emit_private_log_vec_unsafe(&mut self, tag: Field, log: BoundedVec<Field, PRIVATE_LOG_CIPHERTEXT_LEN>) {\n self.emit_raw_note_log_vec_unsafe(tag, log, 0);\n }\n\n // TODO: rename.\n /// Emits a private log that is explicitly tied to a newly-emitted note_hash, to convey to the kernel: \"this log\n /// relates to this note\".\n ///\n /// This linkage is important in case the note gets squashed (due to being read later in this same tx), since we\n /// can then squash the log as well.\n ///\n /// See `emit_private_log_unsafe` for more info about private log emission.\n ///\n /// # Arguments\n /// * `tag` - A tag placed at `fields[0]`. See `emit_private_log_unsafe`.\n /// * `log` - The log data as an array of Field elements\n /// * `length` - The actual length of the `log` (measured in number of Fields).\n /// * `note_hash_counter` - The side-effect counter that was assigned to the new note_hash when it was pushed to\n /// this `PrivateContext`.\n ///\n /// Important: If your application logic requires the log to always be emitted regardless of note squashing,\n /// consider using `emit_private_log_unsafe` instead, or emitting additional events.\n ///\n /// ## Safety\n ///\n /// Same as [`PrivateContext::emit_private_log_unsafe`]: the `tag` should be domain-separated.\n // TODO(F-555): remove this function in favor of `emit_raw_note_log_vec_unsafe`\n #[deprecated(\"use `emit_raw_note_log_vec_unsafe` instead\")]\n pub fn emit_raw_note_log_unsafe(\n &mut self,\n tag: Field,\n log: [Field; PRIVATE_LOG_CIPHERTEXT_LEN],\n length: u32,\n note_hash_counter: u32,\n ) {\n let counter = self.next_counter();\n let full_log = [tag].concat(log);\n let private_log = PrivateLogData { log: PrivateLog::new(full_log, length + 1), note_hash_counter };\n self.private_logs.push(private_log.count(counter));\n }\n\n /// `BoundedVec`-based variant of [`emit_raw_note_log_unsafe`](PrivateContext::emit_raw_note_log_unsafe).\n ///\n /// See [`emit_raw_note_log_unsafe`](PrivateContext::emit_raw_note_log_unsafe) for the full description of\n /// note-tied private log semantics.\n // TODO(F-555): once `emit_raw_note_log_unsafe` is removed, rename this function to drop the `_vec` suffix.\n pub fn emit_raw_note_log_vec_unsafe(\n &mut self,\n tag: Field,\n log: BoundedVec<Field, PRIVATE_LOG_CIPHERTEXT_LEN>,\n note_hash_counter: u32,\n ) {\n let counter = self.next_counter();\n let full_log = [tag].concat(log.storage());\n let private_log = PrivateLogData { log: PrivateLog::new(full_log, log.len() + 1), note_hash_counter };\n self.private_logs.push(private_log.count(counter));\n }\n\n /// Emits large data blobs.\n ///\n /// This reuses the Contract Class Log channel to emit blobs of up to [`CONTRACT_CLASS_LOG_SIZE_IN_FIELDS`].\n ///\n /// ## Privacy\n ///\n /// The address of the contract emitting these blobs is revelead.\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 // Note: the length is not always N, it is the number of fields we want to broadcast, omitting trailing zeros\n // to save blob space.\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) };\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 = compute_contract_class_log_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(counter));\n }\n\n /// Calls a private function on another contract (or the same contract).\n ///\n /// Very low-level function.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - Array of arguments to pass to the called function\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values. Use `.get_preimage()` to extract the actual\n /// return values.\n ///\n /// This enables contracts to interact with each other while maintaining privacy. This \"composability\" of private\n /// contract functions is a key feature of the Aztec network.\n ///\n /// If a user's transaction includes multiple private function calls, then by the design of Aztec, the following\n /// information will remain private[1]:\n /// - The function selectors and contract addresses of all private function calls will remain private, so an\n /// observer of the public mempool will not be able to look at a tx and deduce which private functions have been\n /// executed.\n /// - The arguments and return values of all private function calls will remain private.\n /// - The person who initiated the tx will remain private.\n /// - The notes and nullifiers and private logs that are emitted by all private function calls will (if designed\n /// well) not leak any user secrets, nor leak which functions have been executed.\n ///\n /// [1] Caveats: Some of these privacy guarantees depend on how app developers design their smart contracts. Some\n /// actions _can_ leak information, such as:\n /// - Calling an internal public function.\n /// - Calling a public function and not setting msg_sender to Option::none (feature not built yet - see github).\n /// - Calling any public function will always leak details about the nature of the transaction, so devs should be\n /// careful in their contract designs. If it can be done in a private function, then that will give the best\n /// privacy.\n /// - Not padding the side-effects of a tx to some standardized, uniform size. The kernel circuits can take hints\n /// to pad side-effects, so a wallet should be able to request for a particular amount of padding. Wallets should\n /// ideally agree on some standard.\n /// - Padding should include:\n /// - Padding the lengths of note & nullifier arrays\n /// - Padding private logs with random fields, up to some standardized size. See also:\n /// https://docs.aztec.network/developers/resources/considerations/privacy_considerations\n ///\n /// # Advanced\n /// * The call is added to the private call stack and executed by kernel circuits after this function completes\n /// * The called function can modify its own contract's private state\n /// * Side effects from the called function are included in this transaction\n /// * The call inherits the current transaction's context and gas limits\n ///\n pub fn 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(contract_address, function_selector, args_hash, false)\n }\n\n /// Makes a read-only call to a private function on another contract.\n ///\n /// This is similar to Solidity's `staticcall`. The called function cannot modify state, emit L2->L2 messages, nor\n /// emit events. Any nested calls are constrained to also be staticcalls.\n ///\n /// See `call_private_function` for more general info on private function calls.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract to call\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - Array of arguments to pass to the called function\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values. Use `.get_preimage()` to extract the actual\n /// return values.\n ///\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(contract_address, function_selector, args_hash, true)\n }\n\n /// Calls a private function that takes no arguments.\n ///\n /// This is a convenience function for calling private functions that don't require any input parameters. It's\n /// equivalent to `call_private_function` but slightly more efficient to use when no arguments are needed.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values. Use `.get_preimage()` to extract the actual\n /// return values.\n ///\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) -> ReturnsHash {\n self.call_private_function_with_args_hash(contract_address, function_selector, 0, false)\n }\n\n /// Makes a read-only call to a private function which takes no arguments.\n ///\n /// This combines the optimisation of `call_private_function_no_args` with the safety of\n /// `static_call_private_function`.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values. Use `.get_preimage()` to extract the actual\n /// return values.\n ///\n pub fn static_call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) -> ReturnsHash {\n self.call_private_function_with_args_hash(contract_address, function_selector, 0, true)\n }\n\n /// Low-level private function call.\n ///\n /// This is the underlying implementation used by all other private function call methods. Instead of taking raw\n /// arguments, it accepts a hash of the arguments.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args_hash` - Pre-computed hash of the function arguments\n /// * `is_static_call` - Whether this should be a read-only call\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values\n ///\n pub 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 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 (which means that end_side_effect_counter - start_side_effect_counter is the number of\n // side effects that took place), along with the hash of the return values. We validate these by requesting a\n // private kernel iteration in which the return values are constrained to hash to `returns_hash` and the side\n // effects counter to increment from start to end.\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 // The kernel circuits ensure that end_side_effect_counter is greater than start_side_effect_counter, and that\n // all side effects emitted in the child call have counters within the range [start_side_effect_counter,\n // end_side_effect_counter]. Therefore, we only need to ensure that the next side effect from the current call\n // starts after the end side effect from the child call.\n self.side_effect_counter = end_side_effect_counter + 1;\n\n ReturnsHash::new(returns_hash)\n }\n\n /// Enqueues a call to a public function to be executed later.\n ///\n /// Unlike private functions which execute immediately on the user's device, public function calls are \"enqueued\"\n /// and executed some time later by a block proposer.\n ///\n /// This means a public function cannot return any values back to a private function, because by the time the\n /// public function is being executed, the private function which called it has already completed execution. (In\n /// fact, the private function has been executed and proven, along with all other private function calls of the\n /// user's tx. A single proof of the tx has been submitted to the Aztec network, and some time later a proposer has\n /// picked the tx up from the mempool and begun executing all of the enqueued public functions).\n ///\n /// # Privacy warning Enqueueing a public function call is an inherently leaky action. Many interesting applications will require some interaction with public state, but smart contract developers should try to use public function calls sparingly, and carefully. _Internal_ public function calls are especially leaky, because they completely leak which private contract made the call. See also: https://docs.aztec.network/developers/resources/considerations/privacy_considerations\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - Array of arguments to pass to the public function\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn call_public_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n hide_msg_sender: bool,\n ) {\n let calldata = [function_selector.to_field()].concat(args);\n let calldata_hash = hash_calldata_array(calldata);\n execution_cache::store(calldata, calldata_hash);\n self.call_public_function_with_calldata_hash(contract_address, calldata_hash, false, hide_msg_sender)\n }\n\n /// Enqueues a read-only call to a public function.\n ///\n /// This is similar to Solidity's `staticcall`. The called function cannot modify state or emit events. Any nested\n /// calls are constrained to also be staticcalls.\n ///\n /// See also `call_public_function` for more important information about making private -> public function calls.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - Array of arguments to pass to the public function\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn static_call_public_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n hide_msg_sender: bool,\n ) {\n let calldata = [function_selector.to_field()].concat(args);\n let calldata_hash = hash_calldata_array(calldata);\n execution_cache::store(calldata, calldata_hash);\n self.call_public_function_with_calldata_hash(contract_address, calldata_hash, true, hide_msg_sender)\n }\n\n /// Enqueues a call to a public function that takes no arguments.\n ///\n /// This is an optimisation for calling public functions that don't take any input parameters. It's otherwise\n /// equivalent to `call_public_function`.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n hide_msg_sender: bool,\n ) {\n let calldata_hash = hash_calldata_array([function_selector.to_field()]);\n self.call_public_function_with_calldata_hash(contract_address, calldata_hash, false, hide_msg_sender)\n }\n\n /// Enqueues a read-only call to a public function with no arguments.\n ///\n /// This combines the optimisation of `call_public_function_no_args` with the safety of\n /// `static_call_public_function`.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn static_call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n hide_msg_sender: bool,\n ) {\n let calldata_hash = hash_calldata_array([function_selector.to_field()]);\n self.call_public_function_with_calldata_hash(contract_address, calldata_hash, true, hide_msg_sender)\n }\n\n /// Low-level public function call.\n ///\n /// This is the underlying implementation used by all other public function call methods. Instead of taking raw\n /// arguments, it accepts a hash of the arguments.\n ///\n /// Advanced function: Most developers should use `call_public_function` or `static_call_public_function` instead.\n /// This function is exposed for performance optimization and advanced use cases.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `calldata_hash` - Hash of the function calldata\n /// * `is_static_call` - Whether this should be a read-only call\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\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 assert_valid_public_call_data(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 = 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 /// Enqueues a public function call, and designates it to be the teardown function for this tx. Only one teardown\n /// function call can be made by a tx.\n ///\n /// Niche function: Only wallet developers and paymaster contract developers (aka Fee-payment contracts) will need\n /// to make use of this function.\n ///\n /// Aztec supports a three-phase execution model: setup, app logic, teardown. The phases exist to enable a fee\n /// payer to take on the risk of paying a transaction fee, safe in the knowledge that their payment (in whatever\n /// token or method the user chooses) will succeed, regardless of whether the app logic will succeed. The \"setup\"\n /// phase ensures the fee payer has sufficient balance to pay the proposer their fees. The teardown phase is\n /// primarily intended to: calculate exactly how much the user owes, based on gas consumption, and refund the user\n /// any change.\n ///\n /// Note: in some cases, the cost of refunding the user (i.e. DA costs of tx side-effects) might exceed the refund\n /// amount. For app logic with fairly stable and predictable gas consumption, a material refund amount is unlikely.\n /// For app logic with unpredictable gas consumption, a refund might be important to the user (e.g. if a hefty\n /// function reverts very early). Wallet/FPC/Paymaster developers should be mindful of this.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the teardown function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - An array of fields to pass to the function.\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n pub fn set_public_teardown_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n hide_msg_sender: bool,\n ) {\n let calldata = [function_selector.to_field()].concat(args);\n let calldata_hash = hash_calldata_array(calldata);\n execution_cache::store(calldata, calldata_hash);\n self.set_public_teardown_function_with_calldata_hash(contract_address, calldata_hash, false, hide_msg_sender)\n }\n\n /// Low-level function to set the public teardown function.\n ///\n /// This is the underlying implementation for setting the teardown function call that will execute at the end of\n /// the transaction. Instead of taking raw arguments, it accepts a hash of the arguments.\n ///\n /// Advanced function: Most developers should use `set_public_teardown_function` instead.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the teardown function\n /// * `calldata_hash` - Hash of the function calldata\n /// * `is_static_call` - Whether this should be a read-only call\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn set_public_teardown_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 is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n\n assert_valid_public_call_data(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 self.public_teardown_call_request =\n PublicCallRequest { msg_sender, contract_address, is_static_call, calldata_hash };\n }\n\n /// Increments the side-effect counter.\n ///\n /// Very low-level function.\n ///\n /// # Advanced\n ///\n /// Every side-effect of a private function is given a \"side-effect counter\", based on when it is created. This\n /// PrivateContext is in charge of assigning the counters.\n ///\n /// The reason we have side-effect counters is complicated. Consider this illustrative pseudocode of inter-contract\n /// function calls:\n /// ```\n /// contract A {\n /// let x = 5; // pseudocode for storage var x.\n /// fn a1 {\n /// read x; // value: 5, counter: 1.\n /// x = x + 1;\n /// write x; // value: 6, counter: 2.\n ///\n /// B.b(); // start_counter: 2, end_counter: 4\n ///\n /// read x; // value: 36, counter: 5.\n /// x = x + 1;\n /// write x; // value: 37, counter: 6.\n /// }\n ///\n /// fn a2 {\n /// read x; // value: 6, counter: 3.\n /// x = x * x;\n /// write x; // value: 36, counter: 4.\n /// }\n /// }\n ///\n /// contract B {\n /// fn b() {\n /// A.a2();\n /// }\n /// }\n /// ```\n ///\n /// Suppose a1 is the first function called. The comments show the execution counter of each side-effect, and what\n /// the new value of `x` is.\n ///\n /// These (private) functions are processed by Aztec's kernel circuits in an order that is different from execution\n /// order: All of A.a1 is proven before B.b is proven, before A.a2 is proven. So when we're in the 2nd execution\n /// frame of A.a1 (after the call to B.b), the circuit needs to justify why x went from being `6` to `36`. But the\n /// circuit doesn't know why, and given the order of proving, the kernel hasn't _seen_ a value of 36 get written\n /// yet. The kernel needs to track big arrays of all side-effects of all private functions in a tx. Then, as it\n /// recurses and processes B.b(), it will eventually see a value of 36 get written.\n ///\n /// Suppose side-effect counters weren't exposed: The kernel would only see this ordering (in order of proof\n /// verification): [ A.a1.read, A.a1.write, A.a1.read, A.a1.write, A.a2.read, A.a2.write ]\n /// [ 5, 6, 36, 37, 6, 36 ]\n /// The kernel wouldn't know _when_ B.b() was called within A.a1(), because it can't see what's going on within an\n /// app circuit. So the kernel wouldn't know that the ordering of reads and writes should actually be: [ A.a1.read,\n /// A.a1.write, A.a2.read, A.a2.write, A.a1.read, A.a1.write ]\n /// [ 5, 6, 6, 36, 36, 37 ]\n ///\n /// And so, we introduced side-effect counters: every private function must assign side-effect counters alongside\n /// every side-effect that it emits, and also expose to the kernel the counters that it started and ended with.\n /// This gives the kernel enough information to arrange all side-effects in the correct order. It can then catch\n /// (for example) if a function tries to read state before it has been written (e.g. if A.a2() maliciously tried to\n /// read a value of x=37) (e.g. if A.a1() maliciously tried to read x=6).\n ///\n /// If a malicious app contract _lies_ and does not count correctly:\n /// - It cannot lie about its start and end counters because the kernel will catch this.\n /// - It _could_ lie about its intermediate counters:\n /// - 1. It could not increment its side-effects correctly\n /// - 2. It could label its side-effects with counters outside of its start and end counters' range. The kernel\n /// will catch 2. The kernel will not catch 1., but this would only cause corruption to the private state of the\n /// malicious contract, and not any other contracts (because a contract can only modify its own state). If a \"good\"\n /// contract is given _read access_ to a maliciously-counting contract (via an external getter function, or by\n /// reading historic state from the archive tree directly), and they then make state changes to their _own_ state\n /// accordingly, that could be dangerous. Developers should be mindful not to trust the claimed innards of external\n /// contracts unless they have audited/vetted the contracts including vetting the side-effect counter\n /// incrementation. This is a similar paradigm to Ethereum smart contract development: you must vet external\n /// contracts that your contract relies upon, and you must not make any presumptions about their claimed behaviour.\n /// (Hopefully if a contract imports a version of aztec-nr, we will get contract verification tooling that can\n /// validate the authenticity of the imported aztec-nr package, and hence infer that the side- effect counting will\n /// be correct, without having to re-audit such logic for every contract).\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 note_hash_read_requests: BoundedVec::new(),\n nullifier_read_requests: BoundedVec::new(),\n key_validation_requests_and_separators: BoundedVec::new(),\n note_hashes: 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 last_key_validation_requests: [Option::none(); NUM_KEY_TYPES],\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n}\n"
4223
+ "source": "use crate::{\n context::{inputs::PrivateContextInputs, NoteExistenceRequest, NullifierExistenceRequest, ReturnsHash},\n hash::{hash_args, hash_calldata_array},\n keys::constants::{NULLIFIER_INDEX, NUM_KEY_TYPES, OUTGOING_INDEX, public_key_domain_separators},\n messaging::process_l1_to_l2_message,\n oracle::{\n block_header::get_block_header_at,\n call_private_function::call_private_function_internal,\n execution_cache,\n key_validation_request::get_key_validation_request,\n logs::notify_created_contract_class_log,\n notes::notify_nullified_note,\n nullifiers::notify_created_nullifier,\n public_call::assert_valid_public_call_data,\n tx_phase::{is_execution_in_revertible_phase, notify_revertible_phase_start},\n },\n};\nuse crate::logging::aztecnr_trace_log_format;\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 note_hash::NoteHash,\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 validation_requests::{KeyValidationRequest, KeyValidationRequestAndSeparator},\n },\n address::{AztecAddress, EthAddress},\n constants::{\n CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, MAX_CONTRACT_CLASS_LOGS_PER_CALL, MAX_ENQUEUED_CALLS_PER_CALL,\n MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,\n MAX_NOTE_HASHES_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL, MAX_TX_LIFETIME,\n NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_CIPHERTEXT_LEN,\n },\n hash::compute_contract_class_log_hash,\n messaging::l2_to_l1_message::L2ToL1Message,\n side_effect::{Counted, scoped::Scoped},\n traits::{Empty, ToField},\n utils::arrays::{ClaimedLengthArray, trimmed_array_length_hint},\n};\n\n/// # PrivateContext\n///\n/// The **main interface** between an #[external(\"private\")] function and the Aztec blockchain.\n///\n/// An instance of the PrivateContext is initialized automatically at the outset of every private function, within the\n/// #[external(\"private\")] macro, so you'll never need to consciously instantiate this yourself.\n///\n/// The instance is always named `context`, and it is always be available within the body of every\n/// #[external(\"private\")] function in your smart contract.\n///\n/// > For those used to \"vanilla\" Noir, it might be jarring to have access to > `context` without seeing a declaration\n/// `let context = PrivateContext::new(...)` > within the body of your function. This is just a consequence of using >\n/// macros to tidy-up verbose boilerplate. You can use `nargo expand` to > expand all macros, if you dare.\n///\n/// Typical usage for a smart contract developer will be to call getter methods of the PrivateContext.\n///\n/// _Pushing_ data and requests to the context is mostly handled within aztec-nr's own functions, so typically a smart\n/// contract developer won't need to call any setter methods directly.\n///\n/// > Advanced users might occasionally wish to push data to the context > directly for lower-level control. If you\n/// find yourself doing this, please > open an issue on GitHub to describe your use case: it might be that > new\n/// functionality should be added to aztec-nr.\n///\n/// ## Responsibilities\n/// - Exposes contextual data to a private function:\n/// - Data relating to how this private function was called.\n/// - msg_sender\n/// - this_address - (the contract address of the private function being executed)\n/// - See `CallContext` for more data.\n/// - Data relating to the transaction in which this private function is being executed.\n/// - chain_id\n/// - version\n/// - gas_settings\n/// - Provides state access:\n/// - Access to the \"Anchor block\" header. Recall, a private function cannot read from the \"current\" block header, but\n/// must read from some historical block header, because as soon as private function execution begins (asynchronously,\n/// on a user's device), the public state of the chain (the \"current state\") will have progressed forward. We call this\n/// reference the \"Anchor block\". See `BlockHeader`.\n/// - Enables consumption of L1->L2 messages.\n/// - Enables calls to functions of other smart contracts:\n/// - Private function calls\n/// - Enqueueing of public function call requests (Since public functions are executed at a later time, by a block\n/// proposer, we say they are \"enqueued\").\n/// - Writes data to the blockchain:\n/// - New notes\n/// - New nullifiers\n/// - Private logs (for sending encrypted note contents or encrypted events)\n/// - New L2->L1 messages.\n/// - Provides args to the private function (handled by the #[external(\"private\")] macro).\n/// - Returns the return values of this private function (handled by the\n/// #[external(\"private\")] macro).\n/// - Makes Key Validation Requests.\n/// - Private functions are not allowed to see master secret keys, because we do not trust them. They are instead given\n/// \"app-siloed\" secret keys with a claim that they relate to a master public key. They can then request validation of\n/// this claim, by making a \"key validation request\" to the protocol's kernel circuits (which _are_ allowed to see\n/// certain master secret keys).\n///\n/// ## Advanced Responsibilities\n///\n/// - Ultimately, the PrivateContext is responsible for constructing the PrivateCircuitPublicInputs of the private\n/// function being executed. All private functions on Aztec must have public inputs which adhere to the rigid layout of\n/// the PrivateCircuitPublicInputs, in order to be compatible with the protocol's kernel circuits. A well-known\n/// misnomer:\n/// - \"public inputs\" contain both inputs and outputs of this function.\n/// - By \"outputs\" we mean a lot more side-effects than just the \"return values\" of the function.\n/// - Most of the so-called \"public inputs\" are kept _private_, and never leak to the outside world, because they are\n/// 'swallowed' by the protocol's kernel circuits before the tx is sent to the network. Only the following are exposed\n/// to the outside world:\n/// - New note_hashes\n/// - New nullifiers\n/// - New private logs\n/// - New L2->L1 messages\n/// - New enqueued public function call requests All the above-listed arrays of side-effects can be padded by the\n/// user's wallet (through instructions to the kernel circuits, via the PXE) to obscure their true lengths.\n///\n/// ## Syntax Justification\n///\n/// Both user-defined functions _and_ most functions in aztec-nr need access to the PrivateContext instance to\n/// read/write data. This is why you'll see the arguably-ugly pervasiveness of the \"context\" throughout your smart\n/// contract and the aztec-nr library. For example, `&mut context` is prevalent. In some languages, you can access and\n/// mutate a global variable (such as a PrivateContext instance) from a function without polluting the function's\n/// parameters. With Noir, a function must explicitly pass control of a mutable variable to another function, by\n/// reference. Since many functions in aztec-nr need to be able to push new data to the PrivateContext, they need to be\n/// handed a mutable reference _to_ the context as a parameter. For example, `Context` is prevalent as a generic\n/// parameter, to give better type safety at compile time. Many `aztec-nr` functions don't make sense if they're called\n/// in a particular runtime (private, public or utility), and so are intentionally only implemented over certain\n/// [Private|Public|Utility]Context structs. This gives smart contract developers a much faster feedback loop if\n/// they're making a mistake, as an error will be thrown by the LSP or when they compile their contract.\n///\n#[derive(Eq)]\npub struct PrivateContext {\n // docs:start:private-context\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(crate) note_hash_read_requests: BoundedVec<Scoped<Counted<Field>>, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>,\n pub(crate) nullifier_read_requests: BoundedVec<Scoped<Counted<Field>>, MAX_NULLIFIER_READ_REQUESTS_PER_CALL>,\n key_validation_requests_and_separators: BoundedVec<KeyValidationRequestAndSeparator, MAX_KEY_VALIDATION_REQUESTS_PER_CALL>,\n\n pub note_hashes: BoundedVec<Counted<NoteHash>, MAX_NOTE_HASHES_PER_CALL>,\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 // docs:end:private-context\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 // Contains the last key validation request for each key type. This is used to cache the last request and avoid\n // fetching the same request multiple times. The index of the array corresponds to the key type (0 nullifier, 1\n // incoming, 2 outgoing, 3 tagging).\n pub last_key_validation_requests: [Option<KeyValidationRequest>; NUM_KEY_TYPES],\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.timestamp() + MAX_TX_LIFETIME,\n note_hash_read_requests: BoundedVec::new(),\n nullifier_read_requests: BoundedVec::new(),\n key_validation_requests_and_separators: BoundedVec::new(),\n note_hashes: 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 last_key_validation_requests: [Option::none(); NUM_KEY_TYPES],\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.\n ///\n /// This is similar to `msg.sender` in Solidity (hence the name).\n ///\n /// Important Note: Since Aztec doesn't have a concept of an EoA (Externally-owned Account), the msg_sender is\n /// \"none\" for the first function call of every transaction. The first function call of a tx is likely to be a call\n /// to the user's account contract, so this quirk will most often be handled by account contract developers.\n ///\n /// # Returns\n /// * `Option<AztecAddress>` - The address of the smart contract that called this function (be it an app contract\n /// or a user's account contract). Returns `Option<AztecAddress>::none` for the first function call of the tx. No\n /// other _private_ function calls in the tx will have a `none` msg_sender, but _public_ function calls might (see\n /// the PublicContext).\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 ///\n /// This is equivalent to `address(this)` in Solidity (hence the name). Use this to identify the current contract's\n /// address, commonly needed for access control or when interacting with other contracts.\n ///\n /// # Returns\n /// * `AztecAddress` - The contract address of the current function being executed.\n ///\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 ///\n /// This is similar to `block.chainid` in Solidity. Returns the unique identifier for the blockchain network this\n /// transaction is executing on.\n ///\n /// Helps prevent cross-chain replay attacks. Useful if implementing multi-chain contract logic.\n ///\n /// # Returns\n /// * `Field` - The chain ID as a field element\n ///\n pub fn chain_id(self) -> Field {\n self.inputs.tx_context.chain_id\n }\n\n /// Returns the Aztec protocol version that this transaction is executing under. Different versions may have\n /// different rules, opcodes, or cryptographic primitives.\n ///\n /// This is similar to how Ethereum has different EVM versions.\n ///\n /// Useful for forward/backward compatibility checks\n ///\n /// Not to be confused with contract versions; this is the protocol version.\n ///\n /// # Returns\n /// * `Field` - The protocol version as a field element\n ///\n pub fn version(self) -> Field {\n self.inputs.tx_context.version\n }\n\n /// Returns the gas settings for the current transaction.\n ///\n /// This provides information about gas limits and pricing for the transaction, similar to `tx.gasprice` and gas\n /// limits in Ethereum. However, Aztec has a more sophisticated gas model with separate accounting for L2\n /// computation and data availability (DA) costs.\n ///\n /// # Returns\n /// * `GasSettings` - Struct containing gas limits and fee information\n ///\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 ///\n /// Low-level function: Ordinarily, smart contract developers will not need to access this.\n ///\n /// This is similar to `msg.sig` in Solidity, which returns the first 4 bytes of the function signature. In Aztec,\n /// the selector uniquely identifies which function within the contract is being called.\n ///\n /// # Returns\n /// * `FunctionSelector` - The 4-byte function identifier\n ///\n /// # Advanced\n /// Only #[external(\"private\")] functions have a function selector as a protocol- enshrined concept. The function\n /// selectors of private functions are baked into the preimage of the contract address, and are used by the\n /// protocol's kernel circuits to identify each private function and ensure the correct one is being executed.\n ///\n /// Used internally for function dispatch and call verification.\n ///\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 ///\n /// Very low-level function: You shouldn't need to call this. The #[external(\"private\")] macro calls this, and it\n /// makes the arguments neatly available to the body of your private function.\n ///\n /// # Returns\n /// * `Field` - Hash of the function arguments\n ///\n /// # Advanced\n /// * Arguments are hashed to reduce proof size and verification time\n /// * Enables efficient argument passing in recursive function calls\n /// * The hash can be used to retrieve the original arguments from the PXE.\n ///\n pub fn get_args_hash(self) -> Field {\n self.args_hash\n }\n\n /// Pushes a new note_hash to the Aztec blockchain's global Note Hash Tree (a state tree).\n ///\n /// A note_hash is a commitment to a piece of private state.\n ///\n /// Low-level function: Ordinarily, smart contract developers will not need to manually call this. Aztec-nr's state\n /// variables (see `../state_vars/`) are designed to understand when to create and push new note hashes.\n ///\n /// # Arguments\n /// * `note_hash` - The new note_hash.\n ///\n /// # Advanced\n /// From here, the protocol's kernel circuits will take over and insert the note_hash into the protocol's \"note\n /// hash tree\" (in the Base Rollup circuit). Before insertion, the protocol will:\n /// - \"Silo\" the `note_hash` with the contract address of this function, to yield a `siloed_note_hash`. This\n /// prevents state collisions between different smart contracts.\n /// - Ensure uniqueness of the `siloed_note_hash`, to prevent Faerie-Gold attacks, by hashing the\n /// `siloed_note_hash` with a unique value, to yield a `unique_siloed_note_hash` (see the protocol spec for more).\n ///\n /// In addition to calling this function, aztec-nr provides the contents of the newly-created note to the PXE, via\n /// the `notify_created_note` oracle.\n ///\n /// > Advanced users might occasionally wish to push data to the context > directly for lower-level control. If you\n /// find yourself doing this, > please open an issue on GitHub to describe your use case: it might be > that new\n /// functionality should be added to aztec-nr.\n ///\n pub fn push_note_hash(&mut self, note_hash: Field) {\n self.note_hashes.push(Counted::new(note_hash, self.next_counter()));\n }\n\n /// Creates a new [nullifier](crate::nullifier).\n ///\n /// ## Safety\n ///\n /// This is a low-level function that must be used with great care to avoid subtle corruption of contract state.\n /// Instead of calling this function, consider using the higher-level [`crate::state_vars::SingleUseClaim`].\n ///\n /// In particular, callers must ensure all nullifiers created by a contract are properly domain-separated, so that\n /// unrelated components don't interfere with one another (e.g. a transaction nullifier accidentally marking a\n /// variable as initialized). Only [`PrivateContext::push_nullifier_for_note_hash`] should be used for note\n /// nullifiers, never this one.\n ///\n /// ## Advanced\n ///\n /// The raw `nullifier` is not what is inserted into the Aztec state tree: it will be first siloed by contract\n /// address via [`crate::protocol::hash::compute_siloed_nullifier`] in order to prevent accidental or malicious\n /// interference of nullifiers from different contracts.\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 /// Creates a new [nullifier](crate::nullifier) associated with a note.\n ///\n /// This is a variant of [`PrivateContext::push_nullifier`] that is used for note nullifiers, i.e. nullifiers that\n /// correspond to a note. If a note and its nullifier are created in the same transaction, then the private kernels\n /// will 'squash' these values, deleting them both as if they never existed and reducing transaction fees.\n ///\n /// The `nullification_note_hash` must be the result of calling\n /// [`crate::note::utils::compute_confirmed_note_hash_for_nullification`] for pending notes, and `0` for settled\n /// notes (which cannot be squashed).\n ///\n /// ## Safety\n ///\n /// This is a low-level function that must be used with great care to avoid subtle corruption of contract state.\n /// Instead of calling this function, consider using the higher-level [`crate::note::lifecycle::destroy_note`].\n ///\n /// The precautions listed for [`PrivateContext::push_nullifier`] apply here as well, and callers should\n /// additionally ensure `nullification_note_hash` corresponds to a note emitted by this contract, with its hash\n /// computed in the same transaction execution phase as the call to this function. Finally, only this function\n /// should be used for note nullifiers, never [`PrivateContext::push_nullifier`].\n ///\n /// Failure to do these things can result in unprovable contexts, accidental deletion of notes, or double-spend\n /// attacks.\n pub fn push_nullifier_for_note_hash(&mut self, nullifier: Field, nullification_note_hash: Field) {\n let nullifier_counter = self.next_counter();\n notify_nullified_note(nullifier, nullification_note_hash, nullifier_counter);\n self.nullifiers.push(Nullifier { value: nullifier, note_hash: nullification_note_hash }.count(\n nullifier_counter,\n ));\n }\n\n /// Returns the anchor block header - the historical block header that this private function is reading from.\n ///\n /// A private function CANNOT read from the \"current\" block header, but must read from some older block header,\n /// because as soon as private function execution begins (asynchronously, on a user's device), the public state of\n /// the chain (the \"current state\") will have progressed forward.\n ///\n /// # Returns\n /// * `BlockHeader` - The anchor block header.\n ///\n /// # Advanced\n /// * All private functions of a tx read from the same anchor block header.\n /// * The protocol asserts that the `expiration_timestamp` of every tx is at most 24 hours beyond the timestamp of\n /// the tx's chosen anchor block header. This enables the network's nodes to safely prune old txs from the mempool.\n /// Therefore, the chosen block header _must_ be one from within the last 24 hours.\n ///\n pub fn get_anchor_block_header(self) -> BlockHeader {\n self.anchor_block_header\n }\n\n /// Returns the header of any historical block at or before the anchor block.\n ///\n /// This enables private contracts to access information from even older blocks than the anchor block header.\n ///\n /// Useful for time-based contract logic that needs to compare against multiple historical points.\n ///\n /// # Arguments\n /// * `block_number` - The block number to retrieve (must be <= anchor block number)\n ///\n /// # Returns\n /// * `BlockHeader` - The header of the requested historical block\n ///\n /// # Advanced\n /// This function uses an oracle to fetch block header data from the user's PXE. Depending on how much blockchain\n /// data the user's PXE has been set up to store, this might require a query from the PXE to another Aztec node to\n /// get the data. > This is generally true of all oracle getters (see `../oracle`).\n ///\n /// Each block header gets hashed and stored as a leaf in the protocol's Archive Tree. In fact, the i-th block\n /// header gets stored at the i-th leaf index of the Archive Tree. Behind the scenes, this `get_block_header_at`\n /// function will add Archive Tree merkle-membership constraints (~3k) to your smart contract function's circuit,\n /// to prove existence of the block header in the Archive Tree.\n ///\n /// Note: we don't do any caching, so avoid making duplicate calls for the same block header, because each call\n /// will add duplicate constraints.\n ///\n /// Calling this function is more expensive (constraint-wise) than getting the anchor block header (via\n /// `get_block_header`). This is because the anchor block's merkle membership proof is handled by Aztec's protocol\n /// circuits, and is only performed once for the entire tx because all private functions of a tx share a common\n /// anchor block header. Therefore, the cost (constraint-wise) of calling `get_block_header` is effectively free.\n ///\n pub fn get_block_header_at(self, block_number: u32) -> BlockHeader {\n get_block_header_at(block_number, self)\n }\n\n /// Sets the hash of the return values for this private function.\n ///\n /// Very low-level function: this is called by the #[external(\"private\")] macro.\n ///\n /// # Arguments\n /// * `serialized_return_values` - The serialized return values as a field array\n ///\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, to ensure compatibility with the protocol's\n /// kernel circuits.\n ///\n /// Very low-level function: This function is automatically called by the #[external(\"private\")] macro.\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::from_bounded_vec(self.note_hash_read_requests),\n nullifier_read_requests: ClaimedLengthArray::from_bounded_vec(self.nullifier_read_requests),\n key_validation_requests_and_separators: ClaimedLengthArray::from_bounded_vec(\n self.key_validation_requests_and_separators,\n ),\n note_hashes: ClaimedLengthArray::from_bounded_vec(self.note_hashes),\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(self.contract_class_logs_hashes),\n anchor_block_header: self.anchor_block_header,\n tx_context: self.inputs.tx_context,\n expected_non_revertible_side_effect_counter: self.expected_non_revertible_side_effect_counter,\n expected_revertible_side_effect_counter: self.expected_revertible_side_effect_counter,\n }\n }\n\n /// Designates this contract as the fee payer for the transaction.\n ///\n /// Unlike Ethereum, where the transaction sender always pays fees, Aztec allows any contract to voluntarily pay\n /// transaction fees. This enables patterns like sponsored transactions or fee abstraction where users don't need\n /// to hold fee-juice themselves. (Fee juice is a fee-paying asset for Aztec).\n ///\n /// Only one contract per transaction can declare itself as the fee payer, and it must have sufficient fee-juice\n /// balance (>= the gas limits specified in the TxContext) by the time we reach the public setup phase of the tx.\n ///\n pub fn set_as_fee_payer(&mut self) {\n aztecnr_trace_log_format!(\"Setting {0} as fee payer\")([self.this_address().to_field()]);\n self.is_fee_payer = true;\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 = unsafe { is_execution_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 /// Declares the end of the \"setup phase\" of this tx.\n ///\n /// Only one function per tx can declare the end of the setup phase.\n ///\n /// Niche function: Only wallet developers and paymaster contract developers (aka Fee-payment contracts) will need\n /// to make use of this function.\n ///\n /// Aztec supports a three-phase execution model: setup, app logic, teardown. The phases exist to enable a fee\n /// payer to take on the risk of paying a transaction fee, safe in the knowledge that their payment (in whatever\n /// token or method the user chooses) will succeed, regardless of whether the app logic will succeed. The \"setup\"\n /// phase enables such a payment to be made, because the setup phase _cannot revert_: a reverting function within\n /// the setup phase would result in an invalid block which cannot be proven. Any side-effects generated during that\n /// phase are guaranteed to be inserted into Aztec's state trees (except for squashed notes & nullifiers, of\n /// course).\n ///\n /// Even though the end of the setup phase is declared within a private function, you might have noticed that\n /// _public_ functions can also execute within the setup phase. This is because any public function calls which\n /// were enqueued _within the setup phase_ by a private function are considered part of the setup phase.\n ///\n /// # Advanced\n /// * Sets the minimum revertible side effect counter of this tx to be the PrivateContext's _current_ side effect\n /// counter.\n ///\n pub fn end_setup(&mut self) {\n // We bump the counter twice: once so that `min_revertible_side_effect_counter` sits strictly above any\n // non-revertible side effect counter (including queries made via `in_revertible_phase` before this call), and\n // once more so that the next revertible side effect counter is strictly greater than\n // `min_revertible_side_effect_counter`. This ensures `min_revertible_side_effect_counter` occupies a gap that\n // no side effect takes, which the kernel relies on when validating the phase split.\n self.side_effect_counter += 1;\n self.min_revertible_side_effect_counter = self.side_effect_counter;\n self.side_effect_counter += 1;\n\n aztecnr_trace_log_format!(\n \"Ending setup, minimum revertible side effect counter is {0}\",\n )(\n [self.min_revertible_side_effect_counter as Field],\n );\n notify_revertible_phase_start(self.min_revertible_side_effect_counter);\n }\n\n /// Sets a deadline (an \"include-by timestamp\") for when this transaction must be included in a block.\n ///\n /// Other functions in this tx might call this setter with differing values for the include-by timestamp. To ensure\n /// that all functions' deadlines are met, the _minimum_ of all these include-by timestamps will be exposed when\n /// this tx is submitted to the network.\n ///\n /// If the transaction is not included in a block by its include-by timestamp, it becomes invalid and it will never\n /// be included.\n ///\n /// This expiry timestamp is publicly visible. See the \"Advanced\" section for privacy concerns.\n ///\n /// # Arguments\n /// * `expiration_timestamp` - Unix timestamp (seconds) deadline for inclusion. The include-by timestamp of this tx\n /// will be _at most_ the timestamp specified.\n ///\n /// # Advanced\n /// * If multiple functions set differing `expiration_timestamp`s, the kernel circuits will set it to be the\n /// _minimum_ of the two. This ensures the tx expiry requirements of all functions in the tx are met.\n /// * Rollup circuits will reject expired txs.\n /// * The protocol enforces that all transactions must be included within 24 hours of their chosen anchor block's\n /// timestamp, to enable safe mempool pruning.\n /// * The DelayedPublicMutable design makes heavy use of this functionality, to enable private functions to read\n /// public state.\n /// * A sophisticated Wallet should cleverly set an include-by timestamp to improve the privacy of the user and the\n /// network as a whole. For example, if a contract interaction sets include-by to some publicly-known value (e.g.\n /// the time when a contract upgrades), then the wallet might wish to set an even lower one to avoid revealing that\n /// this tx is interacting with said contract. Ideally, all wallets should standardize on an approach in order to\n /// provide users with a large privacy set -- although the exact approach\n /// will need to be discussed. Wallets that deviate from a standard might accidentally reveal which wallet each\n /// transaction originates from.\n ///\n // docs:start:expiration-timestamp\n pub fn set_expiration_timestamp(&mut self, expiration_timestamp: u64) {\n // docs:end:expiration-timestamp\n self.expiration_timestamp = std::cmp::min(self.expiration_timestamp, expiration_timestamp);\n }\n\n /// Asserts that a note has been created.\n ///\n /// This function will cause the transaction to fail unless the requested note exists. This is the preferred\n /// mechanism for performing this check, and the only one that works for pending notes.\n ///\n /// ## Pending Notes\n ///\n /// Both settled notes (created in prior transactions) and pending notes (created in the current transaction) will\n /// be considered by this function. Pending notes must have been created **before** this call is made for the check\n /// to pass.\n ///\n /// ## Historical Notes\n ///\n /// If you need to assert that a note existed _by some specific block in the past_, instead of simply proving that\n /// it exists by the current anchor block, use [`crate::history::note::assert_note_existed_by`] instead.\n ///\n /// ## Cost\n ///\n /// This uses up one of the call's kernel note hash read requests, which are limited. Like all kernel requests,\n /// proving time costs are only incurred when the total number of requests exceeds the kernel's capacity, requiring\n /// an additional invocation of the kernel reset circuit.\n pub fn assert_note_exists(&mut self, note_existence_request: NoteExistenceRequest) {\n // Note that the `note_hash_read_requests` array does not hold `NoteExistenceRequest` objects, but rather a\n // custom kernel type. We convert from the aztec-nr type into it.\n\n let note_hash = note_existence_request.note_hash();\n let contract_address = note_existence_request.maybe_contract_address().unwrap_or(AztecAddress::zero());\n\n let side_effect = Scoped::new(\n Counted::new(note_hash, self.next_counter()),\n contract_address,\n );\n\n self.note_hash_read_requests.push(side_effect);\n }\n\n /// Asserts that a nullifier has been emitted.\n ///\n /// This function will cause the transaction to fail unless the requested nullifier exists. This is the preferred\n /// mechanism for performing this check, and the only one that works for pending nullifiers.\n ///\n /// ## Pending Nullifiers\n ///\n /// Both settled nullifiers (emitted in prior transactions) and pending nullifiers (emitted in the current\n /// transaction) will be considered by this function. Pending nullifiers must have been emitted **before** this\n /// call is made for the check to pass.\n ///\n /// ## Historical Nullifiers\n ///\n /// If you need to assert that a nullifier existed _by some specific block in the past_, instead of simply proving\n /// that it exists by the current anchor block, use [`crate::history::nullifier::assert_nullifier_existed_by`]\n /// instead.\n ///\n /// ## Public vs Private\n ///\n /// In general, it is unsafe to check for nullifier non-existence in private, as that will not consider the\n /// possibility of the nullifier having been emitted in any transaction between the anchor block and the inclusion\n /// block. Private functions instead prove existence via this function and 'prove' non-existence by _emitting_ the\n /// nullifer, which would cause the transaction to fail if the nullifier existed.\n ///\n /// This is not the case in public functions, which do have access to the tip of the blockchain and so can reliably\n /// prove whether a nullifier exists or not via\n /// [`crate::context::public_context::PublicContext::nullifier_exists_unsafe`].\n ///\n /// ## Cost\n ///\n /// This uses up one of the call's kernel nullifier read requests, which are limited. Like all kernel requests,\n /// proving time costs are only incurred when the total number of requests exceeds the kernel's capacity, requiring\n /// an additional invocation of the kernel reset circuit.\n pub fn assert_nullifier_exists(&mut self, nullifier_existence_request: NullifierExistenceRequest) {\n let nullifier = nullifier_existence_request.nullifier();\n let contract_address = 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 /// Requests the app-siloed nullifier hiding key (nhk_app) for the given (hashed) master nullifier public key\n /// (npk_m), from the user's PXE.\n ///\n /// Advanced function: Only needed if you're designing your own notes and/or nullifiers.\n ///\n /// Contracts are not allowed to compute nullifiers for other contracts, as that would let them read parts of their\n /// private state. Because of this, a contract is only given an \"app-siloed key\", which is constructed by\n /// hashing the user's master nullifier hiding key with the contract's address. However, because contracts cannot\n /// be trusted with a user's master nullifier hiding key (because we don't know which contracts are honest or\n /// malicious), the PXE refuses to provide any master secret keys to any app smart contract function. This means\n /// app functions are unable to prove that the derivation of an app-siloed nullifier hiding key has been computed\n /// correctly. Instead, an app function can request to the kernel (via `request_nhk_app`) that it validates the\n /// siloed derivation, since the kernel has been vetted to not leak any master secret keys.\n ///\n /// A common nullification scheme is to inject a nullifier hiding key into the preimage of a nullifier, to make the\n /// nullifier deterministic but random-looking. This function enables that flow.\n ///\n /// # Arguments\n /// * `npk_m_hash` - A hash of the master nullifier public key of the user whose PXE is executing this function.\n ///\n /// # Returns\n /// * The app-siloed nullifier hiding key that corresponds to the given `npk_m_hash`.\n ///\n pub fn request_nhk_app(&mut self, npk_m_hash: Field) -> Field {\n self.request_sk_app(npk_m_hash, NULLIFIER_INDEX)\n }\n\n /// Requests the app-siloed outgoing viewing secret key (ovsk_app) for the given (hashed) master outgoing\n /// viewing public key (ovpk_m), from the user's PXE.\n ///\n /// See `request_nhk_app` and `request_sk_app` for more info.\n ///\n /// The intention of the \"outgoing\" keypair is to provide a second secret key for all of a user's outgoing activity\n /// (i.e. for notes that a user creates, as opposed to notes that a user receives from others). The separation of\n /// incoming and outgoing data was a distinction made by zcash, with the intention of enabling a user to optionally\n /// share with a 3rd party a controlled view of only incoming or outgoing notes. Similar functionality of sharing\n /// select data can be achieved with offchain zero-knowledge proofs. It is up to an app developer whether they\n /// choose to make use of a user's outgoing keypair within their application logic, or instead simply use the same\n /// keypair (the address keypair (which is effectively the same as the \"incoming\" keypair)) for all incoming &\n /// outgoing messages to a user.\n ///\n /// Currently, all of the exposed encryption functions in aztec-nr ignore the outgoing viewing keys, and instead\n /// encrypt all note logs and event logs to a user's address public key.\n ///\n /// # Arguments\n /// * `ovpk_m_hash` - Hash of the outgoing viewing public key master\n ///\n /// # Returns\n /// * The application-specific outgoing viewing secret key\n ///\n pub fn request_ovsk_app(&mut self, ovpk_m_hash: Field) -> Field {\n self.request_sk_app(ovpk_m_hash, OUTGOING_INDEX)\n }\n\n /// Pushes a Key Validation Request to the kernel.\n ///\n /// Private functions are not allowed to see a user's master secret keys, because we do not trust them. They are\n /// instead given \"app-siloed\" secret keys with a claim that they relate to a master public key. They can then\n /// request validation of this claim, by making a \"key validation request\" to the protocol's kernel circuits (which\n /// _are_ allowed to see certain master secret keys).\n ///\n /// The app circuit only sees `pk_m_hash` (not the raw point). The kernel derives the\n /// point from `sk_m`, hashes it, and asserts equality. When a Key Validation Request tuple of\n /// (sk_app, pk_m_hash, app_address) is submitted to the kernel, it performs the following\n /// derivations to validate the relationship between the claimed sk_app and the user's pk_m_hash:\n ///\n /// (sk_m) ----> * G ----> pk_m ----> hash_public_key(pk_m)\n /// | |\n /// v | We use the kernel to prove this\n /// h(sk_m, app_address) | sk_app-pk_m_hash relationship, because app\n /// | | circuits must not be trusted to see sk_m.\n /// v |\n /// sk_app - - - - - - - - - - - - - - - - - -\n ///\n /// The function is named \"request_\" instead of \"get_\" to remind the user that a Key Validation Request will be\n /// emitted to the kernel.\n ///\n fn request_sk_app(&mut self, pk_m_hash: Field, key_index: Field) -> Field {\n // Match against the cache only when a request is actually present in the slot.\n let cached_slot = self.last_key_validation_requests[key_index as u32];\n let cache_hit = cached_slot.is_some() & (cached_slot.unwrap_unchecked().pk_m_hash == pk_m_hash);\n\n if cache_hit {\n // We get a match so the cached request is the latest one\n cached_slot.unwrap_unchecked().sk_app\n } else {\n // We didn't get a match meaning the cached result is stale. Typically we'd validate keys by showing that\n // the master secret key derives to a public key matching `pk_m_hash`, but that'd require the oracle\n // returning the master secret keys, which could cause malicious contracts to leak it or learn about\n // secrets from other contracts. We therefore silo secret keys, and rely on the private kernel to validate\n // that the siloed secret key corresponds to correct siloing of the master secret key that hashes to\n // `pk_m_hash`.\n\n // Safety: Kernels verify that the key validation request is valid and below we verify that a request for\n // the correct public key has been received.\n let request = unsafe { get_key_validation_request(pk_m_hash, key_index) };\n assert_eq(request.pk_m_hash, pk_m_hash, \"Obtained key validation request for wrong pk_m_hash\");\n\n self.key_validation_requests_and_separators.push(\n KeyValidationRequestAndSeparator {\n request,\n key_type_domain_separator: public_key_domain_separators[key_index as u32],\n },\n );\n self.last_key_validation_requests[key_index as u32] = Option::some(request);\n request.sk_app\n }\n }\n\n /// Sends an \"L2 -> L1 message\" from this function (Aztec, L2) to a smart contract on Ethereum (L1). L1 contracts\n /// which are designed to send/receive messages to/from Aztec are called \"Portal Contracts\".\n ///\n /// Common use cases include withdrawals, cross-chain asset transfers, and triggering L1 actions based on L2 state\n /// changes.\n ///\n /// The message will be inserted into an Aztec \"Outbox\" contract on L1, when this transaction's block is proposed\n /// to L1. Sending the message will not result in any immediate state changes in the target portal contract. The\n /// message will need to be manually consumed from the Outbox through a separate Ethereum transaction: a user will\n /// need to call a function of the portal contract -- a function specifically designed to make a call to the Outbox\n /// to consume the message. The message will only be available for consumption once the _epoch_ proof has been\n /// submitted. Given that there are multiple Aztec blocks within an epoch, it might take some time for this epoch\n /// proof to be submitted -- especially if the block was near the start of an epoch.\n ///\n /// # Arguments\n /// * `recipient` - Ethereum address that will receive the message\n /// * `content` - Message content (32 bytes as a Field element). This content has a very\n /// specific layout. docs:start:context_message_portal\n pub fn message_portal(&mut self, recipient: EthAddress, content: Field) {\n let message = L2ToL1Message { recipient, content };\n self.l2_to_l1_msgs.push(message.count(self.next_counter()));\n }\n\n /// Consumes a message sent from Ethereum (L1) to Aztec (L2).\n ///\n /// Common use cases include token bridging, cross-chain governance, and triggering L2 actions based on L1 events.\n ///\n /// Use this function if you only want the message to ever be \"referred to\" once. Once consumed using this method,\n /// the message cannot be consumed again, because a nullifier is emitted. If your use case wants for the message to\n /// be read unlimited times, then you can always read any historic message from the L1-to-L2 messages tree;\n /// messages never technically get deleted from that tree.\n ///\n /// The message will first be inserted into an Aztec \"Inbox\" smart contract on L1. Sending the message will not\n /// result in any immediate state changes in the target L2 contract. The message will need to be manually consumed\n /// by the target contract through a separate Aztec transaction. The message will not be available for consumption\n /// immediately. Messages get copied over from the L1 Inbox to L2 by the next Proposer in batches. So you will need\n /// to wait until the messages are copied before you can consume them.\n ///\n /// # Arguments\n /// * `content` - The message content that was sent from L1\n /// * `secret` - Secret value used for message privacy (if needed)\n /// * `sender` - Ethereum address that sent the message\n /// * `leaf_index` - Index of the message in the L1-to-L2 message tree\n ///\n /// # Advanced\n /// Validates message existence in the L1-to-L2 message tree and nullifies the message to prevent\n /// double-consumption.\n pub fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress, leaf_index: Field) {\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 (an array of Fields) that will be published to an Ethereum blob.\n ///\n /// Private logs are intended for the broadcasting of ciphertexts: that is, encrypted events or encrypted note\n /// contents. Since the data in the logs is meant to be _encrypted_, private_logs are broadcast to publicly-visible\n /// Ethereum blobs. The intended recipients of such encrypted messages can then discover and decrypt these\n /// encrypted logs using their viewing secret key. (See `../messages/discovery` for more details).\n ///\n /// Important note: This function DOES NOT _do_ any encryption of the input `log` fields. This function blindly\n /// publishes whatever input `log` data is fed into it, so the caller of this function should have already\n /// performed the encryption, and the `log` should be the result of that encryption.\n ///\n /// The protocol does not dictate what encryption scheme should be used: a smart contract developer can choose\n /// whatever encryption scheme they like. Aztec-nr includes some off-the-shelf encryption libraries that developers\n /// might wish to use, for convenience. These libraries not only encrypt a plaintext (to produce a ciphertext);\n /// they also prepend the ciphertext with a `tag` and `ephemeral public key` for easier message discovery. This is\n /// a very dense topic, and we will be writing more libraries and docs soon.\n ///\n /// > Currently, AES128 CBC encryption is the main scheme included in > aztec.nr. > We are currently making\n /// significant changes to the interfaces of the > encryption library.\n ///\n /// In some niche use cases, an app might be tempted to publish _un-encrypted_ data via a private log, because\n /// _public logs_ are not available to private functions. Be warned that emitting public data via private logs is\n /// strongly discouraged, and is considered a \"privacy anti-pattern\", because it reveals identifiable information\n /// about _which_ function has been executed. A tx which leaks such information does not contribute to the privacy\n /// set of the network.\n ///\n /// * Unlike `emit_raw_note_log_unsafe`, this log is not tied to any specific note\n ///\n /// # Arguments\n /// * `tag` - A tag placed at `fields[0]` of the emitted log. Used by recipients and nodes to identify and\n /// filter for relevant logs without scanning all of them.\n /// * `log` - The log data that will be publicly broadcast (so make sure it's already been encrypted before you\n /// call this function). Private logs are bounded in size (`PRIVATE_LOG_CIPHERTEXT_LEN`), to encourage all logs\n /// from all smart contracts look identical. The protocol's kernel circuits can then append random fields as\n /// \"padding\" after the log's length, so that the logs of this smart contract look indistinguishable from (the\n /// same length as) the logs of all other applications. It's up to wallets how much padding to apply, so\n /// ideally all wallets should agree on standards for this.\n ///\n /// ## Safety\n ///\n /// The `tag` should be domain-separated (e.g. via [`crate::protocol::hash::compute_log_tag`]) to prevent\n /// collisions between logs from different sources. Without domain separation, two unrelated log types that\n /// happen to share a raw tag value become indistinguishable. Prefer the higher-level APIs\n /// ([`crate::messages::message_delivery::MessageDelivery`] for messages, `self.emit(event)` for events) which\n /// handle tagging automatically.\n pub fn emit_private_log_unsafe(&mut self, tag: Field, log: BoundedVec<Field, PRIVATE_LOG_CIPHERTEXT_LEN>) {\n self.emit_raw_note_log_unsafe(tag, log, 0);\n }\n\n /// Emits a private log that is explicitly tied to a newly-emitted note_hash, to convey to the kernel: \"this log\n /// relates to this note\".\n ///\n /// This linkage is important in case the note gets squashed (due to being read later in this same tx), since we\n /// can then squash the log as well.\n ///\n /// See [`emit_private_log_unsafe`](PrivateContext::emit_private_log_unsafe) for more info about private log\n /// emission.\n ///\n /// # Arguments\n /// * `tag` - A tag placed at `fields[0]`. See\n /// [`emit_private_log_unsafe`](PrivateContext::emit_private_log_unsafe).\n /// * `log` - The log data as a `BoundedVec` of Field elements.\n /// * `note_hash_counter` - The side-effect counter that was assigned to the new note_hash when it was pushed to\n /// this `PrivateContext`.\n ///\n /// Important: If your application logic requires the log to always be emitted regardless of note squashing,\n /// consider using [`emit_private_log_unsafe`](PrivateContext::emit_private_log_unsafe) instead, or emitting\n /// additional events.\n ///\n /// ## Safety\n ///\n /// Same as [`PrivateContext::emit_private_log_unsafe`]: the `tag` should be domain-separated.\n pub fn emit_raw_note_log_unsafe(\n &mut self,\n tag: Field,\n log: BoundedVec<Field, PRIVATE_LOG_CIPHERTEXT_LEN>,\n note_hash_counter: u32,\n ) {\n let counter = self.next_counter();\n let full_log = [tag].concat(log.storage());\n let private_log = PrivateLogData { log: PrivateLog::new(full_log, log.len() + 1), note_hash_counter };\n self.private_logs.push(private_log.count(counter));\n }\n\n /// Emits large data blobs.\n ///\n /// This reuses the Contract Class Log channel to emit blobs of up to [`CONTRACT_CLASS_LOG_SIZE_IN_FIELDS`].\n ///\n /// ## Privacy\n ///\n /// The address of the contract emitting these blobs is revelead.\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 // Note: the length is not always N, it is the number of fields we want to broadcast, omitting trailing zeros\n // to save blob space.\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) };\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 = compute_contract_class_log_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(counter));\n }\n\n /// Calls a private function on another contract (or the same contract).\n ///\n /// Very low-level function.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - Array of arguments to pass to the called function\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values. Use `.get_preimage()` to extract the actual\n /// return values.\n ///\n /// This enables contracts to interact with each other while maintaining privacy. This \"composability\" of private\n /// contract functions is a key feature of the Aztec network.\n ///\n /// If a user's transaction includes multiple private function calls, then by the design of Aztec, the following\n /// information will remain private[1]:\n /// - The function selectors and contract addresses of all private function calls will remain private, so an\n /// observer of the public mempool will not be able to look at a tx and deduce which private functions have been\n /// executed.\n /// - The arguments and return values of all private function calls will remain private.\n /// - The person who initiated the tx will remain private.\n /// - The notes and nullifiers and private logs that are emitted by all private function calls will (if designed\n /// well) not leak any user secrets, nor leak which functions have been executed.\n ///\n /// [1] Caveats: Some of these privacy guarantees depend on how app developers design their smart contracts. Some\n /// actions _can_ leak information, such as:\n /// - Calling an internal public function.\n /// - Calling a public function and not setting msg_sender to Option::none (feature not built yet - see github).\n /// - Calling any public function will always leak details about the nature of the transaction, so devs should be\n /// careful in their contract designs. If it can be done in a private function, then that will give the best\n /// privacy.\n /// - Not padding the side-effects of a tx to some standardized, uniform size. The kernel circuits can take hints\n /// to pad side-effects, so a wallet should be able to request for a particular amount of padding. Wallets should\n /// ideally agree on some standard.\n /// - Padding should include:\n /// - Padding the lengths of note & nullifier arrays\n /// - Padding private logs with random fields, up to some standardized size. See also:\n /// https://docs.aztec.network/developers/resources/considerations/privacy_considerations\n ///\n /// # Advanced\n /// * The call is added to the private call stack and executed by kernel circuits after this function completes\n /// * The called function can modify its own contract's private state\n /// * Side effects from the called function are included in this transaction\n /// * The call inherits the current transaction's context and gas limits\n ///\n pub fn 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(contract_address, function_selector, args_hash, false)\n }\n\n /// Makes a read-only call to a private function on another contract.\n ///\n /// This is similar to Solidity's `staticcall`. The called function cannot modify state, emit L2->L2 messages, nor\n /// emit events. Any nested calls are constrained to also be staticcalls.\n ///\n /// See `call_private_function` for more general info on private function calls.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract to call\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - Array of arguments to pass to the called function\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values. Use `.get_preimage()` to extract the actual\n /// return values.\n ///\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(contract_address, function_selector, args_hash, true)\n }\n\n /// Calls a private function that takes no arguments.\n ///\n /// This is a convenience function for calling private functions that don't require any input parameters. It's\n /// equivalent to `call_private_function` but slightly more efficient to use when no arguments are needed.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values. Use `.get_preimage()` to extract the actual\n /// return values.\n ///\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) -> ReturnsHash {\n self.call_private_function_with_args_hash(contract_address, function_selector, 0, false)\n }\n\n /// Makes a read-only call to a private function which takes no arguments.\n ///\n /// This combines the optimisation of `call_private_function_no_args` with the safety of\n /// `static_call_private_function`.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values. Use `.get_preimage()` to extract the actual\n /// return values.\n ///\n pub fn static_call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) -> ReturnsHash {\n self.call_private_function_with_args_hash(contract_address, function_selector, 0, true)\n }\n\n /// Low-level private function call.\n ///\n /// This is the underlying implementation used by all other private function call methods. Instead of taking raw\n /// arguments, it accepts a hash of the arguments.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args_hash` - Pre-computed hash of the function arguments\n /// * `is_static_call` - Whether this should be a read-only call\n ///\n /// # Returns\n /// * `ReturnsHash` - Hash of the called function's return values\n ///\n pub 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 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 (which means that end_side_effect_counter - start_side_effect_counter is the number of\n // side effects that took place), along with the hash of the return values. We validate these by requesting a\n // private kernel iteration in which the return values are constrained to hash to `returns_hash` and the side\n // effects counter to increment from start to end.\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 // The kernel circuits ensure that end_side_effect_counter is greater than start_side_effect_counter, and that\n // all side effects emitted in the child call have counters within the range [start_side_effect_counter,\n // end_side_effect_counter]. Therefore, we only need to ensure that the next side effect from the current call\n // starts after the end side effect from the child call.\n self.side_effect_counter = end_side_effect_counter + 1;\n\n ReturnsHash::new(returns_hash)\n }\n\n /// Enqueues a call to a public function to be executed later.\n ///\n /// Unlike private functions which execute immediately on the user's device, public function calls are \"enqueued\"\n /// and executed some time later by a block proposer.\n ///\n /// This means a public function cannot return any values back to a private function, because by the time the\n /// public function is being executed, the private function which called it has already completed execution. (In\n /// fact, the private function has been executed and proven, along with all other private function calls of the\n /// user's tx. A single proof of the tx has been submitted to the Aztec network, and some time later a proposer has\n /// picked the tx up from the mempool and begun executing all of the enqueued public functions).\n ///\n /// # Privacy warning Enqueueing a public function call is an inherently leaky action. Many interesting applications will require some interaction with public state, but smart contract developers should try to use public function calls sparingly, and carefully. _Internal_ public function calls are especially leaky, because they completely leak which private contract made the call. See also: https://docs.aztec.network/developers/resources/considerations/privacy_considerations\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - Array of arguments to pass to the public function\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn call_public_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n hide_msg_sender: bool,\n ) {\n let calldata = [function_selector.to_field()].concat(args);\n let calldata_hash = hash_calldata_array(calldata);\n execution_cache::store(calldata, calldata_hash);\n self.call_public_function_with_calldata_hash(contract_address, calldata_hash, false, hide_msg_sender)\n }\n\n /// Enqueues a read-only call to a public function.\n ///\n /// This is similar to Solidity's `staticcall`. The called function cannot modify state or emit events. Any nested\n /// calls are constrained to also be staticcalls.\n ///\n /// See also `call_public_function` for more important information about making private -> public function calls.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - Array of arguments to pass to the public function\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn static_call_public_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n hide_msg_sender: bool,\n ) {\n let calldata = [function_selector.to_field()].concat(args);\n let calldata_hash = hash_calldata_array(calldata);\n execution_cache::store(calldata, calldata_hash);\n self.call_public_function_with_calldata_hash(contract_address, calldata_hash, true, hide_msg_sender)\n }\n\n /// Enqueues a call to a public function that takes no arguments.\n ///\n /// This is an optimisation for calling public functions that don't take any input parameters. It's otherwise\n /// equivalent to `call_public_function`.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n hide_msg_sender: bool,\n ) {\n let calldata_hash = hash_calldata_array([function_selector.to_field()]);\n self.call_public_function_with_calldata_hash(contract_address, calldata_hash, false, hide_msg_sender)\n }\n\n /// Enqueues a read-only call to a public function with no arguments.\n ///\n /// This combines the optimisation of `call_public_function_no_args` with the safety of\n /// `static_call_public_function`.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn static_call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n hide_msg_sender: bool,\n ) {\n let calldata_hash = hash_calldata_array([function_selector.to_field()]);\n self.call_public_function_with_calldata_hash(contract_address, calldata_hash, true, hide_msg_sender)\n }\n\n /// Low-level public function call.\n ///\n /// This is the underlying implementation used by all other public function call methods. Instead of taking raw\n /// arguments, it accepts a hash of the arguments.\n ///\n /// Advanced function: Most developers should use `call_public_function` or `static_call_public_function` instead.\n /// This function is exposed for performance optimization and advanced use cases.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the function\n /// * `calldata_hash` - Hash of the function calldata\n /// * `is_static_call` - Whether this should be a read-only call\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\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 assert_valid_public_call_data(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 = 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 /// Enqueues a public function call, and designates it to be the teardown function for this tx. Only one teardown\n /// function call can be made by a tx.\n ///\n /// Niche function: Only wallet developers and paymaster contract developers (aka Fee-payment contracts) will need\n /// to make use of this function.\n ///\n /// Aztec supports a three-phase execution model: setup, app logic, teardown. The phases exist to enable a fee\n /// payer to take on the risk of paying a transaction fee, safe in the knowledge that their payment (in whatever\n /// token or method the user chooses) will succeed, regardless of whether the app logic will succeed. The \"setup\"\n /// phase ensures the fee payer has sufficient balance to pay the proposer their fees. The teardown phase is\n /// primarily intended to: calculate exactly how much the user owes, based on gas consumption, and refund the user\n /// any change.\n ///\n /// Note: in some cases, the cost of refunding the user (i.e. DA costs of tx side-effects) might exceed the refund\n /// amount. For app logic with fairly stable and predictable gas consumption, a material refund amount is unlikely.\n /// For app logic with unpredictable gas consumption, a refund might be important to the user (e.g. if a hefty\n /// function reverts very early). Wallet/FPC/Paymaster developers should be mindful of this.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the teardown function\n /// * `function_selector` - 4-byte identifier of the function to call\n /// * `args` - An array of fields to pass to the function.\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n pub fn set_public_teardown_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n hide_msg_sender: bool,\n ) {\n let calldata = [function_selector.to_field()].concat(args);\n let calldata_hash = hash_calldata_array(calldata);\n execution_cache::store(calldata, calldata_hash);\n self.set_public_teardown_function_with_calldata_hash(contract_address, calldata_hash, false, hide_msg_sender)\n }\n\n /// Low-level function to set the public teardown function.\n ///\n /// This is the underlying implementation for setting the teardown function call that will execute at the end of\n /// the transaction. Instead of taking raw arguments, it accepts a hash of the arguments.\n ///\n /// Advanced function: Most developers should use `set_public_teardown_function` instead.\n ///\n /// # Arguments\n /// * `contract_address` - Address of the contract containing the teardown function\n /// * `calldata_hash` - Hash of the function calldata\n /// * `is_static_call` - Whether this should be a read-only call\n /// * `hide_msg_sender` - the called function will see a \"null\" value for `msg_sender` if set to `true`\n ///\n pub fn set_public_teardown_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 is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n\n assert_valid_public_call_data(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 self.public_teardown_call_request =\n PublicCallRequest { msg_sender, contract_address, is_static_call, calldata_hash };\n }\n\n /// Increments the side-effect counter.\n ///\n /// Very low-level function.\n ///\n /// # Advanced\n ///\n /// Every side-effect of a private function is given a \"side-effect counter\", based on when it is created. This\n /// PrivateContext is in charge of assigning the counters.\n ///\n /// The reason we have side-effect counters is complicated. Consider this illustrative pseudocode of inter-contract\n /// function calls:\n /// ```\n /// contract A {\n /// let x = 5; // pseudocode for storage var x.\n /// fn a1 {\n /// read x; // value: 5, counter: 1.\n /// x = x + 1;\n /// write x; // value: 6, counter: 2.\n ///\n /// B.b(); // start_counter: 2, end_counter: 4\n ///\n /// read x; // value: 36, counter: 5.\n /// x = x + 1;\n /// write x; // value: 37, counter: 6.\n /// }\n ///\n /// fn a2 {\n /// read x; // value: 6, counter: 3.\n /// x = x * x;\n /// write x; // value: 36, counter: 4.\n /// }\n /// }\n ///\n /// contract B {\n /// fn b() {\n /// A.a2();\n /// }\n /// }\n /// ```\n ///\n /// Suppose a1 is the first function called. The comments show the execution counter of each side-effect, and what\n /// the new value of `x` is.\n ///\n /// These (private) functions are processed by Aztec's kernel circuits in an order that is different from execution\n /// order: All of A.a1 is proven before B.b is proven, before A.a2 is proven. So when we're in the 2nd execution\n /// frame of A.a1 (after the call to B.b), the circuit needs to justify why x went from being `6` to `36`. But the\n /// circuit doesn't know why, and given the order of proving, the kernel hasn't _seen_ a value of 36 get written\n /// yet. The kernel needs to track big arrays of all side-effects of all private functions in a tx. Then, as it\n /// recurses and processes B.b(), it will eventually see a value of 36 get written.\n ///\n /// Suppose side-effect counters weren't exposed: The kernel would only see this ordering (in order of proof\n /// verification): [ A.a1.read, A.a1.write, A.a1.read, A.a1.write, A.a2.read, A.a2.write ]\n /// [ 5, 6, 36, 37, 6, 36 ]\n /// The kernel wouldn't know _when_ B.b() was called within A.a1(), because it can't see what's going on within an\n /// app circuit. So the kernel wouldn't know that the ordering of reads and writes should actually be: [ A.a1.read,\n /// A.a1.write, A.a2.read, A.a2.write, A.a1.read, A.a1.write ]\n /// [ 5, 6, 6, 36, 36, 37 ]\n ///\n /// And so, we introduced side-effect counters: every private function must assign side-effect counters alongside\n /// every side-effect that it emits, and also expose to the kernel the counters that it started and ended with.\n /// This gives the kernel enough information to arrange all side-effects in the correct order. It can then catch\n /// (for example) if a function tries to read state before it has been written (e.g. if A.a2() maliciously tried to\n /// read a value of x=37) (e.g. if A.a1() maliciously tried to read x=6).\n ///\n /// If a malicious app contract _lies_ and does not count correctly:\n /// - It cannot lie about its start and end counters because the kernel will catch this.\n /// - It _could_ lie about its intermediate counters:\n /// - 1. It could not increment its side-effects correctly\n /// - 2. It could label its side-effects with counters outside of its start and end counters' range. The kernel\n /// will catch 2. The kernel will not catch 1., but this would only cause corruption to the private state of the\n /// malicious contract, and not any other contracts (because a contract can only modify its own state). If a \"good\"\n /// contract is given _read access_ to a maliciously-counting contract (via an external getter function, or by\n /// reading historic state from the archive tree directly), and they then make state changes to their _own_ state\n /// accordingly, that could be dangerous. Developers should be mindful not to trust the claimed innards of external\n /// contracts unless they have audited/vetted the contracts including vetting the side-effect counter\n /// incrementation. This is a similar paradigm to Ethereum smart contract development: you must vet external\n /// contracts that your contract relies upon, and you must not make any presumptions about their claimed behaviour.\n /// (Hopefully if a contract imports a version of aztec-nr, we will get contract verification tooling that can\n /// validate the authenticity of the imported aztec-nr package, and hence infer that the side- effect counting will\n /// be correct, without having to re-audit such logic for every contract).\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 note_hash_read_requests: BoundedVec::new(),\n nullifier_read_requests: BoundedVec::new(),\n key_validation_requests_and_separators: BoundedVec::new(),\n note_hashes: 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 last_key_validation_requests: [Option::none(); NUM_KEY_TYPES],\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n}\n"
4322
4224
  },
4323
4225
  "67": {
4324
4226
  "function_locations": [
@@ -4760,39 +4662,39 @@
4760
4662
  "function_locations": [
4761
4663
  {
4762
4664
  "name": "derive_ecdh_shared_secret",
4763
- "start": 954
4665
+ "start": 993
4764
4666
  },
4765
4667
  {
4766
4668
  "name": "compute_app_siloed_shared_secret",
4767
- "start": 1478
4669
+ "start": 1348
4768
4670
  },
4769
4671
  {
4770
4672
  "name": "derive_shared_secret_subkey",
4771
- "start": 1869
4673
+ "start": 1739
4772
4674
  },
4773
4675
  {
4774
4676
  "name": "derive_shared_secret_field_mask",
4775
- "start": 2187
4677
+ "start": 2057
4776
4678
  },
4777
4679
  {
4778
4680
  "name": "test_consistency_with_typescript",
4779
- "start": 2329
4681
+ "start": 2199
4780
4682
  },
4781
4683
  {
4782
4684
  "name": "test_shared_secret_computation_in_both_directions",
4783
- "start": 3443
4685
+ "start": 3283
4784
4686
  },
4785
4687
  {
4786
4688
  "name": "test_shared_secret_computation_from_address_in_both_directions",
4787
- "start": 4010
4689
+ "start": 3822
4788
4690
  },
4789
4691
  {
4790
4692
  "name": "test_app_siloed_shared_secret_differs_per_contract",
4791
- "start": 5271
4693
+ "start": 5055
4792
4694
  }
4793
4695
  ],
4794
4696
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr",
4795
- "source": "use crate::protocol::{\n address::aztec_address::AztecAddress,\n constants::{DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY},\n hash::poseidon2_hash_with_separator,\n point::Point,\n scalar::Scalar,\n traits::{FromField, ToField},\n};\nuse std::{embedded_curve_ops::multi_scalar_mul, ops::Neg};\n\n/// Computes a standard ECDH shared secret: secret * public_key = shared_secret.\n///\n/// The input secret is known only to one party. The output shared secret can be derived given knowledge of\n/// `public_key`'s key-pair and the public ephemeral secret, using this same function (with reversed inputs).\n///\n/// E.g.: Epk = esk * G // ephemeral key-pair\n/// Pk = sk * G // recipient key-pair\n/// Shared secret S = esk * Pk = sk * Epk\n///\n/// See also: https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman\npub fn derive_ecdh_shared_secret(secret: Scalar, public_key: Point) -> Point {\n // TODO(F-553): Drop the `.to_embedded()` / `.into()` round-trip once the custom `Point` wrapper is removed and we\n // use `EmbeddedCurvePoint` directly.\n multi_scalar_mul([public_key.to_embedded()], [secret]).into()\n}\n\n/// Computes an app-siloed shared secret from a raw ECDH shared secret point and a contract address.\n///\n/// `s_app = h(DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, S.x, S.y, contract_address)`\npub fn compute_app_siloed_shared_secret(shared_secret: Point, contract_address: AztecAddress) -> Field {\n poseidon2_hash_with_separator(\n [shared_secret.x, shared_secret.y, contract_address.to_field()],\n DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET,\n )\n}\n\n/// Derives an indexed subkey from an app-siloed shared secret, used for AES key/IV derivation.\n///\n/// `s_i = h(DOM_SEP__ECDH_SUBKEY + i, s_app)`\npub(crate) fn derive_shared_secret_subkey(s_app: Field, index: u32) -> Field {\n poseidon2_hash_with_separator([s_app], DOM_SEP__ECDH_SUBKEY + index)\n}\n\n/// Derives an indexed field mask from an app-siloed shared secret, used for masking ciphertext fields.\n///\n/// `m_i = h(DOM_SEP__ECDH_FIELD_MASK + i, s_app)`\npub(crate) fn derive_shared_secret_field_mask(s_app: Field, index: u32) -> Field {\n poseidon2_hash_with_separator([s_app], DOM_SEP__ECDH_FIELD_MASK + index)\n}\n\n#[test]\nunconstrained fn test_consistency_with_typescript() {\n let secret = Scalar {\n lo: 0x00000000000000000000000000000000649e7ca01d9de27b21624098b897babd,\n hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06,\n };\n let point = Point {\n x: 0x2688431c705a5ff3e6c6f2573c9e3ba1c1026d2251d0dbbf2d810aa53fd1d186,\n y: 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e,\n is_infinite: false,\n };\n\n let shared_secret = derive_ecdh_shared_secret(secret, point);\n\n // This is just pasted from a test run. The original typescript code from which this could be generated seems to\n // have been deleted by someone, and soon the typescript code for encryption and decryption won't be needed, so\n // this will have to do.\n let hard_coded_shared_secret = Point {\n x: 0x15d55a5b3b2caa6a6207f313f05c5113deba5da9927d6421bcaa164822b911bc,\n y: 0x0974c3d0825031ae933243d653ebb1a0b08b90ee7f228f94c5c74739ea3c871e,\n is_infinite: false,\n };\n assert_eq(shared_secret, hard_coded_shared_secret);\n}\n\n#[test]\nunconstrained fn test_shared_secret_computation_in_both_directions() {\n let secret_a = Scalar { lo: 0x1234, hi: 0x2345 };\n let secret_b = Scalar { lo: 0x3456, hi: 0x4567 };\n\n let pk_a: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a).into();\n let pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b).into();\n\n let shared_secret = derive_ecdh_shared_secret(secret_a, pk_b);\n let shared_secret_alt = derive_ecdh_shared_secret(secret_b, pk_a);\n\n assert_eq(shared_secret, shared_secret_alt);\n}\n\n#[test]\nunconstrained fn test_shared_secret_computation_from_address_in_both_directions() {\n let secret_a = Scalar { lo: 0x1234, hi: 0x2345 };\n let secret_b = Scalar { lo: 0x3456, hi: 0x4567 };\n\n let mut pk_a: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a).into();\n let mut pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b).into();\n\n let address_b = AztecAddress::from_field(pk_b.x);\n\n // We were lazy in deriving the secret keys, and didn't check the resulting y-coordinates of the pk_a or pk_b to be\n // less than half the field modulus. If needed, we negate the pk's so that they yield valid address points. (We\n // could also have negated the secrets, but there's no negate method for EmbeddedCurvesScalar).\n pk_a = if (AztecAddress::from_field(pk_a.x).to_address_point().unwrap().inner == pk_a) {\n pk_a\n } else {\n pk_a.neg()\n };\n pk_b = if (address_b.to_address_point().unwrap().inner == pk_b) {\n pk_b\n } else {\n pk_b.neg()\n };\n\n let shared_secret = derive_ecdh_shared_secret(secret_a, address_b.to_address_point().unwrap().inner);\n let shared_secret_alt = derive_ecdh_shared_secret(secret_b, pk_a);\n\n assert_eq(shared_secret, shared_secret_alt);\n}\n\n#[test]\nunconstrained fn test_app_siloed_shared_secret_differs_per_contract() {\n let secret_a = Scalar { lo: 0x1234, hi: 0x2345 };\n let pk_b: Point = std::embedded_curve_ops::fixed_base_scalar_mul(Scalar { lo: 0x3456, hi: 0x4567 }).into();\n\n let shared_secret = derive_ecdh_shared_secret(secret_a, pk_b);\n\n let contract_a = AztecAddress::from_field(0xAAAA);\n let contract_b = AztecAddress::from_field(0xBBBB);\n\n let s_app_a = compute_app_siloed_shared_secret(shared_secret, contract_a);\n let s_app_b = compute_app_siloed_shared_secret(shared_secret, contract_b);\n\n assert(s_app_a != s_app_b, \"app-siloed secrets must differ for different contracts\");\n}\n"
4697
+ "source": "use crate::protocol::{\n address::aztec_address::AztecAddress,\n constants::{DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY},\n hash::poseidon2_hash_with_separator,\n point::EmbeddedCurvePoint,\n scalar::Scalar,\n traits::{FromField, ToField},\n};\nuse std::{embedded_curve_ops::multi_scalar_mul, ops::Neg};\n\n/// Computes a standard ECDH shared secret: secret * public_key = shared_secret.\n///\n/// The input secret is known only to one party. The output shared secret can be derived given knowledge of\n/// `public_key`'s key-pair and the public ephemeral secret, using this same function (with reversed inputs).\n///\n/// E.g.: Epk = esk * G // ephemeral key-pair\n/// Pk = sk * G // recipient key-pair\n/// Shared secret S = esk * Pk = sk * Epk\n///\n/// See also: https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman\npub fn derive_ecdh_shared_secret(secret: Scalar, public_key: EmbeddedCurvePoint) -> EmbeddedCurvePoint {\n multi_scalar_mul([public_key], [secret])\n}\n\n/// Computes an app-siloed shared secret from a raw ECDH shared secret point and a contract address.\n///\n/// `s_app = h(DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, S.x, S.y, contract_address)`\npub fn compute_app_siloed_shared_secret(shared_secret: EmbeddedCurvePoint, contract_address: AztecAddress) -> Field {\n poseidon2_hash_with_separator(\n [shared_secret.x, shared_secret.y, contract_address.to_field()],\n DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET,\n )\n}\n\n/// Derives an indexed subkey from an app-siloed shared secret, used for AES key/IV derivation.\n///\n/// `s_i = h(DOM_SEP__ECDH_SUBKEY + i, s_app)`\npub(crate) fn derive_shared_secret_subkey(s_app: Field, index: u32) -> Field {\n poseidon2_hash_with_separator([s_app], DOM_SEP__ECDH_SUBKEY + index)\n}\n\n/// Derives an indexed field mask from an app-siloed shared secret, used for masking ciphertext fields.\n///\n/// `m_i = h(DOM_SEP__ECDH_FIELD_MASK + i, s_app)`\npub(crate) fn derive_shared_secret_field_mask(s_app: Field, index: u32) -> Field {\n poseidon2_hash_with_separator([s_app], DOM_SEP__ECDH_FIELD_MASK + index)\n}\n\n#[test]\nunconstrained fn test_consistency_with_typescript() {\n let secret = Scalar {\n lo: 0x00000000000000000000000000000000649e7ca01d9de27b21624098b897babd,\n hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06,\n };\n let point = EmbeddedCurvePoint {\n x: 0x2688431c705a5ff3e6c6f2573c9e3ba1c1026d2251d0dbbf2d810aa53fd1d186,\n y: 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e,\n };\n\n let shared_secret = derive_ecdh_shared_secret(secret, point);\n\n // This is just pasted from a test run. The original typescript code from which this could be generated seems to\n // have been deleted by someone, and soon the typescript code for encryption and decryption won't be needed, so\n // this will have to do.\n let hard_coded_shared_secret = EmbeddedCurvePoint {\n x: 0x15d55a5b3b2caa6a6207f313f05c5113deba5da9927d6421bcaa164822b911bc,\n y: 0x0974c3d0825031ae933243d653ebb1a0b08b90ee7f228f94c5c74739ea3c871e,\n };\n assert_eq(shared_secret, hard_coded_shared_secret);\n}\n\n#[test]\nunconstrained fn test_shared_secret_computation_in_both_directions() {\n let secret_a = Scalar { lo: 0x1234, hi: 0x2345 };\n let secret_b = Scalar { lo: 0x3456, hi: 0x4567 };\n\n let pk_a = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a);\n let pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b);\n\n let shared_secret = derive_ecdh_shared_secret(secret_a, pk_b);\n let shared_secret_alt = derive_ecdh_shared_secret(secret_b, pk_a);\n\n assert_eq(shared_secret, shared_secret_alt);\n}\n\n#[test]\nunconstrained fn test_shared_secret_computation_from_address_in_both_directions() {\n let secret_a = Scalar { lo: 0x1234, hi: 0x2345 };\n let secret_b = Scalar { lo: 0x3456, hi: 0x4567 };\n\n let mut pk_a = std::embedded_curve_ops::fixed_base_scalar_mul(secret_a);\n let mut pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(secret_b);\n\n let address_b = AztecAddress::from_field(pk_b.x);\n\n // We were lazy in deriving the secret keys, and didn't check the resulting y-coordinates of the pk_a or pk_b to be\n // less than half the field modulus. If needed, we negate the pk's so that they yield valid address points. (We\n // could also have negated the secrets, but there's no negate method for EmbeddedCurvesScalar).\n pk_a = if (AztecAddress::from_field(pk_a.x).to_address_point().unwrap().inner == pk_a) {\n pk_a\n } else {\n pk_a.neg()\n };\n pk_b = if (address_b.to_address_point().unwrap().inner == pk_b) {\n pk_b\n } else {\n pk_b.neg()\n };\n\n let shared_secret = derive_ecdh_shared_secret(secret_a, address_b.to_address_point().unwrap().inner);\n let shared_secret_alt = derive_ecdh_shared_secret(secret_b, pk_a);\n\n assert_eq(shared_secret, shared_secret_alt);\n}\n\n#[test]\nunconstrained fn test_app_siloed_shared_secret_differs_per_contract() {\n let secret_a = Scalar { lo: 0x1234, hi: 0x2345 };\n let pk_b = std::embedded_curve_ops::fixed_base_scalar_mul(Scalar { lo: 0x3456, hi: 0x4567 });\n\n let shared_secret = derive_ecdh_shared_secret(secret_a, pk_b);\n\n let contract_a = AztecAddress::from_field(0xAAAA);\n let contract_b = AztecAddress::from_field(0xBBBB);\n\n let s_app_a = compute_app_siloed_shared_secret(shared_secret, contract_a);\n let s_app_b = compute_app_siloed_shared_secret(shared_secret, contract_b);\n\n assert(s_app_a != s_app_b, \"app-siloed secrets must differ for different contracts\");\n}\n"
4796
4698
  },
4797
4699
  "96": {
4798
4700
  "function_locations": [
@@ -4969,7 +4871,7 @@
4969
4871
  "abi_public",
4970
4872
  "abi_only_self"
4971
4873
  ],
4972
- "debug_symbols": "rZjbbuIwEIbfJddceDzjw/Aqq6qiNK2QIkAprLSqePcdF08OSPZmm97AxyT+M2P/44R8Nq/ty/X9+XB8O30021+fzUt/6LrD+3N32u8uh9NRop+NSR8Avtm6TQMWmi2nb/kNKIASgHQEfQYy+RC5DC5FQgKXwWvExwwBFYJAFIg2AxsFGW7lEtYYBc6AGkFS0EOkEdKI04iLGbxVCBkCKPgMUS8RNY2YBCVny6gQ74AGFTQCGgGN2JRGTMAZUCMo56ARIFRIERBwmMGDgmSIaVQwCi5D1EjUCGuESSHegVLOdwgZwCrkS1Ba/zuIIJkEnCElfweNkEZII04jyQAECZxCOkfcQiGdQwk4QwwZWPKhdHWWiIPbbdOoV58vfdsmq07MK5Y+7/r2eGm2x2vXbZrfu+76ddLHeXf8+r7sejkqGbXHV/kWwbdD1ya6bcbRpjzUGefzaAcQBgEAN5OAsgQZb7OEzDgVJWxZAiJrDcBgihJYlrCGnKYh7P0g4sNMgyoaIaoCT+oIuLQOK32nCijDSnX4sgQSuSyB4q5BIsBMIfzATMS1M1HzlbSa+orQl31V0RA3+cFYrjgVUPGmlXFDJeBkZGEuwNaWhHVFfHky/pFG9EMaHmMxjYo7yWqPkLU8KHxzPieVPM5nxZ1sdDZ5kgIt324oVZhtEVzRFjUJS+puZ8NYBfG8Cq5uem7Y9MyYhXTLvNMracj9VE3B43LK/WmuUDEFo9EsGMmOGm7uCWtr65HuOXcNw6asgTV7qwTGsRLr41yhtm9CGN0d6XsaFjUNm8YVNXzN4GFsETO5mYXFaSAPO7ggF9Oo28vweE/1ZXtx7abKYehVoO9qDNMB01oeNJY2WwylZkO7vtkQ1zYb0vpmQ7e+2dCvbTYM65utqrGw2ZBXN1stjaXNVrfXsmajioY88mseRGYyHQ+11DUiDRqTR79HjYXNhqbYbFSxaGCj5giMtlxJ1aJghmWRzaf4zESVpXXgxn1j0rHxP9IwnoY0TCw/0FdMKn9JUSdEmG1JxFXWBX3UdcFgcf4E+CQ/d/tDP3vrcEti/WH30rX559v1uJ8cvfw56xF9a3HuT/v29dq3SWn66kL+CLLbcHi6pav9BQ==",
4874
+ "debug_symbols": "rZhbbuMwDEX34u98iCL1YLYyKIo0dYsARhK4yQCDInsfqhH9CCCNp+5PfExb16R0aTv+bF7bl+v78+H4dvpotr8+m5f+0HWH9+futN9dDqejRD8bk34AfLN1mwYsNFtOW9kHFEAJQDqCPgOZfIhcBpciIYHL4DXiY4aACkEgCkSbgY2CDLdyCWuMAmdAjSAp6CHSCGnEacTFDN4qhAwBFHyGqJeImkZMgpKzZVSId0CDChoBjYBGbEojJuAMqBGUc9AIECqkCAg4zOBBQTLENCoYBZchaiRqhDXCpBDvQCnnO4QMYBXyJSit/x1EkEwCzpCSv4NGSCOkEaeRZACCBE4hnSNuoZDOoQScIYYMLPlQujpLxMHttmnUq8+Xvm2TVSfmFUufd317vDTb47XrNs3vXXf9OunjvDt+bS+7Xo5KRu3xVbYi+Hbo2kS3zTjalIc643we7QDCIADgZhJQliDjbZaQGaeihC1LQGStARhMUQLLEtaQ0zSEvR9EfJhpUEUjRFXgSR0Bl9Zhpe9UAWVYqQ5flkAilyVQ3DVIBJgphB+Yibh2Jmq+klZTXxH6sq8qGuImPxjLFacCKt60Mm6oBJyMLMwF2NqSsK6IL0/GP9KIfkjDYyymUXEnWe0RspYHhW/O56SSx/msuJONziZPUqDltxtKFWZbBFe0RU3Ckrrb2TBWQTyvgqs3PTfc9MyYhXTLvNMracjzVE3B43LK82muUDEFo9EsGMmOGm7uCWtr65GeOXcNw6asgTV7qwTGsRLr41yhdt+EMLo70vc0LGoaNo0raviawcPYImbyMAuL00Ae7uCCXEyjbi/D4zPVl+3FtYcqh6FXgb6rMUwHTGt50FjabDGUmg3t+mZDXNtsSOubDd36ZkO/ttkwrG+2qsbCZkNe3Wy1NJY2W91ey5qNKhryyq95EJnJdDzUUteINGhMXv0eNRY2G5pis1HFooGNmiMw2nIlVYuCGZZFbj7FdyaqLK0LQ9PHacfG/0jDeBrSMLH8Ql8xqfwlRZ0QYbYlEVdZF/RR1wWDxfkb4JPs7vaHfvbV4ZbE+sPupWvz7tv1uJ8cvfw56xH9anHuT/v29dq3SWn66UL+CLLbcHi6pav9BQ==",
4973
4875
  "is_unconstrained": true,
4974
4876
  "name": "_set_authorized"
4975
4877
  },
@@ -5025,7 +4927,7 @@
5025
4927
  "custom_attributes": [
5026
4928
  "abi_public"
5027
4929
  ],
5028
- "debug_symbols": "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",
4930
+ "debug_symbols": "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",
5029
4931
  "is_unconstrained": true,
5030
4932
  "name": "consume"
5031
4933
  },
@@ -5078,7 +4980,7 @@
5078
4980
  "abi_public",
5079
4981
  "abi_view"
5080
4982
  ],
5081
- "debug_symbols": "rZlhb+I8DMe/S1/zIk5sJ+GrnE4T29gJCbGJg0d6NPHdz17jUpCS6y28WX+47b92Y8dmfA6v2+fzr6fd4e3997D+8Tk8H3f7/e7X0/79ZXPavR/E+jk4/cNpWNNqiGFYZznIJ/CrIclHCHJM4zHzeAQHw9o7BS4AVCCYBZ2BnSKzkFnYLIwGqYC6MkIskLyBPSKbG1kFvUIewTs0MAuYBczizRLUjaBABdAsqNeQQi5AamGFXIDNEr2B+BxUWX0OKJBFMOgpdVUhOGegligAzkAtScA7A7GgPD2oqyOgQS6AZkGzkFkoFWBvEAtEMOACyR6R7KFJBdWxHAzSCOiCgVnALGAWfc+YFHKBINeQU9C8AwEMBQgMxB/SizVJRqAC0SzRLMksCQ1SAfV5hDgCOW9QHkEABiLITiEXUOdHMEswSzALmkUznEGBDPQaSSTSJGFUyAU0Sb5AkyTq7UksUdKGNEminGJNkhHMokkSSYEKaJJEViADeUSMl8tqsEp/Oh23Wy30WenLhvCxOW4Pp2F9OO/3q+G/zf78ddHvj83h63jaHOWsuLY9vMpRBN92+63SZXW929VvJUdc7paXHCcB2S9uJKAugY59kUDwWJXwdQlI2WKQPcNVJUJdQjYUMjeEmScRjjca2NCIyRTyLI4YlsbhfQRTCHJbLQ6uS8guQUUiSEFNEhFuFOID3kTqfROtvOI85VX09TcBDQ3Zb9HcEOZcCwQa2QkumSMALn8vlpSnWJCrsbQkYrIloeTSJIH5NhBsVipNlequiSFLfKtBjWVNVmbSICaFkG+3C2ikZ5ZuWCRyQH/VoLslaSRodhhMw2VX10itMjGJkK6ReE63CrnxLiBaYnhI+D0NH8wNr/fVNHxr+4Roi4LezXbguNiNkKdtRzDXQ2mml8vXRsDV9PINDQzZ/ECcZbm/i6WtkXDSmG2h9xpLi83HWrH5RooypFgk2IOvR9JKUc/R/BDOobZ9+dbSysSMk4gDqIkE94COEKC7ObZjwXyNxVPVjUafD0RTrrPzdUfaK8PXlYmzTL13hFopMmVImO2DOf2DAk8KsVcB6z60SiUhTqUSuVYqIff3JXS9fQmhvy+h7+9LGHr7EmJ/X2pqLOxLyN19qeXG0r7UTq9lfQlz6xtKjtM3FMDvakyvA+ax3GksLbZZO7grNvL9xUaht9gI+4uNqL/YiHuLjWJ/sTU1FhYb5e5ia7mxtNja6bWs2Nj3D4Ftjf4hcFZseTbB3RUbU/8QyPyAIZDjA4ZATg8YAjn3DoF/iWXZEBihfwj8y8osGwJj6B0C2wpLhsCFCt8cAmOCa6ngTan8lE+bl93x5ieJi2odd5vn/bZ8fDsfXmZnT/9/2Bn7SePj+P6yfT0ft6p0/V1D/7H7A2RYh+B+XvR5fwA=",
4983
+ "debug_symbols": "rZlhb+I8DMe/S1/zIk4cO+GrnE4T29gJCbGJg0d6NPHdz17jUpCS6y28WX+47b92Y8dmfA6v2+fzr6fd4e3997D+8Tk8H3f7/e7X0/79ZXPavR/E+jk4/UNpWMfVwGFYZznIJ/CrIclHCHJM4zHTeAQHw9o7BSoAsUAwCzoDOxXNEs1CZiE0SAXUlRG4QPIG9ohsbmQV9Ap5BO/QwCxgFjCLN0tQN4JCLIBmQb0mKuQCUS2kkAuQWdgbiM9BldXngAJZBIOeUlcVgnMGamEBcAZqSQLeGYgF5elBXR0BDXIBNAuaJZolpgLkDbgAgwEVSPaIZA9NKqiO5WCQRkAXDMwCZgGz6HvGpJALBLkmOgXNOxDAUCCCgfgT9WJNkhFiATYLmyWZJaFBKqA+j8AjROcNyiMigIEIklPIBdT5EcwSzBLMgmbRDCdQiAZ6jSRS1CQhVMgFNEm+QJOE9fYkFpa0iZokLKdIk2QEs2iScFSIBTRJmBSigTyC+XJZDVbpT6fjdquFPit92RA+Nsft4TSsD+f9fjX8t9mfvy76/bE5fB1Pm6OcFde2h1c5iuDbbr9Vuqyud7v6rdFFKnfLS+ZJQPaLGwmoS6AjXyQQPFYlfF0CUrYYZM9wVYlQl5ANJZobwkSTCPGNBjY0OJlCnsXBYWkc3jOYQpDbanFQXUJ2iVgkghTUJMFwo8APeBOp90208orylFfs628CGhqy36K5IUy5Fgg0shNcMkcAXP5eLClPsSBVY2lJcLIlicmlSQLzbSDYrNQ4Vaq7JoYs8a1GbCxrsjKTBjEphHy7XUAjPbN0wyKRA/qrRrxbkkaCZofBNFx2dY3UKhOTCOkaiad0q5Ab7wLYEsNDwu9p+GBueL2vpuFb2yewLQp6N9uBebEbIU/bjmCuh9JML5evjYCq6eUbGhiy+YE4y3J/F0tbI+GkMdtC7zWWFpvnWrH5RooSJC4S5MHXI2mlqCc2P4RzqG1fvrW0MjHjJOIAaiLBPaAjBOhuju1YMF9j8bHqRqPPhxinXCfn6460V4auK8OzTL13pLGXEk8Zkmf7YE7/oECTAncqsKv70CqVhDiVClOtVELu70voevsSQn9fQt/flzD09iXE/r7U1FjYl5C6+1LLjaV9qZ1ey/oS5tY3lMzTNxTA72pMrwPmsdxpLC22WTu4K7bo+4stht5ii9hfbDH2F1uk3mKL3F9sTY2FxRZzd7G13FhabO30WlZs5PuHwLZG/xA4K7Y8m+Duio1i/xBI9IAhkPgBQyClBwyBlHuHwL/EsmwIZOgfAv+yMsuGQA69Q2BbYckQuEzhu0MgJ7iWCt6Uyk/5tHnZHW9+krio1nG3ed5vy8e38+Fldvb0/4edsZ80Po7vL9vX83GrStffNfQfuz9AhnUI7udFn/cH",
5082
4984
  "is_unconstrained": true,
5083
4985
  "name": "is_consumable"
5084
4986
  },
@@ -5124,7 +5026,7 @@
5124
5026
  "abi_public",
5125
5027
  "abi_view"
5126
5028
  ],
5127
- "debug_symbols": "rZfdavMwDIbvJcc5sH4s272VMUbXZSMQ0pK1H3yM3vvszcpPwaZsO6nfyPUTyZKV5KN56Z4vb0/9+Hp8b3YPH83z1A9D//Y0HA/7c38co/WjMelHuNnZtpHQ7ELbuHgFGMd4CdQ2nr/HgHl0zQ5N24CRLACyIFShU6xTrBarFqsWMSpYRcjCkQqfhddbeHUjJCAmYb8FGqNCLaAWUAuqBZMbMSwkUKEWTv+xSdgsbLJIEjYLUYv4LJLPlMjJZ+IofARSmkqufotsIZMsLgnJIm0m+SQkC/yyXK9to6l7Ok9dlzK3ymXM8Gk/deO52Y2XYWibf/vh8vWn99N+/BrP+ynOxj3rxpc4RuBrP3RJXdtltSkvtcZKXm0B3AwAsBsElBFsBDOCAbmIwDICfNAYYvJNEUFlBBq26kbUIjNE3IbBFYbzSgirOBzdGweiAyVQXFaKQ8oIYrYZQSx2RjjYENwf7IT/7U7U6krCXFcOyzsBFQaBYXUjagmlQKBSnWC8OgJgws9i8WGOhaUYSw1hzbwdlnBGcNgGwtWTaueTapbCiCneMmwlrV6PGQU/Eyhs2wVUyjOQUS8C8RII2ZuUVAo0GCZlmGDKDF87Joogv0QSW/aWECp7AU5TguD5ZwwkdQPTuhIDa+0TnCaF0aw6sLvbDQpz24kylEOplpcJy4NAiuWFFQZTUD+YzWo7bmKpMzzPjFULvWXce9gslA4bVkpU4stIRggCliOplSiK0z4cdaBS+8JaaiEEniEGoAQh8wdPBIJfPxzrsXBYYkFbdKPynKeYUWWIwbIj9czIkhm3qtRbR2ytROYKWTX01FfvJ8hMcL8l8I0Pj/Fyf+inzcfBNaGmfv88dPny9TIeVrPn/yed0Y+L03Q8dC+XqUuk5QsjvdQ+CLcij9d0t08=",
5029
+ "debug_symbols": "rZfdbusgDMffJde5wB8Y6KtM09R12RQpSqusPdLR1Hc/sOF8VALtrLsp/5jyi42Nk3w0L93z5e2pH1+P783u4aN5nvph6N+ehuNhf+6PY7R+NCb9CDc72zYSml1oGxevAOMYL4HaxvPXGDCPrtmhaRswkgVAFoQqdIp1itVi1WLVIkYFqwhZOFLhs/B6C69uhATEJOyXQGNUqAXUAmpBtWByI4aFBCrUwuk/NgmbhU0WScJmIWoRn0XymRI5+UwchY9ASlPJ1S+RLWSSxSUhWaTNJJ+EZIGfluu1bTR1T+ep61LmVrmMGT7tp248N7vxMgxt82c/XD7/9H7aj5/jeT/F2bhn3fgSxwh87YcuqWu7rDblpdZYyastgJsBAHaDgDKCjWBGMCAXEVhGgA8aQ0y+KSKojEDDVt2IWmSGiNswuMJwXglhFYej78aB6EAJFJeV4pAygphtRhCLnREONgT3Czvh792JWl1JmOvKYXknoMIgMKxuRC2hFAhUqhOMV0cATPhZLD7MsbAUY6khrJm3wxLOCA7bQLh6Uu18Us1SGDHFW4atpNXrMaPgZwKFbbuASnkGMupFIF4CIXuTkkqBBsOkDBNMmeFrx0QR5JdIYsveEkJlL8BpShA8/4yBpG5gWldiYK19gtOkMJpVB3bfdoPC3HaiDOVQquVlwvIgkGJ5YYXBFNQPZrPajptY6gzPM2PVQm8Z3z1sFkqHDSslKvFlJCMEAcuR1EoUxWkfjjpQqX1hLbUQAs8QA1CCkPmFJwLB3Q/HeiwclljQFt2oPOcpZlQZYrDsSD0zsmTGrSr11pFKLxU3V0hY9cHg/4MgM8HdSXDmxofHeLk/9NPm4+CaUFO/fx66fPl6GQ+r2fPfk87ox8VpOh66l8vUJdLyhZFeah+EW5HHa7rbPw==",
5128
5030
  "is_unconstrained": true,
5129
5031
  "name": "is_reject_all"
5130
5032
  },
@@ -5158,7 +5060,7 @@
5158
5060
  "custom_attributes": [
5159
5061
  "abi_public"
5160
5062
  ],
5161
- "debug_symbols": "rVjbbtswDP0XP+dBIqkL8yvDUKStWwQIksBNBgxF/n1UI8p2AGlevZf4hLKOKeocSfZn99o/X9+f9se300e3/fHZPQ/7w2H//nQ4vewu+9NRop+dST/WQrd1G7mGbstyBflvMQEJ2NSCoMDnJrIKUiQIcFaBRjwp4AwCdlugBGIGMdwBmByBlM0daBNoBDSCGkn5fAEyCpwCzsCRAn2ERwWJ0AsIVoHPIGokaoQ1wjmCJqUREggZWI3YdI8UE8EqkAgaAWgVcAYkGWLqRTEDhwo04jXiNRJAgc8g5XwHLgM2CvQRzHdAJhFyAiGDlPwdaAQ0AhpBjaCkQZI8ESqQewgEOLmHMIGQgXcZBMmH0tODRJy53TadCvLpMvR90uNEoaLb827oj5due7weDpvu1+5w/brp47w7fl0vu0Fa5fn98VWuQvi2P/QJ3TZjb1Pv6ozzubcTCxQCa92MwtYpyHjIFFJEqlJAncJG1jFYtqZKgXUKMFL5zCHY+0Liw4yDGhwhKgNPxhFw6TjEo1YZULrVxuHrFGIHlylQlFMogp0xhP9Qibi2Eg1dgYyjVMJxoSCey6pBIWLyRVeuWgnbkCZIvzIQ66RnpRQWWjPCOiG+Xou/pBF9ScNjrKbRECeBWkQWprGg7nv1nIzksZ4NcbLRavIkBTLLVWFHfxBWVRGbC5YrC5YZVSFKn3NwI42opUQe50K2i7nPGwNhNJoFI8HI4eYTCrZVzLQp3DkMmzpHU5tKgXEcCfg4Z2itmzaM0oz0PQ5ATQNSvyqHa6kzjPo2k40oLE4Duay+ArmaRltehsf90FflBbG1IXIoRrP0XY5SDjsdywPHUrNNdpIHs6FdbzaEtWZDXG82pPVmQ7fWbOjXm63JsdBsGFebrZXGUrO15bXMbNQ6fSJrHkRmUo6HsbQ5IhWOybHtkWOp2WLVbNSQaGCj4giMUB9JU6LWlGmRxad64KHG1DpbTA9Tx8Z/SMN4KmmYWD+MN0SK4jctiGCGKkljq5cXRj0Lyysjzo9vP+Xv7mU/zD4L3BLZsN89H/r89+16fJm0Xn6ftUU/K5yH00v/eh36xDT9tiAvcTFu2Py8paf9AQ==",
5063
+ "debug_symbols": "rVjbbqMwEP0XnvNge8aXya+sqipNaYWESESTlVZV/n3HjcdAJHvZ0pdwMsaH8fgc2/DZvLYv1/fnbng7fTT7X5/Ny9j1fff+3J+Oh0t3Gjj62aj4o7Vp9nbHV9/sia+G/2uIgAM6toAR4FITagEx4hlYLUAiDgVQAh6avcEIQgLB34FRKWJiNncgTUYiRiIgkZjPF0AlwAqgBCwKkEc4EBAJHQOvBbgEgkSCREgilCKgYho+Ap+AloiO93AxwWgBHAHFALQASgA5Q4i9MCRgQYBEnEScRLwR4BKIOd+BTYCUAHkE0R2gioQUgU8gJn8HEjESMRIBiQCngZw8Igjge9AwsHwPQgQ+AWcT8JwPxqd7jlh1u+0aEeTzZWzbqMeZQlm358PYDpdmP1z7ftf8PvTXr5s+zofh63o5jNzKz2+HV74y4VvXtxHddlNvVe5qlXWpt2ULZAKt7YJClylQOZMouIhYpDBlCh1IxqBJqyIFlCmM4sonDsbOZRLnFxxY4fBBGGg2Dg9rx8Ee1cIA3K00DlemYDvYRAGsnEzh9YLB/0AlwtZKVHRleBy5EpYyBdJSVhUKFpPLurLFSuiKNA33ywPRlnsWSqFNbUZIJsSVa/GPNILLaTgIxTQq4kQjFuGFaSqo/V49ZyN5rGdFnKSkmjRLAdV6VejJHwhFVYTqgmXzgqUmVbDSlxxUSSNIKYGmueDtYunzykAIlGRBgGbisMsJNbpWzLgp3DkUqTJHVZtCAWEaiXFhyVBbN7WfpBnwexwGJA0T+xU5bE2dftK3mm1EfnUaQHn1ZUjFNOryUjTth64oLxNqGyL5bDSN3+XI5dDzsTxwrDXbbCd5MBvo7WYDs9VsANvNBrjdbGC3mg3cdrNVOVaaDcJms9XSWGu2urzWmQ1rp08gyQNRzcrxMJY6R8DMMTu2PXKsNVsomg0rEvWkRByewJRHUpWoVnlaePEpHniwMrXWZ9OHuWPDf6ShHOY0VCgfxisiBfabFIQxmSJJZavnF0Y5C/MrIyyPb0/893DsxsVngVskG7vDS9+mv2/X4Thrvfw5S4t8VjiPp2P7eh3byDT/tsAvcSHsSD3d4tP+Ag==",
5162
5064
  "is_unconstrained": true,
5163
5065
  "name": "set_authorized"
5164
5066
  },
@@ -6334,30 +6236,9 @@
6334
6236
  "type": {
6335
6237
  "fields": [
6336
6238
  {
6337
- "name": "pk_m",
6239
+ "name": "pk_m_hash",
6338
6240
  "type": {
6339
- "fields": [
6340
- {
6341
- "name": "x",
6342
- "type": {
6343
- "kind": "field"
6344
- }
6345
- },
6346
- {
6347
- "name": "y",
6348
- "type": {
6349
- "kind": "field"
6350
- }
6351
- },
6352
- {
6353
- "name": "is_infinite",
6354
- "type": {
6355
- "kind": "boolean"
6356
- }
6357
- }
6358
- ],
6359
- "kind": "struct",
6360
- "path": "aztec::protocol_types::point::Point"
6241
+ "kind": "field"
6361
6242
  }
6362
6243
  },
6363
6244
  {
@@ -6977,14 +6858,14 @@
6977
6858
  "visibility": "databus"
6978
6859
  }
6979
6860
  },
6980
- "bytecode": "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",
6861
+ "bytecode": "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",
6981
6862
  "custom_attributes": [
6982
6863
  "abi_private"
6983
6864
  ],
6984
- "debug_symbols": "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",
6865
+ "debug_symbols": "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",
6985
6866
  "is_unconstrained": false,
6986
6867
  "name": "set_authorized_private",
6987
- "verification_key": "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"
6868
+ "verification_key": "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"
6988
6869
  },
6989
6870
  {
6990
6871
  "abi": {
@@ -7009,7 +6890,7 @@
7009
6890
  "custom_attributes": [
7010
6891
  "abi_public"
7011
6892
  ],
7012
- "debug_symbols": "rVdbbuMwDLyLv/MhknoxVymKwkmcwoDhBG6ywCLI3VdqRdkOIG222594TFnjITmSnFtz6HbX97d+PJ4+mu3LrdlN/TD072/Dad9e+tMYordGxR9QvtmaTQNAzZbjNdwDBYAhAHEEfQKEaYhcAjpGXAQuASMRqwQYAdxsUQfgfAKevgAqLSANIcgQSAQlghKJer6ATUCDAJOAUQLkFSbJQBsJbQQuAYcCJOIl4iXCEuEoI+RFigRIBOIzHIFLAEOEVAQuATIJ6KCQdAQx4u73TSNtertMXRe7tOhb6Oa5nbrx0mzH6zBsml/tcP186OPcjp/XSzuF0cDdjYdwDYTHfugium/m2ao81Shj02wD4DIBgFlRQJlCK4uJQgPqIgWWKcCz5AAMqkhBZYpgLCMyArY2k1i34tAVDueFgRd5OHo2D0QHwkBhWikPW6YgrU2iIG1NpnCwYnA/UAn/v5Wo+AotZw1Ozb7SvLZVhSKYyWZfmWIloGJNDPNyImDCzEIpAGsdYWmILdfiLzK8zTIs+aKMijk1yhLRiJwZzPfqucjksZ4Vc7KSavJCglbPu8KKuYNBoOgKX92wTN6w1OyK4PQ1B1dkeCkl8dwL4nUeWEmESYkKJo0zh1k3FKFWTE3CoViVOareFArycyZo/Zqhtm+Cm63p9fc4kEQGxnlFDlNzp5v9vdgwwD0tgzjvvgFyUUbdXorn89AW7YUVDk0sOrRWi3I85lLl8DpzLE6SR44nF5tbpPKw2KhiUcdKzOGYsKiCqhYFlduiAYp7MFVaayAvelyuWP8PMpTVWYbyxVORKialsN6kIAEzFklqJ7z1cjSSQ1qfKK/htt330+r7/R7Jpr7dDV26PV7H/WL08vssI/L9f55O++5wnbrItPgTED6bXyxsLL3e49v+AA==",
6893
+ "debug_symbols": "rVdbbuMwDLyLv/MhknoxVymKwkmcwoDhBG6ywCLI3VdqRdkOIG222594TFnjITmSnFtz6HbX97d+PJ4+mu3LrdlN/TD072/Dad9e+tMYordGxR9QvtmaTQNAzZbjNdwDBYAhAHEEfQKEaYhcAjpGXAQuASMRqwQYAdxsUQfgfAKevgAqLSANIcgQSAQlghKJer6ATUCDAJOAUQLkFSbJQBsJbQQuAYcCJOIl4iXCEuEoI+RFigRIBOIzHIFLAEOEVAQuATIJ6KCQdAQx4u73TSNtertMXRe7tOhb6Oa5nbrx0mzH6zBsml/tcP186OPcjp/XSzuF0cDdjYdwDYTHfugium/m2ao81Shj02wD4DIBgFlRQJlCK4uJQgPqIgWWKcCz5AAMqkhBZYpgLCMyArY2k1i34tAVDueFgRd5OHo2D0QHwkBhWikPW6YgrU2iIG1NpnCwYnA/UAn/v5Wo+AotZw1Ozb7SvLZVhSKYyWZfmWIloGJNDPNyImDCzEIpAGsdYWmILdfiLzK8zTIs+aKMijk1yhLRiJwZzPfqucjksZ4Vc7KSavJCglbPu8KKuYNBoOgKX92wTN6w1OyK4PQ1B1dkeCkl8dwL4nUeWEmESYkKJo0zh1k3FKFWTE3CoViVOareFArycyZo/Zqhtm+Cm63p9fc4kEQGxnlFDlNzp5v9vdgwwD0tgzjvvgFyUUbdXorn89AW7YUVDk0sOrRWi3I85lLl8DpzLE6SR44nF5tbpPKw2KhiUcdKzOGYsKiCqhYFlduiAYp7MFVaa1xe9H65Yv0/yFBWZxnKF09FqpiUwnqTggTMWCSpnfDWy9FIDml9oryG23bfT6vv93skm/p2N3Tp9ngd94vRy++zjMj3/3k67bvDdeoi0+JPQPhsfrGwsfR6j2/7Aw==",
7013
6894
  "is_unconstrained": true,
7014
6895
  "name": "set_reject_all"
7015
6896
  },
@@ -7061,11 +6942,11 @@
7061
6942
  "visibility": "public"
7062
6943
  }
7063
6944
  },
7064
- "bytecode": "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",
6945
+ "bytecode": "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",
7065
6946
  "custom_attributes": [
7066
6947
  "abi_utility"
7067
6948
  ],
7068
- "debug_symbols": "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",
6949
+ "debug_symbols": "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",
7069
6950
  "is_unconstrained": true,
7070
6951
  "name": "utility_is_consumable"
7071
6952
  },
@@ -7199,7 +7080,7 @@
7199
7080
  ],
7200
7081
  "return_type": null
7201
7082
  },
7202
- "bytecode": "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",
7083
+ "bytecode": "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",
7203
7084
  "custom_attributes": [
7204
7085
  "abi_utility"
7205
7086
  ],
@@ -7259,7 +7140,7 @@
7259
7140
  "custom_attributes": [
7260
7141
  "abi_public"
7261
7142
  ],
7262
- "debug_symbols": "vZ3djt02DoDfZa5zIZH6ofIqRVGkbboIEKRFNllgUeTdV6Qk0jML8yhjpzfxdzg+1B8lUqJ98vfT7+9//fqvXz58+uPPfz+9/envp18/f/j48cO/fvn452/vvnz481OX/v0U+J8Y69Pb+OYpQhlXjE9vga9lXNP8nObnHOY1j2uZn8v63Ma1pnmlcSWUK5SuL/E1j2sN8zo/0/xM83Pr36t8JbligKe3ja91XGPXFwNDmQBdQywMXCWWINcxMbCE/5TCgjT/lNqEzBJiaBNKnVBhQS8Lcweu7YA8oS1Jm5IUwoK0gCZEXFAnACyYRSQekAGssDK0CVz5AUuSlyQvSVkS7mgkhryg35N6/yTq96TI0Ca0OiBzdydiKBO4wwcsCSwJLAl3+IC0oE1IuIAm5FVErhPYRnJgyBO48gOWhJaElqQtSevVyL3yJcQFfA92iHxPYsgTABf0+uReesEuKfwtHKZcEs7rMOXCFS6sjSsswBUeUCbUJSGQeVValGuNSey6RhpXLl+u8zPOzzg/87zrdl5znNc8zLzyxBuQhr1XmXos4blXKkOXFP4Wj/AAmn/ieTWAJ1avGQWcwCM8oEzgKVWJIS1oE3BJcEnSknB/CXCHDagTuMMGlAl1FcEjPKArpN4c4qVjAE1oS9KmpAVcsCTc0RQZ2gTuakIGvqd3buPOFuBVbkCvD/XSm/Q3f4vr3Ee9lTivYyFsXGEe4cYVHtAmSG8LTEkMvAhEgTYBQQa4Q5mQ4oIlyUuSl4QHuw1qi+pYIjvQBDG6IlSHTcTQWBak6FYWxhANTRpNGk0qC+vEZNgUuTsXkmICw6qYpQgUzIrDqAeatJq0mpRMSlJJ7owo82yi3MvdANL9oQpmxYiGXN/IyoDNpFeKkdfeXqZgUUwmTSIlRmnQRJE28arRsCnyBO0qBVkKUholQ9Ib2NYXipQLxoCKMlgTi6IMFgZBbjGyBvGEEZtgUywmlcVkot1QTVpNSiaV+g4UO5tYFyaxs4lFMQbDbMhFsPfppoOGpIgmRZMmkyaTskfsXxZsikXuRUFSKfv3hVWRTCp2NlDsbCJXPSUJjoKhFJwFm0rF5CaSIpgUqiKCoRTMA5tTMMyK2aTZpMWkxaRVqk6CRVGmU5b6ysBObIrNpE2lJSRDUoxgWBU5UFhYFDEYZkMpgusr/nchKWaTZpMWkxaTiv2yc+/YFNmv9FoL8r3s9Hv8igurGO1Erm/hr1Ux2olZEUwKJkWTYjIkRWnbxKqYwdAKlrVkIhdRg2BTlGZONCmZlEzaVEpitOznO2ZDuZenCEW5Nwk2RbHUgWKpJMqQpSQRv5gnyQ1inhNNKuZJWTArympPRVCkPIQk5jmRFGWwxAuSLDaCjYPWhdx9jZU1GbeJ2VCCJm6mxAcLSZHb1p2GYFGUbdFE3lRwJBYlaIAYBYtiMWkxKTdzYVYkk9JB2hR53BbSxO7e0NCkPAsXSsHICNEwK8oeaaJJ09gV9pbmCXXEpx3qBIIFS9KWpE1JZLtqQjwKk9LY2UUeAgEegCZAE8SwglBdJO63CJUR3EAcHS9KRsfLt0fHD8x6w+j4gSwFbpdEEwtJke1rIUdSwFtYYPuaGIOhKGuCTZEjpYUmRZOiSWWjMbEqZjAsitK2iVawtG0iF4FRkBRlGz7RpM2kTaUSYyzkSiI3E2MylHt5MFHmDm9TO5KiTJiBMmGSfE0mzEA5TZho0mLScpA2RTbChaTIhriwKjYrmOPegbIpB/atINvyhU0xmjSaFEwKJpUJw66+fw6Gcm8VlHuJUY4XBhYw5PpmqZkcMmTRMM9OQEKQAXVCm/vLTnPLCRJ8TMqLospgbEBBNucCeU7lsfFmKLBgSeqSrOku+22ZwLLhnjS3oCCRgUxJCQyAHW1HFuYmpz9VkY86oBTBoijnTxNNmkyaTCrWMzEZNkWOBhaSYrWCuVUTSYqQ+srKO7AFQ5XWEAxNGk0qyy1vuKHKcjuR72XvChIYdIFgVpQFYCLXt4oyHidg7woSAgDJDeJKBlaTVpHygFdp0ESRyjGbTIeJXDD7UZAQYHgKCQEmRpPGg7QpQjI0KZoU1RlRQsOqmMHQpOoxgYo6I6rBMBk2RTJpm/6qSXzKANOSG5R1shgXLElakrQkee63O7VFZR1JFppQ536709xv93UUlv03UqNv0udZDjClz1ljx2TYFKNJo0nBpLLSDpQoZWJVlGkzsShmK1gW3YlSBJ+JBpk2E0mxmrSalExKJpUopcl5rawIglEcSpNTWzkCDXJuK4egA3muLOTzT968oxxJd+2CfKw5jnvl8HOiSeUAlC2nY1OUQ9AIgiKVOnCDFpIimZRM2kzKgcBA4A3CwqLI02ZhNtSCJSZYyEVwgNE9KBhWxWTSZNJs0mxSHjfkYKQjKVa5NwnKvXw6DQSKcmQ9keuL8jUet4EoB9cTTRpNGk3KgcDCqihtm1gU2TwXasESEyyUIsbJPSlKMyeatJq0mpRMSlJJbia2ZCj3VskJyL0kSIqxKIp5JskWiHkmySDwcodJbhDzHJhMKuaZeLjH+fxElvJ5NY4z+omSGuDRTDLfSGpW1zLaNaKhSZtJ21pGUQ7vF5o0mjQWRYiGWRGD4UHaFMeqjoKkOFb1gVWxmFTaJhMyj7YJkknJpM2kTaUloKFJo0mjScGkYFI0KZo0mXS4KcHRoIEmLSYtJhVvPDErjo3dwGTYFK2ZxZpZAxhqETVGw6IIwTAbahEVk6EVYS2u1uJqLa7ZiihWcLEiqhVcrYhqBdvAVhvY2qyIpgVTiIZa8AxFBmZDLWKGIgO1CLIxloOJiQkMrYhsBWcroljBxYooVrCZMpkpE1kRZAU3K6JpwS0Ew2wo6wPPFkllTBz5wYFVceQIBxbFZFJZXgfKQjpQFtKJJq0mrVYEmTIyZSPbOXBJUwjBMBk2xYiGo+Bv3948rez0L18+v3/PyelDuronsf969/n9py9Pbz99/fjxzdN/3n38Kjf9+693n+T65d3n/te+ir7/9Hu/doV/fPj4nunbG/t2OP9qSnzcJd/ua3ZSBT2dsK1CzqWGin4k9RoVfYuYpwrevp2qQE9FA1WBaCoqbteitdUXPQqD01rkcxWlj/hUUQJYQ/rW+pmK4vbFakepBwVxtw5RPLdoiN01ntaB/qk65HJaB2c0+oJTllmFcD4a7JPPdPRDgaWj5/CtJT3V9VwHOObdTUHNG9K5Dsc4+7RYc5TPZM91JGdMQspq4X1rY53ah+iZEmdcZHc9VBwn+4s54jUFZDM/VHSXet6U6gxtUvvq0V9WHfW5fUW6ozfa5d5wDAwkNJ69kQ9zrT1TAdFbPkHtvOeBzjoDHBPtW66sLeFc11lnAHqDslauHgWedsaDalDRavQA87QajoUmWDMl9YNZ1ZBf15+HlrzsT8c+W1i92Q5VSOE7zCLaJEl4ahbNXbqyLl3BzAJeukTPodHqyx7AqIYeZj3X4DSkYVi1aH0DaDry8xFF8HozLbfaA7xwrsM1TvXMZC3pO/7nGrzls2cN1TYpvU4H4KoG8PdOdRTPPKsZeDi4pLpdjR6jRh3X2k6r4ZuXBirdM5Zz82qeZ2wW+MX0Wh3aHfHYlu/w8s9m28GdvJhtCa7PtoRXZ1tK12dbytdnWypXZ1uq12ebq2NztqV2ebZ51didbb557c227MWh2KLu1MKhO160xddBSXUcgreXOrZnG53OtuzYaG1hWUdtCOdNcW1UHqqbQWSMpzFPdsY2R531cJyy9B3VCCVpNQKdxqHZsdJ+WIurQzo3OFNSvP1SoRUQ9wOwV22Ae/xpoVM734YXx8Q41aKb6JpfF1UX28vXw6x9YWIlXY6qS74hqi7lalT9oBp7UXWhi1H1dn+eR9U1/MiouhQ7lmjxzCzqDX6+Xvbz9QY/X2/w8/Wyn683+Pl6g5+v1/18vcHP1xv8PN3g5+lH+/nDbKuHtryYbXSDn6c7/Dxd9vN0h5+nO/x8u8HPe2tHrmvj1o4OpS/yz6sB10+6G149ZvaMFM1I0XEJLV93Ca1cdQmtXncJja67hNauuoQYwnWf4CvZdAoxwGWv4FZk1y34JrbnFmLI1/3CAyXXHcNxztVDMuPFnIvBMdViOcPSc79OYzxb5ccaV016RIinOYDoDTA/X65awrmDia633M5HeLmm3YSE3xzbcvDT7ucV8Y4Yc1arL8fk28uqPBifYuNTA51XpXimopZyCCFe+u4HKoqqqI4Kz+YTqc3juc17KihoZ1A83dRGCJd3tdHLj2xva6OX69nb1z6qyN7GNkK6uLPd79Tzra3c9cP2tvzYjlpHTufW4eVEc8Cmz0CEg5b/61BvK9UsHIJXHd8gqdtFaueTxUs8Qa7B2nKMc1+2xUs95bJWsR7xvq4ttVhoB+ez1k0bIRyyxFhtXPILE8N8PUKMWK6HiBHr5RgR6YYY0VWyGyOmcD1GdCuSwWz14GG+rzU56bl6LvhKJQWqbqkwv1aJLSOlvFIJP8GnEyc1Z3DKjx2c3QDeXQWa7hF71HC+CqQbEvoxX87ox3xDSj/mG3L6MV9O6sd8Q1bfV7K7juQbTDXfkNh/YGebm818Q2r/kZLLuf3DzOMHa09nXrnh0D+Wy6f+sdxw7B/LDef+sVw++I/lhpN/X8nuzCvXz/7dimzPvHLD6X+sNxz/P1BywzHPcebB6TNs0UtSbR/zuFmq7WMeN72zfcxTb3nstF5/7vRBczaPeSjecMzzYHw2j3kILx/z+Cq2jnk2VSR41UlRCmiPrdf2mpOiZ34T4FQF0Q0+z8tXbfo8L1u17fNavMHnNbjs89x81a7Pc5Xs+jwvo7Dr83atDM8N1ctabVuZl7batbJ23coghOtWBiFetTIIcN3KfCWbVgYh/XNW5rwgEcr1xwgg1BsS+ODlrbYz+OAmRm54VA9rszDRgpnveW8PNafRVZy/+gfxBz/ulxPoMW3vXtMRX771cf2BP4h3PPEH8fIjf48qsvkmTbz60N9+pzrv0sCPfOyvn4smNY+jib1848zTIT+BNHRAPT1GAO8FqV1nB166as/ZAdyQCAC4IREAcDkRAHBDIsBXsuvs8HoiwK3I9ps5vp3tHSOA98LU7gHeIyWXD/Cezbzzo3PwslbbM8/LWm3OPC+VsD3zvDeetmeel7XanHkp3jDzXCW7M897cWp35qV4w8zz7Wxz5rk5q80DvAdKrh/gHWcenr9FAV4yYTv0zq6xbj7CC17eau8Z3gcV2d0DuGmr7T2Am+vZ3AO4I1ya/rzBMx0vA2f3DaYe7+uzTfwT6+fNcVbXGDRgjTG0VzaHdPrVVF4X6GU12Jzx9OwMvDeptt1NiZfdjZdP2HY3Xt5q2914matNd+O/xrTpblwlu+7Gy/XsuhuvItvuxrezTXdTww3uxldyg7s5zrx8+ig+VLyeLwLv7artfBF4qavtfBF4uZHtfBG4b0ht5YseNWcvXwRe4mo3X/RofPbyReClrvbyRQ9U7OSLdlU4+SJv5tnYJsTzV27Bfc9Kn1GsdJh48aUK7zwA9Y2gfP4yjzv/qwY0mQ6D+nL+35G1gutZK7gjawV3ZK3getYK7shawR1ZK7gha+VWZNvz+na26Xm9vNW25/WV3OB5jzPv/BllDPG650Uv6bTteTHgDZ4Xwx0/l4bh8u+lPWrOnudFN3216Xkfjc+e50Uve7XneR+o2PG8uype+aRGJn0qP1M9fcEZ4w05AYyXcwIYb8gJYLwhJ4Dxck4A4w05AV/J7m91wfWcgFuRXYf1wM42f64LbsgJPFJyPSdwnHnt9NFChBtyAgiXcwIIN+QEEG7ICSBezgkg3pAT8JXszjy8nhNwK7I98+CGnADiDTmBB0puCBUPM6/F0+NRxHZDqOgmsLZDRTfrsx0qer/Oth8quj//txcqPmjOZqjo/QLgdqj4YHw2Q0Xvt/M2Q0VfxVaouKnitaFipWjT5vTxEe+s134QO+PxIZaXy0h2DVXN9PBD1Cl++/Zz//Tutw+fn/1v599Y0+cP7379+H5+/OPrp98Of/3y37/WX9b/lv7X5z9/e//718/vWZP9l+n9n5+ob7cI4Oc3T8ifML+hlPsn/o8ZfqIeMxDkn79xXf4H",
7143
+ "debug_symbols": "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",
7263
7144
  "is_unconstrained": true,
7264
7145
  "name": "public_dispatch"
7265
7146
  },
@@ -7392,17 +7273,17 @@
7392
7273
  ],
7393
7274
  "return_type": null
7394
7275
  },
7395
- "bytecode": "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",
7276
+ "bytecode": "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",
7396
7277
  "custom_attributes": [
7397
7278
  "abi_utility"
7398
7279
  ],
7399
- "debug_symbols": "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",
7280
+ "debug_symbols": "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",
7400
7281
  "is_unconstrained": true,
7401
7282
  "name": "sync_state"
7402
7283
  }
7403
7284
  ],
7404
7285
  "name": "AuthRegistry",
7405
- "noir_version": "1.0.0-beta.21+4f77d904a259301b1784dbb1e1e7b82e5e0e2260",
7286
+ "noir_version": "1.0.0-beta.21+f1a4575adac59af0a86b036cf73ff5883d142a91",
7406
7287
  "outputs": {
7407
7288
  "globals": {
7408
7289
  "storage": [