From a7938718512332c68f9ed5529a37cfd727c595ce Mon Sep 17 00:00:00 2001 From: Oleh Misarosh Date: Wed, 11 Sep 2024 22:57:35 +0200 Subject: [PATCH 1/2] chore: update to noir 0.34.0 --- src/lib.nr | 52 ++++++++++++++++++++++++++-------------------------- src/utils.nr | 9 ++++++--- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/lib.nr b/src/lib.nr index ac0264f..9c12308 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -4,7 +4,7 @@ use utils::{conditional_select, lt_f, DebugRandomEngine}; /** * @brief represents a byte-array of up to MaxBytes, that is used as a "haystack" array, - * where we want to validate a substring "needle" is present in the "haystack" + * where we want to validate a substring "needle" is present in the "haystack" * @details the "body" parameter contains some input bytes, zero-padded to the nearest multiple of 31 * We pack "bytes" into 31-byte "chunks", as this is the maximum number of bytes we can fit * into a field element without overflowing. @@ -25,7 +25,7 @@ struct StringBody let rhs = haystack[predicate as Field * (i as Field + starting_haystack_chunk)]; assert(predicate * (lhs - rhs) == 0); } - } + } } // ###################################################### @@ -206,25 +206,7 @@ impl StringBo for i in 0..InputBytes { body[i] = data[i]; } - StringBody { body, chunks: StringBody::compute_chunks(body), byte_length: length } - } - - /** - * @brief given an input byte array, convert into 31-byte chunks - * cost is ~0.5 gates per byte - **/ - fn compute_chunks(body: [u8; MaxPaddedBytes]) -> [Field; PaddedChunks] { - let mut chunks: [Field; PaddedChunks] = [0; PaddedChunks]; - for i in 0..PaddedChunks { - let mut limb: Field = 0; - for j in 0..31 { - limb *= 256; - limb += body[i * 31 + j] as Field; - } - chunks[i] = limb; - std::as_witness(chunks[i]); - } - chunks + StringBody { body, chunks: compute_chunks(body), byte_length: length } } /** @@ -236,7 +218,7 @@ impl StringBo ) -> (bool, u32) where NeedleSubString : SubStringTrait { // use unconstrained function to determine: // a: is the substring present in the body text - // b: the position of the first match in the body text + // b: the position of the first match in the body text let position: u32 = utils::search( self.body, substring.get_body(), @@ -311,8 +293,8 @@ impl StringBo let initial_haystack_chunk = self.chunks[chunk_index]; let final_haystack_chunk = self.chunks[chunk_index_of_final_haystack_chunk_with_matching_needle_bytes]; - let initial_body_bytes: [u8; 31] = initial_haystack_chunk.to_be_bytes(31).as_array(); - let final_body_bytes: [u8; 31] = final_haystack_chunk.to_be_bytes(31).as_array(); + let initial_body_bytes: [u8; 31] = initial_haystack_chunk.to_be_bytes(); + let final_body_bytes: [u8; 31] = final_haystack_chunk.to_be_bytes(); // When defining the initial chunk bytes, we can represent as Field elements as we are deriving values from known bytes. // This saves us a few gates @@ -370,7 +352,7 @@ impl StringBo final_chunk[i] = destination_byte; } - // TODO: moving this above the previous code block adds 31 gates. find out why? :/ + // TODO: moving this above the previous code block adds 31 gates. find out why? :/ let mut initial_needle_chunk: Field = 0; let mut final_needle_chunk: Field = 0; @@ -409,6 +391,24 @@ impl StringBo } } +/** + * @brief given an input byte array, convert into 31-byte chunks + * cost is ~0.5 gates per byte + **/ +fn compute_chunks(body: [u8; MaxPaddedBytes]) -> [Field; PaddedChunks] { + let mut chunks: [Field; PaddedChunks] = [0; PaddedChunks]; + for i in 0..PaddedChunks { + let mut limb: Field = 0; + for j in 0..31 { + limb *= 256; + limb += body[i * 31 + j] as Field; + } + chunks[i] = limb; + std::as_witness(chunks[i]); + } + chunks +} + #[test] fn test() { 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(); diff --git a/src/utils.nr b/src/utils.nr index ad3b317..d5c02b8 100644 --- a/src/utils.nr +++ b/src/utils.nr @@ -32,7 +32,11 @@ unconstrained pub fn search( * @brief validate the body text contains zero-values for all indices >= byte_length * @note NOT NEEDED. Consider removing. Values beyond byte_length are not used in matching algorithm so no need to constrain them **/ -fn validate_body(data: [u8; BODYBYTES], length: u32, _: [Field; BODYCHUNKS]) { +fn validate_body( + data: [u8; BODYBYTES], + length: u32, + _: [Field; BODYCHUNKS] +) { // we want a conditional assert for cases where i >= length // if i >= length we want to assert that data = 0 let mut delta: Field = length as Field; @@ -95,7 +99,7 @@ struct DebugRandomEngine { impl DebugRandomEngine { unconstrained fn get_random_32_bytes(&mut self) -> [u8; 32] { self.seed += 1; - let input: [u8; 32] = self.seed.to_be_bytes(32).as_array(); + let input: [u8; 32] = self.seed.to_be_bytes(); let hash: [u8; 32] = dep::std::hash::sha256(input); hash } @@ -127,4 +131,3 @@ impl DebugRandomEngine { result } } - From 507263fc5f0a09f3ffe20f1475992fa2eaa38ccd Mon Sep 17 00:00:00 2001 From: Oleh Misarosh Date: Tue, 17 Sep 2024 07:15:37 +0200 Subject: [PATCH 2/2] chore: update compiler_version in Nargo --- Nargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Nargo.toml b/Nargo.toml index d2e0bb0..93897a3 100644 --- a/Nargo.toml +++ b/Nargo.toml @@ -2,6 +2,6 @@ name = "noir_string_search" type = "lib" authors = [""] -compiler_version = ">=0.32.0" +compiler_version = ">=0.34.0" -[dependencies] \ No newline at end of file +[dependencies]