diff --git a/.gitignore b/.gitignore index c41cc9e..1de5659 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/target \ No newline at end of file +target \ No newline at end of file diff --git a/README.md b/README.md index da1bc98..13904a8 100644 --- a/README.md +++ b/README.md @@ -8,37 +8,25 @@ Features: - Efficient implementation ~2 gates per haystack byte, ~5 gates per needle byte - Both needle and haystack strings can be dynamically constructed in-circuit if required -# Typedefs +## Dependencies -Multiple type definitions represent different hardcoded maximum lengths for the needle/haystack: +- Noir ≥v0.32.0 +- Barretenberg ≥v0.46.1 -``` -Haystack types ranging from 32 max bytes to 16,384 max bytes -StringBody32 -StringBody64 -StringBody128 -StringBody256 -StringBody512 -StringBody1024 -StringBody2048 -StringBody4096 -StringBody8192 -StringBody16384 -``` +Refer to [Noir's docs](https://noir-lang.org/docs/getting_started/installation/) and [Barretenberg's docs](https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/cpp/src/barretenberg/bb/readme.md#installation) for installation steps. + +## Installation + +In your _Nargo.toml_ file, add the version of this library you would like to install under dependency: ``` -Needle types ranging from 32 bytes to 1,024 max bytes -SubString32 -SubString64 -SubString128 -SubString256 -SubString512 -SubString1024 +[dependencies] +noir_string_search = { tag = "v0.1", git = "https://github.com/noir-lang/noir_string_search" } ``` -# Usage +## Usage -### Basic usage +Verify whether and where a substring is present withing another (larger) string: ```rust let haystack_text = "the quick brown fox jumped over the lazy dog".as_bytes(); @@ -50,8 +38,14 @@ let needle: SubString32 = SubString::new(needle_text, needle_text.len()); let (result, match_position): (bool, u32) = haystack.substring_match(needle); ``` +Both substring and larger string require a type with hardcoded maximum length. See type definitions below for the available lengths. + +Find this code snippet in `/example` and steps for proof generation and verification explained below. + ### Dynamic needle construction +An example of dynamically creating the needle from 2 substrings: + ```rust fn validate_account(padded_email_text: [u8; 8192], padded_username: [u8; 100], username_length: u32) { @@ -66,8 +60,82 @@ fn validate_account(padded_email_text: [u8; 8192], padded_username: [u8; 100], u let (result, match_position): (bool, u32) = haystack.substring_match(needle); } ``` +See all methods available in the next section. + +## Types & methods + +`StringBody` represents the "haystack" array, where you will check a "needle" (substring) is present. It is a byte array of up to `MaxBytes`. + +The content will be packed into 31-byte chunks and padded with zero. `MaxPaddedBytes`represents the max number of bytes after padding and `PaddedChunks` the number of 31-bytes chunks that are needed. `byte_length` is the length of the initial byte array (without padding). + +```rust +struct StringBody { + body: [u8; MaxPaddedBytes], + chunks: [Field; PaddedChunks], + byte_length: u32 +} +``` +Example: `type StringBody256 = StringBody<279, 9, 256>;`. -### Costs +`SubString` is the struct for the "needle", or the substring that is checked to be in the `StringBody`. It is a byte array of length max `MaxBytes`. + +Also this type is packed into 31-byte chunks and zero-padded to the nearest multiple of 31. `MaxPaddedBytes` is the max number of bytes after padding and `PaddedChunksMinusOne` is the number of chunks needed minus 1. `byte_length` represents the actual length of the substring as a byte array (without padding). + +```rust +struct SubString { + body: [u8; MaxPaddedBytes], + byte_length: u32 +} +``` + +Example: `type SubString32 = SubString<62, 1, 32>;`. + + +Multiple type definitions represent different hardcoded maximum lengths for the needle/haystack: + + +``` +Haystack types ranging from 32 max bytes to 16,384 max bytes +StringBody32 +StringBody64 +StringBody128 +StringBody256 +StringBody512 +StringBody1024 +StringBody2048 +StringBody4096 +StringBody8192 +StringBody16384 +``` + +``` +Needle types ranging from 32 bytes to 1,024 max bytes +SubString32 +SubString64 +SubString128 +SubString256 +SubString512 +SubString1024 +``` + +### Methods + +#### `StringBody` + +- `new(input, input_length)`, create a `StringBody` object from the byte array (that represents the string) and the length of the byte array +- `substring_match(substring)`, validates that the given needle exists in the haystack. + + +#### `SubString` + +- `new(input, input_length)`, create a `SubString` object from the byte array (that represents the string) and the length of the byte array +- `concat(self, other)`, concatenate two substrings together where `other.MaxBytes <= self.MaxBytes` +- `concat_into(self, other)`, concatenate two substrings together where `other.MaxBytes > self.MaxBytes` +- `len`, actual length of the bytes representing the substring +- `get(self, idx)`, returns byte for given index +- `get_body`, returns the inner array that the SubString contains + +## Costs Matching a SubString128 with a StringBody1024 costs 6,630 gates (as of noir 0.32.0 and bb 0.46.1) @@ -88,3 +156,44 @@ Some rough measurements: | 2,048 | 256 | 9,474 | 3,854 | Extrapolating from this table for some very rough estimates: costs for `substring_match` (excluding range table and byte array init costs) are ~6.5 gates per needle byte, ~0.5 gates per haystack byte and a ~1,100 gate constant cost. + +## Example + +Find the example with above usage code in `/example`. + +Run the test: + +```bash +nargo test +``` + +### Prove it + +Run `nargo check` to check for errors: + +```bash +nargo check +``` +In `Prover.toml`, the current value is equal to the test value, but can be adjusted. + +Then execute it, and prove it i.e. with barretenberg: + +```bash +nargo execute str_search +bb prove -b ./target/example.json -w ./target/str_search.gz -o ./target/proof +``` + +### Verify it + +To verify, we need to export the verification key: + +```bash +bb write_vk -b ./target/example.json -o ./target/vk +``` + +And verify: + +```bash +bb verify -k ./target/vk -p ./target/proof +``` +If verification passes, nothing is shown. Otherwise errors will pop up. \ No newline at end of file diff --git a/example/Nargo.toml b/example/Nargo.toml new file mode 100644 index 0000000..0c7172c --- /dev/null +++ b/example/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "example" +type = "bin" +authors = [""] +compiler_version = ">=0.32.0" + +[dependencies] +noir_string_search = { path = "../lib" } diff --git a/example/Prover.toml b/example/Prover.toml new file mode 100644 index 0000000..95c5f2c --- /dev/null +++ b/example/Prover.toml @@ -0,0 +1 @@ +needle_text = " the lazy dog" diff --git a/example/src/main.nr b/example/src/main.nr new file mode 100644 index 0000000..429f461 --- /dev/null +++ b/example/src/main.nr @@ -0,0 +1,18 @@ +use dep::noir_string_search::{StringBody, StringBody64, SubString, SubString32}; + +fn main(needle_text: str<13>) { + let haystack_text = "the quick brown fox jumped over the lazy dog".as_bytes(); + let needle_text_bytes = needle_text.as_bytes(); + + let haystack: StringBody64 = StringBody::new(haystack_text, haystack_text.len()); + let needle: SubString32 = SubString::new(needle_text_bytes, needle_text_bytes.len()); + + let (result, _): (bool, u32) = haystack.substring_match(needle); + assert(result); +} + +#[test] +fn test_main() { + let needle_text = " the lazy dog"; + main(needle_text); +} diff --git a/Nargo.toml b/lib/Nargo.toml similarity index 100% rename from Nargo.toml rename to lib/Nargo.toml diff --git a/info.sh b/lib/info.sh similarity index 100% rename from info.sh rename to lib/info.sh diff --git a/src/lib.nr b/lib/src/lib.nr similarity index 100% rename from src/lib.nr rename to lib/src/lib.nr diff --git a/src/utils.nr b/lib/src/utils.nr similarity index 100% rename from src/utils.nr rename to lib/src/utils.nr diff --git a/target/noir_string_search.json b/target/noir_string_search.json deleted file mode 100644 index cce8c1b..0000000 --- a/target/noir_string_search.json +++ /dev/null @@ -1 +0,0 @@ -{"noir_version":"0.32.0+c679f01a19b02ad2ac2287c8e699b46887f7872c","hash":78584144448352783,"abi":{"parameters":[{"name":"body_text","type":{"kind":"array","length":2048,"type":{"kind":"integer","sign":"unsigned","width":8}},"visibility":"private"},{"name":"substring_text","type":{"kind":"array","length":128,"type":{"kind":"integer","sign":"unsigned","width":8}},"visibility":"private"},{"name":"body_length","type":{"kind":"integer","sign":"unsigned","width":32},"visibility":"private"},{"name":"substring_length","type":{"kind":"integer","sign":"unsigned","width":32},"visibility":"private"}],"return_type":null,"error_types":{}},"bytecode":"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","debug_symbols":"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","file_map":{"23":{"source":"mod bn254;\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n pub fn to_le_bits(self: Self, bit_size: u32) -> [u1] {\n crate::assert_constant(bit_size);\n self.__to_le_bits(bit_size)\n }\n\n pub fn to_be_bits(self: Self, bit_size: u32) -> [u1] {\n crate::assert_constant(bit_size);\n self.__to_be_bits(bit_size)\n }\n\n #[builtin(to_le_bits)]\n fn __to_le_bits(self, _bit_size: u32) -> [u1] {}\n\n #[builtin(to_be_bits)]\n fn __to_be_bits(self, bit_size: u32) -> [u1] {}\n\n #[builtin(apply_range_constraint)]\n fn __assert_max_bit_size(self, bit_size: u32) {}\n\n pub fn assert_max_bit_size(self: Self, bit_size: u32) {\n crate::assert_constant(bit_size);\n assert(bit_size < modulus_num_bits() as u32);\n self.__assert_max_bit_size(bit_size);\n }\n\n pub fn to_le_bytes(self: Self, byte_size: u32) -> [u8] {\n self.to_le_radix(256, byte_size)\n }\n\n pub fn to_be_bytes(self: Self, byte_size: u32) -> [u8] {\n self.to_be_radix(256, byte_size)\n }\n\n pub fn to_le_radix(self: Self, radix: u32, result_len: u32) -> [u8] {\n crate::assert_constant(radix);\n crate::assert_constant(result_len);\n self.__to_le_radix(radix, result_len)\n }\n\n pub fn to_be_radix(self: Self, radix: u32, result_len: u32) -> [u8] {\n crate::assert_constant(radix);\n crate::assert_constant(result_len);\n self.__to_be_radix(radix, result_len)\n }\n\n // decompose `_self` into a `_result_len` vector over the `_radix` basis\n // `_radix` must be less than 256\n #[builtin(to_le_radix)]\n fn __to_le_radix(self, radix: u32, result_len: u32) -> [u8] {}\n\n #[builtin(to_be_radix)]\n fn __to_be_radix(self, radix: u32, result_len: u32) -> [u8] {}\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b = exponent.to_le_bits(32);\n\n for i in 1..33 {\n r *= r;\n r = (b[32-i] as Field) * (r * self) + (1 - b[32-i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\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\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\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// 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 let num_bytes = (modulus_num_bits() as u32 + 7) / 8;\n let x_bytes = x.to_le_bytes(num_bytes);\n let y_bytes = y.to_le_bytes(num_bytes);\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..num_bytes {\n if (!done) {\n let x_byte = x_bytes[num_bytes - 1 - i] as u8;\n let y_byte = y_bytes[num_bytes - 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","path":"std/field/mod.nr"},"32":{"source":"mod hash;\nmod aes128;\nmod array;\nmod slice;\nmod merkle;\nmod schnorr;\nmod ecdsa_secp256k1;\nmod ecdsa_secp256r1;\nmod eddsa;\nmod embedded_curve_ops;\nmod sha256;\nmod sha512;\nmod field;\nmod ec;\nmod unsafe;\nmod collections;\nmod compat;\nmod convert;\nmod option;\nmod string;\nmod test;\nmod cmp;\nmod ops;\nmod default;\nmod prelude;\nmod uint128;\nmod bigint;\nmod runtime;\nmod meta;\nmod append;\n\n// Oracle calls are required to be wrapped in an unconstrained function\n// Thus, the only argument to the `println` oracle is expected to always be an ident\n#[oracle(print)]\nunconstrained fn print_oracle(with_newline: bool, input: T) {}\n\nunconstrained pub fn print(input: T) {\n print_oracle(false, input);\n}\n\nunconstrained pub fn println(input: T) {\n print_oracle(true, input);\n}\n\n#[foreign(recursive_aggregation)]\npub fn verify_proof(verification_key: [Field], proof: [Field], public_inputs: [Field], key_hash: Field) {}\n\n// Asserts that the given value is known at compile-time.\n// Useful for debugging for-loop bounds.\n#[builtin(assert_constant)]\npub fn assert_constant(x: T) {}\n\n// Asserts that the given value is both true and known at compile-time\n#[builtin(static_assert)]\npub fn static_assert(predicate: bool, message: str) {}\n\n// from_field and as_field are private since they are not valid for every type.\n// `as` should be the default for users to cast between primitive types, and in the future\n// traits can be used to work with generic types.\n#[builtin(from_field)]\nfn from_field(x: Field) -> T {}\n\n#[builtin(as_field)]\nfn as_field(x: T) -> Field {}\n\npub fn wrapping_add(x: T, y: T) -> T {\n crate::from_field(crate::as_field(x) + crate::as_field(y))\n}\n\npub fn wrapping_sub(x: T, y: T) -> T {\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n crate::from_field(crate::as_field(x) + 340282366920938463463374607431768211456 - crate::as_field(y))\n}\n\npub fn wrapping_mul(x: T, y: T) -> T {\n crate::from_field(crate::as_field(x) * crate::as_field(y))\n}\n\n#[builtin(as_witness)]\npub fn as_witness(x: Field) {}\n\n","path":"std/lib.nr"},"53":{"source":"unconstrained pub fn search(\n haystack: [u8; N],\n needle: [u8],\n haystack_length: u32,\n needle_length: u32\n) -> u32 {\n assert(needle_length > 0, \"needle length of size 0 not supported\");\n assert(haystack_length > 0, \"haystack length of size 0 not supported\");\n let mut found = false;\n let mut found_index: u32 = 0;\n for i in 0..haystack_length - needle_length + 1 {\n if (found == true) {\n break;\n }\n for j in 0..needle_length {\n if haystack[i + j] != needle[j] {\n break;\n } else if (j == needle_length - 1) {\n found = true;\n }\n if (found == true) {\n found_index = i;\n break;\n }\n }\n }\n assert(found == true, \"utils::search could not find needle in haystack\");\n found_index\n}\n\n/**\n * @brief validate the body text contains zero-values for all indices >= byte_length\n * @note NOT NEEDED. Consider removing. Values beyond byte_length are not used in matching algorithm so no need to constrain them\n **/\nfn validate_body(data: [u8; BODYBYTES], length: u32, _: [Field; BODYCHUNKS]) {\n // we want a conditional assert for cases where i >= length\n // if i >= length we want to assert that data = 0\n let mut delta: Field = length as Field;\n for i in 0..BODYBYTES {\n let predicate = lt_f(i as Field, length as Field);\n let predicate = get_lt_predicate_f(i as Field, length as Field);\n\n let lt_parameter = 2 * (predicate as Field) * delta - predicate as Field - delta;\n lt_parameter.assert_max_bit_size(32);\n delta = delta - 1;\n std::as_witness(delta);\n\n // assert that if predicate = 0 then byte = 0\n assert(data[i] as Field * predicate as Field == data[i] as Field);\n }\n}\n\nunconstrained fn __conditional_select(lhs: u8, rhs: u8, predicate: bool) -> u8 {\n let mut result: u8 = 0;\n if (predicate) {\n result = lhs;\n } else {\n result = rhs;\n }\n result\n}\n\npub fn conditional_select(lhs: u8, rhs: u8, predicate: bool) -> u8 {\n let result = __conditional_select(lhs, rhs, predicate);\n let result_f = result as Field;\n let lhs_f = lhs as Field;\n let rhs_f = rhs as Field;\n\n let diff = lhs_f - rhs_f;\n std::as_witness(diff);\n assert((predicate as Field) * (diff) + rhs_f == result_f);\n result\n}\n\nunconstrained pub fn get_lt_predicate_f(x: Field, y: Field) -> bool {\n let a = x as u32;\n let b = y as u32;\n let r = a < b;\n r\n}\n\npub fn lt_f(x: Field, y: Field) -> bool {\n let predicate = get_lt_predicate_f(x, y);\n let delta = y as Field - x as Field;\n let lt_parameter = 2 * (predicate as Field) * delta - predicate as Field - delta;\n lt_parameter.assert_max_bit_size(32);\n\n predicate\n}\n\nstruct DebugRandomEngine {\n seed: Field,\n}\n\nimpl DebugRandomEngine {\n unconstrained fn get_random_32_bytes(&mut self) -> [u8; 32] {\n self.seed += 1;\n let input: [u8; 32] = self.seed.to_be_bytes(32).as_array();\n let hash: [u8; 32] = dep::std::hash::sha256(input);\n hash\n }\n unconstrained fn get_random_field(&mut self) -> Field {\n let hash = self.get_random_32_bytes();\n let mut result: Field = 0;\n for i in 0..32 {\n result *= 256;\n result += hash[i] as Field;\n }\n result\n }\n\n unconstrained fn get_random_bytes(&mut self) -> [u8; NBytes] {\n let num_chunks = (NBytes / 32) + ((NBytes % 32) != 0) as u32;\n\n let mut result: [u8; NBytes] = [0; NBytes];\n for i in 0..num_chunks - 1 {\n let bytes = self.get_random_32_bytes();\n for j in 0..32 {\n result[i * 32 + j] = bytes[j];\n }\n }\n\n let bytes = self.get_random_32_bytes();\n for j in 0..(NBytes - (num_chunks - 1) * 32) {\n result[(num_chunks - 1) * 32 + j] = bytes[j];\n }\n result\n }\n}\n\n","path":"/Users/zac/noir_string_search/src/utils.nr"},"54":{"source":"mod utils;\n\nuse utils::{conditional_select, lt_f, DebugRandomEngine};\n\n/**\n * @brief represents a byte-array of up to MaxBytes, that is used as a \"haystack\" array,\n * where we want to validate a substring \"needle\" is present in the \"haystack\" \n * @details the \"body\" parameter contains some input bytes, zero-padded to the nearest multiple of 31\n * We pack \"bytes\" into 31-byte \"chunks\", as this is the maximum number of bytes we can fit\n * into a field element without overflowing.\n * TODO: once we can derive generics via arithmetic on other generics, we want this \"31\" parameter\n * to be defined by the backend being used instead of being hardcoded to 31\n *\n * @note We perform this 31-byte packing because it dramatically reduces the number of constraints required for substring matching. See (chicken)\n *\n * @tparam MaxBytes: the maximum number of bytes that StringBody can contain\n * @tparam MaxPaddedBytes: the maximum number of bytes after zero-padding to the nearest multiple of 31\n * @tparam PaddedChunks: the number of 31-byte chunks needed to represent MaxPaddedBytes\n **/\nstruct StringBody {\n body: [u8; MaxPaddedBytes],\n chunks: [Field; PaddedChunks],\n byte_length: u32\n}\n\n/**\n * @brief represents a byte-array of up to MaxBytes, that is used as a \"needle\" array,\n * where we want to validate a substring \"needle\" is present in the \"haystack\" \n * @tparam MaxBytes: the maximum number of bytes that StringBody can contain\n * @tparam MaxPaddedBytes: the maximum number of bytes after zero-padding to the nearest multiple of 31\n * @tparam PaddedChunksMinusOne: the number of 31-byte chunks needed to represent MaxPaddedBytes minus one!\n *\n * @note PaddedChunksMinusOne is because we are going to do the following:\n * 1. align the SubString bytes according to the StringBody bytes being matched against\n * 2. split the aligned bytes into 31-byte chunks. The 1st and last chunks might contain\n * fewer than 31 bytes due to the above alignment\n * 3. validate the aligned-byte-chunks match the StringBody byte chunks\n * To account for the fact that the 1st and last chunks might have fewer bytes we treat those separately\n * The param PaddedChunksMinusOne is the number of 31-byte chunks required to represent SubString *EXCLUDING* the initial and final chunks\n */\nstruct SubString {\n body: [u8; MaxPaddedBytes],\n byte_length: u32\n}\n\ntype StringBody32 = StringBody<62, 2, 32>;\ntype StringBody64 = StringBody<93, 3, 64>;\ntype StringBody128 = StringBody<155, 5, 128>;\ntype StringBody256 = StringBody<279, 9, 256>;\ntype StringBody512 = StringBody<527, 17, 512>;\ntype StringBody1024 = StringBody<1054, 34, 1024>;\ntype StringBody2048 = StringBody<2077, 67, 2048>;\ntype StringBody4096 = StringBody<4123, 133, 4096>;\ntype StringBody8192 = StringBody<8215, 265, 8192>;\ntype StringBody16384 = StringBody<16399, 529, 16384>;\n\ntype SubString32 = SubString<62, 1, 32>;\ntype SubString64 = SubString<93, 2, 64>;\ntype SubString128 = SubString<155, 4, 128>;\ntype SubString256 = SubString<279, 8, 256>;\ntype SubString512 = SubString<527, 16, 512>;\ntype SubString1024 = SubString<1054, 33, 1024>;\n\ntrait SubStringTrait {\n fn match_chunks(\n self,\n haystack: [Field; HaystackChunks],\n num_bytes_in_first_chunk: Field,\n body_chunk_offset: Field,\n num_full_chunks: Field\n );\n\n fn len(self) -> u32;\n fn get(self, idx: Field) -> u8;\n fn get_body(self) -> [u8];\n}\n\n// ######################################################\n// S U B S T R I N G\n// ######################################################\nimpl SubString {\n\n /**\n * @brief construct a SubString object from an input byte array\n * @details the input byte array must have a number of bytes less than or equal to MaxBytes\n **/\n fn new(input: [u8; InputBytes], input_length: u32) -> Self {\n assert(MaxBytes <= MaxPaddedBytes);\n assert(input_length <= MaxBytes);\n assert(InputBytes <= MaxBytes);\n let mut body: [u8; MaxPaddedBytes] = [0; MaxPaddedBytes];\n for i in 0..InputBytes {\n body[i] = input[i];\n }\n SubString { body, byte_length: input_length }\n }\n\n /**\n * @brief concatenate two SubString objects together\n * @details each SubString can have different MaxBytes sizes, however we need OtherBytes <= MaxBytes\n * (use concat_into for cases where this is not the case)\n **/\n fn concat(self, other: SubString) -> Self {\n assert(\n OtherPaddedBytes <= MaxPaddedBytes, \"SubString::concat. SubString being concatted has larger max length. Try calling concat_into\"\n );\n assert(\n self.byte_length + other.byte_length <= MaxPaddedBytes, \"SubString::concat, concatenated string exceeds MaxPaddedBytes\"\n );\n let mut body = self.body;\n let offset: u32 = self.byte_length;\n for i in 0..MaxPaddedBytes {\n if (i + offset < MaxPaddedBytes) {\n body[i + offset] = other.body[i];\n }\n }\n SubString { body, byte_length: self.byte_length + other.byte_length }\n }\n\n /**\n * @brief concatenate two SubString objects together. Return type has OtherPaddedBytes max bytes\n * @details each SubString can have different MaxBytes sizes, however we need MaxBytes <= OtherBytes\n * (use concat for cases where this is not the case)\n **/\n fn concat_into(\n self,\n other: SubString\n ) -> SubString {\n assert(\n MaxPaddedBytes <= OtherPaddedBytes, \"SubString::concat_into. SubString being concat has larger max length. Try calling concat\"\n );\n assert(\n self.byte_length + other.byte_length <= OtherPaddedBytes, \"SubString::concat_into, concatenated string exceeds MaxPaddedBytes\"\n );\n let mut body: [u8; OtherPaddedBytes] = [0; OtherPaddedBytes];\n for i in 0..MaxBytes {\n body[i] = self.body[i];\n }\n\n let offset: u32 = self.byte_length;\n for i in 0..OtherPaddedBytes {\n if (i + offset < OtherPaddedBytes) {\n body[i + offset] = other.body[i];\n }\n }\n SubString { body, byte_length: self.byte_length + other.byte_length }\n }\n}\n\nimpl SubStringTrait for SubString {\n\n fn len(self) -> u32 { self.byte_length }\n fn get(self, idx: Field) -> u8 { self.body[idx] }\n fn get_body(self) -> [u8] { let x = self.body.as_slice(); println(f\"X = {x}\"); x }\n\n /**\n * @brief given some `haystack` 31-byte chunks, validate that there exist `num_full_chunks`\n * in the SubString, starting at byte position `starting_needle_byte`.\n * The selected chunks must be equal to the haystack chunks starting at `starting_haystack_chunk`\n **/\n fn match_chunks(\n self,\n haystack: [Field; HaystackChunks],\n starting_needle_byte: Field,\n starting_haystack_chunk: Field,\n num_full_chunks: Field\n ) {\n let mut substring_chunks: [Field; PaddedChunksMinusOne] = [0; PaddedChunksMinusOne];\n // pack the substring into 31 byte chunks.\n // This is fairly expensive as we need a ROM table to access the SubString.body\n // which is 2 gates per byte\n for i in 0..PaddedChunksMinusOne {\n let mut slice: Field = 0;\n for j in 0..31 {\n slice *= 256;\n let substring_idx = starting_needle_byte as Field + (i as Field * 31) + j as Field;\n let mut byte = self.body[substring_idx];\n slice += byte as Field;\n }\n std::as_witness(slice);\n substring_chunks[i] = slice;\n }\n // iterate over the needle chunks and validate they match the haystack chunks\n for i in 0..PaddedChunksMinusOne {\n let predicate: Field = lt_f(i as Field, num_full_chunks) as Field;\n let lhs = substring_chunks[i];\n let rhs = haystack[predicate as Field * (i as Field + starting_haystack_chunk)];\n assert(predicate * (lhs - rhs) == 0);\n }\n } \n}\n\n// ######################################################\n// S T R I N G B O D Y\n// ######################################################\nimpl StringBody {\n\n /**\n * @brief construct a StringBody object from an input byte array\n * @details the input byte array must have a number of bytes less than or equal to MaxBytes\n **/\n fn new(data: [u8; InputBytes], length: u32) -> Self {\n assert(length <= MaxBytes);\n assert(length <= InputBytes);\n let mut body: [u8; MaxPaddedBytes] = [0; MaxPaddedBytes];\n for i in 0..InputBytes {\n body[i] = data[i];\n }\n StringBody { body, chunks: StringBody::compute_chunks(body), byte_length: length }\n }\n\n /**\n * @brief given an input byte array, convert into 31-byte chunks\n * cost is ~0.5 gates per byte\n **/\n fn compute_chunks(body: [u8; MaxPaddedBytes]) -> [Field; PaddedChunks] {\n let mut chunks: [Field; PaddedChunks] = [0; PaddedChunks];\n for i in 0..PaddedChunks {\n let mut limb: Field = 0;\n for j in 0..31 {\n limb *= 256;\n limb += body[i * 31 + j] as Field;\n }\n chunks[i] = limb;\n std::as_witness(chunks[i]);\n }\n chunks\n }\n\n /**\n * @brief Validate a substring exists in the StringBody. Returns a success flag and the position within the StringBody that the match was found\n **/\n fn substring_match(\n self,\n substring: NeedleSubString\n ) -> (bool, u32) where NeedleSubString : SubStringTrait {\n // use unconstrained function to determine:\n // a: is the substring present in the body text\n // b: the position of the first match in the body text \n let position: u32 = utils::search(\n self.body,\n substring.get_body(),\n self.byte_length,\n substring.len()\n );\n\n assert(\n position + substring.len() <= self.byte_length, \"substring not present in main text (match found if a padding text included. is main text correctly formatted?)\"\n );\n let substring_length = substring.len();\n\n // chunk_index = which 31-byte haystack chunk does the needle begin in?\n let chunk_index: u32 = position / 31;\n // chunk_offset = how many haystack bytes are present in the 1st haystack chunk?\n let chunk_offset: u32 = position % 31;\n // how many needle bytes are in 1st haystack chunk?\n let num_bytes_in_first_chunk: u32 = 31 - chunk_offset;\n let mut starting_needle_byte_index_of_final_chunk: Field = 0;\n let mut chunk_index_of_final_haystack_chunk_with_matching_needle_bytes: Field = 0;\n let mut num_full_chunks = 0;\n println(\"A\");\n // is there only one haystack chunk that contains needle bytes?\n let merge_initial_final_needle_chunks = lt_f(substring_length as Field, num_bytes_in_first_chunk as Field);\n\n // if the above is false...\n if (!merge_initial_final_needle_chunks) {\n // compute how many full 31-byte haystack chunks contain 31 needle bytes\n num_full_chunks = (substring_length - num_bytes_in_first_chunk) / 31;\n // for the final haystack chunk that contains needle bytes, where in the needle does this chunk begin?\n starting_needle_byte_index_of_final_chunk = num_full_chunks as Field * 31 + num_bytes_in_first_chunk as Field;\n // what is the index of the final haystack chunk that contains needle bytes?\n chunk_index_of_final_haystack_chunk_with_matching_needle_bytes = num_full_chunks as Field + chunk_index as Field + 1;\n } else {\n starting_needle_byte_index_of_final_chunk = 0;\n // if the needle bytes does NOT span more than 1 haystack chunk,\n // the final haystack index will be the same as the initial haystack index\n chunk_index_of_final_haystack_chunk_with_matching_needle_bytes = chunk_index as Field;\n }\n\n // To minimize the number of comparisons between the haystack bytes and the needle bytes,\n // we pack both the haystack bytes and needle bytes into 31-byte Field \"chunks\" and compare chunks.\n // To do this correctly, we need to align the needle chunks with the haystack chunks\n /*\n e.g. consider a toy example where we pack 3 bytes into a chunk\n haystack: [VWXZYABCDEQRSTU]\n needle: [ABCDE]\n\n when constructing needle chunks, we need to align according to where the needle is located in the haystack\n haystack chunks: [VWX] [ZYA] [BCD] [EQR] [STU]\n _.. ... .__\n processed needle chunks: [ZYA] [BCD] [EQR]\n\n a \"_\" symbole means that a chunk byte has been sourced from the haystack bytes,\n a \".\" symbol means a byte is sourced from the needle bytes\n\n Both the initial and final chunks of the processed needle are \"composite\" constructions.\n If chunk byte index < `position` or is > `position + needle length\", byte is sourced from haystack, otherwise byte is sourced from needle\n\n The way we execute this in code is to define an \"initial\" needle chunk and a \"final\" needle chunk.\n Num needle bytes in initial chunk = position % 31\n Num needle bytes in final chunk = (needle_length - (position % 31)) % 31\n\n If needle_length < 31 then the \"initial\" and \"final\" chunks\n are actually the *same* chunk and we must perform a merge operation\n (see later in algo for comments)\n */\n\n // instead of directly reading haystack bytes, we derive the bytes from the haystack chunks.\n // This way we don't have to instantiate the haystack bytes as a ROM table, which would cost 2 * haystack.length gates\n let offset_to_first_needle_byte_in_chunk: Field = chunk_offset as Field;\n let initial_haystack_chunk = self.chunks[chunk_index];\n let final_haystack_chunk = self.chunks[chunk_index_of_final_haystack_chunk_with_matching_needle_bytes];\n\n let initial_body_bytes: [u8; 31] = initial_haystack_chunk.to_be_bytes(31).as_array();\n let final_body_bytes: [u8; 31] = final_haystack_chunk.to_be_bytes(31).as_array();\n\n // When defining the initial chunk bytes, we can represent as Field elements as we are deriving values from known bytes.\n // This saves us a few gates\n let mut initial_chunk: [Field; 31] = [0; 31];\n let mut final_chunk: [Field; 31] = [0; 31];\n for i in 0..31 {\n // if i < offset_to_first_needle_byte_in_chunk, we read from the haystack\n // otherwise we read from the needle\n // n.b. this can be done with an if statement, but the following code produces fewer constraints\n let idx: Field = i as Field;\n let predicate: Field = lt_f(i as Field, offset_to_first_needle_byte_in_chunk) as Field;\n let lhs: Field = initial_body_bytes[i] as Field;\n // if i < offset_to_first_needle_byte_in_chunk then `idx - offset_to_first_needle_byte_in_chunk` is negative\n // to ensure we access array correctly we need to set the lookup index to 0 if predicate = 0\n let substring_idx = (1 - predicate) * (idx - offset_to_first_needle_byte_in_chunk);\n let rhs: Field = substring.get(substring_idx) as Field;\n let byte: Field = predicate * (lhs - rhs) + rhs;\n initial_chunk[i] = byte;\n }\n println(\"C\");\n\n // If `merge_initial_final_needle_chunks = true`, `final_chunk` will contain the full needle data,\n // this requires some complex logic to determine where we are sourcing the needle bytes from.\n // Either they come from the `initial_chunk`, the haystack bytes or the substring bytes.\n for i in 0..31 {\n let mut lhs_index: Field = starting_needle_byte_index_of_final_chunk as Field + i as Field;\n let predicate = lt_f(lhs_index, substring_length as Field);\n\n /*\n | merge_initial_final_needle_chunks | predicate | byte_source |\n | false | false | body_bytes[i] |\n | false | true | substring[lhs_idx] |\n | true | false | body_bytes[i] |\n | true | true | initial_chunk[lhs_index] |\n\n NOTE: if `merge = true` and `predicate = true`, we read from `initial_chunk` to short-circuit some extra logic.\n if `initial_chunk` did not exist, then we would need to validate whether `i < offset_to_first_needle_byte_in_chunk`.\n if true, the byte source would be body_bytes, otherwise the source would be substring bytes\n */\n let byte_from_substring = substring.get(lhs_index) as Field;\n let byte_from_initial_chunk = initial_chunk[i] as Field;\n let byte_from_haystack = final_body_bytes[i] as Field;\n\n // TODO: find out why this cuts 1 gate per iteration\n std::as_witness(byte_from_initial_chunk);\n\n let p = predicate as Field;\n let m = merge_initial_final_needle_chunks as Field;\n // p * (m * (a - b) + (b - c)) + c\n let ab = byte_from_initial_chunk - byte_from_substring;\n std::as_witness(ab);\n let bc = byte_from_substring - byte_from_haystack;\n let t0 = m * ab + bc;\n let destination_byte = p * t0 + byte_from_haystack;\n\n final_chunk[i] = destination_byte;\n }\n println(\"D\");\n\n // TODO: moving this above the previous code block adds 31 gates. find out why? :/ \n let mut initial_needle_chunk: Field = 0;\n let mut final_needle_chunk: Field = 0;\n\n // Construct the initial and final needle chunks from the byte arrays we previously built.\n // Validate they match the initial and final haystack chunks\n for i in 0..31 {\n initial_needle_chunk *= 256;\n initial_needle_chunk += initial_chunk[i];\n final_needle_chunk *= 256;\n final_needle_chunk += final_chunk[i];\n }\n\n std::as_witness(initial_needle_chunk);\n std::as_witness(final_needle_chunk);\n\n initial_needle_chunk = merge_initial_final_needle_chunks as Field * (final_needle_chunk - initial_needle_chunk) + initial_needle_chunk;\n assert(initial_needle_chunk == initial_haystack_chunk);\n assert(final_needle_chunk == final_haystack_chunk);\n\n // Step 3: Construct needle chunks (for all but the 1st and last chunks) and validate they match the haystack chunks.\n // This part is much simpler as we know that all bytes in the chunk are sourced from the needle chunk.\n // NOTE: If we chose to not pack bytes into 31-byte chunks, the string matching algorithm would be simpler but more expensive.\n // Instead of matching chunks with each other, we would match individual byte values.\n // i.e. the number of iterations in this loop would be 31x greater\n // each loop iteration would also require a predicate, to check whether the byte index was within the needle range or not\n // Combined these two operations would add about 10 gates per loop iteration,\n // combined with a 31x iteration length would make this algorithm much more costly than the chunked variant\n let body_chunk_offset: Field = chunk_index as Field + 1;\n substring.match_chunks(\n self.chunks,\n num_bytes_in_first_chunk as Field,\n body_chunk_offset,\n num_full_chunks as Field\n );\n (true, position)\n }\n}\n\n#[test]\nfn test() {\n let haystack_text = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\".as_bytes();\n let needle_text = \" dolor in reprehenderit in voluptate velit esse\".as_bytes();\n\n let mut haystack: StringBody512 = StringBody::new(haystack_text, haystack_text.len());\n let mut needle: SubString64 = SubString::new(needle_text, needle_text.len());\n\n let result = haystack.substring_match(needle);\n assert(result.0 == true);\n}\n\n#[test]\nfn test_small_needle() {\n let haystack_text = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\".as_bytes();\n let needle_text = \"olor\".as_bytes();\n let mut haystack: StringBody512 = StringBody::new(haystack_text, haystack_text.len());\n let mut needle: SubString32 = SubString::new(needle_text, needle_text.len());\n\n let result = haystack.substring_match(needle);\n assert(result.0 == true);\n}\n\n#[test]\nfn test_needle_aligned_on_byte_boundary() {\n let haystack_text = \"the quick brown fox jumped over the lazy dog\".as_bytes();\n let needle_text = \" the lazy dog\".as_bytes();\n\n let mut haystack: StringBody256 = StringBody::new(haystack_text, haystack_text.len());\n let mut needle: SubString256 = SubString::new(needle_text, needle_text.len());\n\n let result = haystack.substring_match(needle);\n assert(result.0 == true);\n}\n\n#[test]\nfn test_needle_haystack_equal_size() {\n let haystack_text = \"the quick brown fox jumped over the lazy dog lorem ipsum blahhhh\".as_bytes();\n let needle_text = \"the quick brown fox jumped over the lazy dog lorem ipsum blahhhh\".as_bytes();\n\n let mut haystack: StringBody64 = StringBody::new(haystack_text, haystack_text.len());\n let mut needle: SubString64 = SubString::new(needle_text, needle_text.len());\n\n let result = haystack.substring_match(needle);\n assert(result.0 == true);\n}\n\n#[test]\nfn test_concat() {\n let email_text = \"account recovery for Bartholomew Fibblesworth\".as_bytes();\n let username = \"Bartholomew Fibblesworth\".as_bytes();\n let mut padded_email_text: [u8; 256] = [0; 256];\n let mut padded_username: [u8; 100] = [0; 100];\n for i in 0..username.len() {\n padded_username[i] = username[i];\n }\n for i in 0..email_text.len() {\n padded_email_text[i] = email_text[i];\n }\n let needle_text_init = \"account recovery for \".as_bytes();\n\n let needle_start: SubString128 = SubString::new(needle_text_init, needle_text_init.len());\n let needle_end: SubString128 = SubString::new(padded_username, username.len());\n let needle = needle_start.concat(needle_end);\n\n for i in 0..45 {\n assert(needle.body[i] == email_text[i]);\n }\n\n let haystack: StringBody256 = StringBody::new(padded_email_text, 200);\n let (result, _): (bool, u32) = haystack.substring_match(needle);\n assert(result == true);\n}\n\n#[test]\nfn test_concat_into() {\n let email_text = \"account recovery for Bartholomew Fibblesworth\".as_bytes();\n let username = \"Bartholomew Fibblesworth\".as_bytes();\n let mut padded_email_text: [u8; 256] = [0; 256];\n let mut padded_username: [u8; 100] = [0; 100];\n for i in 0..username.len() {\n padded_username[i] = username[i];\n }\n for i in 0..email_text.len() {\n padded_email_text[i] = email_text[i];\n }\n let needle_text_init = \"account recovery for \".as_bytes();\n\n let needle_start: SubString32 = SubString::new(needle_text_init, needle_text_init.len());\n let needle_end: SubString128 = SubString::new(padded_username, username.len());\n let needle = needle_start.concat_into(needle_end);\n\n for i in 0..45 {\n assert(needle.body[i] == email_text[i]);\n }\n\n let haystack: StringBody256 = StringBody::new(padded_email_text, 200);\n let (result, _): (bool, u32) = haystack.substring_match(needle);\n assert(result == true);\n}\n\nfn main(body_text: [u8; 2048], substring_text: [u8; 128], body_length: u32, substring_length: u32) {\n let Body: StringBody2048 = StringBody::new(body_text, body_length);\n let SubString: SubString128 = SubString::new(substring_text, substring_length);\n\n let r = Body.substring_match(SubString);\n assert(r.1 > 0);\n assert(r.0 == true);\n}\n// 3887 without range check\n// 2735 without byte array initial gates\n// 2447 without byte array range checks\n\n#[test]\nunconstrained fn test_partial_match() {\n let mut Engine = DebugRandomEngine { seed: 0 };\n let mut foo: [u8; 1024] = Engine.get_random_bytes();\n let mut bar: [u8; 128] = [0; 128];\n for i in 0..128 {\n bar[i] = foo[i + 123];\n }\n let position = utils::search(foo, bar.as_slice(), 1024, 128);\n\n assert(position == 123);\n}\n","path":"/Users/zac/noir_string_search/src/main.nr"}},"names":["main"]} \ No newline at end of file diff --git a/target/noir_string_search.txt b/target/noir_string_search.txt deleted file mode 100644 index fd40d44..0000000 --- a/target/noir_string_search.txt +++ /dev/null @@ -1,7 +0,0 @@ -{"functions": [ - { - "acir_opcodes": 4344, - "circuit_size": 8471, - "gates_per_opcode": [46,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,2740,2,0,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,2,1,2,0,2,1,1,0,1,9,1,1,1,0,2,1,1,1,1,1,1,0,0,1,1,1,2,1,1,1,1,2,0,2,2,1,1,1,1,1,1,1,1,1,0,24,1,24,0,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,2,1,0,1,4,0,1,1,1,1,4,0,1,1,3,1,4,0,1,1,1,1,4,0,1,1,2,1,4,0,1,1,1,1,4,0,1,1,3,1,4,0,1,1,1,1,4,0,1,1,2,1,4,0,1,1,1,1,4,0,1,1,3,1,4,0,1,1,1,1,4,0,1,1,2,1,4,0,1,1,1,1,4,0,1,1,3,1,4,0,1,1,1,1,4,0,1,1,2,1,4,0,1,1,1,1,4,0,1,1,3,1,4,0,1,1,1,1,4,0,1,1,2,1,4,0,1,1,1,1,4,0,1,1,3,1,4,0,1,1,1,1,4,0,1,1,2,1,4,0,1,1,1,1,4,0,1,1,3,1,4,0,1,1,1,1,4,0,1,1,2,1,4,0,1,1,1,1,4,0,1,1,3,1,4,0,0,1,1,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,2,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,3,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,2,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,3,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,2,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,3,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,2,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,3,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,2,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,3,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,2,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,3,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,2,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,3,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,2,1,4,1,1,1,1,1,1,0,1,1,1,1,1,4,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,3,1,24,1,1,1,0,1,1,1,1,24,1,1,1,0,1,1,2,1,24,1,1,1,0,1,1,1,1,24,1,1,1,0,3,1,1] - } -]} \ No newline at end of file