@aztec/protocol-contracts 6.0.0-nightly.20260604 → 6.0.0-nightly.20260721

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.
@@ -9,10 +9,14 @@
9
9
  {
10
10
  "name": "aes128_encrypt_padded_input",
11
11
  "start": 824
12
+ },
13
+ {
14
+ "name": "tests::encrypt",
15
+ "start": 921
12
16
  }
13
17
  ],
14
18
  "path": "std/aes128.nr",
15
- "source": "// docs:start:aes128\n/// Given a plaintext as an array of bytes, returns the corresponding aes128 ciphertext (CBC mode). Input padding is performed using PKCS#7, so that the output length is `input.len() + (16 - input.len() % 16)`.\npub fn aes128_encrypt<let N: u32>(\n input: [u8; N],\n iv: [u8; 16],\n key: [u8; 16],\n) -> [u8; N + 16 - N % 16] {\n let padding_length = (16 - N % 16) as u8;\n let mut padded_input: [u8; N + 16 - N % 16] = [0; N + 16 - N % 16];\n for i in 0..N {\n padded_input[i] = input[i];\n }\n for i in N..N + 16 - N % 16 {\n padded_input[i] = padding_length;\n }\n let output = aes128_encrypt_padded_input(padded_input, iv, key);\n output\n}\n\n#[foreign(aes128_encrypt)]\nfn aes128_encrypt_padded_input<let N: u32>(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; N] {}\n\n// docs:end:aes128\n"
19
+ "source": "// docs:start:aes128\n/// Given a plaintext as an array of bytes, returns the corresponding aes128 ciphertext (CBC mode). Input padding is performed using PKCS#7, so that the output length is `input.len() + (16 - input.len() % 16)`.\npub fn aes128_encrypt<let N: u32>(\n input: [u8; N],\n iv: [u8; 16],\n key: [u8; 16],\n) -> [u8; N + 16 - N % 16] {\n let padding_length = (16 - N % 16) as u8;\n let mut padded_input: [u8; N + 16 - N % 16] = [0; N + 16 - N % 16];\n for i in 0..N {\n padded_input[i] = input[i];\n }\n for i in N..N + 16 - N % 16 {\n padded_input[i] = padding_length;\n }\n let output = aes128_encrypt_padded_input(padded_input, iv, key);\n output\n}\n\n#[foreign(aes128_encrypt)]\nfn aes128_encrypt_padded_input<let N: u32>(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; N] {}\n\n// docs:end:aes128\n\nmod tests {\n use super::aes128_encrypt;\n\n #[test]\n fn encrypt() {\n let input = \"kevlovesrust\".as_bytes();\n let iv = \"0000000000000000\".as_bytes();\n let key = \"0000000000000000\".as_bytes();\n let output = [244, 14, 126, 172, 171, 40, 208, 186, 173, 184, 226, 105, 238, 122, 205, 191];\n assert_eq(aes128_encrypt(input, iv, key), output);\n }\n}\n"
16
20
  },
17
21
  "16": {
18
22
  "function_locations": [
@@ -58,183 +62,223 @@
58
62
  },
59
63
  {
60
64
  "name": "Field::from_le_bytes",
61
- "start": 7918
65
+ "start": 8073
62
66
  },
63
67
  {
64
68
  "name": "Field::from_be_bytes",
65
- "start": 8476
69
+ "start": 8820
70
+ },
71
+ {
72
+ "name": "Field::from_le_bytes_checked",
73
+ "start": 9611
74
+ },
75
+ {
76
+ "name": "Field::from_be_bytes_checked",
77
+ "start": 10620
66
78
  },
67
79
  {
68
80
  "name": "__assert_max_bit_size",
69
- "start": 8757
81
+ "start": 11202
70
82
  },
71
83
  {
72
84
  "name": "__to_le_radix",
73
- "start": 8885
85
+ "start": 11330
74
86
  },
75
87
  {
76
88
  "name": "__to_be_radix",
77
- "start": 9013
89
+ "start": 11458
78
90
  },
79
91
  {
80
92
  "name": "__to_le_bits",
81
- "start": 9734
93
+ "start": 12179
82
94
  },
83
95
  {
84
96
  "name": "__to_be_bits",
85
- "start": 10452
97
+ "start": 12897
86
98
  },
87
99
  {
88
100
  "name": "modulus_num_bits",
89
- "start": 10527
101
+ "start": 12972
90
102
  },
91
103
  {
92
104
  "name": "modulus_be_bits",
93
- "start": 10603
105
+ "start": 13048
94
106
  },
95
107
  {
96
108
  "name": "modulus_le_bits",
97
- "start": 10679
109
+ "start": 13124
98
110
  },
99
111
  {
100
112
  "name": "modulus_be_bytes",
101
- "start": 10755
113
+ "start": 13200
102
114
  },
103
115
  {
104
116
  "name": "modulus_le_bytes",
105
- "start": 10831
117
+ "start": 13276
106
118
  },
107
119
  {
108
120
  "name": "__field_less_than",
109
- "start": 10992
121
+ "start": 13437
110
122
  },
111
123
  {
112
124
  "name": "field_less_than",
113
- "start": 11068
114
- },
115
- {
116
- "name": "bytes32_to_field",
117
- "start": 11210
125
+ "start": 13513
118
126
  },
119
127
  {
120
128
  "name": "lt_fallback",
121
- "start": 11617
129
+ "start": 13589
122
130
  },
123
131
  {
124
132
  "name": "tests::test_to_be_bits",
125
- "start": 12579
133
+ "start": 14551
126
134
  },
127
135
  {
128
136
  "name": "tests::test_to_le_bits",
129
- "start": 12852
137
+ "start": 14824
130
138
  },
131
139
  {
132
140
  "name": "tests::test_to_be_bytes",
133
- "start": 13127
141
+ "start": 15099
134
142
  },
135
143
  {
136
144
  "name": "tests::test_to_le_bytes",
137
- "start": 13433
145
+ "start": 15405
138
146
  },
139
147
  {
140
148
  "name": "tests::test_to_be_radix",
141
- "start": 13739
149
+ "start": 15711
142
150
  },
143
151
  {
144
152
  "name": "tests::test_to_le_radix",
145
- "start": 14321
153
+ "start": 16293
146
154
  },
147
155
  {
148
156
  "name": "tests::test_to_le_radix_1",
149
- "start": 14921
157
+ "start": 16893
150
158
  },
151
159
  {
152
160
  "name": "tests::test_to_le_radix_brillig_1",
153
- "start": 15374
161
+ "start": 17346
154
162
  },
155
163
  {
156
164
  "name": "tests::test_to_le_radix_3",
157
- "start": 15728
165
+ "start": 17700
158
166
  },
159
167
  {
160
168
  "name": "tests::test_to_le_radix_brillig_3",
161
- "start": 16039
169
+ "start": 18011
162
170
  },
163
171
  {
164
172
  "name": "tests::test_to_le_radix_512",
165
- "start": 16467
173
+ "start": 18439
166
174
  },
167
175
  {
168
176
  "name": "tests::not_enough_limbs_brillig",
169
- "start": 16876
177
+ "start": 18848
170
178
  },
171
179
  {
172
180
  "name": "tests::not_enough_limbs",
173
- "start": 17072
181
+ "start": 19044
182
+ },
183
+ {
184
+ "name": "tests::non_zero_field_to_le_bytes_zero_limbs",
185
+ "start": 19274
186
+ },
187
+ {
188
+ "name": "tests::non_zero_field_to_be_bytes_zero_limbs",
189
+ "start": 19469
174
190
  },
175
191
  {
176
192
  "name": "tests::test_field_less_than",
177
- "start": 17214
193
+ "start": 19576
178
194
  },
179
195
  {
180
196
  "name": "tests::test_large_field_values_unconstrained",
181
- "start": 17469
197
+ "start": 19831
182
198
  },
183
199
  {
184
200
  "name": "tests::test_large_field_values",
185
- "start": 17922
201
+ "start": 20284
186
202
  },
187
203
  {
188
204
  "name": "tests::test_decomposition_edge_cases",
189
- "start": 18369
205
+ "start": 20731
190
206
  },
191
207
  {
192
208
  "name": "tests::test_pow_32",
193
- "start": 18959
209
+ "start": 21321
194
210
  },
195
211
  {
196
212
  "name": "tests::test_sgn0",
197
- "start": 19288
213
+ "start": 21650
198
214
  },
199
215
  {
200
216
  "name": "tests::test_bit_decomposition_overflow",
201
- "start": 19710
217
+ "start": 22072
202
218
  },
203
219
  {
204
220
  "name": "tests::test_byte_decomposition_overflow",
205
- "start": 19992
221
+ "start": 22354
206
222
  },
207
223
  {
208
224
  "name": "tests::test_to_from_be_bytes_bn254_edge_cases",
209
- "start": 20209
225
+ "start": 22571
210
226
  },
211
227
  {
212
228
  "name": "tests::test_to_from_le_bytes_bn254_edge_cases",
213
- "start": 22160
229
+ "start": 24522
230
+ },
231
+ {
232
+ "name": "tests::test_from_le_bytes_checked_accepts_modulus_minus_one",
233
+ "start": 26457
234
+ },
235
+ {
236
+ "name": "tests::test_from_le_bytes_checked_rejects_modulus",
237
+ "start": 26936
238
+ },
239
+ {
240
+ "name": "tests::test_from_le_bytes_checked_rejects_modulus_plus_one",
241
+ "start": 27321
242
+ },
243
+ {
244
+ "name": "tests::test_from_be_bytes_checked_accepts_modulus_minus_one",
245
+ "start": 27776
246
+ },
247
+ {
248
+ "name": "tests::test_from_be_bytes_checked_rejects_modulus",
249
+ "start": 28265
250
+ },
251
+ {
252
+ "name": "tests::test_from_be_bytes_checked_rejects_modulus_plus_one",
253
+ "start": 28650
254
+ },
255
+ {
256
+ "name": "tests::test_from_bytes_checked_small_n",
257
+ "start": 29094
214
258
  },
215
259
  {
216
260
  "name": "tests::from_le_bits",
217
- "start": 24245
261
+ "start": 29739
218
262
  },
219
263
  {
220
264
  "name": "tests::from_be_bits",
221
- "start": 24792
265
+ "start": 30286
222
266
  },
223
267
  {
224
268
  "name": "tests::test_to_from_be_bits_bn254_edge_cases",
225
- "start": 25038
269
+ "start": 30532
226
270
  },
227
271
  {
228
272
  "name": "tests::test_to_from_le_bits_bn254_edge_cases",
229
- "start": 26971
273
+ "start": 32465
230
274
  },
231
275
  {
232
276
  "name": "tests::max_bit_size_too_large",
233
- "start": 28903
277
+ "start": 34397
234
278
  }
235
279
  ],
236
280
  "path": "std/field/mod.nr",
237
- "source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size<let BIT_SIZE: u32>(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[bool; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits<let N: u32>(self: Self) -> [bool; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[bool; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits<let N: u32>(self: Self) -> [bool; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [bool; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = false if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = true.\n pub fn sgn0(self) -> bool {\n (self as u8) % 2 == 1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[bool; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits<let N: u32>(value: Field) -> [bool; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[bool; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits<let N: u32>(value: Field) -> [bool; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [bool] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [bool] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [bool; 8] = field.to_be_bits();\n assert_eq(bits, [false, false, false, false, false, false, true, false]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [bool; 8] = field.to_le_bits();\n assert_eq(bits, [false, true, false, false, false, false, false, false]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [bool; 64] = large_field.to_le_bits();\n assert_eq(bits[0], true);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [bool; 64] = large_val.to_le_bits();\n assert_eq(bits[0], true);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [bool; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [false; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [bool; 8] = 1.to_le_bits();\n let expected: [bool; 8] = [true, false, false, false, false, false, false, false];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [bool; 8] = 4.to_le_bits();\n let expected: [bool; 8] = [false, false, true, false, false, false, false, false];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), false);\n assert_eq(2.sgn0(), false);\n assert_eq(4.sgn0(), false);\n assert_eq(100.sgn0(), false);\n\n assert_eq(1.sgn0(), true);\n assert_eq(3.sgn0(), true);\n assert_eq(5.sgn0(), true);\n assert_eq(101.sgn0(), true);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [bool; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits<let N: u32>(bits: [bool; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits<let N: u32>(bits: [bool; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [bool; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1]);\n p_minus_1_bits[254 - 1] = false;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [bool; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [bool; 254] = modulus_be_bits().as_array();\n assert(!p_plus_4_bits[254 - 3]);\n p_plus_4_bits[254 - 3] = true;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [bool; 254] = p_plus_4.to_be_bits();\n assert(p_plus_4_converted_bits[254 - 3]);\n p_plus_4_converted_bits[254 - 3] = false;\n assert_eq(p_plus_4_converted_bits, [false; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bits produces 254 false values\n let p_bits: [bool; 254] = 0.to_be_bits();\n assert_eq(p_bits, [false; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [bool; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0]);\n p_minus_1_bits[0] = false;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [bool; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [bool; 254] = modulus_le_bits().as_array();\n assert(!p_plus_4_bits[2]);\n p_plus_4_bits[2] = true;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [bool; 254] = p_plus_4.to_le_bits();\n assert(p_plus_4_converted_bits[2]);\n p_plus_4_converted_bits[2] = false;\n assert_eq(p_plus_4_converted_bits, [false; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bits produces 254 false values\n let p_bits: [bool; 254] = 0.to_le_bits();\n assert_eq(p_bits, [false; 254]);\n }\n }\n\n #[test(should_fail_with = \"call to assert_max_bit_size\")]\n fn max_bit_size_too_large() {\n let x: Field = 0x010000;\n x.assert_max_bit_size::<16>();\n }\n\n}\n"
281
+ "source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size<let BIT_SIZE: u32>(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[bool; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits<let N: u32>(self: Self) -> [bool; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[bool; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits<let N: u32>(self: Self) -> [bool; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [bool; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = false if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = true.\n pub fn sgn0(self) -> bool {\n (self as u8) % 2 == 1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n ///\n /// # Failures\n /// `N` must be no greater than the number of bytes required to represent the field modulus\n // docs:start:from_le_bytes\n pub fn from_le_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n // docs:end:from_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n ///\n /// # Failures\n /// `N` must be no greater than the number of bytes required to represent the field modulus\n // docs:start:from_be_bytes\n pub fn from_be_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n // docs:end:from_be_bytes\n static_assert(\n N <= modulus_be_bytes().len(),\n \"N must be less than or equal to modulus_be_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a little endian byte array to a field element, asserting that the input is a\n /// canonical representation (strictly less than the field modulus).\n ///\n /// # Failures\n /// Causes a constraint failure if `bytes` encodes a value greater than or equal to the\n /// field modulus.\n // docs:start:from_le_bytes_checked\n pub fn from_le_bytes_checked<let N: u32>(bytes: [u8; N]) -> Field {\n // docs:end:from_le_bytes_checked\n let p = modulus_le_bytes();\n let mut ok = N != p.len();\n for i in 0..N {\n if !ok {\n if bytes[N - 1 - i] != p[N - 1 - i] {\n assert(\n bytes[N - 1 - i] < p[N - 1 - i],\n \"input bytes are not a canonical field representation\",\n );\n ok = true;\n }\n }\n }\n assert(ok, \"input bytes are not a canonical field representation\");\n Field::from_le_bytes(bytes)\n }\n\n /// Convert a big endian byte array to a field element, asserting that the input is a\n /// canonical representation (strictly less than the field modulus).\n ///\n /// # Failures\n /// Causes a constraint failure if `bytes` encodes a value greater than or equal to the\n /// field modulus.\n // docs:start:from_be_bytes_checked\n pub fn from_be_bytes_checked<let N: u32>(bytes: [u8; N]) -> Field {\n // docs:end:from_be_bytes_checked\n let p = modulus_be_bytes();\n let mut ok = N != p.len();\n for i in 0..N {\n if !ok {\n if bytes[i] != p[i] {\n assert(bytes[i] < p[i], \"input bytes are not a canonical field representation\");\n ok = true;\n }\n }\n }\n assert(ok, \"input bytes are not a canonical field representation\");\n Field::from_be_bytes(bytes)\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[bool; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits<let N: u32>(value: Field) -> [bool; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[bool; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits<let N: u32>(value: Field) -> [bool; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [bool] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [bool] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [bool; 8] = field.to_be_bits();\n assert_eq(bits, [false, false, false, false, false, false, true, false]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [bool; 8] = field.to_le_bits();\n assert_eq(bits, [false, true, false, false, false, false, false, false]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 0 limbs\")]\n unconstrained fn non_zero_field_to_le_bytes_zero_limbs() {\n let _: [u8; 0] = 5.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 0 limbs\")]\n unconstrained fn non_zero_field_to_be_bytes_zero_limbs() {\n let _: [u8; 0] = 5.to_be_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [bool; 64] = large_field.to_le_bits();\n assert_eq(bits[0], true);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [bool; 64] = large_val.to_le_bits();\n assert_eq(bits[0], true);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [bool; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [false; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [bool; 8] = 1.to_le_bits();\n let expected: [bool; 8] = [true, false, false, false, false, false, false, false];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [bool; 8] = 4.to_le_bits();\n let expected: [bool; 8] = [false, false, true, false, false, false, false, false];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), false);\n assert_eq(2.sgn0(), false);\n assert_eq(4.sgn0(), false);\n assert_eq(100.sgn0(), false);\n\n assert_eq(1.sgn0(), true);\n assert_eq(3.sgn0(), true);\n assert_eq(5.sgn0(), true);\n assert_eq(101.sgn0(), true);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [bool; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_from_le_bytes_checked_accepts_modulus_minus_one() {\n if crate::compat::is_bn254() {\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n let p_minus_1 = Field::from_le_bytes_checked::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n }\n }\n\n #[test(should_fail_with = \"input bytes are not a canonical field representation\")]\n fn test_from_le_bytes_checked_rejects_modulus() {\n if crate::compat::is_bn254() {\n let _ = Field::from_le_bytes_checked::<32>(modulus_le_bytes().as_array());\n } else {\n panic(\"input bytes are not a canonical field representation\");\n }\n }\n\n #[test(should_fail_with = \"input bytes are not a canonical field representation\")]\n fn test_from_le_bytes_checked_rejects_modulus_plus_one() {\n if crate::compat::is_bn254() {\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n let _ = Field::from_le_bytes_checked::<32>(p_plus_1_bytes);\n } else {\n panic(\"input bytes are not a canonical field representation\");\n }\n }\n\n #[test]\n fn test_from_be_bytes_checked_accepts_modulus_minus_one() {\n if crate::compat::is_bn254() {\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n let p_minus_1 = Field::from_be_bytes_checked::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n }\n }\n\n #[test(should_fail_with = \"input bytes are not a canonical field representation\")]\n fn test_from_be_bytes_checked_rejects_modulus() {\n if crate::compat::is_bn254() {\n let _ = Field::from_be_bytes_checked::<32>(modulus_be_bytes().as_array());\n } else {\n panic(\"input bytes are not a canonical field representation\");\n }\n }\n\n #[test(should_fail_with = \"input bytes are not a canonical field representation\")]\n fn test_from_be_bytes_checked_rejects_modulus_plus_one() {\n if crate::compat::is_bn254() {\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n let _ = Field::from_be_bytes_checked::<32>(p_plus_1_bytes);\n } else {\n panic(\"input bytes are not a canonical field representation\");\n }\n }\n\n #[test]\n fn test_from_bytes_checked_small_n() {\n // For N < modulus_bytes().len(), the input cannot overflow the modulus, so the checked\n // variants behave identically to the unchecked ones.\n let le_bytes: [u8; 8] = [3, 1, 0, 0, 0, 0, 0, 0];\n assert_eq(Field::from_le_bytes_checked::<8>(le_bytes), 259);\n let be_bytes: [u8; 8] = [0, 0, 0, 0, 0, 0, 1, 3];\n assert_eq(Field::from_be_bytes_checked::<8>(be_bytes), 259);\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits<let N: u32>(bits: [bool; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits<let N: u32>(bits: [bool; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [bool; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1]);\n p_minus_1_bits[254 - 1] = false;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [bool; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [bool; 254] = modulus_be_bits().as_array();\n assert(!p_plus_4_bits[254 - 3]);\n p_plus_4_bits[254 - 3] = true;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [bool; 254] = p_plus_4.to_be_bits();\n assert(p_plus_4_converted_bits[254 - 3]);\n p_plus_4_converted_bits[254 - 3] = false;\n assert_eq(p_plus_4_converted_bits, [false; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bits produces 254 false values\n let p_bits: [bool; 254] = 0.to_be_bits();\n assert_eq(p_bits, [false; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [bool; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0]);\n p_minus_1_bits[0] = false;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [bool; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [bool; 254] = modulus_le_bits().as_array();\n assert(!p_plus_4_bits[2]);\n p_plus_4_bits[2] = true;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [bool; 254] = p_plus_4.to_le_bits();\n assert(p_plus_4_converted_bits[2]);\n p_plus_4_converted_bits[2] = false;\n assert_eq(p_plus_4_converted_bits, [false; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bits produces 254 false values\n let p_bits: [bool; 254] = 0.to_le_bits();\n assert_eq(p_bits, [false; 254]);\n }\n }\n\n #[test(should_fail_with = \"call to assert_max_bit_size\")]\n fn max_bit_size_too_large() {\n let x: Field = 0x010000;\n x.assert_max_bit_size::<16>();\n }\n\n}\n"
238
282
  },
239
283
  "17": {
240
284
  "function_locations": [
@@ -366,31 +410,63 @@
366
410
  "name": "<impl Hash for [T]>::hash",
367
411
  "start": 8103
368
412
  },
413
+ {
414
+ "name": "<impl Hash for (A,)>::hash",
415
+ "start": 8325
416
+ },
369
417
  {
370
418
  "name": "<impl Hash for (A, B)>::hash",
371
- "start": 8343
419
+ "start": 8494
372
420
  },
373
421
  {
374
422
  "name": "<impl Hash for (A, B, C)>::hash",
375
- "start": 8559
423
+ "start": 8710
376
424
  },
377
425
  {
378
426
  "name": "<impl Hash for (A, B, C, D)>::hash",
379
- "start": 8822
427
+ "start": 8973
380
428
  },
381
429
  {
382
430
  "name": "<impl Hash for (A, B, C, D, E)>::hash",
383
- "start": 9132
431
+ "start": 9283
432
+ },
433
+ {
434
+ "name": "<impl Hash for (A, B, C, D, E, F)>::hash",
435
+ "start": 9640
436
+ },
437
+ {
438
+ "name": "<impl Hash for (A, B, C, D, E, F, G)>::hash",
439
+ "start": 10044
440
+ },
441
+ {
442
+ "name": "<impl Hash for (A, B, C, D, E, F, G, H_)>::hash",
443
+ "start": 10498
444
+ },
445
+ {
446
+ "name": "<impl Hash for (A, B, C, D, E, F, G, H_, I)>::hash",
447
+ "start": 10999
448
+ },
449
+ {
450
+ "name": "<impl Hash for (A, B, C, D, E, F, G, H_, I, J)>::hash",
451
+ "start": 11547
452
+ },
453
+ {
454
+ "name": "<impl Hash for (A, B, C, D, E, F, G, H_, I, J, K)>::hash",
455
+ "start": 12142
456
+ },
457
+ {
458
+ "name": "<impl Hash for (A, B, C, D, E, F, G, H_, I, J, K, L)>::hash",
459
+ "start": 12785
384
460
  },
385
461
  {
386
462
  "name": "assert_pedersen",
387
- "start": 9528
463
+ "start": 13379
388
464
  }
389
465
  ],
390
466
  "path": "std/hash/mod.nr",
391
- "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\nuse crate::static_assert;\n\n/// The size of the state accepted by the backend in `poseidon2_permutation`.\nglobal POSEIDON2_CONFIG_STATE_SIZE: u32 = poseidon2_config_state_size();\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3<let N: u32>(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment<let N: u32>(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator<let N: u32>(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n points[i] = EmbeddedCurveScalar::from_field(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash<let N: u32>(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator<let N: u32>(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n crate::assert_constant(separator);\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = EmbeddedCurveScalar::from_field(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n crate::assert_constant(starting_index);\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\npub fn poseidon2_permutation<let N: u32>(input: [Field; N]) -> [Field; N] {\n static_assert(\n N == POSEIDON2_CONFIG_STATE_SIZE,\n f\"the input length must equal the state size in the Poseidon2 config; expected {POSEIDON2_CONFIG_STATE_SIZE}, got {N}\",\n );\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal<let N: u32>(input: [Field; N]) -> [Field; N] {}\n\n#[foreign(poseidon2_config_state_size)]\ncomptime fn poseidon2_config_state_size() -> u32 {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash<H>(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n /// Returns the hash value without consuming the hasher.\n /// Override this for more efficient implementations that avoid copying.\n /// TODO: deprecate finish() and replace it\n fn finish_ref(&self) -> Field {\n (*self).finish()\n }\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault<H>;\n\nimpl<H> BuildHasher for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl<H> Default for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash<H>(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl<T, let N: u32> Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<T> Hash for [T]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<A, B> Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl<A, B, C> Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl<A, B, C, D> Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl<A, B, C, D, E> Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n },\n );\n}\n"
467
+ "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\nuse crate::static_assert;\n\n/// The size of the state accepted by the backend in `poseidon2_permutation`.\nglobal POSEIDON2_CONFIG_STATE_SIZE: u32 = poseidon2_config_state_size();\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3<let N: u32>(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment<let N: u32>(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator<let N: u32>(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n points[i] = EmbeddedCurveScalar::from_field(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash<let N: u32>(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator<let N: u32>(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n crate::assert_constant(separator);\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = EmbeddedCurveScalar::from_field(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n crate::assert_constant(starting_index);\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\npub fn poseidon2_permutation<let N: u32>(input: [Field; N]) -> [Field; N] {\n static_assert(\n N == POSEIDON2_CONFIG_STATE_SIZE,\n f\"the input length must equal the state size in the Poseidon2 config; expected {POSEIDON2_CONFIG_STATE_SIZE}, got {N}\",\n );\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal<let N: u32>(input: [Field; N]) -> [Field; N] {}\n\n#[foreign(poseidon2_config_state_size)]\ncomptime fn poseidon2_config_state_size() -> u32 {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash<H>(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n /// Returns the hash value without consuming the hasher.\n /// Override this for more efficient implementations that avoid copying.\n /// TODO: deprecate finish() and replace it\n fn finish_ref(&self) -> Field {\n (*self).finish()\n }\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault<H>;\n\nimpl<H> BuildHasher for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl<H> Default for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash<H>(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl<T, let N: u32> Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<T> Hash for [T]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<A> Hash for (A,)\nwhere\n A: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n }\n}\n\nimpl<A, B> Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl<A, B, C> Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl<A, B, C, D> Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl<A, B, C, D, E> Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\nimpl<A, B, C, D, E, F> Hash for (A, B, C, D, E, F)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n F: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n self.5.hash(state);\n }\n}\n\nimpl<A, B, C, D, E, F, G> Hash for (A, B, C, D, E, F, G)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n F: Hash,\n G: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n self.5.hash(state);\n self.6.hash(state);\n }\n}\n\nimpl<A, B, C, D, E, F, G, H_> Hash for (A, B, C, D, E, F, G, H_)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n F: Hash,\n G: Hash,\n H_: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n self.5.hash(state);\n self.6.hash(state);\n self.7.hash(state);\n }\n}\n\nimpl<A, B, C, D, E, F, G, H_, I> Hash for (A, B, C, D, E, F, G, H_, I)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n F: Hash,\n G: Hash,\n H_: Hash,\n I: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n self.5.hash(state);\n self.6.hash(state);\n self.7.hash(state);\n self.8.hash(state);\n }\n}\n\nimpl<A, B, C, D, E, F, G, H_, I, J> Hash for (A, B, C, D, E, F, G, H_, I, J)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n F: Hash,\n G: Hash,\n H_: Hash,\n I: Hash,\n J: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n self.5.hash(state);\n self.6.hash(state);\n self.7.hash(state);\n self.8.hash(state);\n self.9.hash(state);\n }\n}\n\nimpl<A, B, C, D, E, F, G, H_, I, J, K> Hash for (A, B, C, D, E, F, G, H_, I, J, K)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n F: Hash,\n G: Hash,\n H_: Hash,\n I: Hash,\n J: Hash,\n K: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n self.5.hash(state);\n self.6.hash(state);\n self.7.hash(state);\n self.8.hash(state);\n self.9.hash(state);\n self.10.hash(state);\n }\n}\n\nimpl<A, B, C, D, E, F, G, H_, I, J, K, L> Hash for (A, B, C, D, E, F, G, H_, I, J, K, L)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n F: Hash,\n G: Hash,\n H_: Hash,\n I: Hash,\n J: Hash,\n K: Hash,\n L: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n self.5.hash(state);\n self.6.hash(state);\n self.7.hash(state);\n self.8.hash(state);\n self.9.hash(state);\n self.10.hash(state);\n self.11.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n },\n );\n}\n"
392
468
  },
