diff --git a/noir/Nargo.toml b/noir/Nargo.toml index 51454547d..4c75a7dd7 100644 --- a/noir/Nargo.toml +++ b/noir/Nargo.toml @@ -2,9 +2,7 @@ name = "noir" type = "bin" authors = [""] -compiler_version = ">=0.35.0" +compiler_version = ">=0.36.0" [dependencies] -# version error in rsa crate 0.3.1, keep both rsa and bignum are causing some issues. -rsa = { tag = "main", git = "https://github.com/noir-lang/noir_rsa" , directory = "lib" } -bignum = { tag = "v0.3.6", git = "https://github.com/noir-lang/noir-bignum" } \ No newline at end of file +# version error in rsa crate 0.3.1, keep both rsa and bignum are causing some issues. \ No newline at end of file diff --git a/noir/src/dg1/dg1.nr b/noir/src/dg1/dg1.nr index e278484f5..a47911dec 100644 --- a/noir/src/dg1/dg1.nr +++ b/noir/src/dg1/dg1.nr @@ -5,7 +5,7 @@ pub fn verify_dg1_and_dg2( dg1: [u8; 93], dg1_hash_offset: u8, dg2_hash: [u8; 64], - eContent: [u8; MAX_ECONTENT_LEN] + eContent: [u8; MAX_ECONTENT_LEN], ) { let computed_dg1_hash = sha256(dg1); @@ -25,6 +25,6 @@ pub fn verify_econtent( signed_attr: [u8; MAX_SIGNED_ATTR_LEN], signed_attr_econtent_hash_offset: u8, eContent_padded_length: u16, - signed_attr_padded_length: u8 + signed_attr_padded_length: u8, ) {} diff --git a/noir/src/eContent/hasher.nr b/noir/src/eContent/hasher.nr index fc4c1f694..9ff27679c 100644 --- a/noir/src/eContent/hasher.nr +++ b/noir/src/eContent/hasher.nr @@ -1,827 +1,827 @@ -use super::utils::{hash_static, hash_dynamic}; -use crate::types::DG1; -use crate::constants::DG_PADDING_BYTES_LEN; +// use super::utils::{hash_static, hash_dynamic}; +// use crate::types::DG1; +// use crate::constants::DG_PADDING_BYTES_LEN; -pub trait Hasher { - fn hash(data: [u8; MAX_LEN], data_len: u32) -> [u8; OUTPUT_SIZE]; -} +// pub trait Hasher { +// fn hash(data: [u8; MAX_LEN], data_len: u32) -> [u8; OUTPUT_SIZE]; +// } -fn e_content_hasher( - input: DG1, - dg1_hash_offset: u32, - dg2_hash: [u8; 64], - econtent: [u8; MAX_ECONTENT_LEN], - econtent_padded_length: u32, - signed_attr: [u8; MAX_SIGNED_ATTR_LEN], - signed_attr_padded_length: u32, - signed_attr_econtent_hash_offset: u32, - secret: [u8; 32] -) -> [u8; OUTPUT_SIZE] { - // hash dg1 - let dg1_hash = hash_static::(input); +// fn e_content_hasher( +// input: DG1, +// dg1_hash_offset: u32, +// dg2_hash: [u8; 64], +// econtent: [u8; MAX_ECONTENT_LEN], +// econtent_padded_length: u32, +// signed_attr: [u8; MAX_SIGNED_ATTR_LEN], +// signed_attr_padded_length: u32, +// signed_attr_econtent_hash_offset: u32, +// secret: [u8; 32] +// ) -> [u8; OUTPUT_SIZE] { +// // hash dg1 +// let dg1_hash = hash_static::(input); - // assert dg1 and dg2 hashes match the ones in eContent input - for i in 0..OUTPUT_SIZE { - assert(dg1_hash[i] == econtent[i + dg1_hash_offset]); - } +// // assert dg1 and dg2 hashes match the ones in eContent input +// for i in 0..OUTPUT_SIZE { +// assert(dg1_hash[i] == econtent[i + dg1_hash_offset]); +// } - let dg1_dg2_len = 2 * OUTPUT_SIZE + DG_PADDING_BYTES_LEN; +// let dg1_dg2_len = 2 * OUTPUT_SIZE + DG_PADDING_BYTES_LEN; - for i in 0..OUTPUT_SIZE + DG_PADDING_BYTES_LEN { - assert(dg2_hash[i] == econtent[i + dg1_dg2_len]); - } +// for i in 0..OUTPUT_SIZE + DG_PADDING_BYTES_LEN { +// assert(dg2_hash[i] == econtent[i + dg1_dg2_len]); +// } - // compute hash of eContent - let econtent_hash = hash_dynamic::(econtent, econtent_padded_length); +// // compute hash of eContent +// let econtent_hash = hash_dynamic::(econtent, econtent_padded_length); - // assert eContent hash matches the one in signedAttr - for i in 0..OUTPUT_SIZE { - assert(econtent_hash[i] == signed_attr[i + signed_attr_econtent_hash_offset]); - } +// // assert eContent hash matches the one in signedAttr +// for i in 0..OUTPUT_SIZE { +// assert(econtent_hash[i] == signed_attr[i + signed_attr_econtent_hash_offset]); +// } - // compute hash of signedAttr - let signed_attr_hash = hash_dynamic::(signed_attr, signed_attr_padded_length); +// // compute hash of signedAttr +// let signed_attr_hash = hash_dynamic::(signed_attr, signed_attr_padded_length); - // compute hash of secret + signed_attr_hash - let mut pre_hash = [0; 32 + OUTPUT_SIZE]; +// // compute hash of secret + signed_attr_hash +// let mut pre_hash = [0; 32 + OUTPUT_SIZE]; - for i in 0..32 { - pre_hash[i] = secret[i]; - } +// for i in 0..32 { +// pre_hash[i] = secret[i]; +// } - for i in 0..OUTPUT_SIZE { - pre_hash[i + 32] = signed_attr_hash[i]; - } - let secret_signed_attr_hash = hash_static::(pre_hash); - secret_signed_attr_hash -} +// for i in 0..OUTPUT_SIZE { +// pre_hash[i + 32] = signed_attr_hash[i]; +// } +// let secret_signed_attr_hash = hash_static::(pre_hash); +// secret_signed_attr_hash +// } -#[test] +// #[test] -fn test_e_content_hasher() { +// fn test_e_content_hasher() { - // inputs from rsa-inputs - - let dg1 = [ - 97, - 91, - 95, - 31, - 88, - 80, - 60, - 70, - 82, - 65, - 68, - 85, - 80, - 79, - 78, - 84, - 60, - 60, - 65, - 76, - 80, - 72, - 79, - 78, - 83, - 69, - 60, - 72, - 85, - 71, - 72, - 85, - 69, - 83, - 60, - 65, - 76, - 66, - 69, - 82, - 84, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 49, - 53, - 65, - 65, - 56, - 49, - 50, - 51, - 52, - 52, - 70, - 82, - 65, - 48, - 48, - 48, - 49, - 48, - 49, - 49, - 77, - 51, - 48, - 48, - 49, - 48, - 49, - 53, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 60, - 48, - 50 - ]; - let dg1_hash_offset = 37; - let dg2_hash = [ - 190, - 82, - 180, - 235, - 222, - 33, - 79, - 50, - 152, - 136, - 142, - 35, - 116, - 224, - 6, - 242, - 156, - 141, - 128, - 248, - 10, - 61, - 98, - 86, - 248, - 45, - 207, - 210, - 90, - 232, - 175, - 38, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ]; +// // inputs from rsa-inputs - let econtent = [ - 33, - 71, - 37, - 157, - 81, - 139, - 172, - 116, - 118, - 52, - 74, - 239, - 34, - 177, - 182, - 134, - 115, - 24, - 188, - 171, - 220, - 1, - 68, - 196, - 156, - 114, - 90, - 77, - 34, - 46, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 155, - 69, - 163, - 24, - 248, - 167, - 161, - 54, - 179, - 18, - 174, - 196, - 232, - 60, - 51, - 198, - 140, - 219, - 196, - 229, - 145, - 248, - 154, - 203, - 178, - 114, - 17, - 33, - 54, - 80, - 127, - 173, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 190, - 82, - 180, - 235, - 222, - 33, - 79, - 50, - 152, - 136, - 142, - 35, - 116, - 224, - 6, - 242, - 156, - 141, - 128, - 248, - 10, - 61, - 98, - 86, - 248, - 45, - 207, - 210, - 90, - 232, - 175, - 38, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 194, - 104, - 108, - 237, - 246, - 97, - 230, - 116, - 198, - 69, - 110, - 26, - 87, - 17, - 89, - 110, - 199, - 108, - 250, - 36, - 21, - 39, - 87, - 110, - 102, - 250, - 213, - 174, - 131, - 171, - 174, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 136, - 155, - 87, - 144, - 111, - 15, - 152, - 127, - 85, - 25, - 154, - 81, - 20, - 58, - 51, - 75, - 193, - 116, - 234, - 0, - 60, - 30, - 29, - 30, - 183, - 141, - 72, - 247, - 255, - 203, - 100, - 124, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 41, - 234, - 106, - 78, - 31, - 11, - 114, - 137, - 237, - 17, - 92, - 71, - 134, - 47, - 62, - 78, - 189, - 233, - 201, - 214, - 53, - 4, - 47, - 189, - 201, - 133, - 6, - 121, - 34, - 131, - 64, - 142, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 91, - 222, - 210, - 193, - 62, - 222, - 104, - 82, - 36, - 41, - 138, - 253, - 70, - 15, - 148, - 208, - 156, - 45, - 105, - 171, - 241, - 195, - 185, - 43, - 217, - 162, - 146, - 201, - 222, - 89, - 238, - 38, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 76, - 123, - 216, - 13, - 51, - 227, - 72, - 245, - 59, - 193, - 238, - 166, - 103, - 49, - 23, - 164, - 171, - 188, - 194, - 197, - 156, - 187, - 249, - 28, - 198, - 95, - 69, - 15, - 182, - 56, - 54, - 38, - 128, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9, - 120, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ]; +// let dg1 = [ +// 97, +// 91, +// 95, +// 31, +// 88, +// 80, +// 60, +// 70, +// 82, +// 65, +// 68, +// 85, +// 80, +// 79, +// 78, +// 84, +// 60, +// 60, +// 65, +// 76, +// 80, +// 72, +// 79, +// 78, +// 83, +// 69, +// 60, +// 72, +// 85, +// 71, +// 72, +// 85, +// 69, +// 83, +// 60, +// 65, +// 76, +// 66, +// 69, +// 82, +// 84, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 49, +// 53, +// 65, +// 65, +// 56, +// 49, +// 50, +// 51, +// 52, +// 52, +// 70, +// 82, +// 65, +// 48, +// 48, +// 48, +// 49, +// 48, +// 49, +// 49, +// 77, +// 51, +// 48, +// 48, +// 49, +// 48, +// 49, +// 53, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 60, +// 48, +// 50 +// ]; +// let dg1_hash_offset = 37; +// let dg2_hash = [ +// 190, +// 82, +// 180, +// 235, +// 222, +// 33, +// 79, +// 50, +// 152, +// 136, +// 142, +// 35, +// 116, +// 224, +// 6, +// 242, +// 156, +// 141, +// 128, +// 248, +// 10, +// 61, +// 98, +// 86, +// 248, +// 45, +// 207, +// 210, +// 90, +// 232, +// 175, +// 38, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0 +// ]; - let econtent_padded_length = 320; - let signed_attr = [ - 49, - 102, - 48, - 21, - 6, - 9, - 42, - 134, - 72, - 134, - 247, - 13, - 1, - 9, - 3, - 49, - 8, - 6, - 6, - 103, - 129, - 8, - 1, - 1, - 1, - 48, - 28, - 6, - 9, - 42, - 134, - 72, - 134, - 247, - 13, - 1, - 9, - 5, - 49, - 15, - 23, - 13, - 49, - 57, - 49, - 50, - 49, - 54, - 49, - 55, - 50, - 50, - 51, - 56, - 90, - 48, - 47, - 6, - 9, - 42, - 134, - 72, - 134, - 247, - 13, - 1, - 9, - 4, - 49, - 34, - 4, - 32, - 177, - 155, - 49, - 181, - 14, - 247, - 85, - 87, - 152, - 110, - 27, - 53, - 143, - 167, - 42, - 52, - 212, - 157, - 229, - 85, - 250, - 130, - 71, - 58, - 47, - 23, - 4, - 237, - 154, - 139, - 205, - 116, - 128, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3, - 64, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ]; +// let econtent = [ +// 33, +// 71, +// 37, +// 157, +// 81, +// 139, +// 172, +// 116, +// 118, +// 52, +// 74, +// 239, +// 34, +// 177, +// 182, +// 134, +// 115, +// 24, +// 188, +// 171, +// 220, +// 1, +// 68, +// 196, +// 156, +// 114, +// 90, +// 77, +// 34, +// 46, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 155, +// 69, +// 163, +// 24, +// 248, +// 167, +// 161, +// 54, +// 179, +// 18, +// 174, +// 196, +// 232, +// 60, +// 51, +// 198, +// 140, +// 219, +// 196, +// 229, +// 145, +// 248, +// 154, +// 203, +// 178, +// 114, +// 17, +// 33, +// 54, +// 80, +// 127, +// 173, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 190, +// 82, +// 180, +// 235, +// 222, +// 33, +// 79, +// 50, +// 152, +// 136, +// 142, +// 35, +// 116, +// 224, +// 6, +// 242, +// 156, +// 141, +// 128, +// 248, +// 10, +// 61, +// 98, +// 86, +// 248, +// 45, +// 207, +// 210, +// 90, +// 232, +// 175, +// 38, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 194, +// 104, +// 108, +// 237, +// 246, +// 97, +// 230, +// 116, +// 198, +// 69, +// 110, +// 26, +// 87, +// 17, +// 89, +// 110, +// 199, +// 108, +// 250, +// 36, +// 21, +// 39, +// 87, +// 110, +// 102, +// 250, +// 213, +// 174, +// 131, +// 171, +// 174, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 136, +// 155, +// 87, +// 144, +// 111, +// 15, +// 152, +// 127, +// 85, +// 25, +// 154, +// 81, +// 20, +// 58, +// 51, +// 75, +// 193, +// 116, +// 234, +// 0, +// 60, +// 30, +// 29, +// 30, +// 183, +// 141, +// 72, +// 247, +// 255, +// 203, +// 100, +// 124, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 41, +// 234, +// 106, +// 78, +// 31, +// 11, +// 114, +// 137, +// 237, +// 17, +// 92, +// 71, +// 134, +// 47, +// 62, +// 78, +// 189, +// 233, +// 201, +// 214, +// 53, +// 4, +// 47, +// 189, +// 201, +// 133, +// 6, +// 121, +// 34, +// 131, +// 64, +// 142, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 91, +// 222, +// 210, +// 193, +// 62, +// 222, +// 104, +// 82, +// 36, +// 41, +// 138, +// 253, +// 70, +// 15, +// 148, +// 208, +// 156, +// 45, +// 105, +// 171, +// 241, +// 195, +// 185, +// 43, +// 217, +// 162, +// 146, +// 201, +// 222, +// 89, +// 238, +// 38, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 76, +// 123, +// 216, +// 13, +// 51, +// 227, +// 72, +// 245, +// 59, +// 193, +// 238, +// 166, +// 103, +// 49, +// 23, +// 164, +// 171, +// 188, +// 194, +// 197, +// 156, +// 187, +// 249, +// 28, +// 198, +// 95, +// 69, +// 15, +// 182, +// 56, +// 54, +// 38, +// 128, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 9, +// 120, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0 +// ]; - let secret : [u8;32]= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; - - let signed_attr_econtent_hash_offset = 72; +// let econtent_padded_length = 320; +// let signed_attr = [ +// 49, +// 102, +// 48, +// 21, +// 6, +// 9, +// 42, +// 134, +// 72, +// 134, +// 247, +// 13, +// 1, +// 9, +// 3, +// 49, +// 8, +// 6, +// 6, +// 103, +// 129, +// 8, +// 1, +// 1, +// 1, +// 48, +// 28, +// 6, +// 9, +// 42, +// 134, +// 72, +// 134, +// 247, +// 13, +// 1, +// 9, +// 5, +// 49, +// 15, +// 23, +// 13, +// 49, +// 57, +// 49, +// 50, +// 49, +// 54, +// 49, +// 55, +// 50, +// 50, +// 51, +// 56, +// 90, +// 48, +// 47, +// 6, +// 9, +// 42, +// 134, +// 72, +// 134, +// 247, +// 13, +// 1, +// 9, +// 4, +// 49, +// 34, +// 4, +// 32, +// 177, +// 155, +// 49, +// 181, +// 14, +// 247, +// 85, +// 87, +// 152, +// 110, +// 27, +// 53, +// 143, +// 167, +// 42, +// 52, +// 212, +// 157, +// 229, +// 85, +// 250, +// 130, +// 71, +// 58, +// 47, +// 23, +// 4, +// 237, +// 154, +// 139, +// 205, +// 116, +// 128, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 3, +// 64, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0 +// ]; - e_content_hasher::<32, 32, 320>( - dg1, - dg1_hash_offset, - dg2_hash, - econtent, - econtent_padded_length, - signed_attr, - 320, - signed_attr_econtent_hash_offset, - secret - ); +// let secret : [u8;32]= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; -} +// let signed_attr_econtent_hash_offset = 72; + +// e_content_hasher::<32, 32, 320>( +// dg1, +// dg1_hash_offset, +// dg2_hash, +// econtent, +// econtent_padded_length, +// signed_attr, +// 320, +// signed_attr_econtent_hash_offset, +// secret +// ); + +// } diff --git a/noir/src/ofac/ofac_name.nr b/noir/src/ofac/ofac_name.nr index 29a69540c..e234abbad 100644 --- a/noir/src/ofac/ofac_name.nr +++ b/noir/src/ofac/ofac_name.nr @@ -22,3 +22,572 @@ pub fn ofac_name( smt_verify(name_hash, smt_leaf_value, smt_root, smt_siblings, false) } + +mod tests { + use super::ofac_name; + + #[test] + fn test_membership_proof() { + let dg1 = [ + 97, 91, 95, 31, 88, 80, 60, 70, 82, 65, 72, 69, 78, 65, 79, 60, 77, 79, 78, 84, 79, 89, + 65, 60, 60, 65, 82, 67, 65, 78, 71, 69, 76, 60, 68, 69, 60, 74, 69, 83, 85, 83, 60, 60, + 60, 60, 60, 60, 60, 57, 56, 108, 104, 57, 48, 53, 53, 54, 52, 70, 82, 65, 53, 52, 49, + 48, 48, 55, 49, 77, 51, 48, 48, 49, 48, 49, 53, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 48, 50, + ]; + + let smt_leaf_value = + 14861136771255138582189790512719132073503224483690068808762385640824858406629; + + let smt_root = + 17984904875400716818220831094015521032559090125729120459301078263371691488357; + + let smt_siblings = [ + 10199468046253699331670348021047559583700548318540134774348147654688161056749, + 0, + 6083370544989720109156048712010843914429147120094488276721009332466889312273, + 5586594631950621840536853070270815240392587436012623217450280105771860285853, + 14705516658198453418166850749316834667792679277427395163183485819794752164499, + 20294346648230675003512289404512456397527716989223146960883203144613490624816, + 15556345207626951873101308065346231335763211229567088581076981578475211976174, + 8454006058345473657364700463943989954421716114610631888481741171039175175309, + 14712399178116735674021514987362319440088928955532574561485941344812007567829, + 20335650369645130448227168045576376057891850014270871287741110154280660420332, + 11853662051376884493510373227826660669018238713133968635633602226811266599363, + 8816221654924477984371160663012539824223988182807237912242232562054208365736, + 2736247012926663474323421617011790463337288414362372295285359168654313100115, + 2596707961717849786781214040994425093357841893244789816445590708444770449875, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + + //should be false + assert(!ofac_name(dg1, smt_leaf_value, smt_root, smt_siblings)); + } + + #[test] + fn test_non_membership_proof() { + let dg1 = [ + 97, 91, 95, 31, 88, 80, 60, 70, 82, 65, 68, 85, 80, 79, 78, 84, 60, 60, 65, 76, 80, 72, + 79, 78, 83, 69, 60, 72, 85, 71, 72, 85, 69, 83, 60, 65, 76, 66, 69, 82, 84, 60, 60, 60, + 60, 60, 60, 60, 60, 49, 53, 65, 65, 56, 49, 50, 51, 52, 52, 70, 82, 65, 48, 52, 48, 50, + 49, 49, 49, 77, 51, 48, 48, 49, 48, 49, 53, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 48, 50, + ]; + + let mut smt_leaf_value = 0; + + let mut smt_root = + 17984904875400716818220831094015521032559090125729120459301078263371691488357; + + let smt_siblings = [ + 3065957881137995887397051372882352090443894855491365866754555758109929899135, + 5486637173150133037601893391095205722279221272456582770712106734529285414596, + 21877745139488284044947677595277888377089739679552102728633210271204138078662, + 20088094985221023205284225276794353921532832861812194580376175673139434663763, + 9791761062250580261550240660909219868253738637381614611500322616161263306872, + 7752669313063875926985470887065513265708684266879510277148279960335235191327, + 5150620330179796440712226311741104796541354059724724362978902700312860732474, + 372374822543347644817065074545720005008866950044131095955177601657207839375, + 2999395811465490745275443969939757336278090732875051464776040667807754227592, + 3001817857623841966652629754796802143041072311805545518387766832456220325477, + 4143741570693597378106149811709671714764264002589616310458204220860294517586, + 2736247012926663474323421617011790463337288414362372295285359168654313100115, + 2596707961717849786781214040994425093357841893244789816445590708444770449875, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + + assert(ofac_name(dg1, smt_leaf_value, smt_root, smt_siblings)); + + //wrong root - should be false + smt_root -= 1234; + + assert(!ofac_name(dg1, smt_leaf_value, smt_root, smt_siblings)); + + smt_root += 1234; + smt_leaf_value += 1234; + assert(!ofac_name(dg1, smt_leaf_value, smt_root, smt_siblings)); + } +} diff --git a/noir/src/ofac/ofac_name_dob.nr b/noir/src/ofac/ofac_name_dob.nr index 0a48dfbc1..0add9af78 100644 --- a/noir/src/ofac/ofac_name_dob.nr +++ b/noir/src/ofac/ofac_name_dob.nr @@ -1,7 +1,7 @@ use crate::types::DG1; use crate::utils::other::smt::smt_verify; -pub fn ofac_name( +pub fn ofac_name_dob( dg1: DG1, smt_leaf_value: Field, smt_root: Field, @@ -35,3 +35,572 @@ pub fn ofac_name( smt_verify(name_dob_hash, smt_leaf_value, smt_root, smt_siblings, false) } + +mod tests { + use super::ofac_name_dob; + + #[test] + fn test_membership_proof() { + let dg1 = [ + 97, 91, 95, 31, 88, 80, 60, 70, 82, 65, 72, 69, 78, 65, 79, 60, 77, 79, 78, 84, 79, 89, + 65, 60, 60, 65, 82, 67, 65, 78, 71, 69, 76, 60, 68, 69, 60, 74, 69, 83, 85, 83, 60, 60, + 60, 60, 60, 60, 60, 57, 56, 108, 104, 57, 48, 53, 53, 54, 52, 70, 82, 65, 53, 52, 49, + 48, 48, 55, 49, 77, 51, 48, 48, 49, 48, 49, 53, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 48, 50, + ]; + + let smt_leaf_value = + 19121709764585838290739922509076903710717349707375243032134784334729669626864; + + let smt_root = + 15275043987441881288949262865776849415360202675613643770276216220967809869488; + + let smt_siblings = [ + 2275501437671744506319408364556563816466212137867492819139840195047746956164, + 11083391891708608254157195998948109121483248917293149623342164165569455353446, + 16767176731814972896482021107462831258390377967331917202812365494901639931638, + 7562205882306917857170921672752570908146875883800664340033324494703317465834, + 8861526816457113857184268601346270147250846120461261439172893894686351158925, + 16816820758845506704608622317329854241125980416561787807063425675204184519870, + 1198040546025602839664999707966090097707928243279129718903948824758668333583, + 3290324140078760419138406967272848592004539293247352559810627073340266179246, + 20802462207343150637653343538766232986560418588252961623617091202130755834711, + 16994018337727850429211961173445217495163320322824298259289353094572559240287, + 3224290266395612468036887797325795029904596032198242130923084537207308912589, + 21503259802564826534930375203734353849647782948225209528053547742179102936054, + 18449239592792129416419296342294933876584806613658497570303606393628011901528, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + + //should be false + assert(!ofac_name_dob(dg1, smt_leaf_value, smt_root, smt_siblings)); + } + + #[test] + fn test_non_membership_proof() { + let dg1 = [ + 97, 91, 95, 31, 88, 80, 60, 70, 82, 65, 68, 85, 80, 79, 78, 84, 60, 60, 65, 76, 80, 72, + 79, 78, 83, 69, 60, 72, 85, 71, 72, 85, 69, 83, 60, 65, 76, 66, 69, 82, 84, 60, 60, 60, + 60, 60, 60, 60, 60, 49, 53, 65, 65, 56, 49, 50, 51, 52, 52, 70, 82, 65, 48, 52, 48, 50, + 49, 49, 49, 77, 51, 48, 48, 49, 48, 49, 53, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 48, 50, + ]; + + let mut smt_leaf_value = 0; + + let mut smt_root = + 15275043987441881288949262865776849415360202675613643770276216220967809869488; + + let smt_siblings = [ + 20876863927072988098487865258501989990544860900747361143636500803327979506402, + 6037841873623695121283771976841614162724898044173693762095811993867561337586, + 20967710697333841348619818985123584970034637900471985352490710237868869753637, + 9671377179144741905593951787340451635819453114517854941154808106164214926478, + 8382064261229644345256334842610586774090486942529814245311963866707971708286, + 12795352994775728128904508235585515658267044549942172663612611159581235851554, + 18304020634628219507109920629626996488330223421996126369988946719480628369662, + 18559020852291647154996997946614837838242207134243061284774653501024701300008, + 20521328354270154919350007042328235316419777618227383060242765986049417244388, + 7153525528520649991911701608964176435993958113309468417085580412660759433195, + 7299850152172381334552107555398464239242231021241892629341216023423211765700, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + + assert(ofac_name_dob(dg1, smt_leaf_value, smt_root, smt_siblings)); + + //wrong root - should be false + smt_root -= 1234; + + assert(!ofac_name_dob(dg1, smt_leaf_value, smt_root, smt_siblings)); + + smt_root += 1234; + smt_leaf_value += 1234; + assert(!ofac_name_dob(dg1, smt_leaf_value, smt_root, smt_siblings)); + } +} diff --git a/noir/src/ofac/ofac_passport_number.nr b/noir/src/ofac/ofac_passport_number.nr index 7a9f7e0d8..1681eb5eb 100644 --- a/noir/src/ofac/ofac_passport_number.nr +++ b/noir/src/ofac/ofac_passport_number.nr @@ -1,7 +1,7 @@ use crate::types::DG1; use crate::utils::other::smt::smt_verify; -pub fn ofac_name( +pub fn ofac_passport_number( dg1: DG1, smt_leaf_value: Field, smt_root: Field, @@ -17,3 +17,573 @@ pub fn ofac_name( smt_verify(passport_hash, smt_leaf_value, smt_root, smt_siblings, false) } + +mod tests { + use super::ofac_passport_number; + + #[test] + fn test_membership_proof() { + let dg1 = [ + 97, 91, 95, 31, 88, 80, 60, 70, 82, 65, 72, 69, 78, 65, 79, 60, 77, 79, 78, 84, 79, 89, + 65, 60, 60, 65, 82, 67, 65, 78, 71, 69, 76, 60, 68, 69, 60, 74, 69, 83, 85, 83, 60, 60, + 60, 60, 60, 60, 60, 57, 56, 108, 104, 57, 48, 53, 53, 54, 52, 70, 82, 65, 53, 52, 49, + 48, 48, 55, 49, 77, 51, 48, 48, 49, 48, 49, 53, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 48, 50, + ]; + + let smt_leaf_value = + 19378463006833395365107737548446061070205240691229284490379626153269032586499; + + let smt_root = 8835534532168993302133750141226608592096167902191400765009673745674397224484; + + let smt_siblings = [ + 3955491676910407004044472216026991675959367833592171188898198510428253371566, + 0, + 0, + 0, + 0, + 0, + 0, + 18050069708537439860494870379449931231983442566860206355084426800494240483417, + 0, + 1616493180105380757835583979003479501450823805344447027186980306459208668281, + 17329534438480855115635344322734434685059032905018848056522254264566705600021, + 15044767757340226465081834598908883700733033388697706874200923710607553803552, + 12269274693257994778026444445219794191551647294730703826482785664445598393747, + 14020620457951479001623520812728674141602457492519308338791364683313689919091, + 10972922004284943091660912095001768404074825208098932703502420258011736623699, + 6954429082210805353241355771971048027944686260967237748087875581927863631070, + 7725835406597329303714916306387998556969845398822724601324126370257570571627, + 5763248805726558661824921473992685470729864125408418377626966947655507831901, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + + //should be false + assert(!ofac_passport_number(dg1, smt_leaf_value, smt_root, smt_siblings)); + } + + #[test] + fn test_non_membership_proof() { + let dg1 = [ + 97, 91, 95, 31, 88, 80, 60, 70, 82, 65, 68, 85, 80, 79, 78, 84, 60, 60, 65, 76, 80, 72, + 79, 78, 83, 69, 60, 72, 85, 71, 72, 85, 69, 83, 60, 65, 76, 66, 69, 82, 84, 60, 60, 60, + 60, 60, 60, 60, 60, 49, 53, 65, 65, 56, 49, 50, 51, 52, 52, 70, 82, 65, 48, 52, 48, 50, + 49, 49, 49, 77, 51, 48, 48, 49, 48, 49, 53, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 48, 50, + ]; + + let mut smt_leaf_value = + 10720813908115827717913368881852413742238137063691424987013506811486899613202; + + let mut smt_root = + 8835534532168993302133750141226608592096167902191400765009673745674397224484; + + let smt_siblings = [ + 21850086379231919719987400494781366163279608682195949528338021982623629438971, + 2292258584812296662466108928528027050538498389646176421566753234119492614945, + 12467834269246078881307747483550682012949343230803859859010831296556789807920, + 2462075995855523669617684755698005398338301848715269883270042006013201461269, + 12292768095463967230547002621575577158470919531653044337773911671174173215920, + 5109818590371274008574634507154067731398853358351813410663858630529528226623, + 10481784078638447052052245488559706904460793637681508513767526763815701991142, + 9928093918906812116607631424141818926877934757436031296761948821938361778434, + 8306498947975314010201063120789602670840420319063986591027308600956240702618, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + + assert(ofac_passport_number(dg1, smt_leaf_value, smt_root, smt_siblings)); + + //wrong root - should be false + smt_root -= 1234; + + assert(!ofac_passport_number(dg1, smt_leaf_value, smt_root, smt_siblings)); + smt_root += 1234; + + //wrong leaf value + smt_leaf_value += 1234; + assert(!ofac_passport_number(dg1, smt_leaf_value, smt_root, smt_siblings)); + } +} diff --git a/noir/src/signature_verifier/signature_verifier.nr b/noir/src/signature_verifier/signature_verifier.nr index 0a49a01d3..efc8b7e02 100644 --- a/noir/src/signature_verifier/signature_verifier.nr +++ b/noir/src/signature_verifier/signature_verifier.nr @@ -1,12 +1,12 @@ -use dep::bignum::BigNum; -use dep::bignum::runtime_bignum::BigNumInstance; -use dep::std; +// use dep::bignum::BigNum; +// use dep::bignum::runtime_bignum::BigNumInstance; +// use dep::std; -use dep::rsa::types::{RSA, RSA2048, BN2048, BNInst2048}; +// use dep::rsa::types::{RSA, RSA2048, BN2048, BNInst2048}; -pub fn rsa_signature_verifier(bn: [[Field; 18]; 2], hash: [u8; 32], signature: BN2048) { - let rsa: RSA2048 = RSA {}; - let BNInstance: BNInst2048 = BigNumInstance::new(bn[0], bn[1]); - assert(rsa.verify_sha256_pkcs1v15(BNInstance, hash, signature, 65537)); -} +// pub fn rsa_signature_verifier(bn: [[Field; 18]; 2], hash: [u8; 32], signature: BN2048) { +// let rsa: RSA2048 = RSA {}; +// let BNInstance: BNInst2048 = BigNumInstance::new(bn[0], bn[1]); +// assert(rsa.verify_sha256_pkcs1v15(BNInstance, hash, signature, 65537)); +// } diff --git a/noir/src/utils/other/binary_merkle_tree.nr b/noir/src/utils/other/binary_merkle_tree.nr index 9df76c604..5763e3387 100644 --- a/noir/src/utils/other/binary_merkle_tree.nr +++ b/noir/src/utils/other/binary_merkle_tree.nr @@ -10,7 +10,7 @@ pub fn binary_merkle_root( let mut root = 0; for i in 0..N { - let isDepth = if i + 1 == depth { 1 } else { 0 }; + let isDepth = if i == depth { 1 } else { 0 }; root += isDepth * nodes[i]; @@ -23,9 +23,8 @@ pub fn binary_merkle_root( nodes[i + 1] = std::hash::poseidon::bn254::hash_2(child_nodes); } - if depth == 0 { - root = leaf; - } + let isDepth = if N == depth { 1 } else { 0 }; + root += isDepth * nodes[N]; root } @@ -83,7 +82,7 @@ mod tests { let (root, indices, siblings) = get_merkle_path::<134>(leaves, 5); - let computed_root = binary_merkle_root(leaves[5], 4, indices, siblings); + let computed_root = binary_merkle_root(leaves[5], 3, indices, siblings); assert(computed_root == root); } @@ -98,7 +97,7 @@ mod tests { let (root, indices, siblings) = get_merkle_path::<4>(leaves, 5); - let computed_root = binary_merkle_root(leaves[5], 4, indices, siblings); + let computed_root = binary_merkle_root(leaves[5], 3, indices, siblings); assert(computed_root == root); } diff --git a/noir/src/utils/other/smt.nr b/noir/src/utils/other/smt.nr index 1756dfd7c..ac68cd552 100644 --- a/noir/src/utils/other/smt.nr +++ b/noir/src/utils/other/smt.nr @@ -24,16 +24,16 @@ pub fn smt_verify( ) -> bool { let depth = siblings_length(siblings); - let path_in_bits = value.to_be_bits(); + let path_in_bits = virtualValue.to_be_bits::(); let mut path: [u1; N] = [0; N]; //move the last "depth" number of bits from path_in_bits to the starting of path - assert(depth < path_in_bits.len()); + assert(depth < N); for i in 0..depth { path[i] = path_in_bits[path_in_bits.len() - depth + i]; } - let leaf = std::hash::poseidon::bn254::hash_3([value, 1, 1]); + let leaf_or_zero = if value == 0 { 0 } else { leaf }; let computed_root = binary_merkle_root(leaf_or_zero, depth, path, siblings); diff --git a/noir/target/noir.gz b/noir/target/noir.gz deleted file mode 100644 index cc9cd6e2e..000000000 Binary files a/noir/target/noir.gz and /dev/null differ diff --git a/noir/target/noir.json b/noir/target/noir.json deleted file mode 100644 index 56946e62e..000000000 --- a/noir/target/noir.json +++ /dev/null @@ -1 +0,0 @@ -{"noir_version":"0.36.0+801c71880ecf8386a26737a5d8bb5b4cb164b2ab","hash":14169530188467309240,"abi":{"parameters":[{"name":"dg1","type":{"kind":"array","length":93,"type":{"kind":"integer","sign":"unsigned","width":8}},"visibility":"private"},{"name":"dg1_hash_offset","type":{"kind":"integer","sign":"unsigned","width":8},"visibility":"private"},{"name":"dg2_hash","type":{"kind":"array","length":64,"type":{"kind":"integer","sign":"unsigned","width":8}},"visibility":"private"},{"name":"eContent","type":{"kind":"array","length":384,"type":{"kind":"integer","sign":"unsigned","width":8}},"visibility":"private"},{"name":"signed_attr","type":{"kind":"array","length":192,"type":{"kind":"integer","sign":"unsigned","width":8}},"visibility":"private"},{"name":"signed_attr_econtent_hash_offset","type":{"kind":"integer","sign":"unsigned","width":8},"visibility":"private"},{"name":"eContent_padded_length","type":{"kind":"integer","sign":"unsigned","width":16},"visibility":"private"},{"name":"signed_attr_padded_length","type":{"kind":"integer","sign":"unsigned","width":8},"visibility":"private"}],"return_type":null,"error_types":{}},"bytecode":"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","debug_symbols":"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","file_map":{"26":{"source":"pub mod bn254;\nuse bn254::lt as bn254_lt;\nuse crate::runtime::is_unconstrained;\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(self) {\n // docs:end:assert_max_bit_size\n assert(BIT_SIZE < modulus_num_bits() as u32);\n self.__assert_max_bit_size(BIT_SIZE);\n }\n\n #[builtin(apply_range_constraint)]\n fn __assert_max_bit_size(self, bit_size: u32) {}\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice 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 slice 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)]\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {}\n // docs:end:to_le_bits\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; 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 slice 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)]\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {}\n // docs:end:to_be_bits\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(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\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(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\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 // docs:start:to_le_radix\n pub fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n crate::assert_constant(radix);\n }\n self.__to_le_radix(radix)\n }\n // docs:end:to_le_radix\n\n // docs:start:to_be_radix\n pub fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n crate::assert_constant(radix);\n }\n self.__to_be_radix(radix)\n }\n // docs:end:to_be_radix\n\n // `_radix` must be less than 256\n #[builtin(to_le_radix)]\n fn __to_le_radix(self, radix: u32) -> [u8; N] {}\n\n #[builtin(to_be_radix)]\n fn __to_be_radix(self, radix: u32) -> [u8; 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: [u1; 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) = 0 if x `elem` {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 /// 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(bytes: [u8; N]) -> Field {\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(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(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 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\nmod tests {\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\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: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\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 bits: [u8; 8] = field.to_be_bytes();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bits), 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 bits: [u8; 8] = field.to_le_bytes();\n assert_eq(bits, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bits), 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 let field = 2;\n let bits: [u8; 8] = field.to_be_radix(256);\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bits), 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 let field = 2;\n let bits: [u8; 8] = field.to_le_radix(256);\n assert_eq(bits, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bits), field);\n }\n // docs:end:to_le_radix_example\n}\n","path":"std/field/mod.nr"},"35":{"source":"use crate::runtime::is_unconstrained;\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(input: [u8; N]) -> [u8; 32]\n// docs:end:sha256\n{\n digest(input)\n}\n\n#[foreign(sha256_compression)]\npub fn sha256_compression(_input: [u32; 16], _state: [u32; 8]) -> [u32; 8] {}\n\n// SHA-256 hash function\n#[no_predicates]\npub fn digest(msg: [u8; N]) -> [u8; 32] {\n sha256_var(msg, N as u64)\n}\n\n// Convert 64-byte array to array of 16 u32s\nfn msg_u8_to_u32(msg: [u8; 64]) -> [u32; 16] {\n let mut msg32: [u32; 16] = [0; 16];\n\n for i in 0..16 {\n let mut msg_field: Field = 0;\n for j in 0..4 {\n msg_field = msg_field * 256 + msg[64 - 4 * (i + 1) + j] as Field;\n }\n msg32[15 - i] = msg_field as u32;\n }\n\n msg32\n}\n\nunconstrained fn build_msg_block_iter(\n msg: [u8; N],\n message_size: u32,\n msg_start: u32,\n) -> ([u8; 64], u32) {\n let mut msg_block: [u8; BLOCK_SIZE] = [0; BLOCK_SIZE];\n // We insert `BLOCK_SIZE` bytes (or up to the end of the message)\n let block_input = if msg_start + BLOCK_SIZE > message_size {\n 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 {\n message_size - msg_start\n }\n } else {\n BLOCK_SIZE\n };\n for k in 0..block_input {\n msg_block[k] = msg[msg_start + k];\n }\n (msg_block, block_input)\n}\n\n// Verify the block we are compressing was appropriately constructed\nfn verify_msg_block(\n msg: [u8; N],\n message_size: u32,\n msg_block: [u8; 64],\n msg_start: u32,\n) -> u32 {\n let mut msg_byte_ptr: u32 = 0; // Message byte pointer\n let mut msg_end = msg_start + BLOCK_SIZE;\n if msg_end > N {\n msg_end = N;\n }\n\n for k in msg_start..msg_end {\n if k < message_size {\n assert_eq(msg_block[msg_byte_ptr], msg[k]);\n msg_byte_ptr = msg_byte_ptr + 1;\n }\n }\n\n msg_byte_ptr\n}\n\nglobal BLOCK_SIZE = 64;\n\n// Variable size SHA-256 hash\npub fn sha256_var(msg: [u8; N], message_size: u64) -> [u8; 32] {\n let message_size = message_size as u32;\n let num_blocks = N / BLOCK_SIZE;\n let mut msg_block: [u8; BLOCK_SIZE] = [0; BLOCK_SIZE];\n let mut h: [u32; 8] = [\n 1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635,\n 1541459225,\n ]; // Intermediate hash, starting with the canonical initial value\n let mut msg_byte_ptr = 0; // Pointer into msg_block\n for i in 0..num_blocks {\n let msg_start = BLOCK_SIZE * i;\n let (new_msg_block, new_msg_byte_ptr) =\n unsafe { build_msg_block_iter(msg, message_size, msg_start) };\n if msg_start < message_size {\n msg_block = new_msg_block;\n }\n\n if !is_unconstrained() {\n // Verify the block we are compressing was appropriately constructed\n let new_msg_byte_ptr = verify_msg_block(msg, message_size, msg_block, msg_start);\n if msg_start < message_size {\n msg_byte_ptr = new_msg_byte_ptr;\n }\n } else if msg_start < message_size {\n msg_byte_ptr = new_msg_byte_ptr;\n }\n\n // If the block is filled, compress it.\n // An un-filled block is handled after this loop.\n if (msg_start < message_size) & (msg_byte_ptr == BLOCK_SIZE) {\n h = sha256_compression(msg_u8_to_u32(msg_block), h);\n }\n }\n\n let modulo = N % BLOCK_SIZE;\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 if modulo != 0 {\n let msg_start = BLOCK_SIZE * num_blocks;\n let (new_msg_block, new_msg_byte_ptr) =\n unsafe { build_msg_block_iter(msg, message_size, msg_start) };\n\n if msg_start < message_size {\n msg_block = new_msg_block;\n }\n\n if !is_unconstrained() {\n let new_msg_byte_ptr = verify_msg_block(msg, message_size, msg_block, msg_start);\n if msg_start < message_size {\n msg_byte_ptr = new_msg_byte_ptr;\n }\n } else if msg_start < message_size {\n msg_byte_ptr = new_msg_byte_ptr;\n }\n }\n\n if msg_byte_ptr == BLOCK_SIZE {\n msg_byte_ptr = 0;\n }\n\n // This variable is used to get around the compiler under-constrained check giving a warning.\n // We want to check against a constant zero, but if it does not come from the circuit inputs\n // or return values the compiler check will issue a warning.\n let zero = msg_block[0] - msg_block[0];\n\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 msg_block[msg_byte_ptr] = 1 << 7;\n let last_block = msg_block;\n msg_byte_ptr = msg_byte_ptr + 1;\n\n unsafe {\n let (new_msg_block, new_msg_byte_ptr) = pad_msg_block(msg_block, msg_byte_ptr);\n msg_block = new_msg_block;\n if crate::runtime::is_unconstrained() {\n msg_byte_ptr = new_msg_byte_ptr;\n }\n }\n\n if !crate::runtime::is_unconstrained() {\n for i in 0..BLOCK_SIZE {\n assert_eq(msg_block[i], last_block[i]);\n }\n\n // If i >= 57, there aren't enough bits in the current message block to accomplish this, so\n // the 1 and 0s fill up the current block, which we then compress accordingly.\n // Not enough bits (64) to store length. Fill up with zeros.\n for _i in 57..BLOCK_SIZE {\n if msg_byte_ptr <= 63 & msg_byte_ptr >= 57 {\n assert_eq(msg_block[msg_byte_ptr], zero);\n msg_byte_ptr += 1;\n }\n }\n }\n\n if msg_byte_ptr >= 57 {\n h = sha256_compression(msg_u8_to_u32(msg_block), h);\n\n msg_byte_ptr = 0;\n }\n\n msg_block = unsafe { attach_len_to_msg_block(msg_block, msg_byte_ptr, message_size) };\n\n if !crate::runtime::is_unconstrained() {\n for i in 0..56 {\n let predicate = (i < msg_byte_ptr) as u8;\n let expected_byte = predicate * last_block[i];\n assert_eq(msg_block[i], expected_byte);\n }\n\n // We verify the message length was inserted correctly by reversing the byte decomposition.\n let len = 8 * message_size;\n let mut reconstructed_len: Field = 0;\n for i in 56..64 {\n reconstructed_len = 256 * reconstructed_len + msg_block[i] as Field;\n }\n assert_eq(reconstructed_len, len as Field);\n }\n\n hash_final_block(msg_block, h)\n}\n\nunconstrained fn pad_msg_block(\n mut msg_block: [u8; 64],\n mut msg_byte_ptr: u32,\n) -> ([u8; BLOCK_SIZE], u32) {\n // If i >= 57, there aren't enough bits in the current message block to accomplish this, so\n // the 1 and 0s fill up the current block, which we then compress accordingly.\n if msg_byte_ptr >= 57 {\n // Not enough bits (64) to store length. Fill up with zeros.\n for i in msg_byte_ptr..BLOCK_SIZE {\n msg_block[i] = 0;\n }\n (msg_block, BLOCK_SIZE)\n } else {\n (msg_block, msg_byte_ptr)\n }\n}\n\nunconstrained fn attach_len_to_msg_block(\n mut msg_block: [u8; BLOCK_SIZE],\n msg_byte_ptr: u32,\n message_size: u32,\n) -> [u8; BLOCK_SIZE] {\n // We assume that `msg_byte_ptr` is less than 57 because if not then it is reset to zero before calling this function.\n // In any case, fill blocks up with zeros until the last 64 (i.e. until msg_byte_ptr = 56).\n for i in msg_byte_ptr..56 {\n msg_block[i] = 0;\n }\n\n let len = 8 * message_size;\n let len_bytes: [u8; 8] = (len as Field).to_be_bytes();\n for i in 0..8 {\n msg_block[56 + i] = len_bytes[i];\n }\n msg_block\n}\n\nfn hash_final_block(msg_block: [u8; BLOCK_SIZE], mut state: [u32; 8]) -> [u8; 32] {\n let mut out_h: [u8; 32] = [0; 32]; // Digest as sequence of bytes\n // Hash final padded block\n state = sha256_compression(msg_u8_to_u32(msg_block), state);\n\n // Return final hash as byte array\n for j in 0..8 {\n let h_bytes: [u8; 4] = (state[7 - j] as Field).to_le_bytes();\n for k in 0..4 {\n out_h[31 - 4 * j - k] = h_bytes[k];\n }\n }\n\n out_h\n}\n\nmod tests {\n use super::sha256_var;\n\n #[test]\n fn smoke_test() {\n let input = [0xbd];\n let result = [\n 0x68, 0x32, 0x57, 0x20, 0xaa, 0xbd, 0x7c, 0x82, 0xf3, 0x0f, 0x55, 0x4b, 0x31, 0x3d,\n 0x05, 0x70, 0xc9, 0x5a, 0xcc, 0xbb, 0x7d, 0xc4, 0xb5, 0xaa, 0xe1, 0x12, 0x04, 0xc0,\n 0x8f, 0xfe, 0x73, 0x2b,\n ];\n assert_eq(sha256_var(input, input.len() as u64), result);\n }\n\n #[test]\n fn msg_just_over_block() {\n let input = [\n 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117,\n 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99,\n 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112,\n 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116,\n ];\n let result = [\n 91, 122, 146, 93, 52, 109, 133, 148, 171, 61, 156, 70, 189, 238, 153, 7, 222, 184, 94,\n 24, 65, 114, 192, 244, 207, 199, 87, 232, 192, 224, 171, 207,\n ];\n assert_eq(sha256_var(input, input.len() as u64), result);\n }\n\n #[test]\n fn msg_multiple_over_block() {\n let input = [\n 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117,\n 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99,\n 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112,\n 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 117, 115, 45, 97, 115,\n 99, 105, 105, 13, 10, 109, 105, 109, 101, 45, 118, 101, 114, 115, 105, 111, 110, 58, 49,\n 46, 48, 32, 40, 77, 97, 99, 32, 79, 83, 32, 88, 32, 77, 97, 105, 108, 32, 49, 54, 46,\n 48, 32, 92, 40, 51, 55, 51, 49, 46, 53, 48, 48, 46, 50, 51, 49, 92, 41, 41, 13, 10, 115,\n 117, 98, 106, 101, 99, 116, 58, 72, 101, 108, 108, 111, 13, 10, 109, 101, 115, 115, 97,\n 103, 101, 45, 105, 100, 58, 60, 56, 70, 56, 49, 57, 68, 51, 50, 45, 66, 54, 65, 67, 45,\n 52, 56, 57, 68, 45, 57, 55, 55, 70, 45, 52, 51, 56, 66, 66, 67, 52, 67, 65, 66, 50, 55,\n 64, 109, 101, 46, 99, 111, 109, 62, 13, 10, 100, 97, 116, 101, 58, 83, 97, 116, 44, 32,\n 50, 54, 32, 65, 117, 103, 32, 50, 48, 50, 51, 32, 49, 50, 58, 50, 53, 58, 50, 50, 32,\n 43, 48, 52, 48, 48, 13, 10, 116, 111, 58, 122, 107, 101, 119, 116, 101, 115, 116, 64,\n 103, 109, 97, 105, 108, 46, 99, 111, 109, 13, 10, 100, 107, 105, 109, 45, 115, 105, 103,\n 110, 97, 116, 117, 114, 101, 58, 118, 61, 49, 59, 32, 97, 61, 114, 115, 97, 45, 115,\n 104, 97, 50, 53, 54, 59, 32, 99, 61, 114, 101, 108, 97, 120, 101, 100, 47, 114, 101,\n 108, 97, 120, 101, 100, 59, 32, 100, 61, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109,\n 59, 32, 115, 61, 49, 97, 49, 104, 97, 105, 59, 32, 116, 61, 49, 54, 57, 51, 48, 51, 56,\n 51, 51, 55, 59, 32, 98, 104, 61, 55, 120, 81, 77, 68, 117, 111, 86, 86, 85, 52, 109, 48,\n 87, 48, 87, 82, 86, 83, 114, 86, 88, 77, 101, 71, 83, 73, 65, 83, 115, 110, 117, 99, 75,\n 57, 100, 74, 115, 114, 99, 43, 118, 85, 61, 59, 32, 104, 61, 102, 114, 111, 109, 58, 67,\n 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 77, 105, 109, 101, 45, 86, 101,\n 114, 115, 105, 111, 110, 58, 83, 117, 98, 106, 101, 99,\n ];\n let result = [\n 116, 90, 151, 31, 78, 22, 138, 180, 211, 189, 69, 76, 227, 200, 155, 29, 59, 123, 154,\n 60, 47, 153, 203, 129, 157, 251, 48, 2, 79, 11, 65, 47,\n ];\n assert_eq(sha256_var(input, input.len() as u64), result);\n }\n\n #[test]\n fn msg_just_under_block() {\n let input = [\n 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117,\n 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99,\n 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112,\n 108, 97, 105, 110, 59,\n ];\n let result = [\n 143, 140, 76, 173, 222, 123, 102, 68, 70, 149, 207, 43, 39, 61, 34, 79, 216, 252, 213,\n 165, 74, 16, 110, 74, 29, 64, 138, 167, 30, 1, 9, 119,\n ];\n assert_eq(sha256_var(input, input.len() as u64), result);\n }\n\n #[test]\n fn msg_big_not_block_multiple() {\n let input = [\n 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117,\n 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99,\n 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112,\n 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 117, 115, 45, 97, 115,\n 99, 105, 105, 13, 10, 109, 105, 109, 101, 45, 118, 101, 114, 115, 105, 111, 110, 58, 49,\n 46, 48, 32, 40, 77, 97, 99, 32, 79, 83, 32, 88, 32, 77, 97, 105, 108, 32, 49, 54, 46,\n 48, 32, 92, 40, 51, 55, 51, 49, 46, 53, 48, 48, 46, 50, 51, 49, 92, 41, 41, 13, 10, 115,\n 117, 98, 106, 101, 99, 116, 58, 72, 101, 108, 108, 111, 13, 10, 109, 101, 115, 115, 97,\n 103, 101, 45, 105, 100, 58, 60, 56, 70, 56, 49, 57, 68, 51, 50, 45, 66, 54, 65, 67, 45,\n 52, 56, 57, 68, 45, 57, 55, 55, 70, 45, 52, 51, 56, 66, 66, 67, 52, 67, 65, 66, 50, 55,\n 64, 109, 101, 46, 99, 111, 109, 62, 13, 10, 100, 97, 116, 101, 58, 83, 97, 116, 44, 32,\n 50, 54, 32, 65, 117, 103, 32, 50, 48, 50, 51, 32, 49, 50, 58, 50, 53, 58, 50, 50, 32,\n 43, 48, 52, 48, 48, 13, 10, 116, 111, 58, 122, 107, 101, 119, 116, 101, 115, 116, 64,\n 103, 109, 97, 105, 108, 46, 99, 111, 109, 13, 10, 100, 107, 105, 109, 45, 115, 105, 103,\n 110, 97, 116, 117, 114, 101, 58, 118, 61, 49, 59, 32, 97, 61, 114, 115, 97, 45, 115,\n 104, 97, 50, 53, 54, 59, 32, 99, 61, 114, 101, 108, 97, 120, 101, 100, 47, 114, 101,\n 108, 97, 120, 101, 100, 59, 32, 100, 61, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109,\n 59, 32, 115, 61, 49, 97, 49, 104, 97, 105, 59, 32, 116, 61, 49, 54, 57, 51, 48, 51, 56,\n 51, 51, 55, 59, 32, 98, 104, 61, 55, 120, 81, 77, 68, 117, 111, 86, 86, 85, 52, 109, 48,\n 87, 48, 87, 82, 86, 83, 114, 86, 88, 77, 101, 71, 83, 73, 65, 83, 115, 110, 117, 99, 75,\n 57, 100, 74, 115, 114, 99, 43, 118, 85, 61, 59, 32, 104, 61, 102, 114, 111, 109, 58, 67,\n 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 77, 105, 109, 101, 45, 86, 101,\n 114, 115, 105, 111, 110, 58, 83, 117, 98, 106, 101, 99, 116, 58, 77, 101, 115, 115, 97,\n 103, 101, 45, 73, 100, 58, 68, 97, 116, 101, 58, 116, 111, 59, 32, 98, 61,\n ];\n let result = [\n 112, 144, 73, 182, 208, 98, 9, 238, 54, 229, 61, 145, 222, 17, 72, 62, 148, 222, 186,\n 55, 192, 82, 220, 35, 66, 47, 193, 200, 22, 38, 26, 186,\n ];\n assert_eq(sha256_var(input, input.len() as u64), result);\n }\n\n #[test]\n fn msg_big_with_padding() {\n let input = [\n 48, 130, 1, 37, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 48, 130, 1, 17,\n 48, 37, 2, 1, 1, 4, 32, 176, 223, 31, 133, 108, 84, 158, 102, 70, 11, 165, 175, 196, 12,\n 201, 130, 25, 131, 46, 125, 156, 194, 28, 23, 55, 133, 157, 164, 135, 136, 220, 78, 48,\n 37, 2, 1, 2, 4, 32, 190, 82, 180, 235, 222, 33, 79, 50, 152, 136, 142, 35, 116, 224, 6,\n 242, 156, 141, 128, 248, 10, 61, 98, 86, 248, 45, 207, 210, 90, 232, 175, 38, 48, 37, 2,\n 1, 3, 4, 32, 0, 194, 104, 108, 237, 246, 97, 230, 116, 198, 69, 110, 26, 87, 17, 89,\n 110, 199, 108, 250, 36, 21, 39, 87, 110, 102, 250, 213, 174, 131, 171, 174, 48, 37, 2,\n 1, 11, 4, 32, 136, 155, 87, 144, 111, 15, 152, 127, 85, 25, 154, 81, 20, 58, 51, 75,\n 193, 116, 234, 0, 60, 30, 29, 30, 183, 141, 72, 247, 255, 203, 100, 124, 48, 37, 2, 1,\n 12, 4, 32, 41, 234, 106, 78, 31, 11, 114, 137, 237, 17, 92, 71, 134, 47, 62, 78, 189,\n 233, 201, 214, 53, 4, 47, 189, 201, 133, 6, 121, 34, 131, 64, 142, 48, 37, 2, 1, 13, 4,\n 32, 91, 222, 210, 193, 62, 222, 104, 82, 36, 41, 138, 253, 70, 15, 148, 208, 156, 45,\n 105, 171, 241, 195, 185, 43, 217, 162, 146, 201, 222, 89, 238, 38, 48, 37, 2, 1, 14, 4,\n 32, 76, 123, 216, 13, 51, 227, 72, 245, 59, 193, 238, 166, 103, 49, 23, 164, 171, 188,\n 194, 197, 156, 187, 249, 28, 198, 95, 69, 15, 182, 56, 54, 38, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n ];\n let result = [\n 32, 85, 108, 174, 127, 112, 178, 182, 8, 43, 134, 123, 192, 211, 131, 66, 184, 240, 212,\n 181, 240, 180, 106, 195, 24, 117, 54, 129, 19, 10, 250, 53,\n ];\n let message_size = 297;\n assert_eq(sha256_var(input, message_size), result);\n }\n\n #[test]\n fn msg_big_no_padding() {\n let input = [\n 48, 130, 1, 37, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 48, 130, 1, 17,\n 48, 37, 2, 1, 1, 4, 32, 176, 223, 31, 133, 108, 84, 158, 102, 70, 11, 165, 175, 196, 12,\n 201, 130, 25, 131, 46, 125, 156, 194, 28, 23, 55, 133, 157, 164, 135, 136, 220, 78, 48,\n 37, 2, 1, 2, 4, 32, 190, 82, 180, 235, 222, 33, 79, 50, 152, 136, 142, 35, 116, 224, 6,\n 242, 156, 141, 128, 248, 10, 61, 98, 86, 248, 45, 207, 210, 90, 232, 175, 38, 48, 37, 2,\n 1, 3, 4, 32, 0, 194, 104, 108, 237, 246, 97, 230, 116, 198, 69, 110, 26, 87, 17, 89,\n 110, 199, 108, 250, 36, 21, 39, 87, 110, 102, 250, 213, 174, 131, 171, 174, 48, 37, 2,\n 1, 11, 4, 32, 136, 155, 87, 144, 111, 15, 152, 127, 85, 25, 154, 81, 20, 58, 51, 75,\n 193, 116, 234, 0, 60, 30, 29, 30, 183, 141, 72, 247, 255, 203, 100, 124, 48, 37, 2, 1,\n 12, 4, 32, 41, 234, 106, 78, 31, 11, 114, 137, 237, 17, 92, 71, 134, 47, 62, 78, 189,\n 233, 201, 214, 53, 4, 47, 189, 201, 133, 6, 121, 34, 131, 64, 142, 48, 37, 2, 1, 13, 4,\n 32, 91, 222, 210, 193, 62, 222, 104, 82, 36, 41, 138, 253, 70, 15, 148, 208, 156, 45,\n 105, 171, 241, 195, 185, 43, 217, 162, 146, 201, 222, 89, 238, 38, 48, 37, 2, 1, 14, 4,\n 32, 76, 123, 216, 13, 51, 227, 72, 245, 59, 193, 238, 166, 103, 49, 23, 164, 171, 188,\n 194, 197, 156, 187, 249, 28, 198, 95, 69, 15, 182, 56, 54, 38,\n ];\n let result = [\n 32, 85, 108, 174, 127, 112, 178, 182, 8, 43, 134, 123, 192, 211, 131, 66, 184, 240, 212,\n 181, 240, 180, 106, 195, 24, 117, 54, 129, 19, 10, 250, 53,\n ];\n assert_eq(sha256_var(input, input.len() as u64), result);\n }\n\n #[test]\n fn same_msg_len_variable_padding() {\n let input = [\n 29, 81, 165, 84, 243, 114, 101, 37, 242, 146, 127, 99, 69, 145, 39, 72, 213, 39, 253,\n 179, 218, 37, 217, 201, 172, 93, 198, 50, 249, 70, 15, 30, 162, 112, 187, 40, 140, 9,\n 236, 53, 32, 44, 38, 163, 113, 254, 192, 197, 44, 89, 71, 130, 169, 242, 17, 211, 214,\n 72, 19, 178, 186, 168, 147, 127, 99, 101, 252, 227, 8, 147, 150, 85, 97, 158, 17, 107,\n 218, 244, 82, 113, 247, 91, 208, 214, 60, 244, 87, 137, 173, 201, 130, 18, 66, 56, 198,\n 149, 207, 189, 175, 120, 123, 224, 177, 167, 251, 159, 143, 110, 68, 183, 189, 70, 126,\n 32, 35, 164, 44, 30, 44, 12, 65, 18, 62, 239, 242, 2, 248, 104, 2, 178, 64, 28, 126, 36,\n 137, 24, 14, 116, 91, 98, 90, 159, 218, 102, 45, 11, 110, 223, 245, 184, 52, 99, 59,\n 245, 136, 175, 3, 72, 164, 146, 145, 116, 22, 66, 24, 49, 193, 121, 3, 60, 37, 41, 97,\n 3, 190, 66, 195, 225, 63, 46, 3, 118, 4, 208, 15, 1, 40, 254, 235, 151, 123, 70, 180,\n 170, 44, 172, 90, 4, 254, 53, 239, 116, 246, 67, 56, 129, 61, 22, 169, 213, 65, 27, 216,\n 116, 162, 239, 214, 207, 126, 177, 20, 100, 25, 48, 143, 84, 215, 70, 197, 53, 65, 70,\n 86, 172, 61, 62, 9, 212, 167, 169, 133, 41, 126, 213, 196, 33, 192, 238, 0, 63, 246,\n 215, 58, 128, 110, 101, 92, 3, 170, 214, 130, 149, 52, 81, 125, 118, 233, 3, 118, 193,\n 104, 207, 120, 115, 77, 253, 191, 122, 0, 107, 164, 207, 113, 81, 169, 36, 201, 228, 74,\n 134, 131, 218, 178, 35, 30, 216, 101, 2, 103, 174, 87, 95, 50, 50, 215, 157, 5, 210,\n 188, 54, 211, 78, 45, 199, 96, 121, 241, 241, 176, 226, 194, 134, 130, 89, 217, 210,\n 186, 32, 140, 39, 91, 103, 212, 26, 87, 32, 72, 144, 228, 230, 117, 99, 188, 50, 15, 69,\n 79, 179, 50, 12, 106, 86, 218, 101, 73, 142, 243, 29, 250, 122, 228, 233, 29, 255, 22,\n 121, 114, 125, 103, 41, 250, 241, 179, 126, 158, 198, 116, 209, 65, 94, 98, 228, 175,\n 169, 96, 3, 9, 233, 133, 214, 55, 161, 164, 103, 80, 85, 24, 186, 64, 167, 92, 131, 53,\n 101, 202, 47, 25, 104, 118, 155, 14, 12, 12, 25, 116, 45, 221, 249, 28, 246, 212, 200,\n 157, 167, 169, 56, 197, 181, 4, 245, 146, 1, 140, 234, 191, 212, 228, 125, 87, 81, 86,\n 119, 30, 63, 129, 143, 32, 96,\n ];\n\n // Prepare inputs of different lengths\n let mut input_511 = [0; 511];\n let mut input_512 = [0; 512]; // Next block\n let mut input_575 = [0; 575];\n let mut input_576 = [0; 576]; // Next block\n for i in 0..input.len() {\n input_511[i] = input[i];\n input_512[i] = input[i];\n input_575[i] = input[i];\n input_576[i] = input[i];\n }\n\n // Compute hashes of all inputs (with same message length)\n let fixed_length_hash = super::sha256(input);\n let var_full_length_hash = sha256_var(input, input.len() as u64);\n let var_length_hash_511 = sha256_var(input_511, input.len() as u64);\n let var_length_hash_512 = sha256_var(input_512, input.len() as u64);\n let var_length_hash_575 = sha256_var(input_575, input.len() as u64);\n let var_length_hash_576 = sha256_var(input_576, input.len() as u64);\n\n // All of the above should have produced the same hash\n assert_eq(var_full_length_hash, fixed_length_hash);\n assert_eq(var_length_hash_511, fixed_length_hash);\n assert_eq(var_length_hash_512, fixed_length_hash);\n assert_eq(var_length_hash_575, fixed_length_hash);\n assert_eq(var_length_hash_576, fixed_length_hash);\n }\n}\n","path":"std/hash/sha256.nr"},"70":{"source":"use crate::utils::{MAX_ECONTENT_LEN, HASH_LEN_BYTES, DG_PADDING_BYTES_LEN, MAX_SIGNED_ATTR_LEN};\nuse std::hash::sha256;\n\npub fn verify_dg1_and_dg2(\n dg1: [u8; 93],\n dg1_hash_offset: u8,\n dg2_hash: [u8; 64],\n eContent: [u8; MAX_ECONTENT_LEN],\n) {\n let computed_dg1_hash = sha256(dg1);\n\n // Calc position where DG2 hash should start\n let dg2_hash_start = dg1_hash_offset as u32 + HASH_LEN_BYTES + DG_PADDING_BYTES_LEN;\n\n // Verify DG1,DG2 hash matches in eContent\n for i in 0..HASH_LEN_BYTES {\n assert_eq(computed_dg1_hash[i], eContent[dg1_hash_offset as u32 + i as u32]);\n assert_eq(dg2_hash[i], eContent[dg2_hash_start + i as u32]);\n }\n}\n\n// todo\npub fn verify_econtent(\n eContent: [u8; MAX_ECONTENT_LEN],\n signed_attr: [u8; MAX_SIGNED_ATTR_LEN],\n signed_attr_econtent_hash_offset: u8,\n eContent_padded_length: u16,\n signed_attr_padded_length: u8,\n) {}\n\n","path":"/Users/vikasrushi/openpassport/noir/src/dg1.nr"},"72":{"source":"use crate::utils::{MAX_ECONTENT_LEN, MAX_SIGNED_ATTR_LEN};\nuse crate::dg1::{verify_dg1_and_dg2, verify_econtent};\n\npub mod dg1;\npub mod utils;\n\nfn main(\n dg1: [u8; 93],\n dg1_hash_offset: u8,\n dg2_hash: [u8; 64],\n eContent: [u8; MAX_ECONTENT_LEN],\n signed_attr: [u8; MAX_SIGNED_ATTR_LEN],\n signed_attr_econtent_hash_offset: u8,\n eContent_padded_length: u16,\n signed_attr_padded_length: u8,\n) {\n verify_dg1_and_dg2(dg1, dg1_hash_offset, dg2_hash, eContent);\n\n verify_econtent(\n eContent,\n signed_attr,\n signed_attr_econtent_hash_offset,\n eContent_padded_length,\n signed_attr_padded_length,\n );\n}\n\n","path":"/Users/vikasrushi/openpassport/noir/src/main.nr"}},"names":["main"],"brillig_names":["build_msg_block_iter","pad_msg_block","attach_len_to_msg_block","directive_integer_quotient","directive_invert"]} \ No newline at end of file