393
- "180": {
469
+ "179": {
394
470
  "function_locations": [
395
471
  {
396
472
  "name": "sha256_to_field",
@@ -512,7 +588,7 @@
512
588
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr",
513
589
  "source": "mod poseidon2_chunks;\n\nuse crate::{\n abis::{\n contract_class_function_leaf_preimage::ContractClassFunctionLeafPreimage,\n function_selector::FunctionSelector, nullifier::Nullifier, private_log::PrivateLog,\n transaction::tx_request::TxRequest,\n },\n address::{AztecAddress, EthAddress},\n constants::{\n CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, DOM_SEP__NOTE_HASH_NONCE,\n DOM_SEP__PRIVATE_LOG_FIRST_FIELD, DOM_SEP__SILOED_NOTE_HASH, DOM_SEP__SILOED_NULLIFIER,\n DOM_SEP__UNIQUE_NOTE_HASH, FUNCTION_TREE_HEIGHT, NULL_MSG_SENDER_CONTRACT_ADDRESS,\n TWO_POW_64,\n },\n merkle_tree::root_from_sibling_path,\n messaging::l2_to_l1_message::L2ToL1Message,\n poseidon2::Poseidon2Sponge,\n side_effect::{Counted, Scoped},\n traits::{FromField, Hash, ToField},\n utils::field::{field_from_bytes, field_from_bytes_32_trunc},\n};\n\npub use poseidon2_chunks::poseidon2_absorb_in_chunks_existing_sponge;\nuse poseidon2_chunks::poseidon2_absorb_in_chunks;\nuse std::embedded_curve_ops::EmbeddedCurveScalar;\n\n// TODO: refactor these into their own files: sha256, poseidon2, some protocol-specific hash computations, some merkle computations.\n\npub fn sha256_to_field<let N: u32>(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256::digest(bytes_to_hash);\n let hash_in_a_field = field_from_bytes_32_trunc(sha256_hashed);\n\n hash_in_a_field\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT],\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(\n function_leaf,\n function_leaf_index,\n function_leaf_sibling_path,\n )\n}\n\n/// Siloing in the context of Aztec refers to the process of hashing a note hash with a contract address (this way\n/// the note hash is scoped to a specific contract). This is used to prevent intermingling of notes between contracts.\npub fn compute_siloed_note_hash(contract_address: AztecAddress, note_hash: Field) -> Field {\n poseidon2_hash_with_separator(\n [contract_address.to_field(), note_hash],\n DOM_SEP__SILOED_NOTE_HASH,\n )\n}\n\n/// Computes unique, siloed note hashes from siloed note hashes.\n///\n/// The protocol injects uniqueness into every note_hash, so that every single note_hash in the\n/// tree is unique. This prevents faerie gold attacks, where a malicious sender could create\n/// two identical note_hashes for a recipient (meaning only one would be nullifiable in future).\n///\n/// Most privacy protocols will inject the note's leaf_index (its position in the Note Hashes Tree)\n/// into the note, but this requires the creator of a note to wait until their tx is included in\n/// a block to know the note's final note hash (the unique, siloed note hash), because inserting\n/// leaves into trees is the job of a block producer.\n///\n/// We took a different approach so that the creator of a note will know each note's unique, siloed\n/// note hash before broadcasting their tx to the network.\n/// (There was also a historical requirement relating to \"chained transactions\" -- a feature that\n/// Aztec Connect had to enable notes to be spent from distinct txs earlier in the same block,\n/// and hence before an archive block root had been established for that block -- but that feature\n/// was abandoned for the Aztec Network for having too many bad tradeoffs).\n///\n/// (\n/// Edit: it is no longer true that all final note_hashes will be known by the creator of a tx\n/// before they send it to the network. If a tx makes public function calls, then _revertible_\n/// note_hashes that are created in private will not be made unique in private by the Reset circuit,\n/// but will instead be made unique by the AVM, because the `note_index_in_tx` will not be known\n/// until the AVM has executed the public functions of the tx. (See an explanation in\n/// reset_output_composer.nr for why).\n/// For some such txs, the `note_index_in_tx` might still be predictable through simulation, but\n/// for txs whose public functions create a varying number of non-revertible notes (determined at\n/// runtime), the `note_index_in_tx` will not be deterministically derivable before submitting the\n/// tx to the network.\n/// )\n///\n/// We use the `first_nullifier` of a tx as a seed of uniqueness. We have a guarantee that there will\n/// always be at least one nullifier per tx, because the init circuit will create one if one isn't\n/// created naturally by any functions of the tx. (Search \"protocol_nullifier\").\n/// We combine the `first_nullifier` with the note's index (its position within this tx's new\n/// note_hashes array) (`note_index_in_tx`) to get a truly unique value to inject into a note, which\n/// we call a `note_nonce`.\npub fn compute_unique_note_hash(note_nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [note_nonce, siloed_note_hash];\n poseidon2_hash_with_separator(inputs, DOM_SEP__UNIQUE_NOTE_HASH)\n}\n\npub fn compute_note_hash_nonce(first_nullifier_in_tx: Field, note_index_in_tx: u32) -> Field {\n // Hashing the first nullifier with note index in tx is guaranteed to be unique (because all nullifiers are also\n // unique).\n poseidon2_hash_with_separator(\n [first_nullifier_in_tx, note_index_in_tx as Field],\n DOM_SEP__NOTE_HASH_NONCE,\n )\n}\n\npub fn compute_note_nonce_and_unique_note_hash(\n siloed_note_hash: Field,\n first_nullifier: Field,\n note_index_in_tx: u32,\n) -> Field {\n let note_nonce = compute_note_hash_nonce(first_nullifier, note_index_in_tx);\n compute_unique_note_hash(note_nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(contract_address: AztecAddress, nullifier: Field) -> Field {\n poseidon2_hash_with_separator(\n [contract_address.to_field(), nullifier],\n DOM_SEP__SILOED_NULLIFIER,\n )\n}\n\npub fn create_protocol_nullifier(tx_request: TxRequest) -> Scoped<Counted<Nullifier>> {\n // The protocol nullifier is ascribed a special side-effect counter of 1. No other side-effect\n // can have counter 1 (see `validate_as_first_call` for that assertion).\n Nullifier { value: tx_request.hash(), note_hash: 0 }.count(1).scope(\n NULL_MSG_SENDER_CONTRACT_ADDRESS,\n )\n}\n\npub fn compute_log_tag(raw_tag: Field, dom_sep: u32) -> Field {\n poseidon2_hash_with_separator([raw_tag], dom_sep)\n}\n\npub fn compute_siloed_private_log_first_field(\n contract_address: AztecAddress,\n field: Field,\n) -> Field {\n poseidon2_hash_with_separator(\n [contract_address.to_field(), field],\n DOM_SEP__PRIVATE_LOG_FIRST_FIELD,\n )\n}\n\npub fn compute_siloed_private_log(contract_address: AztecAddress, log: PrivateLog) -> PrivateLog {\n let mut fields = log.fields;\n fields[0] = compute_siloed_private_log_first_field(contract_address, fields[0]);\n PrivateLog::new(fields, log.length)\n}\n\npub fn compute_contract_class_log_hash(log: [Field; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS]) -> Field {\n poseidon2_hash(log)\n}\n\npub fn compute_app_siloed_secret_key(\n master_secret_key: EmbeddedCurveScalar,\n app_address: AztecAddress,\n key_type_domain_separator: Field,\n) -> Field {\n poseidon2_hash_with_separator(\n [master_secret_key.hi, master_secret_key.lo, app_address.to_field()],\n key_type_domain_separator,\n )\n}\n\npub fn compute_l2_to_l1_message_hash(\n message: Scoped<L2ToL1Message>,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n let contract_address_bytes: [u8; 32] = message.contract_address.to_field().to_be_bytes();\n let recipient_bytes: [u8; 20] = message.inner.recipient.to_be_bytes();\n let content_bytes: [u8; 32] = message.inner.content.to_be_bytes();\n let rollup_version_id_bytes: [u8; 32] = rollup_version_id.to_be_bytes();\n let chain_id_bytes: [u8; 32] = chain_id.to_be_bytes();\n\n let mut bytes: [u8; 148] = std::mem::zeroed();\n for i in 0..32 {\n bytes[i] = contract_address_bytes[i];\n bytes[i + 32] = rollup_version_id_bytes[i];\n // 64 - 84 are for recipient.\n bytes[i + 84] = chain_id_bytes[i];\n bytes[i + 116] = content_bytes[i];\n }\n\n for i in 0..20 {\n bytes[64 + i] = recipient_bytes[i];\n }\n\n sha256_to_field(bytes)\n}\n\n// TODO: consider a variant that enables domain separation with a u32 (we seem to have standardised u32s for domain separators)\n/// Computes sha256 hash of 2 input fields.\n///\n/// @returns A truncated field (i.e., the first byte is always 0).\npub fn accumulate_sha256(v0: Field, v1: Field) -> Field {\n // Concatenate two fields into 32 x 2 = 64 bytes\n let v0_as_bytes: [u8; 32] = v0.to_be_bytes();\n let v1_as_bytes: [u8; 32] = v1.to_be_bytes();\n let hash_input_flattened = v0_as_bytes.concat(v1_as_bytes);\n\n sha256_to_field(hash_input_flattened)\n}\n\npub fn poseidon2_hash<let N: u32>(inputs: [Field; N]) -> Field {\n poseidon::poseidon2::Poseidon2::hash(inputs, N)\n}\n\n#[no_predicates]\npub fn poseidon2_hash_with_separator<let N: u32, T>(inputs: [Field; N], separator: T) -> Field\nwhere\n T: ToField,\n{\n let inputs_with_separator = [separator.to_field()].concat(inputs);\n poseidon2_hash(inputs_with_separator)\n}\n\n/// Computes a Poseidon2 hash over a dynamic-length subarray of the given input.\n/// Only the first `in_len` fields of `input` are absorbed; any remaining fields are ignored.\n/// The caller is responsible for ensuring that the input is padded with zeros if required.\n#[no_predicates]\npub fn poseidon2_hash_subarray<let N: u32>(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_in_chunks(input, in_len);\n sponge.squeeze()\n}\n\n// This function is unconstrained because it is intended to be used in unconstrained context only as\n// in constrained contexts it would be too inefficient.\npub unconstrained fn poseidon2_hash_with_separator_bounded_vec<let N: u32, T>(\n inputs: BoundedVec<Field, N>,\n separator: T,\n) -> Field\nwhere\n T: ToField,\n{\n let in_len = inputs.len() + 1;\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n sponge.absorb(separator.to_field());\n\n for i in 0..inputs.len() {\n sponge.absorb(inputs.get(i));\n }\n\n sponge.squeeze()\n}\n\n#[no_predicates]\npub fn poseidon2_hash_bytes<let N: u32>(inputs: [u8; N]) -> Field {\n let mut fields = [0; (N + 30) / 31];\n let mut field_index = 0;\n let mut current_field = [0; 31];\n for i in 0..inputs.len() {\n let index = i % 31;\n current_field[index] = inputs[i];\n if index == 30 {\n fields[field_index] = field_from_bytes(current_field, false);\n current_field = [0; 31];\n field_index += 1;\n }\n }\n if field_index != fields.len() {\n fields[field_index] = field_from_bytes(current_field, false);\n }\n poseidon2_hash(fields)\n}\n\n#[test]\nfn subarray_hash_matches_fixed() {\n let values_to_hash = [3; 17];\n let padded = values_to_hash.concat([0; 11]);\n let subarray_hash = poseidon2_hash_subarray(padded, values_to_hash.len());\n\n // Hash the entire values_to_hash.\n let fixed_len_hash = poseidon::poseidon2::Poseidon2::hash(values_to_hash, values_to_hash.len());\n\n assert_eq(subarray_hash, fixed_len_hash);\n}\n\n#[test]\nfn subarray_hash_matches_variable() {\n let values_to_hash = [3; 17];\n let padded = values_to_hash.concat([0; 11]);\n let subarray_hash = poseidon2_hash_subarray(padded, values_to_hash.len());\n\n // Hash up to values_to_hash.len() fields of the padded array.\n let variable_len_hash = poseidon::poseidon2::Poseidon2::hash(padded, values_to_hash.len());\n\n assert_eq(subarray_hash, variable_len_hash);\n}\n\n#[test]\nfn smoke_sha256_to_field() {\n let full_buffer = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\n 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,\n 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,\n 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,\n 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,\n ];\n let result = sha256_to_field(full_buffer);\n\n assert(result == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184c7);\n\n // to show correctness of the current ver (truncate one byte) vs old ver (mod full bytes):\n let result_bytes = sha256::digest(full_buffer);\n let truncated_field = crate::utils::field::field_from_bytes_32_trunc(result_bytes);\n assert(truncated_field == result);\n let mod_res = result + (result_bytes[31] as Field);\n assert(mod_res == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184e0);\n}\n\n#[test]\nfn unique_siloed_note_hash_matches_typescript() {\n let inner_note_hash = 1;\n let contract_address = AztecAddress::from_field(2);\n let first_nullifier = 3;\n let note_index_in_tx = 4;\n\n let siloed_note_hash = compute_siloed_note_hash(contract_address, inner_note_hash);\n let siloed_note_hash_from_ts =\n 0x1986a4bea3eddb1fff917d629a13e10f63f514f401bdd61838c6b475db949169;\n assert_eq(siloed_note_hash, siloed_note_hash_from_ts);\n\n let nonce: Field = compute_note_hash_nonce(first_nullifier, note_index_in_tx);\n let note_hash_nonce_from_ts =\n 0x28e7799791bf066a57bb51fdd0fbcaf3f0926414314c7db515ea343f44f5d58b;\n assert_eq(nonce, note_hash_nonce_from_ts);\n\n let unique_siloed_note_hash_from_nonce = compute_unique_note_hash(nonce, siloed_note_hash);\n let unique_siloed_note_hash = compute_note_nonce_and_unique_note_hash(\n siloed_note_hash,\n first_nullifier,\n note_index_in_tx,\n );\n assert_eq(unique_siloed_note_hash_from_nonce, unique_siloed_note_hash);\n\n let unique_siloed_note_hash_from_ts =\n 0x29949aef207b715303b24639737c17fbfeb375c1d965ecfa85c7e4f0febb7d16;\n assert_eq(unique_siloed_note_hash, unique_siloed_note_hash_from_ts);\n}\n\n#[test]\nfn siloed_nullifier_matches_typescript() {\n let contract_address = AztecAddress::from_field(123);\n let nullifier = 456;\n\n let res = compute_siloed_nullifier(contract_address, nullifier);\n\n let siloed_nullifier_from_ts =\n 0x169b50336c1f29afdb8a03d955a81e485f5ac7d5f0b8065673d1e407e5877813;\n\n assert_eq(res, siloed_nullifier_from_ts);\n}\n\n#[test]\nfn siloed_private_log_first_field_matches_typescript() {\n let contract_address = AztecAddress::from_field(123);\n let field = 456;\n let res = compute_siloed_private_log_first_field(contract_address, field);\n\n let siloed_private_log_first_field_from_ts =\n 0x29480984f7b9257fded523d50addbcfc8d1d33adcf2db73ef3390a8fd5cdffaa;\n\n assert_eq(res, siloed_private_log_first_field_from_ts);\n}\n\n#[test]\nfn empty_l2_to_l1_message_hash_matches_typescript() {\n // All zeroes\n let res = compute_l2_to_l1_message_hash(\n L2ToL1Message { recipient: EthAddress::zero(), content: 0 }.scope(AztecAddress::from_field(\n 0,\n )),\n 0,\n 0,\n );\n\n let empty_l2_to_l1_msg_hash_from_ts =\n 0x003b18c58c739716e76429634a61375c45b3b5cd470c22ab6d3e14cee23dd992;\n\n assert_eq(res, empty_l2_to_l1_msg_hash_from_ts);\n}\n\n#[test]\nfn l2_to_l1_message_hash_matches_typescript() {\n let message = L2ToL1Message { recipient: EthAddress::from_field(1), content: 2 }.scope(\n AztecAddress::from_field(3),\n );\n let version = 4;\n let chainId = 5;\n\n let hash = compute_l2_to_l1_message_hash(message, version, chainId);\n\n // The following value was generated by `yarn-project/stdlib/src/hash/hash.test.ts`\n let l2_to_l1_message_hash_from_ts =\n 0x0081edf209e087ad31b3fd24263698723d57190bd1d6e9fe056fc0c0a68ee661;\n\n assert_eq(hash, l2_to_l1_message_hash_from_ts);\n}\n\n#[test]\nunconstrained fn poseidon2_hash_with_separator_bounded_vec_matches_non_bounded_vec_version() {\n let inputs = BoundedVec::<Field, 4>::from_array([1, 2, 3]);\n let separator = 42;\n\n // Hash using bounded vec version\n let bounded_result = poseidon2_hash_with_separator_bounded_vec(inputs, separator);\n\n // Hash using regular version\n let regular_result = poseidon2_hash_with_separator([1, 2, 3], separator);\n\n // Results should match\n assert_eq(bounded_result, regular_result);\n}\n"
514
590
  },
515
- "188": {
591
+ "187": {
516
592
  "function_locations": [
517
593
  {
518
594
  "name": "merkle_hash",
@@ -540,41 +616,57 @@
540
616
  },
541
617
  {
542
618
  "name": "<impl Empty for MerkleTree<N>>::empty",
543
- "start": 1701
619
+ "start": 2148
544
620
  },
545
621
  {
546
622
  "name": "MerkleTree<N>::new",
547
- "start": 1845
623
+ "start": 2292
548
624
  },
549
625
  {
550
626
  "name": "MerkleTree<N>::new_with_hasher",
551
- "start": 2049
627
+ "start": 2496
552
628
  },
553
629
  {
554
630
  "name": "MerkleTree<N>::new_sha",
555
- "start": 2205
631
+ "start": 2652
556
632
  },
557
633
  {
558
634
  "name": "MerkleTree<N>::get_root",
559
- "start": 2358
635
+ "start": 2805
560
636
  },
561
637
  {
562
638
  "name": "MerkleTree<N>::get_sibling_path",
563
- "start": 2470
639
+ "start": 2917
564
640
  },
565
641
  {
566
642
  "name": "sibling_index",
567
- "start": 3207
643
+ "start": 3654
568
644
  },
569
645
  {
570
646
  "name": "compute_merkle_tree_nodes",
571
- "start": 3420
647
+ "start": 4832
648
+ },
649
+ {
650
+ "name": "tests::add_hasher",
651
+ "start": 5667
652
+ },
653
+ {
654
+ "name": "tests::leaves_and_internal_nodes_share_one_hasher",
655
+ "start": 5761
656
+ },
657
+ {
658
+ "name": "tests::internal_node_value_hashes_identically_as_a_leaf",
659
+ "start": 6024
660
+ },
661
+ {
662
+ "name": "tests::merkle_tree_root_is_last_node",
663
+ "start": 6512
572
664
  }
573
665
  ],
574
666
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/merkle_tree.nr",
575
- "source": "use crate::{\n constants::{\n DOM_SEP__MERKLE_HASH, DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__PUBLIC_DATA_MERKLE,\n DOM_SEP__RETRIEVED_BYTECODES_MERKLE, DOM_SEP__WRITTEN_SLOTS_MERKLE,\n },\n hash::{accumulate_sha256, poseidon2_hash_with_separator},\n traits::Empty,\n utils::math::is_power_of_2_u32,\n};\n\n/// Merkle-node hash used by append-only trees.\npub fn merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__MERKLE_HASH)\n}\n\n/// Merkle-node hash for the nullifier tree's sibling paths.\npub fn nullifier_merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__NULLIFIER_MERKLE)\n}\n\n/// Merkle-node hash for the public-data tree's sibling paths.\npub fn public_data_merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__PUBLIC_DATA_MERKLE)\n}\n\n/// Merkle-node hash for the AVM-internal written-public-data-slots tree's sibling paths.\npub fn written_slots_merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__WRITTEN_SLOTS_MERKLE)\n}\n\n/// Merkle-node hash for the AVM-internal retrieved-bytecodes (class-id) tree's sibling paths.\npub fn retrieved_bytecodes_merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__RETRIEVED_BYTECODES_MERKLE)\n}\n\npub fn sha_merkle_hash(left: Field, right: Field) -> Field {\n accumulate_sha256(left, right)\n}\n\n#[derive(Eq)]\npub struct MerkleTree<let N: u32> {\n pub leaves: [Field; N],\n pub nodes: [Field; N - 1],\n}\n\nimpl<let N: u32> Empty for MerkleTree<N> {\n fn empty() -> Self {\n MerkleTree { leaves: [0; N], nodes: [0; N - 1] }\n }\n}\n\nimpl<let N: u32> MerkleTree<N> {\n pub fn new(leaves: [Field; N]) -> Self {\n let nodes = compute_merkle_tree_nodes(leaves, merkle_hash);\n MerkleTree { leaves, nodes }\n }\n\n pub fn new_with_hasher(leaves: [Field; N], hasher: fn(Field, Field) -> Field) -> Self {\n let nodes = compute_merkle_tree_nodes(leaves, hasher);\n MerkleTree { leaves, nodes }\n }\n\n pub fn new_sha(leaves: [Field; N]) -> Self {\n let nodes = compute_merkle_tree_nodes(leaves, sha_merkle_hash);\n MerkleTree { leaves, nodes }\n }\n\n pub fn get_root(self) -> Field {\n self.nodes[N - 2]\n }\n\n pub fn get_sibling_path<let K: u32>(self, leaf_index: u32) -> [Field; K] {\n assert_eq(2.pow_32(K as Field), N as Field, \"Invalid path length\");\n\n let mut path = [0; K];\n let mut current_index = leaf_index;\n let mut subtree_width = N;\n\n let mut current_sibling_index = sibling_index(current_index);\n\n path[0] = self.leaves[current_sibling_index];\n\n let mut subtree_offset: u32 = 0;\n\n for i in 1..K {\n current_index = current_index / 2;\n subtree_width = subtree_width / 2;\n\n current_sibling_index = sibling_index(current_index);\n\n path[i] = self.nodes[subtree_offset + current_sibling_index];\n\n subtree_offset += subtree_width;\n }\n\n path\n }\n}\n\npub fn sibling_index(index: u32) -> u32 {\n if index % 2 == 0 {\n index + 1\n } else {\n index - 1\n }\n}\n\npub fn compute_merkle_tree_nodes<let N: u32>(\n leaves: [Field; N],\n hasher: fn(Field, Field) -> Field,\n) -> [Field; N - 1] {\n // Note: `N` must be a power of 2.\n std::static_assert(is_power_of_2_u32(N), \"N must be a power of 2\");\n std::static_assert(N != 1, \"2 must divide N\");\n\n let mut nodes = [0; N - 1];\n\n let total_nodes = N - 1;\n let half_size = N / 2;\n\n // Hash base layer.\n for i in 0..half_size {\n nodes[i] = hasher(leaves[2 * i], leaves[2 * i + 1]);\n }\n\n // Hash the other layers.\n for i in 0..(total_nodes - half_size) {\n nodes[half_size + i] = hasher(nodes[2 * i], nodes[2 * i + 1]);\n }\n\n nodes\n}\n"
667
+ "source": "use crate::{\n constants::{\n DOM_SEP__MERKLE_HASH, DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__PUBLIC_DATA_MERKLE,\n DOM_SEP__RETRIEVED_BYTECODES_MERKLE, DOM_SEP__WRITTEN_SLOTS_MERKLE,\n },\n hash::{accumulate_sha256, poseidon2_hash_with_separator},\n traits::Empty,\n utils::math::is_power_of_2_u32,\n};\n\n/// Merkle-node hash used by append-only trees.\npub fn merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__MERKLE_HASH)\n}\n\n/// Merkle-node hash for the nullifier tree's sibling paths.\npub fn nullifier_merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__NULLIFIER_MERKLE)\n}\n\n/// Merkle-node hash for the public-data tree's sibling paths.\npub fn public_data_merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__PUBLIC_DATA_MERKLE)\n}\n\n/// Merkle-node hash for the AVM-internal written-public-data-slots tree's sibling paths.\npub fn written_slots_merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__WRITTEN_SLOTS_MERKLE)\n}\n\n/// Merkle-node hash for the AVM-internal retrieved-bytecodes (class-id) tree's sibling paths.\npub fn retrieved_bytecodes_merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash_with_separator([left, right], DOM_SEP__RETRIEVED_BYTECODES_MERKLE)\n}\n\npub fn sha_merkle_hash(left: Field, right: Field) -> Field {\n accumulate_sha256(left, right)\n}\n\n/// A balanced Merkle tree over `N` leaves (`N` must be a power of 2).\n///\n/// Leaves are stored and consumed as-is; the internal nodes are built by `compute_merkle_tree_nodes`,\n/// which applies `hasher` at every layer with no domain separation between the leaf layer and the\n/// internal-node layers. Callers must therefore pass leaves that are already domain-separated from the\n/// node hashes (see the warning on `compute_merkle_tree_nodes`).\n#[derive(Eq)]\npub struct MerkleTree<let N: u32> {\n pub leaves: [Field; N],\n pub nodes: [Field; N - 1],\n}\n\nimpl<let N: u32> Empty for MerkleTree<N> {\n fn empty() -> Self {\n MerkleTree { leaves: [0; N], nodes: [0; N - 1] }\n }\n}\n\nimpl<let N: u32> MerkleTree<N> {\n pub fn new(leaves: [Field; N]) -> Self {\n let nodes = compute_merkle_tree_nodes(leaves, merkle_hash);\n MerkleTree { leaves, nodes }\n }\n\n pub fn new_with_hasher(leaves: [Field; N], hasher: fn(Field, Field) -> Field) -> Self {\n let nodes = compute_merkle_tree_nodes(leaves, hasher);\n MerkleTree { leaves, nodes }\n }\n\n pub fn new_sha(leaves: [Field; N]) -> Self {\n let nodes = compute_merkle_tree_nodes(leaves, sha_merkle_hash);\n MerkleTree { leaves, nodes }\n }\n\n pub fn get_root(self) -> Field {\n self.nodes[N - 2]\n }\n\n pub fn get_sibling_path<let K: u32>(self, leaf_index: u32) -> [Field; K] {\n assert_eq(2.pow_32(K as Field), N as Field, \"Invalid path length\");\n\n let mut path = [0; K];\n let mut current_index = leaf_index;\n let mut subtree_width = N;\n\n let mut current_sibling_index = sibling_index(current_index);\n\n path[0] = self.leaves[current_sibling_index];\n\n let mut subtree_offset: u32 = 0;\n\n for i in 1..K {\n current_index = current_index / 2;\n subtree_width = subtree_width / 2;\n\n current_sibling_index = sibling_index(current_index);\n\n path[i] = self.nodes[subtree_offset + current_sibling_index];\n\n subtree_offset += subtree_width;\n }\n\n path\n }\n}\n\npub fn sibling_index(index: u32) -> u32 {\n if index % 2 == 0 {\n index + 1\n } else {\n index - 1\n }\n}\n\n/// Computes the `N - 1` internal nodes of a balanced Merkle tree from its `N` leaves (root last);\n/// `N` must be a power of 2 greater than 1.\n///\n/// Leaves are consumed as-is: this helper does not hash leaf preimages, it only hashes pairs upward.\n/// The same `hasher` is applied at every layer (the leaf/base layer and all internal-node layers\n/// alike), so there is NO domain separation between the leaf hashing and the internal-node hashing. An\n/// internal node is therefore just `hasher(left, right)`, indistinguishable in form from a leaf.\n///\n/// WARNING: because of this, callers MUST pass leaves that are already domain-separated from this\n/// helper's internal-node hashes (i.e. produced by a hash whose domain differs from `hasher`), so that\n/// an internal-node value can never be a valid leaf. (Per-tree domain separation of the node hashing\n/// itself is likewise the caller's choice: pass the tree-specific hasher, e.g. `nullifier_merkle_hash`.)\npub fn compute_merkle_tree_nodes<let N: u32>(\n leaves: [Field; N],\n hasher: fn(Field, Field) -> Field,\n) -> [Field; N - 1] {\n // Note: `N` must be a power of 2.\n std::static_assert(is_power_of_2_u32(N), \"N must be a power of 2\");\n std::static_assert(N != 1, \"2 must divide N\");\n\n let mut nodes = [0; N - 1];\n\n let total_nodes = N - 1;\n let half_size = N / 2;\n\n // Hash base layer.\n for i in 0..half_size {\n nodes[i] = hasher(leaves[2 * i], leaves[2 * i + 1]);\n }\n\n // Hash the other layers.\n for i in 0..(total_nodes - half_size) {\n nodes[half_size + i] = hasher(nodes[2 * i], nodes[2 * i + 1]);\n }\n\n nodes\n}\n\nmod tests {\n use super::{compute_merkle_tree_nodes, MerkleTree};\n\n // A trivial, collision-prone hasher that makes the absence of leaf/internal-node domain separation\n // observable: each node is simply the sum of its two children.\n fn add_hasher(left: Field, right: Field) -> Field {\n left + right\n }\n\n #[test]\n fn leaves_and_internal_nodes_share_one_hasher() {\n // base layer: 1+2=3, 3+4=7 ; internal layer (root last): 3+7=10\n let nodes = compute_merkle_tree_nodes([1, 2, 3, 4], add_hasher);\n assert_eq(nodes, [3, 7, 10]);\n }\n\n #[test]\n fn internal_node_value_hashes_identically_as_a_leaf() {\n // Feeding the internal-node values 3 and 7 back in as *leaves* yields the same root (10): the\n // helper hashes the leaf layer and the internal-node layers with one hasher, so an internal\n // node is indistinguishable in form from a leaf. Callers must pass domain-separated leaves.\n let nodes = compute_merkle_tree_nodes([3, 7, 0, 0], add_hasher);\n assert_eq(nodes[nodes.len() - 1], 3 + 7);\n }\n\n #[test]\n fn merkle_tree_root_is_last_node() {\n let tree = MerkleTree::new_with_hasher([1, 2, 3, 4], add_hasher);\n assert_eq(tree.get_root(), 10);\n assert_eq(tree.get_root(), tree.nodes[tree.nodes.len() - 1]);\n }\n}\n"
576
668
  },
577
- "190": {
669
+ "189": {
578
670
  "function_locations": [
579
671
  {
580
672
  "name": "root_from_sibling_path",
@@ -620,7 +712,7 @@
620
712
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/root.nr",
621
713
  "source": "use crate::merkle_tree::merkle_tree::{compute_merkle_tree_nodes, merkle_hash, sha_merkle_hash};\n\n/// Calculate the Merkle tree root from the sibling path and leaf, using the default merkle hash.\npub fn root_from_sibling_path<let N: u32>(\n leaf: Field,\n leaf_index: Field,\n sibling_path: [Field; N],\n) -> Field {\n root_from_sibling_path_with_hasher(leaf, leaf_index, sibling_path, merkle_hash)\n}\n\n/// Calculate the Merkle tree root from the sibling path and leaf, using a custom hasher.\n///\n/// The leaf is hashed with its sibling, the result is then hashed with the next sibling in the path. and so on.\n/// The last hash is the root.\npub fn root_from_sibling_path_with_hasher<let N: u32>(\n leaf: Field,\n leaf_index: Field,\n sibling_path: [Field; N],\n hasher: fn(Field, Field) -> Field,\n) -> Field {\n let mut node = leaf;\n let indices: [bool; N] = leaf_index.to_le_bits();\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = hasher(hash_left, hash_right);\n }\n node\n}\n\npub fn compute_tree_root<let N: u32>(leaves: [Field; N]) -> Field {\n compute_tree_root_with_hasher(leaves, merkle_hash)\n}\n\npub fn compute_sha_tree_root<let N: u32>(leaves: [Field; N]) -> Field {\n compute_tree_root_with_hasher(leaves, sha_merkle_hash)\n}\n\npub fn compute_tree_root_with_hasher<let N: u32>(\n leaves: [Field; N],\n hasher: fn(Field, Field) -> Field,\n) -> Field {\n compute_merkle_tree_nodes(leaves, hasher)[N - 2]\n}\n\npub fn compute_empty_tree_root<let TreeHeight: u32>() -> Field {\n compute_empty_tree_root_with_hasher::<TreeHeight>(merkle_hash)\n}\n\npub fn compute_empty_sha_tree_root<let TreeHeight: u32>() -> Field {\n compute_empty_tree_root_with_hasher::<TreeHeight>(sha_merkle_hash)\n}\n\npub fn compute_empty_tree_root_with_hasher<let TreeHeight: u32>(\n hasher: fn(Field, Field) -> Field,\n) -> Field {\n let mut hashes = [0; TreeHeight + 1];\n for i in 1..TreeHeight + 1 {\n hashes[i] = hasher(hashes[i - 1], hashes[i - 1]);\n }\n hashes[TreeHeight]\n}\n\n#[test]\nfn test_merkle_roots_match_typescript() {\n // The following hardcoded values are generated from yarn-project/foundation/src/trees/balanced_merkle_tree_root.test.ts\n\n let root = compute_tree_root([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n let expected_tree_root_from_ts =\n 0x2bc86dba04dfdd6352c3b1c66b2300445964e2888aa52fdb023d2e645a3d3399;\n assert_eq(root, expected_tree_root_from_ts);\n\n let empty_root = compute_tree_root([0; 16]);\n let expected_empty_root_from_ts =\n 0x1e20ad4181460cbfdc74ca773502c59b890f184efe300ebad895956d318422da;\n assert_eq(empty_root, expected_empty_root_from_ts);\n\n let sha_root = compute_sha_tree_root([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n let expected_sha_root_from_ts =\n 0x00b007869b8a5e2a9b3b580a318e702cea04b2f5438f2e26743f545e4d1ecbdb;\n assert_eq(sha_root, expected_sha_root_from_ts);\n}\n\n#[test]\nfn test_empty_tree_root() {\n assert_eq(compute_empty_tree_root::<0>(), 0);\n\n assert_eq(\n compute_empty_tree_root::<1>(),\n 0x19f1a0c09db4cd026f686e9c8fb45501a9fefb4eb1b4c6c328a51343a0094eeb,\n );\n\n assert_eq(\n compute_empty_tree_root::<2>(),\n 0x14e4b977b2203b70e6ee1c2456eb7114d090fe4b907f631eecd0919fed432e7d,\n );\n\n assert_eq(\n compute_empty_tree_root::<6>(),\n 0x119f56a2e8423a7feaab49b9b5dcbadec0648dfa4096b61b6774ea33ae29dc7f,\n );\n\n assert_eq(\n compute_empty_tree_root::<10>(),\n 0x0d04c63f36bd168215c9b09a227c7e8d3ad48e2f11b8202fd07c524bd30ee88f,\n );\n}\n"
622
714
  },
623
- "213": {
715
+ "212": {
624
716
  "function_locations": [
625
717
  {
626
718
  "name": "derive_storage_slot_in_map",
@@ -634,7 +726,7 @@
634
726
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr",
635
727
  "source": "use crate::{\n constants::DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, hash::poseidon2_hash_with_separator,\n traits::ToField,\n};\n\n// TODO: Move this to src/public_data/storage/map.nr\npub fn derive_storage_slot_in_map<K>(storage_slot: Field, key: K) -> Field\nwhere\n K: ToField,\n{\n poseidon2_hash_with_separator(\n [storage_slot, key.to_field()],\n DOM_SEP__PUBLIC_STORAGE_MAP_SLOT,\n )\n}\n\nmod test {\n use crate::{address::AztecAddress, storage::map::derive_storage_slot_in_map, traits::FromField};\n\n #[test]\n fn test_derive_storage_slot_in_map_matches_typescript() {\n let map_slot = 0x132258fb6962c4387ba659d9556521102d227549a386d39f0b22d1890d59c2b5;\n let key = AztecAddress::from_field(\n 0x302dbc2f9b50a73283d5fb2f35bc01eae8935615817a0b4219a057b2ba8a5a3f,\n );\n\n let slot = derive_storage_slot_in_map(map_slot, key);\n\n // The following value was generated by `map_slot.test.ts`\n let slot_from_typescript =\n 0x2d225f361108379adc2da91378b9702675c5546b57e78bafc1e74ec7fec55967;\n\n assert_eq(slot, slot_from_typescript);\n }\n}\n"
636
728
  },
637
- "221": {
729
+ "220": {
638
730
  "function_locations": [
639
731
  {
640
732
  "name": "<impl Packable for bool>::pack",
@@ -642,129 +734,149 @@
642
734
  },
643
735
  {
644
736
  "name": "<impl Packable for bool>::unpack",
645
- "start": 666
737
+ "start": 946
646
738
  },
647
739
  {
648
740
  "name": "<impl Packable for u8>::pack",
649
- "start": 827
741
+ "start": 1397
650
742
  },
651
743
  {
652
744
  "name": "<impl Packable for u8>::unpack",
653
- "start": 929
745
+ "start": 1499
654
746
  },
655
747
  {
656
748
  "name": "<impl Packable for u16>::pack",
657
- "start": 1081
749
+ "start": 1651
658
750
  },
659
751
  {
660
752
  "name": "<impl Packable for u16>::unpack",
661
- "start": 1183
753
+ "start": 1753
662
754
  },
663
755
  {
664
756
  "name": "<impl Packable for u32>::pack",
665
- "start": 1336
757
+ "start": 1906
666
758
  },
667
759
  {
668
760
  "name": "<impl Packable for u32>::unpack",
669
- "start": 1438
761
+ "start": 2008
670
762
  },
671
763
  {
672
764
  "name": "<impl Packable for u64>::pack",
673
- "start": 1591
765
+ "start": 2161
674
766
  },
675
767
  {
676
768
  "name": "<impl Packable for u64>::unpack",
677
- "start": 1693
769
+ "start": 2263
678
770
  },
679
771
  {
680
772
  "name": "<impl Packable for u128>::pack",
681
- "start": 1848
773
+ "start": 2418
682
774
  },
683
775
  {
684
776
  "name": "<impl Packable for u128>::unpack",
685
- "start": 1950
777
+ "start": 2520
686
778
  },
687
779
  {
688
780
  "name": "<impl Packable for Field>::pack",
689
- "start": 2108
781
+ "start": 2678
690
782
  },
691
783
  {
692
784
  "name": "<impl Packable for Field>::unpack",
693
- "start": 2201
785
+ "start": 2771
694
786
  },
695
787
  {
696
788
  "name": "<impl Packable for i8>::pack",
697
- "start": 2345
789
+ "start": 2915
698
790
  },
699
791
  {
700
792
  "name": "<impl Packable for i8>::unpack",
701
- "start": 2453
793
+ "start": 3023
702
794
  },
703
795
  {
704
796
  "name": "<impl Packable for i16>::pack",
705
- "start": 2611
797
+ "start": 3181
706
798
  },
707
799
  {
708
800
  "name": "<impl Packable for i16>::unpack",
709
- "start": 2720
801
+ "start": 3290
710
802
  },
711
803
  {
712
804
  "name": "<impl Packable for i32>::pack",
713
- "start": 2880
805
+ "start": 3450
714
806
  },
715
807
  {
716
808
  "name": "<impl Packable for i32>::unpack",
717
- "start": 2989
809
+ "start": 3559
718
810
  },
719
811
  {
720
812
  "name": "<impl Packable for i64>::pack",
721
- "start": 3149
813
+ "start": 3719
722
814
  },
723
815
  {
724
816
  "name": "<impl Packable for i64>::unpack",
725
- "start": 3258
817
+ "start": 3828
726
818
  },
727
819
  {
728
820
  "name": "<impl Packable for super::point::EmbeddedCurvePoint>::pack",
729
- "start": 3427
821
+ "start": 3997
730
822
  },
731
823
  {
732
824
  "name": "<impl Packable for super::point::EmbeddedCurvePoint>::unpack",
733
- "start": 3509
825
+ "start": 4079
734
826
  },
735
827
  {
736
828
  "name": "<impl Packable for [T; M]>::pack",
737
- "start": 3720
829
+ "start": 4290
738
830
  },
739
831
  {
740
832
  "name": "<impl Packable for [T; M]>::unpack",
741
- "start": 4082
833
+ "start": 4652
742
834
  },
743
835
  {
744
836
  "name": "test_u16_packing",
745
- "start": 4327
837
+ "start": 4897
746
838
  },
747
839
  {
748
840
  "name": "test_i8_packing",
749
- "start": 4423
841
+ "start": 4993
750
842
  },
751
843
  {
752
844
  "name": "test_i16_packing",
753
- "start": 4519
845
+ "start": 5089
754
846
  },
755
847
  {
756
848
  "name": "test_i32_packing",
757
- "start": 4617
849
+ "start": 5187
758
850
  },
759
851
  {
760
852
  "name": "test_i64_packing",
761
- "start": 4715
853
+ "start": 5285
854
+ },
855
+ {
856
+ "name": "test_bool_unpack_accepts_canonical_values",
857
+ "start": 5408
858
+ },
859
+ {
860
+ "name": "test_bool_unpack_rejects_even_non_bool",
861
+ "start": 5594
862
+ },
863
+ {
864
+ "name": "test_bool_unpack_rejects_odd_non_bool",
865
+ "start": 5827
866
+ },
867
+ {
868
+ "name": "test_bool_unpack_rejects_large_field",
869
+ "start": 6058
870
+ },
871
+ {
872
+ "name": "test_bool_pack_unpack_roundtrip",
873
+ "start": 6145
762
874
  }
763
875
  ],
764
876
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr",
765
- "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"
877
+ "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 /// Unpacks a `bool`, constraining the field to be a canonical boolean. A field outside `{0, 1}` is\n /// rejected (rather than silently reinterpreted), so an arbitrary-origin field cannot be misread.\n /// `pack` always emits `0` or `1`, so round-tripping is unaffected.\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> bool {\n let v = fields[0];\n // v * v == v holds iff v is 0 or 1: a single degree-2 constraint that both validates the field\n // is a canonical bool and avoids the byte-range decomposition that a cast to u8 would require.\n assert(v * v == v, \"Packable::unpack: bool field must be 0 or 1\");\n v == 1\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\n#[test]\nfn test_bool_unpack_accepts_canonical_values() {\n assert_eq(bool::unpack([0]), false);\n assert_eq(bool::unpack([1]), true);\n}\n\n#[test(should_fail_with = \"bool field must be 0 or 1\")]\nfn test_bool_unpack_rejects_even_non_bool() {\n // 2 has LSB 0, so the previous LSB-based unpack silently returned false; now it is rejected.\n let _ = bool::unpack([2]);\n}\n\n#[test(should_fail_with = \"bool field must be 0 or 1\")]\nfn test_bool_unpack_rejects_odd_non_bool() {\n // 3 has LSB 1, so the previous LSB-based unpack silently returned true; now it is rejected.\n let _ = bool::unpack([3]);\n}\n\n#[test(should_fail_with = \"bool field must be 0 or 1\")]\nfn test_bool_unpack_rejects_large_field() {\n let _ = bool::unpack([1000000]);\n}\n\n#[test]\nfn test_bool_pack_unpack_roundtrip() {\n // `pack` always emits 0 or 1, so it round-trips through the canonical-bool check in `unpack`.\n assert_eq(true.pack(), [1]);\n assert_eq(false.pack(), [0]);\n assert_eq(bool::unpack(true.pack()), true);\n assert_eq(bool::unpack(false.pack()), false);\n}\n"
766
878
  },
767
- "240": {
879
+ "239": {
768
880
  "function_locations": [
769
881
  {
770
882
  "name": "Poseidon2::hash",
@@ -806,7 +918,7 @@
806
918
  "path": "/home/aztec-dev/nargo/github.com/noir-lang/poseidon/v0.3.0/src/poseidon2.nr",
807
919
  "source": "use std::default::Default;\nuse std::hash::Hasher;\n\nglobal RATE: u32 = 3;\n\npub struct Poseidon2 {\n cache: [Field; 3],\n state: [Field; 4],\n cache_size: u32,\n squeeze_mode: bool, // 0 => absorb, 1 => squeeze\n}\n\nimpl Poseidon2 {\n #[no_predicates]\n pub fn hash<let N: u32>(input: [Field; N], message_size: u32) -> Field {\n Poseidon2::hash_internal(input, message_size)\n }\n\n pub(crate) fn new(iv: Field) -> Poseidon2 {\n let mut result =\n Poseidon2 { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false };\n result.state[RATE] = iv;\n result\n }\n\n fn perform_duplex(&mut self) {\n // add the cache into sponge state\n self.state[0] += self.cache[0];\n self.state[1] += self.cache[1];\n self.state[2] += self.cache[2];\n self.state = crate::poseidon2_permutation(self.state);\n }\n\n fn absorb(&mut self, input: Field) {\n assert(!self.squeeze_mode);\n if self.cache_size == RATE {\n // If we're absorbing, and the cache is full, apply the sponge permutation to compress the cache\n self.perform_duplex();\n self.cache[0] = input;\n self.cache_size = 1;\n } else {\n // If we're absorbing, and the cache is not full, add the input into the cache\n self.cache[self.cache_size] = input;\n self.cache_size += 1;\n }\n }\n\n fn squeeze(&mut self) -> Field {\n assert(!self.squeeze_mode);\n // If we're in absorb mode, apply sponge permutation to compress the cache.\n self.perform_duplex();\n self.squeeze_mode = true;\n\n // Pop one item off the top of the permutation and return it.\n self.state[0]\n }\n\n fn hash_internal<let N: u32>(input: [Field; N], in_len: u32) -> Field {\n let two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut state = [0; 4];\n state[RATE] = iv;\n\n if std::runtime::is_unconstrained() {\n for i in 0..(in_len / RATE) {\n state[0] += input[i * RATE];\n state[1] += input[i * RATE + 1];\n state[2] += input[i * RATE + 2];\n state = crate::poseidon2_permutation(state);\n }\n\n // handle remaining elements after last full RATE-sized chunk\n let num_extra_fields = in_len % RATE;\n if num_extra_fields != 0 {\n let remainder_start = in_len - num_extra_fields;\n state[0] += input[remainder_start];\n if num_extra_fields > 1 {\n state[1] += input[remainder_start + 1];\n }\n }\n } else {\n let mut states: [[Field; 4]; N / RATE + 1] = [[0; 4]; N / RATE + 1];\n states[0] = state;\n\n // process all full RATE-sized chunks, storing state after each permutation\n for chunk_idx in 0..(N / RATE) {\n for i in 0..RATE {\n state[i] += input[chunk_idx * RATE + i];\n }\n state = crate::poseidon2_permutation(state);\n states[chunk_idx + 1] = state;\n }\n\n // get state at the last full block before in_len\n let first_partially_filled_chunk = in_len / RATE;\n state = states[first_partially_filled_chunk];\n\n // handle remaining elements after last full RATE-sized chunk\n let remainder_start = (in_len / RATE) * RATE;\n for j in 0..RATE {\n let idx = remainder_start + j;\n if idx < in_len {\n state[j] += input[idx];\n }\n }\n }\n\n // always run final permutation unless we just completed a full chunk\n // still need to permute once if in_len is 0\n if (in_len == 0) | (in_len % RATE != 0) {\n state = crate::poseidon2_permutation(state);\n };\n\n state[0]\n }\n}\n\npub struct Poseidon2Hasher {\n _state: [Field],\n}\n\nimpl Hasher for Poseidon2Hasher {\n fn finish(self) -> Field {\n let iv: Field = (self._state.len() as Field) * 18446744073709551616; // iv = (self._state.len() << 64)\n let mut sponge = Poseidon2::new(iv);\n for i in 0..self._state.len() {\n sponge.absorb(self._state[i]);\n }\n sponge.squeeze()\n }\n\n fn write(&mut self, input: Field) {\n self._state = self._state.push_back(input);\n }\n}\n\nimpl Default for Poseidon2Hasher {\n fn default() -> Self {\n Poseidon2Hasher { _state: @[] }\n }\n}\n"
808
920
  },
809
- "243": {
921
+ "242": {
810
922
  "function_locations": [
811
923
  {
812
924
  "name": "Reader<N>::new",
@@ -856,7 +968,7 @@
856
968
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/serde/src/reader.nr",
857
969
  "source": "pub struct Reader<let N: u32> {\n data: [Field; N],\n offset: u32,\n}\n\nimpl<let N: u32> Reader<N> {\n pub fn new(data: [Field; N]) -> Self {\n Self { data, offset: 0 }\n }\n\n pub fn read(&mut self) -> Field {\n let result = self.data[self.offset];\n self.offset += 1;\n result\n }\n\n pub fn read_u32(&mut self) -> u32 {\n self.read() as u32\n }\n\n pub fn read_u64(&mut self) -> u64 {\n self.read() as u64\n }\n\n pub fn read_bool(&mut self) -> bool {\n self.read() != 0\n }\n\n pub fn read_array<let K: u32>(&mut self) -> [Field; K] {\n let mut result = [0; K];\n for i in 0..K {\n result[i] = self.data[self.offset + i];\n }\n self.offset += K;\n result\n }\n\n pub fn read_struct<T, let K: u32>(&mut self, deserialise: fn([Field; K]) -> T) -> T {\n let result = deserialise(self.read_array());\n result\n }\n\n pub fn read_struct_array<T, let K: u32, let C: u32>(\n &mut self,\n deserialise: fn([Field; K]) -> T,\n mut result: [T; C],\n ) -> [T; C] {\n for i in 0..C {\n result[i] = self.read_struct(deserialise);\n }\n result\n }\n\n pub fn peek_offset(&mut self, offset: u32) -> Field {\n self.data[self.offset + offset]\n }\n\n pub fn advance_offset(&mut self, offset: u32) {\n self.offset += offset;\n }\n\n pub fn finish(self) {\n assert_eq(self.offset, self.data.len(), \"Reader did not read all data\");\n }\n}\n"
858
970
  },
859
- "244": {
971
+ "243": {
860
972
  "function_locations": [
861
973
  {
862
974
  "name": "derive_serialize",
@@ -864,25 +976,25 @@
864
976
  },
865
977
  {
866
978
  "name": "derive_deserialize",
867
- "start": 7206
979
+ "start": 7208
868
980
  },
869
981
  {
870
982
  "name": "get_params_len_quote",
871
- "start": 10928
983
+ "start": 10934
872
984
  },
873
985
  {
874
986
  "name": "get_generics_declarations",
875
- "start": 11387
987
+ "start": 11393
876
988
  },
877
989
  {
878
990
  "name": "get_where_trait_clause",
879
- "start": 12469
991
+ "start": 12477
880
992
  }
881
993
  ],
882
994
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/serde/src/serialization.nr",
883
- "source": "use crate::{reader::Reader, writer::Writer};\n\n/// Trait for serializing Noir types into arrays of Fields.\n///\n/// An implementation of the Serialize trait has to follow Noir's intrinsic serialization (each member of a struct\n/// converted directly into one or more Fields without any packing or compression). This trait (and Deserialize) are\n/// typically used to communicate between Noir and TypeScript (via oracles and function arguments).\n///\n/// # On Following Noir's Intrinsic Serialization\n/// When calling a Noir function from TypeScript (TS), first the function arguments are serialized into an array\n/// of fields. This array is then included in the initial witness. Noir's intrinsic serialization is then used\n/// to deserialize the arguments from the witness. When the same Noir function is called from Noir this Serialize trait\n/// is used instead of the serialization in TS. For this reason we need to have a match between TS serialization,\n/// Noir's intrinsic serialization and the implementation of this trait. If there is a mismatch, the function calls\n/// fail with an arguments hash mismatch error message.\n///\n/// # Associated Constants\n/// * `N` - The length of the output Field array, known at compile time\n///\n/// # Example\n/// ```\n/// impl<let N: u32> Serialize for str<N> {\n/// let N: u32 = N;\n///\n/// fn serialize(self) -> [Field; Self::N] {\n/// let mut writer: Writer<Self::N> = Writer::new();\n/// self.stream_serialize(&mut writer);\n/// writer.finish()\n/// }\n///\n/// fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n/// let bytes = self.as_bytes();\n/// for i in 0..bytes.len() {\n/// writer.write(bytes[i] as Field);\n/// }\n/// }\n/// }\n/// ```\n#[derive_via(derive_serialize)]\npub trait Serialize {\n let N: u32;\n\n fn serialize(self) -> [Field; Self::N];\n\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>);\n}\n\n/// Generates a `Serialize` trait implementation for a struct type.\n///\n/// # Parameters\n/// - `s`: The struct type definition to generate the implementation for\n///\n/// # Returns\n/// A quoted code block containing the trait implementation\n///\n/// # Example\n/// For a struct defined as:\n/// ```\n/// struct Log<N> {\n/// fields: [Field; N],\n/// length: u32\n/// }\n/// ```\n///\n/// This function generates code equivalent to:\n/// ```\n/// impl<let N: u32> Serialize for Log<N> {\n/// let N: u32 = <[Field; N] as Serialize>::N + <u32 as Serialize>::N;\n///\n/// fn serialize(self) -> [Field; Self::N] {\n/// let mut writer: Writer<Self::N> = Writer::new();\n/// self.stream_serialize(&mut writer);\n/// writer.finish()\n/// }\n///\n/// #[inline_always]\n/// fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n/// Serialize::stream_serialize(self.fields, writer);\n/// Serialize::stream_serialize(self.length, writer);\n/// }\n/// }\n/// ```\npub comptime fn derive_serialize(s: TypeDefinition) -> Quoted {\n let typ = s.as_type();\n let nested_struct = typ.as_data_type().unwrap();\n\n // We care only about the name and type so we drop the last item of the tuple\n let params = nested_struct.0.fields(nested_struct.1).map(|(name, typ, _)| (name, typ));\n\n // Generates the generic parameter declarations (to be placed after the `impl` keyword) and the `where` clause\n // for the `Serialize` trait.\n let generics_declarations = get_generics_declarations(s);\n let where_serialize_clause = get_where_trait_clause(s, quote {Serialize});\n\n let params_len_quote = get_params_len_quote(params);\n\n let function_body = params\n .map(|(name, _typ): (Quoted, Type)| {\n quote {\n $crate::serialization::Serialize::stream_serialize(self.$name, writer);\n }\n })\n .join(quote {});\n\n quote {\n impl$generics_declarations $crate::serialization::Serialize for $typ\n $where_serialize_clause\n {\n let N: u32 = $params_len_quote;\n\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: $crate::writer::Writer<Self::N> = $crate::writer::Writer::new();\n $crate::serialization::Serialize::stream_serialize(self, &mut writer);\n writer.finish()\n }\n\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut $crate::writer::Writer<K>) {\n $function_body\n }\n }\n }\n}\n\n/// Trait for deserializing Noir types from arrays of Fields.\n///\n/// An implementation of the Deserialize trait has to follow Noir's intrinsic serialization (each member of a struct\n/// converted directly into one or more Fields without any packing or compression). This trait is typically used when\n/// deserializing return values from function calls in Noir. Since the same function could be called from TypeScript\n/// (TS), in which case the TS deserialization would get used, we need to have a match between the 2.\n///\n/// # Associated Constants\n/// * `N` - The length of the input Field array, known at compile time\n///\n/// # Example\n/// ```\n/// impl<let M: u32> Deserialize for str<M> {\n/// let N: u32 = M;\n///\n/// fn deserialize(fields: [Field; Self::N]) -> Self {\n/// let mut reader = Reader::new(fields);\n/// let result = Self::stream_deserialize(&mut reader);\n/// reader.finish();\n/// result\n/// }\n///\n/// fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n/// let mut bytes = [0 as u8; M];\n/// for i in 0..M {\n/// bytes[i] = reader.read() as u8;\n/// }\n/// str::<M>::from(bytes)\n/// }\n/// }\n/// ```\n#[derive_via(derive_deserialize)]\npub trait Deserialize {\n let N: u32;\n\n fn deserialize(fields: [Field; Self::N]) -> Self;\n\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self;\n}\n\n/// Generates a `Deserialize` trait implementation for a given struct `s`.\n///\n/// # Arguments\n/// * `s` - The struct type definition to generate the implementation for\n///\n/// # Returns\n/// A `Quoted` block containing the generated trait implementation\n///\n/// # Requirements\n/// Each struct member type must implement the `Deserialize` trait (it gets used in the generated code).\n///\n/// # Example\n/// For a struct like:\n/// ```\n/// struct MyStruct {\n/// x: AztecAddress,\n/// y: Field,\n/// }\n/// ```\n///\n/// This generates:\n/// ```\n/// impl Deserialize for MyStruct {\n/// let N: u32 = <AztecAddress as Deserialize>::N + <Field as Deserialize>::N;\n///\n/// fn deserialize(fields: [Field; Self::N]) -> Self {\n/// let mut reader = Reader::new(fields);\n/// let result = Self::stream_deserialize(&mut reader);\n/// reader.finish();\n/// result\n/// }\n///\n/// #[inline_always]\n/// fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n/// let x = <AztecAddress as Deserialize>::stream_deserialize(reader);\n/// let y = <Field as Deserialize>::stream_deserialize(reader);\n/// Self { x, y }\n/// }\n/// }\n/// ```\npub comptime fn derive_deserialize(s: TypeDefinition) -> Quoted {\n let typ = s.as_type();\n let nested_struct = typ.as_data_type().unwrap();\n let params = nested_struct.0.fields(nested_struct.1);\n\n // Generates the generic parameter declarations (to be placed after the `impl` keyword) and the `where` clause\n // for the `Deserialize` trait.\n let generics_declarations = get_generics_declarations(s);\n let where_deserialize_clause = get_where_trait_clause(s, quote {Deserialize});\n\n // The following will give us:\n // <type_of_struct_member_1 as Deserialize>::N + <type_of_struct_member_2 as Deserialize>::N + ...\n // (or 0 if the struct has no members)\n let right_hand_side_of_definition_of_n = if params.len() > 0 {\n params\n .map(|(_, param_type, _): (Quoted, Type, Quoted)| {\n quote {\n <$param_type as $crate::serialization::Deserialize>::N\n }\n })\n .join(quote {+})\n } else {\n quote {0}\n };\n\n // For structs containing a single member, we can enhance performance by directly deserializing the input array,\n // bypassing the need for loop-based array construction. While this optimization yields significant benefits in\n // Brillig where the loops are expected to not be optimized, it is not relevant in ACIR where the loops are\n // expected to be optimized away.\n let function_body = if params.len() > 1 {\n // This generates deserialization code for each struct member and concatenates them together.\n let deserialization_of_struct_members = params\n .map(|(param_name, param_type, _): (Quoted, Type, Quoted)| {\n quote {\n let $param_name = <$param_type as Deserialize>::stream_deserialize(reader);\n }\n })\n .join(quote {});\n\n // We join the struct member names with a comma to be used in the `Self { ... }` syntax\n // This will give us e.g. `a, b, c` for a struct with three fields named `a`, `b`, and `c`.\n let struct_members = params\n .map(|(param_name, _, _): (Quoted, Type, Quoted)| quote { $param_name })\n .join(quote {,});\n\n quote {\n $deserialization_of_struct_members\n\n Self { $struct_members }\n }\n } else if params.len() == 1 {\n let param_name = params[0].0;\n quote {\n Self { $param_name: $crate::serialization::Deserialize::stream_deserialize(reader) }\n }\n } else {\n quote {\n Self {}\n }\n };\n\n quote {\n impl$generics_declarations $crate::serialization::Deserialize for $typ\n $where_deserialize_clause\n {\n let N: u32 = $right_hand_side_of_definition_of_n;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = $crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut $crate::reader::Reader<K>) -> Self {\n $function_body\n }\n }\n }\n}\n\n/// Generates a quoted expression that computes the total serialized length of function parameters.\n///\n/// # Parameters\n/// * `params` - An array of tuples where each tuple contains a quoted parameter name and its Type. The type needs\n/// to implement the Serialize trait.\n///\n/// # Returns\n/// A quoted expression that evaluates to:\n/// * `0` if there are no parameters\n/// * `(<type1 as Serialize>::N + <type2 as Serialize>::N + ...)` for one or more parameters\ncomptime fn get_params_len_quote(params: [(Quoted, Type)]) -> Quoted {\n if params.len() == 0 {\n quote { 0 }\n } else {\n let params_quote_without_parentheses = params\n .map(|(_, param_type): (Quoted, Type)| {\n quote {\n <$param_type as $crate::serialization::Serialize>::N\n }\n })\n .join(quote {+});\n quote { ($params_quote_without_parentheses) }\n }\n}\n\ncomptime fn get_generics_declarations(s: TypeDefinition) -> Quoted {\n let generics = s.generics();\n\n if generics.len() > 0 {\n let generics_declarations_items = generics\n .map(|(name, maybe_integer_typ)| {\n // The second item in the generics tuple is an Option of an integer type that is Some only if\n // the generic is numeric.\n if maybe_integer_typ.is_some() {\n // The generic is numeric, so we return a quote defined as e.g. \"let N: u32\"\n let integer_type = maybe_integer_typ.unwrap();\n quote {let $name: $integer_type}\n } else {\n // The generic is not numeric, so we return a quote containing the name of the generic (e.g. \"T\")\n quote {$name}\n }\n })\n .join(quote {,});\n quote {<$generics_declarations_items>}\n } else {\n // The struct doesn't have any generics defined, so we just return an empty quote.\n quote {}\n }\n}\n\ncomptime fn get_where_trait_clause(s: TypeDefinition, trait_name: Quoted) -> Quoted {\n let generics = s.generics();\n\n // The second item in the generics tuple is an Option of an integer type that is Some only if the generic is\n // numeric.\n let non_numeric_generics =\n generics.filter(|(_, maybe_integer_typ)| maybe_integer_typ.is_none());\n\n if non_numeric_generics.len() > 0 {\n let non_numeric_generics_declarations =\n non_numeric_generics.map(|(name, _)| quote {$name: $trait_name}).join(quote {,});\n quote {where $non_numeric_generics_declarations}\n } else {\n // There are no non-numeric generics, so we return an empty quote.\n quote {}\n }\n}\n"
995
+ "source": "use crate::{reader::Reader, writer::Writer};\n\n/// Trait for serializing Noir types into arrays of Fields.\n///\n/// An implementation of the Serialize trait has to follow Noir's intrinsic serialization (each member of a struct\n/// converted directly into one or more Fields without any packing or compression). This trait (and Deserialize) are\n/// typically used to communicate between Noir and TypeScript (via oracles and function arguments).\n///\n/// # On Following Noir's Intrinsic Serialization\n/// When calling a Noir function from TypeScript (TS), first the function arguments are serialized into an array\n/// of fields. This array is then included in the initial witness. Noir's intrinsic serialization is then used\n/// to deserialize the arguments from the witness. When the same Noir function is called from Noir this Serialize trait\n/// is used instead of the serialization in TS. For this reason we need to have a match between TS serialization,\n/// Noir's intrinsic serialization and the implementation of this trait. If there is a mismatch, the function calls\n/// fail with an arguments hash mismatch error message.\n///\n/// # Associated Constants\n/// * `N` - The length of the output Field array, known at compile time\n///\n/// # Example\n/// ```\n/// impl<let N: u32> Serialize for str<N> {\n/// let N: u32 = N;\n///\n/// fn serialize(self) -> [Field; Self::N] {\n/// let mut writer: Writer<Self::N> = Writer::new();\n/// self.stream_serialize(&mut writer);\n/// writer.finish()\n/// }\n///\n/// fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n/// let bytes = self.as_bytes();\n/// for i in 0..bytes.len() {\n/// writer.write(bytes[i] as Field);\n/// }\n/// }\n/// }\n/// ```\n#[derive_via(derive_serialize)]\npub trait Serialize {\n let N: u32;\n\n fn serialize(self) -> [Field; Self::N];\n\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>);\n}\n\n/// Generates a `Serialize` trait implementation for a struct type.\n///\n/// # Parameters\n/// - `s`: The struct type definition to generate the implementation for\n///\n/// # Returns\n/// A quoted code block containing the trait implementation\n///\n/// # Example\n/// For a struct defined as:\n/// ```\n/// struct Log<N> {\n/// fields: [Field; N],\n/// length: u32\n/// }\n/// ```\n///\n/// This function generates code equivalent to:\n/// ```\n/// impl<let N: u32> Serialize for Log<N> {\n/// let N: u32 = <[Field; N] as Serialize>::N + <u32 as Serialize>::N;\n///\n/// fn serialize(self) -> [Field; Self::N] {\n/// let mut writer: Writer<Self::N> = Writer::new();\n/// self.stream_serialize(&mut writer);\n/// writer.finish()\n/// }\n///\n/// #[inline_always]\n/// fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n/// Serialize::stream_serialize(self.fields, writer);\n/// Serialize::stream_serialize(self.length, writer);\n/// }\n/// }\n/// ```\npub comptime fn derive_serialize(s: TypeDefinition) -> Quoted {\n let typ = s.as_type();\n let nested_struct = typ.as_data_type().unwrap();\n\n // We care only about the name and type so we drop the last item of the tuple\n let params = nested_struct.0.fields(nested_struct.1).map(|(name, typ, _)| (name, typ));\n\n // Generates the generic parameter declarations (to be placed after the `impl` keyword) and the `where` clause\n // for the `Serialize` trait.\n let generics_declarations = get_generics_declarations(s);\n let where_serialize_clause = get_where_trait_clause(s, quote { Serialize });\n\n let params_len_quote = get_params_len_quote(params);\n\n let function_body = params\n .map(|(name, _typ): (Quoted, Type)| {\n quote {\n $crate::serialization::Serialize::stream_serialize(self.$name, writer);\n }\n })\n .join(quote {});\n\n quote {\n impl$generics_declarations $crate::serialization::Serialize for $typ\n $where_serialize_clause\n {\n let N: u32 = $params_len_quote;\n\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: $crate::writer::Writer<Self::N> = $crate::writer::Writer::new();\n $crate::serialization::Serialize::stream_serialize(self, &mut writer);\n writer.finish()\n }\n\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut $crate::writer::Writer<K>) {\n $function_body\n }\n }\n }\n}\n\n/// Trait for deserializing Noir types from arrays of Fields.\n///\n/// An implementation of the Deserialize trait has to follow Noir's intrinsic serialization (each member of a struct\n/// converted directly into one or more Fields without any packing or compression). This trait is typically used when\n/// deserializing return values from function calls in Noir. Since the same function could be called from TypeScript\n/// (TS), in which case the TS deserialization would get used, we need to have a match between the 2.\n///\n/// # Associated Constants\n/// * `N` - The length of the input Field array, known at compile time\n///\n/// # Example\n/// ```\n/// impl<let M: u32> Deserialize for str<M> {\n/// let N: u32 = M;\n///\n/// fn deserialize(fields: [Field; Self::N]) -> Self {\n/// let mut reader = Reader::new(fields);\n/// let result = Self::stream_deserialize(&mut reader);\n/// reader.finish();\n/// result\n/// }\n///\n/// fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n/// let mut bytes = [0 as u8; M];\n/// for i in 0..M {\n/// bytes[i] = reader.read() as u8;\n/// }\n/// str::<M>::from(bytes)\n/// }\n/// }\n/// ```\n#[derive_via(derive_deserialize)]\npub trait Deserialize {\n let N: u32;\n\n fn deserialize(fields: [Field; Self::N]) -> Self;\n\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self;\n}\n\n/// Generates a `Deserialize` trait implementation for a given struct `s`.\n///\n/// # Arguments\n/// * `s` - The struct type definition to generate the implementation for\n///\n/// # Returns\n/// A `Quoted` block containing the generated trait implementation\n///\n/// # Requirements\n/// Each struct member type must implement the `Deserialize` trait (it gets used in the generated code).\n///\n/// # Example\n/// For a struct like:\n/// ```\n/// struct MyStruct {\n/// x: AztecAddress,\n/// y: Field,\n/// }\n/// ```\n///\n/// This generates:\n/// ```\n/// impl Deserialize for MyStruct {\n/// let N: u32 = <AztecAddress as Deserialize>::N + <Field as Deserialize>::N;\n///\n/// fn deserialize(fields: [Field; Self::N]) -> Self {\n/// let mut reader = Reader::new(fields);\n/// let result = Self::stream_deserialize(&mut reader);\n/// reader.finish();\n/// result\n/// }\n///\n/// #[inline_always]\n/// fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n/// let x = <AztecAddress as Deserialize>::stream_deserialize(reader);\n/// let y = <Field as Deserialize>::stream_deserialize(reader);\n/// Self { x, y }\n/// }\n/// }\n/// ```\npub comptime fn derive_deserialize(s: TypeDefinition) -> Quoted {\n let typ = s.as_type();\n let nested_struct = typ.as_data_type().unwrap();\n let params = nested_struct.0.fields(nested_struct.1);\n\n // Generates the generic parameter declarations (to be placed after the `impl` keyword) and the `where` clause\n // for the `Deserialize` trait.\n let generics_declarations = get_generics_declarations(s);\n let where_deserialize_clause = get_where_trait_clause(s, quote { Deserialize });\n\n // The following will give us:\n // <type_of_struct_member_1 as Deserialize>::N + <type_of_struct_member_2 as Deserialize>::N + ...\n // (or 0 if the struct has no members)\n let right_hand_side_of_definition_of_n = if params.len() > 0 {\n params\n .map(|(_, param_type, _): (Quoted, Type, Quoted)| {\n quote {\n <$param_type as $crate::serialization::Deserialize>::N\n }\n })\n .join(quote {+})\n } else {\n quote { 0 }\n };\n\n // For structs containing a single member, we can enhance performance by directly deserializing the input array,\n // bypassing the need for loop-based array construction. While this optimization yields significant benefits in\n // Brillig where the loops are expected to not be optimized, it is not relevant in ACIR where the loops are\n // expected to be optimized away.\n let function_body = if params.len() > 1 {\n // This generates deserialization code for each struct member and concatenates them together.\n let deserialization_of_struct_members = params\n .map(|(param_name, param_type, _): (Quoted, Type, Quoted)| {\n quote {\n let $param_name = <$param_type as Deserialize>::stream_deserialize(reader);\n }\n })\n .join(quote {});\n\n // We join the struct member names with a comma to be used in the `Self { ... }` syntax\n // This will give us e.g. `a, b, c` for a struct with three fields named `a`, `b`, and `c`.\n let struct_members = params\n .map(|(param_name, _, _): (Quoted, Type, Quoted)| quote { $param_name })\n .join(quote {,});\n\n quote {\n $deserialization_of_struct_members\n\n Self { $struct_members }\n }\n } else if params.len() == 1 {\n let param_name = params[0].0;\n quote {\n Self { $param_name: $crate::serialization::Deserialize::stream_deserialize(reader) }\n }\n } else {\n quote {\n Self {}\n }\n };\n\n quote {\n impl$generics_declarations $crate::serialization::Deserialize for $typ\n $where_deserialize_clause\n {\n let N: u32 = $right_hand_side_of_definition_of_n;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = $crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut $crate::reader::Reader<K>) -> Self {\n $function_body\n }\n }\n }\n}\n\n/// Generates a quoted expression that computes the total serialized length of function parameters.\n///\n/// # Parameters\n/// * `params` - An array of tuples where each tuple contains a quoted parameter name and its Type. The type needs\n/// to implement the Serialize trait.\n///\n/// # Returns\n/// A quoted expression that evaluates to:\n/// * `0` if there are no parameters\n/// * `(<type1 as Serialize>::N + <type2 as Serialize>::N + ...)` for one or more parameters\ncomptime fn get_params_len_quote(params: [(Quoted, Type)]) -> Quoted {\n if params.len() == 0 {\n quote { 0 }\n } else {\n let params_quote_without_parentheses = params\n .map(|(_, param_type): (Quoted, Type)| {\n quote {\n <$param_type as $crate::serialization::Serialize>::N\n }\n })\n .join(quote {+});\n quote { ($params_quote_without_parentheses) }\n }\n}\n\ncomptime fn get_generics_declarations(s: TypeDefinition) -> Quoted {\n let generics = s.generics();\n\n if generics.len() > 0 {\n let generics_declarations_items = generics\n .map(|(name, maybe_integer_typ)| {\n // The second item in the generics tuple is an Option of an integer type that is Some only if\n // the generic is numeric.\n if maybe_integer_typ.is_some() {\n // The generic is numeric, so we return a quote defined as e.g. \"let N: u32\"\n let integer_type = maybe_integer_typ.unwrap();\n quote {let $name: $integer_type}\n } else {\n // The generic is not numeric, so we return a quote containing the name of the generic (e.g. \"T\")\n quote { $name }\n }\n })\n .join(quote {,});\n quote {<$generics_declarations_items>}\n } else {\n // The struct doesn't have any generics defined, so we just return an empty quote.\n quote {}\n }\n}\n\ncomptime fn get_where_trait_clause(s: TypeDefinition, trait_name: Quoted) -> Quoted {\n let generics = s.generics();\n\n // The second item in the generics tuple is an Option of an integer type that is Some only if the generic is\n // numeric.\n let non_numeric_generics =\n generics.filter(|(_, maybe_integer_typ)| maybe_integer_typ.is_none());\n\n if non_numeric_generics.len() > 0 {\n let non_numeric_generics_declarations =\n non_numeric_generics.map(|(name, _)| quote {$name: $trait_name}).join(quote {,});\n quote {where $non_numeric_generics_declarations}\n } else {\n // There are no non-numeric generics, so we return an empty quote.\n quote {}\n }\n}\n"
884
996
  },
885
- "246": {
997
+ "245": {
886
998
  "function_locations": [
887
999
  {
888
1000
  "name": "<impl Serialize for bool>::serialize",
@@ -1174,29 +1286,29 @@
1174
1286
  },
1175
1287
  {
1176
1288
  "name": "<impl Serialize for (T1,)>::serialize",
1177
- "start": 20158
1289
+ "start": 20178
1178
1290
  },
1179
1291
  {
1180
1292
  "name": "<impl Serialize for (T1,)>::stream_serialize",
1181
- "start": 20409
1293
+ "start": 20429
1182
1294
  },
1183
1295
  {
1184
1296
  "name": "<impl Deserialize for (T1,)>::deserialize",
1185
- "start": 20616
1297
+ "start": 20636
1186
1298
  },
1187
1299
  {
1188
1300
  "name": "<impl Deserialize for (T1,)>::stream_deserialize",
1189
- "start": 20877
1301
+ "start": 20897
1190
1302
  },
1191
1303
  {
1192
1304
  "name": "bounded_vec_serialization",
1193
- "start": 21226
1305
+ "start": 21246
1194
1306
  }
1195
1307
  ],
1196
1308
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/serde/src/type_impls.nr",
1197
- "source": "use crate::{reader::Reader, serialization::{Deserialize, Serialize}, writer::Writer};\nuse std::embedded_curve_ops::EmbeddedCurvePoint;\nuse std::embedded_curve_ops::EmbeddedCurveScalar;\n\nglobal BOOL_SERIALIZED_LEN: u32 = 1;\nglobal U8_SERIALIZED_LEN: u32 = 1;\nglobal U16_SERIALIZED_LEN: u32 = 1;\nglobal U32_SERIALIZED_LEN: u32 = 1;\nglobal U64_SERIALIZED_LEN: u32 = 1;\nglobal U128_SERIALIZED_LEN: u32 = 1;\nglobal FIELD_SERIALIZED_LEN: u32 = 1;\nglobal I8_SERIALIZED_LEN: u32 = 1;\nglobal I16_SERIALIZED_LEN: u32 = 1;\nglobal I32_SERIALIZED_LEN: u32 = 1;\nglobal I64_SERIALIZED_LEN: u32 = 1;\n\nimpl Serialize for bool {\n let N: u32 = BOOL_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for bool {\n let N: u32 = BOOL_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> bool {\n reader.read() != 0\n }\n}\n\nimpl Serialize for u8 {\n let N: u32 = U8_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u8 {\n let N: u32 = U8_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u8\n }\n}\n\nimpl Serialize for u16 {\n let N: u32 = U16_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u16 {\n let N: u32 = U16_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u16\n }\n}\n\nimpl Serialize for u32 {\n let N: u32 = U32_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u32 {\n let N: u32 = U32_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u32\n }\n}\n\nimpl Serialize for u64 {\n let N: u32 = U64_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u64 {\n let N: u32 = U64_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u64\n }\n}\n\nimpl Serialize for u128 {\n let N: u32 = U128_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u128 {\n let N: u32 = U128_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u128\n }\n}\n\nimpl Serialize for Field {\n let N: u32 = FIELD_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self);\n }\n}\n\nimpl Deserialize for Field {\n let N: u32 = FIELD_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read()\n }\n}\n\nimpl Serialize for i8 {\n let N: u32 = I8_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u8 as Field);\n }\n}\n\nimpl Deserialize for i8 {\n let N: u32 = I8_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u8 as i8\n }\n}\n\nimpl Serialize for i16 {\n let N: u32 = I16_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u16 as Field);\n }\n}\n\nimpl Deserialize for i16 {\n let N: u32 = I16_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u16 as i16\n }\n}\n\nimpl Serialize for i32 {\n let N: u32 = I32_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u32 as Field);\n }\n}\n\nimpl Deserialize for i32 {\n let N: u32 = I32_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u32 as i32\n }\n}\n\nimpl Serialize for i64 {\n let N: u32 = I64_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u64 as Field);\n }\n}\n\nimpl Deserialize for i64 {\n let N: u32 = I64_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u64 as i64\n }\n}\n\nimpl<T, let M: u32> Serialize for [T; M]\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N * M;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n for i in 0..M {\n self[i].stream_serialize(writer);\n }\n }\n}\n\nimpl<T, let M: u32> Deserialize for [T; M]\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N * M;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let mut result: [T; M] = std::mem::zeroed();\n for i in 0..M {\n result[i] = T::stream_deserialize(reader);\n }\n result\n }\n}\n\nimpl<T> Serialize for Option<T>\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N + 1;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write_bool(self.is_some());\n if self.is_some() {\n self.unwrap_unchecked().stream_serialize(writer);\n } else {\n writer.advance_offset(<T as Serialize>::N);\n }\n }\n}\n\nimpl<T> Deserialize for Option<T>\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N + 1;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n if reader.read_bool() {\n Option::some(<T as Deserialize>::stream_deserialize(reader))\n } else {\n reader.advance_offset(<T as Deserialize>::N);\n Option::none()\n }\n }\n}\n\nglobal SCALAR_SIZE: u32 = 2;\n\nimpl Serialize for EmbeddedCurveScalar {\n\n let N: u32 = SCALAR_SIZE;\n\n fn serialize(self) -> [Field; SCALAR_SIZE] {\n [self.lo, self.hi]\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self.lo);\n writer.write(self.hi);\n }\n}\n\nimpl Deserialize for EmbeddedCurveScalar {\n let N: u32 = SCALAR_SIZE;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Self { lo: fields[0], hi: fields[1] }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Self { lo: reader.read(), hi: reader.read() }\n }\n}\n\nglobal POINT_SIZE: u32 = 2;\n\nimpl Serialize for EmbeddedCurvePoint {\n let N: u32 = POINT_SIZE;\n\n fn serialize(self) -> [Field; Self::N] {\n [self.x, self.y]\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 }\n}\n\nimpl Deserialize for EmbeddedCurvePoint {\n let N: u32 = POINT_SIZE;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Self { x: fields[0], y: fields[1] }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Self { x: reader.read(), y: reader.read() }\n }\n}\n\nimpl<let M: u32> Deserialize for str<M> {\n let N: u32 = M;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let u8_arr = <[u8; Self::N] as Deserialize>::stream_deserialize(reader);\n str::<Self::N>::from(u8_arr)\n }\n}\n\nimpl<let M: u32> Serialize for str<M> {\n let N: u32 = M;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.as_bytes().stream_serialize(writer);\n }\n}\n\n// Note: Not deriving this because it's not supported to call derive_serialize on a \"remote\" struct (and it will never\n// be supported).\nimpl<T, let M: u32> Deserialize for BoundedVec<T, M>\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N * M + 1;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let mut new_bounded_vec: BoundedVec<T, M> = BoundedVec::new();\n let payload_len = Self::N - 1;\n\n // Length is stored in the last field as we need to match intrinsic Noir serialization and the `len` struct\n // field is after `storage` struct field (see `bounded_vec.nr` in noir-stdlib)\n let len = reader.peek_offset(payload_len) as u32;\n\n for i in 0..M {\n if i < len {\n new_bounded_vec.push(<T as Deserialize>::stream_deserialize(reader));\n }\n }\n\n // +1 for the length of the BoundedVec\n reader.advance_offset((M - len) * <T as Deserialize>::N + 1);\n\n new_bounded_vec\n }\n}\n\n// This may cause issues if used as program input, because noir disallows empty arrays for program input.\n// I think this is okay because I don't foresee a unit type being used as input. But leaving this comment as a hint\n// if someone does run into this in the future.\nimpl Deserialize for () {\n let N: u32 = 0;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(_reader: &mut Reader<K>) -> Self {\n ()\n }\n}\n\n// Note: Not deriving this because it's not supported to call derive_serialize on a \"remote\" struct (and it will never\n// be supported).\nimpl<T, let M: u32> Serialize for BoundedVec<T, M>\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N * M + 1; // +1 for the length of the BoundedVec\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.storage().stream_serialize(writer);\n // Length is stored in the last field as we need to match intrinsic Noir serialization and the `len` struct\n // field is after `storage` struct field (see `bounded_vec.nr` in noir-stdlib)\n writer.write_u32(self.len() as u32);\n }\n}\n\n// Create a slice of the given length with each element made from `f(i)` where `i` is the current index\ncomptime fn make_slice<Env, T>(length: u32, f: fn[Env](u32) -> T) -> [T] {\n let mut slice = @[];\n for i in 0..length {\n slice = slice.push_back(f(i));\n }\n slice\n}\n\n// Implements Serialize and Deserialize for an arbitrary tuple type\ncomptime fn impl_serialize_for_tuple(_m: Module, length: u32) -> Quoted {\n // `T0`, `T1`, `T2`\n let type_names = make_slice(length, |i| f\"T{i}\".quoted_contents());\n\n // `result0`, `result1`, `result2`\n let result_names = make_slice(length, |i| f\"result{i}\".quoted_contents());\n\n // `T0, T1, T2`\n let field_generics = type_names.join(quote [,]);\n\n // `<T0 as Serialize>::N + <T1 as Serialize>::N + <T2 as Serialize>::N`\n let full_size_serialize = type_names\n .map(|type_name| quote {\n <$type_name as Serialize>::N\n })\n .join(quote [+]);\n\n // `<T0 as Deserialize>::N + <T1 as Deserialize>::N + <T2 as Deserialize>::N`\n let full_size_deserialize = type_names\n .map(|type_name| quote {\n <$type_name as Deserialize>::N\n })\n .join(quote [+]);\n\n // `T0: Serialize, T1: Serialize, T2: Serialize,`\n let serialize_constraints = type_names\n .map(|field_name| quote {\n $field_name: Serialize,\n })\n .join(quote []);\n\n // `T0: Deserialize, T1: Deserialize, T2: Deserialize,`\n let deserialize_constraints = type_names\n .map(|field_name| quote {\n $field_name: Deserialize,\n })\n .join(quote []);\n\n // Statements to serialize each field\n let serialized_fields = type_names\n .mapi(|i, _type_name| quote {\n $crate::serialization::Serialize::stream_serialize(self.$i, writer);\n })\n .join(quote []);\n\n // Statements to deserialize each field\n let deserialized_fields = type_names\n .mapi(|i, type_name| {\n let result_name = result_names[i];\n quote {\n let $result_name = <$type_name as $crate::serialization::Deserialize>::stream_deserialize(reader);\n }\n })\n .join(quote []);\n let deserialize_results = result_names.join(quote [,]);\n\n quote {\n impl<$field_generics> Serialize for ($field_generics) where $serialize_constraints {\n let N: u32 = $full_size_serialize;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: $crate::writer::Writer<Self::N> = $crate::writer::Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut $crate::writer::Writer<K>) {\n\n $serialized_fields\n }\n }\n\n impl<$field_generics> Deserialize for ($field_generics) where $deserialize_constraints {\n let N: u32 = $full_size_deserialize;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = $crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n \n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut $crate::reader::Reader<K>) -> Self {\n $deserialized_fields\n ($deserialize_results)\n }\n }\n }\n}\n\n// Keeping these manual impls. They are more efficient since they do not\n// require copying sub-arrays from any serialized arrays.\nimpl<T1> Serialize for (T1,)\nwhere\n T1: Serialize,\n{\n let N: u32 = <T1 as Serialize>::N;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: crate::writer::Writer<Self::N> = crate::writer::Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.0.stream_serialize(writer);\n }\n}\n\nimpl<T1> Deserialize for (T1,)\nwhere\n T1: Deserialize,\n{\n let N: u32 = <T1 as Deserialize>::N;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n (<T1 as Deserialize>::stream_deserialize(reader),)\n }\n}\n\n#[impl_serialize_for_tuple(2)]\n#[impl_serialize_for_tuple(3)]\n#[impl_serialize_for_tuple(4)]\n#[impl_serialize_for_tuple(5)]\n#[impl_serialize_for_tuple(6)]\nmod impls {\n use crate::serialization::{Deserialize, Serialize};\n}\n\n#[test]\nunconstrained fn bounded_vec_serialization() {\n // Test empty BoundedVec\n let empty_vec: BoundedVec<Field, 3> = BoundedVec::from_array([]);\n let serialized = empty_vec.serialize();\n let deserialized = BoundedVec::<Field, 3>::deserialize(serialized);\n assert_eq(empty_vec, deserialized);\n assert_eq(deserialized.len(), 0);\n\n // Test partially filled BoundedVec\n let partial_vec: BoundedVec<[u32; 2], 3> = BoundedVec::from_array([[1, 2]]);\n let serialized = partial_vec.serialize();\n let deserialized = BoundedVec::<[u32; 2], 3>::deserialize(serialized);\n assert_eq(partial_vec, deserialized);\n assert_eq(deserialized.len(), 1);\n assert_eq(deserialized.get(0), [1, 2]);\n\n // Test full BoundedVec\n let full_vec: BoundedVec<[u32; 2], 3> = BoundedVec::from_array([[1, 2], [3, 4], [5, 6]]);\n let serialized = full_vec.serialize();\n let deserialized = BoundedVec::<[u32; 2], 3>::deserialize(serialized);\n assert_eq(full_vec, deserialized);\n assert_eq(deserialized.len(), 3);\n assert_eq(deserialized.get(0), [1, 2]);\n assert_eq(deserialized.get(1), [3, 4]);\n assert_eq(deserialized.get(2), [5, 6]);\n}\n"
1309
+ "source": "use crate::{reader::Reader, serialization::{Deserialize, Serialize}, writer::Writer};\nuse std::embedded_curve_ops::EmbeddedCurvePoint;\nuse std::embedded_curve_ops::EmbeddedCurveScalar;\n\nglobal BOOL_SERIALIZED_LEN: u32 = 1;\nglobal U8_SERIALIZED_LEN: u32 = 1;\nglobal U16_SERIALIZED_LEN: u32 = 1;\nglobal U32_SERIALIZED_LEN: u32 = 1;\nglobal U64_SERIALIZED_LEN: u32 = 1;\nglobal U128_SERIALIZED_LEN: u32 = 1;\nglobal FIELD_SERIALIZED_LEN: u32 = 1;\nglobal I8_SERIALIZED_LEN: u32 = 1;\nglobal I16_SERIALIZED_LEN: u32 = 1;\nglobal I32_SERIALIZED_LEN: u32 = 1;\nglobal I64_SERIALIZED_LEN: u32 = 1;\n\nimpl Serialize for bool {\n let N: u32 = BOOL_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for bool {\n let N: u32 = BOOL_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> bool {\n reader.read() != 0\n }\n}\n\nimpl Serialize for u8 {\n let N: u32 = U8_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u8 {\n let N: u32 = U8_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u8\n }\n}\n\nimpl Serialize for u16 {\n let N: u32 = U16_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u16 {\n let N: u32 = U16_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u16\n }\n}\n\nimpl Serialize for u32 {\n let N: u32 = U32_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u32 {\n let N: u32 = U32_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u32\n }\n}\n\nimpl Serialize for u64 {\n let N: u32 = U64_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u64 {\n let N: u32 = U64_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u64\n }\n}\n\nimpl Serialize for u128 {\n let N: u32 = U128_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u128 {\n let N: u32 = U128_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u128\n }\n}\n\nimpl Serialize for Field {\n let N: u32 = FIELD_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self);\n }\n}\n\nimpl Deserialize for Field {\n let N: u32 = FIELD_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read()\n }\n}\n\nimpl Serialize for i8 {\n let N: u32 = I8_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u8 as Field);\n }\n}\n\nimpl Deserialize for i8 {\n let N: u32 = I8_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u8 as i8\n }\n}\n\nimpl Serialize for i16 {\n let N: u32 = I16_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u16 as Field);\n }\n}\n\nimpl Deserialize for i16 {\n let N: u32 = I16_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u16 as i16\n }\n}\n\nimpl Serialize for i32 {\n let N: u32 = I32_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u32 as Field);\n }\n}\n\nimpl Deserialize for i32 {\n let N: u32 = I32_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u32 as i32\n }\n}\n\nimpl Serialize for i64 {\n let N: u32 = I64_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u64 as Field);\n }\n}\n\nimpl Deserialize for i64 {\n let N: u32 = I64_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u64 as i64\n }\n}\n\nimpl<T, let M: u32> Serialize for [T; M]\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N * M;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n for i in 0..M {\n self[i].stream_serialize(writer);\n }\n }\n}\n\nimpl<T, let M: u32> Deserialize for [T; M]\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N * M;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let mut result: [T; M] = std::mem::zeroed();\n for i in 0..M {\n result[i] = T::stream_deserialize(reader);\n }\n result\n }\n}\n\nimpl<T> Serialize for Option<T>\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N + 1;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write_bool(self.is_some());\n if self.is_some() {\n self.unwrap_unchecked().stream_serialize(writer);\n } else {\n writer.advance_offset(<T as Serialize>::N);\n }\n }\n}\n\nimpl<T> Deserialize for Option<T>\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N + 1;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n if reader.read_bool() {\n Option::some(<T as Deserialize>::stream_deserialize(reader))\n } else {\n reader.advance_offset(<T as Deserialize>::N);\n Option::none()\n }\n }\n}\n\nglobal SCALAR_SIZE: u32 = 2;\n\nimpl Serialize for EmbeddedCurveScalar {\n\n let N: u32 = SCALAR_SIZE;\n\n fn serialize(self) -> [Field; SCALAR_SIZE] {\n [self.lo, self.hi]\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self.lo);\n writer.write(self.hi);\n }\n}\n\nimpl Deserialize for EmbeddedCurveScalar {\n let N: u32 = SCALAR_SIZE;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Self { lo: fields[0], hi: fields[1] }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Self { lo: reader.read(), hi: reader.read() }\n }\n}\n\nglobal POINT_SIZE: u32 = 2;\n\nimpl Serialize for EmbeddedCurvePoint {\n let N: u32 = POINT_SIZE;\n\n fn serialize(self) -> [Field; Self::N] {\n [self.x, self.y]\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 }\n}\n\nimpl Deserialize for EmbeddedCurvePoint {\n let N: u32 = POINT_SIZE;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Self { x: fields[0], y: fields[1] }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Self { x: reader.read(), y: reader.read() }\n }\n}\n\nimpl<let M: u32> Deserialize for str<M> {\n let N: u32 = M;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let u8_arr = <[u8; Self::N] as Deserialize>::stream_deserialize(reader);\n str::<Self::N>::from(u8_arr)\n }\n}\n\nimpl<let M: u32> Serialize for str<M> {\n let N: u32 = M;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.as_bytes().stream_serialize(writer);\n }\n}\n\n// Note: Not deriving this because it's not supported to call derive_serialize on a \"remote\" struct (and it will never\n// be supported).\nimpl<T, let M: u32> Deserialize for BoundedVec<T, M>\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N * M + 1;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let mut new_bounded_vec: BoundedVec<T, M> = BoundedVec::new();\n let payload_len = Self::N - 1;\n\n // Length is stored in the last field as we need to match intrinsic Noir serialization and the `len` struct\n // field is after `storage` struct field (see `bounded_vec.nr` in noir-stdlib)\n let len = reader.peek_offset(payload_len) as u32;\n\n for i in 0..M {\n if i < len {\n new_bounded_vec.push(<T as Deserialize>::stream_deserialize(reader));\n }\n }\n\n // +1 for the length of the BoundedVec\n reader.advance_offset((M - len) * <T as Deserialize>::N + 1);\n\n new_bounded_vec\n }\n}\n\n// This may cause issues if used as program input, because noir disallows empty arrays for program input.\n// I think this is okay because I don't foresee a unit type being used as input. But leaving this comment as a hint\n// if someone does run into this in the future.\nimpl Deserialize for () {\n let N: u32 = 0;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(_reader: &mut Reader<K>) -> Self {\n ()\n }\n}\n\n// Note: Not deriving this because it's not supported to call derive_serialize on a \"remote\" struct (and it will never\n// be supported).\nimpl<T, let M: u32> Serialize for BoundedVec<T, M>\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N * M + 1; // +1 for the length of the BoundedVec\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.storage().stream_serialize(writer);\n // Length is stored in the last field as we need to match intrinsic Noir serialization and the `len` struct\n // field is after `storage` struct field (see `bounded_vec.nr` in noir-stdlib)\n writer.write_u32(self.len() as u32);\n }\n}\n\n// Create a slice of the given length with each element made from `f(i)` where `i` is the current index\ncomptime fn make_slice<Env, T>(length: u32, f: fn[Env](u32) -> T) -> [T] {\n let mut slice = @[];\n for i in 0..length {\n slice = slice.push_back(f(i));\n }\n slice\n}\n\n// Implements Serialize and Deserialize for an arbitrary tuple type\ncomptime fn impl_serialize_for_tuple(_m: Module, length: u32) -> Quoted {\n // `T0`, `T1`, `T2`\n let type_names = make_slice(length, |i| f\"T{i}\".quoted_contents());\n\n // `result0`, `result1`, `result2`\n let result_names = make_slice(length, |i| f\"result{i}\".quoted_contents());\n\n // `T0, T1, T2`\n let field_generics = type_names.join(quote [,]);\n\n // `<T0 as Serialize>::N + <T1 as Serialize>::N + <T2 as Serialize>::N`\n let full_size_serialize = type_names\n .map(|type_name| quote {\n <$type_name as Serialize>::N\n })\n .join(quote [+]);\n\n // `<T0 as Deserialize>::N + <T1 as Deserialize>::N + <T2 as Deserialize>::N`\n let full_size_deserialize = type_names\n .map(|type_name| quote {\n <$type_name as Deserialize>::N\n })\n .join(quote [+]);\n\n // `T0: Serialize, T1: Serialize, T2: Serialize,`\n let serialize_constraints = type_names\n .map(|field_name| quote {\n $field_name: Serialize,\n })\n .join(quote []);\n\n // `T0: Deserialize, T1: Deserialize, T2: Deserialize,`\n let deserialize_constraints = type_names\n .map(|field_name| quote {\n $field_name: Deserialize,\n })\n .join(quote []);\n\n // Statements to serialize each field\n let serialized_fields = type_names\n .mapi(|i, _type_name| quote {\n $crate::serialization::Serialize::stream_serialize(self.$i, writer);\n })\n .join(quote []);\n\n // Statements to deserialize each field\n let deserialized_fields = type_names\n .mapi(|i, type_name| {\n let result_name = result_names[i];\n quote {\n let $result_name = <$type_name as $crate::serialization::Deserialize>::stream_deserialize(reader);\n }\n })\n .join(quote []);\n let deserialize_results = result_names.join(quote [,]);\n\n quote {\n impl<$field_generics> Serialize for ($field_generics) where $serialize_constraints {\n let N: u32 = $full_size_serialize;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: $crate::writer::Writer<Self::N> = $crate::writer::Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut $crate::writer::Writer<K>) {\n\n $serialized_fields\n }\n }\n\n impl<$field_generics> Deserialize for ($field_generics) where $deserialize_constraints {\n let N: u32 = $full_size_deserialize;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = $crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n \n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut $crate::reader::Reader<K>) -> Self {\n $deserialized_fields\n ($deserialize_results)\n }\n }\n }\n}\n\n// Keeping these manual impls. They are more efficient since they do not\n// require copying sub-arrays from any serialized arrays.\nimpl<T1> Serialize for (T1,)\nwhere\n T1: Serialize,\n{\n let N: u32 = <T1 as Serialize>::N;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: crate::writer::Writer<Self::N> = crate::writer::Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.0.stream_serialize(writer);\n }\n}\n\nimpl<T1> Deserialize for (T1,)\nwhere\n T1: Deserialize,\n{\n let N: u32 = <T1 as Deserialize>::N;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n (<T1 as Deserialize>::stream_deserialize(reader),)\n }\n}\n\n#[impl_serialize_for_tuple(2)]\n#[impl_serialize_for_tuple(3)]\n#[impl_serialize_for_tuple(4)]\n#[impl_serialize_for_tuple(5)]\n#[impl_serialize_for_tuple(6)]\nmod impls {\n use crate::serialization::{Deserialize, Serialize};\n}\n\n#[test]\nunconstrained fn bounded_vec_serialization() {\n // Test empty BoundedVec\n let empty_vec: BoundedVec<Field, 3> = BoundedVec::from_array([]);\n let serialized = empty_vec.serialize();\n let deserialized = BoundedVec::<Field, 3>::deserialize(serialized);\n assert_eq(empty_vec, deserialized);\n assert_eq(deserialized.len(), 0);\n\n // Test partially filled BoundedVec\n let partial_vec: BoundedVec<[u32; 2], 3> = BoundedVec::from_array([[1, 2]]);\n let serialized = partial_vec.serialize();\n let deserialized = BoundedVec::<[u32; 2], 3>::deserialize(serialized);\n assert_eq(partial_vec, deserialized);\n assert_eq(deserialized.len(), 1);\n assert_eq(deserialized.get(0), [1, 2]);\n\n // Test full BoundedVec\n let full_vec: BoundedVec<[u32; 2], 3> = BoundedVec::from_array([[1, 2], [3, 4], [5, 6]]);\n let serialized = full_vec.serialize();\n let deserialized = BoundedVec::<[u32; 2], 3>::deserialize(serialized);\n assert_eq(full_vec, deserialized);\n assert_eq(deserialized.len(), 3);\n assert_eq(deserialized.get(0), [1, 2]);\n assert_eq(deserialized.get(1), [3, 4]);\n assert_eq(deserialized.get(2), [5, 6]);\n}\n"
1198
1310
  },
1199
- "256": {
1311
+ "255": {
1200
1312
  "function_locations": [
1201
1313
  {
1202
1314
  "name": "sha256",
@@ -1278,7 +1390,7 @@
1278
1390
  "path": "/home/aztec-dev/nargo/github.com/noir-lang/sha256/v0.3.0/src/sha256.nr",
1279
1391
  "source": "use std::hash::sha256_compression;\nuse std::runtime::is_unconstrained;\n\nuse constants::{\n BLOCK_BYTE_PTR, BLOCK_SIZE, HASH, INITIAL_STATE, INT_BLOCK_SIZE, INT_SIZE, INT_SIZE_PTR,\n MSG_BLOCK, MSG_SIZE_PTR, STATE, TWO_POW_16, TWO_POW_24, TWO_POW_32, TWO_POW_8,\n};\n\npub(crate) mod constants;\nmod tests;\nmod oracle_tests;\n\n// Implementation of SHA-256 mapping a byte array of variable length to\n// 32 bytes.\n\n// Deprecated in favour of `sha256_var`\n// docs:start:sha256\npub fn sha256<let N: u32>(input: [u8; N]) -> HASH\n// docs:end:sha256\n{\n digest(input)\n}\n\n// SHA-256 hash function\n#[no_predicates]\npub fn digest<let N: u32>(msg: [u8; N]) -> HASH {\n sha256_var(msg, N)\n}\n\n// Variable size SHA-256 hash\npub fn sha256_var<let N: u32>(msg: [u8; N], message_size: u32) -> HASH {\n assert(message_size <= N);\n\n let (h, msg_block) = process_full_blocks(msg, message_size, INITIAL_STATE);\n\n finalize_sha256_blocks(message_size, h, msg_block)\n}\n\n/// Returns the first partially filled message block along with the internal state prior to its compression.\npub(crate) fn process_full_blocks<let N: u32>(\n msg: [u8; N],\n message_size: u32,\n initial_state: STATE,\n) -> (STATE, MSG_BLOCK) {\n if std::runtime::is_unconstrained() {\n let num_full_blocks = message_size / BLOCK_SIZE;\n // Intermediate hash, starting with the canonical initial value\n let mut h: STATE = initial_state;\n // Pointer into msg_block on a 64 byte scale\n for i in 0..num_full_blocks {\n let msg_block = build_msg_block(msg, message_size, BLOCK_SIZE * i);\n h = sha256_compression(msg_block, h);\n }\n\n // We now build the final un-filled block.\n let msg_byte_ptr = message_size % BLOCK_SIZE;\n let msg_block: MSG_BLOCK = if msg_byte_ptr != 0 {\n let num_full_blocks = message_size / BLOCK_SIZE;\n let msg_start = BLOCK_SIZE * num_full_blocks;\n build_msg_block(msg, message_size, msg_start)\n } else {\n // If the message size is a multiple of the block size (i.e. `msg_byte_ptr == 0`) then this block will be empty,\n // so we short-circuit in this case.\n [0; 16]\n };\n\n (h, msg_block)\n } else {\n let num_blocks = N / BLOCK_SIZE;\n\n // We store the intermediate hash states and message blocks in these two arrays which allows us to select the correct state\n // for the given message size with a lookup.\n //\n // These can be reasoned about as followed:\n // Consider a message with an unknown number of bytes, `msg_size. It can be seen that this will have `msg_size / BLOCK_SIZE` full blocks.\n // - `states[i]` should then be the state after processing the first `i` blocks.\n // - `blocks[i]` should then be the next message block after processing the first `i` blocks.\n // blocks[first_partially_filled_block_index] is the last block that is partially filled or all 0 if the message is a multiple of the block size.\n //\n // In other words:\n //\n // blocks = [block 1, block 2, ..., block N / BLOCK_SIZE, block N / BLOCK_SIZE + 1]\n // states = [INITIAL_STATE, state after block 1, state after block 2, ..., state after block N / BLOCK_SIZE]\n //\n // We place the initial state in `states[0]` as in the case where the `message_size < BLOCK_SIZE` then there are no full blocks to process and no compressions should occur.\n let mut blocks: [MSG_BLOCK; N / BLOCK_SIZE + 1] = std::mem::zeroed();\n let mut states: [STATE; N / BLOCK_SIZE + 1] = [initial_state; N / BLOCK_SIZE + 1];\n\n // Optimization for small messages. If the largest possible message is smaller than a block then we know that the first block is partially filled\n // no matter the value of `message_size`.\n //\n // Note that the condition `N >= BLOCK_SIZE` is known during monomorphization so this has no runtime cost.\n let first_partially_filled_block_index = if N >= BLOCK_SIZE {\n message_size / BLOCK_SIZE\n } else {\n 0\n };\n\n for i in 0..num_blocks {\n let msg_start = BLOCK_SIZE * i;\n let new_msg_block = build_msg_block(msg, message_size, msg_start);\n\n blocks[i] = new_msg_block;\n states[i + 1] = sha256_compression(new_msg_block, states[i]);\n }\n // If message_size/BLOCK_SIZE == N/BLOCK_SIZE, and there is a remainder, we need to process the last block.\n if N % BLOCK_SIZE != 0 {\n let new_msg_block = build_msg_block(msg, message_size, BLOCK_SIZE * num_blocks);\n\n blocks[num_blocks] = new_msg_block;\n }\n\n (states[first_partially_filled_block_index], blocks[first_partially_filled_block_index])\n }\n}\n\n// Take `BLOCK_SIZE` number of bytes from `msg` starting at `msg_start` and pack them into a `MSG_BLOCK`.\npub(crate) unconstrained fn build_msg_block_helper<let N: u32>(\n msg: [u8; N],\n message_size: u32,\n msg_start: u32,\n) -> MSG_BLOCK {\n let mut msg_block: MSG_BLOCK = [0; INT_BLOCK_SIZE];\n\n // We insert `BLOCK_SIZE` bytes (or up to the end of the message)\n let block_input = if message_size < msg_start {\n // This function is sometimes called with `msg_start` past the end of the message.\n // In this case we return an empty block and zero pointer to signal that the result should be ignored.\n 0\n } else if message_size < msg_start + BLOCK_SIZE {\n message_size - msg_start\n } else {\n BLOCK_SIZE\n };\n\n // Figure out the number of items in the int array that we have to pack.\n // e.g. if the input is [0,1,2,3,4,5] then we need to pack it as 2 items: [0123, 4500]\n let int_input = (block_input + INT_SIZE - 1) / INT_SIZE;\n\n for i in 0..int_input {\n let mut msg_item: u32 = 0;\n // Always construct the integer as 4 bytes, even if it means going beyond the input.\n for j in 0..INT_SIZE {\n let k = i * INT_SIZE + j;\n let msg_byte = if k < block_input {\n msg[msg_start + k]\n } else {\n 0\n };\n msg_item = (msg_item << 8) + msg_byte as u32;\n }\n msg_block[i] = msg_item;\n }\n\n // Returning the index as if it was a 64 byte array.\n // We have to project it down to 16 items and bit shifting to get a byte back if we need it.\n msg_block\n}\n\n// Build a message block from the input message starting at `msg_start`.\n//\n// If `message_size` is less than `msg_start` then this is called with the old non-empty block;\n// in that case we can skip verification, ie. no need to check that everything is zero.\nfn build_msg_block<let N: u32>(msg: [u8; N], message_size: u32, msg_start: u32) -> MSG_BLOCK {\n let msg_block =\n // Safety: We constrain the block below by reconstructing each `u32` word from the input bytes.\n unsafe { build_msg_block_helper(msg, message_size, msg_start) };\n\n if !is_unconstrained() {\n let mut msg_end = msg_start + BLOCK_SIZE;\n\n let max_read_index = std::cmp::min(message_size, msg_end);\n\n // Reconstructed packed item\n let mut msg_item: Field = 0;\n\n // Inclusive at the end so that we can compare the last item.\n for k in msg_start..=msg_end {\n if (k != msg_start) & (k % INT_SIZE == 0) {\n // If we consumed some input we can compare against the block.\n let msg_block_index = (k - msg_start) / INT_SIZE - 1;\n assert_eq(msg_block[msg_block_index] as Field, msg_item);\n\n msg_item = 0;\n }\n\n // If we have input to consume, add it at the rightmost position.\n let msg_byte = if k < max_read_index { msg[k] } else { 0 };\n msg_item = msg_item * (TWO_POW_8 as Field) + msg_byte as Field;\n }\n }\n msg_block\n}\n\n// Encode `8 * message_size` into two `u32` limbs.\nunconstrained fn encode_len(message_size: u32) -> (u32, u32) {\n let len = 8 * message_size as u64;\n let lo = len & 0xFFFFFFFF;\n let hi = (len >> 32) & 0xFFFFFFFF;\n (lo as u32, hi as u32)\n}\n\n// Write the length into the last 8 bytes of the block.\nfn attach_len_to_msg_block(mut msg_block: MSG_BLOCK, message_size: u32) -> MSG_BLOCK {\n // Safety: We assert the correctness of the decomposition below.\n // 2 `u32` limbs cannot overflow the field modulus so performing the check as `Field`s is safe.\n let (lo, hi) = unsafe { encode_len(message_size) };\n assert_eq(8 * (message_size as Field), lo as Field + hi as Field * TWO_POW_32);\n\n msg_block[INT_SIZE_PTR] = hi;\n msg_block[INT_SIZE_PTR + 1] = lo;\n msg_block\n}\n\n// Perform the final compression, then transform the `STATE` into `HASH`.\nfn hash_final_block(msg_block: MSG_BLOCK, mut state: STATE) -> HASH {\n // Hash final padded block\n state = sha256_compression(msg_block, state);\n\n // Return final hash as byte array\n let mut out_h: HASH = [0; 32]; // Digest as sequence of bytes\n for j in 0..8 {\n let h_bytes: [u8; 4] = (state[j] as Field).to_be_bytes();\n for k in 0..4 {\n out_h[4 * j + k] = h_bytes[k];\n }\n }\n\n out_h\n}\n\n/// Lookup table for the position of the padding bit within one of the `u32` words in the final message block.\nglobal PADDING_BIT_TABLE: [u32; 4] =\n [(1 << 7) * TWO_POW_24, (1 << 7) * TWO_POW_16, (1 << 7) * TWO_POW_8, (1 << 7)];\n\n/// Add 1 bit padding to end of message and compress the block if there's not enough room for the 8-byte length.\n/// Returns the updated hash state and message block that will be used to write the message size.\n///\n/// # Assumptions:\n///\n/// - `msg_block[i] == 0` for all `i > msg_byte_ptr / INT_SIZE`\n/// - `msg_block[msg_byte_ptr / INT_SIZE] & ((1 << 7) * (msg_byte_ptr % INT_SIZE)) == 0`\nfn add_padding_byte_and_compress_if_needed(\n mut msg_block: MSG_BLOCK,\n msg_byte_ptr: BLOCK_BYTE_PTR,\n h: STATE,\n) -> (STATE, MSG_BLOCK) {\n // Pad the rest such that we have a [u32; 2] block at the end representing the length\n // of the message, and a block of 1 0 ... 0 following the message (i.e. [1 << 7, 0, ..., 0]).\n // Here we rely on the fact that everything beyond the available input is set to 0.\n let index = msg_byte_ptr / INT_SIZE;\n\n // Lookup the position of the padding bit and insert it into the message block.\n msg_block[index] += PADDING_BIT_TABLE[msg_byte_ptr % INT_SIZE];\n\n // If we don't have room to write the size, compress the block and reset it.\n if msg_byte_ptr >= MSG_SIZE_PTR {\n let h = sha256_compression(msg_block, h);\n\n // In this case, the final block consists of all zeros with the last 8 bytes containing the length.\n // We set msg_block to all zeros and attach_len_to_msg_block will add the length to the last 8 bytes.\n let msg_block = [0; INT_BLOCK_SIZE];\n (h, msg_block)\n } else {\n (h, msg_block)\n }\n}\n\npub(crate) fn finalize_sha256_blocks(\n message_size: u32,\n mut h: STATE,\n mut msg_block: MSG_BLOCK,\n) -> HASH {\n let msg_byte_ptr = message_size % BLOCK_SIZE;\n\n let (h, mut msg_block) = add_padding_byte_and_compress_if_needed(msg_block, msg_byte_ptr, h);\n\n msg_block = attach_len_to_msg_block(msg_block, message_size);\n\n hash_final_block(msg_block, h)\n}\n\n/**\n * Given some state of a partially computed sha256 hash and part of the preimage, continue hashing\n * @notice used for complex/ recursive offloading of post-partial hashing\n *\n * @param N - the maximum length of the message to hash\n * @param h - the intermediate hash state\n * @param msg - the preimage to hash\n * @param message_size - the actual length of the preimage to hash\n * @return the intermediate hash state after compressing in msg to h\n */\npub fn partial_sha256_var_interstitial<let N: u32>(\n mut h: [u32; 8],\n msg: [u8; N],\n message_size: u32,\n) -> [u32; 8] {\n assert(message_size % BLOCK_SIZE == 0, \"Message size must be a multiple of the block size\");\n if std::runtime::is_unconstrained() {\n // Safety: running as an unconstrained function\n unsafe {\n __sha_partial_var_interstitial(h, msg, message_size)\n }\n } else {\n let (h, _) = process_full_blocks(msg, message_size, h);\n\n h\n }\n}\n\n/**\n * Given some state of a partially computed sha256 hash and remaining preimage, complete the hash\n * @notice used for traditional partial hashing\n *\n * @param N - the maximum length of the message to hash\n * @param h - the intermediate hash state\n * @param msg - the remaining preimage to hash\n * @param message_size - the size of the current chunk\n * @param real_message_size - the total size of the original preimage\n * @return finalized sha256 hash\n */\npub fn partial_sha256_var_end<let N: u32>(\n mut h: [u32; 8],\n msg: [u8; N],\n message_size: u32,\n real_message_size: u32,\n) -> [u8; 32] {\n assert(message_size % BLOCK_SIZE == 0, \"Message size must be a multiple of the block size\");\n if std::runtime::is_unconstrained() {\n // Safety: running as an unconstrained function\n unsafe {\n h = __sha_partial_var_interstitial(h, msg, message_size);\n\n // Handle setup of the final msg block.\n // This case is only hit if the msg is less than the block size,\n // or our message cannot be evenly split into blocks.\n\n finalize_last_sha256_block(h, real_message_size, msg)\n }\n } else {\n let (h, msg_block) = process_full_blocks(msg, message_size, h);\n finalize_sha256_blocks(real_message_size, h, msg_block)\n }\n}\n\nunconstrained fn __sha_partial_var_interstitial<let N: u32>(\n mut h: [u32; 8],\n msg: [u8; N],\n message_size: u32,\n) -> [u32; 8] {\n let num_full_blocks = message_size / BLOCK_SIZE;\n // Intermediate hash, starting with the canonical initial value\n // Pointer into msg_block on a 64 byte scale\n for i in 0..num_full_blocks {\n let msg_block = build_msg_block(msg, message_size, BLOCK_SIZE * i);\n h = sha256_compression(msg_block, h);\n }\n h\n}\n\n// Helper function to finalize the message block with padding and length\nunconstrained fn finalize_last_sha256_block<let N: u32>(\n mut h: STATE,\n message_size: u32,\n msg: [u8; N],\n) -> HASH {\n let msg_byte_ptr = message_size % BLOCK_SIZE;\n\n // We now build the final un-filled block.\n let msg_block: MSG_BLOCK = if msg_byte_ptr != 0 {\n let num_full_blocks = message_size / BLOCK_SIZE;\n let msg_start = BLOCK_SIZE * num_full_blocks;\n build_msg_block(msg, message_size, msg_start)\n } else {\n // If the message size is a multiple of the block size (i.e. `msg_byte_ptr == 0`) then this block will be empty,\n // so we short-circuit in this case.\n [0; 16]\n };\n\n // Once built, we need to add the necessary padding bytes and encoded length\n let (h, mut msg_block) = add_padding_byte_and_compress_if_needed(msg_block, msg_byte_ptr, h);\n msg_block = attach_len_to_msg_block(msg_block, message_size);\n\n hash_final_block(msg_block, h)\n}\n\nmod test_process_full_blocks {\n\n /// Wrapper to force an unconstrained runtime on process_full_blocks.\n unconstrained fn unconstrained_process_full_blocks<let N: u32>(\n msg: [u8; N],\n message_size: u32,\n h: super::STATE,\n ) -> (super::STATE, super::MSG_BLOCK) {\n super::process_full_blocks(msg, message_size, h)\n }\n\n #[test]\n fn test_implementations_agree(msg: [u8; 100], message_size: u32) {\n let message_size = message_size % 100;\n // Safety: test function\n let unconstrained_state =\n unsafe { unconstrained_process_full_blocks(msg, message_size, super::INITIAL_STATE) };\n let state = super::process_full_blocks(msg, message_size, super::INITIAL_STATE);\n assert_eq(state, unconstrained_state);\n }\n}\n\nmod test_sha256_var {\n\n /// Wrapper to force an unconstrained runtime on sha256.\n unconstrained fn unconstrained_sha256<let N: u32>(\n msg: [u8; N],\n message_size: u32,\n ) -> super::HASH {\n super::sha256_var(msg, message_size)\n }\n\n #[test]\n fn test_implementations_agree(msg: [u8; 100], message_size: u32) {\n let message_size = message_size % 100;\n // Safety: test function\n let unconstrained_sha = unsafe { unconstrained_sha256(msg, message_size) };\n let sha = super::sha256_var(msg, message_size);\n assert_eq(sha, unconstrained_sha);\n }\n\n}\n"
1280
1392
  },
1281
- "37": {
1393
+ "39": {
1282
1394
  "function_locations": [
1283
1395
  {
1284
1396
  "name": "<impl Add for Field>::add",
@@ -1711,12 +1823,48 @@
1711
1823
  {
1712
1824
  "name": "tests::split_functions::test_split_functions",
1713
1825
  "start": 21622
1826
+ },
1827
+ {
1828
+ "name": "tests::traits::add",
1829
+ "start": 22960
1830
+ },
1831
+ {
1832
+ "name": "tests::traits::sub",
1833
+ "start": 23407
1834
+ },
1835
+ {
1836
+ "name": "tests::traits::mul",
1837
+ "start": 23854
1838
+ },
1839
+ {
1840
+ "name": "tests::traits::div",
1841
+ "start": 24301
1842
+ },
1843
+ {
1844
+ "name": "tests::traits::rem",
1845
+ "start": 24748
1846
+ },
1847
+ {
1848
+ "name": "tests::traits::neg",
1849
+ "start": 25153
1850
+ },
1851
+ {
1852
+ "name": "tests::traits::wrapping_add",
1853
+ "start": 25367
1854
+ },
1855
+ {
1856
+ "name": "tests::traits::wrapping_sub",
1857
+ "start": 26055
1858
+ },
1859
+ {
1860
+ "name": "tests::traits::wrapping_mul",
1861
+ "start": 26751
1714
1862
  }
1715
1863
  ],
1716
1864
  "path": "std/ops/arith.nr",
1717
- "source": "use crate::convert::AsPrimitive;\n\n// docs:start:add-trait\npub trait Add {\n fn add(self, other: Self) -> Self;\n}\n// docs:end:add-trait\n\nimpl Add for Field {\n fn add(self, other: Field) -> Field {\n self + other\n }\n}\n\nimpl Add for u128 {\n fn add(self, other: u128) -> u128 {\n self + other\n }\n}\nimpl Add for u64 {\n fn add(self, other: u64) -> u64 {\n self + other\n }\n}\nimpl Add for u32 {\n fn add(self, other: u32) -> u32 {\n self + other\n }\n}\nimpl Add for u16 {\n fn add(self, other: u16) -> u16 {\n self + other\n }\n}\nimpl Add for u8 {\n fn add(self, other: u8) -> u8 {\n self + other\n }\n}\nimpl Add for i8 {\n fn add(self, other: i8) -> i8 {\n self + other\n }\n}\nimpl Add for i16 {\n fn add(self, other: i16) -> i16 {\n self + other\n }\n}\nimpl Add for i32 {\n fn add(self, other: i32) -> i32 {\n self + other\n }\n}\nimpl Add for i64 {\n fn add(self, other: i64) -> i64 {\n self + other\n }\n}\n\n// docs:start:sub-trait\npub trait Sub {\n fn sub(self, other: Self) -> Self;\n}\n// docs:end:sub-trait\n\nimpl Sub for Field {\n fn sub(self, other: Field) -> Field {\n self - other\n }\n}\n\nimpl Sub for u128 {\n fn sub(self, other: u128) -> u128 {\n self - other\n }\n}\nimpl Sub for u64 {\n fn sub(self, other: u64) -> u64 {\n self - other\n }\n}\nimpl Sub for u32 {\n fn sub(self, other: u32) -> u32 {\n self - other\n }\n}\nimpl Sub for u16 {\n fn sub(self, other: u16) -> u16 {\n self - other\n }\n}\nimpl Sub for u8 {\n fn sub(self, other: u8) -> u8 {\n self - other\n }\n}\nimpl Sub for i8 {\n fn sub(self, other: i8) -> i8 {\n self - other\n }\n}\nimpl Sub for i16 {\n fn sub(self, other: i16) -> i16 {\n self - other\n }\n}\nimpl Sub for i32 {\n fn sub(self, other: i32) -> i32 {\n self - other\n }\n}\nimpl Sub for i64 {\n fn sub(self, other: i64) -> i64 {\n self - other\n }\n}\n\n// docs:start:mul-trait\npub trait Mul {\n fn mul(self, other: Self) -> Self;\n}\n// docs:end:mul-trait\n\nimpl Mul for Field {\n fn mul(self, other: Field) -> Field {\n self * other\n }\n}\n\nimpl Mul for u128 {\n fn mul(self, other: u128) -> u128 {\n self * other\n }\n}\nimpl Mul for u64 {\n fn mul(self, other: u64) -> u64 {\n self * other\n }\n}\nimpl Mul for u32 {\n fn mul(self, other: u32) -> u32 {\n self * other\n }\n}\nimpl Mul for u16 {\n fn mul(self, other: u16) -> u16 {\n self * other\n }\n}\nimpl Mul for u8 {\n fn mul(self, other: u8) -> u8 {\n self * other\n }\n}\nimpl Mul for i8 {\n fn mul(self, other: i8) -> i8 {\n self * other\n }\n}\nimpl Mul for i16 {\n fn mul(self, other: i16) -> i16 {\n self * other\n }\n}\nimpl Mul for i32 {\n fn mul(self, other: i32) -> i32 {\n self * other\n }\n}\nimpl Mul for i64 {\n fn mul(self, other: i64) -> i64 {\n self * other\n }\n}\n\n// docs:start:div-trait\npub trait Div {\n fn div(self, other: Self) -> Self;\n}\n// docs:end:div-trait\n\nimpl Div for Field {\n fn div(self, other: Field) -> Field {\n self / other\n }\n}\n\nimpl Div for u128 {\n fn div(self, other: u128) -> u128 {\n self / other\n }\n}\nimpl Div for u64 {\n fn div(self, other: u64) -> u64 {\n self / other\n }\n}\nimpl Div for u32 {\n fn div(self, other: u32) -> u32 {\n self / other\n }\n}\nimpl Div for u16 {\n fn div(self, other: u16) -> u16 {\n self / other\n }\n}\nimpl Div for u8 {\n fn div(self, other: u8) -> u8 {\n self / other\n }\n}\nimpl Div for i8 {\n fn div(self, other: i8) -> i8 {\n self / other\n }\n}\nimpl Div for i16 {\n fn div(self, other: i16) -> i16 {\n self / other\n }\n}\nimpl Div for i32 {\n fn div(self, other: i32) -> i32 {\n self / other\n }\n}\nimpl Div for i64 {\n fn div(self, other: i64) -> i64 {\n self / other\n }\n}\n\n// docs:start:rem-trait\npub trait Rem {\n fn rem(self, other: Self) -> Self;\n}\n// docs:end:rem-trait\n\nimpl Rem for u128 {\n fn rem(self, other: u128) -> u128 {\n self % other\n }\n}\nimpl Rem for u64 {\n fn rem(self, other: u64) -> u64 {\n self % other\n }\n}\nimpl Rem for u32 {\n fn rem(self, other: u32) -> u32 {\n self % other\n }\n}\nimpl Rem for u16 {\n fn rem(self, other: u16) -> u16 {\n self % other\n }\n}\nimpl Rem for u8 {\n fn rem(self, other: u8) -> u8 {\n self % other\n }\n}\nimpl Rem for i8 {\n fn rem(self, other: i8) -> i8 {\n self % other\n }\n}\nimpl Rem for i16 {\n fn rem(self, other: i16) -> i16 {\n self % other\n }\n}\nimpl Rem for i32 {\n fn rem(self, other: i32) -> i32 {\n self % other\n }\n}\nimpl Rem for i64 {\n fn rem(self, other: i64) -> i64 {\n self % other\n }\n}\n\n// docs:start:neg-trait\npub trait Neg {\n fn neg(self) -> Self;\n}\n// docs:end:neg-trait\n\n// docs:start:neg-trait-impls\nimpl Neg for Field {\n fn neg(self) -> Field {\n -self\n }\n}\n\nimpl Neg for i8 {\n fn neg(self) -> i8 {\n -self\n }\n}\nimpl Neg for i16 {\n fn neg(self) -> i16 {\n -self\n }\n}\nimpl Neg for i32 {\n fn neg(self) -> i32 {\n -self\n }\n}\nimpl Neg for i64 {\n fn neg(self) -> i64 {\n -self\n }\n}\n// docs:end:neg-trait-impls\n\n// docs:start:wrapping-add-trait\npub trait WrappingAdd {\n fn wrapping_add(self, y: Self) -> Self;\n}\n// docs:end:wrapping-add-trait\n\nimpl WrappingAdd for u8 {\n fn wrapping_add(self: u8, y: u8) -> u8 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u16 {\n fn wrapping_add(self: u16, y: u16) -> u16 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u32 {\n fn wrapping_add(self: u32, y: u32) -> u32 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u64 {\n fn wrapping_add(self: u64, y: u64) -> u64 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u128 {\n fn wrapping_add(self: u128, y: u128) -> u128 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for i8 {\n fn wrapping_add(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_add(y as u8) as i8\n }\n}\n\nimpl WrappingAdd for i16 {\n fn wrapping_add(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_add(y as u16) as i16\n }\n}\n\nimpl WrappingAdd for i32 {\n fn wrapping_add(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_add(y as u32) as i32\n }\n}\n\nimpl WrappingAdd for i64 {\n fn wrapping_add(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_add(y as u64) as i64\n }\n}\nimpl WrappingAdd for Field {\n fn wrapping_add(self: Field, y: Field) -> Field {\n self + y\n }\n}\n\n// docs:start:wrapping-sub-trait\npub trait WrappingSub {\n fn wrapping_sub(self, y: Self) -> Self;\n}\n// docs:start:wrapping-sub-trait\n\nimpl WrappingSub for u8 {\n fn wrapping_sub(self: u8, y: u8) -> u8 {\n wrapping_sub_hlp(self, y) as u8\n }\n}\n\nimpl WrappingSub for u16 {\n fn wrapping_sub(self: u16, y: u16) -> u16 {\n wrapping_sub_hlp(self, y) as u16\n }\n}\n\nimpl WrappingSub for u32 {\n fn wrapping_sub(self: u32, y: u32) -> u32 {\n wrapping_sub_hlp(self, y) as u32\n }\n}\nimpl WrappingSub for u64 {\n fn wrapping_sub(self: u64, y: u64) -> u64 {\n wrapping_sub_hlp(self, y) as u64\n }\n}\nimpl WrappingSub for u128 {\n fn wrapping_sub(self: u128, y: u128) -> u128 {\n wrapping_sub_hlp(self, y) as u128\n }\n}\n\nimpl WrappingSub for i8 {\n fn wrapping_sub(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_sub(y as u8) as i8\n }\n}\n\nimpl WrappingSub for i16 {\n fn wrapping_sub(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_sub(y as u16) as i16\n }\n}\n\nimpl WrappingSub for i32 {\n fn wrapping_sub(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_sub(y as u32) as i32\n }\n}\nimpl WrappingSub for i64 {\n fn wrapping_sub(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_sub(y as u64) as i64\n }\n}\nimpl WrappingSub for Field {\n fn wrapping_sub(self: Field, y: Field) -> Field {\n self - y\n }\n}\n\n// docs:start:wrapping-mul-trait\npub trait WrappingMul {\n fn wrapping_mul(self, y: Self) -> Self;\n}\n// docs:start:wrapping-mul-trait\n\nimpl WrappingMul for u8 {\n fn wrapping_mul(self: u8, y: u8) -> u8 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u16 {\n fn wrapping_mul(self: u16, y: u16) -> u16 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u32 {\n fn wrapping_mul(self: u32, y: u32) -> u32 {\n wrapping_mul_hlp(self, y)\n }\n}\nimpl WrappingMul for u64 {\n fn wrapping_mul(self: u64, y: u64) -> u64 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for i8 {\n fn wrapping_mul(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_mul(y as u8) as i8\n }\n}\n\nimpl WrappingMul for i16 {\n fn wrapping_mul(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_mul(y as u16) as i16\n }\n}\n\nimpl WrappingMul for i32 {\n fn wrapping_mul(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_mul(y as u32) as i32\n }\n}\n\nimpl WrappingMul for i64 {\n fn wrapping_mul(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_mul(y as u64) as i64\n }\n}\n\nimpl WrappingMul for u128 {\n fn wrapping_mul(self: u128, y: u128) -> u128 {\n wrapping_mul128_hlp(self, y)\n }\n}\nimpl WrappingMul for Field {\n fn wrapping_mul(self: Field, y: Field) -> Field {\n self * y\n }\n}\n\nfn wrapping_add_hlp<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() + y.as_())\n}\n\nfn wrapping_sub_hlp<T>(x: T, y: T) -> Field\nwhere\n T: AsPrimitive<Field>,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n x.as_() + 340282366920938463463374607431768211456 - y.as_()\n}\n\nfn wrapping_mul_hlp<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() * y.as_())\n}\n\nglobal two_pow_64: u128 = 0x10000000000000000;\n/// Splits a 128 bits number into two 64 bits limbs\nunconstrained fn split64(x: u128) -> (u64, u64) {\n let lo = x as u64;\n let hi = (x / two_pow_64) as u64;\n (lo, hi)\n}\n\n/// Split a 128 bits number into two 64 bits limbs\n/// It will fail if the number is more than 128 bits\nfn split_into_64_bit_limbs(x: u128) -> (u64, u64) {\n // Safety: the limbs are constrained below\n let (x_lo, x_hi) = unsafe { split64(x) };\n assert(x as Field == x_lo as Field + x_hi as Field * two_pow_64 as Field);\n (x_lo, x_hi)\n}\n\n#[field(bn254)]\nfn wrapping_mul128_hlp(x: u128, y: u128) -> u128 {\n let (x_lo, x_hi) = split_into_64_bit_limbs(x);\n let (y_lo, y_hi) = split_into_64_bit_limbs(y);\n // Multiplication using the limbs:(x_lo + 2**64*x_hi)*(y_lo + 2**64*y_hi)=x_lo*y_lo+...\n // and skipping the terms over 2**128\n // Working with u64 limbs ensures that we cannot overflow the field modulus.\n let low = x_lo as Field * y_lo as Field;\n let lo = low as u64 as Field;\n let carry = (low - lo) / two_pow_64 as Field;\n let high = x_lo as Field * y_hi as Field + x_hi as Field * y_lo as Field + carry;\n let hi = high as u64 as Field;\n (lo + two_pow_64 as Field * hi) as u128\n}\n\nmod tests {\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n crate::static_assert(1 == 2, \"custom message\");\n }\n\n mod arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Rem, Sub};\n #[test]\n fn test_basic_arithmetic_traits() {\n // add\n assert_eq(5.add(3), 8);\n assert_eq(0u8.add(255u8), 255u8);\n assert_eq(42.add(58), 100);\n\n // sub\n assert_eq(10.sub(3), 7);\n assert_eq(100.sub(42), 58);\n\n // mul\n assert_eq(6.mul(7), 42);\n\n // div\n assert_eq(15.div(3), 5);\n assert_eq(10u8.div(3u8), 3u8);\n assert_eq(15.div(3), 5);\n\n // rem (Field doesn't implement Rem)\n assert_eq(17u64.rem(5u64), 2u64);\n assert_eq(10u8.rem(3u8), 1u8);\n\n // neg\n assert_eq(42.neg(), -42);\n assert_eq((-10).neg(), 10);\n assert_eq(42.neg(), -42);\n }\n\n #[test]\n fn test_division() {\n // test division by one\n assert_eq(42.div(1), 42);\n assert_eq(0.div(1), 0);\n assert_eq(255u8.div(1u8), 255u8);\n\n // test division by self\n assert_eq(42.div(42), 1);\n assert_eq(1.div(1), 1);\n\n // test remainder (Field doesn't implement Rem)\n assert_eq(42u32.rem(42u32), 0u32);\n assert_eq(0u16.rem(42u16), 0u16);\n assert_eq(1u64.rem(42u64), 1u64);\n }\n\n #[test(should_fail)]\n fn test_u8_sub_overflow_failure() {\n let _ = 0u8.sub(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_add_overflow_failure() {\n let _ = 255u8.add(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_mul_overflow_failure() {\n let _ = 255u8.mul(2u8);\n }\n\n #[test(should_fail)]\n fn test_u16_sub_overflow_failure() {\n let _ = 0u16.sub(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_add_overflow_failure() {\n let _ = 65535u16.add(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_mul_overflow_failure() {\n let _ = 65535u16.mul(2u16);\n }\n\n #[test(should_fail)]\n fn test_signed_sub_overflow_failure() {\n let val: i8 = -128;\n let _ = val.sub(1i8);\n }\n\n #[test(should_fail)]\n fn test_signed_overflow_failure() {\n let _ = 127i8.add(1i8);\n }\n\n #[test]\n fn test_field() {\n let zero: Field = 0;\n let one: Field = 1;\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod wrapping_arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Sub, WrappingAdd, WrappingMul, WrappingSub};\n #[test]\n fn test_wrapping_add() {\n assert_eq(255u8.wrapping_add(1u8), 0u8);\n assert_eq(255u8.wrapping_add(255u8), 254u8);\n assert_eq(0u8.wrapping_add(0u8), 0u8);\n assert_eq(128u8.wrapping_add(128u8), 0u8);\n\n // test u16 wrapping add\n assert_eq(65535u16.wrapping_add(1u16), 0u16);\n assert_eq(65535u16.wrapping_add(65535u16), 65534u16);\n\n // test u32 wrapping add\n assert_eq(0xffffffffu32.wrapping_add(1u32), 0u32);\n assert_eq(0xffffffffu32.wrapping_add(0xffffffffu32), 0xfffffffeu32);\n\n // test u64 wrapping add\n assert_eq(0xffffffffffffffffu64.wrapping_add(1u64), 0u64);\n assert_eq(\n 0xffffffffffffffffu64.wrapping_add(0xffffffffffffffffu64),\n 0xfffffffffffffffeu64,\n );\n\n // test u128 wrapping add\n assert_eq(0xffffffffffffffffffffffffffffffffu128.wrapping_add(1u128), 0u128);\n\n // test signed types\n assert_eq(127i8.wrapping_add(1i8), -128i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_add(-1i8), 127i8);\n\n // test Field wrapping add\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let hundred: Field = 100;\n let neg_two: Field = -2;\n let two: Field = 2;\n let zero: Field = 0;\n let neg_two_hundred: Field = -200;\n let neg_one_ninety_eight: Field = -198;\n assert_eq(forty_two.wrapping_add(fifty_eight), hundred);\n assert_eq(neg_two.wrapping_add(two), zero);\n assert_eq(neg_two_hundred.wrapping_add(two), neg_one_ninety_eight);\n }\n\n #[test]\n fn test_wrapping_sub() {\n assert_eq(0u8.wrapping_sub(1u8), 255u8);\n assert_eq(255u8.wrapping_sub(255u8), 0u8);\n assert_eq(0u8.wrapping_sub(0u8), 0u8);\n assert_eq(1u8.wrapping_sub(2u8), 255u8);\n\n // test u16 wrapping sub\n assert_eq(0u16.wrapping_sub(1u16), 65535u16);\n assert_eq(65535u16.wrapping_sub(65535u16), 0u16);\n\n // test u32 wrapping sub\n assert_eq(0u32.wrapping_sub(1u32), 0xffffffffu32);\n assert_eq(0xffffffffu32.wrapping_sub(0xffffffffu32), 0u32);\n\n // test u64 wrapping sub\n assert_eq(0u64.wrapping_sub(1u64), 0xffffffffffffffffu64);\n assert_eq(0xffffffffffffffffu64.wrapping_sub(0xffffffffffffffffu64), 0u64);\n\n // test u128 wrapping sub\n assert_eq(0u128.wrapping_sub(1u128), 0xffffffffffffffffffffffffffffffffu128);\n\n // test signed types\n let val: i8 = -128;\n assert_eq(val.wrapping_sub(1i8), 127i8);\n assert_eq(127i8.wrapping_sub(-1i8), -128i8);\n\n // test Field wrapping sub\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let neg_sixteen: Field = -16;\n assert_eq(forty_two.wrapping_sub(fifty_eight), neg_sixteen);\n }\n\n #[test]\n fn test_wrapping_mul() {\n let zero: u128 = 0;\n let one: u128 = 1;\n let two_pow_64: u128 = 0x10000000000000000;\n let u128_max: u128 = 0xffffffffffffffffffffffffffffffff;\n\n assert_eq(zero, zero.wrapping_mul(one));\n assert_eq(zero, one.wrapping_mul(zero));\n assert_eq(one, one.wrapping_mul(one));\n assert_eq(zero, zero.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(zero));\n assert_eq(two_pow_64, two_pow_64.wrapping_mul(one));\n assert_eq(two_pow_64, one.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(two_pow_64));\n assert_eq(one, u128_max.wrapping_mul(u128_max));\n\n // test u8 wrapping mul\n assert_eq(255u8.wrapping_mul(2u8), 254u8);\n assert_eq(255u8.wrapping_mul(255u8), 1u8);\n assert_eq(128u8.wrapping_mul(2u8), 0u8);\n\n // test u16 wrapping mul\n assert_eq(65535u16.wrapping_mul(2u16), 65534u16);\n assert_eq(65535u16.wrapping_mul(65535u16), 1u16);\n\n // test u32 wrapping mul\n assert_eq(0xffffffffu32.wrapping_mul(2u32), 0xfffffffeu32);\n assert_eq(0xffffffffu32.wrapping_mul(0xffffffffu32), 1u32);\n\n // test u64 wrapping mul\n // 0xffffffffffffffffu64 is 2^64 - 1\n assert_eq(0xffffffffffffffffu64.wrapping_mul(2u64), 0xfffffffffffffffeu64);\n assert_eq(0xffffffffffffffffu64.wrapping_mul(0xffffffffffffffffu64), 1u64);\n\n // test signed types\n assert_eq(127i8.wrapping_mul(2i8), -2i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_mul(-1i8), -128i8);\n\n // test Field wrapping mul\n let six: Field = 6;\n let seven: Field = 7;\n let forty_two: Field = 42;\n let neg_two: Field = -2;\n let two: Field = 2;\n let neg_four: Field = -4;\n assert_eq(six.wrapping_mul(seven), forty_two);\n assert_eq(neg_two.wrapping_mul(two), neg_four);\n }\n\n // test wrapping operations is the same as the regular operations\n #[test]\n fn test_wrapping_vs_regular() {\n let u64_large = 0x123456789abcdef0u64;\n let u128_large = 0x123456789abcdef0123456789abcdef0u128;\n\n assert_eq(u64_large.wrapping_add(1u64), u64_large + 1u64);\n assert_eq(u64_large.wrapping_sub(1u64), u64_large - 1u64);\n assert_eq(u64_large.wrapping_mul(2u64), u64_large * 2u64);\n\n assert_eq(u128_large.wrapping_add(1u128), u128_large + 1u128);\n assert_eq(u128_large.wrapping_sub(1u128), u128_large - 1u128);\n assert_eq(u128_large.wrapping_mul(2u128), u128_large * 2u128);\n }\n\n #[test]\n fn test_field_wrapping_operations() {\n let zero: Field = 0;\n let one: Field = 1;\n let large_val = 0xffffffffffffffff;\n\n // test Field wrapping operations\n assert_eq(zero.wrapping_add(one), one);\n assert_eq(one.wrapping_add(large_val), one + large_val);\n assert_eq(zero.wrapping_sub(one), -one);\n assert_eq(one.wrapping_sub(large_val), one - large_val);\n assert_eq(zero.wrapping_mul(one), zero);\n assert_eq(one.wrapping_mul(large_val), large_val);\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod split_functions {\n\n use crate::ops::arith::{split64, split_into_64_bit_limbs};\n\n // test split64 and split_into_64_bit_limbs functions\n #[test]\n fn test_split_functions() {\n let small_val = 0x123456789abcdefu128;\n let large_val = 0x123456789abcdef0123456789abcdef0u128;\n let max_val = 0xffffffffffffffffffffffffffffffffu128;\n\n // test split64 (unconstrained)\n // Safety: testing\n unsafe {\n let (lo, hi) = split64(small_val);\n assert_eq(lo, 0x123456789abcdefu64);\n assert_eq(hi, 0u64);\n\n let (lo2, hi2) = split64(large_val);\n assert_eq(lo2, 0x123456789abcdef0u64);\n assert_eq(hi2, 0x123456789abcdef0u64);\n }\n\n // test split_into_64_bit_limbs (constrained)\n let (lo3, hi3) = split_into_64_bit_limbs(small_val);\n assert_eq(lo3, 0x123456789abcdefu64);\n assert_eq(hi3, 0u64);\n\n let (lo4, hi4) = split_into_64_bit_limbs(large_val);\n assert_eq(lo4, 0x123456789abcdef0u64);\n assert_eq(hi4, 0x123456789abcdef0u64);\n\n let (lo5, hi5) = split_into_64_bit_limbs(max_val);\n assert_eq(lo5, 0xffffffffffffffffu64);\n assert_eq(hi5, 0xffffffffffffffffu64);\n }\n }\n}\n"
1865
+ "source": "use crate::convert::AsPrimitive;\n\n// docs:start:add-trait\npub trait Add {\n fn add(self, other: Self) -> Self;\n}\n// docs:end:add-trait\n\nimpl Add for Field {\n fn add(self, other: Field) -> Field {\n self + other\n }\n}\n\nimpl Add for u128 {\n fn add(self, other: u128) -> u128 {\n self + other\n }\n}\nimpl Add for u64 {\n fn add(self, other: u64) -> u64 {\n self + other\n }\n}\nimpl Add for u32 {\n fn add(self, other: u32) -> u32 {\n self + other\n }\n}\nimpl Add for u16 {\n fn add(self, other: u16) -> u16 {\n self + other\n }\n}\nimpl Add for u8 {\n fn add(self, other: u8) -> u8 {\n self + other\n }\n}\nimpl Add for i8 {\n fn add(self, other: i8) -> i8 {\n self + other\n }\n}\nimpl Add for i16 {\n fn add(self, other: i16) -> i16 {\n self + other\n }\n}\nimpl Add for i32 {\n fn add(self, other: i32) -> i32 {\n self + other\n }\n}\nimpl Add for i64 {\n fn add(self, other: i64) -> i64 {\n self + other\n }\n}\n\n// docs:start:sub-trait\npub trait Sub {\n fn sub(self, other: Self) -> Self;\n}\n// docs:end:sub-trait\n\nimpl Sub for Field {\n fn sub(self, other: Field) -> Field {\n self - other\n }\n}\n\nimpl Sub for u128 {\n fn sub(self, other: u128) -> u128 {\n self - other\n }\n}\nimpl Sub for u64 {\n fn sub(self, other: u64) -> u64 {\n self - other\n }\n}\nimpl Sub for u32 {\n fn sub(self, other: u32) -> u32 {\n self - other\n }\n}\nimpl Sub for u16 {\n fn sub(self, other: u16) -> u16 {\n self - other\n }\n}\nimpl Sub for u8 {\n fn sub(self, other: u8) -> u8 {\n self - other\n }\n}\nimpl Sub for i8 {\n fn sub(self, other: i8) -> i8 {\n self - other\n }\n}\nimpl Sub for i16 {\n fn sub(self, other: i16) -> i16 {\n self - other\n }\n}\nimpl Sub for i32 {\n fn sub(self, other: i32) -> i32 {\n self - other\n }\n}\nimpl Sub for i64 {\n fn sub(self, other: i64) -> i64 {\n self - other\n }\n}\n\n// docs:start:mul-trait\npub trait Mul {\n fn mul(self, other: Self) -> Self;\n}\n// docs:end:mul-trait\n\nimpl Mul for Field {\n fn mul(self, other: Field) -> Field {\n self * other\n }\n}\n\nimpl Mul for u128 {\n fn mul(self, other: u128) -> u128 {\n self * other\n }\n}\nimpl Mul for u64 {\n fn mul(self, other: u64) -> u64 {\n self * other\n }\n}\nimpl Mul for u32 {\n fn mul(self, other: u32) -> u32 {\n self * other\n }\n}\nimpl Mul for u16 {\n fn mul(self, other: u16) -> u16 {\n self * other\n }\n}\nimpl Mul for u8 {\n fn mul(self, other: u8) -> u8 {\n self * other\n }\n}\nimpl Mul for i8 {\n fn mul(self, other: i8) -> i8 {\n self * other\n }\n}\nimpl Mul for i16 {\n fn mul(self, other: i16) -> i16 {\n self * other\n }\n}\nimpl Mul for i32 {\n fn mul(self, other: i32) -> i32 {\n self * other\n }\n}\nimpl Mul for i64 {\n fn mul(self, other: i64) -> i64 {\n self * other\n }\n}\n\n// docs:start:div-trait\npub trait Div {\n fn div(self, other: Self) -> Self;\n}\n// docs:end:div-trait\n\nimpl Div for Field {\n fn div(self, other: Field) -> Field {\n self / other\n }\n}\n\nimpl Div for u128 {\n fn div(self, other: u128) -> u128 {\n self / other\n }\n}\nimpl Div for u64 {\n fn div(self, other: u64) -> u64 {\n self / other\n }\n}\nimpl Div for u32 {\n fn div(self, other: u32) -> u32 {\n self / other\n }\n}\nimpl Div for u16 {\n fn div(self, other: u16) -> u16 {\n self / other\n }\n}\nimpl Div for u8 {\n fn div(self, other: u8) -> u8 {\n self / other\n }\n}\nimpl Div for i8 {\n fn div(self, other: i8) -> i8 {\n self / other\n }\n}\nimpl Div for i16 {\n fn div(self, other: i16) -> i16 {\n self / other\n }\n}\nimpl Div for i32 {\n fn div(self, other: i32) -> i32 {\n self / other\n }\n}\nimpl Div for i64 {\n fn div(self, other: i64) -> i64 {\n self / other\n }\n}\n\n// docs:start:rem-trait\npub trait Rem {\n fn rem(self, other: Self) -> Self;\n}\n// docs:end:rem-trait\n\nimpl Rem for u128 {\n fn rem(self, other: u128) -> u128 {\n self % other\n }\n}\nimpl Rem for u64 {\n fn rem(self, other: u64) -> u64 {\n self % other\n }\n}\nimpl Rem for u32 {\n fn rem(self, other: u32) -> u32 {\n self % other\n }\n}\nimpl Rem for u16 {\n fn rem(self, other: u16) -> u16 {\n self % other\n }\n}\nimpl Rem for u8 {\n fn rem(self, other: u8) -> u8 {\n self % other\n }\n}\nimpl Rem for i8 {\n fn rem(self, other: i8) -> i8 {\n self % other\n }\n}\nimpl Rem for i16 {\n fn rem(self, other: i16) -> i16 {\n self % other\n }\n}\nimpl Rem for i32 {\n fn rem(self, other: i32) -> i32 {\n self % other\n }\n}\nimpl Rem for i64 {\n fn rem(self, other: i64) -> i64 {\n self % other\n }\n}\n\n// docs:start:neg-trait\npub trait Neg {\n fn neg(self) -> Self;\n}\n// docs:end:neg-trait\n\n// docs:start:neg-trait-impls\nimpl Neg for Field {\n fn neg(self) -> Field {\n -self\n }\n}\n\nimpl Neg for i8 {\n fn neg(self) -> i8 {\n -self\n }\n}\nimpl Neg for i16 {\n fn neg(self) -> i16 {\n -self\n }\n}\nimpl Neg for i32 {\n fn neg(self) -> i32 {\n -self\n }\n}\nimpl Neg for i64 {\n fn neg(self) -> i64 {\n -self\n }\n}\n// docs:end:neg-trait-impls\n\n// docs:start:wrapping-add-trait\npub trait WrappingAdd {\n fn wrapping_add(self, y: Self) -> Self;\n}\n// docs:end:wrapping-add-trait\n\nimpl WrappingAdd for u8 {\n fn wrapping_add(self: u8, y: u8) -> u8 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u16 {\n fn wrapping_add(self: u16, y: u16) -> u16 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u32 {\n fn wrapping_add(self: u32, y: u32) -> u32 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u64 {\n fn wrapping_add(self: u64, y: u64) -> u64 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u128 {\n fn wrapping_add(self: u128, y: u128) -> u128 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for i8 {\n fn wrapping_add(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_add(y as u8) as i8\n }\n}\n\nimpl WrappingAdd for i16 {\n fn wrapping_add(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_add(y as u16) as i16\n }\n}\n\nimpl WrappingAdd for i32 {\n fn wrapping_add(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_add(y as u32) as i32\n }\n}\n\nimpl WrappingAdd for i64 {\n fn wrapping_add(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_add(y as u64) as i64\n }\n}\nimpl WrappingAdd for Field {\n fn wrapping_add(self: Field, y: Field) -> Field {\n self + y\n }\n}\n\n// docs:start:wrapping-sub-trait\npub trait WrappingSub {\n fn wrapping_sub(self, y: Self) -> Self;\n}\n// docs:start:wrapping-sub-trait\n\nimpl WrappingSub for u8 {\n fn wrapping_sub(self: u8, y: u8) -> u8 {\n wrapping_sub_hlp(self, y) as u8\n }\n}\n\nimpl WrappingSub for u16 {\n fn wrapping_sub(self: u16, y: u16) -> u16 {\n wrapping_sub_hlp(self, y) as u16\n }\n}\n\nimpl WrappingSub for u32 {\n fn wrapping_sub(self: u32, y: u32) -> u32 {\n wrapping_sub_hlp(self, y) as u32\n }\n}\nimpl WrappingSub for u64 {\n fn wrapping_sub(self: u64, y: u64) -> u64 {\n wrapping_sub_hlp(self, y) as u64\n }\n}\nimpl WrappingSub for u128 {\n fn wrapping_sub(self: u128, y: u128) -> u128 {\n wrapping_sub_hlp(self, y) as u128\n }\n}\n\nimpl WrappingSub for i8 {\n fn wrapping_sub(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_sub(y as u8) as i8\n }\n}\n\nimpl WrappingSub for i16 {\n fn wrapping_sub(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_sub(y as u16) as i16\n }\n}\n\nimpl WrappingSub for i32 {\n fn wrapping_sub(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_sub(y as u32) as i32\n }\n}\nimpl WrappingSub for i64 {\n fn wrapping_sub(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_sub(y as u64) as i64\n }\n}\nimpl WrappingSub for Field {\n fn wrapping_sub(self: Field, y: Field) -> Field {\n self - y\n }\n}\n\n// docs:start:wrapping-mul-trait\npub trait WrappingMul {\n fn wrapping_mul(self, y: Self) -> Self;\n}\n// docs:start:wrapping-mul-trait\n\nimpl WrappingMul for u8 {\n fn wrapping_mul(self: u8, y: u8) -> u8 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u16 {\n fn wrapping_mul(self: u16, y: u16) -> u16 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u32 {\n fn wrapping_mul(self: u32, y: u32) -> u32 {\n wrapping_mul_hlp(self, y)\n }\n}\nimpl WrappingMul for u64 {\n fn wrapping_mul(self: u64, y: u64) -> u64 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for i8 {\n fn wrapping_mul(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_mul(y as u8) as i8\n }\n}\n\nimpl WrappingMul for i16 {\n fn wrapping_mul(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_mul(y as u16) as i16\n }\n}\n\nimpl WrappingMul for i32 {\n fn wrapping_mul(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_mul(y as u32) as i32\n }\n}\n\nimpl WrappingMul for i64 {\n fn wrapping_mul(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_mul(y as u64) as i64\n }\n}\n\nimpl WrappingMul for u128 {\n fn wrapping_mul(self: u128, y: u128) -> u128 {\n wrapping_mul128_hlp(self, y)\n }\n}\nimpl WrappingMul for Field {\n fn wrapping_mul(self: Field, y: Field) -> Field {\n self * y\n }\n}\n\nfn wrapping_add_hlp<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() + y.as_())\n}\n\nfn wrapping_sub_hlp<T>(x: T, y: T) -> Field\nwhere\n T: AsPrimitive<Field>,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n x.as_() + 340282366920938463463374607431768211456 - y.as_()\n}\n\nfn wrapping_mul_hlp<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() * y.as_())\n}\n\nglobal two_pow_64: u128 = 0x10000000000000000;\n/// Splits a 128 bits number into two 64 bits limbs\nunconstrained fn split64(x: u128) -> (u64, u64) {\n let lo = x as u64;\n let hi = (x / two_pow_64) as u64;\n (lo, hi)\n}\n\n/// Split a 128 bits number into two 64 bits limbs\n/// It will fail if the number is more than 128 bits\nfn split_into_64_bit_limbs(x: u128) -> (u64, u64) {\n // Safety: the limbs are constrained below\n let (x_lo, x_hi) = unsafe { split64(x) };\n assert(x as Field == x_lo as Field + x_hi as Field * two_pow_64 as Field);\n (x_lo, x_hi)\n}\n\n#[field(bn254)]\nfn wrapping_mul128_hlp(x: u128, y: u128) -> u128 {\n let (x_lo, x_hi) = split_into_64_bit_limbs(x);\n let (y_lo, y_hi) = split_into_64_bit_limbs(y);\n // Multiplication using the limbs:(x_lo + 2**64*x_hi)*(y_lo + 2**64*y_hi)=x_lo*y_lo+...\n // and skipping the terms over 2**128\n // Working with u64 limbs ensures that we cannot overflow the field modulus.\n let low = x_lo as Field * y_lo as Field;\n let lo = low as u64 as Field;\n let carry = (low - lo) / two_pow_64 as Field;\n let high = x_lo as Field * y_hi as Field + x_hi as Field * y_lo as Field + carry;\n let hi = high as u64 as Field;\n (lo + two_pow_64 as Field * hi) as u128\n}\n\nmod tests {\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n crate::static_assert(1 == 2, \"custom message\");\n }\n\n mod arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Rem, Sub};\n #[test]\n fn test_basic_arithmetic_traits() {\n // add\n assert_eq(5.add(3), 8);\n assert_eq(0u8.add(255u8), 255u8);\n assert_eq(42.add(58), 100);\n\n // sub\n assert_eq(10.sub(3), 7);\n assert_eq(100.sub(42), 58);\n\n // mul\n assert_eq(6.mul(7), 42);\n\n // div\n assert_eq(15.div(3), 5);\n assert_eq(10u8.div(3u8), 3u8);\n assert_eq(15.div(3), 5);\n\n // rem (Field doesn't implement Rem)\n assert_eq(17u64.rem(5u64), 2u64);\n assert_eq(10u8.rem(3u8), 1u8);\n\n // neg\n assert_eq(42.neg(), -42);\n assert_eq((-10).neg(), 10);\n assert_eq(42.neg(), -42);\n }\n\n #[test]\n fn test_division() {\n // test division by one\n assert_eq(42.div(1), 42);\n assert_eq(0.div(1), 0);\n assert_eq(255u8.div(1u8), 255u8);\n\n // test division by self\n assert_eq(42.div(42), 1);\n assert_eq(1.div(1), 1);\n\n // test remainder (Field doesn't implement Rem)\n assert_eq(42u32.rem(42u32), 0u32);\n assert_eq(0u16.rem(42u16), 0u16);\n assert_eq(1u64.rem(42u64), 1u64);\n }\n\n #[test(should_fail)]\n fn test_u8_sub_overflow_failure() {\n let _ = 0u8.sub(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_add_overflow_failure() {\n let _ = 255u8.add(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_mul_overflow_failure() {\n let _ = 255u8.mul(2u8);\n }\n\n #[test(should_fail)]\n fn test_u16_sub_overflow_failure() {\n let _ = 0u16.sub(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_add_overflow_failure() {\n let _ = 65535u16.add(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_mul_overflow_failure() {\n let _ = 65535u16.mul(2u16);\n }\n\n #[test(should_fail)]\n fn test_signed_sub_overflow_failure() {\n let val: i8 = -128;\n let _ = val.sub(1i8);\n }\n\n #[test(should_fail)]\n fn test_signed_overflow_failure() {\n let _ = 127i8.add(1i8);\n }\n\n #[test]\n fn test_field() {\n let zero: Field = 0;\n let one: Field = 1;\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod wrapping_arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Sub, WrappingAdd, WrappingMul, WrappingSub};\n #[test]\n fn test_wrapping_add() {\n assert_eq(255u8.wrapping_add(1u8), 0u8);\n assert_eq(255u8.wrapping_add(255u8), 254u8);\n assert_eq(0u8.wrapping_add(0u8), 0u8);\n assert_eq(128u8.wrapping_add(128u8), 0u8);\n\n // test u16 wrapping add\n assert_eq(65535u16.wrapping_add(1u16), 0u16);\n assert_eq(65535u16.wrapping_add(65535u16), 65534u16);\n\n // test u32 wrapping add\n assert_eq(0xffffffffu32.wrapping_add(1u32), 0u32);\n assert_eq(0xffffffffu32.wrapping_add(0xffffffffu32), 0xfffffffeu32);\n\n // test u64 wrapping add\n assert_eq(0xffffffffffffffffu64.wrapping_add(1u64), 0u64);\n assert_eq(\n 0xffffffffffffffffu64.wrapping_add(0xffffffffffffffffu64),\n 0xfffffffffffffffeu64,\n );\n\n // test u128 wrapping add\n assert_eq(0xffffffffffffffffffffffffffffffffu128.wrapping_add(1u128), 0u128);\n\n // test signed types\n assert_eq(127i8.wrapping_add(1i8), -128i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_add(-1i8), 127i8);\n\n // test Field wrapping add\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let hundred: Field = 100;\n let neg_two: Field = -2;\n let two: Field = 2;\n let zero: Field = 0;\n let neg_two_hundred: Field = -200;\n let neg_one_ninety_eight: Field = -198;\n assert_eq(forty_two.wrapping_add(fifty_eight), hundred);\n assert_eq(neg_two.wrapping_add(two), zero);\n assert_eq(neg_two_hundred.wrapping_add(two), neg_one_ninety_eight);\n }\n\n #[test]\n fn test_wrapping_sub() {\n assert_eq(0u8.wrapping_sub(1u8), 255u8);\n assert_eq(255u8.wrapping_sub(255u8), 0u8);\n assert_eq(0u8.wrapping_sub(0u8), 0u8);\n assert_eq(1u8.wrapping_sub(2u8), 255u8);\n\n // test u16 wrapping sub\n assert_eq(0u16.wrapping_sub(1u16), 65535u16);\n assert_eq(65535u16.wrapping_sub(65535u16), 0u16);\n\n // test u32 wrapping sub\n assert_eq(0u32.wrapping_sub(1u32), 0xffffffffu32);\n assert_eq(0xffffffffu32.wrapping_sub(0xffffffffu32), 0u32);\n\n // test u64 wrapping sub\n assert_eq(0u64.wrapping_sub(1u64), 0xffffffffffffffffu64);\n assert_eq(0xffffffffffffffffu64.wrapping_sub(0xffffffffffffffffu64), 0u64);\n\n // test u128 wrapping sub\n assert_eq(0u128.wrapping_sub(1u128), 0xffffffffffffffffffffffffffffffffu128);\n\n // test signed types\n let val: i8 = -128;\n assert_eq(val.wrapping_sub(1i8), 127i8);\n assert_eq(127i8.wrapping_sub(-1i8), -128i8);\n\n // test Field wrapping sub\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let neg_sixteen: Field = -16;\n assert_eq(forty_two.wrapping_sub(fifty_eight), neg_sixteen);\n }\n\n #[test]\n fn test_wrapping_mul() {\n let zero: u128 = 0;\n let one: u128 = 1;\n let two_pow_64: u128 = 0x10000000000000000;\n let u128_max: u128 = 0xffffffffffffffffffffffffffffffff;\n\n assert_eq(zero, zero.wrapping_mul(one));\n assert_eq(zero, one.wrapping_mul(zero));\n assert_eq(one, one.wrapping_mul(one));\n assert_eq(zero, zero.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(zero));\n assert_eq(two_pow_64, two_pow_64.wrapping_mul(one));\n assert_eq(two_pow_64, one.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(two_pow_64));\n assert_eq(one, u128_max.wrapping_mul(u128_max));\n\n // test u8 wrapping mul\n assert_eq(255u8.wrapping_mul(2u8), 254u8);\n assert_eq(255u8.wrapping_mul(255u8), 1u8);\n assert_eq(128u8.wrapping_mul(2u8), 0u8);\n\n // test u16 wrapping mul\n assert_eq(65535u16.wrapping_mul(2u16), 65534u16);\n assert_eq(65535u16.wrapping_mul(65535u16), 1u16);\n\n // test u32 wrapping mul\n assert_eq(0xffffffffu32.wrapping_mul(2u32), 0xfffffffeu32);\n assert_eq(0xffffffffu32.wrapping_mul(0xffffffffu32), 1u32);\n\n // test u64 wrapping mul\n // 0xffffffffffffffffu64 is 2^64 - 1\n assert_eq(0xffffffffffffffffu64.wrapping_mul(2u64), 0xfffffffffffffffeu64);\n assert_eq(0xffffffffffffffffu64.wrapping_mul(0xffffffffffffffffu64), 1u64);\n\n // test signed types\n assert_eq(127i8.wrapping_mul(2i8), -2i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_mul(-1i8), -128i8);\n\n // test Field wrapping mul\n let six: Field = 6;\n let seven: Field = 7;\n let forty_two: Field = 42;\n let neg_two: Field = -2;\n let two: Field = 2;\n let neg_four: Field = -4;\n assert_eq(six.wrapping_mul(seven), forty_two);\n assert_eq(neg_two.wrapping_mul(two), neg_four);\n }\n\n // test wrapping operations is the same as the regular operations\n #[test]\n fn test_wrapping_vs_regular() {\n let u64_large = 0x123456789abcdef0u64;\n let u128_large = 0x123456789abcdef0123456789abcdef0u128;\n\n assert_eq(u64_large.wrapping_add(1u64), u64_large + 1u64);\n assert_eq(u64_large.wrapping_sub(1u64), u64_large - 1u64);\n assert_eq(u64_large.wrapping_mul(2u64), u64_large * 2u64);\n\n assert_eq(u128_large.wrapping_add(1u128), u128_large + 1u128);\n assert_eq(u128_large.wrapping_sub(1u128), u128_large - 1u128);\n assert_eq(u128_large.wrapping_mul(2u128), u128_large * 2u128);\n }\n\n #[test]\n fn test_field_wrapping_operations() {\n let zero: Field = 0;\n let one: Field = 1;\n let large_val = 0xffffffffffffffff;\n\n // test Field wrapping operations\n assert_eq(zero.wrapping_add(one), one);\n assert_eq(one.wrapping_add(large_val), one + large_val);\n assert_eq(zero.wrapping_sub(one), -one);\n assert_eq(one.wrapping_sub(large_val), one - large_val);\n assert_eq(zero.wrapping_mul(one), zero);\n assert_eq(one.wrapping_mul(large_val), large_val);\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod split_functions {\n\n use crate::ops::arith::{split64, split_into_64_bit_limbs};\n\n // test split64 and split_into_64_bit_limbs functions\n #[test]\n fn test_split_functions() {\n let small_val = 0x123456789abcdefu128;\n let large_val = 0x123456789abcdef0123456789abcdef0u128;\n let max_val = 0xffffffffffffffffffffffffffffffffu128;\n\n // test split64 (unconstrained)\n // Safety: testing\n unsafe {\n let (lo, hi) = split64(small_val);\n assert_eq(lo, 0x123456789abcdefu64);\n assert_eq(hi, 0u64);\n\n let (lo2, hi2) = split64(large_val);\n assert_eq(lo2, 0x123456789abcdef0u64);\n assert_eq(hi2, 0x123456789abcdef0u64);\n }\n\n // test split_into_64_bit_limbs (constrained)\n let (lo3, hi3) = split_into_64_bit_limbs(small_val);\n assert_eq(lo3, 0x123456789abcdefu64);\n assert_eq(hi3, 0u64);\n\n let (lo4, hi4) = split_into_64_bit_limbs(large_val);\n assert_eq(lo4, 0x123456789abcdef0u64);\n assert_eq(hi4, 0x123456789abcdef0u64);\n\n let (lo5, hi5) = split_into_64_bit_limbs(max_val);\n assert_eq(lo5, 0xffffffffffffffffu64);\n assert_eq(hi5, 0xffffffffffffffffu64);\n }\n }\n\n mod traits {\n use crate::ops::arith::{\n Add, Div, Mul, Neg, Rem, Sub, WrappingAdd, WrappingMul, WrappingSub,\n };\n\n #[test]\n fn add() {\n assert_eq(1_u8.add(2), 3);\n assert_eq(1_u16.add(2), 3);\n assert_eq(1_u32.add(2), 3);\n assert_eq(1_u64.add(2), 3);\n assert_eq(1_u128.add(2), 3);\n assert_eq(1_i8.add(2), 3);\n assert_eq(1_i16.add(2), 3);\n assert_eq(1_i32.add(2), 3);\n assert_eq(1_i64.add(2), 3);\n assert_eq(1_Field.add(2), 3);\n }\n\n #[test]\n fn sub() {\n assert_eq(3_u8.sub(2), 1);\n assert_eq(3_u16.sub(2), 1);\n assert_eq(3_u32.sub(2), 1);\n assert_eq(3_u64.sub(2), 1);\n assert_eq(3_u128.sub(2), 1);\n assert_eq(3_i8.sub(2), 1);\n assert_eq(3_i16.sub(2), 1);\n assert_eq(3_i32.sub(2), 1);\n assert_eq(3_i64.sub(2), 1);\n assert_eq(3_Field.sub(2), 1);\n }\n\n #[test]\n fn mul() {\n assert_eq(3_u8.mul(2), 6);\n assert_eq(3_u16.mul(2), 6);\n assert_eq(3_u32.mul(2), 6);\n assert_eq(3_u64.mul(2), 6);\n assert_eq(3_u128.mul(2), 6);\n assert_eq(3_i8.mul(2), 6);\n assert_eq(3_i16.mul(2), 6);\n assert_eq(3_i32.mul(2), 6);\n assert_eq(3_i64.mul(2), 6);\n assert_eq(3_Field.mul(2), 6);\n }\n\n #[test]\n fn div() {\n assert_eq(6_u8.div(2), 3);\n assert_eq(6_u16.div(2), 3);\n assert_eq(6_u32.div(2), 3);\n assert_eq(6_u64.div(2), 3);\n assert_eq(6_u128.div(2), 3);\n assert_eq(6_i8.div(2), 3);\n assert_eq(6_i16.div(2), 3);\n assert_eq(6_i32.div(2), 3);\n assert_eq(6_i64.div(2), 3);\n assert_eq(6_Field.div(2), 3);\n }\n\n #[test]\n fn rem() {\n assert_eq(3_u8.rem(2), 1);\n assert_eq(3_u16.rem(2), 1);\n assert_eq(3_u32.rem(2), 1);\n assert_eq(3_u64.rem(2), 1);\n assert_eq(3_u128.rem(2), 1);\n assert_eq(3_i8.rem(2), 1);\n assert_eq(3_i16.rem(2), 1);\n assert_eq(3_i32.rem(2), 1);\n assert_eq(3_i64.rem(2), 1);\n }\n\n #[test]\n fn neg() {\n assert_eq(3_i8.neg(), -3);\n assert_eq(3_i16.neg(), -3);\n assert_eq(3_i32.neg(), -3);\n assert_eq(3_i64.neg(), -3);\n }\n\n #[test]\n fn wrapping_add() {\n assert_eq(255_u8.wrapping_add(2), 1);\n assert_eq(65535_u16.wrapping_add(2), 1);\n assert_eq(4294967295_u32.wrapping_add(2), 1);\n assert_eq(18446744073709551615_u64.wrapping_add(2), 1);\n assert_eq(340282366920938463463374607431768211455_u128.wrapping_add(2), 1);\n assert_eq(127_i8.wrapping_add(2), -127);\n assert_eq(32767_i16.wrapping_add(2), -32767);\n assert_eq(2147483647_i32.wrapping_add(2), -2147483647);\n assert_eq(9223372036854775807_i64.wrapping_add(2), -9223372036854775807);\n assert_eq(1_Field.wrapping_add(2), 3);\n }\n\n #[test]\n fn wrapping_sub() {\n assert_eq(0_u8.wrapping_sub(1), 255);\n assert_eq(0_u16.wrapping_sub(1), 65535);\n assert_eq(0_u32.wrapping_sub(1), 4294967295);\n assert_eq(0_u64.wrapping_sub(1), 18446744073709551615);\n assert_eq(0_u128.wrapping_sub(1), 340282366920938463463374607431768211455);\n assert_eq((-128_i8).wrapping_sub(1), 127);\n assert_eq((-32768_i16).wrapping_sub(1), 32767);\n assert_eq((-2147483648_i32).wrapping_sub(1), 2147483647);\n assert_eq((-9223372036854775808_i64).wrapping_sub(1), 9223372036854775807);\n assert_eq(3_Field.wrapping_sub(1), 2);\n }\n\n #[test]\n fn wrapping_mul() {\n assert_eq(255_u8.wrapping_mul(2), 254);\n assert_eq(65535_u16.wrapping_mul(2), 65534);\n assert_eq(4294967295_u32.wrapping_mul(2), 4294967294);\n assert_eq(18446744073709551615_u64.wrapping_mul(2), 18446744073709551614);\n assert_eq(\n 340282366920938463463374607431768211455_u128.wrapping_mul(2),\n 340282366920938463463374607431768211454,\n );\n assert_eq(127_i8.wrapping_mul(2), -2);\n assert_eq(32767_i16.wrapping_mul(2), -2);\n assert_eq(2147483647_i32.wrapping_mul(2), -2);\n assert_eq(9223372036854775807_i64.wrapping_mul(2), -2);\n assert_eq(2_Field.wrapping_mul(3), 6);\n }\n }\n}\n"
1718
1866
  },
1719
- "40": {
1867
+ "42": {
1720
1868
  "function_locations": [
1721
1869
  {
1722
1870
  "name": "Option<T>::none",
@@ -1809,34 +1957,104 @@
1809
1957
  {
1810
1958
  "name": "<impl Ord for Option<T>>::cmp",
1811
1959
  "start": 5975
1960
+ },
1961
+ {
1962
+ "name": "tests::some_and_none",
1963
+ "start": 6447
1964
+ },
1965
+ {
1966
+ "name": "tests::unwrap_succeeds",
1967
+ "start": 6677
1968
+ },
1969
+ {
1970
+ "name": "tests::unwrap_fails",
1971
+ "start": 6781
1972
+ },
1973
+ {
1974
+ "name": "tests::unwrap_or",
1975
+ "start": 6868
1976
+ },
1977
+ {
1978
+ "name": "tests::unwrap_or_else",
1979
+ "start": 7016
1980
+ },
1981
+ {
1982
+ "name": "tests::expect_succeeds",
1983
+ "start": 7181
1984
+ },
1985
+ {
1986
+ "name": "tests::expect_fails",
1987
+ "start": 7328
1988
+ },
1989
+ {
1990
+ "name": "tests::map",
1991
+ "start": 7427
1992
+ },
1993
+ {
1994
+ "name": "tests::map_or",
1995
+ "start": 7595
1996
+ },
1997
+ {
1998
+ "name": "tests::map_or_else",
1999
+ "start": 7762
2000
+ },
2001
+ {
2002
+ "name": "tests::and",
2003
+ "start": 7937
2004
+ },
2005
+ {
2006
+ "name": "tests::and_then",
2007
+ "start": 8277
2008
+ },
2009
+ {
2010
+ "name": "tests::or",
2011
+ "start": 8663
2012
+ },
2013
+ {
2014
+ "name": "tests::or_else",
2015
+ "start": 9000
2016
+ },
2017
+ {
2018
+ "name": "tests::xor",
2019
+ "start": 9365
2020
+ },
2021
+ {
2022
+ "name": "tests::filter",
2023
+ "start": 9704
2024
+ },
2025
+ {
2026
+ "name": "tests::flatten",
2027
+ "start": 10030
2028
+ },
2029
+ {
2030
+ "name": "tests::default",
2031
+ "start": 10301
2032
+ },
2033
+ {
2034
+ "name": "tests::eq",
2035
+ "start": 10394
2036
+ },
2037
+ {
2038
+ "name": "tests::cmp",
2039
+ "start": 10714
1812
2040
  }
1813
2041
  ],
1814
2042
  "path": "std/option.nr",
1815
- "source": "use crate::cmp::{Eq, Ord, Ordering};\nuse crate::default::Default;\nuse crate::hash::{Hash, Hasher};\n\n/// Represents a value of type T or its absence.\n/// Use `Option::some(value)` to construct a value or `Option::none()` to record the absence of one.\npub struct Option<T> {\n _is_some: bool,\n _value: T,\n}\n\nimpl<T> Option<T> {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::mem::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(&self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(&self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else<Env>(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n pub fn expect<let N: u32, MessageTypes>(self, message: fmtstr<N, MessageTypes>) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> Option<U> {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or<U, Env>(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else<U, Env1, Env2>(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then<U, Env>(self, f: fn[Env](T) -> Option<U>) -> Option<U> {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else<Env>(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter<Env>(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option<Option<T>> into a Option<T>.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option<Option<T>>) -> Option<T> {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n\nimpl<T> Default for Option<T> {\n fn default() -> Self {\n Option::none()\n }\n}\n\nimpl<T> Eq for Option<T>\nwhere\n T: Eq,\n{\n fn eq(self, other: Self) -> bool {\n if self._is_some == other._is_some {\n if self._is_some {\n self._value == other._value\n } else {\n true\n }\n } else {\n false\n }\n }\n}\n\nimpl<T> Hash for Option<T>\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self._is_some.hash(state);\n if self._is_some {\n self._value.hash(state);\n }\n }\n}\n\n// For this impl we're declaring Option::none < Option::some\nimpl<T> Ord for Option<T>\nwhere\n T: Ord,\n{\n fn cmp(self, other: Self) -> Ordering {\n if self._is_some {\n if other._is_some {\n self._value.cmp(other._value)\n } else {\n Ordering::greater()\n }\n } else if other._is_some {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n"
2043
+ "source": "use crate::cmp::{Eq, Ord, Ordering};\nuse crate::default::Default;\nuse crate::hash::{Hash, Hasher};\n\n/// Represents a value of type T or its absence.\n/// Use `Option::some(value)` to construct a value or `Option::none()` to record the absence of one.\npub struct Option<T> {\n _is_some: bool,\n _value: T,\n}\n\nimpl<T> Option<T> {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::mem::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(&self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(&self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else<Env>(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n pub fn expect<let N: u32, MessageTypes>(self, message: fmtstr<N, MessageTypes>) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> Option<U> {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or<U, Env>(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else<U, Env1, Env2>(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then<U, Env>(self, f: fn[Env](T) -> Option<U>) -> Option<U> {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else<Env>(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter<Env>(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option<Option<T>> into a Option<T>.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option<Option<T>>) -> Option<T> {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n\nimpl<T> Default for Option<T> {\n fn default() -> Self {\n Option::none()\n }\n}\n\nimpl<T> Eq for Option<T>\nwhere\n T: Eq,\n{\n fn eq(self, other: Self) -> bool {\n if self._is_some == other._is_some {\n if self._is_some {\n self._value == other._value\n } else {\n true\n }\n } else {\n false\n }\n }\n}\n\nimpl<T> Hash for Option<T>\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self._is_some.hash(state);\n if self._is_some {\n self._value.hash(state);\n }\n }\n}\n\n// For this impl we're declaring Option::none < Option::some\nimpl<T> Ord for Option<T>\nwhere\n T: Ord,\n{\n fn cmp(self, other: Self) -> Ordering {\n if self._is_some {\n if other._is_some {\n self._value.cmp(other._value)\n } else {\n Ordering::greater()\n }\n } else if other._is_some {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n\nmod tests {\n use crate::cmp::Ord;\n use crate::cmp::Ordering;\n use crate::default::Default as _;\n use super::Option;\n\n #[test]\n fn some_and_none() {\n assert(Option::<u8>::none().is_none());\n assert(!Option::<u8>::none().is_some());\n assert(Option::some(1).is_some());\n assert(!Option::some(1).is_none());\n }\n\n #[test]\n fn unwrap_succeeds() {\n assert_eq(Option::some(1).unwrap(), 1);\n }\n\n #[test(should_fail)]\n fn unwrap_fails() {\n let _ = Option::<u8>::none().unwrap();\n }\n\n #[test]\n fn unwrap_or() {\n assert_eq(Option::some(1).unwrap_or(2), 1);\n assert_eq(Option::none().unwrap_or(2), 2);\n }\n\n #[test]\n fn unwrap_or_else() {\n assert_eq(Option::some(1).unwrap_or_else(|| 2), 1);\n assert_eq(Option::none().unwrap_or_else(|| 2), 2);\n }\n\n #[test]\n fn expect_succeeds() {\n assert_eq(Option::some(1).expect(f\"Should be there\"), 1);\n }\n\n #[test(should_fail_with = \"Should be there\")]\n fn expect_fails() {\n let _ = Option::<u8>::none().expect(f\"Should be there\");\n }\n\n #[test]\n fn map() {\n assert(Option::<u8>::none().map(|x| x + 1).is_none());\n assert_eq(Option::some(1).map(|x| x + 1), Option::some(2));\n }\n\n #[test]\n fn map_or() {\n assert_eq(Option::<u8>::none().map_or(0, |x| x + 1), 0);\n assert_eq(Option::some(1).map_or(0, |x| x + 1), 2);\n }\n\n #[test]\n fn map_or_else() {\n assert_eq(Option::<u8>::none().map_or_else(|| 0, |x| x + 1), 0);\n assert_eq(Option::some(1).map_or_else(|| 0, |x| x + 1), 2);\n }\n\n #[test]\n fn and() {\n assert_eq(Option::<u8>::none().and(Option::none()), Option::none());\n assert_eq(Option::<u8>::none().and(Option::some(1)), Option::none());\n assert_eq(Option::some(1).and(Option::some(2)), Option::some(2));\n assert_eq(Option::some(1).and(Option::none()), Option::none());\n }\n\n #[test]\n fn and_then() {\n assert_eq(Option::<u8>::none().and_then(|_| Option::<u8>::none()), Option::none());\n assert_eq(Option::<u8>::none().and_then(|_| Option::some(1)), Option::none());\n assert_eq(Option::some(1).and_then(|x| Option::some(x + 1)), Option::some(2));\n assert_eq(Option::some(1).and_then(|_| Option::<u8>::none()), Option::none());\n }\n\n #[test]\n fn or() {\n assert_eq(Option::<u8>::none().or(Option::none()), Option::none());\n assert_eq(Option::<u8>::none().or(Option::some(1)), Option::some(1));\n assert_eq(Option::some(1).or(Option::some(2)), Option::some(1));\n assert_eq(Option::some(1).or(Option::none()), Option::some(1));\n }\n\n #[test]\n fn or_else() {\n assert_eq(Option::<u8>::none().or_else(|| Option::none()), Option::none());\n assert_eq(Option::<u8>::none().or_else(|| Option::some(1)), Option::some(1));\n assert_eq(Option::some(1).or_else(|| Option::some(2)), Option::some(1));\n assert_eq(Option::some(1).or_else(|| Option::none()), Option::some(1));\n }\n\n #[test]\n fn xor() {\n assert_eq(Option::<u8>::none().xor(Option::none()), Option::none());\n assert_eq(Option::<u8>::none().xor(Option::some(1)), Option::some(1));\n assert_eq(Option::some(1).xor(Option::some(2)), Option::none());\n assert_eq(Option::some(1).xor(Option::none()), Option::some(1));\n }\n\n #[test]\n fn filter() {\n assert_eq(Option::<u8>::none().filter(|_| true), Option::none());\n assert_eq(Option::some(1).filter(|x| x == 1), Option::some(1));\n assert_eq(Option::some(1).filter(|x| x == 2), Option::none());\n assert_eq(Option::some(1).filter(|x| x == 2), Option::none());\n }\n\n #[test]\n fn flatten() {\n assert_eq(Option::<Option<u8>>::none().flatten(), Option::none());\n assert_eq(Option::some(Option::<u8>::none()).flatten(), Option::none());\n assert_eq(Option::some(Option::some(1)).flatten(), Option::some(1));\n }\n\n #[test]\n fn default() {\n assert_eq(Option::<u8>::default(), Option::none());\n }\n\n #[test]\n fn eq() {\n assert(Option::<u8>::none() == Option::none());\n assert(Option::<u8>::some(1) != Option::none());\n assert(Option::<u8>::none() != Option::some(1));\n assert(Option::<u8>::some(1) == Option::some(1));\n assert(Option::<u8>::some(1) != Option::some(2));\n }\n\n #[test]\n fn cmp() {\n let none = Option::<u8>::none();\n let one = Option::<u8>::some(1);\n let two = Option::<u8>::some(2);\n assert_eq(none.cmp(none), Ordering::equal());\n assert_eq(none.cmp(one), Ordering::less());\n assert_eq(one.cmp(none), Ordering::greater());\n assert_eq(one.cmp(one), Ordering::equal());\n assert_eq(one.cmp(two), Ordering::less());\n assert_eq(two.cmp(one), Ordering::greater());\n }\n}\n"
1816
2044
  },
1817
- "41": {
2045
+ "43": {
1818
2046
  "function_locations": [
1819
2047
  {
1820
2048
  "name": "panic",
1821
2049
  "start": 196
1822
- }
1823
- ],
1824
- "path": "std/panic.nr",
1825
- "source": "/// Halt the program at runtime with the given error message.\n///\n/// The provided error message must be either a `str` or a `fmtstr`.\npub fn panic<T, U>(message: T) -> U\nwhere\n T: StringLike,\n{\n assert(false, message);\n crate::mem::zeroed()\n}\n\ntrait StringLike {}\n\nimpl<let N: u32> StringLike for str<N> {}\nimpl<let N: u32, T> StringLike for fmtstr<N, T> {}\n"
1826
- },
1827
- "49": {
1828
- "function_locations": [
1829
- {
1830
- "name": "calculate_fee",
1831
- "start": 232
1832
2050
  },
1833
2051
  {
1834
- "name": "get_bridge_gas_msg_hash",
1835
- "start": 747
2052
+ "name": "tests::panics",
2053
+ "start": 469
1836
2054
  }
1837
2055
  ],
1838
- "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/fee_juice_contract/src/lib.nr",
1839
- "source": "use aztec::context::PublicContext;\nuse aztec::protocol::address::AztecAddress;\nuse aztec::protocol::hash::sha256_to_field;\nuse aztec::protocol::traits::ToField;\n\npub fn calculate_fee<TPublicContext>(context: PublicContext) -> Field {\n context.transaction_fee()\n}\n\n/// Computes the content hash for an L1-to-L2 \"bridge gas\" message, matching the hash produced on L1 by\n/// `FeeJuicePortal.depositToAztecPublic`: `sha256ToField(abi.encodeWithSignature(\"claim(bytes32,uint256)\", to,\n/// amount))`.\n///\n/// The 68-byte buffer is: [4-byte selector of \"claim(bytes32,uint256)\"][32-byte recipient][32-byte amount], hashed\n/// with `sha256_to_field` to produce a single Field.\npub fn get_bridge_gas_msg_hash(owner: AztecAddress, amount: u128) -> Field {\n let mut hash_bytes = [0; 68];\n let recipient_bytes: [u8; 32] = owner.to_field().to_be_bytes();\n let amount_bytes: [u8; 32] = (amount as Field).to_be_bytes();\n\n // The purpose of including the following selector is to make the message unique to that specific call. Note that\n // it has nothing to do with calling the function.\n let selector = comptime { keccak256::keccak256(\"claim(bytes32,uint256)\".as_bytes(), 22) };\n\n for i in 0..4 {\n hash_bytes[i] = selector[i];\n }\n\n for i in 0..32 {\n hash_bytes[i + 4] = recipient_bytes[i];\n hash_bytes[i + 36] = amount_bytes[i];\n }\n\n let content_hash = sha256_to_field(hash_bytes);\n content_hash\n}\n"
2056
+ "path": "std/panic.nr",
2057
+ "source": "/// Halt the program at runtime with the given error message.\n///\n/// The provided error message must be either a `str` or a `fmtstr`.\npub fn panic<T, U>(message: T) -> U\nwhere\n T: StringLike,\n{\n assert(false, message);\n crate::mem::zeroed()\n}\n\ntrait StringLike {}\n\nimpl<let N: u32> StringLike for str<N> {}\nimpl<let N: u32, T> StringLike for fmtstr<N, T> {}\n\nmod tests {\n use crate::prelude::panic;\n\n #[test(should_fail_with = \"OH NO\")]\n fn panics() {\n panic(\"OH NO\");\n }\n}\n"
1840
2058
  },
1841
2059
  "5": {
1842
2060
  "function_locations": [
@@ -1908,199 +2126,261 @@
1908
2126
  "name": "make_tuple_eq_body",
1909
2127
  "start": 2598
1910
2128
  },
2129
+ {
2130
+ "name": "<impl Eq for (A,)>::eq",
2131
+ "start": 2848
2132
+ },
1911
2133
  {
1912
2134
  "name": "<impl Eq for (A, B)>::eq",
1913
- "start": 2859
2135
+ "start": 2959
1914
2136
  },
1915
2137
  {
1916
2138
  "name": "<impl Eq for (A, B, C)>::eq",
1917
- "start": 2991
2139
+ "start": 3091
1918
2140
  },
1919
2141
  {
1920
2142
  "name": "<impl Eq for (A, B, C, D)>::eq",
1921
- "start": 3136
2143
+ "start": 3236
1922
2144
  },
1923
2145
  {
1924
2146
  "name": "<impl Eq for (A, B, C, D, E)>::eq",
1925
- "start": 3294
2147
+ "start": 3394
1926
2148
  },
1927
2149
  {
1928
2150
  "name": "<impl Eq for (A, B, C, D, E, F)>::eq",
1929
- "start": 3465
2151
+ "start": 3565
1930
2152
  },
1931
2153
  {
1932
2154
  "name": "<impl Eq for (A, B, C, D, E, F, G)>::eq",
1933
- "start": 3649
2155
+ "start": 3749
1934
2156
  },
1935
2157
  {
1936
2158
  "name": "<impl Eq for (A, B, C, D, E, F, G, H)>::eq",
1937
- "start": 3846
2159
+ "start": 3946
1938
2160
  },
1939
2161
  {
1940
2162
  "name": "<impl Eq for (A, B, C, D, E, F, G, H, I)>::eq",
1941
- "start": 4056
2163
+ "start": 4156
1942
2164
  },
1943
2165
  {
1944
2166
  "name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J)>::eq",
1945
- "start": 4279
2167
+ "start": 4379
1946
2168
  },
1947
2169
  {
1948
2170
  "name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J, K)>::eq",
1949
- "start": 4516
2171
+ "start": 4616
1950
2172
  },
1951
2173
  {
1952
2174
  "name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J, K, L)>::eq",
1953
- "start": 4766
2175
+ "start": 4866
1954
2176
  },
1955
2177
  {
1956
2178
  "name": "<impl Eq for Ordering>::eq",
1957
- "start": 4876
2179
+ "start": 4976
1958
2180
  },
1959
2181
  {
1960
2182
  "name": "Ordering::less",
1961
- "start": 5477
2183
+ "start": 5577
1962
2184
  },
1963
2185
  {
1964
2186
  "name": "Ordering::equal",
1965
- "start": 5548
2187
+ "start": 5648
1966
2188
  },
1967
2189
  {
1968
2190
  "name": "Ordering::greater",
1969
- "start": 5621
2191
+ "start": 5721
1970
2192
  },
1971
2193
  {
1972
2194
  "name": "derive_ord",
1973
- "start": 5992
2195
+ "start": 6092
1974
2196
  },
1975
2197
  {
1976
2198
  "name": "<impl Ord for u128>::cmp",
1977
- "start": 6642
2199
+ "start": 6742
1978
2200
  },
1979
2201
  {
1980
2202
  "name": "<impl Ord for u64>::cmp",
1981
- "start": 6889
2203
+ "start": 6989
1982
2204
  },
1983
2205
  {
1984
2206
  "name": "<impl Ord for u32>::cmp",
1985
- "start": 7137
2207
+ "start": 7237
1986
2208
  },
1987
2209
  {
1988
2210
  "name": "<impl Ord for u16>::cmp",
1989
- "start": 7385
2211
+ "start": 7485
1990
2212
  },
1991
2213
  {
1992
2214
  "name": "<impl Ord for u8>::cmp",
1993
- "start": 7631
2215
+ "start": 7731
1994
2216
  },
1995
2217
  {
1996
2218
  "name": "<impl Ord for i8>::cmp",
1997
- "start": 7877
2219
+ "start": 7977
1998
2220
  },
1999
2221
  {
2000
2222
  "name": "<impl Ord for i16>::cmp",
2001
- "start": 8125
2223
+ "start": 8225
2002
2224
  },
2003
2225
  {
2004
2226
  "name": "<impl Ord for i32>::cmp",
2005
- "start": 8373
2227
+ "start": 8473
2006
2228
  },
2007
2229
  {
2008
2230
  "name": "<impl Ord for i64>::cmp",
2009
- "start": 8621
2231
+ "start": 8721
2010
2232
  },
2011
2233
  {
2012
2234
  "name": "<impl Ord for ()>::cmp",
2013
- "start": 8875
2235
+ "start": 8975
2014
2236
  },
2015
2237
  {
2016
2238
  "name": "<impl Ord for bool>::cmp",
2017
- "start": 8974
2239
+ "start": 9074
2018
2240
  },
2019
2241
  {
2020
2242
  "name": "<impl Ord for [T; N]>::cmp",
2021
- "start": 9444
2243
+ "start": 9544
2022
2244
  },
2023
2245
  {
2024
2246
  "name": "<impl Ord for [T]>::cmp",
2025
- "start": 9847
2247
+ "start": 9947
2026
2248
  },
2027
2249
  {
2028
2250
  "name": "make_tuple_ord_body",
2029
- "start": 10415
2251
+ "start": 10515
2252
+ },
2253
+ {
2254
+ "name": "<impl Ord for (A,)>::cmp",
2255
+ "start": 11125
2030
2256
  },
2031
2257
  {
2032
2258
  "name": "<impl Ord for (A, B)>::cmp",
2033
- "start": 11037
2259
+ "start": 11246
2034
2260
  },
2035
2261
  {
2036
2262
  "name": "<impl Ord for (A, B, C)>::cmp",
2037
- "start": 11179
2263
+ "start": 11388
2038
2264
  },
2039
2265
  {
2040
2266
  "name": "<impl Ord for (A, B, C, D)>::cmp",
2041
- "start": 11335
2267
+ "start": 11544
2042
2268
  },
2043
2269
  {
2044
2270
  "name": "<impl Ord for (A, B, C, D, E)>::cmp",
2045
- "start": 11505
2271
+ "start": 11714
2046
2272
  },
2047
2273
  {
2048
2274
  "name": "<impl Ord for (A, B, C, D, E, F)>::cmp",
2049
- "start": 11689
2275
+ "start": 11898
2050
2276
  },
2051
2277
  {
2052
2278
  "name": "<impl Ord for (A, B, C, D, E, F, G)>::cmp",
2053
- "start": 11887
2279
+ "start": 12096
2054
2280
  },
2055
2281
  {
2056
2282
  "name": "<impl Ord for (A, B, C, D, E, F, G, H)>::cmp",
2057
- "start": 12099
2283
+ "start": 12308
2058
2284
  },
2059
2285
  {
2060
2286
  "name": "<impl Ord for (A, B, C, D, E, F, G, H, I)>::cmp",
2061
- "start": 12325
2287
+ "start": 12534
2062
2288
  },
2063
2289
  {
2064
2290
  "name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J)>::cmp",
2065
- "start": 12565
2291
+ "start": 12774
2066
2292
  },
2067
2293
  {
2068
2294
  "name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J, K)>::cmp",
2069
- "start": 12820
2295
+ "start": 13029
2070
2296
  },
2071
2297
  {
2072
2298
  "name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J, K, L)>::cmp",
2073
- "start": 13089
2299
+ "start": 13298
2074
2300
  },
2075
2301
  {
2076
2302
  "name": "max",
2077
- "start": 13451
2303
+ "start": 13660
2078
2304
  },
2079
2305
  {
2080
2306
  "name": "min",
2081
- "start": 13828
2307
+ "start": 14037
2082
2308
  },
2083
2309
  {
2084
2310
  "name": "cmp_tests::sanity_check_min",
2085
- "start": 13982
2311
+ "start": 14231
2086
2312
  },
2087
2313
  {
2088
2314
  "name": "cmp_tests::sanity_check_max",
2089
- "start": 14178
2315
+ "start": 14427
2090
2316
  },
2091
2317
  {
2092
2318
  "name": "cmp_tests::correctly_handles_unequal_length_vectors",
2093
- "start": 14400
2319
+ "start": 14649
2094
2320
  },
2095
2321
  {
2096
2322
  "name": "cmp_tests::lexicographic_ordering_for_vectors",
2097
- "start": 14600
2323
+ "start": 14849
2324
+ },
2325
+ {
2326
+ "name": "cmp_tests::eq_unit",
2327
+ "start": 15181
2328
+ },
2329
+ {
2330
+ "name": "cmp_tests::eq_bool",
2331
+ "start": 15246
2332
+ },
2333
+ {
2334
+ "name": "cmp_tests::eq_integers",
2335
+ "start": 15422
2336
+ },
2337
+ {
2338
+ "name": "cmp_tests::eq_tuples",
2339
+ "start": 16163
2340
+ },
2341
+ {
2342
+ "name": "cmp_tests::cmp_unit",
2343
+ "start": 17041
2344
+ },
2345
+ {
2346
+ "name": "cmp_tests::cmp_bool",
2347
+ "start": 17130
2348
+ },
2349
+ {
2350
+ "name": "cmp_tests::cmp_integers",
2351
+ "start": 17394
2352
+ },
2353
+ {
2354
+ "name": "cmp_tests::cmp_tuples",
2355
+ "start": 18217
2356
+ },
2357
+ {
2358
+ "name": "cmp_tests::cmp_array",
2359
+ "start": 19224
2360
+ },
2361
+ {
2362
+ "name": "cmp_tests::cmp_vectors",
2363
+ "start": 19468
2098
2364
  }
2099
2365
  ],
2100
2366
  "path": "std/cmp.nr",
2101
- "source": "use crate::meta::ctstring::AsCtString;\nuse crate::meta::derive_via;\n\n/// Compare two values for equality\n#[derive_via(derive_eq)]\n// docs:start:eq-trait\npub trait Eq {\n fn eq(self, other: Self) -> bool;\n}\n// docs:end:eq-trait\n\n// docs:start:derive_eq\ncomptime fn derive_eq(s: TypeDefinition) -> Quoted {\n let signature = quote { fn eq(_self: Self, _other: Self) -> bool };\n let for_each_field = |name| quote { (_self.$name == _other.$name) };\n let body = |fields| {\n if s.fields_as_written().len() == 0 {\n quote { true }\n } else {\n fields\n }\n };\n crate::meta::make_trait_impl(\n s,\n quote { $crate::cmp::Eq },\n signature,\n for_each_field,\n quote { & },\n body,\n )\n}\n// docs:end:derive_eq\n\nimpl Eq for Field {\n fn eq(self, other: Field) -> bool {\n self == other\n }\n}\n\nimpl Eq for u128 {\n fn eq(self, other: u128) -> bool {\n self == other\n }\n}\nimpl Eq for u64 {\n fn eq(self, other: u64) -> bool {\n self == other\n }\n}\nimpl Eq for u32 {\n fn eq(self, other: u32) -> bool {\n self == other\n }\n}\nimpl Eq for u16 {\n fn eq(self, other: u16) -> bool {\n self == other\n }\n}\nimpl Eq for u8 {\n fn eq(self, other: u8) -> bool {\n self == other\n }\n}\nimpl Eq for i8 {\n fn eq(self, other: i8) -> bool {\n self == other\n }\n}\nimpl Eq for i16 {\n fn eq(self, other: i16) -> bool {\n self == other\n }\n}\nimpl Eq for i32 {\n fn eq(self, other: i32) -> bool {\n self == other\n }\n}\nimpl Eq for i64 {\n fn eq(self, other: i64) -> bool {\n self == other\n }\n}\n\nimpl Eq for () {\n fn eq(_self: Self, _other: ()) -> bool {\n true\n }\n}\nimpl Eq for bool {\n fn eq(self, other: bool) -> bool {\n self == other\n }\n}\n\nimpl<T, let N: u32> Eq for [T; N]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T; N]) -> bool {\n let mut result = true;\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n result\n }\n}\n\nimpl<T> Eq for [T]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T]) -> bool {\n let mut result = self.len() == other.len();\n if result {\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n }\n result\n }\n}\n\nimpl<let N: u32> Eq for str<N> {\n fn eq(self, other: str<N>) -> bool {\n let self_bytes = self.as_bytes();\n let other_bytes = other.as_bytes();\n self_bytes == other_bytes\n }\n}\n\ncomptime fn make_tuple_eq_body(n: u32) -> Quoted {\n let mut body = f\"self.0.eq(other.0)\".as_ctstring();\n for i in 1u32..n {\n body = body.append_fmtstr(f\" & self.{i}.eq(other.{i})\");\n }\n f\"{body}\".quoted_contents()\n}\n\nimpl<A: Eq, B: Eq> Eq for (A, B) {\n fn eq(self, other: (A, B)) -> bool {\n make_tuple_eq_body!(2u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq> Eq for (A, B, C) {\n fn eq(self, other: (A, B, C)) -> bool {\n make_tuple_eq_body!(3u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq> Eq for (A, B, C, D) {\n fn eq(self, other: (A, B, C, D)) -> bool {\n make_tuple_eq_body!(4u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq> Eq for (A, B, C, D, E) {\n fn eq(self, other: (A, B, C, D, E)) -> bool {\n make_tuple_eq_body!(5u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq> Eq for (A, B, C, D, E, F) {\n fn eq(self, other: (A, B, C, D, E, F)) -> bool {\n make_tuple_eq_body!(6u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq> Eq for (A, B, C, D, E, F, G) {\n fn eq(self, other: (A, B, C, D, E, F, G)) -> bool {\n make_tuple_eq_body!(7u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq> Eq for (A, B, C, D, E, F, G, H) {\n fn eq(self, other: (A, B, C, D, E, F, G, H)) -> bool {\n make_tuple_eq_body!(8u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq> Eq for (A, B, C, D, E, F, G, H, I) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I)) -> bool {\n make_tuple_eq_body!(9u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq> Eq for (A, B, C, D, E, F, G, H, I, J) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J)) -> bool {\n make_tuple_eq_body!(10u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq> Eq for (A, B, C, D, E, F, G, H, I, J, K) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J, K)) -> bool {\n make_tuple_eq_body!(11u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq, L: Eq> Eq for (A, B, C, D, E, F, G, H, I, J, K, L) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J, K, L)) -> bool {\n make_tuple_eq_body!(12u32)\n }\n}\n\nimpl Eq for Ordering {\n fn eq(self, other: Ordering) -> bool {\n self.result == other.result\n }\n}\n\n// Noir doesn't have enums yet so we emulate (Lt | Eq | Gt) with a struct\n// that has 3 public functions for constructing the struct.\n/// A value with three states: `Ordering::less()`, `Ordering::equal()` or `Ordering::greater()`.\n/// Most often used to encode the result of a comparison operation.\npub struct Ordering {\n result: Field,\n}\n\nimpl Ordering {\n // Implementation note: 0, 1, and 2 for Lt, Eq, and Gt are built\n // into the compiler, do not change these without also updating\n // the compiler itself!\n pub fn less() -> Ordering {\n Ordering { result: 0 }\n }\n\n pub fn equal() -> Ordering {\n Ordering { result: 1 }\n }\n\n pub fn greater() -> Ordering {\n Ordering { result: 2 }\n }\n}\n\n/// Compare one object to another, returning whether it is less-than, equal-to,\n/// or greater-than the other object.\n#[derive_via(derive_ord)]\n// docs:start:ord-trait\npub trait Ord {\n fn cmp(self, other: Self) -> Ordering;\n}\n// docs:end:ord-trait\n\n// docs:start:derive_ord\ncomptime fn derive_ord(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::cmp::Ord };\n let signature = quote { fn cmp(_self: Self, _other: Self) -> $crate::cmp::Ordering };\n let for_each_field = |name| quote {\n if result == $crate::cmp::Ordering::equal() {\n result = _self.$name.cmp(_other.$name);\n }\n };\n let body = |fields| quote {\n let mut result = $crate::cmp::Ordering::equal();\n $fields\n result\n };\n crate::meta::make_trait_impl(s, name, signature, for_each_field, quote {}, body)\n}\n// docs:end:derive_ord\n\n// Note: Field deliberately does not implement Ord\n\nimpl Ord for u128 {\n fn cmp(self, other: u128) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\nimpl Ord for u64 {\n fn cmp(self, other: u64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u32 {\n fn cmp(self, other: u32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u16 {\n fn cmp(self, other: u16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u8 {\n fn cmp(self, other: u8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i8 {\n fn cmp(self, other: i8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i16 {\n fn cmp(self, other: i16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i32 {\n fn cmp(self, other: i32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i64 {\n fn cmp(self, other: i64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for () {\n fn cmp(_self: Self, _other: ()) -> Ordering {\n Ordering::equal()\n }\n}\n\nimpl Ord for bool {\n fn cmp(self, other: bool) -> Ordering {\n if self {\n if other {\n Ordering::equal()\n } else {\n Ordering::greater()\n }\n } else if other {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl<T, let N: u32> Ord for [T; N]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T; N]) -> Ordering {\n let mut result = Ordering::equal();\n for i in 0..self.len() {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n result\n }\n}\n\nimpl<T> Ord for [T]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T]) -> Ordering {\n let self_len = self.len();\n let other_len = other.len();\n let min_len = if self_len < other_len {\n self_len\n } else {\n other_len\n };\n\n let mut result = Ordering::equal();\n for i in 0..min_len {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n\n if result != Ordering::equal() {\n result\n } else {\n self_len.cmp(other_len)\n }\n }\n}\n\ncomptime fn make_tuple_ord_body(n: u32) -> Quoted {\n let last = n - 1u32;\n let mut body = if last == 1 {\n f\"let result = self.0.cmp(other.0);\".as_ctstring()\n } else {\n f\"let mut result = self.0.cmp(other.0);\".as_ctstring()\n };\n for i in 1u32..last {\n body = body.append_fmtstr(\n f\" if result == Ordering::equal() {{ result = self.{i}.cmp(other.{i}); }}\",\n );\n }\n body = body.append_fmtstr(\n f\" if result != Ordering::equal() {{ result }} else {{ self.{last}.cmp(other.{last}) }}\",\n );\n f\"{body}\".quoted_contents()\n}\n\nimpl<A: Ord, B: Ord> Ord for (A, B) {\n fn cmp(self, other: (A, B)) -> Ordering {\n make_tuple_ord_body!(2u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord> Ord for (A, B, C) {\n fn cmp(self, other: (A, B, C)) -> Ordering {\n make_tuple_ord_body!(3u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord> Ord for (A, B, C, D) {\n fn cmp(self, other: (A, B, C, D)) -> Ordering {\n make_tuple_ord_body!(4u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord> Ord for (A, B, C, D, E) {\n fn cmp(self, other: (A, B, C, D, E)) -> Ordering {\n make_tuple_ord_body!(5u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord> Ord for (A, B, C, D, E, F) {\n fn cmp(self, other: (A, B, C, D, E, F)) -> Ordering {\n make_tuple_ord_body!(6u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord> Ord for (A, B, C, D, E, F, G) {\n fn cmp(self, other: (A, B, C, D, E, F, G)) -> Ordering {\n make_tuple_ord_body!(7u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord> Ord for (A, B, C, D, E, F, G, H) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H)) -> Ordering {\n make_tuple_ord_body!(8u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord> Ord for (A, B, C, D, E, F, G, H, I) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I)) -> Ordering {\n make_tuple_ord_body!(9u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord> Ord for (A, B, C, D, E, F, G, H, I, J) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J)) -> Ordering {\n make_tuple_ord_body!(10u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord, K: Ord> Ord for (A, B, C, D, E, F, G, H, I, J, K) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J, K)) -> Ordering {\n make_tuple_ord_body!(11u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord, K: Ord, L: Ord> Ord for (A, B, C, D, E, F, G, H, I, J, K, L) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J, K, L)) -> Ordering {\n make_tuple_ord_body!(12u32)\n }\n}\n\n/// Compares and returns the maximum of two values.\n///\n/// Returns the second argument if the comparison determines them to be equal.\n///\n/// # Examples\n///\n/// ```\n/// use std::cmp;\n///\n/// assert_eq(cmp::max(1, 2), 2);\n/// assert_eq(cmp::max(2, 2), 2);\n/// ```\npub fn max<T>(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v1\n } else {\n v2\n }\n}\n\n/// Compares and returns the minimum of two values.\n///\n/// Returns the first argument if the comparison determines them to be equal.\n///\n/// # Examples\n///\n/// ```\n/// use std::cmp;\n///\n/// assert_eq(cmp::min(1, 2), 1);\n/// assert_eq(cmp::min(2, 2), 2);\n/// ```\npub fn min<T>(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v2\n } else {\n v1\n }\n}\n\nmod cmp_tests {\n use super::{Eq, max, min, Ord};\n\n #[test]\n fn sanity_check_min() {\n assert_eq(min(0_u64, 1), 0);\n assert_eq(min(0_u64, 0), 0);\n assert_eq(min(1_u64, 1), 1);\n assert_eq(min(255_u8, 0), 0);\n }\n\n #[test]\n fn sanity_check_max() {\n assert_eq(max(0_u64, 1), 1);\n assert_eq(max(0_u64, 0), 0);\n assert_eq(max(1_u64, 1), 1);\n assert_eq(max(255_u8, 0), 255);\n }\n\n #[test]\n fn correctly_handles_unequal_length_vectors() {\n let vector_1 = [0, 1, 2, 3].as_vector();\n let vector_2 = [0, 1, 2].as_vector();\n assert(!vector_1.eq(vector_2));\n }\n\n #[test]\n fn lexicographic_ordering_for_vectors() {\n assert(\n [2_u32].as_vector().cmp([1_u32, 1_u32, 1_u32].as_vector())\n == super::Ordering::greater(),\n );\n assert(\n [1_u32, 2_u32].as_vector().cmp([1_u32, 2_u32, 3_u32].as_vector())\n == super::Ordering::less(),\n );\n }\n}\n"
2367
+ "source": "use crate::meta::ctstring::AsCtString;\nuse crate::meta::derive_via;\n\n/// Compare two values for equality\n#[derive_via(derive_eq)]\n// docs:start:eq-trait\npub trait Eq {\n fn eq(self, other: Self) -> bool;\n}\n// docs:end:eq-trait\n\n// docs:start:derive_eq\ncomptime fn derive_eq(s: TypeDefinition) -> Quoted {\n let signature = quote { fn eq(_self: Self, _other: Self) -> bool };\n let for_each_field = |name| quote { (_self.$name == _other.$name) };\n let body = |fields| {\n if s.fields_as_written().len() == 0 {\n quote { true }\n } else {\n fields\n }\n };\n crate::meta::make_trait_impl(\n s,\n quote { $crate::cmp::Eq },\n signature,\n for_each_field,\n quote { & },\n body,\n )\n}\n// docs:end:derive_eq\n\nimpl Eq for Field {\n fn eq(self, other: Field) -> bool {\n self == other\n }\n}\n\nimpl Eq for u128 {\n fn eq(self, other: u128) -> bool {\n self == other\n }\n}\nimpl Eq for u64 {\n fn eq(self, other: u64) -> bool {\n self == other\n }\n}\nimpl Eq for u32 {\n fn eq(self, other: u32) -> bool {\n self == other\n }\n}\nimpl Eq for u16 {\n fn eq(self, other: u16) -> bool {\n self == other\n }\n}\nimpl Eq for u8 {\n fn eq(self, other: u8) -> bool {\n self == other\n }\n}\nimpl Eq for i8 {\n fn eq(self, other: i8) -> bool {\n self == other\n }\n}\nimpl Eq for i16 {\n fn eq(self, other: i16) -> bool {\n self == other\n }\n}\nimpl Eq for i32 {\n fn eq(self, other: i32) -> bool {\n self == other\n }\n}\nimpl Eq for i64 {\n fn eq(self, other: i64) -> bool {\n self == other\n }\n}\n\nimpl Eq for () {\n fn eq(_self: Self, _other: ()) -> bool {\n true\n }\n}\nimpl Eq for bool {\n fn eq(self, other: bool) -> bool {\n self == other\n }\n}\n\nimpl<T, let N: u32> Eq for [T; N]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T; N]) -> bool {\n let mut result = true;\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n result\n }\n}\n\nimpl<T> Eq for [T]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T]) -> bool {\n let mut result = self.len() == other.len();\n if result {\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n }\n result\n }\n}\n\nimpl<let N: u32> Eq for str<N> {\n fn eq(self, other: str<N>) -> bool {\n let self_bytes = self.as_bytes();\n let other_bytes = other.as_bytes();\n self_bytes == other_bytes\n }\n}\n\ncomptime fn make_tuple_eq_body(n: u32) -> Quoted {\n let mut body = f\"self.0.eq(other.0)\".as_ctstring();\n for i in 1u32..n {\n body = body.append_fmtstr(f\" & self.{i}.eq(other.{i})\");\n }\n f\"{body}\".quoted_contents()\n}\n\nimpl<A: Eq> Eq for (A,) {\n fn eq(self, other: (A,)) -> bool {\n self.0 == other.0\n }\n}\n\nimpl<A: Eq, B: Eq> Eq for (A, B) {\n fn eq(self, other: (A, B)) -> bool {\n make_tuple_eq_body!(2u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq> Eq for (A, B, C) {\n fn eq(self, other: (A, B, C)) -> bool {\n make_tuple_eq_body!(3u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq> Eq for (A, B, C, D) {\n fn eq(self, other: (A, B, C, D)) -> bool {\n make_tuple_eq_body!(4u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq> Eq for (A, B, C, D, E) {\n fn eq(self, other: (A, B, C, D, E)) -> bool {\n make_tuple_eq_body!(5u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq> Eq for (A, B, C, D, E, F) {\n fn eq(self, other: (A, B, C, D, E, F)) -> bool {\n make_tuple_eq_body!(6u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq> Eq for (A, B, C, D, E, F, G) {\n fn eq(self, other: (A, B, C, D, E, F, G)) -> bool {\n make_tuple_eq_body!(7u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq> Eq for (A, B, C, D, E, F, G, H) {\n fn eq(self, other: (A, B, C, D, E, F, G, H)) -> bool {\n make_tuple_eq_body!(8u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq> Eq for (A, B, C, D, E, F, G, H, I) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I)) -> bool {\n make_tuple_eq_body!(9u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq> Eq for (A, B, C, D, E, F, G, H, I, J) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J)) -> bool {\n make_tuple_eq_body!(10u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq> Eq for (A, B, C, D, E, F, G, H, I, J, K) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J, K)) -> bool {\n make_tuple_eq_body!(11u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq, L: Eq> Eq for (A, B, C, D, E, F, G, H, I, J, K, L) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J, K, L)) -> bool {\n make_tuple_eq_body!(12u32)\n }\n}\n\nimpl Eq for Ordering {\n fn eq(self, other: Ordering) -> bool {\n self.result == other.result\n }\n}\n\n// Noir doesn't have enums yet so we emulate (Lt | Eq | Gt) with a struct\n// that has 3 public functions for constructing the struct.\n/// A value with three states: `Ordering::less()`, `Ordering::equal()` or `Ordering::greater()`.\n/// Most often used to encode the result of a comparison operation.\npub struct Ordering {\n result: Field,\n}\n\nimpl Ordering {\n // Implementation note: 0, 1, and 2 for Lt, Eq, and Gt are built\n // into the compiler, do not change these without also updating\n // the compiler itself!\n pub fn less() -> Ordering {\n Ordering { result: 0 }\n }\n\n pub fn equal() -> Ordering {\n Ordering { result: 1 }\n }\n\n pub fn greater() -> Ordering {\n Ordering { result: 2 }\n }\n}\n\n/// Compare one object to another, returning whether it is less-than, equal-to,\n/// or greater-than the other object.\n#[derive_via(derive_ord)]\n// docs:start:ord-trait\npub trait Ord {\n fn cmp(self, other: Self) -> Ordering;\n}\n// docs:end:ord-trait\n\n// docs:start:derive_ord\ncomptime fn derive_ord(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::cmp::Ord };\n let signature = quote { fn cmp(_self: Self, _other: Self) -> $crate::cmp::Ordering };\n let for_each_field = |name| quote {\n if result == $crate::cmp::Ordering::equal() {\n result = _self.$name.cmp(_other.$name);\n }\n };\n let body = |fields| quote {\n let mut result = $crate::cmp::Ordering::equal();\n $fields\n result\n };\n crate::meta::make_trait_impl(s, name, signature, for_each_field, quote {}, body)\n}\n// docs:end:derive_ord\n\n// Note: Field deliberately does not implement Ord\n\nimpl Ord for u128 {\n fn cmp(self, other: u128) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\nimpl Ord for u64 {\n fn cmp(self, other: u64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u32 {\n fn cmp(self, other: u32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u16 {\n fn cmp(self, other: u16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u8 {\n fn cmp(self, other: u8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i8 {\n fn cmp(self, other: i8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i16 {\n fn cmp(self, other: i16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i32 {\n fn cmp(self, other: i32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i64 {\n fn cmp(self, other: i64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for () {\n fn cmp(_self: Self, _other: ()) -> Ordering {\n Ordering::equal()\n }\n}\n\nimpl Ord for bool {\n fn cmp(self, other: bool) -> Ordering {\n if self {\n if other {\n Ordering::equal()\n } else {\n Ordering::greater()\n }\n } else if other {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl<T, let N: u32> Ord for [T; N]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T; N]) -> Ordering {\n let mut result = Ordering::equal();\n for i in 0..self.len() {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n result\n }\n}\n\nimpl<T> Ord for [T]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T]) -> Ordering {\n let self_len = self.len();\n let other_len = other.len();\n let min_len = if self_len < other_len {\n self_len\n } else {\n other_len\n };\n\n let mut result = Ordering::equal();\n for i in 0..min_len {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n\n if result != Ordering::equal() {\n result\n } else {\n self_len.cmp(other_len)\n }\n }\n}\n\ncomptime fn make_tuple_ord_body(n: u32) -> Quoted {\n let last = n - 1u32;\n let mut body = if last == 1 {\n f\"let result = self.0.cmp(other.0);\".as_ctstring()\n } else {\n f\"let mut result = self.0.cmp(other.0);\".as_ctstring()\n };\n for i in 1u32..last {\n body = body.append_fmtstr(\n f\" if result == Ordering::equal() {{ result = self.{i}.cmp(other.{i}); }}\",\n );\n }\n body = body.append_fmtstr(\n f\" if result != Ordering::equal() {{ result }} else {{ self.{last}.cmp(other.{last}) }}\",\n );\n f\"{body}\".quoted_contents()\n}\n\nimpl<A: Ord> Ord for (A,) {\n fn cmp(self, other: (A,)) -> Ordering {\n self.0.cmp(other.0)\n }\n}\n\nimpl<A: Ord, B: Ord> Ord for (A, B) {\n fn cmp(self, other: (A, B)) -> Ordering {\n make_tuple_ord_body!(2u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord> Ord for (A, B, C) {\n fn cmp(self, other: (A, B, C)) -> Ordering {\n make_tuple_ord_body!(3u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord> Ord for (A, B, C, D) {\n fn cmp(self, other: (A, B, C, D)) -> Ordering {\n make_tuple_ord_body!(4u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord> Ord for (A, B, C, D, E) {\n fn cmp(self, other: (A, B, C, D, E)) -> Ordering {\n make_tuple_ord_body!(5u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord> Ord for (A, B, C, D, E, F) {\n fn cmp(self, other: (A, B, C, D, E, F)) -> Ordering {\n make_tuple_ord_body!(6u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord> Ord for (A, B, C, D, E, F, G) {\n fn cmp(self, other: (A, B, C, D, E, F, G)) -> Ordering {\n make_tuple_ord_body!(7u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord> Ord for (A, B, C, D, E, F, G, H) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H)) -> Ordering {\n make_tuple_ord_body!(8u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord> Ord for (A, B, C, D, E, F, G, H, I) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I)) -> Ordering {\n make_tuple_ord_body!(9u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord> Ord for (A, B, C, D, E, F, G, H, I, J) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J)) -> Ordering {\n make_tuple_ord_body!(10u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord, K: Ord> Ord for (A, B, C, D, E, F, G, H, I, J, K) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J, K)) -> Ordering {\n make_tuple_ord_body!(11u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord, K: Ord, L: Ord> Ord for (A, B, C, D, E, F, G, H, I, J, K, L) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J, K, L)) -> Ordering {\n make_tuple_ord_body!(12u32)\n }\n}\n\n/// Compares and returns the maximum of two values.\n///\n/// Returns the second argument if the comparison determines them to be equal.\n///\n/// # Examples\n///\n/// ```\n/// use std::cmp;\n///\n/// assert_eq(cmp::max(1, 2), 2);\n/// assert_eq(cmp::max(2, 2), 2);\n/// ```\npub fn max<T>(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v1\n } else {\n v2\n }\n}\n\n/// Compares and returns the minimum of two values.\n///\n/// Returns the first argument if the comparison determines them to be equal.\n///\n/// # Examples\n///\n/// ```\n/// use std::cmp;\n///\n/// assert_eq(cmp::min(1, 2), 1);\n/// assert_eq(cmp::min(2, 2), 2);\n/// ```\npub fn min<T>(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v2\n } else {\n v1\n }\n}\n\nmod cmp_tests {\n use crate::meta::unquote;\n use super::{Eq, max, min, Ord, Ordering};\n\n #[test]\n fn sanity_check_min() {\n assert_eq(min(0_u64, 1), 0);\n assert_eq(min(0_u64, 0), 0);\n assert_eq(min(1_u64, 1), 1);\n assert_eq(min(255_u8, 0), 0);\n }\n\n #[test]\n fn sanity_check_max() {\n assert_eq(max(0_u64, 1), 1);\n assert_eq(max(0_u64, 0), 0);\n assert_eq(max(1_u64, 1), 1);\n assert_eq(max(255_u8, 0), 255);\n }\n\n #[test]\n fn correctly_handles_unequal_length_vectors() {\n let vector_1 = [0, 1, 2, 3].as_vector();\n let vector_2 = [0, 1, 2].as_vector();\n assert(!vector_1.eq(vector_2));\n }\n\n #[test]\n fn lexicographic_ordering_for_vectors() {\n assert(\n [2_u32].as_vector().cmp([1_u32, 1_u32, 1_u32].as_vector())\n == super::Ordering::greater(),\n );\n assert(\n [1_u32, 2_u32].as_vector().cmp([1_u32, 2_u32, 3_u32].as_vector())\n == super::Ordering::less(),\n );\n }\n\n #[test]\n fn eq_unit() {\n assert(().eq(()));\n }\n\n #[test]\n fn eq_bool() {\n assert(false.eq(false));\n assert(!(false.eq(true)));\n assert(!(true.eq(false)));\n assert(true.eq(true));\n }\n\n #[test]\n fn eq_integers() {\n comptime {\n for typ in @[\n quote { u8 },\n quote { i8 },\n quote { u16 },\n quote { i16 },\n quote { u32 },\n quote { i32 },\n quote { u64 },\n quote { i64 },\n quote { u128 },\n quote { Field },\n ] {\n let one = f\"1_{typ}\".quoted_contents();\n let two = f\"2_{typ}\".quoted_contents();\n unquote!(\n quote {\n assert($one.eq($one));\n assert(!($one.eq($two)));\n },\n );\n }\n }\n }\n\n #[test]\n fn eq_tuples() {\n comptime {\n for i in 1..=12 {\n let mut tuple1 = @[];\n let mut tuple2 = @[];\n for _ in 0..i - 1 {\n tuple1 = tuple1.push_back(quote { 0 });\n tuple2 = tuple2.push_back(quote { 0 });\n }\n tuple1 = tuple1.push_back(quote { 0 });\n tuple2 = tuple2.push_back(quote { 1 });\n let tuple1 = tuple1.join(quote { , });\n let tuple2 = tuple2.join(quote { , });\n let tuple1 = quote { ($tuple1,) };\n let tuple2 = quote { ($tuple2,) };\n unquote!(\n quote {\n assert($tuple1.eq($tuple1));\n assert(!($tuple1.eq($tuple2)));\n },\n )\n }\n }\n }\n\n #[test]\n fn cmp_unit() {\n assert_eq(().cmp(()), Ordering::equal());\n }\n\n #[test]\n fn cmp_bool() {\n assert_eq(false.cmp(true), Ordering::less());\n assert_eq(false.cmp(false), Ordering::equal());\n assert_eq(true.cmp(true), Ordering::equal());\n assert_eq(true.cmp(false), Ordering::greater());\n }\n\n #[test]\n fn cmp_integers() {\n comptime {\n for typ in @[\n quote { u8 },\n quote { i8 },\n quote { u16 },\n quote { i16 },\n quote { u32 },\n quote { i32 },\n quote { u64 },\n quote { i64 },\n quote { u128 },\n ] {\n let one = f\"1_{typ}\".quoted_contents();\n let two = f\"2_{typ}\".quoted_contents();\n unquote!(\n quote {\n assert_eq($one.cmp($two), Ordering::less());\n assert_eq($one.cmp($one), Ordering::equal());\n assert_eq($two.cmp($one), Ordering::greater());\n },\n );\n }\n }\n }\n\n #[test]\n fn cmp_tuples() {\n comptime {\n for i in 1..=12 {\n let mut tuple1 = @[];\n let mut tuple2 = @[];\n for _ in 0..i - 1 {\n tuple1 = tuple1.push_back(quote { 0_u8 });\n tuple2 = tuple2.push_back(quote { 0_u8 });\n }\n tuple1 = tuple1.push_back(quote { 0_u8 });\n tuple2 = tuple2.push_back(quote { 1_u8 });\n let tuple1 = tuple1.join(quote { , });\n let tuple2 = tuple2.join(quote { , });\n let tuple1 = quote { ($tuple1,) };\n let tuple2 = quote { ($tuple2,) };\n unquote!(\n quote {\n assert_eq($tuple1.cmp($tuple1), Ordering::equal());\n assert_eq($tuple1.cmp($tuple2), Ordering::less());\n assert_eq($tuple2.cmp($tuple1), Ordering::greater());\n },\n )\n }\n }\n }\n\n #[test]\n fn cmp_array() {\n assert_eq([1_u8, 2, 3].cmp([1, 2, 3]), Ordering::equal());\n assert_eq([1_u8, 2, 3].cmp([1, 3, 2]), Ordering::less());\n assert_eq([1_u8, 3, 3].cmp([1, 2, 3]), Ordering::greater());\n }\n\n #[test]\n fn cmp_vectors() {\n // Equal lengths\n assert_eq(@[1_u8, 2, 3].cmp(@[1, 2, 3]), Ordering::equal());\n assert_eq(@[1_u8, 3, 3].cmp(@[1, 2, 3]), Ordering::greater());\n assert_eq(@[1_u8, 2, 3].cmp(@[1, 3, 3]), Ordering::less());\n\n // Different lengths\n assert_eq(@[1_u8, 2].cmp(@[1, 2, 3]), Ordering::less());\n assert_eq(@[1_u8, 2, 3].cmp(@[1, 2]), Ordering::greater());\n assert_eq(@[10_u8, 0].cmp(@[9]), Ordering::greater());\n assert_eq(@[9_u8, 0].cmp(@[10]), Ordering::less());\n assert_eq(@[9_u8].cmp(@[10, 0]), Ordering::less());\n assert_eq(@[10_u8].cmp(@[9, 0]), Ordering::greater());\n }\n}\n"
2102
2368
  },
2103
- "50": {
2369
+ "51": {
2370
+ "function_locations": [
2371
+ {
2372
+ "name": "calculate_fee",
2373
+ "start": 232
2374
+ },
2375
+ {
2376
+ "name": "get_bridge_gas_msg_hash",
2377
+ "start": 747
2378
+ }
2379
+ ],
2380
+ "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/fee_juice_contract/src/lib.nr",
2381
+ "source": "use aztec::context::PublicContext;\nuse aztec::protocol::address::AztecAddress;\nuse aztec::protocol::hash::sha256_to_field;\nuse aztec::protocol::traits::ToField;\n\npub fn calculate_fee<TPublicContext>(context: PublicContext) -> Field {\n context.transaction_fee()\n}\n\n/// Computes the content hash for an L1-to-L2 \"bridge gas\" message, matching the hash produced on L1 by\n/// `FeeJuicePortal.depositToAztecPublic`: `sha256ToField(abi.encodeWithSignature(\"claim(bytes32,uint256)\", to,\n/// amount))`.\n///\n/// The 68-byte buffer is: [4-byte selector of \"claim(bytes32,uint256)\"][32-byte recipient][32-byte amount], hashed\n/// with `sha256_to_field` to produce a single Field.\npub fn get_bridge_gas_msg_hash(owner: AztecAddress, amount: u128) -> Field {\n let mut hash_bytes = [0; 68];\n let recipient_bytes: [u8; 32] = owner.to_field().to_be_bytes();\n let amount_bytes: [u8; 32] = (amount as Field).to_be_bytes();\n\n // The purpose of including the following selector is to make the message unique to that specific call. Note that\n // it has nothing to do with calling the function.\n let selector = comptime { keccak256::keccak256(\"claim(bytes32,uint256)\".as_bytes(), 22) };\n\n for i in 0..4 {\n hash_bytes[i] = selector[i];\n }\n\n for i in 0..32 {\n hash_bytes[i + 4] = recipient_bytes[i];\n hash_bytes[i + 36] = amount_bytes[i];\n }\n\n let content_hash = sha256_to_field(hash_bytes);\n content_hash\n}\n"
2382
+ },
2383
+ "52": {
2104
2384
  "function_locations": [
2105
2385
  {
2106
2386
  "name": "FeeJuice::claim_helper",
@@ -2186,59 +2466,59 @@
2186
2466
  },
2187
2467
  {
2188
2468
  "name": "PrivateContext::end_setup",
2189
- "start": 8177
2469
+ "start": 8235
2190
2470
  },
2191
2471
  {
2192
2472
  "name": "PrivateContext::in_revertible_phase",
2193
- "start": 8426
2473
+ "start": 8484
2194
2474
  },
2195
2475
  {
2196
2476
  "name": "PrivateContext::set_expiration_timestamp",
2197
- "start": 9311
2477
+ "start": 9369
2198
2478
  },
2199
2479
  {
2200
2480
  "name": "PrivateContext::push_nullifier",
2201
- "start": 9553
2481
+ "start": 9611
2202
2482
  },
2203
2483
  {
2204
2484
  "name": "PrivateContext::assert_nullifier_exists",
2205
- "start": 9913
2485
+ "start": 9971
2206
2486
  },
2207
2487
  {
2208
2488
  "name": "PrivateContext::consume_l1_to_l2_message",
2209
- "start": 10553
2489
+ "start": 10611
2210
2490
  },
2211
2491
  {
2212
2492
  "name": "PrivateContext::emit_private_log",
2213
- "start": 11145
2493
+ "start": 11203
2214
2494
  },
2215
2495
  {
2216
2496
  "name": "PrivateContext::emit_contract_class_log",
2217
- "start": 11507
2497
+ "start": 11565
2218
2498
  },
2219
2499
  {
2220
2500
  "name": "PrivateContext::static_call_private_function",
2221
- "start": 13005
2501
+ "start": 13063
2222
2502
  },
2223
2503
  {
2224
2504
  "name": "PrivateContext::call_private_function_with_args_hash",
2225
- "start": 13493
2505
+ "start": 13551
2226
2506
  },
2227
2507
  {
2228
2508
  "name": "PrivateContext::call_public_function_with_calldata_hash",
2229
- "start": 14997
2509
+ "start": 15055
2230
2510
  },
2231
2511
  {
2232
2512
  "name": "PrivateContext::next_counter",
2233
- "start": 15578
2513
+ "start": 15636
2234
2514
  },
2235
2515
  {
2236
2516
  "name": "<impl Empty for PrivateContext>::empty",
2237
- "start": 15747
2517
+ "start": 15805
2238
2518
  }
2239
2519
  ],
2240
2520
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/context/private_context.nr",
2241
- "source": "use crate::{\n context::{inputs::PrivateContextInputs, NullifierExistenceRequest, ReturnsHash},\n hash::hash_args,\n messaging::process_l1_to_l2_message,\n oracle::{\n call_private_function::call_private_function_internal,\n public_call::validate_public_calldata,\n tx_phase::{in_revertible_phase, notify_revertible_phase_start},\n execution_cache,\n logs::notify_created_contract_class_log,\n nullifiers::notify_created_nullifier,\n },\n};\nuse crate::protocol::{\n abis::{\n block_header::BlockHeader,\n call_context::CallContext,\n function_selector::FunctionSelector,\n gas_settings::GasSettings,\n log_hash::LogHash,\n nullifier::Nullifier,\n private_call_request::PrivateCallRequest,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n private_log::{PrivateLog, PrivateLogData},\n public_call_request::PublicCallRequest,\n },\n address::{AztecAddress, EthAddress},\n constants::{\n CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, MAX_CONTRACT_CLASS_LOGS_PER_CALL,\n MAX_ENQUEUED_CALLS_PER_CALL, MAX_TX_LIFETIME, MAX_L2_TO_L1_MSGS_PER_CALL,\n MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL,\n NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_SIZE_IN_FIELDS,\n },\n hash::poseidon2_hash,\n messaging::l2_to_l1_message::L2ToL1Message,\n side_effect::{Counted, scoped::Scoped},\n traits::Empty,\n utils::arrays::{ClaimedLengthArray, trimmed_array_length_hint},\n};\n\n/// Minimal PrivateContext for protocol contracts going to audit.\n/// Contains only the methods actually used by: fee_juice, auth_registry, contract_class_registry, contract_instance_registry\n#[derive(Eq)]\npub struct PrivateContext {\n pub inputs: PrivateContextInputs,\n pub side_effect_counter: u32,\n\n pub min_revertible_side_effect_counter: u32,\n pub is_fee_payer: bool,\n\n pub args_hash: Field,\n pub return_hash: Field,\n\n pub expiration_timestamp: u64,\n\n pub nullifier_read_requests: BoundedVec<Scoped<Counted<Field>>, MAX_NULLIFIER_READ_REQUESTS_PER_CALL>,\n\n pub nullifiers: BoundedVec<Counted<Nullifier>, MAX_NULLIFIERS_PER_CALL>,\n\n pub private_call_requests: BoundedVec<PrivateCallRequest, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL>,\n pub public_call_requests: BoundedVec<Counted<PublicCallRequest>, MAX_ENQUEUED_CALLS_PER_CALL>,\n pub public_teardown_call_request: PublicCallRequest,\n pub l2_to_l1_msgs: BoundedVec<Counted<L2ToL1Message>, MAX_L2_TO_L1_MSGS_PER_CALL>,\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n pub anchor_block_header: BlockHeader,\n\n pub private_logs: BoundedVec<Counted<PrivateLogData>, MAX_PRIVATE_LOGS_PER_CALL>,\n pub contract_class_logs_hashes: BoundedVec<Counted<LogHash>, MAX_CONTRACT_CLASS_LOGS_PER_CALL>,\n\n pub expected_non_revertible_side_effect_counter: u32,\n pub expected_revertible_side_effect_counter: u32,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.start_side_effect_counter + 1,\n min_revertible_side_effect_counter: 0,\n is_fee_payer: false,\n args_hash,\n return_hash: 0,\n expiration_timestamp: inputs.anchor_block_header.global_variables.timestamp\n + MAX_TX_LIFETIME,\n nullifier_read_requests: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n anchor_block_header: inputs.anchor_block_header,\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n\n /// Returns the contract address that initiated this function call (similar to msg.sender in Solidity).\n pub fn maybe_msg_sender(self) -> Option<AztecAddress> {\n let maybe_msg_sender = self.inputs.call_context.msg_sender;\n if maybe_msg_sender == NULL_MSG_SENDER_CONTRACT_ADDRESS {\n Option::none()\n } else {\n Option::some(maybe_msg_sender)\n }\n }\n\n /// Returns the contract address of the current function being executed.\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.contract_address\n }\n\n /// Returns the chain ID of the current network.\n pub fn chain_id(self) -> Field {\n self.inputs.tx_context.chain_id\n }\n\n /// Returns the protocol version.\n pub fn version(self) -> Field {\n self.inputs.tx_context.version\n }\n\n /// Returns the gas settings for the current transaction.\n pub fn gas_settings(self) -> GasSettings {\n self.inputs.tx_context.gas_settings\n }\n\n /// Returns the function selector of the currently executing function.\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n /// Returns the hash of the arguments passed to the current function.\n pub fn get_args_hash(self) -> Field {\n self.args_hash\n }\n\n /// Returns the anchor block header.\n pub fn get_anchor_block_header(self) -> BlockHeader {\n self.anchor_block_header\n }\n\n /// Sets the hash of the return values for this private function.\n pub fn set_return_hash<let N: u32>(&mut self, serialized_return_values: [Field; N]) {\n let return_hash = hash_args(serialized_return_values);\n self.return_hash = return_hash;\n execution_cache::store(serialized_return_values, return_hash);\n }\n\n /// Builds the PrivateCircuitPublicInputs for this private function.\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n returns_hash: self.return_hash,\n min_revertible_side_effect_counter: self.min_revertible_side_effect_counter,\n is_fee_payer: self.is_fee_payer,\n expiration_timestamp: self.expiration_timestamp,\n note_hash_read_requests: ClaimedLengthArray::empty(), // Not used by protocol contracts\n nullifier_read_requests: ClaimedLengthArray::from_bounded_vec(\n self.nullifier_read_requests,\n ),\n key_validation_requests_and_separators: ClaimedLengthArray::empty(), // Not used by protocol contracts\n note_hashes: ClaimedLengthArray::empty(), // Not used by protocol contracts\n nullifiers: ClaimedLengthArray::from_bounded_vec(self.nullifiers),\n private_call_requests: ClaimedLengthArray::from_bounded_vec(self.private_call_requests),\n public_call_requests: ClaimedLengthArray::from_bounded_vec(self.public_call_requests),\n public_teardown_call_request: self.public_teardown_call_request,\n l2_to_l1_msgs: ClaimedLengthArray::from_bounded_vec(self.l2_to_l1_msgs),\n start_side_effect_counter: self.inputs.start_side_effect_counter,\n end_side_effect_counter: self.side_effect_counter,\n private_logs: ClaimedLengthArray::from_bounded_vec(self.private_logs),\n contract_class_logs_hashes: ClaimedLengthArray::from_bounded_vec(\n self.contract_class_logs_hashes,\n ),\n anchor_block_header: self.anchor_block_header,\n tx_context: self.inputs.tx_context,\n expected_non_revertible_side_effect_counter: self\n .expected_non_revertible_side_effect_counter,\n expected_revertible_side_effect_counter: self.expected_revertible_side_effect_counter,\n }\n }\n\n /// Declares the end of the \"setup phase\" of this tx. Used by fee_juice.\n pub fn end_setup(&mut self) {\n self.side_effect_counter += 1;\n self.min_revertible_side_effect_counter = self.next_counter();\n notify_revertible_phase_start(self.min_revertible_side_effect_counter);\n }\n\n pub fn in_revertible_phase(&mut self) -> bool {\n let current_counter = self.side_effect_counter;\n\n // Safety: Kernel will validate that the claim is correct by validating the expected counters.\n let is_revertible =\n unsafe { in_revertible_phase(current_counter) };\n\n if is_revertible {\n if (self.expected_revertible_side_effect_counter == 0)\n | (current_counter < self.expected_revertible_side_effect_counter) {\n self.expected_revertible_side_effect_counter = current_counter;\n }\n } else if current_counter > self.expected_non_revertible_side_effect_counter {\n self.expected_non_revertible_side_effect_counter = current_counter;\n }\n\n is_revertible\n }\n\n /// Sets a deadline for when this transaction must be included in a block.\n pub fn set_expiration_timestamp(&mut self, expiration_timestamp: u64) {\n self.expiration_timestamp = std::cmp::min(self.expiration_timestamp, expiration_timestamp);\n }\n\n /// Pushes a new nullifier. Used by class_registry and instance_registry.\n pub fn push_nullifier(&mut self, nullifier: Field) {\n notify_created_nullifier(nullifier);\n self.nullifiers.push(Nullifier { value: nullifier, note_hash: 0 }.count(self.next_counter()));\n }\n\n /// Asserts that a nullifier has been emitted. Used by instance_registry.\n pub fn assert_nullifier_exists(\n &mut self,\n nullifier_existence_request: NullifierExistenceRequest,\n ) {\n let nullifier = nullifier_existence_request.nullifier();\n let contract_address =\n nullifier_existence_request.maybe_contract_address().unwrap_or(AztecAddress::zero());\n\n let request = Scoped::new(\n Counted::new(nullifier, self.next_counter()),\n contract_address,\n );\n\n self.nullifier_read_requests.push(request);\n }\n\n /// Consumes a message sent from Ethereum (L1) to Aztec (L2). Used by fee_juice.\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let nullifier = process_l1_to_l2_message(\n self.anchor_block_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n sender,\n self.chain_id(),\n self.version(),\n content,\n secret,\n leaf_index,\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_nullifier(nullifier)\n }\n\n /// Emits a private log. Used by instance_registry.\n pub fn emit_private_log(&mut self, log: [Field; PRIVATE_LOG_SIZE_IN_FIELDS], length: u32) {\n let counter = self.next_counter();\n let private_log = PrivateLogData { log: PrivateLog::new(log, length), note_hash_counter: 0 }\n .count(counter);\n self.private_logs.push(private_log);\n }\n\n /// Emits a contract class log. Used by class_registry.\n pub fn emit_contract_class_log<let N: u32>(&mut self, log: [Field; N]) {\n let contract_address = self.this_address();\n let counter = self.next_counter();\n\n let log_to_emit: [Field; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS] =\n log.concat([0; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS - N]);\n // Safety: The below length is constrained in the base rollup, which will make sure that all the fields beyond\n // length are zero. However, it won't be able to check that we didn't add extra padding (trailing zeroes) or\n // that we cut trailing zeroes from the end.\n let length = unsafe { trimmed_array_length_hint(log_to_emit) };\n // We hash the entire padded log to ensure a user cannot pass a shorter length and so emit incorrect shorter\n // bytecode.\n let log_hash = poseidon2_hash(log_to_emit);\n // Safety: the below only exists to broadcast the raw log, so we can provide it to the base rollup later to be\n // constrained.\n unsafe {\n notify_created_contract_class_log(contract_address, log_to_emit, length, counter);\n }\n\n self.contract_class_logs_hashes.push(LogHash { value: log_hash, length: length }.count(\n counter,\n ));\n }\n\n /// Makes a read-only call to a private function. Used by auth_registry for authwit.\n pub fn static_call_private_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n ) -> ReturnsHash {\n let args_hash = hash_args(args);\n execution_cache::store(args, args_hash);\n self.call_private_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n true,\n )\n }\n\n fn call_private_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> ReturnsHash {\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n let start_side_effect_counter = self.side_effect_counter;\n\n // Safety: The oracle simulates the private call and returns the value of the side effects counter after\n // execution of the call.\n let (end_side_effect_counter, returns_hash) = unsafe {\n call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n start_side_effect_counter,\n is_static_call,\n )\n };\n\n self.private_call_requests.push(\n PrivateCallRequest {\n call_context: CallContext {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n },\n args_hash,\n returns_hash,\n start_side_effect_counter,\n end_side_effect_counter,\n },\n );\n\n self.side_effect_counter = end_side_effect_counter + 1;\n ReturnsHash::new(returns_hash)\n }\n\n /// Enqueues a call to a public function with a calldata hash. Used by fee_juice and auth_registry.\n pub fn call_public_function_with_calldata_hash(\n &mut self,\n contract_address: AztecAddress,\n calldata_hash: Field,\n is_static_call: bool,\n hide_msg_sender: bool,\n ) {\n let counter = self.next_counter();\n\n let is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n\n validate_public_calldata(calldata_hash);\n\n let msg_sender = if hide_msg_sender {\n NULL_MSG_SENDER_CONTRACT_ADDRESS\n } else {\n self.this_address()\n };\n\n let call_request =\n PublicCallRequest { msg_sender, contract_address, is_static_call, calldata_hash };\n\n self.public_call_requests.push(Counted::new(call_request, counter));\n }\n\n fn next_counter(&mut self) -> u32 {\n let counter = self.side_effect_counter;\n self.side_effect_counter += 1;\n counter\n }\n}\n\nimpl Empty for PrivateContext {\n fn empty() -> Self {\n PrivateContext {\n inputs: PrivateContextInputs::empty(),\n side_effect_counter: 0 as u32,\n min_revertible_side_effect_counter: 0 as u32,\n is_fee_payer: false,\n args_hash: 0,\n return_hash: 0,\n expiration_timestamp: 0,\n nullifier_read_requests: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n anchor_block_header: BlockHeader::empty(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n}\n"
2521
+ "source": "use crate::{\n context::{inputs::PrivateContextInputs, NullifierExistenceRequest, ReturnsHash},\n hash::hash_args,\n messaging::process_l1_to_l2_message,\n oracle::{\n call_private_function::call_private_function_internal,\n public_call::validate_public_calldata,\n tx_phase::{in_revertible_phase, notify_revertible_phase_start},\n execution_cache,\n logs::notify_created_contract_class_log,\n nullifiers::notify_created_nullifier,\n },\n};\nuse crate::protocol::{\n abis::{\n block_header::BlockHeader,\n call_context::CallContext,\n function_selector::FunctionSelector,\n gas_settings::GasSettings,\n log_hash::LogHash,\n nullifier::Nullifier,\n private_call_request::PrivateCallRequest,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n private_log::{PrivateLog, PrivateLogData},\n public_call_request::PublicCallRequest,\n },\n address::{AztecAddress, EthAddress},\n constants::{\n CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, MAX_CONTRACT_CLASS_LOGS_PER_CALL,\n MAX_ENQUEUED_CALLS_PER_CALL, MAX_TX_LIFETIME, MAX_L2_TO_L1_MSGS_PER_CALL,\n MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL,\n NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_SIZE_IN_FIELDS,\n },\n hash::poseidon2_hash,\n messaging::l2_to_l1_message::L2ToL1Message,\n side_effect::{Counted, scoped::Scoped},\n traits::Empty,\n utils::arrays::{ClaimedLengthArray, trimmed_array_length_hint},\n};\n\n/// Minimal PrivateContext for protocol contracts going to audit.\n/// Contains only the methods actually used by: fee_juice, auth_registry, contract_class_registry, contract_instance_registry\n#[derive(Eq)]\npub struct PrivateContext {\n pub inputs: PrivateContextInputs,\n pub side_effect_counter: u32,\n\n pub min_revertible_side_effect_counter: u32,\n pub is_fee_payer: bool,\n\n pub args_hash: Field,\n pub return_hash: Field,\n\n pub expiration_timestamp: u64,\n\n pub nullifier_read_requests: BoundedVec<Scoped<Counted<Field>>, MAX_NULLIFIER_READ_REQUESTS_PER_CALL>,\n\n pub nullifiers: BoundedVec<Counted<Nullifier>, MAX_NULLIFIERS_PER_CALL>,\n\n pub private_call_requests: BoundedVec<PrivateCallRequest, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL>,\n pub public_call_requests: BoundedVec<Counted<PublicCallRequest>, MAX_ENQUEUED_CALLS_PER_CALL>,\n pub public_teardown_call_request: PublicCallRequest,\n pub l2_to_l1_msgs: BoundedVec<Counted<L2ToL1Message>, MAX_L2_TO_L1_MSGS_PER_CALL>,\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n pub anchor_block_header: BlockHeader,\n\n pub private_logs: BoundedVec<Counted<PrivateLogData>, MAX_PRIVATE_LOGS_PER_CALL>,\n pub contract_class_logs_hashes: BoundedVec<Counted<LogHash>, MAX_CONTRACT_CLASS_LOGS_PER_CALL>,\n\n pub expected_non_revertible_side_effect_counter: u32,\n pub expected_revertible_side_effect_counter: u32,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.start_side_effect_counter + 1,\n min_revertible_side_effect_counter: 0,\n is_fee_payer: false,\n args_hash,\n return_hash: 0,\n expiration_timestamp: inputs.anchor_block_header.global_variables.timestamp\n + MAX_TX_LIFETIME,\n nullifier_read_requests: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n anchor_block_header: inputs.anchor_block_header,\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n\n /// Returns the contract address that initiated this function call (similar to msg.sender in Solidity).\n pub fn maybe_msg_sender(self) -> Option<AztecAddress> {\n let maybe_msg_sender = self.inputs.call_context.msg_sender;\n if maybe_msg_sender == NULL_MSG_SENDER_CONTRACT_ADDRESS {\n Option::none()\n } else {\n Option::some(maybe_msg_sender)\n }\n }\n\n /// Returns the contract address of the current function being executed.\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.contract_address\n }\n\n /// Returns the chain ID of the current network.\n pub fn chain_id(self) -> Field {\n self.inputs.tx_context.chain_id\n }\n\n /// Returns the protocol version.\n pub fn version(self) -> Field {\n self.inputs.tx_context.version\n }\n\n /// Returns the gas settings for the current transaction.\n pub fn gas_settings(self) -> GasSettings {\n self.inputs.tx_context.gas_settings\n }\n\n /// Returns the function selector of the currently executing function.\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n /// Returns the hash of the arguments passed to the current function.\n pub fn get_args_hash(self) -> Field {\n self.args_hash\n }\n\n /// Returns the anchor block header.\n pub fn get_anchor_block_header(self) -> BlockHeader {\n self.anchor_block_header\n }\n\n /// Sets the hash of the return values for this private function.\n pub fn set_return_hash<let N: u32>(&mut self, serialized_return_values: [Field; N]) {\n let return_hash = hash_args(serialized_return_values);\n self.return_hash = return_hash;\n execution_cache::store(serialized_return_values, return_hash);\n }\n\n /// Builds the PrivateCircuitPublicInputs for this private function.\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n returns_hash: self.return_hash,\n min_revertible_side_effect_counter: self.min_revertible_side_effect_counter,\n is_fee_payer: self.is_fee_payer,\n expiration_timestamp: self.expiration_timestamp,\n note_hash_read_requests: ClaimedLengthArray::empty(), // Not used by protocol contracts\n nullifier_read_requests: ClaimedLengthArray::from_bounded_vec(\n self.nullifier_read_requests,\n ),\n key_validation_requests_and_separators: ClaimedLengthArray::empty(), // Not used by protocol contracts\n note_hashes: ClaimedLengthArray::empty(), // Not used by protocol contracts\n nullifiers: ClaimedLengthArray::from_bounded_vec(self.nullifiers),\n private_call_requests: ClaimedLengthArray::from_bounded_vec(self.private_call_requests),\n public_call_requests: ClaimedLengthArray::from_bounded_vec(self.public_call_requests),\n public_teardown_call_request: self.public_teardown_call_request,\n l2_to_l1_msgs: ClaimedLengthArray::from_bounded_vec(self.l2_to_l1_msgs),\n start_side_effect_counter: self.inputs.start_side_effect_counter,\n end_side_effect_counter: self.side_effect_counter,\n private_logs: ClaimedLengthArray::from_bounded_vec(self.private_logs),\n contract_class_logs_hashes: ClaimedLengthArray::from_bounded_vec(\n self.contract_class_logs_hashes,\n ),\n anchor_block_header: self.anchor_block_header,\n tx_context: self.inputs.tx_context,\n expected_non_revertible_side_effect_counter: self\n .expected_non_revertible_side_effect_counter,\n expected_revertible_side_effect_counter: self.expected_revertible_side_effect_counter,\n tx_request_salt: self.inputs.tx_request_salt,\n }\n }\n\n /// Declares the end of the \"setup phase\" of this tx. Used by fee_juice.\n pub fn end_setup(&mut self) {\n self.side_effect_counter += 1;\n self.min_revertible_side_effect_counter = self.next_counter();\n notify_revertible_phase_start(self.min_revertible_side_effect_counter);\n }\n\n pub fn in_revertible_phase(&mut self) -> bool {\n let current_counter = self.side_effect_counter;\n\n // Safety: Kernel will validate that the claim is correct by validating the expected counters.\n let is_revertible =\n unsafe { in_revertible_phase(current_counter) };\n\n if is_revertible {\n if (self.expected_revertible_side_effect_counter == 0)\n | (current_counter < self.expected_revertible_side_effect_counter) {\n self.expected_revertible_side_effect_counter = current_counter;\n }\n } else if current_counter > self.expected_non_revertible_side_effect_counter {\n self.expected_non_revertible_side_effect_counter = current_counter;\n }\n\n is_revertible\n }\n\n /// Sets a deadline for when this transaction must be included in a block.\n pub fn set_expiration_timestamp(&mut self, expiration_timestamp: u64) {\n self.expiration_timestamp = std::cmp::min(self.expiration_timestamp, expiration_timestamp);\n }\n\n /// Pushes a new nullifier. Used by class_registry and instance_registry.\n pub fn push_nullifier(&mut self, nullifier: Field) {\n notify_created_nullifier(nullifier);\n self.nullifiers.push(Nullifier { value: nullifier, note_hash: 0 }.count(self.next_counter()));\n }\n\n /// Asserts that a nullifier has been emitted. Used by instance_registry.\n pub fn assert_nullifier_exists(\n &mut self,\n nullifier_existence_request: NullifierExistenceRequest,\n ) {\n let nullifier = nullifier_existence_request.nullifier();\n let contract_address =\n nullifier_existence_request.maybe_contract_address().unwrap_or(AztecAddress::zero());\n\n let request = Scoped::new(\n Counted::new(nullifier, self.next_counter()),\n contract_address,\n );\n\n self.nullifier_read_requests.push(request);\n }\n\n /// Consumes a message sent from Ethereum (L1) to Aztec (L2). Used by fee_juice.\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let nullifier = process_l1_to_l2_message(\n self.anchor_block_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n sender,\n self.chain_id(),\n self.version(),\n content,\n secret,\n leaf_index,\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_nullifier(nullifier)\n }\n\n /// Emits a private log. Used by instance_registry.\n pub fn emit_private_log(&mut self, log: [Field; PRIVATE_LOG_SIZE_IN_FIELDS], length: u32) {\n let counter = self.next_counter();\n let private_log = PrivateLogData { log: PrivateLog::new(log, length), note_hash_counter: 0 }\n .count(counter);\n self.private_logs.push(private_log);\n }\n\n /// Emits a contract class log. Used by class_registry.\n pub fn emit_contract_class_log<let N: u32>(&mut self, log: [Field; N]) {\n let contract_address = self.this_address();\n let counter = self.next_counter();\n\n let log_to_emit: [Field; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS] =\n log.concat([0; CONTRACT_CLASS_LOG_SIZE_IN_FIELDS - N]);\n // Safety: The below length is constrained in the base rollup, which will make sure that all the fields beyond\n // length are zero. However, it won't be able to check that we didn't add extra padding (trailing zeroes) or\n // that we cut trailing zeroes from the end.\n let length = unsafe { trimmed_array_length_hint(log_to_emit) };\n // We hash the entire padded log to ensure a user cannot pass a shorter length and so emit incorrect shorter\n // bytecode.\n let log_hash = poseidon2_hash(log_to_emit);\n // Safety: the below only exists to broadcast the raw log, so we can provide it to the base rollup later to be\n // constrained.\n unsafe {\n notify_created_contract_class_log(contract_address, log_to_emit, length, counter);\n }\n\n self.contract_class_logs_hashes.push(LogHash { value: log_hash, length: length }.count(\n counter,\n ));\n }\n\n /// Makes a read-only call to a private function. Used by auth_registry for authwit.\n pub fn static_call_private_function<let ArgsCount: u32>(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ArgsCount],\n ) -> ReturnsHash {\n let args_hash = hash_args(args);\n execution_cache::store(args, args_hash);\n self.call_private_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n true,\n )\n }\n\n fn call_private_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> ReturnsHash {\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n let start_side_effect_counter = self.side_effect_counter;\n\n // Safety: The oracle simulates the private call and returns the value of the side effects counter after\n // execution of the call.\n let (end_side_effect_counter, returns_hash) = unsafe {\n call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n start_side_effect_counter,\n is_static_call,\n )\n };\n\n self.private_call_requests.push(\n PrivateCallRequest {\n call_context: CallContext {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n },\n args_hash,\n returns_hash,\n start_side_effect_counter,\n end_side_effect_counter,\n },\n );\n\n self.side_effect_counter = end_side_effect_counter + 1;\n ReturnsHash::new(returns_hash)\n }\n\n /// Enqueues a call to a public function with a calldata hash. Used by fee_juice and auth_registry.\n pub fn call_public_function_with_calldata_hash(\n &mut self,\n contract_address: AztecAddress,\n calldata_hash: Field,\n is_static_call: bool,\n hide_msg_sender: bool,\n ) {\n let counter = self.next_counter();\n\n let is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n\n validate_public_calldata(calldata_hash);\n\n let msg_sender = if hide_msg_sender {\n NULL_MSG_SENDER_CONTRACT_ADDRESS\n } else {\n self.this_address()\n };\n\n let call_request =\n PublicCallRequest { msg_sender, contract_address, is_static_call, calldata_hash };\n\n self.public_call_requests.push(Counted::new(call_request, counter));\n }\n\n fn next_counter(&mut self) -> u32 {\n let counter = self.side_effect_counter;\n self.side_effect_counter += 1;\n counter\n }\n}\n\nimpl Empty for PrivateContext {\n fn empty() -> Self {\n PrivateContext {\n inputs: PrivateContextInputs::empty(),\n side_effect_counter: 0 as u32,\n min_revertible_side_effect_counter: 0 as u32,\n is_fee_payer: false,\n args_hash: 0,\n return_hash: 0,\n expiration_timestamp: 0,\n nullifier_read_requests: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n anchor_block_header: BlockHeader::empty(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n expected_non_revertible_side_effect_counter: 0,\n expected_revertible_side_effect_counter: 0,\n }\n }\n}\n"
2242
2522
  },
2243
2523
  "58": {
2244
2524
  "function_locations": [
@@ -2766,29 +3046,29 @@
2766
3046
  "function_locations": [
2767
3047
  {
2768
3048
  "name": "assert_compatible_oracle_version",
2769
- "start": 1191
3049
+ "start": 1192
2770
3050
  },
2771
3051
  {
2772
3052
  "name": "assert_compatible_oracle_version_wrapper",
2773
- "start": 1500
3053
+ "start": 1501
2774
3054
  },
2775
3055
  {
2776
3056
  "name": "assert_compatible_oracle_version_oracle",
2777
- "start": 1730
3057
+ "start": 1732
2778
3058
  },
2779
3059
  {
2780
3060
  "name": "test::compatible_oracle_version",
2781
- "start": 1924
3061
+ "start": 1926
2782
3062
  },
2783
3063
  {
2784
3064
  "name": "test::incompatible_oracle_version_major",
2785
- "start": 2149
3065
+ "start": 2151
2786
3066
  }
2787
3067
  ],
2788
3068
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/oracle/version.nr",
2789
- "source": "/// The oracle version constants are used to check that the oracle interface is in sync between PXE and Aztec.nr.\n/// We version the oracle interface as `major.minor` where:\n/// - `major` = backward-breaking changes (must match exactly between PXE and Aztec.nr)\n/// - `minor` = oracle additions (non-breaking; PXE minor >= contract minor)\n///\n/// The TypeScript counterparts are in `oracle_version.ts`.\n///\n/// @dev Whenever a contract function or Noir test is run, the `aztec_utl_assertCompatibleOracleVersion` oracle is\n/// called. If the major version is incompatible, an error is thrown immediately. The minor version is recorded by\n/// the PXE and used to provide helpful error messages if a contract calls an oracle that doesn't exist. We don't throw\n/// immediately if AZTEC_NR_MINOR > PXE_MINOR because if a contract is updated to use a newer Aztec.nr dependency\n/// without actually using any of the new oracles then there is no reason to throw.\npub global ORACLE_VERSION_MAJOR: Field = 28;\npub global ORACLE_VERSION_MINOR: Field = 0;\n\n/// Asserts that the version of the oracle is compatible with the version expected by the contract.\npub fn assert_compatible_oracle_version() {\n // Safety: This oracle call returns nothing: we only call it to check Aztec.nr and Oracle interface versions are\n // compatible. It is therefore always safe to call.\n unsafe {\n assert_compatible_oracle_version_wrapper();\n }\n}\n\nunconstrained fn assert_compatible_oracle_version_wrapper() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR);\n}\n\n#[oracle(aztec_utl_assertCompatibleOracleVersion)]\nunconstrained fn assert_compatible_oracle_version_oracle(major: Field, minor: Field) {}\n\nmod test {\n use super::{\n assert_compatible_oracle_version_oracle, ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR,\n };\n\n #[test]\n unconstrained fn compatible_oracle_version() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR);\n }\n\n #[test(should_fail_with = \"Incompatible aztec cli version:\")]\n unconstrained fn incompatible_oracle_version_major() {\n let arbitrary_incorrect_major = 318183437;\n assert_compatible_oracle_version_oracle(arbitrary_incorrect_major, ORACLE_VERSION_MINOR);\n }\n}\n"
3069
+ "source": "/// The oracle version constants are used to check that the oracle interface is in sync between PXE and Aztec.nr.\n/// We version the oracle interface as `major.minor` where:\n/// - `major` = backward-breaking changes (must match exactly between PXE and Aztec.nr)\n/// - `minor` = oracle additions (non-breaking; PXE minor >= contract minor)\n///\n/// The TypeScript counterparts are in `oracle_version.ts`.\n///\n/// @dev Whenever a contract function or Noir test is run, the `aztec_misc_assertCompatibleOracleVersion` oracle is\n/// called. If the major version is incompatible, an error is thrown immediately. The minor version is recorded by\n/// the PXE and used to provide helpful error messages if a contract calls an oracle that doesn't exist. We don't throw\n/// immediately if AZTEC_NR_MINOR > PXE_MINOR because if a contract is updated to use a newer Aztec.nr dependency\n/// without actually using any of the new oracles then there is no reason to throw.\npub global ORACLE_VERSION_MAJOR: Field = 30;\npub global ORACLE_VERSION_MINOR: Field = 0;\n\n/// Asserts that the version of the oracle is compatible with the version expected by the contract.\npub fn assert_compatible_oracle_version() {\n // Safety: This oracle call returns nothing: we only call it to check Aztec.nr and Oracle interface versions are\n // compatible. It is therefore always safe to call.\n unsafe {\n assert_compatible_oracle_version_wrapper();\n }\n}\n\nunconstrained fn assert_compatible_oracle_version_wrapper() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR);\n}\n\n#[oracle(aztec_misc_assertCompatibleOracleVersion)]\nunconstrained fn assert_compatible_oracle_version_oracle(major: Field, minor: Field) {}\n\nmod test {\n use super::{\n assert_compatible_oracle_version_oracle, ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR,\n };\n\n #[test]\n unconstrained fn compatible_oracle_version() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR);\n }\n\n #[test(should_fail_with = \"Incompatible aztec cli version:\")]\n unconstrained fn incompatible_oracle_version_major() {\n let arbitrary_incorrect_major = 318183437;\n assert_compatible_oracle_version_oracle(arbitrary_incorrect_major, ORACLE_VERSION_MINOR);\n }\n}\n"
2790
3070
  },
2791
- "86": {
3071
+ "85": {
2792
3072
  "function_locations": [
2793
3073
  {
2794
3074
  "name": "<impl StateVariable<1, Context> for Map<K, V, Context>>::new",
@@ -2806,7 +3086,7 @@
2806
3086
  "path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/state_vars/map.nr",
2807
3087
  "source": "use crate::protocol::{storage::map::derive_storage_slot_in_map, traits::ToField};\nuse crate::state_vars::StateVariable;\n\n/// A key-value container for state variables.\n///\n/// A key-value storage container that maps keys to state variables, similar to Solidity mappings.\npub struct Map<K, V, Context> {\n pub context: Context,\n storage_slot: Field,\n}\n\n// Map reserves a single storage slot regardless of what it stores because nothing is stored at said slot: it is only\n// used to derive the storage slots of nested state variables.\nimpl<K, V, Context> StateVariable<1, Context> for Map<K, V, Context> {\n fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot }\n }\n\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl<K, V, Context> Map<K, V, Context> {\n /// Returns the state variable associated with the given key.\n ///\n /// This is equivalent to accessing `mapping[key]` in Solidity.\n pub fn at<let N: u32>(self, key: K) -> V\n where\n K: ToField,\n V: StateVariable<N, Context>,\n {\n V::new(\n self.context,\n derive_storage_slot_in_map(self.storage_slot, key),\n )\n }\n}\n"
2808
3088
  },
2809
- "88": {
3089
+ "87": {
2810
3090
  "function_locations": [
2811
3091
  {
2812
3092
  "name": "<impl StateVariable<M, Context> for PublicMutable<T, Context>>::new",
@@ -2884,7 +3164,7 @@
2884
3164
  "abi_public",
2885
3165
  "abi_only_self"
2886
3166
  ],
2887
- "debug_symbols": "pVjbbiIxDP2XeeYhvuRifmVVVbSdVkiIVhRWWlX8+zoQZwakRKjTh+aMhznYzrEd5md4G19OH8/b/fvn97D+8zO8HLa73fbjeff5ujluP/dq/Rlc/geAw5pWusZh7XVFLGu42gnKqtdRV4aylmvPZZXrGmhYg8sgKQAFkQpIYECfhaRA4ArQuQLQLOgLILtFZmGzcLVIAZ4MpAICGogFRPuKWNzApIToMmADUoCYRYqFHBswC6gbqHEROgPVkj+j6SNiA9nCCpgL8GhAPaRMmH0mVBCVkPKt6AtIZknZEhSIM1As7MiAJoH1Szlv8hXEAnKe2WfgC8h5vgJ1jCUDddXj+bwaTDfPx8M4ZtnMhKTy+tocxv1xWO9Pu91q+LvZnS4f+v7a7C/rcXPQuxrZuH/TVQnft7sxo/Nqetq1H436V56OyUEl8LcM0GYInEO6MAQOODGkGwZsM1AloMD1+QiPe1BjCB6l5QG3GRgthYxzgl9lEVwri6HNIC4VApk5wI/vY4JQPaDQ8iB1sqjtxLIIKbayKG0GjBaDFndrH7tZ9DWLQqkVQ49BxGJQMWNTzR0xAuZSvVAAiq8UKdxSUCcPydREMkWBQLcMHT0KOXNCiKc4IN0F4nuKYsuFOHFtjtCrTKOgNIvkTpYQO7mAaLpESPw7DiRzAzF0/OhoU/vzVOJuUjfEh90giVD3NUrbjZ66QKzXAbnQUhd2KHyqZeqmXU3pcYK6IyH4FsGjRYbNkYE9bbIVukRsxtARJjgki0Kxb7Yr7GyoiMTK4YCbHMu7Ji5tm/04PE5xYGo5QZ0ZSt5XcQeHTTf6e4KzPYnNowB1eidIsDoFiVM+9fj6O33Glj6po0+sVUowCZzioy4kV4dIcrMzzb0LcfEcorR0DpEsn0Psls8hhqVziHH5HOpyPDiHmBfPoUe1FZva4l6lQt1W0J+hrQbMPXm6lA8wpdgTNpsndwQKyddpmGb94r7Y+45MZ2/F0jz+e9cj8Ty1UC/NFup7Ig3JOCgi3bTQJ73avG4PN+8JzpnrsN287MZy+X7av87uHv992R17z/B1+Hwd306HMTPNXzboz8XkVyk+nfO3/Qc=",
3167
+ "debug_symbols": "pVjbbuJADP2XPPMwvszF/MqqqmibVkiIVhRWWlX8+3pgPAlIM0IND8yJQ05sz7Ed8jO8jS+nj+ft/v3ze1j/+RleDtvdbvvxvPt83Ry3n3u1/gwufwHgsKaVrnFYe10RyxqudoKy6nHUlaGs5dhzWeW6BhrW4DJICkBBpAISGNBrISkQuAJ0rgA0C/oCyE6RWdgsXC1SgCcDqYCABmIB0W4RixuYlBBdBmxAChCzSLGQYwNmAXUDNS5CZ6Ba8m80fURsIFtYAXMBHg2oh5QJs8+ECqISUj4VfQHJLClbggJxBoqFHRnQJLDelPMmX0EsIOeZfQa+gJznK1DHWDJQVz2ez6vBdPN8PIxjls1MSCqvr81h3B+H9f60262Gv5vd6fKj76/N/rIeNwc9q5GN+zddlfB9uxszOq+mq1370qifcnVMDirBxbuJAdoMgXNIF4bAASeGdMOAbQaqBBS4Xh/hcQ9qDMGjtDzgNgOjpdCDmxH8KovgWlkMbQZxqRDILALGhz1IEKoHFFoepE4WtZ1YFiHFVhalzYDRYtDibu1jN4u+ZlEotWLoMYhYDCpmbKq5I0bAXKoXCkDxlSLdigGok4dkaiKZokC4c6KjRyFnTgjxFAdEueXwPUWx5UKcuDZH6FWmUVCaRUJ3DLGTC4imS4TEv+NAMjcQQ8ePjja1P9umaLHHWTYedoMkQt3XKG03euoCsV4H5EJLXdih8KmWqZt2NcXHCeqOhOBbBI8WGTZHBva0yVboErEZQ0eY4JAsCsW+2a6ws6EiEiuHA25yLO+auLRt9uPwOMWBqeUEdWYoeV/FHRw23ejvCc72JDYfBajXOz1ZnaLnKZ+I7nf6jC19UkefWKuUYBL4XZ13XEiuDpHkZs809y7ExXOI0tI5RLJ8DrFbPocYls4hxuVzqMvx4BxiXjyHHtVWbGqLe5UKdVtB/4a2GjD35OlSfoApxZ6w2Ty5J1BGqzPkmbzui73vyPTsrViaj//e9Ug8Ty3US7OF+p5IQzIOikg3LfRJjzav28PNe4Jz5jpsNy+7sRy+n/avs7PHf192xt4zfB0+X8e302HMTPOXDfp3MflVik/nfLf/",
2888
3168
  "is_unconstrained": true,
2889
3169
  "name": "_increase_public_balance"
2890
3170
  },
@@ -2932,7 +3212,7 @@
2932
3212
  "abi_public",
2933
3213
  "abi_view"
2934
3214
  ],
2935
- "debug_symbols": "nZbbjuIwDIbfJde9sJ2jeZXRCBUoo0pVQR1YaYX67ptA3cNIybJ7Q36c9uvv2En7UKfmcP/at/358q12Hw91GNqua7/23eVY39pLH6MPBenHGbXTlXKsdqZS3jyHQK/Bqx1ipdi9RgScBJEImdIypSViJGIkYkGEEcGTcFpEmISXR/jJBYYE1EnYSTCImCIEIEIiKBFMNmJWRChCIjpd45KwkzAp4pOwk7ASsWESyTMlcvJMNgofgZSmktWXeEbGsVKy9Pvb0DRp5Ve1iBW61kPT39Suv3ddpX7V3f150fe17p/jrR7iLFSq6U9xjMBz2zVJjdVyN+RvRQBjp9ujdn5G2C0D8wx2qRBPBDtNCyFsCFRyEZyYQOCZ4PEf8tBhzgM15PIoMtD5hRFcjmELDFqWk9jOhAhbE1yeQEHKqTnM9xPqDcAXyqFBLLA2SzkwbLMIBQQYLQhgyCI4j9AzQYdVGuZHVxXKQeilKQiD+T8GabER93XBR6E5DXqpiCFYNgj6t21o9jgX1XPWRqmxkFkaS4PLNRYWEDbIWjhYahrC+4C5IM7ZHOD9DbZq75+HTak3jSDYUzYLLrkgPZ82QNZnD6xCKsy8ZAJosozCuenQzwXBkLdR6E3ycugRm9yxWc7D0pIHhawJU+hua+fudkA5G3+pCa1q4vMvkcLJiexkoyL7ZT3jq30cP+Pf+tgOm4+dMcGGtj50zfT3fO+Pq9nb76vMyMfSdbgcm9N9aBJp+WLC+G7/sKFy8Dmmp/0B",
3215
+ "debug_symbols": "nZbbjuIwDIbfJde9sJ2jeZXRCBUoo0pVQR1YaYV4901K3cNKybJzQ36c5uvv2E37UKfmcP/at/358q12Hw91GNqua7/23eVY39pLH6MPBenHGbXTlXKsdqZS3oxDoNfg1Q6xUuxeIwJOgkiETGmZ0hIxEjESsSDCiOBJOC0iTMLLLfzkAkMC6iTsJBhETBECECERlAgmGzErIhQhEZ2ucUnYSZgU8UnYSViJ2DCJ5JkSOXkmG4WPQEpTyepLjJHns1Ky9fvb0DRp51e1iBW61kPT39Suv3ddpX7V3X286Pta9+N4q4c4C5Vq+lMcI/Dcdk1Sz2pZDfmlCGDstDxq52eEpQ0D8wx2qRAjgp2mhRA2BCq5CE5MIPBM8Pgfeegw54EacnkUGej8wggux7AFBi3bSWxnQrAbgssTKEg5NYd5PeHWgi+UQ4NYYG2WcqDnDSIUEGC0IIAhi+A8Qs8EHVZp6C0AC+Ug9NIUhMH8jEFabMTnuuCj0JwGvVTEEPjVZrxtQ7PHuaieszZKjYXM0lgaXK6xsICwQfbCwVLT4N8HzAVxzuYA7z9gq/b++7Ap9aYRBHvKZsElF6Tn0wbI+uyBVUiFmZdMAE2WUTg3Hfq5IBjyNgq9SV4OPWKTOzbLeVha8qCQNWEK3W3t3N0OKGfjHzWhVU18/iVSOjmtlgeVrFn2kyi+Dj/j3/rYDpuPnWeCDW196Jrp7/neH1ezt99XmZGPpetwOTan+9Ak0vLFhPHd/mFD5eDzme72Bw==",
2936
3216
  "is_unconstrained": true,
2937
3217
  "name": "balance_of_public"
2938
3218
  },
@@ -2970,7 +3250,7 @@
2970
3250
  "abi_public",
2971
3251
  "abi_view"
2972
3252
  ],
2973
- "debug_symbols": "nVbbauMwEP0XP+dBM6Pb5FdKKW7qFoNxgpssLCX/vqNaYzsBiWxeouNRfHzmKv00H9375eutHz+P383+5ad5n/ph6L/ehuOhPffHUaw/jUk/YGKzp10DQM3epjXOK/p5JWj2Ia3yzLJayKub7c7kVZ4BBHijQC2BFMQMIgqIAhgU+BkghAwQFOgWqYXUYtWS1MyAM3BWQczAkwL9REAFQohGQDQKXAasFs4WMkaBWkBkICTgM0C1YPqPxJfIKEgWiSxZoyBm4EQhJcKkmVCAF0JKWwEUqCUmi0sgWbyAFMwZcALX667RhL+dp65L+d5UgNTFqZ268dzsx8sw7Jo/7XD5/dP3qR1/13M7ya4o6sYPWYXwsx+6hK679W1TfjUy+/w2G4gLgbtlgDID+1QxM4MnXBniDQOWGaTEVQOA4YUhwONeRF68CKHkRYWBpW+UQRqjxODKDN5a1eCtL8bBlxloISBvS1GoKghBFTjkkoJYZrCopWRxS/BUFIMtVlONwkRl2Ciw/5FIXCVYU5RQq0eZVlqPMlUWiuhvKahMIXNKU8lrUyHQLYOt+CHTS/0gu5YTxDtHXC2Wlpa2YFPmqBalUlDceHKXEAiVWEDQ9kaI9jkOJJUhx01FB1eKG8Ja3WYdEhAelkEcYMlr4LKMWnUBa5sDGV+qLqxQuKjB8GbNaoyPEywZ8ZtZd0fwaJNFLDUZ1mrT6qzigEUffO3UQFqODYMuFE+eSkKZOSwcBmyRozI0vdyfNJoQyzIqpYlBhx5ycfLX/XC4+oGxJIIqBzk5txS3N1iUUc8JbnISiqcgVWanXDW1T4E3h7lcOJ+qT37uPpCGcz6H4JbhVZ7aQz/d3NaviWvq2/ehy4+fl/Gw2T3/PemO3vZP0/HQfVymLjFtrvxyTXyRmgru9Zq+9g8=",
3253
+ "debug_symbols": "nVbbauMwEP0XP+dBM6Pb5FdKKW7qFoNxgpssLCX/vqNaYzsBiWxeouNRfHzmKv00H9375eutHz+P383+5ad5n/ph6L/ehuOhPffHUaw/jUk/YGKzp10DQM3epjXOK/p5JWj2Ia3yzLJayKub7c7kVZ4BBHijQC2BFMQMIgqIAhgU+BkghAwQFOgWqYXUYtWS1MyAM3BWQczAkwL9REAFQohGQDQKXAasFs4WMkaBWkBkICTgM0C1YPqPxJfIKEgWiSxZoyBm4EQhJcKkmVCAF0JKWwEUqCUmi0sgWbyAFMwZcALX667RhL+dp65L+d5UgNTFqZ268dzsx8sw7Jo/7XD5/dP3qR1/13M7ya4o6sYPWYXwsx+6hK679W1TfjUy+/w2G4gLgcMbBigzsE8VMzN4wpUh3jBgmUFKXDUAGF4YAjzuReTFixBKXlQYWPpGGaQxSgyuzOCtVQ3e+mIcfJmBFgLythSFqoIQVIFDLimIZQaLWkpumwj3VBSDLVZTjcJEZdi4YP8jkbhKsKYooVaPMq20HmWqLBTxNg5AZQqZU5pKXpsK4U6Erfgh00v9ILuWEwS+5XC1WFpa2oJNmaNalEpBceMJ3TGESiwgaHsjRPscB5LKkOOmooMrxQ1BkyJ1HjbReFgGcYAlr4HLMmrVBaxtDmR8qbqwQuGiBsObNasxPE6wZMRvZt0dwaNNFrHUZFirTauzigMWffC1UwNpOTYMulA8eSoJZeawcBiwRY7K0PRyf9JoQizLqJQmBh16yMXJX/fD4eoHxpIIqhzk5NxS3N5gUUY9J7jJSSieglSbnY60T+WSuMYT0TxVn/zcfSAN53wOwS3Dqzy1h366ua1fE9fUt+9Dlx8/L+Nhs3v+e9Idve2fpuOh+7hMXWLaXPnlmvgiNRXc6zV97R8=",
2974
3254
  "is_unconstrained": true,
2975
3255
  "name": "check_balance"
2976
3256
  },
@@ -3466,6 +3746,12 @@
3466
3746
  "sign": "unsigned",
3467
3747
  "width": 32
3468
3748
  }
3749
+ },
3750
+ {
3751
+ "name": "tx_request_salt",
3752
+ "type": {
3753
+ "kind": "field"
3754
+ }
3469
3755
  }
3470
3756
  ],
3471
3757
  "kind": "struct",
@@ -4788,6 +5074,12 @@
4788
5074
  "kind": "struct",
4789
5075
  "path": "aztec::protocol_types::utils::arrays::claimed_length_array::ClaimedLengthArray"
4790
5076
  }
5077
+ },
5078
+ {
5079
+ "name": "tx_request_salt",
5080
+ "type": {
5081
+ "kind": "field"
5082
+ }
4791
5083
  }
4792
5084
  ],
4793
5085
  "kind": "struct",
@@ -4796,14 +5088,14 @@
4796
5088
  "visibility": "databus"
4797
5089
  }
4798
5090
  },
4799
- "bytecode": "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",
5091
+ "bytecode": "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",
4800
5092
  "custom_attributes": [
4801
5093
  "abi_private"
4802
5094
  ],
4803
- "debug_symbols": "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",
5095
+ "debug_symbols": "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",
4804
5096
  "is_unconstrained": false,
4805
5097
  "name": "claim",
4806
- "verification_key": "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"
5098
+ "verification_key": "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"
4807
5099
  },
4808
5100
  {
4809
5101
  "abi": {
@@ -5297,6 +5589,12 @@
5297
5589
  "sign": "unsigned",
5298
5590
  "width": 32
5299
5591
  }
5592
+ },
5593
+ {
5594
+ "name": "tx_request_salt",
5595
+ "type": {
5596
+ "kind": "field"
5597
+ }
5300
5598
  }
5301
5599
  ],
5302
5600
  "kind": "struct",
@@ -6619,6 +6917,12 @@
6619
6917
  "kind": "struct",
6620
6918
  "path": "aztec::protocol_types::utils::arrays::claimed_length_array::ClaimedLengthArray"
6621
6919
  }
6920
+ },
6921
+ {
6922
+ "name": "tx_request_salt",
6923
+ "type": {
6924
+ "kind": "field"
6925
+ }
6622
6926
  }
6623
6927
  ],
6624
6928
  "kind": "struct",
@@ -6627,14 +6931,14 @@
6627
6931
  "visibility": "databus"
6628
6932
  }
6629
6933
  },
6630
- "bytecode": "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",
6934
+ "bytecode": "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",
6631
6935
  "custom_attributes": [
6632
6936
  "abi_private"
6633
6937
  ],
6634
- "debug_symbols": "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",
6938
+ "debug_symbols": "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",
6635
6939
  "is_unconstrained": false,
6636
6940
  "name": "claim_and_end_setup",
6637
- "verification_key": "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"
6941
+ "verification_key": "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"
6638
6942
  },
6639
6943
  {
6640
6944
  "abi": {
@@ -6688,13 +6992,13 @@
6688
6992
  "custom_attributes": [
6689
6993
  "abi_public"
6690
6994
  ],
6691
- "debug_symbols": "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",
6995
+ "debug_symbols": "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",
6692
6996
  "is_unconstrained": true,
6693
6997
  "name": "public_dispatch"
6694
6998
  }
6695
6999
  ],
6696
7000
  "name": "FeeJuice",
6697
- "noir_version": "1.0.0-beta.21+f1a4575adac59af0a86b036cf73ff5883d142a91",
7001
+ "noir_version": "1.0.0-beta.22+c57152f91260ecdb9faad4efc20abb14b6d2ece7",
6698
7002
  "outputs": {
6699
7003
  "globals": {
6700
7004
  "storage": [
@@ -6941,5 +7245,5 @@
6941
7245
  }
6942
7246
  },
6943
7247
  "transpiled": true,
6944
- "aztec_version": "6.0.0-nightly.20260604"
7248
+ "aztec_version": "6.0.0-nightly.20260721"
6945
7249
  }