diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/Nargo.toml b/noir-examples/noir-passport-examples/fragmented_age_check/Nargo.toml new file mode 100644 index 00000000..8a8d00fd --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/Nargo.toml @@ -0,0 +1,10 @@ +[workspace] +members = [ + "sig_check_dsc_720", + "sig_check_dsc_1300_hash", + "sig_check_dsc_1300_verify", + "sig_check_id_data_720", + "sig_check_id_data_1300", + "data_check_integrity_sa", + "compare_age", +] diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/README.md b/noir-examples/noir-passport-examples/fragmented_age_check/README.md new file mode 100644 index 00000000..92c98a3b --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/README.md @@ -0,0 +1,25 @@ +# Fragmented zkPassport Age Verification + +This directory contains two approaches for zkPassport age verification, optimized based on TBS certificate size. + +## Approach 1: 4-Circuit Chain + +**Used when**: TBS certificate actual length < 720 bytes (padded to exactly 720 bytes) + +**Circuits**: +1. [sig_check_dsc_720](sig_check_dsc_720/) - Verify CSCA signed DSC certificate +2. [sig_check_id_data_720](sig_check_id_data_720/) - Verify DSC signed passport data +3. [data_check_integrity_sa](data_check_integrity_sa/) - Verify data integrity (DG1 → eContent → SignedAttributes) +4. [compare_age](compare_age/) - Extract DOB from MRZ, compute age, generate nullifier + +## Approach 2: 5-Circuit Chain + +**Used when**: TBS certificate actual length >= 720 bytes (padded to exactly 1300 bytes) + +**Circuits**: +1. [sig_check_dsc_1300_hash](sig_check_dsc_1300_hash/) - Process first 640 bytes of DSC certificate (SHA256 start) +2. [sig_check_dsc_1300_verify](sig_check_dsc_1300_verify/) - Complete SHA256 and verify CSCA signature +3. [sig_check_id_data_1300](sig_check_id_data_1300/) - Verify DSC signed passport data +4. [data_check_integrity_sa](data_check_integrity_sa/) - Verify data integrity (DG1 → eContent → SignedAttributes) +5. [compare_age](compare_age/) - Extract DOB from MRZ, compute age, generate nullifier + diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/compare_age_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/compare_age_prover.toml new file mode 100644 index 00000000..7edd3269 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/compare_age_prover.toml @@ -0,0 +1,10 @@ +comm_in = "0x13ddc00c81d5d01bc387262c471bba35c357a93b0b6dd5afd493e6ca3a332ffd" +current_date = 1758300539 +salted_private_nullifier = { salt = "0x3", value = "0x1926a3c576ec5e1ca8b46ce0926cb03dd74461874126a1ba1a5d8c7d30408695", hash = "0x0" } +salted_expiry_date = { salt = "0x3", value = [51, 50, 48, 49, 48, 49], hash = "0x0" } +salted_dg1 = { salt = "0x3", value = [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 48, 55, 48, 49, 48, 49, 60, 60, 51, 50, 48, 49, 48, 49, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 0], hash = "0x0" } +min_age_required = 18 +max_age_required = 70 +nullifier_secret = "0x0" +service_scope = "0x0" +service_subscope = "0x0" diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/data_check_integrity_sa_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/data_check_integrity_sa_prover.toml new file mode 100644 index 00000000..632a41ac --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/data_check_integrity_sa_prover.toml @@ -0,0 +1,11 @@ +comm_in = "0x0474e94cd1216de623c7e80e47a315d3d00c52a22bda4f331f5fdfd999da21be" +salt_in = "0x2" +salted_dg1 = { salt = "0x3", value = [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 48, 55, 48, 49, 48, 49, 60, 60, 51, 50, 48, 49, 48, 49, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 0], hash = "0x0" } +expiry_date_salt = "0x3" +dg1_hash_offset= 0 +dg1_padded_length=95 +signed_attributes = [213, 19, 219, 127, 44, 247, 154, 190, 26, 122, 188, 163, 73, 227, 191, 71, 139, 129, 120, 193, 5, 130, 52, 127, 40, 83, 242, 75, 244, 200, 248, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 = [54, 197, 174, 86, 62, 194, 237, 211, 184, 91, 92, 169, 195, 149, 233, 156, 60, 80, 224, 124, 161, 170, 204, 239, 154, 92, 165, 10, 81, 42, 90, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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_len = 32 +signed_attributes_size = 32 +salted_private_nullifier = { salt = "0x3", value = "0x1926a3c576ec5e1ca8b46ce0926cb03dd74461874126a1ba1a5d8c7d30408695", hash = "0x0" } diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/sig_check_dsc_720_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/sig_check_dsc_720_prover.toml new file mode 100644 index 00000000..6ba31956 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/sig_check_dsc_720_prover.toml @@ -0,0 +1,8 @@ +csc_pubkey = [191, 56, 52, 58, 68, 102, 237, 183, 171, 195, 84, 11, 3, 233, 51, 203, 74, 37, 42, 68, 152, 19, 154, 192, 131, 19, 113, 213, 124, 239, 224, 225, 165, 80, 127, 141, 153, 142, 67, 27, 80, 195, 133, 114, 240, 90, 185, 199, 165, 202, 176, 89, 69, 36, 65, 105, 30, 110, 4, 208, 12, 242, 135, 138, 112, 0, 112, 23, 63, 255, 106, 101, 85, 230, 227, 208, 200, 233, 85, 158, 57, 216, 198, 32, 116, 4, 181, 10, 208, 243, 151, 165, 147, 187, 14, 133, 61, 31, 15, 146, 160, 16, 91, 221, 65, 81, 131, 77, 250, 8, 5, 30, 244, 110, 139, 157, 228, 250, 47, 54, 46, 153, 235, 164, 201, 64, 61, 171, 152, 23, 115, 253, 143, 134, 106, 100, 221, 126, 124, 29, 158, 68, 169, 153, 8, 134, 19, 141, 243, 173, 103, 176, 135, 248, 179, 254, 74, 187, 86, 47, 12, 204, 128, 145, 46, 121, 60, 229, 217, 220, 247, 135, 186, 158, 69, 91, 128, 116, 92, 152, 233, 139, 249, 106, 63, 203, 217, 86, 113, 2, 78, 165, 244, 86, 152, 213, 164, 36, 24, 179, 100, 67, 182, 69, 30, 5, 131, 11, 129, 211, 171, 52, 237, 148, 104, 197, 107, 44, 64, 38, 244, 242, 170, 3, 191, 182, 145, 129, 165, 236, 217, 97, 192, 75, 17, 254, 254, 33, 68, 205, 70, 79, 134, 69, 244, 176, 24, 133, 19, 70, 24, 170, 161, 72, 171, 48, 146, 75, 134, 119, 13, 39, 217, 189, 2, 173, 141, 136, 176, 140, 220, 230, 94, 151, 182, 4, 120, 218, 39, 115, 34, 78, 139, 102, 230, 227, 223, 78, 72, 133, 59, 224, 128, 79, 71, 67, 133, 171, 11, 66, 200, 133, 21, 76, 125, 126, 111, 212, 29, 7, 92, 4, 5, 189, 41, 21, 15, 96, 31, 28, 233, 156, 44, 254, 47, 121, 82, 71, 133, 69, 3, 135, 247, 237, 29, 140, 111, 2, 232, 200, 129, 234, 113, 146, 243, 148, 127, 227, 183, 110, 190, 65, 93, 136, 180, 104, 17, 121, 45, 128, 216, 192, 95, 111, 75, 47, 182, 96, 41, 126, 100, 40, 129, 43, 154, 14, 220, 192, 8, 64, 47, 153, 2, 244, 140, 51, 4, 212, 105, 249, 255, 60, 143, 2, 60, 86, 176, 65, 253, 132, 133, 84, 56, 165, 169, 121, 182, 176, 237, 210, 209, 119, 253, 138, 95, 127, 194, 72, 248, 212, 91, 87, 203, 173, 38, 80, 222, 101, 163, 252, 86, 186, 143, 161, 184, 70, 24, 248, 230, 196, 157, 35, 205, 39, 49, 136, 8, 204, 176, 116, 68, 167, 1, 10, 217, 82, 208, 215, 28, 231, 252, 203, 70, 240, 62, 4, 211, 209, 148, 141, 44, 246, 215, 112, 162, 20, 129, 94, 123, 230, 126, 128, 33, 41, 231, 119, 64, 51, 253, 166, 145, 64, 10, 158, 141, 43, 193, 20, 69, 15, 194, 35, 139, 233, 28, 240, 166, 131, 61, 187, 241, 129] +salt = "0x1" +country = "<<<" +tbs_certificate = [48, 130, 1, 10, 2, 130, 1, 1, 0, 144, 96, 22, 98, 202, 23, 238, 6, 187, 83, 246, 10, 141, 149, 39, 62, 150, 207, 25, 76, 254, 121, 159, 193, 25, 17, 64, 229, 112, 170, 152, 94, 212, 213, 4, 191, 8, 183, 225, 184, 213, 181, 211, 100, 210, 60, 155, 26, 13, 219, 11, 116, 84, 236, 33, 212, 47, 5, 187, 226, 120, 161, 57, 97, 200, 250, 174, 139, 216, 171, 95, 178, 148, 109, 3, 137, 151, 245, 142, 53, 177, 251, 74, 202, 2, 157, 33, 55, 30, 189, 239, 243, 101, 183, 43, 68, 245, 198, 9, 90, 109, 89, 109, 33, 98, 32, 173, 121, 203, 2, 79, 68, 150, 135, 158, 72, 76, 223, 55, 66, 30, 45, 33, 16, 91, 153, 158, 127, 64, 221, 31, 151, 241, 93, 105, 235, 153, 176, 146, 221, 20, 231, 141, 2, 146, 77, 209, 30, 90, 33, 33, 232, 176, 145, 244, 229, 221, 43, 101, 10, 210, 55, 50, 200, 103, 87, 18, 82, 53, 193, 130, 124, 69, 96, 179, 87, 245, 203, 181, 205, 57, 67, 181, 80, 198, 57, 101, 151, 179, 103, 201, 243, 52, 68, 91, 122, 137, 209, 141, 39, 68, 73, 244, 200, 211, 125, 2, 176, 12, 80, 77, 81, 225, 169, 34, 209, 187, 212, 47, 56, 92, 220, 159, 89, 236, 133, 200, 211, 11, 237, 217, 129, 115, 191, 208, 39, 198, 179, 16, 28, 59, 121, 160, 48, 239, 81, 144, 102, 168, 122, 158, 59, 83, 54, 91, 211, 2, 3, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +csc_pubkey_redc_param = [21, 107, 159, 157, 72, 119, 18, 0, 27, 71, 177, 110, 89, 195, 140, 32, 0, 81, 204, 142, 10, 42, 57, 174, 56, 49, 20, 174, 40, 168, 13, 110, 119, 62, 130, 206, 113, 131, 163, 69, 216, 148, 52, 169, 100, 129, 114, 255, 46, 231, 61, 14, 80, 203, 136, 94, 50, 194, 33, 127, 20, 160, 234, 71, 20, 201, 8, 231, 223, 0, 192, 38, 138, 232, 188, 101, 68, 103, 102, 81, 27, 78, 37, 96, 11, 135, 61, 12, 158, 37, 141, 215, 151, 25, 176, 135, 41, 133, 163, 113, 221, 161, 175, 226, 9, 113, 252, 229, 239, 48, 55, 162, 33, 178, 224, 94, 18, 161, 220, 186, 163, 10, 133, 85, 127, 74, 95, 74, 192, 164, 69, 236, 121, 95, 224, 115, 181, 169, 156, 121, 161, 180, 127, 61, 26, 113, 65, 35, 241, 87, 67, 152, 40, 160, 29, 190, 249, 119, 178, 40, 99, 198, 222, 102, 162, 68, 138, 169, 237, 193, 199, 151, 159, 80, 118, 20, 141, 97, 224, 76, 212, 29, 80, 238, 32, 234, 172, 151, 141, 134, 227, 177, 61, 106, 9, 105, 194, 149, 232, 171, 165, 135, 244, 24, 214, 213, 28, 115, 68, 75, 160, 198, 129, 73, 238, 59, 59, 4, 45, 101, 235, 220, 224, 224, 5, 76, 13, 218, 137, 189, 174, 52, 38, 192, 245, 127, 138, 81, 96, 255, 162, 119, 44, 210, 247, 66, 99, 3, 202, 110, 26, 174, 27, 157, 15, 85, 81, 115, 162, 35, 217, 73, 84, 139, 198, 206, 205, 93, 221, 207, 182, 126, 20, 211, 178, 23, 232, 95, 253, 252, 254, 211, 143, 149, 130, 102, 69, 47, 230, 141, 23, 107, 148, 35, 98, 85, 98, 111, 238, 85, 148, 111, 251, 83, 220, 88, 156, 81, 27, 196, 8, 5, 66, 216, 111, 3, 226, 212, 80, 151, 38, 164, 172, 189, 112, 224, 225, 98, 165, 86, 180, 31, 32, 249, 202, 127, 244, 142, 127, 17, 239, 16, 41, 1, 191, 113, 134, 18, 66, 251, 227, 254, 73, 53, 180, 104, 27, 133, 32, 198, 218, 159, 226, 32, 79, 136, 115, 52, 110, 242, 239, 204, 109, 154, 29, 180, 85, 142, 244, 160, 90, 14, 37, 236, 159, 130, 229, 169, 11, 37, 132, 37, 49, 124, 225, 206, 164, 202, 94, 34, 8, 5, 49, 56, 17, 171, 65, 211, 126, 42, 109, 62, 176, 132, 107, 62, 190, 141, 214, 11, 217, 6, 52, 198, 157, 181, 22, 107, 245, 249, 222, 4, 71, 63, 54, 104, 23, 171, 180, 131, 16, 230, 23, 94, 39, 61, 149, 204, 15, 42, 7, 187, 147, 37, 55, 67, 188, 147, 194, 254, 154, 193, 95, 227, 162, 216, 3, 127, 116, 248, 115, 121, 126, 176, 253, 175, 7, 245, 175, 129, 254, 70, 151, 36, 174, 235, 172, 158, 244, 206, 119, 184, 231, 1, 14, 162, 152, 159, 97, 136, 82, 216, 75, 161, 36, 208, 59, 62, 13, 12, 35, 82, 236] +dsc_signature = [71, 151, 90, 104, 225, 194, 204, 189, 133, 238, 99, 243, 154, 33, 179, 225, 16, 61, 209, 231, 178, 20, 10, 41, 218, 115, 35, 100, 165, 196, 140, 201, 144, 176, 84, 28, 141, 196, 127, 247, 234, 183, 55, 102, 230, 157, 209, 2, 35, 235, 82, 126, 131, 245, 25, 60, 149, 44, 150, 113, 186, 83, 136, 220, 43, 195, 6, 82, 238, 87, 88, 26, 60, 14, 243, 84, 14, 216, 239, 139, 152, 108, 134, 184, 173, 109, 237, 100, 24, 132, 38, 204, 127, 184, 90, 12, 227, 198, 79, 121, 169, 157, 218, 114, 132, 153, 147, 135, 226, 41, 192, 253, 62, 55, 119, 193, 65, 236, 77, 150, 118, 245, 136, 133, 203, 25, 230, 208, 134, 31, 17, 236, 182, 20, 70, 47, 91, 177, 122, 182, 76, 118, 84, 27, 190, 39, 67, 47, 52, 98, 17, 1, 150, 87, 160, 226, 171, 189, 227, 205, 208, 166, 141, 43, 118, 39, 191, 146, 241, 176, 225, 178, 255, 101, 1, 133, 35, 103, 203, 147, 147, 0, 113, 6, 206, 134, 199, 64, 203, 248, 203, 174, 35, 99, 123, 223, 212, 70, 122, 213, 0, 61, 125, 205, 220, 136, 58, 37, 190, 26, 19, 13, 37, 2, 221, 152, 255, 89, 57, 1, 157, 72, 232, 84, 206, 221, 206, 233, 94, 247, 117, 227, 208, 206, 13, 245, 63, 195, 75, 224, 26, 99, 230, 232, 223, 90, 87, 170, 117, 216, 105, 241, 124, 246, 47, 60, 221, 159, 152, 20, 196, 235, 232, 25, 135, 174, 18, 204, 240, 11, 146, 51, 210, 235, 198, 119, 167, 232, 219, 28, 70, 181, 132, 138, 192, 18, 42, 80, 147, 168, 185, 248, 224, 26, 70, 116, 133, 150, 215, 250, 195, 165, 232, 18, 157, 24, 179, 22, 109, 4, 201, 236, 206, 25, 153, 44, 208, 222, 136, 39, 38, 13, 141, 115, 72, 114, 49, 0, 61, 247, 155, 211, 23, 75, 229, 128, 29, 13, 80, 236, 170, 80, 70, 219, 165, 106, 2, 37, 84, 29, 12, 10, 201, 238, 100, 237, 79, 214, 192, 228, 170, 181, 160, 211, 210, 215, 220, 139, 100, 142, 13, 161, 118, 52, 92, 141, 84, 237, 130, 139, 203, 97, 153, 234, 43, 11, 106, 168, 246, 146, 82, 212, 6, 149, 196, 166, 223, 219, 24, 57, 187, 219, 3, 3, 216, 191, 187, 147, 172, 35, 226, 142, 231, 79, 180, 17, 78, 102, 57, 160, 169, 45, 233, 40, 195, 137, 241, 24, 151, 228, 107, 125, 154, 227, 25, 213, 59, 124, 200, 183, 64, 181, 82, 47, 227, 146, 95, 48, 65, 34, 165, 28, 66, 162, 46, 175, 59, 108, 183, 153, 205, 48, 95, 165, 78, 18, 88, 154, 121, 211, 8, 125, 152, 120, 225, 237, 37, 49, 215, 93, 174, 197, 33, 189, 51, 30, 225, 223, 26, 30, 39, 143, 49, 74, 95, 227, 205, 194, 79, 72, 94, 254, 55, 197, 85, 69, 148, 242, 124, 64, 251, 186] +exponent = 65537 +tbs_certificate_len = 270 diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/sig_check_id_data_720_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/sig_check_id_data_720_prover.toml new file mode 100644 index 00000000..6f1902aa --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case1/sig_check_id_data_720_prover.toml @@ -0,0 +1,13 @@ +comm_in = "0x1001f704bdd46fedab2fb77c487e05382ae948fd4cd169cb0ed2564aa439b847" +salt_in = "0x1" +salt_out = "0x2" +dg1 = [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 48, 55, 48, 49, 48, 49, 60, 60, 51, 50, 48, 49, 48, 49, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 0] +dsc_pubkey = [144, 96, 22, 98, 202, 23, 238, 6, 187, 83, 246, 10, 141, 149, 39, 62, 150, 207, 25, 76, 254, 121, 159, 193, 25, 17, 64, 229, 112, 170, 152, 94, 212, 213, 4, 191, 8, 183, 225, 184, 213, 181, 211, 100, 210, 60, 155, 26, 13, 219, 11, 116, 84, 236, 33, 212, 47, 5, 187, 226, 120, 161, 57, 97, 200, 250, 174, 139, 216, 171, 95, 178, 148, 109, 3, 137, 151, 245, 142, 53, 177, 251, 74, 202, 2, 157, 33, 55, 30, 189, 239, 243, 101, 183, 43, 68, 245, 198, 9, 90, 109, 89, 109, 33, 98, 32, 173, 121, 203, 2, 79, 68, 150, 135, 158, 72, 76, 223, 55, 66, 30, 45, 33, 16, 91, 153, 158, 127, 64, 221, 31, 151, 241, 93, 105, 235, 153, 176, 146, 221, 20, 231, 141, 2, 146, 77, 209, 30, 90, 33, 33, 232, 176, 145, 244, 229, 221, 43, 101, 10, 210, 55, 50, 200, 103, 87, 18, 82, 53, 193, 130, 124, 69, 96, 179, 87, 245, 203, 181, 205, 57, 67, 181, 80, 198, 57, 101, 151, 179, 103, 201, 243, 52, 68, 91, 122, 137, 209, 141, 39, 68, 73, 244, 200, 211, 125, 2, 176, 12, 80, 77, 81, 225, 169, 34, 209, 187, 212, 47, 56, 92, 220, 159, 89, 236, 133, 200, 211, 11, 237, 217, 129, 115, 191, 208, 39, 198, 179, 16, 28, 59, 121, 160, 48, 239, 81, 144, 102, 168, 122, 158, 59, 83, 54, 91, 211] +dsc_pubkey_redc_param = [28, 94, 216, 205, 130, 214, 187, 182, 58, 208, 228, 159, 128, 141, 147, 245, 68, 203, 236, 129, 99, 140, 108, 211, 245, 198, 71, 176, 2, 196, 241, 58, 221, 37, 54, 244, 93, 131, 148, 193, 87, 121, 38, 188, 142, 196, 4, 105, 26, 37, 150, 148, 152, 205, 235, 126, 184, 93, 105, 56, 44, 19, 57, 156, 74, 145, 52, 201, 54, 91, 218, 1, 26, 107, 219, 199, 28, 10, 57, 32, 22, 195, 131, 58, 46, 165, 57, 181, 53, 133, 182, 229, 180, 5, 229, 103, 172, 187, 96, 43, 14, 4, 151, 199, 136, 53, 224, 199, 167, 81, 240, 180, 174, 254, 87, 255, 239, 218, 1, 170, 8, 126, 189, 0, 83, 125, 173, 191, 84, 53, 29, 80, 88, 48, 59, 50, 243, 156, 221, 1, 81, 7, 140, 195, 28, 126, 195, 88, 226, 224, 141, 129, 220, 242, 189, 217, 16, 44, 163, 154, 247, 61, 237, 213, 56, 204, 14, 199, 251, 110, 139, 117, 142, 16, 234, 116, 47, 82, 226, 88, 40, 15, 104, 74, 12, 48, 224, 229, 64, 4, 157, 1, 124, 203, 51, 181, 191, 194, 149, 113, 225, 34, 173, 236, 206, 22, 80, 189, 181, 158, 100, 248, 60, 60, 68, 157, 169, 68, 26, 229, 226, 151, 181, 39, 197, 51, 51, 171, 197, 130, 196, 219, 115, 145, 84, 69, 157, 247, 71, 141, 198, 109, 219, 255, 149, 228, 19, 23, 56, 175, 123, 107, 192, 219, 175, 130, 60] +dsc_pubkey_offset_in_dsc_cert = 9 +sod_signature = [113, 231, 195, 7, 247, 11, 13, 57, 73, 228, 48, 151, 133, 177, 43, 142, 233, 232, 70, 198, 60, 147, 234, 31, 248, 165, 161, 227, 36, 157, 234, 192, 235, 66, 210, 134, 202, 126, 240, 251, 47, 94, 6, 66, 165, 99, 234, 225, 135, 175, 214, 112, 243, 5, 12, 58, 222, 45, 16, 140, 95, 199, 207, 243, 17, 141, 236, 227, 27, 183, 92, 45, 92, 117, 20, 139, 103, 240, 111, 189, 113, 164, 58, 126, 186, 35, 39, 145, 166, 239, 112, 202, 131, 158, 133, 248, 79, 243, 9, 0, 128, 80, 184, 109, 14, 4, 40, 173, 155, 206, 61, 0, 149, 194, 127, 58, 248, 183, 11, 117, 246, 66, 248, 251, 74, 141, 219, 83, 53, 11, 222, 95, 146, 140, 147, 135, 235, 177, 214, 35, 212, 87, 103, 117, 40, 147, 213, 173, 201, 2, 233, 69, 28, 152, 17, 217, 168, 186, 12, 39, 27, 118, 62, 66, 202, 18, 180, 191, 20, 14, 158, 218, 47, 227, 158, 150, 150, 69, 205, 76, 190, 201, 137, 71, 240, 190, 250, 180, 225, 107, 131, 18, 221, 210, 116, 127, 218, 219, 60, 166, 172, 0, 104, 115, 76, 65, 186, 6, 109, 66, 73, 156, 158, 248, 7, 30, 208, 69, 51, 242, 110, 193, 169, 240, 188, 19, 64, 161, 116, 211, 138, 136, 15, 100, 130, 251, 1, 243, 115, 185, 237, 30, 196, 110, 105, 193, 248, 56, 97, 213, 178, 105, 201, 134, 50, 102] +tbs_certificate = [48, 130, 1, 10, 2, 130, 1, 1, 0, 144, 96, 22, 98, 202, 23, 238, 6, 187, 83, 246, 10, 141, 149, 39, 62, 150, 207, 25, 76, 254, 121, 159, 193, 25, 17, 64, 229, 112, 170, 152, 94, 212, 213, 4, 191, 8, 183, 225, 184, 213, 181, 211, 100, 210, 60, 155, 26, 13, 219, 11, 116, 84, 236, 33, 212, 47, 5, 187, 226, 120, 161, 57, 97, 200, 250, 174, 139, 216, 171, 95, 178, 148, 109, 3, 137, 151, 245, 142, 53, 177, 251, 74, 202, 2, 157, 33, 55, 30, 189, 239, 243, 101, 183, 43, 68, 245, 198, 9, 90, 109, 89, 109, 33, 98, 32, 173, 121, 203, 2, 79, 68, 150, 135, 158, 72, 76, 223, 55, 66, 30, 45, 33, 16, 91, 153, 158, 127, 64, 221, 31, 151, 241, 93, 105, 235, 153, 176, 146, 221, 20, 231, 141, 2, 146, 77, 209, 30, 90, 33, 33, 232, 176, 145, 244, 229, 221, 43, 101, 10, 210, 55, 50, 200, 103, 87, 18, 82, 53, 193, 130, 124, 69, 96, 179, 87, 245, 203, 181, 205, 57, 67, 181, 80, 198, 57, 101, 151, 179, 103, 201, 243, 52, 68, 91, 122, 137, 209, 141, 39, 68, 73, 244, 200, 211, 125, 2, 176, 12, 80, 77, 81, 225, 169, 34, 209, 187, 212, 47, 56, 92, 220, 159, 89, 236, 133, 200, 211, 11, 237, 217, 129, 115, 191, 208, 39, 198, 179, 16, 28, 59, 121, 160, 48, 239, 81, 144, 102, 168, 122, 158, 59, 83, 54, 91, 211, 2, 3, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +signed_attributes = [213, 19, 219, 127, 44, 247, 154, 190, 26, 122, 188, 163, 73, 227, 191, 71, 139, 129, 120, 193, 5, 130, 52, 127, 40, 83, 242, 75, 244, 200, 248, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +signed_attributes_size = 32 +exponent = 65537 +e_content = [54, 197, 174, 86, 62, 194, 237, 211, 184, 91, 92, 169, 195, 149, 233, 156, 60, 80, 224, 124, 161, 170, 204, 239, 154, 92, 165, 10, 81, 42, 90, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] \ No newline at end of file diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/compare_age_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/compare_age_prover.toml new file mode 100644 index 00000000..7ea84a30 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/compare_age_prover.toml @@ -0,0 +1,10 @@ +comm_in = "0x1beff4275b56006bd98e0c94b566c4810a803bebb2c7d614212e063fa6172371" +current_date = 1758300539 +salted_private_nullifier = { salt = "0x3", value = "0x0e54c7a27d1b06d06f8aa014ad75a9c9fae9b79c84097d0650caa544828062e1", hash = "0x0" } +salted_expiry_date = { salt = "0x3", value = [51, 50, 48, 49, 48, 49], hash = "0x0" } +salted_dg1 = { salt = "0x3", value = [60, 60, 60, 60, 60, 60, 60, 65, 85, 83, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 48, 55, 48, 49, 48, 49, 60, 60, 51, 50, 48, 49, 48, 49, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 0], hash = "0x0" } +min_age_required = 18 +max_age_required = 70 +nullifier_secret = "0x0" +service_scope = "0x0" +service_subscope = "0x0" diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/data_check_integrity_sa_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/data_check_integrity_sa_prover.toml new file mode 100644 index 00000000..cf571323 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/data_check_integrity_sa_prover.toml @@ -0,0 +1,11 @@ +comm_in = "0x00c2be911a2957a80fb3384012b08dc81bc24ae0fd1ecafe9aacc7177b7411a3" +salt_in = "0x3" +salted_dg1 = { salt = "0x3", value = [60, 60, 60, 60, 60, 60, 60, 65, 85, 83, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 48, 55, 48, 49, 48, 49, 60, 60, 51, 50, 48, 49, 48, 49, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 0], hash = "0x0" } +dg1_padded_length = 95 +dg1_hash_offset = 0 +expiry_date_salt = "0x3" +signed_attributes = [211, 193, 250, 21, 235, 80, 39, 78, 193, 183, 135, 72, 121, 250, 28, 5, 52, 114, 247, 226, 239, 85, 157, 215, 111, 196, 53, 0, 194, 221, 150, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 = [253, 51, 11, 117, 232, 161, 148, 187, 21, 27, 187, 140, 18, 92, 136, 34, 182, 250, 146, 125, 141, 230, 22, 147, 205, 153, 108, 117, 179, 69, 32, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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_len = 32 +signed_attributes_size = 32 +salted_private_nullifier = { salt = "0x3", value = "0x0e54c7a27d1b06d06f8aa014ad75a9c9fae9b79c84097d0650caa544828062e1", hash = "0x0" } diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_dsc_1300_hash_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_dsc_1300_hash_prover.toml new file mode 100644 index 00000000..f809c9d6 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_dsc_1300_hash_prover.toml @@ -0,0 +1,2 @@ +salt = "0x1" +chunk1 = [48, 130, 1, 10, 2, 130, 1, 1, 0, 175, 129, 169, 48, 75, 201, 148, 9, 44, 101, 74, 102, 208, 170, 80, 87, 167, 158, 254, 182, 81, 253, 14, 124, 113, 45, 48, 144, 36, 5, 248, 31, 93, 49, 75, 149, 184, 114, 188, 161, 128, 33, 61, 152, 20, 57, 11, 226, 80, 82, 80, 10, 209, 152, 144, 112, 231, 229, 31, 130, 146, 213, 195, 46, 163, 187, 24, 68, 79, 56, 124, 205, 49, 44, 70, 146, 221, 223, 68, 147, 89, 27, 16, 80, 111, 178, 109, 166, 123, 27, 29, 37, 120, 192, 202, 246, 6, 132, 249, 14, 254, 239, 204, 225, 127, 186, 207, 215, 178, 142, 60, 232, 125, 83, 126, 240, 68, 243, 79, 119, 91, 83, 101, 115, 122, 64, 30, 91, 221, 154, 108, 225, 93, 137, 17, 211, 26, 118, 192, 139, 66, 108, 134, 167, 187, 106, 71, 227, 24, 98, 192, 198, 153, 49, 239, 67, 212, 101, 101, 4, 76, 153, 212, 177, 159, 190, 78, 10, 224, 173, 157, 91, 210, 237, 178, 115, 123, 245, 116, 202, 34, 222, 78, 153, 81, 155, 248, 151, 112, 213, 128, 252, 173, 11, 165, 189, 128, 245, 216, 176, 34, 8, 89, 234, 4, 237, 161, 225, 16, 206, 84, 251, 235, 84, 100, 148, 53, 18, 159, 134, 159, 65, 197, 221, 254, 23, 118, 144, 109, 54, 163, 163, 137, 13, 21, 182, 72, 183, 104, 190, 89, 8, 248, 244, 38, 62, 248, 56, 97, 149, 68, 81, 218, 203, 203, 183, 2, 3, 1, 0, 1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134] diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_dsc_1300_verify_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_dsc_1300_verify_prover.toml new file mode 100644 index 00000000..bee50a8e --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_dsc_1300_verify_prover.toml @@ -0,0 +1,11 @@ +comm_in = "0x045433920bc35680c37f22815da747e86bf7974625da04b1f015af21e42446b1" +csc_pubkey = [208, 127, 177, 234, 50, 75, 101, 18, 206, 250, 228, 33, 237, 90, 21, 227, 71, 98, 152, 19, 83, 127, 240, 191, 83, 173, 209, 187, 204, 60, 55, 28, 178, 233, 40, 5, 26, 161, 3, 42, 9, 148, 226, 21, 124, 212, 182, 17, 167, 231, 99, 128, 28, 250, 218, 14, 223, 217, 242, 124, 76, 41, 160, 20, 185, 228, 97, 210, 75, 124, 211, 41, 123, 229, 70, 248, 109, 185, 175, 88, 101, 3, 128, 57, 26, 13, 146, 228, 150, 23, 74, 10, 8, 201, 116, 10, 252, 113, 176, 23, 57, 44, 17, 23, 199, 168, 105, 179, 70, 248, 60, 188, 153, 245, 115, 154, 29, 195, 140, 35, 100, 139, 242, 7, 17, 105, 135, 171, 196, 62, 119, 6, 137, 47, 31, 125, 57, 43, 71, 93, 251, 142, 245, 144, 12, 110, 5, 41, 174, 83, 34, 125, 87, 11, 80, 87, 49, 218, 214, 94, 228, 182, 112, 118, 178, 152, 120, 51, 25, 174, 238, 149, 140, 67, 183, 97, 227, 45, 231, 191, 253, 19, 128, 181, 183, 234, 34, 233, 155, 72, 130, 155, 247, 178, 203, 11, 54, 129, 252, 122, 126, 54, 245, 227, 208, 128, 158, 19, 149, 120, 73, 235, 222, 79, 132, 79, 124, 86, 226, 45, 0, 162, 0, 181, 7, 169, 46, 150, 74, 171, 56, 166, 99, 236, 234, 160, 94, 37, 57, 195, 104, 119, 80, 182, 180, 153, 20, 108, 233, 58, 34, 50, 159, 117, 217, 178, 239, 49, 177, 197, 41, 79, 22, 119, 78, 141, 51, 152, 217, 137, 227, 212, 113, 201, 120, 179, 105, 110, 60, 68, 50, 216, 247, 16, 16, 171, 247, 226, 220, 94, 162, 14, 42, 47, 121, 89, 25, 139, 66, 94, 195, 168, 87, 126, 188, 68, 63, 106, 174, 121, 249, 100, 252, 109, 210, 159, 95, 78, 238, 52, 158, 64, 133, 84, 3, 111, 224, 12, 237, 101, 169, 103, 200, 155, 68, 58, 252, 30, 71, 203, 191, 0, 121, 242, 105, 77, 112, 25, 135, 189, 123, 132, 44, 173, 199, 176, 211, 77, 185, 13, 122, 158, 36, 214, 172, 5, 69, 161, 42, 214, 82, 74, 50, 127, 129, 65, 52, 169, 223, 167, 157, 9, 20, 185, 159, 200, 253, 140, 94, 131, 115, 134, 180, 174, 3, 101, 13, 114, 146, 180, 163, 157, 9, 152, 173, 8, 120, 245, 206, 101, 156, 181, 194, 105, 80, 143, 20, 85, 24, 142, 104, 41, 183, 185, 93, 150, 59, 226, 166, 155, 103, 239, 249, 251, 67, 173, 67, 84, 4, 120, 89, 186, 232, 45, 142, 143, 113, 255, 2, 30, 164, 102, 109, 23, 85, 54, 174, 131, 194, 168, 126, 143, 61, 219, 98, 90, 67, 52, 225, 72, 68, 51, 98, 183, 38, 200, 115, 23, 217, 81, 202, 0, 241, 182, 149, 36, 29, 193, 121, 181, 147, 52, 76, 245, 92, 42, 174, 244, 252, 43, 139, 8, 106, 30, 150, 55, 151, 43, 104, 249, 147, 101] +salt = "0x1" +country = "AUS" +state1 = [3828948639, 4073271942, 433182166, 3811311365, 3566743306, 1923568254, 3109579459, 1110735471] +tbs_certificate = [48, 130, 1, 10, 2, 130, 1, 1, 0, 175, 129, 169, 48, 75, 201, 148, 9, 44, 101, 74, 102, 208, 170, 80, 87, 167, 158, 254, 182, 81, 253, 14, 124, 113, 45, 48, 144, 36, 5, 248, 31, 93, 49, 75, 149, 184, 114, 188, 161, 128, 33, 61, 152, 20, 57, 11, 226, 80, 82, 80, 10, 209, 152, 144, 112, 231, 229, 31, 130, 146, 213, 195, 46, 163, 187, 24, 68, 79, 56, 124, 205, 49, 44, 70, 146, 221, 223, 68, 147, 89, 27, 16, 80, 111, 178, 109, 166, 123, 27, 29, 37, 120, 192, 202, 246, 6, 132, 249, 14, 254, 239, 204, 225, 127, 186, 207, 215, 178, 142, 60, 232, 125, 83, 126, 240, 68, 243, 79, 119, 91, 83, 101, 115, 122, 64, 30, 91, 221, 154, 108, 225, 93, 137, 17, 211, 26, 118, 192, 139, 66, 108, 134, 167, 187, 106, 71, 227, 24, 98, 192, 198, 153, 49, 239, 67, 212, 101, 101, 4, 76, 153, 212, 177, 159, 190, 78, 10, 224, 173, 157, 91, 210, 237, 178, 115, 123, 245, 116, 202, 34, 222, 78, 153, 81, 155, 248, 151, 112, 213, 128, 252, 173, 11, 165, 189, 128, 245, 216, 176, 34, 8, 89, 234, 4, 237, 161, 225, 16, 206, 84, 251, 235, 84, 100, 148, 53, 18, 159, 134, 159, 65, 197, 221, 254, 23, 118, 144, 109, 54, 163, 163, 137, 13, 21, 182, 72, 183, 104, 190, 89, 8, 248, 244, 38, 62, 248, 56, 97, 149, 68, 81, 218, 203, 203, 183, 2, 3, 1, 0, 1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +tbs_certificate_len = 850 +csc_pubkey_redc_param = [19, 165, 43, 147, 243, 62, 245, 198, 16, 226, 76, 181, 11, 33, 122, 50, 8, 146, 184, 53, 157, 103, 217, 123, 12, 245, 111, 27, 121, 118, 147, 162, 61, 247, 152, 155, 102, 232, 126, 61, 244, 200, 5, 80, 102, 48, 32, 140, 144, 42, 210, 143, 10, 110, 82, 31, 155, 109, 240, 20, 37, 253, 18, 42, 212, 15, 119, 136, 208, 106, 8, 161, 39, 28, 142, 243, 211, 182, 159, 196, 20, 118, 120, 239, 161, 160, 111, 130, 89, 15, 25, 125, 45, 173, 199, 5, 251, 173, 171, 187, 15, 150, 84, 233, 168, 215, 245, 49, 58, 201, 10, 23, 42, 23, 103, 52, 166, 72, 33, 68, 151, 78, 90, 181, 143, 216, 76, 93, 210, 66, 109, 141, 126, 111, 20, 178, 1, 8, 84, 100, 10, 136, 22, 11, 112, 73, 87, 58, 190, 60, 241, 221, 145, 178, 144, 121, 119, 118, 78, 144, 149, 199, 110, 186, 255, 41, 78, 174, 77, 163, 171, 6, 98, 168, 106, 17, 106, 250, 165, 128, 195, 128, 55, 154, 152, 194, 95, 206, 157, 104, 5, 155, 203, 40, 77, 230, 108, 67, 83, 248, 67, 19, 116, 214, 205, 23, 253, 227, 97, 20, 42, 154, 63, 148, 52, 139, 189, 53, 46, 53, 232, 126, 221, 112, 154, 24, 186, 11, 136, 247, 76, 19, 208, 218, 103, 179, 86, 52, 140, 162, 176, 0, 208, 190, 69, 203, 245, 46, 131, 95, 167, 239, 135, 114, 201, 28, 182, 153, 206, 37, 75, 189, 189, 131, 193, 88, 193, 148, 56, 104, 10, 82, 180, 233, 127, 21, 102, 22, 60, 109, 198, 224, 219, 59, 192, 25, 132, 201, 222, 3, 201, 6, 175, 173, 90, 78, 94, 19, 140, 8, 178, 201, 152, 76, 158, 197, 156, 114, 124, 41, 130, 31, 112, 240, 132, 51, 120, 64, 84, 131, 3, 154, 87, 14, 13, 134, 198, 54, 197, 151, 230, 111, 184, 196, 181, 61, 118, 163, 35, 9, 88, 4, 184, 83, 229, 214, 179, 23, 215, 26, 85, 162, 181, 19, 112, 124, 153, 77, 36, 165, 18, 204, 12, 147, 240, 48, 74, 252, 215, 249, 68, 157, 28, 48, 82, 143, 44, 157, 228, 215, 162, 154, 255, 49, 36, 133, 150, 81, 182, 142, 148, 108, 17, 234, 161, 116, 9, 13, 245, 35, 187, 112, 90, 104, 136, 169, 243, 160, 139, 119, 191, 219, 41, 146, 81, 208, 188, 238, 136, 223, 113, 215, 231, 158, 30, 246, 143, 195, 156, 44, 236, 158, 235, 208, 223, 8, 233, 71, 68, 208, 244, 3, 40, 0, 30, 192, 39, 241, 121, 47, 133, 149, 27, 130, 99, 234, 24, 144, 199, 40, 160, 232, 251, 143, 213, 50, 26, 251, 100, 101, 9, 76, 7, 77, 171, 0, 39, 250, 162, 119, 14, 198, 87, 253, 191, 47, 42, 26, 225, 119, 79, 17, 108, 245, 196, 68, 84, 214, 34, 210, 229, 253, 172, 6, 180, 104, 65, 83, 6, 10, 164, 29, 155] +dsc_signature = [134, 242, 235, 133, 124, 225, 36, 1, 12, 194, 232, 181, 146, 9, 71, 223, 30, 21, 228, 131, 0, 44, 65, 127, 139, 103, 111, 149, 167, 229, 79, 233, 180, 60, 166, 16, 34, 195, 92, 60, 46, 129, 60, 49, 39, 183, 212, 164, 89, 15, 123, 9, 97, 228, 61, 191, 127, 186, 188, 180, 79, 225, 19, 145, 0, 66, 36, 152, 22, 189, 125, 175, 3, 49, 191, 217, 76, 116, 10, 204, 17, 41, 49, 97, 79, 121, 59, 46, 157, 49, 245, 198, 228, 67, 118, 129, 1, 105, 161, 129, 88, 147, 128, 120, 36, 211, 218, 95, 190, 174, 121, 205, 91, 107, 186, 193, 63, 79, 204, 81, 126, 34, 64, 186, 24, 172, 186, 120, 215, 109, 82, 251, 0, 225, 13, 110, 110, 200, 175, 242, 197, 227, 1, 85, 43, 126, 29, 235, 18, 101, 182, 175, 19, 49, 128, 152, 54, 147, 250, 123, 233, 255, 35, 250, 21, 173, 37, 219, 141, 233, 34, 37, 18, 190, 37, 123, 244, 143, 5, 45, 86, 0, 82, 64, 190, 157, 96, 201, 121, 24, 113, 226, 168, 73, 17, 173, 65, 232, 111, 246, 34, 231, 0, 128, 149, 190, 55, 183, 234, 102, 142, 137, 60, 190, 193, 204, 86, 179, 249, 119, 244, 59, 160, 81, 107, 167, 35, 87, 90, 36, 183, 176, 203, 240, 8, 253, 71, 209, 120, 159, 190, 28, 126, 238, 180, 21, 32, 14, 213, 238, 44, 140, 152, 211, 36, 83, 229, 57, 143, 157, 37, 182, 163, 149, 241, 242, 39, 175, 128, 49, 175, 158, 209, 167, 131, 120, 128, 51, 238, 151, 114, 96, 118, 128, 231, 240, 246, 236, 215, 16, 50, 47, 248, 88, 211, 34, 15, 81, 180, 247, 254, 107, 182, 148, 243, 218, 16, 251, 7, 196, 231, 57, 69, 19, 123, 28, 43, 86, 192, 176, 30, 174, 135, 63, 150, 145, 210, 161, 244, 147, 13, 63, 204, 228, 241, 221, 208, 18, 158, 97, 57, 254, 50, 25, 215, 44, 102, 212, 47, 243, 15, 125, 253, 15, 29, 30, 38, 122, 209, 126, 121, 188, 174, 164, 131, 201, 100, 36, 232, 250, 168, 211, 49, 246, 20, 176, 171, 94, 11, 249, 172, 56, 185, 72, 132, 21, 163, 228, 6, 113, 204, 228, 49, 84, 126, 205, 161, 122, 155, 172, 102, 161, 185, 184, 238, 239, 176, 168, 194, 97, 205, 25, 191, 180, 221, 20, 174, 82, 143, 209, 110, 202, 31, 15, 224, 43, 45, 217, 134, 41, 124, 64, 135, 51, 81, 26, 188, 227, 227, 176, 0, 160, 107, 152, 105, 244, 51, 104, 147, 85, 158, 121, 155, 178, 31, 213, 35, 130, 109, 49, 16, 184, 55, 232, 199, 128, 103, 248, 0, 96, 124, 135, 189, 224, 188, 78, 35, 162, 156, 250, 170, 89, 167, 248, 90, 146, 187, 37, 166, 128, 225, 174, 63, 25, 236, 210, 97, 33, 161, 113, 111, 207, 28, 254, 47, 177, 1, 249, 211, 94, 96, 185] +exponent = 65537 +salt_out = "0x2" diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_id_data_1300_prover.toml b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_id_data_1300_prover.toml new file mode 100644 index 00000000..73f9c906 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/benchmark-inputs/case2/sig_check_id_data_1300_prover.toml @@ -0,0 +1,13 @@ +comm_in = "0x070407794e3b7c40e9d8892b4e040d2c39fc3c10ca8f61e928dcbc8d5440cf84" +salt_in = "0x2" +salt_out = "0x3" +dg1 = [60, 60, 60, 60, 60, 60, 60, 65, 85, 83, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 48, 55, 48, 49, 48, 49, 60, 60, 51, 50, 48, 49, 48, 49, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 0] +dsc_pubkey = [175, 129, 169, 48, 75, 201, 148, 9, 44, 101, 74, 102, 208, 170, 80, 87, 167, 158, 254, 182, 81, 253, 14, 124, 113, 45, 48, 144, 36, 5, 248, 31, 93, 49, 75, 149, 184, 114, 188, 161, 128, 33, 61, 152, 20, 57, 11, 226, 80, 82, 80, 10, 209, 152, 144, 112, 231, 229, 31, 130, 146, 213, 195, 46, 163, 187, 24, 68, 79, 56, 124, 205, 49, 44, 70, 146, 221, 223, 68, 147, 89, 27, 16, 80, 111, 178, 109, 166, 123, 27, 29, 37, 120, 192, 202, 246, 6, 132, 249, 14, 254, 239, 204, 225, 127, 186, 207, 215, 178, 142, 60, 232, 125, 83, 126, 240, 68, 243, 79, 119, 91, 83, 101, 115, 122, 64, 30, 91, 221, 154, 108, 225, 93, 137, 17, 211, 26, 118, 192, 139, 66, 108, 134, 167, 187, 106, 71, 227, 24, 98, 192, 198, 153, 49, 239, 67, 212, 101, 101, 4, 76, 153, 212, 177, 159, 190, 78, 10, 224, 173, 157, 91, 210, 237, 178, 115, 123, 245, 116, 202, 34, 222, 78, 153, 81, 155, 248, 151, 112, 213, 128, 252, 173, 11, 165, 189, 128, 245, 216, 176, 34, 8, 89, 234, 4, 237, 161, 225, 16, 206, 84, 251, 235, 84, 100, 148, 53, 18, 159, 134, 159, 65, 197, 221, 254, 23, 118, 144, 109, 54, 163, 163, 137, 13, 21, 182, 72, 183, 104, 190, 89, 8, 248, 244, 38, 62, 248, 56, 97, 149, 68, 81, 218, 203, 203, 183] +dsc_pubkey_redc_param = [23, 86, 146, 55, 63, 159, 232, 60, 221, 119, 124, 9, 188, 82, 165, 23, 158, 68, 5, 232, 168, 133, 63, 147, 86, 8, 2, 197, 30, 202, 6, 196, 129, 59, 244, 235, 113, 52, 51, 248, 98, 48, 137, 234, 84, 170, 65, 207, 33, 186, 6, 254, 161, 135, 119, 198, 104, 247, 24, 246, 156, 81, 61, 99, 126, 80, 216, 52, 161, 179, 129, 133, 173, 141, 134, 234, 156, 64, 79, 255, 61, 141, 190, 123, 205, 191, 152, 53, 145, 191, 77, 125, 60, 188, 104, 182, 169, 121, 230, 26, 1, 124, 62, 101, 28, 75, 250, 66, 171, 241, 231, 237, 225, 61, 249, 0, 117, 84, 60, 140, 51, 219, 193, 160, 77, 14, 253, 51, 64, 71, 45, 165, 162, 194, 117, 93, 144, 116, 178, 209, 189, 183, 77, 171, 54, 237, 113, 243, 114, 148, 21, 228, 165, 153, 19, 160, 227, 104, 59, 208, 214, 235, 96, 164, 133, 47, 251, 13, 59, 164, 129, 240, 105, 214, 104, 124, 12, 21, 255, 35, 85, 51, 170, 117, 71, 178, 214, 151, 127, 253, 71, 112, 209, 152, 120, 178, 174, 176, 58, 133, 236, 254, 22, 242, 94, 92, 52, 237, 195, 7, 135, 23, 202, 41, 67, 107, 115, 192, 105, 51, 59, 132, 59, 206, 91, 236, 171, 188, 82, 152, 31, 108, 101, 190, 85, 255, 129, 181, 133, 126, 193, 79, 106, 11, 58, 161, 68, 180, 115, 123, 0, 189, 63, 28, 219, 233, 56] +dsc_pubkey_offset_in_dsc_cert = 9 +sod_signature = [49, 82, 246, 122, 19, 59, 45, 0, 177, 1, 87, 120, 87, 11, 161, 239, 3, 249, 38, 76, 252, 218, 41, 186, 212, 255, 115, 93, 61, 126, 32, 45, 23, 213, 196, 108, 114, 169, 113, 7, 154, 18, 167, 25, 25, 27, 194, 114, 135, 8, 37, 84, 208, 23, 27, 57, 163, 118, 74, 6, 231, 69, 9, 217, 236, 137, 219, 240, 189, 26, 131, 1, 235, 7, 154, 43, 28, 206, 16, 186, 23, 101, 46, 95, 236, 154, 223, 150, 100, 20, 161, 29, 86, 197, 67, 93, 206, 196, 125, 105, 53, 145, 158, 61, 204, 142, 223, 173, 216, 92, 32, 103, 98, 195, 108, 15, 123, 238, 9, 7, 149, 47, 149, 249, 97, 112, 140, 53, 7, 173, 48, 226, 190, 242, 124, 83, 23, 84, 52, 101, 194, 21, 138, 178, 155, 243, 196, 72, 173, 74, 160, 87, 171, 165, 251, 137, 93, 34, 78, 37, 248, 131, 241, 134, 158, 12, 44, 0, 225, 80, 16, 3, 29, 30, 144, 38, 191, 129, 51, 186, 7, 125, 14, 87, 88, 158, 30, 6, 109, 47, 101, 202, 94, 215, 177, 113, 2, 148, 208, 150, 29, 57, 165, 123, 73, 103, 247, 176, 90, 74, 58, 214, 151, 149, 112, 198, 55, 27, 242, 91, 215, 74, 52, 244, 241, 51, 75, 142, 233, 181, 37, 113, 101, 113, 106, 164, 216, 83, 189, 110, 194, 226, 251, 61, 238, 86, 238, 228, 238, 254, 32, 95, 49, 100, 15, 179] +tbs_certificate = [48, 130, 1, 10, 2, 130, 1, 1, 0, 175, 129, 169, 48, 75, 201, 148, 9, 44, 101, 74, 102, 208, 170, 80, 87, 167, 158, 254, 182, 81, 253, 14, 124, 113, 45, 48, 144, 36, 5, 248, 31, 93, 49, 75, 149, 184, 114, 188, 161, 128, 33, 61, 152, 20, 57, 11, 226, 80, 82, 80, 10, 209, 152, 144, 112, 231, 229, 31, 130, 146, 213, 195, 46, 163, 187, 24, 68, 79, 56, 124, 205, 49, 44, 70, 146, 221, 223, 68, 147, 89, 27, 16, 80, 111, 178, 109, 166, 123, 27, 29, 37, 120, 192, 202, 246, 6, 132, 249, 14, 254, 239, 204, 225, 127, 186, 207, 215, 178, 142, 60, 232, 125, 83, 126, 240, 68, 243, 79, 119, 91, 83, 101, 115, 122, 64, 30, 91, 221, 154, 108, 225, 93, 137, 17, 211, 26, 118, 192, 139, 66, 108, 134, 167, 187, 106, 71, 227, 24, 98, 192, 198, 153, 49, 239, 67, 212, 101, 101, 4, 76, 153, 212, 177, 159, 190, 78, 10, 224, 173, 157, 91, 210, 237, 178, 115, 123, 245, 116, 202, 34, 222, 78, 153, 81, 155, 248, 151, 112, 213, 128, 252, 173, 11, 165, 189, 128, 245, 216, 176, 34, 8, 89, 234, 4, 237, 161, 225, 16, 206, 84, 251, 235, 84, 100, 148, 53, 18, 159, 134, 159, 65, 197, 221, 254, 23, 118, 144, 109, 54, 163, 163, 137, 13, 21, 182, 72, 183, 104, 190, 89, 8, 248, 244, 38, 62, 248, 56, 97, 149, 68, 81, 218, 203, 203, 183, 2, 3, 1, 0, 1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +signed_attributes = [211, 193, 250, 21, 235, 80, 39, 78, 193, 183, 135, 72, 121, 250, 28, 5, 52, 114, 247, 226, 239, 85, 157, 215, 111, 196, 53, 0, 194, 221, 150, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +signed_attributes_size = 32 +exponent = 65537 +e_content = [253, 51, 11, 117, 232, 161, 148, 187, 21, 27, 187, 140, 18, 92, 136, 34, 182, 250, 146, 125, 141, 230, 22, 147, 205, 153, 108, 117, 179, 69, 32, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/compare_age/Nargo.toml b/noir-examples/noir-passport-examples/fragmented_age_check/compare_age/Nargo.toml new file mode 100644 index 00000000..87716124 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/compare_age/Nargo.toml @@ -0,0 +1,10 @@ +[package] +name = "compare_age" +type = "bin" +compiler_version = ">=1.0.0" + +[dependencies] +compare_age = { path = "../../zkpassport_libs/compare/age" } +data_check_expiry = { path = "../../zkpassport_libs/data-check/expiry" } +commitment = { path = "../../zkpassport_libs/commitment/scoped-nullifier" } +utils = { path = "../../zkpassport_libs/utils" } diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/compare_age/src/main.nr b/noir-examples/noir-passport-examples/fragmented_age_check/compare_age/src/main.nr new file mode 100644 index 00000000..8e42f3f5 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/compare_age/src/main.nr @@ -0,0 +1,37 @@ +// Extract DOB from MRZ, verify age and expiry, generate nullifier +use commitment::nullify; +use compare_age::{calculate_param_commitment, compare_age}; +use data_check_expiry::check_expiry; +use utils::types::{DG1Data, SaltedValue,MRZExpiryDate}; + +fn main( + comm_in: pub Field, + current_date: pub u64, + salted_private_nullifier: SaltedValue, + salted_expiry_date: SaltedValue, + salted_dg1: SaltedValue, + min_age_required: u8, + max_age_required: u8, + nullifier_secret: Field, + service_scope: pub Field, + service_subscope: pub Field, +) -> pub (Field, Field, Field) { + check_expiry(salted_dg1.value, current_date); + compare_age( + salted_dg1.value, + min_age_required, + max_age_required, + current_date, + ); + let (nullifier, nullifier_type) = nullify( + comm_in, + salted_dg1, + salted_expiry_date, + salted_private_nullifier, + service_scope, + service_subscope, + nullifier_secret, + ); + let param_commitment = calculate_param_commitment(current_date, min_age_required, max_age_required); + (param_commitment, nullifier_type, nullifier) +} diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/data_check_integrity_sa/Nargo.toml b/noir-examples/noir-passport-examples/fragmented_age_check/data_check_integrity_sa/Nargo.toml new file mode 100644 index 00000000..5ccd3e56 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/data_check_integrity_sa/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "data_check_integrity_sa" +type = "bin" +compiler_version = ">=1.0.0" + +[dependencies] +data_check_integrity = { path = "../../zkpassport_libs/data-check/integrity" } +commitment = { path = "../../zkpassport_libs/commitment/integrity-to-disclosure" } +utils = { path = "../../zkpassport_libs/utils" } diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/data_check_integrity_sa/src/main.nr b/noir-examples/noir-passport-examples/fragmented_age_check/data_check_integrity_sa/src/main.nr new file mode 100644 index 00000000..d1dd38ca --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/data_check_integrity_sa/src/main.nr @@ -0,0 +1,36 @@ +// Verify data integrity chain (DG1 -> eContent -> SignedAttributes) +use commitment::commit_to_disclosure; +use data_check_integrity::{ + check_dg1_hash_within_sod, check_signed_attributes_sha256, +}; +use utils::{ + types::{DG1Data, EContentData, SaltedValue, SignedAttrsData}, +}; + +fn main( + comm_in: pub Field, + salt_in: Field, + salted_dg1: SaltedValue, + dg1_padded_length: u64, + dg1_hash_offset: u32, + expiry_date_salt: Field, + signed_attributes: SignedAttrsData, + e_content: EContentData, + e_content_len: u32, + signed_attributes_size: u32, + salted_private_nullifier: SaltedValue, +) -> pub Field { + check_dg1_hash_within_sod(salted_dg1.value, dg1_padded_length, e_content, e_content_len, dg1_hash_offset); + check_signed_attributes_sha256(signed_attributes, e_content, e_content_len); + let comm_out = commit_to_disclosure( + comm_in, + salt_in, + salted_dg1, + expiry_date_salt, + signed_attributes, + signed_attributes_size as Field, + e_content, + salted_private_nullifier, + ); + comm_out +} diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/compile-circuits.sh b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/compile-circuits.sh new file mode 100755 index 00000000..dffef75d --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/compile-circuits.sh @@ -0,0 +1,19 @@ +CIRCUITS=( + "sig_check_dsc_720" + "sig_check_id_data_720" + "data_check_integrity_sa" + "compare_age" +) +LOG_DIR="../../benchmark-inputs/logs/compile/case1" +mkdir -p "$LOG_DIR" + +# Function to strip ANSI escape codes (works on macOS) +strip_ansi() { + sed $'s/\x1b\[[0-9;]*m//g' +} + +for circuit in "${CIRCUITS[@]}"; do + echo "Compiling $circuit" + nargo compile --force --print-acir --package "$circuit" 2>&1 | strip_ansi | tee "$LOG_DIR/$circuit.log" + echo "Compiled $circuit" +done \ No newline at end of file diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/prepare-circuits.sh b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/prepare-circuits.sh new file mode 100755 index 00000000..17353ef6 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/prepare-circuits.sh @@ -0,0 +1,19 @@ +CIRCUITS=( + "sig_check_dsc_720" + "sig_check_id_data_720" + "data_check_integrity_sa" + "compare_age" +) +LOG_DIR="../../benchmark-inputs/logs/prepare/case1" +mkdir -p "$LOG_DIR" + +# Function to strip ANSI escape codes (works on macOS) +strip_ansi() { + sed $'s/\x1b\[[0-9;]*m//g' +} + +for circuit in "${CIRCUITS[@]}"; do + echo "Preparing $circuit" + cargo run --release --bin provekit-cli prepare ../../target/$circuit.json --pkp ../../benchmark-inputs/$circuit-prover.pkp --pkv ../../benchmark-inputs/$circuit-verifier.pkv 2>&1 | strip_ansi | tee "$LOG_DIR/$circuit.log" + echo "Prepared $circuit" +done diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/prove-circuits.sh b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/prove-circuits.sh new file mode 100755 index 00000000..7d2d7668 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case1/prove-circuits.sh @@ -0,0 +1,20 @@ +CIRCUITS=( + "sig_check_dsc_720" + "sig_check_id_data_720" + "data_check_integrity_sa" + "compare_age" +) + +LOG_DIR="../../benchmark-inputs/logs/prove/case1" +mkdir -p "$LOG_DIR" + +# Function to strip ANSI escape codes (works on macOS) +strip_ansi() { + sed $'s/\x1b\[[0-9;]*m//g' +} + +for circuit in "${CIRCUITS[@]}"; do + echo "Proving $circuit" + cargo run --release --bin provekit-cli prove ../../benchmark-inputs/$circuit-prover.pkp ../../benchmark-inputs/case1/"$circuit"_prover.toml -o ../../benchmark-inputs/$circuit-proof.np 2>&1 | strip_ansi | tee "$LOG_DIR/$circuit.log" + echo "Proved $circuit" +done diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/compile-circuits.sh b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/compile-circuits.sh new file mode 100755 index 00000000..db05a49c --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/compile-circuits.sh @@ -0,0 +1,20 @@ +CIRCUITS=( + "sig_check_dsc_1300_hash" + "sig_check_dsc_1300_verify" + "sig_check_id_data_1300" + "data_check_integrity_sa" + "compare_age" +) +LOG_DIR="../../benchmark-inputs/logs/compile/case2" +mkdir -p "$LOG_DIR" + +# Function to strip ANSI escape codes (works on macOS) +strip_ansi() { + sed $'s/\x1b\[[0-9;]*m//g' +} + +for circuit in "${CIRCUITS[@]}"; do + echo "Compiling $circuit" + nargo compile --force --print-acir --package "$circuit" 2>&1 | strip_ansi | tee "$LOG_DIR/$circuit.log" + echo "Compiled $circuit" +done \ No newline at end of file diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/prepare-circuits.sh b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/prepare-circuits.sh new file mode 100755 index 00000000..b1861594 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/prepare-circuits.sh @@ -0,0 +1,20 @@ +CIRCUITS=( + "sig_check_dsc_1300_hash" + "sig_check_dsc_1300_verify" + "sig_check_id_data_1300" + "data_check_integrity_sa" + "compare_age" +) +LOG_DIR="../../benchmark-inputs/logs/prepare/case2" +mkdir -p "$LOG_DIR" + +# Function to strip ANSI escape codes (works on macOS) +strip_ansi() { + sed $'s/\x1b\[[0-9;]*m//g' +} + +for circuit in "${CIRCUITS[@]}"; do + echo "Preparing $circuit" + cargo run --release --bin provekit-cli prepare ../../target/$circuit.json --pkp ../../benchmark-inputs/$circuit-prover.pkp --pkv ../../benchmark-inputs/$circuit-verifier.pkv 2>&1 | strip_ansi | tee "$LOG_DIR/$circuit.log" + echo "Prepared $circuit" +done diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/prove-circuits.sh b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/prove-circuits.sh new file mode 100755 index 00000000..75d7697c --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/scripts/case2/prove-circuits.sh @@ -0,0 +1,20 @@ +CIRCUITS=( + "sig_check_dsc_1300_hash" + "sig_check_dsc_1300_verify" + "sig_check_id_data_1300" + "data_check_integrity_sa" + "compare_age" +) +LOG_DIR="../../benchmark-inputs/logs/prove/case2" +mkdir -p "$LOG_DIR" + +# Function to strip ANSI escape codes (works on macOS) +strip_ansi() { + sed $'s/\x1b\[[0-9;]*m//g' +} + +for circuit in "${CIRCUITS[@]}"; do + echo "Proving $circuit" + cargo run --release --bin provekit-cli prove ../../benchmark-inputs/$circuit-prover.pkp ../../benchmark-inputs/case2/"$circuit"_prover.toml -o ../../benchmark-inputs/$circuit-proof.np 2>&1 | strip_ansi | tee "$LOG_DIR/$circuit.log" + echo "Proved $circuit" +done diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_hash/Nargo.toml b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_hash/Nargo.toml new file mode 100644 index 00000000..8d24d2ee --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_hash/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "sig_check_dsc_1300_hash" +type = "bin" +compiler_version = ">=1.0.0" + +[dependencies] +partial_sha256 = { path = "../../zkpassport_libs/partial-sha256" } diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_hash/src/main.nr b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_hash/src/main.nr new file mode 100644 index 00000000..94113c01 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_hash/src/main.nr @@ -0,0 +1,16 @@ +// Process first 640 bytes of DSC certificate (SHA256 start) +use partial_sha256::{ + SHA256State, sha256_start, commit_to_sha256_state_and_data, commit_to_data_chunk, +}; + +global CHUNK1_SIZE: u32 = 640; + +fn main( + salt: Field, + chunk1: [u8; CHUNK1_SIZE], +) -> pub Field { + let state1: SHA256State = sha256_start(chunk1); + let data_comm1 = commit_to_data_chunk(salt, chunk1); + let comm_out = commit_to_sha256_state_and_data(salt, state1, CHUNK1_SIZE, data_comm1); + comm_out +} diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_verify/Nargo.toml b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_verify/Nargo.toml new file mode 100644 index 00000000..4612bad6 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_verify/Nargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sig_check_dsc_1300_verify" +type = "bin" +compiler_version = ">=1.0.0" + +[dependencies] +partial_sha256 = { path = "../../zkpassport_libs/partial-sha256" } +sig_check_rsa = { path = "../../zkpassport_libs/sig-check/rsa" } +utils = { path = "../../zkpassport_libs/utils" } +commitment = { path = "../../zkpassport_libs/commitment/common" } diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_verify/src/main.nr b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_verify/src/main.nr new file mode 100644 index 00000000..0cfc75bd --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_1300_verify/src/main.nr @@ -0,0 +1,78 @@ +// Complete SHA256 and verify CSCA signature (1300-byte TBS) +use commitment::hash_salt_country_tbs; +use partial_sha256::{ + SHA256State, sha256_continue, sha256_finalize, verify_sha256_state_and_data_commitment, commit_to_data_chunk, +}; +use sig_check_rsa::verify_rsa_signature; +use utils::types::{Alpha3CountryCode, SHA256Digest}; + +global CHUNK1_SIZE: u32 = 640; +global CHUNK2_SIZE: u32 = 640; +global TBS_CERT_SIZE: u32 = 1300; + +fn main( + comm_in: pub Field, + csc_pubkey: pub [u8; 512], + salt: Field, + country: Alpha3CountryCode, + state1: SHA256State, + tbs_certificate: [u8; TBS_CERT_SIZE], + tbs_certificate_len: u32, + csc_pubkey_redc_param: [u8; 513], + dsc_signature: [u8; 512], + exponent: u32, + salt_out: Field, +) -> pub Field { + let mut chunk1: [u8; CHUNK1_SIZE] = [0; CHUNK1_SIZE]; + for i in 0..CHUNK1_SIZE { + chunk1[i] = tbs_certificate[i]; + } + + let data_comm1 = commit_to_data_chunk(salt, chunk1); + verify_sha256_state_and_data_commitment(comm_in, salt, state1, CHUNK1_SIZE, data_comm1); + + let remaining_size: u32 = if tbs_certificate_len > CHUNK1_SIZE { + tbs_certificate_len - CHUNK1_SIZE + } else { + 0 + }; + + let num_full_blocks = remaining_size / 64; + let full_block_bytes = num_full_blocks * 64; + let final_partial_bytes = remaining_size - full_block_bytes; + + let mut chunk2: [u8; CHUNK2_SIZE] = [0; CHUNK2_SIZE]; + for i in 0..CHUNK2_SIZE { + chunk2[i] = tbs_certificate[CHUNK1_SIZE + i]; + } + + let state2 = sha256_continue(state1, chunk2, full_block_bytes); + + let mut final_block: [u8; 64] = [0; 64]; + for i in 0..64 { + if i < final_partial_bytes { + final_block[i] = tbs_certificate[CHUNK1_SIZE + full_block_bytes + i]; + } + } + + let tbs_hash: SHA256Digest = sha256_finalize(state2, final_block, final_partial_bytes, tbs_certificate_len); + + assert( + verify_rsa_signature::<512, 0, 1300, 32>( + csc_pubkey, + dsc_signature, + csc_pubkey_redc_param, + exponent, + tbs_hash, + ), + "RSA signature verification failed", + ); + + let comm_out = hash_salt_country_tbs( + salt_out, + country, + tbs_certificate, + ); + + comm_out +} diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_720/Nargo.toml b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_720/Nargo.toml new file mode 100644 index 00000000..d4becbcf --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_720/Nargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sig_check_dsc_720" +type = "bin" +compiler_version = ">=1.0.0" + +[dependencies] +sig_check_rsa = { path = "../../zkpassport_libs/sig-check/rsa" } +utils = { path = "../../zkpassport_libs/utils" } +commitment = { path = "../../zkpassport_libs/commitment/common" } + diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_720/src/main.nr b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_720/src/main.nr new file mode 100644 index 00000000..258e3d73 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_dsc_720/src/main.nr @@ -0,0 +1,34 @@ +// Verify CSCA signed DSC certificate (720-byte TBS) +use commitment::hash_salt_country_tbs; +use sig_check_rsa::verify_signature; +use utils::types::Alpha3CountryCode; + +fn main( + csc_pubkey: pub [u8; 512], + salt: Field, + country: Alpha3CountryCode, + tbs_certificate: [u8; 720], + csc_pubkey_redc_param: [u8; 513], + dsc_signature: [u8; 512], + exponent: u32, + tbs_certificate_len: u32 +) -> pub Field { + assert( + verify_signature::<512, 0, 720, 32>( + csc_pubkey, + dsc_signature, + csc_pubkey_redc_param, + exponent, + tbs_certificate, + tbs_certificate_len, + 0, + ), + "RSA signature verification failed", + ); + let comm_out = hash_salt_country_tbs( + salt, + country, + tbs_certificate, + ); + comm_out +} diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_1300/Nargo.toml b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_1300/Nargo.toml new file mode 100644 index 00000000..d2d53687 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_1300/Nargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sig_check_id_data_1300" +type = "bin" +compiler_version = ">=1.0.0" + +[dependencies] +sig_check_rsa = { path = "../../zkpassport_libs/sig-check/rsa" } +utils = { path = "../../zkpassport_libs/utils" } +data_check_tbs_pubkey = { path = "../../zkpassport_libs/data-check/tbs-pubkey" } +commitment = { path = "../../zkpassport_libs/commitment/dsc-to-id" } diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_1300/src/main.nr b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_1300/src/main.nr new file mode 100644 index 00000000..e0706f3e --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_1300/src/main.nr @@ -0,0 +1,48 @@ +// Verify DSC signed passport SignedAttributes (1300-byte TBS) +use commitment::commit_to_id; +use data_check_tbs_pubkey::{verify_rsa_pubkey_in_tbs}; +use sig_check_rsa::verify_signature; +use utils::types::{DG1Data, EContentData, SignedAttrsData}; + +fn main( + comm_in: pub Field, + salt_in: Field, + salt_out: Field, + dg1: DG1Data, + dsc_pubkey: [u8; 256], + dsc_pubkey_redc_param: [u8; 257], + dsc_pubkey_offset_in_dsc_cert: u32, + sod_signature: [u8; 256], + tbs_certificate: [u8; 1300], + signed_attributes: SignedAttrsData, + signed_attributes_size: u64, + exponent: u32, + e_content: EContentData, +) -> pub Field { + verify_rsa_pubkey_in_tbs(dsc_pubkey, tbs_certificate,dsc_pubkey_offset_in_dsc_cert); + + assert( + verify_signature::<256, 0, 200, 32>( + dsc_pubkey, + sod_signature, + dsc_pubkey_redc_param, + exponent, + signed_attributes, + signed_attributes_size as u32, + 0, + ), + "RSA signature verification failed", + ); + let comm_out = commit_to_id( + comm_in, + salt_in, + salt_out, + dg1, + tbs_certificate, + sod_signature, + signed_attributes, + signed_attributes_size as Field, + e_content, + ); + comm_out +} diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_720/Nargo.toml b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_720/Nargo.toml new file mode 100644 index 00000000..c311f0c9 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_720/Nargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sig_check_id_data_720" +type = "bin" +compiler_version = ">=1.0.0" + +[dependencies] +sig_check_rsa = { path = "../../zkpassport_libs/sig-check/rsa" } +utils = { path = "../../zkpassport_libs/utils" } +data_check_tbs_pubkey = { path = "../../zkpassport_libs/data-check/tbs-pubkey" } +commitment = { path = "../../zkpassport_libs/commitment/dsc-to-id" } diff --git a/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_720/src/main.nr b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_720/src/main.nr new file mode 100644 index 00000000..6d44b737 --- /dev/null +++ b/noir-examples/noir-passport-examples/fragmented_age_check/sig_check_id_data_720/src/main.nr @@ -0,0 +1,47 @@ +// Verify DSC signed passport SignedAttributes (720-byte TBS) +use commitment::commit_to_id; +use data_check_tbs_pubkey::verify_rsa_pubkey_in_tbs; +use sig_check_rsa::verify_signature; +use utils::types::{DG1Data, EContentData, SignedAttrsData}; + +fn main( + comm_in: pub Field, + salt_in: Field, + salt_out: Field, + dg1: DG1Data, + dsc_pubkey: [u8; 256], + dsc_pubkey_redc_param: [u8; 257], + dsc_pubkey_offset_in_dsc_cert: u32, + sod_signature: [u8; 256], + tbs_certificate: [u8; 720], + signed_attributes: SignedAttrsData, + signed_attributes_size: u64, + exponent: u32, + e_content: EContentData, +) -> pub Field { + verify_rsa_pubkey_in_tbs(dsc_pubkey, tbs_certificate,dsc_pubkey_offset_in_dsc_cert); + assert( + verify_signature::<256, 0, 200, 32>( + dsc_pubkey, + sod_signature, + dsc_pubkey_redc_param, + exponent, + signed_attributes, + signed_attributes_size as u32, + 0, + ), + "RSA signature verification failed", + ); + let comm_out = commit_to_id( + comm_in, + salt_in, + salt_out, + dg1, + tbs_certificate, + sod_signature, + signed_attributes, + signed_attributes_size as Field, + e_content, + ); + comm_out +} diff --git a/noir-examples/noir-passport-examples/noir_native_sha256/Nargo.toml b/noir-examples/noir-passport-examples/noir_native_sha256/Nargo.toml deleted file mode 100644 index 757d45f5..00000000 --- a/noir-examples/noir-passport-examples/noir_native_sha256/Nargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "noir_native_sha256" -type = "lib" -compiler_version = ">=1.0.0" -authors = ["Ryan Cao"] - -[dependencies] -sha256 = { tag = "v0.2.0", git = "https://github.com/noir-lang/sha256" } \ No newline at end of file diff --git a/noir-examples/noir-passport-examples/noir_native_sha256/Prover.toml b/noir-examples/noir-passport-examples/noir_native_sha256/Prover.toml deleted file mode 100644 index e7efaaab..00000000 --- a/noir-examples/noir-passport-examples/noir_native_sha256/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -msg = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33] -message_size_bytes = 12 diff --git a/noir-examples/noir-passport-examples/noir_native_sha256/src/lib.nr b/noir-examples/noir-passport-examples/noir_native_sha256/src/lib.nr deleted file mode 100644 index 43bf350e..00000000 --- a/noir-examples/noir-passport-examples/noir_native_sha256/src/lib.nr +++ /dev/null @@ -1,184 +0,0 @@ -use ryan_sha256_compression::ryan_sha256_digest_block_u32; -use ryan_sha256_constants::{MAX_MSG_LEN, RANDOM_BYTES_MANY_ROUNDS}; -use std::hash::sha256_compression; - -pub mod ryan_sha256_noir; -pub(crate) mod ryan_sha256_compression; -pub(crate) mod ryan_sha256_constants; -mod tests; - -fn is_id_card(dg1: [u8; 95]) -> bool { - // For passport, the last two bytes are 0 - // since the real length is 93 for passports - // while it is 95 for ID cards - (dg1[93] != 0) & (dg1[94] != 0) -} - -#[test] -fn test_failing_sha256_var() { - let dg1: [u8; 95] = [ - 42, 19, 88, 237, 91, 63, 129, 7, 250, 198, 14, 76, 211, 45, 5, 99, 170, 38, 240, 201, 64, - 123, 3, 81, 33, 156, 212, 18, 199, 111, 222, 61, 143, 247, 8, 195, 29, 157, 132, 71, 102, - 17, 173, 108, 245, 214, 224, 66, 115, 86, 189, 234, 90, 44, 207, 16, 58, 134, 103, 251, 193, - 35, 140, 248, 79, 105, 202, 137, 100, 196, 125, 31, 83, 41, 209, 93, 10, 229, 144, 116, 225, - 67, 133, 204, 77, 112, 69, 253, 154, 246, 17, 99, 88, 0, 0, - ]; - - // For passports we ignore the last padding characters - let mut dg1_size: u64 = 93; - let mut x: u64 = 0; - - // If it's an ID card then the array should not have any padding - // character - if is_id_card(dg1) { - println("this is reached"); - x = 3; - dg1_size = 95; - } - - // We only need to recompute the hash of the MRZ (or more accurately that of Data Group 1) - // within the circuit as this is the only data group we use to build the proof (age, country, etc.) - // let other_hash = sha256::sha256_var(dg1, dg1_size); - let dg1_hash_attempt_1 = ryan_sha256_noir::sha256_var(dg1, x + 95 - x); // So this gives the correct result but falsely fails R1CS constraints - let dg1_hash_attempt_2 = ryan_sha256_noir::sha256_var(dg1, dg1.len() as u64); // This gives the wrong result but succeeds in R1CS constraints - let other_dg1_hash = sha256::digest(dg1); - println("This is Noir's dg1_hash"); - println(other_dg1_hash); - - // println(other_hash); - println("This is the dg1_hash_attempt_1"); - println(dg1_hash_attempt_1); - - println("This is the dg1_hash_attempt_2"); - println(dg1_hash_attempt_2); -} - -#[test] -fn test_sha256_var() { - // --- Let's test two versions of `sha256_var` against each other --- - for idx in 0..10 { - let thing_to_absorb: [u8; MAX_MSG_LEN] = RANDOM_BYTES_MANY_ROUNDS[idx]; - - let mut msg_len = MAX_MSG_LEN; - if thing_to_absorb[0] == 0 { - msg_len -= 2; - } - - let blackbox_result = sha256::sha256_var(thing_to_absorb, msg_len as u64); - let ryan_result = ryan_sha256_noir::sha256_var(thing_to_absorb, msg_len as u64); - - println(blackbox_result); - println(ryan_result); - assert_eq(blackbox_result, ryan_result); - } -} - -#[test] -fn test_ryan_sha256_digest_block_u32() { - let random_states: [[u32; 8]; 10] = [ - [ - 3711890665, 3714332401, 3387837403, 1311576937, 2850423420, 1766807436, 279261662, - 980698040, - ], - [ - 241080654, 2776327254, 2836034795, 4011727061, 692717810, 3472968387, 2336079546, - 3472865588, - ], - [ - 1814694129, 898153453, 2718683824, 1980947199, 124660220, 3730354208, 3567088773, - 1301108289, - ], - [ - 3070321822, 3745622196, 1475927390, 1408189715, 157514634, 200331949, 2985323570, - 1134610593, - ], - [ - 3776767489, 3958445956, 34729136, 2244258599, 935645256, 1185556939, 1882358357, - 1071787888, - ], - [ - 1428952096, 3457008629, 4079094404, 2092226862, 395173293, 3283923843, 865111316, - 2696302365, - ], - [ - 3193282606, 2455080160, 1470231557, 52232517, 3123999614, 1751048468, 1511590211, - 3572795290, - ], - [ - 2482781779, 2543833787, 1648932745, 1094288520, 1490389861, 1062138401, 2701750777, - 4086905298, - ], - [ - 2073696290, 429529299, 658199888, 1237181425, 3259720900, 1132273219, 820741923, - 3134182660, - ], - [ - 2106415170, 4057092793, 1060978477, 3378096126, 2758276607, 938643281, 2868160936, - 472120090, - ], - ]; - let random_things_to_absorb: [[u32; 16]; 10] = [ - [ - 1277355385, 22445438, 817981005, 1510743426, 2669419464, 243984557, 3715704331, - 3351129034, 1050294448, 1326592289, 130423761, 2623807512, 1561557411, 2521042731, - 1097327247, 3068172910, - ], - [ - 642031562, 2531093294, 209598467, 1636419963, 1035403787, 49355406, 1571735684, - 3160016159, 4232504228, 557530806, 2447633372, 2637401205, 363737925, 3293614601, - 236471905, 3997477011, - ], - [ - 572654401, 3902053496, 3408636837, 3607322483, 2470026909, 2752661972, 499944812, - 2880063031, 2441148372, 600390524, 4020459520, 2921542983, 2499385623, 2371016017, - 3829979851, 3342537836, - ], - [ - 3008025510, 917961269, 2923099632, 7696709, 2135557940, 3460350958, 2966732963, - 1625920042, 2673707951, 3696379411, 1480305399, 3784819888, 2398046752, 1157717730, - 2858103740, 3269707097, - ], - [ - 2288317606, 2595904485, 42896947, 1637923610, 908051416, 2463899481, 3311817896, - 141630765, 2801911017, 251176618, 4096056149, 555154172, 3150320497, 3036229357, - 1132287542, 3859394292, - ], - [ - 1282404551, 72031527, 1643203889, 1560283573, 4104931948, 1517886706, 3446512707, - 3312007269, 3042382991, 3867167222, 1613960926, 3449768118, 4042603251, 4151709098, - 3975368320, 2602443230, - ], - [ - 293867709, 896730560, 4058455315, 296253730, 2506231107, 4007085280, 907876420, - 3425083873, 1737118966, 536585638, 472348727, 2373166844, 2143603884, 2847565666, - 1405187978, 270342293, - ], - [ - 3822838650, 3968797499, 2404366212, 1908633276, 2478306128, 2834276327, 2519762659, - 3753423485, 2690247494, 932818742, 2651610469, 3552893028, 253034649, 813152430, - 3816068176, 3762292230, - ], - [ - 898570312, 673147241, 520504408, 3808700629, 2797906140, 1823662319, 548008261, - 340382032, 3564205661, 292516889, 1563614420, 2249064997, 177816195, 3597367921, - 3022258837, 1621940911, - ], - [ - 707284061, 2231665729, 2478251141, 2894474131, 3916603775, 4213252696, 1395674200, - 350417223, 2277379131, 2533289716, 1350595999, 4067840646, 895320447, 3184565247, - 468404587, 3529508635, - ], - ]; - - // --- Let's test the two versions of `sha256_compression` against each other! --- - for idx in 0..10 { - let thing_to_absorb: [u32; 16] = random_things_to_absorb[idx]; - let state: [u32; 8] = random_states[idx]; - let blackbox_result = sha256_compression(thing_to_absorb, state); - let ryan_result = ryan_sha256_digest_block_u32(state, thing_to_absorb); - - println(blackbox_result); - println(ryan_result); - assert_eq(blackbox_result, ryan_result); - } -} diff --git a/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_compression.nr b/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_compression.nr deleted file mode 100644 index fd13effa..00000000 --- a/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_compression.nr +++ /dev/null @@ -1,257 +0,0 @@ -/// Note: This is the naive implementation of SHA-256's block compression -/// function, i.e. (state: [u32; 8], block: [u32; 16]) -> updated_state: [u32; 8]. -/// -/// This file has been optimized internally to use a standard loop-based approach -/// for the SHA-256 algorithm, while preserving the original function signatures. - -use super::ryan_sha256_constants::{K32, MSG_BLOCK, STATE}; -use std::static_assert; - -// ------------------- ALL THE SHA STUFF ------------------- - -global SCHEDULE_SIZE: u32 = 64; -global BLOCK_WORDS: u32 = 16; - -// Casting the 64-bit sum back to u32 automatically keeps the low 32 bits, -// which is equivalent to (a + b) mod 2^32. -fn add_u32(a: u32, b: u32) -> u32 { - let sum = (a as u64) + (b as u64); - sum as u32 -} - -fn add4_u32(a: u32, b: u32, c: u32, d: u32) -> u32 { - let sum = (a as u64) + (b as u64) + (c as u64) + (d as u64); - sum as u32 -} - -fn add5_u32(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 { - let sum = (a as u64) + (b as u64) + (c as u64) + (d as u64) + (e as u64); - sum as u32 -} - -// ------ Vec element-wise operations ------ -fn vec_eltwise_add_u32(a: [u32; 4], b: [u32; 4]) -> [u32; 4] { - [add_u32(a[0], b[0]), add_u32(a[1], b[1]), add_u32(a[2], b[2]), add_u32(a[3], b[3])] -} - -fn vec_shift_left_u32(a: [u32; 4], shift_offset: u8) -> [u32; 4] { - [ - a[0] >> (shift_offset as u32), - a[1] >> (shift_offset as u32), - a[2] >> (shift_offset as u32), - a[3] >> (shift_offset as u32), - ] -} - -fn vec_shift_right_u32(a: [u32; 4], shift_offset: u8) -> [u32; 4] { - [ - a[0] << (shift_offset as u32), - a[1] << (shift_offset as u32), - a[2] << (shift_offset as u32), - a[3] << (shift_offset as u32), - ] -} - -fn vec_eltwise_or_u32(a: [u32; 4], b: [u32; 4]) -> [u32; 4] { - [a[0] | b[0], a[1] | b[1], a[2] | b[2], a[3] | b[3]] -} - -fn vec_eltwise_xor_u32(a: [u32; 4], b: [u32; 4]) -> [u32; 4] { - [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]] -} - -// ------ Rotate left / rotate right functionality ------ -/// Attempting to mimic the `rotate_left` and `rotate_right` functionality -/// using bit-shifts. -/// WARNING: CANNOT USE THIS IF ROTATION_AMT == 0 -fn rotate_left_via_shift_u32(val: u32, rotation_amt: u8) -> u32 { - let rotation_amt = rotation_amt % 32; - static_assert( - rotation_amt != 0, - "Cannot use this function with `rotation_amt` = 0", - ); - // 01234567| - // 012|34567 -> 34567|012 - // We can do this with bit-masking and/or shifting - let left_side_already_moved = val >> (32u32 - (rotation_amt as u32)); - let right_side_already_moved = val << (rotation_amt as u32); - left_side_already_moved | right_side_already_moved -} - -/// WARNING: CANNOT USE THIS IF ROTATION_AMT == 0 -/// Also small note -- this is the elegant but probably inefficient way of doing it -fn rotate_right_via_shift_u32(val: u32, rotation_amt: u8) -> u32 { - let rotation_amt = rotation_amt % 32; - static_assert( - rotation_amt != 0, - "Cannot use this function with `rotation_amt` = 0", - ); - rotate_left_via_shift_u32(val, 32 - rotation_amt) -} - -// ------ `u32`-specific permutation operations ------ -fn big_sigma0(a: u32) -> u32 { - rotate_right_via_shift_u32(a, 2) - ^ rotate_right_via_shift_u32(a, 13) - ^ rotate_right_via_shift_u32(a, 22) -} - -fn big_sigma1(a: u32) -> u32 { - rotate_right_via_shift_u32(a, 6) - ^ rotate_right_via_shift_u32(a, 11) - ^ rotate_right_via_shift_u32(a, 25) -} - -fn small_sigma0(x: u32) -> u32 { - rotate_right_via_shift_u32(x, 7) ^ rotate_right_via_shift_u32(x, 18) ^ (x >> 3) -} - -fn small_sigma1(x: u32) -> u32 { - rotate_right_via_shift_u32(x, 17) ^ rotate_right_via_shift_u32(x, 19) ^ (x >> 10) -} - -fn bool3ary_202(a: u32, b: u32, c: u32) -> u32 { - c ^ (a & (b ^ c)) -} - -fn bool3ary_232(a: u32, b: u32, c: u32) -> u32 { - (a & b) ^ (a & c) ^ (b & c) -} - -fn sha256load(v2: [u32; 4], v3: [u32; 4]) -> [u32; 4] { - [v3[3], v2[0], v2[1], v2[2]] -} - -// sigma 0 on vectors -fn sigma0x4(x: [u32; 4]) -> [u32; 4] { - let t1 = vec_eltwise_or_u32(vec_shift_left_u32(x, 7), vec_shift_right_u32(x, 25)); - let t2 = vec_eltwise_or_u32(vec_shift_left_u32(x, 18), vec_shift_right_u32(x, 14)); - let t3 = vec_shift_left_u32(x, 3); - vec_eltwise_xor_u32(vec_eltwise_xor_u32(t1, t2), t3) -} - -fn sigma1(a: u32) -> u32 { - rotate_right_via_shift_u32(a, 17) ^ rotate_right_via_shift_u32(a, 19) ^ (a >> 10) -} - -fn sha256msg1(v0: [u32; 4], v1: [u32; 4]) -> [u32; 4] { - vec_eltwise_add_u32(v0, sigma0x4(sha256load(v0, v1))) -} - -fn sha256msg2(v4: [u32; 4], v3: [u32; 4]) -> [u32; 4] { - // --- Manual unpacking --- - // let [x3, x2, x1, x0] = v4; - // let [w15, w14, _, _] = v3; - let x3 = v4[0]; - let x2 = v4[1]; - let x1 = v4[2]; - let x0 = v4[3]; - let w15 = v3[0]; - let w14 = v3[1]; - - let w16 = add_u32(x0, sigma1(w14)); - let w17 = add_u32(x1, sigma1(w15)); - let w18 = add_u32(x2, sigma1(w16)); - let w19 = add_u32(x3, sigma1(w17)); - - [w19, w18, w17, w16] -} - -fn schedule(v0: [u32; 4], v1: [u32; 4], v2: [u32; 4], v3: [u32; 4]) -> [u32; 4] { - // --- Okay we do a `msg1` on the first half of the state --- - let t1 = sha256msg1(v0, v1); - // --- Then a `load` on the second half of the state --- - let t2 = sha256load(v2, v3); - // --- Then we add the two results together elt-wise --- - let t3 = vec_eltwise_add_u32(t1, t2); - // --- Then we do a `msg2` on the last part of the state and the result of the earlier add --- - sha256msg2(t3, v3) -} - -/// This is the main block compression function. Its internal logic has been optimized -/// to match the standard SHA-256 algorithm implementation. -pub fn ryan_sha256_digest_block_u32(state: STATE, block: MSG_BLOCK) -> [u32; 8] { - // 1. Message Schedule Generation - let mut schedule: [u32; SCHEDULE_SIZE] = [0; SCHEDULE_SIZE]; - for i in 0..BLOCK_WORDS { - schedule[i] = block[i]; - } - for t in BLOCK_WORDS..SCHEDULE_SIZE { - let s0 = small_sigma0(schedule[t - 15]); - let s1 = small_sigma1(schedule[t - 2]); - schedule[t] = add4_u32(schedule[t - 16], s0, schedule[t - 7], s1); - } - - // 2. Initialize working variables - let mut a = state[0]; - let mut b = state[1]; - let mut c = state[2]; - let mut d = state[3]; - let mut e = state[4]; - let mut f = state[5]; - let mut g = state[6]; - let mut h = state[7]; - - // 3. Main Compression Loop (64 rounds) - for t in 0..SCHEDULE_SIZE { - let w = schedule[t]; - let k = K32[t]; - - let sigma1_e = big_sigma1(e); - let ch_efg = bool3ary_202(e, f, g); - let temp1 = add5_u32(h, sigma1_e, ch_efg, k, w); - - let sigma0_a = big_sigma0(a); - let maj_abc = bool3ary_232(a, b, c); - let temp2 = add_u32(sigma0_a, maj_abc); - - h = g; - g = f; - f = e; - e = add_u32(d, temp1); - d = c; - c = b; - b = a; - a = add_u32(temp1, temp2); - } - - // 4. Add the compressed block to the initial state - [ - add_u32(state[0], a), - add_u32(state[1], b), - add_u32(state[2], c), - add_u32(state[3], d), - add_u32(state[4], e), - add_u32(state[5], f), - add_u32(state[6], g), - add_u32(state[7], h), - ] -} - -mod test { - #[test] - fn test_no_overflow() { - let res = super::add_u32(1, 2); - assert(res == 3); - } - - #[test] - fn test_overflow_exact() { - let max = 0xFFFFFFFF; - let res = super::add_u32(max, 1); - assert(res == 0); - } - - #[test] - fn test_overflow_carry() { - let max = 0xFFFFFFFF; - let res = super::add_u32(max, 2); - assert(res == 1); - } - - #[test] - fn test_large_sum() { - let res = super::add_u32(4000000000, 4000000000); - assert(res == 3705032704); - } -} diff --git a/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_constants.nr b/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_constants.nr deleted file mode 100644 index 768e5181..00000000 --- a/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_constants.nr +++ /dev/null @@ -1,206 +0,0 @@ -/// Note: Everything here was taken exactly from Noir's stdlib! - -// A message block is up to 64 bytes taken from the input. -pub(crate) global BLOCK_SIZE: u32 = 64; - -// The first index in the block where the 8 byte message size will be written. -pub(crate) global MSG_SIZE_PTR: u32 = 56; - -// Size of the message block when packed as 4-byte integer array. -pub(crate) global INT_BLOCK_SIZE: u32 = 16; - -// A `u32` integer consists of 4 bytes. -pub(crate) global INT_SIZE: u32 = 4; - -// Index of the integer in the `INT_BLOCK` where the length is written. -pub(crate) global INT_SIZE_PTR: u32 = MSG_SIZE_PTR / INT_SIZE; - -// Magic numbers for bit shifting. -// Works with actual bit shifting as well as the compiler turns them into * and / -// but circuit execution appears to be 10% faster this way. -pub(crate) global TWO_POW_8: u32 = 256; -pub(crate) global TWO_POW_16: u32 = TWO_POW_8 * 256; -pub(crate) global TWO_POW_24: u32 = TWO_POW_16 * 256; -pub(crate) global TWO_POW_32: u64 = TWO_POW_24 as u64 * 256; - -// Index of a byte in a 64 byte block; ie. 0..=63 -pub(crate) type BLOCK_BYTE_PTR = u32; - -// The foreign function to compress blocks works on 16 pieces of 4-byte integers, instead of 64 bytes. -pub(crate) type INT_BLOCK = [u32; INT_BLOCK_SIZE]; - -// A message block is a slice of the original message of a fixed size, -// potentially padded with zeros, with neighbouring 4 bytes packed into integers. -pub(crate) type MSG_BLOCK = INT_BLOCK; - -// The hash is 32 bytes. -pub(crate) type HASH = [u8; 32]; - -// The state accumulates the blocks. -// Its overall size is the same as the `HASH`. -pub(crate) type STATE = [u32; 8]; - -pub(crate) global INITIAL_STATE: STATE = - [1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]; - -/// Constants necessary for SHA-256 family of digests. -/// This comes straight from the Rust crate! -pub(crate) global K32: [u32; 64] = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, -]; - -/// Constants necessary for SHA-256 family of digests. -pub(crate) global K32X4: [[u32; 4]; 16] = [ - [K32[3], K32[2], K32[1], K32[0]], - [K32[7], K32[6], K32[5], K32[4]], - [K32[11], K32[10], K32[9], K32[8]], - [K32[15], K32[14], K32[13], K32[12]], - [K32[19], K32[18], K32[17], K32[16]], - [K32[23], K32[22], K32[21], K32[20]], - [K32[27], K32[26], K32[25], K32[24]], - [K32[31], K32[30], K32[29], K32[28]], - [K32[35], K32[34], K32[33], K32[32]], - [K32[39], K32[38], K32[37], K32[36]], - [K32[43], K32[42], K32[41], K32[40]], - [K32[47], K32[46], K32[45], K32[44]], - [K32[51], K32[50], K32[49], K32[48]], - [K32[55], K32[54], K32[53], K32[52]], - [K32[59], K32[58], K32[57], K32[56]], - [K32[63], K32[62], K32[61], K32[60]], -]; - -// For testing only! -pub global MAX_MSG_LEN: u32 = 200; -pub global RANDOM_BYTES_MANY_ROUNDS: [[u8; MAX_MSG_LEN]; 10] = [ - [ - 135, 110, 24, 10, 50, 41, 232, 130, 213, 127, 120, 31, 206, 8, 233, 158, 66, 139, 104, 226, - 235, 241, 54, 22, 186, 25, 40, 158, 14, 191, 166, 105, 201, 132, 98, 169, 150, 250, 198, - 156, 126, 90, 34, 191, 246, 131, 194, 148, 141, 212, 30, 249, 111, 204, 131, 224, 186, 194, - 32, 190, 166, 96, 232, 211, 113, 102, 182, 191, 136, 55, 35, 159, 38, 254, 75, 25, 78, 76, - 138, 160, 239, 202, 238, 255, 131, 225, 184, 133, 48, 156, 82, 235, 6, 94, 19, 183, 215, - 115, 123, 237, 72, 239, 252, 103, 200, 8, 130, 134, 61, 42, 156, 121, 123, 213, 149, 189, - 164, 143, 211, 158, 208, 242, 84, 77, 66, 24, 11, 221, 173, 233, 172, 73, 242, 102, 116, 25, - 197, 222, 33, 143, 50, 123, 32, 88, 142, 133, 128, 6, 149, 141, 192, 177, 125, 103, 237, 58, - 224, 57, 229, 124, 111, 150, 146, 29, 19, 116, 205, 96, 67, 134, 179, 76, 212, 138, 83, 11, - 69, 195, 141, 7, 105, 154, 100, 168, 218, 165, 136, 243, 100, 171, 145, 112, 254, 119, 86, - 104, 78, 74, 178, 23, - ], - [ - 221, 143, 116, 82, 31, 121, 28, 55, 232, 30, 163, 164, 152, 202, 228, 36, 247, 33, 246, 100, - 170, 16, 137, 241, 234, 114, 13, 85, 124, 238, 199, 7, 106, 46, 19, 70, 128, 222, 104, 71, - 26, 228, 30, 5, 81, 89, 14, 149, 65, 60, 150, 165, 51, 19, 88, 20, 94, 239, 197, 244, 0, 82, - 59, 225, 80, 43, 70, 182, 34, 218, 115, 207, 226, 210, 193, 105, 212, 171, 215, 14, 121, - 129, 67, 252, 248, 167, 67, 160, 215, 143, 160, 219, 134, 163, 19, 23, 241, 150, 208, 135, - 75, 234, 28, 145, 151, 59, 176, 130, 109, 28, 144, 199, 223, 10, 64, 226, 138, 3, 218, 185, - 67, 159, 121, 109, 10, 6, 22, 18, 239, 249, 124, 64, 150, 209, 209, 196, 30, 12, 82, 13, - 147, 192, 148, 239, 134, 222, 37, 127, 65, 94, 251, 253, 96, 195, 93, 13, 238, 185, 1, 177, - 108, 200, 106, 45, 143, 74, 5, 161, 157, 60, 62, 14, 254, 35, 158, 61, 203, 105, 36, 177, - 88, 210, 254, 167, 187, 63, 80, 100, 208, 117, 15, 212, 144, 34, 37, 251, 249, 79, 53, 26, - ], - [ - 246, 122, 161, 103, 235, 115, 127, 169, 26, 7, 26, 29, 150, 102, 88, 221, 113, 229, 17, 5, - 51, 197, 33, 69, 215, 104, 241, 172, 115, 148, 53, 78, 45, 227, 172, 106, 72, 227, 239, 14, - 195, 111, 9, 100, 135, 88, 6, 248, 186, 9, 12, 212, 101, 255, 158, 21, 71, 211, 55, 96, 198, - 169, 3, 93, 211, 221, 31, 224, 61, 213, 156, 101, 53, 106, 184, 185, 22, 45, 54, 149, 157, - 199, 126, 227, 163, 144, 13, 88, 228, 41, 68, 65, 172, 158, 0, 116, 255, 110, 222, 138, 29, - 100, 1, 137, 164, 246, 116, 118, 249, 132, 176, 169, 206, 113, 18, 242, 53, 220, 130, 167, - 142, 224, 15, 248, 28, 138, 89, 249, 15, 255, 163, 12, 254, 150, 143, 191, 98, 201, 102, 74, - 24, 156, 61, 66, 88, 249, 144, 35, 9, 173, 130, 41, 47, 120, 121, 100, 145, 227, 68, 172, - 196, 36, 72, 126, 183, 146, 71, 254, 127, 27, 141, 133, 215, 120, 60, 239, 192, 115, 165, - 211, 91, 9, 119, 254, 187, 116, 19, 81, 25, 50, 112, 73, 47, 81, 54, 206, 34, 248, 140, 69, - ], - [ - 74, 2, 238, 64, 71, 241, 29, 60, 232, 166, 74, 80, 232, 91, 137, 134, 64, 5, 0, 196, 249, - 171, 108, 2, 13, 194, 164, 157, 236, 148, 38, 113, 47, 32, 219, 154, 212, 188, 216, 232, - 228, 135, 117, 103, 160, 64, 206, 166, 194, 80, 18, 233, 130, 192, 94, 94, 198, 223, 197, - 80, 222, 15, 202, 139, 34, 228, 134, 1, 157, 138, 166, 105, 139, 230, 250, 134, 138, 47, - 181, 225, 226, 225, 1, 207, 28, 176, 22, 229, 113, 151, 5, 135, 12, 218, 204, 81, 56, 33, - 14, 120, 102, 209, 24, 101, 105, 219, 126, 147, 102, 56, 237, 210, 120, 15, 232, 175, 174, - 202, 249, 60, 69, 120, 125, 110, 118, 109, 210, 249, 222, 85, 128, 254, 228, 125, 151, 32, - 168, 204, 138, 244, 237, 240, 101, 5, 209, 73, 24, 246, 230, 225, 35, 150, 97, 73, 27, 165, - 4, 82, 168, 206, 51, 54, 144, 237, 33, 147, 117, 250, 97, 23, 115, 195, 227, 179, 166, 187, - 118, 237, 247, 113, 100, 208, 174, 86, 82, 124, 75, 128, 90, 80, 220, 43, 176, 134, 43, 74, - 48, 205, 118, 27, - ], - [ - 252, 93, 181, 230, 15, 86, 96, 14, 167, 96, 133, 93, 17, 125, 27, 62, 228, 85, 43, 229, 186, - 45, 192, 185, 4, 204, 11, 249, 33, 90, 199, 90, 64, 60, 112, 35, 159, 246, 70, 31, 191, 51, - 108, 156, 225, 110, 208, 18, 189, 125, 186, 210, 68, 215, 53, 145, 93, 85, 217, 215, 129, - 49, 165, 48, 168, 38, 31, 152, 191, 154, 174, 157, 149, 122, 165, 84, 92, 218, 60, 76, 157, - 166, 219, 21, 112, 113, 218, 92, 177, 31, 71, 73, 185, 61, 93, 152, 107, 153, 223, 94, 163, - 131, 141, 110, 10, 73, 78, 150, 166, 72, 4, 59, 30, 175, 102, 51, 163, 26, 8, 182, 92, 169, - 45, 146, 34, 149, 62, 32, 103, 7, 254, 57, 52, 188, 13, 145, 116, 74, 129, 226, 133, 218, - 199, 230, 107, 179, 0, 81, 198, 37, 59, 53, 60, 42, 107, 194, 75, 212, 39, 148, 1, 242, 200, - 255, 119, 245, 119, 249, 248, 130, 196, 104, 3, 30, 253, 91, 89, 169, 113, 46, 197, 191, - 206, 167, 5, 88, 229, 208, 60, 250, 84, 102, 63, 110, 151, 21, 93, 238, 10, 94, - ], - [ - 74, 157, 115, 100, 40, 44, 36, 154, 71, 71, 49, 83, 218, 204, 192, 140, 44, 154, 188, 1, - 209, 116, 6, 249, 243, 27, 59, 212, 165, 25, 65, 254, 75, 159, 23, 100, 161, 58, 188, 182, - 96, 27, 96, 125, 112, 216, 80, 141, 8, 57, 7, 216, 52, 247, 16, 102, 24, 250, 231, 162, 79, - 5, 116, 172, 172, 162, 34, 219, 207, 126, 17, 132, 240, 96, 122, 122, 81, 135, 168, 99, 220, - 26, 113, 200, 34, 221, 186, 249, 174, 68, 103, 245, 202, 77, 24, 165, 187, 133, 246, 139, 2, - 235, 236, 30, 233, 63, 115, 57, 63, 96, 224, 244, 96, 17, 128, 175, 94, 131, 129, 72, 6, - 101, 0, 23, 8, 183, 229, 206, 131, 141, 142, 98, 8, 31, 108, 149, 92, 190, 30, 193, 36, 111, - 193, 63, 66, 36, 189, 189, 67, 192, 177, 136, 30, 44, 118, 138, 100, 80, 79, 69, 164, 160, - 184, 227, 163, 228, 221, 91, 202, 5, 119, 11, 163, 141, 219, 119, 2, 179, 148, 78, 7, 109, - 19, 226, 108, 151, 75, 153, 186, 91, 41, 231, 75, 159, 167, 44, 173, 233, 83, 128, - ], - [ - 175, 63, 171, 211, 79, 53, 78, 174, 208, 4, 112, 147, 58, 77, 161, 210, 6, 105, 209, 17, 25, - 15, 233, 73, 230, 229, 41, 181, 12, 3, 221, 71, 172, 115, 237, 145, 114, 37, 32, 82, 252, - 179, 208, 74, 219, 190, 120, 35, 35, 3, 159, 187, 32, 56, 171, 188, 54, 144, 12, 227, 254, - 64, 202, 68, 122, 153, 99, 4, 144, 243, 138, 21, 65, 91, 44, 243, 108, 4, 243, 133, 253, 48, - 30, 138, 144, 70, 4, 103, 179, 173, 102, 97, 243, 255, 105, 235, 79, 208, 135, 70, 131, 246, - 128, 109, 71, 218, 63, 225, 162, 189, 96, 91, 198, 73, 159, 97, 158, 62, 179, 5, 34, 161, - 17, 170, 154, 2, 90, 184, 128, 77, 171, 0, 70, 193, 191, 199, 47, 186, 216, 204, 63, 30, 42, - 185, 3, 58, 107, 66, 237, 242, 136, 108, 112, 78, 54, 80, 13, 84, 70, 59, 225, 71, 221, 11, - 91, 201, 106, 27, 52, 10, 1, 19, 123, 146, 160, 236, 55, 151, 90, 140, 118, 205, 104, 232, - 250, 248, 1, 122, 68, 163, 216, 255, 21, 129, 175, 10, 77, 34, 138, 95, - ], - [ - 121, 149, 30, 162, 8, 35, 149, 174, 234, 51, 166, 157, 62, 15, 63, 193, 75, 164, 22, 67, 10, - 54, 240, 231, 69, 29, 193, 12, 159, 161, 156, 111, 0, 231, 168, 205, 253, 203, 239, 175, - 154, 200, 109, 210, 207, 59, 101, 236, 40, 15, 114, 162, 150, 167, 202, 120, 220, 184, 63, - 100, 234, 186, 137, 70, 131, 161, 3, 190, 162, 96, 72, 241, 45, 61, 212, 144, 227, 254, 197, - 143, 15, 42, 88, 25, 122, 148, 42, 25, 193, 255, 248, 139, 45, 93, 94, 212, 87, 210, 253, 4, - 65, 212, 226, 202, 63, 78, 158, 54, 70, 242, 120, 145, 136, 73, 74, 237, 86, 171, 33, 48, - 113, 243, 134, 198, 120, 188, 189, 169, 2, 233, 24, 252, 76, 127, 54, 59, 62, 1, 146, 71, - 255, 200, 165, 222, 69, 150, 216, 228, 86, 144, 66, 96, 104, 93, 240, 28, 49, 1, 155, 153, - 198, 137, 33, 204, 168, 202, 45, 10, 47, 136, 217, 155, 99, 183, 38, 202, 55, 215, 91, 91, - 143, 21, 211, 155, 162, 143, 176, 144, 40, 50, 169, 89, 99, 55, 29, 161, 100, 238, 92, 13, - ], - [ - 222, 3, 164, 51, 162, 96, 39, 241, 77, 66, 149, 57, 205, 94, 177, 214, 106, 192, 240, 126, - 6, 137, 248, 76, 19, 111, 195, 160, 204, 112, 126, 45, 159, 176, 240, 209, 205, 29, 236, - 227, 83, 173, 127, 239, 183, 157, 91, 175, 114, 130, 220, 108, 189, 101, 34, 223, 251, 196, - 55, 237, 21, 194, 174, 157, 85, 47, 214, 176, 185, 178, 155, 11, 27, 65, 114, 2, 165, 218, - 232, 193, 235, 124, 211, 144, 198, 166, 168, 125, 164, 95, 147, 196, 223, 48, 18, 174, 234, - 24, 227, 45, 238, 205, 166, 47, 158, 25, 140, 57, 157, 160, 132, 159, 15, 107, 6, 163, 12, - 63, 198, 179, 225, 193, 199, 124, 33, 76, 4, 18, 202, 30, 221, 178, 42, 106, 17, 137, 30, - 118, 71, 252, 169, 145, 45, 116, 132, 112, 124, 183, 93, 112, 1, 228, 209, 146, 90, 171, - 208, 36, 75, 254, 202, 27, 174, 149, 223, 60, 137, 125, 219, 215, 65, 86, 165, 100, 0, 30, - 165, 181, 112, 91, 111, 31, 145, 249, 144, 32, 86, 242, 188, 203, 212, 158, 17, 110, 90, - 204, 22, 48, 111, 9, - ], - [ - 158, 130, 60, 123, 23, 127, 11, 161, 125, 102, 44, 222, 31, 30, 181, 219, 64, 63, 215, 137, - 193, 101, 143, 29, 239, 44, 209, 158, 49, 179, 106, 183, 173, 222, 113, 226, 127, 143, 253, - 187, 73, 62, 70, 233, 190, 231, 161, 132, 141, 76, 193, 148, 85, 13, 61, 144, 54, 133, 149, - 126, 173, 175, 81, 94, 228, 62, 221, 171, 135, 129, 231, 22, 108, 207, 204, 35, 66, 173, - 111, 238, 232, 19, 119, 219, 59, 21, 133, 101, 147, 98, 195, 3, 101, 72, 48, 104, 158, 145, - 83, 151, 186, 105, 125, 139, 221, 58, 91, 20, 172, 128, 182, 122, 225, 69, 170, 32, 120, - 192, 156, 120, 248, 25, 124, 112, 175, 97, 142, 201, 32, 82, 84, 139, 42, 211, 118, 205, 56, - 93, 155, 58, 217, 251, 84, 206, 48, 153, 66, 118, 222, 24, 156, 40, 124, 248, 1, 97, 9, 178, - 5, 29, 128, 19, 153, 20, 83, 202, 233, 177, 81, 245, 71, 253, 57, 104, 44, 101, 68, 202, - 217, 170, 240, 22, 181, 66, 39, 36, 195, 119, 254, 165, 14, 250, 68, 109, 173, 131, 150, - 244, 181, 165, - ], -]; diff --git a/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_noir.nr b/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_noir.nr deleted file mode 100644 index 55366a1f..00000000 --- a/noir-examples/noir-passport-examples/noir_native_sha256/src/ryan_sha256_noir.nr +++ /dev/null @@ -1,520 +0,0 @@ -use std::runtime::is_unconstrained; - -use super::{ - ryan_sha256_compression::ryan_sha256_digest_block_u32, - ryan_sha256_constants::{ - BLOCK_BYTE_PTR, BLOCK_SIZE, HASH, INITIAL_STATE, INT_BLOCK, INT_BLOCK_SIZE, INT_SIZE, - INT_SIZE_PTR, MSG_BLOCK, MSG_SIZE_PTR, STATE, TWO_POW_16, TWO_POW_24, TWO_POW_32, TWO_POW_8, - }, -}; - -// Implementation of SHA-256 mapping a byte array of variable length to -// 32 bytes. - -// Variable size SHA-256 hash -pub fn sha256_var(msg: [u8; N], message_size: u64) -> HASH { - let message_size = message_size as u32; - assert(message_size <= N); - - if std::runtime::is_unconstrained() { - // Safety: SHA256 is running as an unconstrained function. - unsafe { - __sha256_var(msg, message_size) - } - } else { - let mut msg_block: MSG_BLOCK = [0; INT_BLOCK_SIZE]; // [u32; 16] - // Intermediate hash, starting with the canonical initial value - let mut h: STATE = INITIAL_STATE; // [u32; 8] - // Pointer into msg_block on a 64 byte scale - // --- Note: 64 bytes == 512 bits --- - let mut msg_byte_ptr = 0; - let num_blocks = N / BLOCK_SIZE; - for i in 0..num_blocks { - let msg_start = BLOCK_SIZE * i; - // Safety: The `verify_msg_block` function should cover this. - let (new_msg_block, new_msg_byte_ptr) = - unsafe { build_msg_block(msg, message_size, msg_start) }; - - if msg_start < message_size { - msg_block = new_msg_block; - } - - // Verify the block we are compressing was appropriately constructed - let new_msg_byte_ptr = verify_msg_block(msg, message_size, msg_block, msg_start); - if msg_start < message_size { - msg_byte_ptr = new_msg_byte_ptr; - } - - // If the block is filled, compress it. - // An un-filled block is handled after this loop. - if (msg_start < message_size) & (msg_byte_ptr == BLOCK_SIZE) { - h = ryan_sha256_digest_block_u32(h, msg_block); - } - } - - let modulo = N % BLOCK_SIZE; - // Handle setup of the final msg block. - // This case is only hit if the msg is less than the block size, - // or our message cannot be evenly split into blocks. - if modulo != 0 { - let msg_start = BLOCK_SIZE * num_blocks; - // Safety: The `verify_msg_block` function should cover this. - let (new_msg_block, new_msg_byte_ptr) = - unsafe { build_msg_block(msg, message_size, msg_start) }; - - if msg_start < message_size { - msg_block = new_msg_block; - } - - let new_msg_byte_ptr = verify_msg_block(msg, message_size, msg_block, msg_start); - if msg_start < message_size { - msg_byte_ptr = new_msg_byte_ptr; - verify_msg_block_padding(msg_block, msg_byte_ptr); - } - } - - // If we had modulo == 0 then it means the last block was full, - // and we can reset the pointer to zero to overwrite it. - if msg_byte_ptr == BLOCK_SIZE { - msg_byte_ptr = 0; - } - - // Pad the rest such that we have a [u32; 2] block at the end representing the length - // of the message, and a block of 1 0 ... 0 following the message (i.e. [1 << 7, 0, ..., 0]). - // Here we rely on the fact that everything beyond the available input is set to 0. - let index = msg_byte_ptr / INT_SIZE; - msg_block[index] = set_item_byte_then_zeros(msg_block[index], msg_byte_ptr, 1 << 7); - - msg_byte_ptr = msg_byte_ptr + 1; - let last_block = msg_block; - - // If we don't have room to write the size, compress the block and reset it. - if msg_byte_ptr > MSG_SIZE_PTR { - h = ryan_sha256_digest_block_u32(h, msg_block); - // `attach_len_to_msg_block` will zero out everything after the `msg_byte_ptr`. - msg_byte_ptr = 0; - } - - // Safety: The `verify_msg_block` function should cover this. - msg_block = unsafe { attach_len_to_msg_block(msg_block, msg_byte_ptr, message_size) }; - - verify_msg_len(msg_block, last_block, msg_byte_ptr, message_size); - - hash_final_block(msg_block, h) - } -} - -// Variable size SHA-256 hash -unconstrained fn __sha256_var(msg: [u8; N], message_size: u32) -> HASH { - let num_full_blocks = message_size / BLOCK_SIZE; - // Intermediate hash, starting with the canonical initial value - let mut h: STATE = INITIAL_STATE; - // Pointer into msg_block on a 64 byte scale - for i in 0..num_full_blocks { - let (msg_block, _) = build_msg_block(msg, message_size, BLOCK_SIZE * i); - h = ryan_sha256_digest_block_u32(h, msg_block); - } - - // Handle setup of the final msg block. - // This case is only hit if the msg is less than the block size, - // or our message cannot be evenly split into blocks. - let modulo = message_size % BLOCK_SIZE; - let (mut msg_block, mut msg_byte_ptr): (INT_BLOCK, u32) = if modulo != 0 { - let msg_start = BLOCK_SIZE * num_full_blocks; - let (new_msg_block, new_msg_byte_ptr) = build_msg_block(msg, message_size, msg_start); - - (new_msg_block, new_msg_byte_ptr) - } else { - // If we had modulo == 0 then it means the last block was full, - // and we can reset the pointer to zero to overwrite it. - ([0; INT_BLOCK_SIZE], 0) - }; - - // Pad the rest such that we have a [u32; 2] block at the end representing the length - // of the message, and a block of 1 0 ... 0 following the message (i.e. [1 << 7, 0, ..., 0]). - // Here we rely on the fact that everything beyond the available input is set to 0. - let index = msg_byte_ptr / INT_SIZE; - msg_block[index] = set_item_byte_then_zeros(msg_block[index], msg_byte_ptr, 1 << 7); - - // If we don't have room to write the size, compress the block and reset it. - let (h, mut msg_byte_ptr): (STATE, u32) = if msg_byte_ptr >= MSG_SIZE_PTR { - // `attach_len_to_msg_block` will zero out everything after the `msg_byte_ptr`. - (ryan_sha256_digest_block_u32(h, msg_block), 0) - } else { - (h, msg_byte_ptr + 1) - }; - msg_block = attach_len_to_msg_block(msg_block, msg_byte_ptr, message_size); - - hash_final_block(msg_block, h) -} - -// Take `BLOCK_SIZE` number of bytes from `msg` starting at `msg_start`. -// Returns the block and the length that has been copied rather than padded with zeros. -unconstrained fn build_msg_block( - msg: [u8; N], - message_size: u32, - msg_start: u32, -) -> (MSG_BLOCK, BLOCK_BYTE_PTR) { - let mut msg_block: MSG_BLOCK = [0; INT_BLOCK_SIZE]; - - // We insert `BLOCK_SIZE` bytes (or up to the end of the message) - let block_input = if msg_start + BLOCK_SIZE > message_size { - if message_size < msg_start { - // This function is sometimes called with `msg_start` past the end of the message. - // In this case we return an empty block and zero pointer to signal that the result should be ignored. - 0 - } else { - message_size - msg_start - } - } else { - BLOCK_SIZE - }; - - // Figure out the number of items in the int array that we have to pack. - // e.g. if the input is [0,1,2,3,4,5] then we need to pack it as 2 items: [0123, 4500] - let mut int_input = block_input / INT_SIZE; - if block_input % INT_SIZE != 0 { - int_input = int_input + 1; - }; - - for i in 0..int_input { - let mut msg_item: u32 = 0; - // Always construct the integer as 4 bytes, even if it means going beyond the input. - for j in 0..INT_SIZE { - let k = i * INT_SIZE + j; - let msg_byte = if k < block_input { - msg[msg_start + k] - } else { - 0 - }; - msg_item = lshift8(msg_item, 1) + msg_byte as u32; - } - msg_block[i] = msg_item; - } - - // Returning the index as if it was a 64 byte array. - // We have to project it down to 16 items and bit shifting to get a byte back if we need it. - (msg_block, block_input) -} - -// Verify the block we are compressing was appropriately constructed by `build_msg_block` -// and matches the input data. Returns the index of the first unset item. -// If `message_size` is less than `msg_start` then this is called with the old non-empty block; -// in that case we can skip verification, ie. no need to check that everything is zero. -fn verify_msg_block( - msg: [u8; N], - message_size: u32, - msg_block: MSG_BLOCK, - msg_start: u32, -) -> BLOCK_BYTE_PTR { - let mut msg_byte_ptr = 0; - let mut msg_end = msg_start + BLOCK_SIZE; - if msg_end > N { - msg_end = N; - } - // We might have to go beyond the input to pad the fields. - if msg_end % INT_SIZE != 0 { - msg_end = msg_end + INT_SIZE - msg_end % INT_SIZE; - } - - // Reconstructed packed item. - let mut msg_item: u32 = 0; - - // Inclusive at the end so that we can compare the last item. - let mut i: u32 = 0; - for k in msg_start..=msg_end { - if k % INT_SIZE == 0 { - // If we consumed some input we can compare against the block. - if (msg_start < message_size) & (k > msg_start) { - assert_eq(msg_block[i], msg_item as u32); - i = i + 1; - msg_item = 0; - } - } - // Shift the accumulator - msg_item = lshift8(msg_item, 1); - // If we have input to consume, add it at the rightmost position. - if k < message_size & k < msg_end { - msg_item = msg_item + msg[k] as u32; - msg_byte_ptr = msg_byte_ptr + 1; - } - } - - msg_byte_ptr -} - -// Verify the block we are compressing was appropriately padded with zeros by `build_msg_block`. -// This is only relevant for the last, potentially partially filled block. -fn verify_msg_block_padding(msg_block: MSG_BLOCK, msg_byte_ptr: BLOCK_BYTE_PTR) { - // Check all the way to the end of the block. - verify_msg_block_zeros(msg_block, msg_byte_ptr, INT_BLOCK_SIZE); -} - -// Verify that a region of ints in the message block are (partially) zeroed, -// up to an (exclusive) maximum which can either be the end of the block -// or just where the size is to be written. -fn verify_msg_block_zeros( - msg_block: MSG_BLOCK, - mut msg_byte_ptr: BLOCK_BYTE_PTR, - max_int_byte_ptr: u32, -) { - // This variable is used to get around the compiler under-constrained check giving a warning. - // We want to check against a constant zero, but if it does not come from the circuit inputs - // or return values the compiler check will issue a warning. - let zero = msg_block[0] - msg_block[0]; - - // First integer which is supposed to be (partially) zero. - let mut int_byte_ptr = msg_byte_ptr / INT_SIZE; - - // Check partial zeros. - let modulo = msg_byte_ptr % INT_SIZE; - if modulo != 0 { - let zeros = INT_SIZE - modulo; - let mask = if zeros == 3 { - TWO_POW_24 - } else if zeros == 2 { - TWO_POW_16 - } else { - TWO_POW_8 - }; - assert_eq(msg_block[int_byte_ptr] % mask, zero); - int_byte_ptr = int_byte_ptr + 1; - } - - // Check the rest of the items. - for i in 0..max_int_byte_ptr { - if i >= int_byte_ptr { - assert_eq(msg_block[i], zero); - } - } -} - -// Verify that up to the byte pointer the two blocks are equal. -// At the byte pointer the new block can be partially zeroed. -fn verify_msg_block_equals_last( - msg_block: MSG_BLOCK, - last_block: MSG_BLOCK, - mut msg_byte_ptr: BLOCK_BYTE_PTR, -) { - // msg_byte_ptr is the position at which they are no longer have to be the same. - // First integer which is supposed to be (partially) zero contains that pointer. - let mut int_byte_ptr = msg_byte_ptr / INT_SIZE; - - // Check partial zeros. - let modulo = msg_byte_ptr % INT_SIZE; - if modulo != 0 { - // Reconstruct the partially zero item from the last block. - let last_field = last_block[int_byte_ptr]; - let mut msg_item: u32 = 0; - // Reset to where they are still equal. - msg_byte_ptr = msg_byte_ptr - modulo; - for i in 0..INT_SIZE { - msg_item = lshift8(msg_item, 1); - if i < modulo { - msg_item = msg_item + get_item_byte(last_field, msg_byte_ptr) as u32; - msg_byte_ptr = msg_byte_ptr + 1; - } - } - assert_eq(msg_block[int_byte_ptr], msg_item); - } - - for i in 0..INT_SIZE_PTR { - if i < int_byte_ptr { - assert_eq(msg_block[i], last_block[i]); - } - } -} - -// Set the rightmost `zeros` number of bytes to 0. -fn set_item_zeros(item: u32, zeros: u8) -> u32 { - lshift8(rshift8(item, zeros), zeros) -} - -// Replace one byte in the item with a value, and set everything after it to zero. -fn set_item_byte_then_zeros(msg_item: u32, msg_byte_ptr: BLOCK_BYTE_PTR, msg_byte: u8) -> u32 { - let zeros = INT_SIZE - msg_byte_ptr % INT_SIZE; - let zeroed_item = set_item_zeros(msg_item, zeros as u8); - let new_item = byte_into_item(msg_byte, msg_byte_ptr); - zeroed_item + new_item -} - -// Get a byte of a message item according to its overall position in the `BLOCK_SIZE` space. -fn get_item_byte(mut msg_item: u32, msg_byte_ptr: BLOCK_BYTE_PTR) -> u8 { - // How many times do we have to shift to the right to get to the position we want? - let max_shifts = INT_SIZE - 1; - let shifts = max_shifts - msg_byte_ptr % INT_SIZE; - msg_item = rshift8(msg_item, shifts as u8); - // At this point the byte we want is in the rightmost position. - msg_item as u8 -} - -// Project a byte into a position in a field based on the overall block pointer. -// For example putting 1 into pointer 5 would be 100, because overall we would -// have [____, 0100] with indexes [0123,4567]. -fn byte_into_item(msg_byte: u8, msg_byte_ptr: BLOCK_BYTE_PTR) -> u32 { - let mut msg_item = msg_byte as u32; - // How many times do we have to shift to the left to get to the position we want? - let max_shifts = INT_SIZE - 1; - let shifts = max_shifts - msg_byte_ptr % INT_SIZE; - lshift8(msg_item, shifts as u8) -} - -// Construct a field out of 4 bytes. -fn make_item(b0: u8, b1: u8, b2: u8, b3: u8) -> u32 { - let mut item = b0 as u32; - item = lshift8(item, 1) + b1 as u32; - item = lshift8(item, 1) + b2 as u32; - item = lshift8(item, 1) + b3 as u32; - item -} - -// Shift by 8 bits to the left between 0 and 4 times. -// Checks `is_unconstrained()` to just use a bitshift if we're running in an unconstrained context, -// otherwise multiplies by 256. -fn lshift8(item: u32, shifts: u8) -> u32 { - if is_unconstrained() { - if item == 0 { - 0 - } else { - // Brillig wouldn't shift 0<<4 without overflow. - item << (8 * shifts) as u32 - } - } else { - // We can do a for loop up to INT_SIZE or an if-else. - if shifts == 0 { - item - } else if shifts == 1 { - item * TWO_POW_8 - } else if shifts == 2 { - item * TWO_POW_16 - } else if shifts == 3 { - item * TWO_POW_24 - } else { - // Doesn't make sense, but it's most likely called on 0 anyway. - 0 - } - } -} - -// Shift by 8 bits to the right between 0 and 4 times. -// Checks `is_unconstrained()` to just use a bitshift if we're running in an unconstrained context, -// otherwise divides by 256. -fn rshift8(item: u32, shifts: u8) -> u32 { - if is_unconstrained() { - let shift_amount = (8 * shifts) as u32; - if shift_amount >= 32 { - 0 - } else { - item >> shift_amount - } - } else { - // Division wouldn't work on `Field`. - if shifts == 0 { - item - } else if shifts == 1 { - item / TWO_POW_8 - } else if shifts == 2 { - item / TWO_POW_16 - } else if shifts == 3 { - item / TWO_POW_24 - } else { - 0 - } - } -} - -// Zero out all bytes between the end of the message and where the length is appended, -// then write the length into the last 8 bytes of the block. -unconstrained fn attach_len_to_msg_block( - mut msg_block: MSG_BLOCK, - mut msg_byte_ptr: BLOCK_BYTE_PTR, - message_size: u32, -) -> MSG_BLOCK { - // We assume that `msg_byte_ptr` is less than 57 because if not then it is reset to zero before calling this function. - // In any case, fill blocks up with zeros until the last 64 bits (i.e. until msg_byte_ptr = 56). - // There can be one item which has to be partially zeroed. - let modulo = msg_byte_ptr % INT_SIZE; - if modulo != 0 { - // Index of the block in which we find the item we need to partially zero. - let i = msg_byte_ptr / INT_SIZE; - let zeros = INT_SIZE - modulo; - msg_block[i] = set_item_zeros(msg_block[i], zeros as u8); - msg_byte_ptr = msg_byte_ptr + zeros; - } - - // The rest can be zeroed without bit shifting anything. - for i in (msg_byte_ptr / INT_SIZE)..INT_SIZE_PTR { - msg_block[i] = 0; - } - - // Set the last two 4 byte ints as the first/second half of the 8 bytes of the length. - let len = 8 * message_size; - let len_bytes: [u8; 8] = (len as Field).to_be_bytes(); - for i in 0..=1 { - let shift = i * 4; - msg_block[INT_SIZE_PTR + i] = make_item( - len_bytes[shift], - len_bytes[shift + 1], - len_bytes[shift + 2], - len_bytes[shift + 3], - ); - } - msg_block -} - -// Verify that the message length was correctly written by `attach_len_to_msg_block`, -// and that everything between the byte pointer and the size pointer was zeroed, -// and that everything before the byte pointer was untouched. -fn verify_msg_len( - msg_block: MSG_BLOCK, - last_block: MSG_BLOCK, - msg_byte_ptr: BLOCK_BYTE_PTR, - message_size: u32, -) { - // Check zeros up to the size pointer. - verify_msg_block_zeros(msg_block, msg_byte_ptr, INT_SIZE_PTR); - - // Check that up to the pointer we match the last block. - verify_msg_block_equals_last(msg_block, last_block, msg_byte_ptr); - - // We verify the message length was inserted correctly by reversing the byte decomposition. - let mut reconstructed_len: u64 = 0; - for i in INT_SIZE_PTR..INT_BLOCK_SIZE { - reconstructed_len = reconstructed_len * TWO_POW_32; - reconstructed_len = reconstructed_len + msg_block[i] as u64; - } - let len = 8 * message_size as u64; - assert_eq(reconstructed_len, len); -} - -// Perform the final compression, then transform the `STATE` into `HASH`. -fn hash_final_block(msg_block: MSG_BLOCK, mut state: STATE) -> HASH { - let mut out_h: HASH = [0; 32]; // Digest as sequence of bytes - // Hash final padded block - // println("--------- Hashing final block ---------"); - // println(state); - // println(msg_block); - state = ryan_sha256_digest_block_u32(state, msg_block); - - // Return final hash as byte array - for j in 0..8 { - let h_bytes: [u8; 4] = (state[j] as Field).to_be_bytes(); - for k in 0..4 { - out_h[4 * j + k] = h_bytes[k]; - } - } - - out_h -} - -mod equivalence_test { - - #[test] - fn test_implementations_agree(msg: [u8; 100], message_size: u64) { - let message_size = message_size % 100; - // Safety: We don't care about constraining since this is just for a test - let unconstrained_sha = unsafe { super::__sha256_var(msg, message_size as u32) }; - let sha = super::sha256_var(msg, message_size); - assert_eq(sha, unconstrained_sha); - } -} diff --git a/noir-examples/noir-passport-examples/noir_native_sha256/src/tests.nr b/noir-examples/noir-passport-examples/noir_native_sha256/src/tests.nr deleted file mode 100644 index f134d332..00000000 --- a/noir-examples/noir-passport-examples/noir_native_sha256/src/tests.nr +++ /dev/null @@ -1,261 +0,0 @@ -// imported from https://github.com/noir-lang/sha256/blob/main/src/sha256/tests.nr -use super::ryan_sha256_noir::sha256_var; -use sha256::digest; -#[export] -fn test_sha256_1(input: [u8; 1], len: u64) -> [u8; 32] { - sha256_var(input, len) -} - -#[export] -fn test_sha256_200(input: [u8; 200], len: u64) -> [u8; 32] { - sha256_var(input, len) -} - -#[export] -fn test_sha256_511(input: [u8; 511], len: u64) -> [u8; 32] { - sha256_var(input, len) -} - -#[export] -fn test_sha256_512(input: [u8; 512], len: u64) -> [u8; 32] { - sha256_var(input, len) -} - -#[test] -fn empty_sha256() { - let input = []; - let result = [ - 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, - 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, - 0xb8, 0x55, - ]; - assert_eq(sha256_var(input, input.len() as u64), result); -} - -#[test] -fn smoke_test() { - let input = [0xbd]; - let result = [ - 0x68, 0x32, 0x57, 0x20, 0xaa, 0xbd, 0x7c, 0x82, 0xf3, 0x0f, 0x55, 0x4b, 0x31, 0x3d, 0x05, - 0x70, 0xc9, 0x5a, 0xcc, 0xbb, 0x7d, 0xc4, 0xb5, 0xaa, 0xe1, 0x12, 0x04, 0xc0, 0x8f, 0xfe, - 0x73, 0x2b, - ]; - assert_eq(sha256_var(input, input.len() as u64), result); -} - -#[test] -fn msg_just_over_block() { - let input = [ - 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, 101, - 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, 111, 110, - 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, 108, 97, 105, - 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, - ]; - let result = [ - 91, 122, 146, 93, 52, 109, 133, 148, 171, 61, 156, 70, 189, 238, 153, 7, 222, 184, 94, 24, - 65, 114, 192, 244, 207, 199, 87, 232, 192, 224, 171, 207, - ]; - assert_eq(sha256_var(input, input.len() as u64), result); -} - -#[test] -fn msg_multiple_over_block() { - let input = [ - 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, 101, - 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, 111, 110, - 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, 108, 97, 105, - 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 117, 115, 45, 97, 115, 99, 105, 105, 13, - 10, 109, 105, 109, 101, 45, 118, 101, 114, 115, 105, 111, 110, 58, 49, 46, 48, 32, 40, 77, - 97, 99, 32, 79, 83, 32, 88, 32, 77, 97, 105, 108, 32, 49, 54, 46, 48, 32, 92, 40, 51, 55, - 51, 49, 46, 53, 48, 48, 46, 50, 51, 49, 92, 41, 41, 13, 10, 115, 117, 98, 106, 101, 99, 116, - 58, 72, 101, 108, 108, 111, 13, 10, 109, 101, 115, 115, 97, 103, 101, 45, 105, 100, 58, 60, - 56, 70, 56, 49, 57, 68, 51, 50, 45, 66, 54, 65, 67, 45, 52, 56, 57, 68, 45, 57, 55, 55, 70, - 45, 52, 51, 56, 66, 66, 67, 52, 67, 65, 66, 50, 55, 64, 109, 101, 46, 99, 111, 109, 62, 13, - 10, 100, 97, 116, 101, 58, 83, 97, 116, 44, 32, 50, 54, 32, 65, 117, 103, 32, 50, 48, 50, - 51, 32, 49, 50, 58, 50, 53, 58, 50, 50, 32, 43, 48, 52, 48, 48, 13, 10, 116, 111, 58, 122, - 107, 101, 119, 116, 101, 115, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 13, 10, - 100, 107, 105, 109, 45, 115, 105, 103, 110, 97, 116, 117, 114, 101, 58, 118, 61, 49, 59, 32, - 97, 61, 114, 115, 97, 45, 115, 104, 97, 50, 53, 54, 59, 32, 99, 61, 114, 101, 108, 97, 120, - 101, 100, 47, 114, 101, 108, 97, 120, 101, 100, 59, 32, 100, 61, 105, 99, 108, 111, 117, - 100, 46, 99, 111, 109, 59, 32, 115, 61, 49, 97, 49, 104, 97, 105, 59, 32, 116, 61, 49, 54, - 57, 51, 48, 51, 56, 51, 51, 55, 59, 32, 98, 104, 61, 55, 120, 81, 77, 68, 117, 111, 86, 86, - 85, 52, 109, 48, 87, 48, 87, 82, 86, 83, 114, 86, 88, 77, 101, 71, 83, 73, 65, 83, 115, 110, - 117, 99, 75, 57, 100, 74, 115, 114, 99, 43, 118, 85, 61, 59, 32, 104, 61, 102, 114, 111, - 109, 58, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 77, 105, 109, 101, 45, - 86, 101, 114, 115, 105, 111, 110, 58, 83, 117, 98, 106, 101, 99, - ]; - let result = [ - 116, 90, 151, 31, 78, 22, 138, 180, 211, 189, 69, 76, 227, 200, 155, 29, 59, 123, 154, 60, - 47, 153, 203, 129, 157, 251, 48, 2, 79, 11, 65, 47, - ]; - assert_eq(sha256_var(input, input.len() as u64), result); -} - -#[test] -fn msg_just_under_block() { - let input = [ - 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, 101, - 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, 111, 110, - 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, 108, 97, 105, - 110, 59, - ]; - let result = [ - 143, 140, 76, 173, 222, 123, 102, 68, 70, 149, 207, 43, 39, 61, 34, 79, 216, 252, 213, 165, - 74, 16, 110, 74, 29, 64, 138, 167, 30, 1, 9, 119, - ]; - assert_eq(sha256_var(input, input.len() as u64), result); -} - -#[test] -fn msg_big_not_block_multiple() { - let input = [ - 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, 101, - 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, 111, 110, - 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, 108, 97, 105, - 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 117, 115, 45, 97, 115, 99, 105, 105, 13, - 10, 109, 105, 109, 101, 45, 118, 101, 114, 115, 105, 111, 110, 58, 49, 46, 48, 32, 40, 77, - 97, 99, 32, 79, 83, 32, 88, 32, 77, 97, 105, 108, 32, 49, 54, 46, 48, 32, 92, 40, 51, 55, - 51, 49, 46, 53, 48, 48, 46, 50, 51, 49, 92, 41, 41, 13, 10, 115, 117, 98, 106, 101, 99, 116, - 58, 72, 101, 108, 108, 111, 13, 10, 109, 101, 115, 115, 97, 103, 101, 45, 105, 100, 58, 60, - 56, 70, 56, 49, 57, 68, 51, 50, 45, 66, 54, 65, 67, 45, 52, 56, 57, 68, 45, 57, 55, 55, 70, - 45, 52, 51, 56, 66, 66, 67, 52, 67, 65, 66, 50, 55, 64, 109, 101, 46, 99, 111, 109, 62, 13, - 10, 100, 97, 116, 101, 58, 83, 97, 116, 44, 32, 50, 54, 32, 65, 117, 103, 32, 50, 48, 50, - 51, 32, 49, 50, 58, 50, 53, 58, 50, 50, 32, 43, 48, 52, 48, 48, 13, 10, 116, 111, 58, 122, - 107, 101, 119, 116, 101, 115, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 13, 10, - 100, 107, 105, 109, 45, 115, 105, 103, 110, 97, 116, 117, 114, 101, 58, 118, 61, 49, 59, 32, - 97, 61, 114, 115, 97, 45, 115, 104, 97, 50, 53, 54, 59, 32, 99, 61, 114, 101, 108, 97, 120, - 101, 100, 47, 114, 101, 108, 97, 120, 101, 100, 59, 32, 100, 61, 105, 99, 108, 111, 117, - 100, 46, 99, 111, 109, 59, 32, 115, 61, 49, 97, 49, 104, 97, 105, 59, 32, 116, 61, 49, 54, - 57, 51, 48, 51, 56, 51, 51, 55, 59, 32, 98, 104, 61, 55, 120, 81, 77, 68, 117, 111, 86, 86, - 85, 52, 109, 48, 87, 48, 87, 82, 86, 83, 114, 86, 88, 77, 101, 71, 83, 73, 65, 83, 115, 110, - 117, 99, 75, 57, 100, 74, 115, 114, 99, 43, 118, 85, 61, 59, 32, 104, 61, 102, 114, 111, - 109, 58, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 77, 105, 109, 101, 45, - 86, 101, 114, 115, 105, 111, 110, 58, 83, 117, 98, 106, 101, 99, 116, 58, 77, 101, 115, 115, - 97, 103, 101, 45, 73, 100, 58, 68, 97, 116, 101, 58, 116, 111, 59, 32, 98, 61, - ]; - let result = [ - 112, 144, 73, 182, 208, 98, 9, 238, 54, 229, 61, 145, 222, 17, 72, 62, 148, 222, 186, 55, - 192, 82, 220, 35, 66, 47, 193, 200, 22, 38, 26, 186, - ]; - assert_eq(sha256_var(input, input.len() as u64), result); -} - -#[test] -fn msg_big_with_padding() { - let input = [ - 48, 130, 1, 37, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 48, 130, 1, 17, 48, - 37, 2, 1, 1, 4, 32, 176, 223, 31, 133, 108, 84, 158, 102, 70, 11, 165, 175, 196, 12, 201, - 130, 25, 131, 46, 125, 156, 194, 28, 23, 55, 133, 157, 164, 135, 136, 220, 78, 48, 37, 2, 1, - 2, 4, 32, 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, 48, 37, 2, 1, 3, 4, 32, 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, 48, 37, 2, 1, 11, 4, 32, 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, 48, 37, 2, 1, 12, 4, 32, 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, 48, 37, 2, 1, 13, 4, 32, 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, 48, 37, 2, 1, 14, 4, 32, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 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 result = [ - 32, 85, 108, 174, 127, 112, 178, 182, 8, 43, 134, 123, 192, 211, 131, 66, 184, 240, 212, - 181, 240, 180, 106, 195, 24, 117, 54, 129, 19, 10, 250, 53, - ]; - let message_size = 297; - assert_eq(sha256_var(input, message_size), result); -} - -#[test] -fn msg_big_no_padding() { - let input = [ - 48, 130, 1, 37, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 48, 130, 1, 17, 48, - 37, 2, 1, 1, 4, 32, 176, 223, 31, 133, 108, 84, 158, 102, 70, 11, 165, 175, 196, 12, 201, - 130, 25, 131, 46, 125, 156, 194, 28, 23, 55, 133, 157, 164, 135, 136, 220, 78, 48, 37, 2, 1, - 2, 4, 32, 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, 48, 37, 2, 1, 3, 4, 32, 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, 48, 37, 2, 1, 11, 4, 32, 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, 48, 37, 2, 1, 12, 4, 32, 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, 48, 37, 2, 1, 13, 4, 32, 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, 48, 37, 2, 1, 14, 4, 32, 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, - ]; - let result = [ - 32, 85, 108, 174, 127, 112, 178, 182, 8, 43, 134, 123, 192, 211, 131, 66, 184, 240, 212, - 181, 240, 180, 106, 195, 24, 117, 54, 129, 19, 10, 250, 53, - ]; - assert_eq(sha256_var(input, input.len() as u64), result); -} - -#[test] -fn same_msg_len_variable_padding() { - let input = [ - 29, 81, 165, 84, 243, 114, 101, 37, 242, 146, 127, 99, 69, 145, 39, 72, 213, 39, 253, 179, - 218, 37, 217, 201, 172, 93, 198, 50, 249, 70, 15, 30, 162, 112, 187, 40, 140, 9, 236, 53, - 32, 44, 38, 163, 113, 254, 192, 197, 44, 89, 71, 130, 169, 242, 17, 211, 214, 72, 19, 178, - 186, 168, 147, 127, 99, 101, 252, 227, 8, 147, 150, 85, 97, 158, 17, 107, 218, 244, 82, 113, - 247, 91, 208, 214, 60, 244, 87, 137, 173, 201, 130, 18, 66, 56, 198, 149, 207, 189, 175, - 120, 123, 224, 177, 167, 251, 159, 143, 110, 68, 183, 189, 70, 126, 32, 35, 164, 44, 30, 44, - 12, 65, 18, 62, 239, 242, 2, 248, 104, 2, 178, 64, 28, 126, 36, 137, 24, 14, 116, 91, 98, - 90, 159, 218, 102, 45, 11, 110, 223, 245, 184, 52, 99, 59, 245, 136, 175, 3, 72, 164, 146, - 145, 116, 22, 66, 24, 49, 193, 121, 3, 60, 37, 41, 97, 3, 190, 66, 195, 225, 63, 46, 3, 118, - 4, 208, 15, 1, 40, 254, 235, 151, 123, 70, 180, 170, 44, 172, 90, 4, 254, 53, 239, 116, 246, - 67, 56, 129, 61, 22, 169, 213, 65, 27, 216, 116, 162, 239, 214, 207, 126, 177, 20, 100, 25, - 48, 143, 84, 215, 70, 197, 53, 65, 70, 86, 172, 61, 62, 9, 212, 167, 169, 133, 41, 126, 213, - 196, 33, 192, 238, 0, 63, 246, 215, 58, 128, 110, 101, 92, 3, 170, 214, 130, 149, 52, 81, - 125, 118, 233, 3, 118, 193, 104, 207, 120, 115, 77, 253, 191, 122, 0, 107, 164, 207, 113, - 81, 169, 36, 201, 228, 74, 134, 131, 218, 178, 35, 30, 216, 101, 2, 103, 174, 87, 95, 50, - 50, 215, 157, 5, 210, 188, 54, 211, 78, 45, 199, 96, 121, 241, 241, 176, 226, 194, 134, 130, - 89, 217, 210, 186, 32, 140, 39, 91, 103, 212, 26, 87, 32, 72, 144, 228, 230, 117, 99, 188, - 50, 15, 69, 79, 179, 50, 12, 106, 86, 218, 101, 73, 142, 243, 29, 250, 122, 228, 233, 29, - 255, 22, 121, 114, 125, 103, 41, 250, 241, 179, 126, 158, 198, 116, 209, 65, 94, 98, 228, - 175, 169, 96, 3, 9, 233, 133, 214, 55, 161, 164, 103, 80, 85, 24, 186, 64, 167, 92, 131, 53, - 101, 202, 47, 25, 104, 118, 155, 14, 12, 12, 25, 116, 45, 221, 249, 28, 246, 212, 200, 157, - 167, 169, 56, 197, 181, 4, 245, 146, 1, 140, 234, 191, 212, 228, 125, 87, 81, 86, 119, 30, - 63, 129, 143, 32, 96, - ]; - - // Prepare inputs of different lengths - let mut input_511 = [0; 511]; - let mut input_512 = [0; 512]; // Next block - let mut input_575 = [0; 575]; - let mut input_576 = [0; 576]; // Next block - for i in 0..input.len() { - input_511[i] = input[i]; - input_512[i] = input[i]; - input_575[i] = input[i]; - input_576[i] = input[i]; - } - - // Compute hashes of all inputs (with same message length) - let fixed_length_hash = digest(input); - let var_full_length_hash = sha256_var(input, input.len() as u64); - let var_length_hash_511 = sha256_var(input_511, input.len() as u64); - let var_length_hash_512 = sha256_var(input_512, input.len() as u64); - let var_length_hash_575 = sha256_var(input_575, input.len() as u64); - let var_length_hash_576 = sha256_var(input_576, input.len() as u64); - - // All of the above should have produced the same hash - assert_eq(var_full_length_hash, fixed_length_hash); - assert_eq(var_length_hash_511, fixed_length_hash); - assert_eq(var_length_hash_512, fixed_length_hash); - assert_eq(var_length_hash_575, fixed_length_hash); - assert_eq(var_length_hash_576, fixed_length_hash); -} diff --git a/noir-examples/noir-passport-examples/noir_rsa/Nargo.toml b/noir-examples/noir-passport-examples/noir_rsa/Nargo.toml deleted file mode 100644 index 5e4d4e34..00000000 --- a/noir-examples/noir-passport-examples/noir_rsa/Nargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "noir_rsa" -type = "lib" -authors = [""] -compiler_version = ">=1.0.0" -version = "0.9.0" - -[dependencies] -bignum = {tag = "v0.8.0", git = "https://github.com/noir-lang/noir-bignum"} -noir_native_sha256 = { path = "../noir_native_sha256" } -sha512 = { tag = "v0.1.0", git = "https://github.com/zkpassport/sha512" } -sha1 = { tag = "v0.11", git = "https://github.com/zac-williamson/sha1" } diff --git a/noir-examples/noir-passport-examples/noir_rsa/README.md b/noir-examples/noir-passport-examples/noir_rsa/README.md deleted file mode 100644 index 2eec4391..00000000 --- a/noir-examples/noir-passport-examples/noir_rsa/README.md +++ /dev/null @@ -1 +0,0 @@ -Borrowed from https://github.com/zkpassport/noir_rsa and compiles with Nargo v1.0.0-beta.11 diff --git a/noir-examples/noir-passport-examples/noir_rsa/src/lib.nr b/noir-examples/noir-passport-examples/noir_rsa/src/lib.nr deleted file mode 100644 index 24e60f61..00000000 --- a/noir-examples/noir-passport-examples/noir_rsa/src/lib.nr +++ /dev/null @@ -1,2 +0,0 @@ -pub mod rsa; -pub mod types; diff --git a/noir-examples/noir-passport-examples/noir_rsa/src/rsa.nr b/noir-examples/noir-passport-examples/noir_rsa/src/rsa.nr deleted file mode 100644 index b45bdc4e..00000000 --- a/noir-examples/noir-passport-examples/noir_rsa/src/rsa.nr +++ /dev/null @@ -1,2156 +0,0 @@ -use dep::bignum::RuntimeBigNum; -use noir_native_sha256::ryan_sha256_noir; -use sha1::sha1; -use sha512::{sha384, sha512}; - -global SHA1_HASH_LEN: u32 = 20; -global SHA256_HASH_LEN: u32 = 32; -global SHA384_HASH_LEN: u32 = 48; -global SHA512_HASH_LEN: u32 = 64; - -fn reverse_array(array: [u8; N]) -> [u8; N] { - let mut reversed = [0 as u8; N]; - for i in 0..N { - reversed[i] = array[N - i - 1]; - } - reversed -} - -fn get_array_slice(array: [u8; N], start: u32, end: u32) -> [u8; M] { - assert(end - start <= M); - let mut slice = [0 as u8; M]; - for i in 0..M { - if i < end - start { - slice[i] = array[start + i]; - } - } - slice -} - -fn pow(base: u32, exp: u32) -> u32 { - let mut result = 1; - for _ in 0..exp { - result *= base; - } - result -} - -/** - * @brief Generate a mask from a seed using the MGF1 algorithm with SHA1 as the hash function - **/ -fn mgf1_sha1(seed: [u8; SEED_LEN]) -> [u8; MASK_LEN] { - // MASK_LEN must be less than 2^32 * SHA1_HASH_LEN - dep::std::field::bn254::assert_lt(MASK_LEN as Field, 0xffffffff * SHA1_HASH_LEN as Field + 1); - - // SHA1_HASH_LEN bytes are added at each iteration - let iterations = (MASK_LEN / SHA1_HASH_LEN) + 1; - - let mut mask: [u8; MASK_LEN] = [0; MASK_LEN]; - let mut hashed: [u8; SHA1_HASH_LEN] = [0; SHA1_HASH_LEN]; - - for i in 0..iterations { - let mut block: [u8; SEED_LEN + 4] = [0; SEED_LEN + 4]; - - // Copy seed to block - for j in 0..SEED_LEN { - block[j] = seed[j]; - } - - // Add counter to block - let counter_bytes: [u8; 4] = (i as Field).to_be_bytes(); - for j in 0..4 { - block[SEED_LEN + j] = counter_bytes[j]; - } - - // Hash the block using SHA-1 - let block_vec = BoundedVec::from_parts(block, SEED_LEN + 4); - hashed = sha1::sha1_var(block_vec); - - // Copy hashed output to mask - for j in 0..SHA1_HASH_LEN { - if i * SHA1_HASH_LEN + j < MASK_LEN { - mask[i * SHA1_HASH_LEN + j] = hashed[j]; - } - } - } - - mask -} - -/** - * @brief Generate a mask from a seed using the MGF1 algorithm with SHA256 as the hash function - **/ -fn mgf1_sha256(seed: [u8; SEED_LEN]) -> [u8; MASK_LEN] { - // MASK_LEN must be less than 2^32 * SHA256_HASH_LEN - dep::std::field::bn254::assert_lt(MASK_LEN as Field, 0xffffffff * SHA256_HASH_LEN as Field + 1); - - // SHA256_HASH_LEN bytes are added at each iteration and there is at least 1 iteration - // so if SHA256_HASH_LEN is not enough to fill MASK_LEN bytes in one iteration, - // another one is required and so on. - let iterations = (MASK_LEN / SHA256_HASH_LEN) + 1; - - let mut mask: [u8; MASK_LEN] = [0; MASK_LEN]; - let mut hashed: [u8; SHA256_HASH_LEN] = [0; SHA256_HASH_LEN]; - - for i in 0..iterations { - let mut block: [u8; SEED_LEN + 4] = [0; SEED_LEN + 4]; - - // Copy seed to block - for j in 0..SEED_LEN { - block[j] = seed[j]; - } - - // Add counter to block - let counter_bytes: [u8; 4] = (i as Field).to_be_bytes(); - for j in 0..4 { - block[SEED_LEN + j] = counter_bytes[j]; - } - - // Hash the block - // First SEED_LEN bytes are the seed, next 4 bytes are the counter - hashed = noir_native_sha256::ryan_sha256_noir::sha256_var(block, SEED_LEN as u64 + 4); - - // Copy hashed output to mask - for j in 0..SHA256_HASH_LEN { - if i * SHA256_HASH_LEN + j < MASK_LEN { - mask[i * SHA256_HASH_LEN + j] = hashed[j]; - } - } - } - - mask -} - -/** - * @brief Generate a mask from a seed using the MGF1 algorithm with SHA384 as the hash function - **/ -fn mgf1_sha384(seed: [u8; SEED_LEN]) -> [u8; MASK_LEN] { - // MASK_LEN must be less than 2^32 * SHA384_HASH_LEN - dep::std::field::bn254::assert_lt(MASK_LEN as Field, 0xffffffff * SHA384_HASH_LEN as Field + 1); - - // SHA384_HASH_LEN bytes are added at each iteration - let iterations = (MASK_LEN / SHA384_HASH_LEN) + 1; - - let mut mask: [u8; MASK_LEN] = [0; MASK_LEN]; - let mut hashed: [u8; SHA384_HASH_LEN] = [0; SHA384_HASH_LEN]; - - for i in 0..iterations { - let mut block: [u8; SEED_LEN + 4] = [0; SEED_LEN + 4]; - - // Copy seed to block - for j in 0..SEED_LEN { - block[j] = seed[j]; - } - - // Add counter to block - let counter_bytes: [u8; 4] = (i as Field).to_be_bytes(); - for j in 0..4 { - block[SEED_LEN + j] = counter_bytes[j]; - } - - let block_vec = BoundedVec::from_parts(block, SEED_LEN + 4); - hashed = sha384::sha384_var(block_vec); - - // Copy hashed output to mask - for j in 0..SHA384_HASH_LEN { - if i * SHA384_HASH_LEN + j < MASK_LEN { - mask[i * SHA384_HASH_LEN + j] = hashed[j]; - } - } - } - - mask -} - -/** - * @brief Generate a mask from a seed using the MGF1 algorithm with SHA512 as the hash function - **/ -fn mgf1_sha512(seed: [u8; SEED_LEN]) -> [u8; MASK_LEN] { - // MASK_LEN must be less than 2^32 * SHA512_HASH_LEN - dep::std::field::bn254::assert_lt(MASK_LEN as Field, 0xffffffff * SHA512_HASH_LEN as Field + 1); - - // SHA512_HASH_LEN bytes are added at each iteration - let iterations = (MASK_LEN / SHA512_HASH_LEN) + 1; - - let mut mask: [u8; MASK_LEN] = [0; MASK_LEN]; - let mut hashed: [u8; SHA512_HASH_LEN] = [0; SHA512_HASH_LEN]; - - for i in 0..iterations { - let mut block: [u8; SEED_LEN + 4] = [0; SEED_LEN + 4]; - - // Copy seed to block - for j in 0..SEED_LEN { - block[j] = seed[j]; - } - - // Add counter to block - let counter_bytes: [u8; 4] = (i as Field).to_be_bytes(); - for j in 0..4 { - block[SEED_LEN + j] = counter_bytes[j]; - } - - let block_vec = BoundedVec::from_parts(block, SEED_LEN + 4); - hashed = sha512::sha512_var(block_vec); - - // Copy hashed output to mask - for j in 0..SHA512_HASH_LEN { - if i * SHA512_HASH_LEN + j < MASK_LEN { - mask[i * SHA512_HASH_LEN + j] = hashed[j]; - } - } - } - - mask -} - -/** - * @brief Compare a recovered byte hash from an RSA signature using SHA-1 to the original message hash - **/ -fn compare_signature_sha1(padded_sha1_hash: [u8; N], msg_hash: [u8; 20]) -> bool { - // Get length of sig (e.g. 1048 = 128 bytes, 2048 = 256 bytes) - for i in 0..20 { - // Padded hash is reversed - assert(padded_sha1_hash[19 - i] == msg_hash[i]); - } - - // SHA-1 ASN.1 DER identifier - let hash_prefix: [u8; 15] = [20, 4, 0, 5, 26, 2, 3, 14, 43, 5, 6, 9, 48, 33, 48]; - - for i in 20..35 { - assert(hash_prefix[i - 20] == padded_sha1_hash[i]); - } - - assert(padded_sha1_hash[35] == 0); - - // Sub 20 bytes for hash, 15 bytes for prefix, 1 byte for 0, 1 byte for 1, 1 byte for 0 - let ps_len = N - 38; - for i in 36..N { - if i < 36 + ps_len { - // PS padding - assert(padded_sha1_hash[i] == 255); - } else if i == 36 + ps_len { - // Pad 0x01 - assert(padded_sha1_hash[i] == 1); - } else if i == 37 + ps_len { - // 0x00 - assert(padded_sha1_hash[i] == 0); - } else { - // Padded with 0 until MAX_BYTES - assert(padded_sha1_hash[i] == 0); - } - } - - true -} - -/** - * @brief Compare a recovered byte hash from an RSA signature to the original message hash - * @details Taken from https://github.com/richardliang/noir-rsa - **/ -fn compare_signature_sha256(padded_sha256_hash: [u8; N], msg_hash: [u8; 32]) -> bool { - // Get length of sig (e.g. 1048 = 128 bytes, 2048 = 256 bytes) - // NOTE: Assume MAX_BYTES < 2^32 bit number. MAX_BYTES of 259 > 2^8 bits so need to cast it to u32 - for i in 0..32 { - // Padded hash is reversed - assert(padded_sha256_hash[31 - i] == msg_hash[i]); - } - - let hash_prefix: [u8; 19] = - [32, 4, 0, 5, 1, 2, 4, 3, 101, 1, 72, 134, 96, 9, 6, 13, 48, 49, 48]; - - for i in 32..51 { - assert(hash_prefix[i - 32] == padded_sha256_hash[i]); - } - - assert(padded_sha256_hash[51] == 0); - - // Sub 32 bytes for hash, 19 bytes for prefix, 1 byte for 0, 1 byte for 1, 1 byte for 0 - let ps_len = N - 54; - for i in 52..N { - if i < 52 + ps_len { - // PS padding which depends on RSA modulus / sig length. 1024 bits = 128 bytes = 128 - 54 = 74 bytes of 0xFF padding - assert(padded_sha256_hash[i] == 255); - } else if i == 52 + ps_len { - // Pad 0x01 - assert(padded_sha256_hash[i] == 1); - } else if i == 53 + ps_len { - // 0x00 - assert(padded_sha256_hash[i] == 0); - } else { - // Padded with 0 until MAX_BYTES - assert(padded_sha256_hash[i] == 0); - } - } - - true -} - -/** - * @brief Compare a recovered byte hash from an RSA signature using SHA-384 to the original message hash - **/ -fn compare_signature_sha384(padded_sha384_hash: [u8; N], msg_hash: [u8; 48]) -> bool { - // Get length of sig (e.g. 1048 = 128 bytes, 2048 = 256 bytes) - for i in 0..48 { - // Padded hash is reversed - assert(padded_sha384_hash[47 - i] == msg_hash[i]); - } - - // SHA-384 ASN.1 DER identifier - let hash_prefix: [u8; 19] = - [48, 4, 0, 5, 2, 2, 4, 3, 101, 1, 72, 134, 96, 9, 6, 13, 48, 65, 48]; - - for i in 48..67 { - assert(hash_prefix[i - 48] == padded_sha384_hash[i]); - } - - assert(padded_sha384_hash[67] == 0); - - // Sub 48 bytes for hash, 19 bytes for prefix, 1 byte for 0, 1 byte for 1, 1 byte for 0 - let ps_len = N - 70; - for i in 68..N { - if i as u32 < 68 + ps_len as u32 { - // PS padding - assert(padded_sha384_hash[i] == 255); - } else if i as u32 == 68 + ps_len as u32 { - // Pad 0x01 - assert(padded_sha384_hash[i] == 1); - } else if i as u32 == 69 + ps_len as u32 { - // 0x00 - assert(padded_sha384_hash[i] == 0); - } else { - // Padded with 0 until MAX_BYTES - assert(padded_sha384_hash[i] == 0); - } - } - - true -} - -/** - * @brief Compare a recovered byte hash from an RSA signature using SHA-512 to the original message hash - **/ -fn compare_signature_sha512(padded_sha512_hash: [u8; N], msg_hash: [u8; 64]) -> bool { - // Get length of sig (e.g. 1048 = 128 bytes, 2048 = 256 bytes) - for i in 0..64 { - // Padded hash is reversed - assert(padded_sha512_hash[63 - i] == msg_hash[i]); - } - - // SHA-512 ASN.1 DER identifier - let hash_prefix: [u8; 19] = - [64, 4, 0, 5, 3, 2, 4, 3, 101, 1, 72, 134, 96, 9, 6, 13, 48, 81, 48]; - - for i in 64..83 { - assert(hash_prefix[i - 64] == padded_sha512_hash[i]); - } - - assert(padded_sha512_hash[83] == 0); - - // Sub 64 bytes for hash, 19 bytes for prefix, 1 byte for 0, 1 byte for 1, 1 byte for 0 - let ps_len = N - 86; - for i in 84..N { - if i as u32 < 84 + ps_len as u32 { - // PS padding - assert(padded_sha512_hash[i] == 255); - } else if i as u32 == 84 + ps_len as u32 { - // Pad 0x01 - assert(padded_sha512_hash[i] == 1); - } else if i as u32 == 85 + ps_len as u32 { - // 0x00 - assert(padded_sha512_hash[i] == 0); - } else { - // Padded with 0 until MAX_BYTES - assert(padded_sha512_hash[i] == 0); - } - } - - true -} - -/** - * @brief Exponentiate a signature by a given exponent using binary exponentiation - * @details This function handles the exponentiation of a signature by any given exponent. - * Uses the square-and-multiply algorithm for efficient modular exponentiation. - * @param sig The signature to exponentiate - * @param exponent The exponent to use (any positive integer) - * @return The exponentiated signature - */ -fn exponentiate_signature( - sig: RuntimeBigNum, - exponent: u32, -) -> RuntimeBigNum { - assert((exponent > 0) & (exponent < 131072), "Exponent must be positive and less than 2^17"); - - // Binary exponentiation (square-and-multiply algorithm) - let mut result = RuntimeBigNum::one(sig.params); - let mut base = sig; - let mut exp = exponent; - - // We assume the exponent won't be more than to 2^17 so we can - // have less iterations - for _ in 0..17 { - if exp > 0 { - // If the exponent is odd, multiply result by current base - if exp % 2 == 1 { - result = result * base; - } - - // Square the base for the next bit - base = base * base; - - // Divide exponent by 2 (move to the next bit) - exp = exp / 2; - } - } - - result -} - -/** - * @brief Verify an RSA signature using the PKCS#1 v1.5 padding scheme with SHA-1 - * - * @param msg_hash The SHA-1 hash of the message being verified - * @param sig The RSA signature - * @param exponent The public exponent (any positive integer) - * @return True if the signature is valid, false otherwise - */ -pub fn verify_sha1_pkcs1v15( - msg_hash: [u8; 20], - sig: RuntimeBigNum, - exponent: u32, -) -> bool { - let exponentiated = exponentiate_signature(sig, exponent); - let mut padded_sha1_hash_bytes: [u8; (ModBits + 7) / 8] = exponentiated.to_le_bytes(); - compare_signature_sha1(padded_sha1_hash_bytes, msg_hash) -} - -/** - * @brief Verify an RSA signature generated via the pkcs1v15 signature scheme with SHA-256 - * @note The `exponent` can be any positive integer (commonly 3 or 65537 are used for RSA) - * Rough cost: 2,048 bit RSA: 26,888 gates per verification - * 1,024 bit RSA: 11,983 gates per verification - * A circuit that verifies 1 signature (and does nothing else) will cost ~32k due to initialization costs of lookup tables - **/ -pub fn verify_sha256_pkcs1v15( - msg_hash: [u8; 32], - sig: RuntimeBigNum, - exponent: u32, -) -> bool { - let exponentiated = exponentiate_signature(sig, exponent); - let mut padded_sha256_hash_bytes: [u8; (ModBits + 7) / 8] = exponentiated.to_le_bytes(); - compare_signature_sha256(padded_sha256_hash_bytes, msg_hash) -} - -/** - * @brief Verify an RSA signature using the PKCS#1 v1.5 padding scheme with SHA-384 - * - * @param msg_hash The SHA-384 hash of the message being verified - * @param sig The RSA signature - * @param exponent The public exponent (any positive integer) - * @return True if the signature is valid, false otherwise - */ -pub fn verify_sha384_pkcs1v15( - msg_hash: [u8; 48], - sig: RuntimeBigNum, - exponent: u32, -) -> bool { - let exponentiated = exponentiate_signature(sig, exponent); - let mut padded_sha384_hash_bytes: [u8; (ModBits + 7) / 8] = exponentiated.to_le_bytes(); - compare_signature_sha384(padded_sha384_hash_bytes, msg_hash) -} - -/** - * @brief Verify an RSA signature using the PKCS#1 v1.5 padding scheme with SHA-512 - * - * @param msg_hash The SHA-512 hash of the message being verified - * @param sig The RSA signature - * @param exponent The public exponent (any positive integer) - * @return True if the signature is valid, false otherwise - */ -pub fn verify_sha512_pkcs1v15( - msg_hash: [u8; 64], - sig: RuntimeBigNum, - exponent: u32, -) -> bool { - let exponentiated = exponentiate_signature(sig, exponent); - let mut padded_sha512_hash_bytes: [u8; (ModBits + 7) / 8] = exponentiated.to_le_bytes(); - compare_signature_sha512(padded_sha512_hash_bytes, msg_hash) -} - -/** - * @brief Verify an RSA signature generated via the PSS signature scheme using SHA-1. - * - * @note The exponent `e` can be any positive integer (commonly 3 or 65537 are used for RSA) - **/ -pub fn verify_sha1_pss( - msg_hash: [u8; 20], - sig: RuntimeBigNum, - exponent: u32, -) -> bool { - let exponentiated = exponentiate_signature(sig, exponent); - - // Convert the exponentiated signature to a byte array and reverse it to - // get it in big endian order, which is much easier to work with for - // the rest of the verification process - let em: [u8; (ModBits + 7) / 8] = reverse_array(exponentiated.to_le_bytes()); - - // The modulus size in bits minus 1 - let em_bits = ModBits - 1; - // The actual length of the encoded message without any of the leftmost 0s - let em_len = (em_bits + 7) / 8; - // The length of the modulus in bytes - let key_len = (ModBits + 7) / 8; - let h_len = 20; // SHA-1 produces 20-byte hashes - let s_len = 20; // Salt length is typically equal to hash length - - // Check if emLen < hLen + sLen + 2 - assert(em_len >= h_len + s_len + 2); - - // Check if eM ends with 0xBC - assert_eq(em[em.len() - 1], 0xBC); - - let db_mask_len = em_len - h_len - 1; - // In some rare cases, em_len is not equal to key_len (e.g. 1025 bit RSA) - // In this case, we'll have a leading zero byte in em that we need to ignore - // c.f. https://github.com/RustCrypto/RSA/blob/aeedb5adf5297892fcb9e11f7c0f6c0157005c58/src/algorithms/pss.rs#L242 - let offset = key_len - em_len; - // As the hash is 20 bytes and we also remove the 0xBC at the end, we have up to NumBytes - 21 bytes left for DB - // For example, for 2048 bit RSA (i.e. 256 bytes), we have 256 - 21 = 235 bytes left for DB - // and for 1024 bit RSA (i.e. 128 bytes), we have 128 - 21 = 107 bytes left for DB - let masked_db: [u8; (ModBits + 7) / 8 - 21] = get_array_slice(em, offset, db_mask_len + offset); - let h = get_array_slice(em, db_mask_len + offset, em.len() - 1); - - // Make sure the 8 * em_len - em_bits leftmost bits are 0 - // c.f. https://github.com/RustCrypto/RSA/blob/aeedb5adf5297892fcb9e11f7c0f6c0157005c58/src/algorithms/pss.rs#L205 - let bits_to_mask = 8 - (8 * em_len - em_bits); - let mask_value = pow(2, bits_to_mask as u32); - assert_eq(masked_db[0] as u32 / mask_value, 0); - - // Generate dbMask using MGF1 with SHA-1 - let db_mask: [u8; (ModBits + 7) / 8 - 21] = mgf1_sha1(h); - - // Compute DB = maskedDB xor dbMask - let mut db = [0 as u8; (ModBits + 7) / 8 - 21]; - for i in 0..db_mask_len { - db[i] = masked_db[i] ^ db_mask[i]; - } - - // Set leftmost byte of DB to 0 - db[0] = 0; - - // Check if the leftmost octets of DB are zero - for i in 0..(em_len - h_len - s_len - 2) { - assert_eq(db[i], 0); - } - - // Check if the octet at position emLen - hLen - sLen - 2 is 1 - assert_eq(db[em_len - h_len - s_len - 2], 1); - - // Extract salt - let salt: [u8; 20] = get_array_slice(db, db_mask_len - s_len, db_mask_len); - - // Construct M' - // M' = (0x)00 00 00 00 00 00 00 00 || msg_hash || salt - let mut m_prime = [0 as u8; 48]; // 8 + h_len + s_len = 8 + 20 + 20 = 48 - for i in 8..28 { - m_prime[i] = msg_hash[i - 8]; - } - for i in 28..48 { - m_prime[i] = salt[i - 28]; - } - - // Compute H' using SHA-1 - let m_prime_vec = BoundedVec::from_parts(m_prime, 48); - let h_prime = sha1::sha1_var(m_prime_vec); - - // Compare H and H' - h == h_prime -} - -/** - * @brief Verify an RSA signature generated via the PSS signature scheme. - * - * @note The exponent `e` can be any positive integer (commonly 3 or 65537 are used for RSA) - **/ -pub fn verify_sha256_pss( - msg_hash: [u8; 32], - sig: RuntimeBigNum, - exponent: u32, -) -> bool { - let exponentiated = exponentiate_signature(sig, exponent); - - // Convert the exponentiated signature to a byte array and reverse it to - // get it in big endian order, which is much easier to work with for - // the rest of the verification process - let em: [u8; (ModBits + 7) / 8] = reverse_array(exponentiated.to_le_bytes()); - - // The modulus size in bits minus 1 - let em_bits = ModBits - 1; - // The actual length of the encoded message without any of the leftmost 0s - let em_len = (em_bits + 7) / 8; - // The length of the modulus in bytes - let key_len = (ModBits + 7) / 8; - let h_len = 32; - let s_len = 32; - - // Check if emLen < hLen + sLen + 2 - assert(em_len >= h_len + s_len + 2); - - // Check if eM ends with 0xBC - assert_eq(em[em.len() - 1], 0xBC); - - let db_mask_len = em_len - h_len - 1; - // In some rare cases, em_len is not equal to key_len (e.g. 1025 bit RSA) - // In this case, we'll have a leading zero byte in em that we need to ignore - // c.f. https://github.com/RustCrypto/RSA/blob/aeedb5adf5297892fcb9e11f7c0f6c0157005c58/src/algorithms/pss.rs#L242 - let offset = key_len - em_len; - // As the hash is 32 bytes and we also remove the 0xBC at the end, we have up to NumBytes - 33 bytes left for DB - // For example, for 2048 bit RSA (i.e. 256 bytes), we have 256 - 33 = 223 bytes left for DB - // and for 1024 bit RSA (i.e. 128 bytes), we have 128 - 33 = 95 bytes left for DB - let masked_db: [u8; (ModBits + 7) / 8 - 33] = get_array_slice::<(ModBits + 7) / 8, (ModBits + 7) / 8 - 33>( - em, - offset, - db_mask_len + offset, - ); - let h: [u8; 32] = - get_array_slice::<(ModBits + 7) / 8, 32>(em, db_mask_len + offset, em.len() - 1); - - // Make sure the 8 * em_len - em_bits leftmost bits are 0 - // c.f. https://github.com/RustCrypto/RSA/blob/aeedb5adf5297892fcb9e11f7c0f6c0157005c58/src/algorithms/pss.rs#L205 - let bits_to_mask = 8 - (8 * em_len - em_bits); - let mask_value = pow(2, bits_to_mask as u32); - assert_eq(masked_db[0] as u32 / mask_value, 0); - - // Generate dbMask using MGF1 - let db_mask: [u8; (ModBits + 7) / 8 - 33] = mgf1_sha256::<32, (ModBits + 7) / 8 - 33>(h); - - // Compute DB = maskedDB xor dbMask - let mut db = [0 as u8; (ModBits + 7) / 8 - 33]; - for i in 0..db_mask_len { - db[i] = masked_db[i] ^ db_mask[i]; - } - - // Set leftmost byte of DB to 0 - db[0] = 0; - - // Check if the leftmost octets of DB are zero - for i in 0..(em_len - h_len - s_len - 2) { - assert_eq(db[i], 0); - } - - // Check if the octet at position emLen - hLen - sLen - 2 is 1 - assert_eq(db[em_len - h_len - s_len - 2], 1); - - // Extract salt - let salt: [u8; 32] = get_array_slice(db, db_mask_len - s_len, db_mask_len); - - // Construct M' - // M' = (0x)00 00 00 00 00 00 00 00 || msg_hash || salt - let mut m_prime = [0 as u8; 72]; // 8 + h_len + s_len - for i in 8..40 { - m_prime[i] = msg_hash[i - 8]; - } - for i in 40..72 { - m_prime[i] = salt[i - 40]; - } - - // Compute H' - let h_prime = ryan_sha256_noir::sha256_var(m_prime, 72); - - // Compare H and H' - h == h_prime -} - -/** - * @brief Verify an RSA signature generated via the PSS signature scheme using SHA-384. - * - * @note The exponent `e` can be any positive integer (commonly 3 or 65537 are used for RSA) - **/ -pub fn verify_sha384_pss( - msg_hash: [u8; 48], - sig: RuntimeBigNum, - exponent: u32, -) -> bool { - let exponentiated = exponentiate_signature(sig, exponent); - - // Convert the exponentiated signature to a byte array and reverse it to - // get it in big endian order, which is much easier to work with for - // the rest of the verification process - let em: [u8; (ModBits + 7) / 8] = reverse_array(exponentiated.to_le_bytes()); - - // The modulus size in bits minus 1 - let em_bits = ModBits - 1; - // The actual length of the encoded message without any of the leftmost 0s - let em_len = (em_bits + 7) / 8; - // The length of the modulus in bytes - let key_len = (ModBits + 7) / 8; - let h_len = 48; // SHA-384 produces 48-byte hashes - let s_len = 48; // Salt length is typically equal to hash length - - // Check if emLen < hLen + sLen + 2 - assert(em_len >= h_len + s_len + 2); - - // Check if eM ends with 0xBC - assert_eq(em[em.len() - 1], 0xBC); - - let db_mask_len = em_len - h_len - 1; - // In some rare cases, em_len is not equal to key_len (e.g. 1025 bit RSA) - // In this case, we'll have a leading zero byte in em that we need to ignore - let offset = key_len - em_len; - - // The array slice sizes will be different for SHA-384 compared to SHA-256 - let masked_db: [u8; (ModBits + 7) / 8 - 49] = get_array_slice(em, offset, db_mask_len + offset); - let h = get_array_slice(em, db_mask_len + offset, em.len() - 1); - - // Make sure the 8 * em_len - em_bits leftmost bits are 0 - let bits_to_mask = 8 - (8 * em_len - em_bits); - let mask_value = pow(2, bits_to_mask as u32); - assert_eq(masked_db[0] as u32 / mask_value, 0); - - // Generate dbMask using MGF1 with SHA-384 - let db_mask: [u8; (ModBits + 7) / 8 - 49] = mgf1_sha384(h); - - // Compute DB = maskedDB xor dbMask - let mut db = [0 as u8; (ModBits + 7) / 8 - 49]; - for i in 0..db_mask_len { - db[i] = masked_db[i] ^ db_mask[i]; - } - - // Set leftmost byte of DB to 0 - db[0] = 0; - - // Check if the leftmost octets of DB are zero - for i in 0..(em_len - h_len - s_len - 2) { - assert_eq(db[i], 0); - } - - // Check if the octet at position emLen - hLen - sLen - 2 is 1 - assert_eq(db[em_len - h_len - s_len - 2], 1); - - // Extract salt - let salt: [u8; 48] = get_array_slice(db, db_mask_len - s_len, db_mask_len); - - // Construct M' - // M' = (0x)00 00 00 00 00 00 00 00 || msg_hash || salt - let mut m_prime = [0 as u8; 104]; // 8 + h_len + s_len = 8 + 48 + 48 = 104 - for i in 8..56 { - m_prime[i] = msg_hash[i - 8]; - } - for i in 56..104 { - m_prime[i] = salt[i - 56]; - } - - // Compute H' using SHA-384 - let m_prime_vec = BoundedVec::from_parts(m_prime, 104); - let h_prime = sha384::sha384_var(m_prime_vec); - - // Compare H and H' - h == h_prime -} - -/** - * @brief Verify an RSA signature generated via the PSS signature scheme using SHA-512. - * - * @note The exponent `e` can be any positive integer (commonly 3 or 65537 are used for RSA) - **/ -pub fn verify_sha512_pss( - msg_hash: [u8; 64], - sig: RuntimeBigNum, - exponent: u32, -) -> bool { - let exponentiated = exponentiate_signature(sig, exponent); - - // Convert the exponentiated signature to a byte array and reverse it to - // get it in big endian order, which is much easier to work with for - // the rest of the verification process - let em: [u8; (ModBits + 7) / 8] = reverse_array(exponentiated.to_le_bytes()); - - // The modulus size in bits minus 1 - let em_bits = ModBits - 1; - // The actual length of the encoded message without any of the leftmost 0s - let em_len = (em_bits + 7) / 8; - // The length of the modulus in bytes - let key_len = (ModBits + 7) / 8; - let h_len = 64; // SHA-512 produces 64-byte hashes - let s_len = 64; // Salt length is typically equal to hash length - - // Check if emLen < hLen + sLen + 2 - assert(em_len >= h_len + s_len + 2); - - // Check if eM ends with 0xBC - assert_eq(em[em.len() - 1], 0xBC); - - let db_mask_len = em_len - h_len - 1; - // In some rare cases, em_len is not equal to key_len (e.g. 1025 bit RSA) - // In this case, we'll have a leading zero byte in em that we need to ignore - let offset = key_len - em_len; - - // The array slice sizes will be different for SHA-512 compared to SHA-256 - let masked_db: [u8; (ModBits + 7) / 8 - 65] = get_array_slice(em, offset, db_mask_len + offset); - let h = get_array_slice(em, db_mask_len + offset, em.len() - 1); - - // Make sure the 8 * em_len - em_bits leftmost bits are 0 - let bits_to_mask = 8 - (8 * em_len - em_bits); - let mask_value = pow(2, bits_to_mask as u32); - assert_eq(masked_db[0] as u32 / mask_value, 0); - - // Generate dbMask using MGF1 with SHA-512 - let db_mask: [u8; (ModBits + 7) / 8 - 65] = mgf1_sha512(h); - - // Compute DB = maskedDB xor dbMask - let mut db = [0 as u8; (ModBits + 7) / 8 - 65]; - for i in 0..db_mask_len { - db[i] = masked_db[i] ^ db_mask[i]; - } - - // Set leftmost byte of DB to 0 - db[0] = 0; - - // Check if the leftmost octets of DB are zero - for i in 0..(em_len - h_len - s_len - 2) { - assert_eq(db[i], 0); - } - - // Check if the octet at position emLen - hLen - sLen - 2 is 1 - assert_eq(db[em_len - h_len - s_len - 2], 1); - - // Extract salt - let salt: [u8; 64] = get_array_slice(db, db_mask_len - s_len, db_mask_len); - - // Construct M' - // M' = (0x)00 00 00 00 00 00 00 00 || msg_hash || salt - let mut m_prime = [0 as u8; 136]; // 8 + h_len + s_len = 8 + 64 + 64 = 136 - for i in 8..72 { - m_prime[i] = msg_hash[i - 8]; - } - for i in 72..136 { - m_prime[i] = salt[i - 72]; - } - - // Compute H' using SHA-512 - let m_prime_vec = BoundedVec::from_parts(m_prime, 136); - let h_prime = sha512::sha512_var(m_prime_vec); - - // Compare H and H' - h == h_prime -} - -mod tests { - - use crate::types::{Params1025, Params2048, Params4096, RBN1025, RBN2048, RBN4096}; - use super::{ - mgf1_sha256, verify_sha1_pkcs1v15, verify_sha1_pss, verify_sha256_pkcs1v15, - verify_sha256_pss, verify_sha384_pkcs1v15, verify_sha384_pss, verify_sha512_pkcs1v15, - verify_sha512_pss, - }; - use bignum::params::BigNumParams; - use bignum::RuntimeBigNum; - use noir_native_sha256::ryan_sha256_noir; - use sha1::sha1; - use sha512::{sha384, sha512}; - - #[test] - fn test_verify_sha256_pkcs1v15_1024() { - // Output of `cargo run -- --msg "hello world! test#123" --bits 1024` in the `signature_gen` directory - let sha256_hash: [u8; 32] = [ - 220, 155, 229, 143, 122, 133, 55, 215, 75, 44, 132, 111, 57, 33, 248, 84, 213, 170, 193, - 96, 253, 57, 124, 13, 251, 42, 92, 147, 105, 172, 233, 85, - ]; - - let params: BigNumParams<9, 1024> = BigNumParams::new( - false, - [ - 0xab238ad9cb37979a43aefbf10be8fb, - 0x31347febe45fe8c2dac1dd30900704, - 0xa5a9a6b9cd0cc2b9d13bbd4e068263, - 0x5eac6390f7873fe97ff9bb14a173ea, - 0xbc41f700c91fd733a2c63177bbdbd4, - 0x41442bd58769a3595b659a2ec9c6be, - 0x4ddc91395f330382aa2e2d3fbe147, - 0x3d008ff255a0bc71c7887f5728ba1, - 0xb640c3a8f511c64e, - ], - [ - 0x5d53d2634c6a0918266043968ce263, - 0x5dd4be3dce0323a492ee9340aec4db, - 0xf82d0e2e5c8319f01a460c72c01854, - 0x236e6fc6e62e8a1d522acda5fb3892, - 0xdaf755619d66e580901aa224d03174, - 0x8366291616480e7e1f202dbcedda87, - 0x40ba1202537d1e94561ccc05265586, - 0x69b993d857ba89ea5de9822aeb4b93, - 0x167968c0000761a273, - ], - ); - - let signature: RuntimeBigNum<9, 1024> = RuntimeBigNum { - params, - limbs: [ - 0xc3850e84ea02da3f028ff422f4d6a9, - 0x9761f0bd9021f76d45c60df0670a19, - 0xc1ede421a43607ab623ed4d5a17fc8, - 0x86197b4315206f4d53200b42555831, - 0xe95783b69db28c26a83706f39d04cd, - 0x18b178dc1a9ec76fb22b57e4dfa703, - 0xdd0e19cd5a09ab48e7af4d0e3470e3, - 0x10004dfab1cf91304e80e6baa4dfc7, - 0x241c3fd77b90adef, - ], - }; - - assert(verify_sha256_pkcs1v15(sha256_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha256_pkcs1v15_2048() { - // Output of `cargo run -- --msg "Hello World! This is Noir-RSA"` in the `signature_gen` directory - let sha256_hash: [u8; 32] = [ - 91, 207, 46, 60, 22, 153, 217, 144, 2, 127, 224, 143, 181, 45, 32, 120, 122, 131, 166, - 79, 166, 183, 43, 158, 116, 105, 73, 207, 196, 77, 33, 5, - ]; - - let params: BigNumParams<18, 2048> = BigNumParams::new( - false, - [ - 0x8d5e7d9daedd6cfd1c9bdf0227e05b, - 0xbfb937fc4d3cf02cc0af780f3cab44, - 0xd20637ef7adcf5d238ee87bccc9bca, - 0xb9db4f2663108e2f8b673f7612ae8b, - 0x85f894ef669b36bfd3d86b0a28873, - 0xdcc70e1884e38b8229cce3b884121d, - 0x35488d1138e0b03e1676f7f5d8a5b3, - 0xe1a97820e7dcbb4eab35c9b71bb273, - 0x97d19eb3c63249ddbfcff915863f54, - 0x3a78c7af6da0f6af0d67b1ca4b6065, - 0xd7a3c433c020f624821e5e678c7d69, - 0x52d5b53240feae82ffea3d2a3d9b09, - 0xb8aad5e19e2163f68997c6fdd71906, - 0x5db432d06e8b0bf59511100c7894e2, - 0xadc0bbc4c54da10d1cc88438ea3127, - 0xece1cf6a1501109cd2734d5893c8d9, - 0x7196b90acdf06c31b1288064fd0c27, - 0xc8, - ], - [ - 0x1b1deccf4dbde852c34a5d6908a0f, - 0xbc9e5bdab22f023fbcca58692bccf5, - 0x1f65439685623e45396ff55751c3bf, - 0x2b6ad2c5f8e3aac15d0ccbab816bfa, - 0x5ca2e8e3048243c16c708a8030ab0d, - 0x30079bfeb1fa51e5501581173ca19c, - 0xff8d5f6bea485fdcc2716327f69ab4, - 0x36b599d81589416b5b5f037986b999, - 0x75612e34a4ff29f0a19a7823512f58, - 0x288b6897929b54c3b26a5faa07c00f, - 0x4b5675fa13ab7444f1f047d3eb1bbe, - 0x6ba0ac610ef9f267ab30fe25bb1c84, - 0xa386b48ee03168d5cea3ecb9dc901f, - 0xacf1a01f7dba44e050c976142fb1f6, - 0x97a63b5cb7efc60d3502946aec63cf, - 0x12cc1d5cab10a1e9e2398d29b9e3ef, - 0x4635cf25c66e76bba8034df46204fb, - 0x146f, - ], - ); - - let signature: RuntimeBigNum<18, 2048> = RuntimeBigNum { - params, - limbs: [ - 0xad29e07d16a278de49a371b9760a27, - 0x86311920cc0e17a3c20cdff4c56dbb, - 0x863556c6c5247dd83668dd825716ae, - 0xc247c960945f4485b46c33b87425ca, - 0x7326463c5c4cd5b08e21b938d9ed9a, - 0x4f89fe0c82da08a0259eddb34d0da1, - 0x43a74e76d4e1bd2666f1591889af0d, - 0x240f7b80f0ff29f4253ee3019f832d, - 0xc6edd131fbaaf725fd423dac52b362, - 0x85f9732679242163e8afff44f6104d, - 0xd3c3bbcb1757013fd6fb80f31dd9a6, - 0x9008633f15df440e6df6d21ee585a2, - 0x324df3425ed256e283be5b6b761741, - 0xc60c1302929bd0e07caa4aeff4e8fd, - 0x600d804ff13ba8d0e1bc9508714212, - 0x50f7e75e5751d7edd61167027926be, - 0x0db41d39442023e1420a8a84fe81d9, - 0xab, - ], - }; - assert(verify_sha256_pkcs1v15(sha256_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha256_pkcs1v15_2048_exponent_3() { - // Output of `cargo run -- --msg "hello world" -e 3` in the `signature_gen` directory - let sha256_hash: [u8; 32] = [ - 185, 77, 39, 185, 147, 77, 62, 8, 165, 46, 82, 215, 218, 125, 171, 250, 196, 132, 239, - 227, 122, 83, 128, 238, 144, 136, 247, 172, 226, 239, 205, 233, - ]; - - let params: BigNumParams<18, 2048> = BigNumParams::new( - false, - [ - 0xe40ee47801326543c8e84b85d567c1, - 0x5b54ea87f0ce29de1995697b0696fd, - 0x457078f8fdce68b437cac0970b2452, - 0x473ec776fee3731b6ab06e35875ddc, - 0x62dedd594e5f12c80c3ccb5791a6cd, - 0xecb934b9d8272c5e3a418145345499, - 0xd1af643b3d785470ed0c6cd633f706, - 0xb58a57b9e96eccbdfc7c17f0333d4, - 0x2ebd34b5039fc596504927c282c60d, - 0x3a44928a74f25fc1043bb37ce4dfa8, - 0x91448459f9617fac33a2816162ac9e, - 0x70cb910d9f3e1a78864640ec6c8240, - 0x9aed33f6b31f1c9de67248a98c180, - 0x7f1416e032c79488c94b311e87bd9c, - 0x7191b4ebb1b3fffa949fa48ed01e5, - 0x350a75cbaeca6bfdd71ca83cdbcae9, - 0xfb1d274fa207457c6814d42c09f9cf, - 0xd4, - ], - [ - 0x803bf4d38110a7d37fdd05f590dee9, - 0xa68d317c933f37cab5ab4e7c00a3b9, - 0x476a05a536bf5f2aa1b8850146cba7, - 0xca297ea8b5528d91d4836ff27c30ab, - 0x75cf2eaab76eefa12bbd570f1aea9f, - 0x8f6a8ab877d9c5bcd98c37bdc5c2d3, - 0xd497db1f6ebe83decacaa647fabea6, - 0x686b27ca330e25e7a7cf197f6433ef, - 0xfde04d2225c8308b07580af0058a0f, - 0xa29fb69777c0e916976243b2b09855, - 0xf983592285852e7e1c2cb3ae968323, - 0x673608017f9f5acf67a01b73728d70, - 0xeeff82521c0bc432a05f4b7444fac0, - 0x85a89c4d229f60aaa3aa7ac7dac1e2, - 0xcfecff93bc9fbfe0d6dff6091f2db8, - 0xf20f047dcb224b4447bd098c07f8c2, - 0x554bb53cadeb3eaab911a189f90227, - 0x133b, - ], - ); - - let signature: RuntimeBigNum<18, 2048> = RuntimeBigNum { - params, - limbs: [ - 0xa250eff812c63eaaeaa3f04641c05f, - 0xecc09613cb8b289c1f37c8f92e6a05, - 0x2c0a0510058360c07af65d46f594fd, - 0x943d67513363d3de430c94a1dafe7c, - 0x511ec8e9b10bc6c6ff0d6c232ccf92, - 0x50ffd07b3c093b3f5fc027de847731, - 0xc268e1489449943fdafdf89ff168c3, - 0x0b8b7f9f49b492f78fda58d252f23a, - 0x491c6c4ef836a6a8730b7bf81e865e, - 0x8746c75fb079d014e419543f56d7f0, - 0x65804c417d6168a8bc0025d255cebf, - 0xf695e91b77890b8e3fd775fa56e627, - 0x5e90001c0218550f4083ae28025a2f, - 0x526bd4eff34f25f62a698f0470e0a6, - 0x7f224306a7d9daf536b1559434c6c6, - 0x88809f16fe1fcea3c87511d9319735, - 0x7694685fee0bfab4a9196b92ec6f2e, - 0xa7, - ], - }; - - assert(verify_sha256_pkcs1v15(sha256_hash, signature, 3)); - } - - #[test] - fn test_verify_sha256_pkcs1v15_2048_exponent_38129() { - let sha256_hash: [u8; 32] = - ryan_sha256_noir::sha256_var("Hello World! This is Noir-RSA".as_bytes(), 29); - - let params: Params2048 = BigNumParams::new( - false, - [ - 0x4f79aee9e865ee89b9695c2ac44903, - 0xe33ac311e740f4dfc39492d38186d4, - 0xf513677b71c4cdf88b9011d109402d, - 0x940eba50ebc0a50b539268b2c9edee, - 0x6d7b7dc633b0ba7deb34669da59af9, - 0x69f0b92bd973d83643b54c86302bc8, - 0xbee39cd038bb54491cab410bc1382d, - 0xe59688c01aa8491c6522aa467fbdba, - 0x8731b6ff98f9e1f792d4a4dff8c81d, - 0x9d1773f064f1ce81301053e3abcc43, - 0xe80e6137f3ccf06ca669e0d0f14c30, - 0xefbf9d55ae96471f9fef8d5ac29c46, - 0x284807c893f7e7af1a39d9c599ba76, - 0x17491bdeafd3a2c796dd50f2444997, - 0x21742c4e2dc66d064e36abb50f9c67, - 0x58f1503ad765979883692dcff55252, - 0xf613ad8641b9195cb742ac5d3ff778, - 0xad, - ], - [ - 0xbd864af583a9911c93c5b92ab68568, - 0x10d63ed8c0c83e91e945683061045b, - 0xf38982278a43cfae6438348ae94c9b, - 0x75133ea58bac5abff54a6e7a165283, - 0xd3449474e97738f4c6a2d843722783, - 0x9e3b3c08f360d9f967416af9becf84, - 0xcd40081688aedd976009f34a964356, - 0xa27adea282e0227e69ff47203440cb, - 0x99f812956fd9377b0bed8deb543ede, - 0x5f655415ed123df19398d5d479401d, - 0x587d5cae3d0a5b34e3f8b2ca43ade1, - 0xa4fde6c7f37ea8267d2183519ceb1, - 0x1ba5bec0bb36c67251aa7678f7c169, - 0x2e1ddae393d6a4f1a320b15b23b974, - 0xfc61518efd066b5912b60cfd1d7474, - 0xf854c457bf3908af1e4934d7c72d1f, - 0xa44257cffc0c579bf0addd3c75d4df, - 0x178b, - ], - ); - - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x98156ae7cbad0e0fbaa9b254c445cf, - 0x6f3ea82d1faf48ecb60f3f7481f020, - 0xea0f2df747bbe8a8629c9dc6246da7, - 0xb635b9de66aa7e600e924c0932b43b, - 0xa010df8938db4c035c8473f0fd167d, - 0xe37d1709aae17c76199c99efa5e5a7, - 0xf8336b32c807dfb62d149fb8353f4e, - 0xf852a4cc6a84981cd8a0d9eef5510f, - 0x10c5cae74e75c83e3835906e5eea2a, - 0xd83e21dc7e49277c86d81144837750, - 0x72e367e8e2db3320145626438e6e93, - 0x2129c9c0c2ce89e77661a15c8c7647, - 0xe9c0b584a2ed003dbe4cadd2cfd87f, - 0x6e5bd7521c235ab9e18356d089863a, - 0x28e861ed03b6acc39fa7af5c068fa7, - 0x4d1a681de2ce54f0d19eb736723af8, - 0x2042cf79eb42702aab8526c68a64fd, - 0x90, - ], - }; - assert(verify_sha256_pkcs1v15(sha256_hash, signature, 38129)); - } - - #[test] - fn test_verify_sha256_pkcs1v15_2048_exponent_107903() { - let sha256_hash: [u8; 32] = - ryan_sha256_noir::sha256_var("Hello World! This is Noir-RSA".as_bytes(), 29); - - let params: Params2048 = BigNumParams::new( - false, - [ - 0xf2bc2f4fd3637bb9ccc7e163324dbf, - 0x88ac5e7a9abee89a393533168e8743, - 0xa9d1ef7f5677329e23336052001928, - 0x2fa85860b512fed4ecc0c94388e4dc, - 0x61b27bbdb48fd8dcf155a1d3242029, - 0x8119d20bb357bee95c9e6038448ea2, - 0x4e8759208ccbfc555d32e3fa487af4, - 0x7608d025ac5a266c1e795b7dc0840b, - 0xd9df24711a6d2fed0d9248057cf278, - 0xfbcd7907dc0dacc66a855324c5ae85, - 0xcf3eca7c8405dfaf7ce39c1b1e526d, - 0xf2c0a24eb8fd5b2b49eb261b01e5cb, - 0xb7be784d951012ec79c8df7bb35e10, - 0x2f7a97fe187189f04fead5f1b00850, - 0x8246d382cd0821b066e801665eb949, - 0xbca14eae9a7d4b426639eb99d15c3e, - 0xfd0f6549b224f1be363e496501a0d8, - 0xd0, - ], - [ - 0x66eb2aa6aa1141cacc9004c4aaafcb, - 0x3983dda53fcc7548cac5070988d128, - 0xa94b8ccd7bc37c9c6c074ec9dc418e, - 0x57d6ec9504d4f025839a764cc80cd6, - 0x5a99da586dd573c790ad0b0cf4048f, - 0x4c7432020677232539d08b80c4d3, - 0x338f75091af189cb1d224bd37c6249, - 0xee6a89be24e36b5f7f1e7c38fae7ba, - 0x1464843dcb6adf79a5775db61a461c, - 0x6040e8536fcfa579e6058fe8fe2faf, - 0x493b2bb04dd77744a5adc46d90652c, - 0xef49699688680f2bed603abb89bf31, - 0x5d86fdb1035de7023db8815fea79ef, - 0x36e4b0aca5531d5c0da94709ba17a4, - 0xa4327a03320a6982a60603abc981cb, - 0x5d54032f69977241b356abc4590887, - 0x62bf97079a59e9ce6320da47988e99, - 0x1399, - ], - ); - - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x4b2f40b350af5cf9b4cd5e4a48484b, - 0x2d45da942f02e9c1ca4d0b5c8891eb, - 0x95e181ee7a25546bb5f06881ed06ab, - 0x96daf6f89a37583781ac3cadc3b474, - 0xca3d251f57ab831e38da4a72febd6b, - 0xd331a8762354c7a21a205bd00a56e4, - 0x30e1612ca0c22b20df7e3b13ce20ab, - 0x0e44e8752d7f365a5be65666a695c7, - 0x2f9371a16fac95bdbe2bdd29fe3660, - 0xb5aa14bd29c9cead7fe248cc8d8fef, - 0x5152b5458eac4871b2dad8ae6f82a9, - 0xb440d47429dfc47c83afa416a4f6e2, - 0x6c71eb1897abe36235364ea0257868, - 0xd2d51b57e037b494d663d8238f7ee5, - 0xcc7fdf728797297df1292e63fd6e3c, - 0x4eaf8992cf23b65390e2dfa7b012d7, - 0xe84bdde98147a17f3a9297786a9b84, - 0xaa, - ], - }; - assert(verify_sha256_pkcs1v15(sha256_hash, signature, 107903)); - } - - #[test] - fn smoke_test() { - // Output of `cargo run -- --msg "hello world"` in the `signature_gen` directory - // Create runtime params: - let modulus_limbs = [ - 0x65af46d235241cf0e8fbe8cff4abb7, - 0xeead39ba3f377ddd5ccb2ef2085190, - 0xe483f94c0a98e8b618d92fb926f596, - 0x1fa8c1b2c62cca6db090cd74a29db2, - 0xc38e22042fcb74585a7e535301f50f, - 0xcbc4378e5212752743ae78a75a44a9, - 0xf5acc41788d9a346a0f75630a8b2b6, - 0xf7a741bb3ecf1aadd5a327f362abd8, - 0x4d5f24e815db43a1b2cc2ba40f8715, - 0xe501f1a01305cb198475a4bff0da2e, - 0xd541b78cfbc2b314083c340840c82c, - 0xa0ab069c26b2a0458f4c642bf72526, - 0x2ccb676d8f22517116fee0d2340533, - 0x7cf2a7cf772025c0a83747bbc18228, - 0xf9475f17988a56f17b3bdf88dc72dc, - 0x4ff228bee24415fae7a7c05771e830, - 0x55acd96b485515c38906106cf0d189, - 0xb9, - ]; - let redc_limbs = [ - 0x172c8f156f020ad88d30fa3ba47f03, - 0x1740a43a67cb9a7be1ac1422d77246, - 0x2d967be1edf369834317e04856e591, - 0x65d9fa0de5fdab598c04d9a515156a, - 0xc6791a661ea7621db7e6c4ec48f466, - 0xa4a1a7c06d3e8a0bcbc540c6af6788, - 0xdcaffeb149f5bf646caa00d7355715, - 0xb75471630a9d0fefb5cb61e66991a1, - 0x97c041a0fc30fdff3d5ed16997da02, - 0xbfbe7d217694b269e1ed37819c2f17, - 0x1b44ffc3180531e2ab8bdf7848a3a9, - 0x9f004af11132cb68bb55998ed7616a, - 0x1b15dbbb96ce80f479724bbd768a0c, - 0x59ba1419093ae6ed2592ffb3065867, - 0xa35b69affa3bb3f4713f315e50b584, - 0xa873210f83a6de0d8cbb816af3e37, - 0xbe4fe7cf98da87ec87638030797e92, - 0x1619, - ]; - - let signature_limbs = [ - 0x2f397c4611d4a4271453e1e50e1578, - 0xe506a7f47c721a4943783e8ad459e6, - 0x6cc4ae1d91cb381cba9673470999fb, - 0x1e127364d07f94e58227f50fbf5687, - 0xf64a2579c7189f882d68832d16faa4, - 0x3b014b74c6c6f76f2f8af170fa0fe4, - 0x7df41e68c86815a6fdc33968c66b67, - 0x6a57ac06282527242fddb6ed08dbdc, - 0xac40d37b819c4b6193f90a634e4fc7, - 0x96606ed166a7f032d858cd40ac73a5, - 0x8eb7d4351159a46733f92610d5c597, - 0xc8e8e9faa9738e82dbe774a3f5cf07, - 0x89ca84fd54ee3d5cca87c9f178375e, - 0xdb7a1465fc76507ea498a351af70dd, - 0x6ac6fe14f51c711f983125c776f712, - 0x3254c17fef51bf4194a8a1674634e3, - 0xee38c83c77c6e1ff7b70a5d9d1dd0f, - 0x26, - ]; - - let hash: [u8; 32] = [ - 0xb9, 0x4d, 0x27, 0xb9, 0x93, 0x4d, 0x3e, 0x08, 0xa5, 0x2e, 0x52, 0xd7, 0xda, 0x7d, - 0xab, 0xfa, 0xc4, 0x84, 0xef, 0xe3, 0x7a, 0x53, 0x80, 0xee, 0x90, 0x88, 0xf7, 0xac, - 0xe2, 0xef, 0xcd, 0xe9, - ]; - - let has_multiplicative_inverse = false; - let params: BigNumParams<18, 2048> = - BigNumParams::new(has_multiplicative_inverse, modulus_limbs, redc_limbs); - - let signature: RBN2048 = RBN2048::from_array(params, signature_limbs); - - assert(verify_sha256_pkcs1v15(hash, signature, 65537)); - } - - #[test] - fn test_verify_sha384_pkcs1v15_2048() { - let sha384_hash: [u8; 48] = sha384::sha384_var(BoundedVec::from_parts( - "Hello World! This is Noir-RSA".as_bytes(), - 29, - )); - - let params: Params2048 = BigNumParams::new( - false, - [ - 0x1dccbc1b553aef560cd665aa2ca411, - 0xdf1b70d8f0ff39013065a5a886490f, - 0xc3952220c2f6ba45b86fd1842f6db5, - 0x13403323f2e86127e7d30ca5c3741f, - 0xdd9593e1b80868ee660cff6aed224d, - 0xa768ff67951f621cf220c3f11fb7d0, - 0x827a30c8fc6da6d9e0002ccbab7354, - 0xd4f4b3326c1822490ba84bf7d8f2ff, - 0xbc1aed9983525cf9795c5ee886efbe, - 0x95eca388e0ef68d9e1b51bfdb3f38b, - 0x5f250161202b7d91724180734cd057, - 0x5f6a6e4b2adf9db128af321e90bc61, - 0x2b395ebbeaaf0c6c40a8e7ab2f041b, - 0x8fea1754c39077bbc232d8380c4eac, - 0xa113212c3d6ba516cdf08b1c0c0cae, - 0x9ba6c1d51332cd846f88cfe28dabb, - 0x57a8d8bfcb8839f3ef85c7ee2dc2e0, - 0xb4, - ], - [ - 0xeb993de4326322c7d2e7979b705653, - 0x1d611f18aa83085ef385333ec454c3, - 0xb7a3bee73153dae2577781e9a435b0, - 0xee599bc9d964a749c73673b0559c2c, - 0x35c1adbbcbfe860f721aa7a0fc3f13, - 0xa8c28cff73d6ab769ff07f77246062, - 0xa6263efec60ed7d395f486a0a96b2d, - 0xa6da86e3c3abd7bec42b6fab8927bf, - 0xc5a27d894e67e310bc4490762e53dd, - 0xea29c3c6430885ae7b68d1399dd42e, - 0xb5a82288241107dcc02e4d04cc0fd, - 0xf9dbe42935c2111913f05933346bb8, - 0xc82f5eca04e0b6ab27cdbc55ed1cf6, - 0xbc6d3e01593e9d1c9399245a306ccd, - 0xf5da9e23e54b7ace54fc14e9b8fe89, - 0xc087aabdf746e1a12a8792cf7ac5d1, - 0x5c825b2c8353558dd371d57b1d31af, - 0x16b6, - ], - ); - - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x0d643395f61610f78e0965ff28b34a, - 0x991a18b16cd776f8ba0dc7d3a2c0ac, - 0x59ad92fdc6573338573a5ec3a8ac1f, - 0x39fa3c545c220904560f89449e0cb6, - 0x77c0492bb5f8faeab6484258164fef, - 0x32f66a824fc81c4bc3a10228c9d875, - 0xaf5a933d03c5c769af3e1c43112418, - 0xe4b3c71e29d230dbcd784dfd344cc6, - 0x08f5fd6f3b0782eaae154fe56fbe0f, - 0x9b785970ee35b2cd656cd9f098565c, - 0xc6c649021334fff3d4ba072255eb0e, - 0x1fb7d5c84e2fc4e975ea5793a92fc9, - 0xcbb718f2f6c780b4f6e3a17575b89f, - 0x04f7eb7174814ff492727916397bb8, - 0x77790f451d53ce4d4229791f142d38, - 0xd9ab6403501d48c29b3abbad760d43, - 0x20d90ee7975dcbd1761fa7f6487391, - 0x17, - ], - }; - assert(verify_sha384_pkcs1v15(sha384_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha512_pkcs1v15_2048() { - let sha512_hash: [u8; 64] = sha512::sha512_var(BoundedVec::from_parts( - "Hello World! This is Noir-RSA".as_bytes(), - 29, - )); - - let params: Params2048 = BigNumParams::new( - false, - [ - 0x56acc9475dd0568166f6d519d2b123, - 0x4388e4291f2a16d58441e4c966d869, - 0x3b6cbbf6524f2e12e274d96a598cf3, - 0xcb7b28845e13e53fc8827fadcbf5c2, - 0xc2f20ecad4360634ca81a3f2700df9, - 0x71b5ed85f3cc58e9820fa9cdabf2b4, - 0x8e15d0237c7dbee5369ccbf8f6e25e, - 0x280d4771bcddaebaa691b4870d4a92, - 0x3f8ab4c278a35f45149814c95c1c6a, - 0x4b88bb3a4f16adaa8a9ffa781086ad, - 0xb4e8dad6bc3fd7d666683e872832e1, - 0x3135b2958becadcb9e25ec25e55b23, - 0x405ef523d210399f9def6302a36221, - 0xb9aaf3a3c5b2e3f4f86393bde7b852, - 0x5f66a3d278b5759b92269481eb94ca, - 0xb0ae491acfb3d0a8a46a92b7adffb7, - 0xa61f0e1720a3cc4594121de7aedf34, - 0xc0, - ], - [ - 0xa1818833c46a2c4799148d9f1264d9, - 0x91008bc32d17f31c4f28b53cf3b9a, - 0xbf512971ab01254af711f37837279b, - 0x4f98e0725dbc7d52fba2f5d5482d5, - 0xc06343b59716c402d33ae0d15ce9b, - 0x96e236079ec038a21029aba4ff7ffb, - 0x76e91c4ee8870b1d1c06b73a00f0f9, - 0xc5018d4394283930ab64cc401b3809, - 0xc8b4f3f863b01b0fe223822f163552, - 0x6a94ec6a63708552ac0ab6a824f380, - 0xc3cf47d1d72b08284f9c04e265a5bc, - 0xa9d863c6820f2ec1cd35de9327b153, - 0x85983ec02cffd866801e790bbfa7d2, - 0x5ee89f7c98ece0aaf4150b6c5b6abe, - 0x7255ef31994f3cb4b731d0bbf76c57, - 0x3aba2e537e9003f447c62153c3dcd7, - 0xf005726db837e60cff0feaac8d326d, - 0x1542, - ], - ); - - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x8c1ac22b4f25479bd4d63adc5647a5, - 0xc226d235d17e3ce2d6303804edd317, - 0x75992147cd0883367aac32c28927e2, - 0x7f131d0a5dc76ac9a3982bc3430a66, - 0x1e5c5471a794bede59e42c5125df77, - 0x7d4d8bffa69b08eb5a9338c96eb042, - 0x44bc5745bdb2ed1944e61939c9b325, - 0xa9c536593f93201b1493257bfceedb, - 0x9f00b9f27e424f9724c1486fb54314, - 0xeae7e1250521e254ee2d31f94002f9, - 0x9ee4db7dbe46139670393a1250fa79, - 0x014039fcd5bcfa3db273bf7188b3ce, - 0x4967a88c2ddaf359c3c813cfa3ccc6, - 0x9c3f74383a8c3326b47401d5815c45, - 0x2f666d5fbe8464dcfaf569bffa0248, - 0xfeccacb7e9e0e44320651e58344e8e, - 0x8942c708df7e40a175d44fee7cf5ec, - 0x4c, - ], - }; - assert(verify_sha512_pkcs1v15(sha512_hash, signature, 65537)); - } - - #[test] - fn test_mgf1_sha256() { - let seed: [u8; 32] = - ryan_sha256_noir::sha256_var("Hello World! This is Noir-RSA".as_bytes(), 29); - let expected_mask: [u8; 32] = [ - 106, 93, 232, 46, 236, 203, 51, 228, 103, 104, 145, 29, 197, 74, 26, 194, 135, 200, 40, - 232, 179, 172, 220, 135, 51, 185, 209, 35, 194, 131, 176, 190, - ]; - let mask: [u8; 32] = mgf1_sha256(seed); - assert(mask == expected_mask); - } - - #[test] - fn test_verify_sha256_pss_2048() { - let sha256_hash: [u8; 32] = - ryan_sha256_noir::sha256_var("Hello World! This is Noir-RSA".as_bytes(), 29); - let params: Params2048 = BigNumParams::new( - false, - [ - 0xb2cae9b4d726643aef459696fb80d7, - 0x46585d789783e6f0ea6a4a17001b8e, - 0xfdf7476659c117564ca991f3d635f4, - 0x9bb5835a63f78d2ff06927d5f5a64d, - 0x18ce92c21c9a7dad5ed41c66790811, - 0x38003b2699273864cc87b363714855, - 0x7c19d41f8dbe41e03505fe1e061a5a, - 0xd63a7a6d91625495e46db9161b0d7c, - 0x3dffb1f7121946f6e04dc642a85da9, - 0x389eabe29dbf38c1be95c9b9c0c029, - 0x77a14dc6452603a154cc463e4c2a3a, - 0x68eaeef1963fa3866c934d1225ac67, - 0x3a66b9b64048ed95cec6bbe4235189, - 0x113fd1c23822a8dd63e7d97b034eeb, - 0x28b7376afc6109602ed94eb40284f6, - 0x4d331f4da82c798979e7d9d2c5f7bf, - 0x716d8b401bea115cf1265f976aaccf, - 0xaf, - ], - [ - 0x399ea4dac74d4757a7a2956b5b0493, - 0x954c409a53ce8d70f35be10b94d284, - 0xee4d330032d52a65e66f54f9e091f4, - 0x7522b6ca940bfc5133b8fd77ca4bc8, - 0x43485c2c6ac94d8041c5a056da794b, - 0xa464924f3a28ab23c5ffa0493dddee, - 0x8fe3f1bc6a09e1103acbb53acbf6f1, - 0x5e47597909e86c168b5748cc089ce1, - 0xc86b6b4de2aa786e144d0ef5556c30, - 0xf45a9d9d93fbe0cd5f2ddca2316648, - 0x5edab2328b0b639407f9c773a06c5c, - 0xb61d4e287c0c6a969f5decfd036ea5, - 0xd47864f47e49cd0e0ec34f120ba0a4, - 0x3eaa94f799b276ef6a790eb61722d4, - 0x5c18da1341811cee5de6f76ed1a186, - 0x5ef0641da7cac0c45ba74d4355befa, - 0xbb04586630e92ea5ece8e5db45caea, - 0x1758, - ], - ); - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x6d3125fde00a57fb5971460c38a826, - 0xba2092dd58c4de8ffff2bf13f5ef57, - 0xf0ad4ed46727881e7e7f6a103d7713, - 0x7e8b2203a7a6e3a3a30219d6edf8a2, - 0x9b0b861dd1cb2751f30d54d07ad167, - 0x4373e863b15edba97439182a6a9043, - 0x61621211db5f34a0786d5ef38cd90c, - 0x63001609f7dffdc70761c67617b580, - 0x8b2b817a0508e4be6f2c50df23962d, - 0x6d6f9396978782a90fe06ca78c4f88, - 0xc567a9fe5f7175225384d7c1e4c991, - 0x38926dfee8636b9e36728c1cf51198, - 0x0eb84e90f89a0bd21536a537618b92, - 0x23dbdcda1fee2b57c8dc2e605777b7, - 0x6acac69b2fc1c12c204e790034a01e, - 0xee44b77264385863ccef2e133241cd, - 0xe9c67049c219997cc8c43b0b1f420b, - 0x78, - ], - }; - assert(verify_sha256_pss(sha256_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha384_pss_2048() { - let sha384_hash: [u8; 48] = sha384::sha384_var(BoundedVec::from_parts( - "Hello World! This is Noir-RSA".as_bytes(), - 29, - )); - let params: Params2048 = BigNumParams::new( - false, - [ - 0xc3034c17b5578d9c029b22158a8e45, - 0xa84c80b43a68c9eb7cde67f1f60e07, - 0xa8d82a4aef2cd733a9fdf43439ffbb, - 0xa1b9aae31832c2815b81f0db70962e, - 0xcfcbc51338d691443e702bd18354a7, - 0xaa2c5f465a247efc9d97fb052579b8, - 0x571f3c233fa322a933a4cfc0c4b213, - 0x3280f1f7238a3416c5e1140077537a, - 0x8685f03e3076c1bb62550cb363ae08, - 0x55ebdcb84073ad2dfd3553c5e2d21a, - 0x1e5a0a662b44f5250377abcd1069e6, - 0x178357493184215e38603004f6c9f3, - 0x75cb8889b33c6b78bab0a378453376, - 0x4f5f7baa56492d5ac52c1bf7b998b, - 0x16cf48a7c416bbf67657a263376e22, - 0x1d8ab41c7021ebcb15da705dab5343, - 0xc5e43d48377059df0aa5d7e5441586, - 0xc7, - ], - [ - 0x721a52a87ca82263e96fd6d2bf3417, - 0x74bfd742af70020df01f6cae960793, - 0x1091edcad411cdbfc254bbb2ab2906, - 0x9d1a2951a8e50de9c90b803c3d4931, - 0x506ad1760d06b52708ccc0ed9fe629, - 0x11b96266505a62523f9cfa1101a9c8, - 0xbe5243b0f30ee090c4181e19f45f1a, - 0xa2a56edaec8f9fe12d4d07d725931e, - 0x50723b780f7ef18393031ced4f1489, - 0x1ef7d8dc5b567db0b1a65b745625f2, - 0xf9f37b5efea9a93029d7d5dda26bc2, - 0x759247cff5570cb9075ae0e8b5cfee, - 0xfb2e6c00b4ce0feedc40f3633d354e, - 0xc9051ad4f912e7a5753e614d892320, - 0x3cf78d852f5f76bc267b0ebcf13c39, - 0x7b3cb2df2619a3020f2080dd555657, - 0xd649e6032585f42250ac6c95111c09, - 0x1480, - ], - ); - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x06d24f9dbd859780c7684e7733ebb1, - 0x3acb7e4bd7c9f42a5f9649e1fef5c4, - 0x67878f2493de5cb48ae107df08dbf1, - 0xf268bc940d64e42b8719216fef188e, - 0x2c4701120db41532e6d195ba1f8faa, - 0x03d3b537eefd6f0c99fbb7c1f359d9, - 0x35b732ca45b03bb17b1f3564f18464, - 0x468584d7dac0a4ba51032e2a5f95e2, - 0xe10042eb30d1662517aed3b89e1154, - 0x0e5743acb366c6251627e64f751256, - 0xb06e6af3e06ed5c656e66aa0295f63, - 0x67378aabfe17e33e305825eb4f6c5a, - 0x8cd4c7aa81b660325dba4b0d899a9c, - 0x40c83a9c74f99c026aa845fa222b69, - 0xd52f8e19032a33a1d9a01063fff8f9, - 0x7dc36972054edf46bbfe918711e693, - 0xb035fca3baf4329ff5d588baf7b034, - 0x1c, - ], - }; - - assert(verify_sha384_pss(sha384_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha512_pss_2048() { - let sha512_hash: [u8; 64] = sha512::sha512_var(BoundedVec::from_parts( - "Hello World! This is Noir-RSA".as_bytes(), - 29, - )); - let params: Params2048 = BigNumParams::new( - false, - [ - 0x928a173c3947c058b084e258b8a4c1, - 0x5f1179c22cfacb440464695cfa393e, - 0xc409e532b3077ce4d90e66e913f125, - 0x29e8696374f86380ff45d0f29a98d5, - 0xf931d155d89d3753ee931433a8e2fd, - 0xfc3d1c2a999f0112f5c5416c2e0428, - 0x4d21692b210bec2ab8e1b52fe78e66, - 0x9df364fad350d314b146e84f114203, - 0x8511a74031596831dda8ac9d18dcf7, - 0xab5f9ad71b33284aae738988284229, - 0x3332aa31681f69a5f470caadad7469, - 0xf1fcad281e0fea144e1f4208d38e38, - 0xe83d3b0afb20bc39814ea22df000ef, - 0x3d9244664808f54fc4f0702adc9399, - 0xc087b5dc693953e6371b9c7c175a21, - 0xd5910d0d4232e8f92148482a72baec, - 0x44e57b58ec4e75250116ce2f1abf3b, - 0xd2, - ], - [ - 0x74b3f4c907125a6150549b8b5a387e, - 0x9c2ecc9981d5fc27f5a6a7b4f23756, - 0x57ee194ec44b4a44df198809f8d673, - 0x7ffa9a1ec7d9a9b915e1abc75c493f, - 0xde339596c27c993135a7ee132cf774, - 0xfdb788951d3777aeea6afee171b569, - 0x8dda93126970270ed42ae605e9824f, - 0x3fa6e07b4429f0ee8370c988553ee3, - 0x26d95e43ed1e1960a316eebf6b3b0b, - 0xfd155b9025d16ecdbdac73725d9a89, - 0x2f5a47107ec03b05f5a10fba4fa1df, - 0x61a45285c5dc3355741713d6d71a24, - 0x8644f1f46cecd803e531110da3bd5f, - 0xaf989d56c5412bee6598af25829723, - 0x52f7827f7aee453f9c3eb9753fbe4b, - 0x9f38d6f5f1a3ff0d40c601d799dbb0, - 0xd401bd1620fdd206413a8977de6375, - 0x137a, - ], - ); - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x2058f7115f339e55a93f8dcefe81b9, - 0x38a20cdbfc439a1fea423c119f2879, - 0x7ac4e03a5fa662754e6e21a78984d4, - 0x69d714829d29b235d588476152b5af, - 0xce3db2102990c27bb66bc32da8dec4, - 0xb4914f6f0e73718b5f1e422fac6ddf, - 0x7d812b554c81ccb7932d1e78c6e002, - 0x438fe60d9e0912328374513ab91b69, - 0x56abaf2b8d9a6dcb9201586d2f0d0a, - 0x4151c524481066bd81b4cd17829481, - 0x7c63b445e245d09ca91057032ad22b, - 0x9f242d5a655035a028a68d337ae40d, - 0xb5f91b99b495862044bc7122913806, - 0xc123aa56dff5b23d7d8ad097748efb, - 0x6892e3a32a7b6963d97b3bdd81b91d, - 0xcd7aa9e3e77f68f0ed195bff92a162, - 0x583a32fd5a399f3acd867dd7d6a1b6, - 0x7f, - ], - }; - - assert(verify_sha512_pss(sha512_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha256_pss_4096() { - let sha256_hash: [u8; 32] = - ryan_sha256_noir::sha256_var("Hello World! This is Noir-RSA".as_bytes(), 29); - let params: Params4096 = BigNumParams::new( - false, - [ - 0xd78653b3d43a72784415fc0537129b, - 0xc725d4fb19419a03b58e0fb5ea4ad2, - 0x1d866cfc050224a0eb317e835ee283, - 0xd298018e86d3225a264a449c63d69d, - 0x824db5365a077bf704acd2446baa7f, - 0x5c419e562b5b5ccb0dcb151a3f48c9, - 0x198a6627edcbc2afce1893217c2e25, - 0x29a693a0bb3f6f02d80e660f681d6d, - 0x5656562a9622f87bfb969db2542f63, - 0xb9408b08a3ee3b25b6dc6ae12899ef, - 0x4ce9b767219e1e0593782ce46a041f, - 0xc5a4f318b34ff79121677f283ceea1, - 0xbd5e62c599453a94e0bf5f48c6b58a, - 0x6ce23c4978ae07af4c46ea9b9964ad, - 0x68d4db6209ac89538e6d986cb77459, - 0xf2ada72cff01696e2efdf123ab60f3, - 0xf951c3c1965c355f460fa815587ed2, - 0x6063ac0275e6592b878d5a66e68501, - 0x594eb3db288ad091bc1db2b2a90101, - 0xb72899c91edcdf890053f87d5b1dab, - 0xdfd45eab0c435e275202bff1e22f5d, - 0x3da05e1d0d3cd0012e6c40e1878ab7, - 0x4fe053feaf486a27dd119cbee9ce1e, - 0xa3781b036bd3a3411c2af8377ad0d9, - 0xdf4410ba8397cbe580fc5eca7d230d, - 0xdc34151036d459fc3c21d8ba0702fc, - 0x4ea71eb1b0b1a2f36741b61e8765d8, - 0x22cb66b4eb0b34b34320402ef652dd, - 0xd19167b88620fc6b60709fd39cd48b, - 0x524e4fbe4d75e4817de075ac70c72f, - 0xd0de26679602cd331c3e5534ce668a, - 0xf5aa120ff51d4bd3d57c1d68359f95, - 0xaa06f0791b623cddd53d787035bd66, - 0x122e014d565fa26417a5ed0f786fbb, - 0xb95e, - ], - [ - 0xc4c3bf6cc9335c4bb7199f9eb47a5d, - 0x7bcbe7b5b3cfb697c6b77fe1aa066f, - 0x3e936bb516c60dec6e7bde90a54056, - 0x78a92edbea967a370dc928b2f4cb53, - 0x99df0977952d4278e6b4c792b31c39, - 0x7d894ebed8702b158c7a51dff502b8, - 0x6da93f37eabadd8e55d4f450bf48a6, - 0xfb59acbad033856be388bf59b73c4a, - 0x8644dd32dc773e5e12e03380dbff01, - 0xdff59e8aefb7acc81bde30f7b22890, - 0xa646c3f6a98819547eae677e99679, - 0xc777d7da058b7a0d88b7ec84400a6, - 0xc6ba50b7cc4d0aebf8a25d1eaca0ec, - 0x6f2cc8babdde75a318872b952885fa, - 0x6fc91aadc8ce227e9039c8f3148d9c, - 0x67773f804221d4f58ca3bd11952bc7, - 0xcf5a20affc5a099ad25abb5b9cc622, - 0xf60a9108eb36c8068e93e524c23512, - 0x8b67af87617dcd94e38a62a7297673, - 0x656343f8e1802e8c043b2621f5b08d, - 0xd82c8e1a8d3e458e7979a77cd76424, - 0xd2bf783c787be340bd66fb8a07d1d7, - 0xc94d16e2ea48369f57abca5909b81c, - 0x2ff442542b4e904ad3ca20d06ee11f, - 0xa1fa20565627dd7eb96b4027b6714f, - 0xd3a82d484df4983db5fadd7b93048a, - 0x5f4e993b09d0ab81b8312bc09f069, - 0xcd135a6daa623b906fb62c6e28e9e1, - 0x1a5abe5655f62a0a0d0d9479ae7675, - 0xcfa89adba08b924725c940a56ad9e, - 0x6023b1d30936eb9ee54bf789026e22, - 0x9e91f11aa269f381122653c704cd5, - 0x2116e976d592737e0c57dc12269efc, - 0xe88a3202a09bdeaa3db69af98a651, - 0x1618be, - ], - ); - let signature: RBN4096 = RuntimeBigNum { - params, - limbs: [ - 0x5d9212d0c25acc14b61c6ce61a844e, - 0x9d369ae765eb0545f83f552b8d7bb6, - 0x5f0f5d383bd70d7726a851c422fe29, - 0xcff5886575636efcde5d9843e59a10, - 0x5820fa1e3158154641adb2c28a8954, - 0x03ce0301512be13c0317fb679e6348, - 0x13ec0af966303ca69b6f7fece6c2f4, - 0x58dcc592b80e4756a8d01224e6174f, - 0x73610ba199750de1e35cd658cbae92, - 0xeb1d49f1ecc3bf332b4048d978a46a, - 0x8c9ad13691accdce88ce1e6fda0bf5, - 0x425e80441351444e751cd86b97b464, - 0xd25a9581921c44fba102ed92a75658, - 0x698c73a7fc85fee22b1c7f04fb4600, - 0x70267fc50db236dfcf1e9405e25856, - 0x1a35b94cf56f801be96defed712afe, - 0xa3ecae6965b3bdee416f8d506f64fd, - 0xc875faf0fb4e4fa47ff65aba633529, - 0x3ca01bcaf3c4a5eee7fa8fdf0e98, - 0xa666b5d8c9f3217c412610ae91c862, - 0x517ccc77102fa7799e521ef0e6d4e7, - 0x7a50f7e553db75f0e0bd18d43bd622, - 0x98e8da14444b6cf3d2b91d84da3506, - 0xd1f5e4f7a725babc988cc7822c3d0a, - 0x09ee2caa2e6f8b02db37ebe2352624, - 0xd500b790312328a681b89b5de51b4f, - 0x5ce0ebb445d4c82c3ecf21134c00bf, - 0x83b6fafae79bc59f07e9b6802ef018, - 0x8efd78556c637f8af6299ace0cd790, - 0x5e99cf54d0f7e491cd72bcf20701fe, - 0x19f15da137fe1bbe44c5531300829a, - 0x0aae159f54317b49ec6b083292f57e, - 0x37c2bba2237a59a35556f2d351c728, - 0x7ec51821f03bde0c862e19e6ebe62c, - 0x2081, - ], - }; - - assert(verify_sha256_pss(sha256_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha256_pss_2048_exponent_3() { - let sha256_hash: [u8; 32] = - ryan_sha256_noir::sha256_var("Hello World! This is Noir-RSA".as_bytes(), 29); - let params: Params2048 = BigNumParams::new( - false, - [ - 0x1c961b234309c24fdab3f3e8a09da1, - 0xf4aa851a30a198c359f3779b6bf4e0, - 0x844034a1488c79edf31b1711a5e547, - 0xc83ad2f9b30cfcb6d5f7c152a78e62, - 0x16e97e0f8d8bad08da76d859c575c6, - 0x6a85158069b211820a596359d0dc47, - 0x1b834ed69818f1aa7d9944dee07b20, - 0x4d7148da361f1881cd4fd396ef46d2, - 0xc4cf36bbfa2781703699abf19a1e6d, - 0xca4bd632c8eb2c8051915c3530aef9, - 0x9cbfd5681aa95ade8eb256925d60ea, - 0x3b8153585ff5f1d7b1ed37ac709dc6, - 0x7d741c118fd653af3c21848f789ed8, - 0x7aefa65093c124e46405849ca82ad1, - 0xf9dbb9414e8eb849e2532d3f55d0b9, - 0x35aeee862ac76c20be58527220f6a, - 0xa3b6f81f07963c34ff0168634f8a99, - 0xc4, - ], - [ - 0xaf8e2d749a5966b98ffa10ea071d41, - 0x83704b0ef8ae71e3f1a7d24d871556, - 0x82903be42859c5bd5cbb935d1097fb, - 0x5bdc4e1e26670ed73580e2c8c144c1, - 0xce5178ff7019c4a6c0a2743ab2fae1, - 0xfd9ba73654ecf2020bdfa6ed9dc777, - 0x9ba95e3e7551ee261a4f10eca35f05, - 0x9e09b71274e5df10e06a6ce6319c3f, - 0xb14781efad91be0888f5150771eea5, - 0x15d2f490d6ba3cf25ad91e5e2539b0, - 0x7887aca3df2194cdbed904e6d42977, - 0xb797f21802a052c11e5c205bcb7d21, - 0x94d15b35eaf46e2fe69f2b60c02922, - 0x73814f1d160107a3ff1081b0cd1fea, - 0xaa4c31b61839c41980a8bb9c922a0c, - 0x123cc9f0ad08747529171a2e286eb6, - 0x7a8b658fe4e9b448debf21d8ea0cc0, - 0x14d4, - ], - ); - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x091a8c417287e046ec96c62b5ac66f, - 0xbe71db0fe3122ea5624e8e7a0a72dc, - 0xf35e5f3537c0ad0e938fdedd454de9, - 0xd53c652cc3aac5d11fe6f5bc7ec536, - 0x5d6869f0dd8b00697743f956b9b112, - 0x5d46286274a1128a8fe0d96e859837, - 0x951ee9dcb59dacebba972e9b9d7cfd, - 0xd22245a462bff840a882f6869689a5, - 0xcf7605b64a20dc2c3e6d5ceb88a03a, - 0x7831aa25052c11411c3e5bdbe7dc10, - 0x8e3bce799814987c984a2cc0e5d283, - 0x7fdb0ce6e413e0f32742f4652f14a2, - 0xa896a360bd70243209390e00761c57, - 0x0d326051ac677371678f92bd182f13, - 0xfcc593faaa9f45448ab756d70def, - 0x2fd6d46ec8d25a6648dadf8246daf0, - 0xe4aea2700222e610c1d94d82dd0f52, - 0x9b, - ], - }; - - assert(verify_sha256_pss(sha256_hash, signature, 3)); - } - - // Test an unusual key length that is not a multiple of 8 - /*#[test] -fn test_verify_sha256_pss_1964() { - let sha256_hash: [u8; 32] = sha256::sha256_var("Hello World! This is Noir-RSA".as_bytes(), 29); - let params: Params1964 = BigNumParams::new( - false, - [ - 0x75ac0d9987aebebd25983ab5a48fdf, - 0xae0a5ffc69f51e789ea8f90a72745b, - 0x9b8c92fb6ea3ca021a894ae52025f1, - 0x50de84cce0d856376083aa1785fd38, - 0xa912e3aabd4191e143128ce89e2086, - 0xcf361d0e7f4fb458b950ca7f58414e, - 0xe27bbefff3820e512b05a07d2d7e1c, - 0x7a2fd42d837098a67f056f1b15ed33, - 0x4ebeddd5d6fde42dc68ba5bb2a3732, - 0x2d1cbcf87c37b430c33b04aa35ce2b, - 0x9e9cd702ef1e7191c78e712ac6e151, - 0x9aef318e4318c313c0cf0c71ba378b, - 0xc1cd2e631f327acf58dca9f4e63bfd, - 0xc828e43ce8acda48fa1fff12de4df4, - 0x2d91364c2a898031a0ea615c82fe50, - 0x3fed935e1e73af131b48aafef030d7, - 0xc278be706ab, - ], - [ - 0xd4343ba7542877db4a663c12d159c, - 0xb7f3ebb5e9a7e46abb5fa5ebebf068, - 0x6f2ab6c72bbdcd87bf3cd5343f7059, - 0xa437eae960f2ac5714f7a35b803598, - 0xae01beec10904488485933615d62b6, - 0xf9509a6004d765dfa27536888f2757, - 0x57dbdd558fa8831a632849dbaecdfa, - 0xe7c4027a23af2ef309461db1f95629, - 0x388a2b780c78da825692f1cec5055e, - 0xd064ac53ec3c505b8e8e25b9350ce7, - 0x529b1374876a3bbf8e83e5d239cd69, - 0x7206c8bf4a0d11655219207de991b4, - 0x5fe1135077b5b760d31bdbfcb4f698, - 0xdb00d1d10cdb6c91c0f93f4b1a18c8, - 0x8329224ca1e3c5ef415cb1629f82d8, - 0xecca0fb0c3e52adfd165bbf85b34eb, - 0x150fec084e187, - ], - ); - let signature: RBN1964 = RuntimeBigNum { - params, - limbs: [ - 0xbd4bab3d5a9af46cac40fc2f6c9547, - 0xd3e04f0b8e833f1e80a4022684694f, - 0xbb4267e4fc29ec83dc8398dc547fca, - 0xba625b4fdf379883f6ccabede3574a, - 0xc9736193ab3cc0d1ef8ea63fdba46f, - 0x72dc058e8abcbe15ed09e97c1bb58a, - 0x98d8c915cb9447bcce3bbfc0f92032, - 0x9a0778461e9dec09e41c0ea354a41f, - 0xe4a6b80a5f62abf93268cde64b5e9c, - 0xd36dc0ccfdc6d9d8e8a939a3e762d0, - 0x1b2593bff17ff433ee20f1a60c6861, - 0x78115ebfd2484df0b59abfa3222e79, - 0x7693ac9aa8acfb4b5379c0adbcb7d1, - 0xd76979aa97b41f1f58c65ad896f1cf, - 0xe1f7c4fa2dc6cbe0162be9adb01c14, - 0x5f5a8f5b9ca6fe12c4fe3c00795f10, - 0x8b4a98cedd, - ], - }; - - assert(verify_sha256_pss(sha256_hash, signature, 65537)); -}*/ - - // Test an edge case where the key length in bytes is greater than the encoded message length - #[test] - fn test_verify_sha256_pss_1025() { - let sha256_hash: [u8; 32] = - ryan_sha256_noir::sha256_var("Hello World! This is Noir-RSA".as_bytes(), 29); - let params: Params1025 = BigNumParams::new( - false, - [ - 0xf278b138628000b2652c779e852235, - 0x6d0676977e76ef0429002673ce9be2, - 0x6cfc0db4d97f20ad2a1ad48cd899a0, - 0x64024c19a1b1540e23ba4531e677f2, - 0x3696125dd256ffed9567fccff06be6, - 0x2dc09476b0c7629eed3c7c2cb591e3, - 0x2e007f2f978504c5cfea0ec51ba0e9, - 0x84ec9458cc6d0e95e06a7f404f26b4, - 0x174fd186dca48668a, - ], - [ - 0x7ab08c63fb6eeee6204bd814d3134a, - 0x20d51c551c06e8ae471cc43e84d131, - 0x5eac3eae8238c6c2c37c1ce5bec407, - 0xcff61632bd2ea6bc1dc8da002aa0c5, - 0x801c1e85137856c4a6dc8c25078a59, - 0x5ce8ee248cac12cbc3faa426acd58b, - 0xe72384bb8302bbb78a3766fc61c5f0, - 0x6ea716c0a657933b91b2d488b29cec, - 0x2bed1ff958b58c194c, - ], - ); - - let signature: RBN1025 = RuntimeBigNum { - params, - limbs: [ - 0xa90e06eff7cbd20dd9c1241fe89290, - 0x9ff719ce8f34229cd248e1f0ef4246, - 0xd1d032dbf236cd711aa4fb49f0c71f, - 0x454abf136ae14c7617df3b4d505e08, - 0x45f30ac2c023205d35803f114f8ee3, - 0xc8b1265c786d6da808ab31d35795a1, - 0x1f75005a85f3636b099c58edd9fb8e, - 0xac251bf9bb342b551c0f5c80449a3f, - 0x03e2bc114292962b, - ], - }; - - assert(verify_sha256_pss(sha256_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha1_pkcs1v15_2048() { - let sha1_hash: [u8; 20] = sha1::sha1_var(BoundedVec::from_parts( - "Hello World! This is Noir-RSA".as_bytes(), - 29, - )); - - let params: Params2048 = BigNumParams::new( - false, - [ - 0x156ceaf444d8819f2aedf0ba175481, - 0xd3bf95380882ed1e760191e383dc84, - 0x8585e65def5c89b3b3aeab9ceb6c80, - 0xf215a93f61d5165db91d88a871368c, - 0x5274e088a95fb4053f26fcc5619e6d, - 0xf4494a491b66f30025ee633bed7a72, - 0x801bdf85598a082dbac2b26a4fbff9, - 0x9cd2905057dcca8c319d294785aa89, - 0xb155d5581ec0bfd4096e6878b3bc25, - 0xa0cfdf3decd16f8dde113e85a38c7b, - 0x9452a725f9f2f3e82ebef589345c23, - 0x1984df6bd68eaf0cc88b42b166ab6c, - 0xff925851486b26af0a896eae9c7fe9, - 0xe6fd92b72a2381389820a8ab283ff3, - 0xbd5a35556d716ba8685d106a944555, - 0xd9102f1ca16442372df5234fc4c23, - 0xae1aa56a4a4e1b155af1ac4fbef88a, - 0xdc, - ], - [ - 0x8ad3c9e65e7035db6d57a4182a4fb2, - 0x9df5db4eabb63cb8306ba17ab7d99, - 0x4177c0f5014aa2717306987d9ff827, - 0xb35faed8cc169c33eecfac2341d47d, - 0xff5faf8dbca65f1431a5d94d3a6d60, - 0xbd49ab8984a0739a666a81bcf41f4, - 0xb97ef986aa48a3f9c5160b1a9165c5, - 0x3b34d06a7867dc8c0e9411bb389f30, - 0x66ccff351294c073811e0e018e0917, - 0x4bb0ee68c1f5ddebb71a9dd3a6df38, - 0x29d2d550ec2d549320fec501d71108, - 0x6609e5236bb550a30e29378259ed01, - 0x4c33e3f52407cc796ba41acfaa3007, - 0x6e6ec514bb4f26c0ac197aa2f995f2, - 0x47967368b344f7c4fe0e84bdddc040, - 0x1dc9219753dbeb4aa003c81b210e0e, - 0x90dbe39955df1d4aa7c6efce2a8b3d, - 0x128f, - ], - ); - - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x1999f7717a7fd287d0b3e2d66a3437, - 0xc8fb6805554123679c362e6f002aae, - 0x3facdc5f1def4f49606b908e2a2538, - 0xc05aa4965a11190493a6f4e7fd5984, - 0x1672f3416fb95821efcb5375f1779e, - 0x2f81eb13f1894268f4acb1b0ae7513, - 0x15d997bac63df6624c2603e93cb0fa, - 0x536c959eea6cb9fc3980b86d9877b7, - 0x4296d1c42936c208b6ae13cd06d60b, - 0x39144ec79fc42ccc160b14c8b793e4, - 0xc40a783835d9df4c5f69ba68faaa, - 0xde2af88216d83b8136f094d8945b95, - 0x4ecac07a39171bd9a01383a4919924, - 0x737d8ffc839f4a503c431c507ba5f3, - 0x844f4957cf4b01c277f67a7591b7f5, - 0x0291a8afc7cda7e4c6e73e011c181f, - 0x7afcd49577ffbc75fbe9a2e2959b82, - 0x83, - ], - }; - - assert(verify_sha1_pkcs1v15(sha1_hash, signature, 65537)); - } - - #[test] - fn test_verify_sha1_pss_2048() { - let sha1_hash: [u8; 20] = sha1::sha1_var(BoundedVec::from_parts( - "Hello World! This is Noir-RSA".as_bytes(), - 29, - )); - let params: Params2048 = BigNumParams::new( - false, - [ - 0x8076ee27cf6ed266e737de20b03e47, - 0xbd07415cda0752a917b4f40d19c992, - 0xd473ccfa4dc8a5690c17eceab674d4, - 0xdf2645d4e31531b5e68d7b30152182, - 0xe4e6d87d9b3222f56ddc48b46dc544, - 0x587c5d66e6970f42fe18afa99b5e5b, - 0x30261d8162c75fe7ba96ab0c2a6dd3, - 0xdc69073390846c7fb3c98c9c316d60, - 0x4b6a2bc2c1e5131129539c38b0ac3b, - 0xf05187e8d7cf34d2c1685409173080, - 0x2d26be5b0d792a3d92b7d4062b3d44, - 0x4eb7f21f6c4e3df8d2829f6b3e6eaa, - 0x9f1cd4d18bd53d4bbcf804651435f3, - 0x3d266b2f1223e08dd2159d58cb48d4, - 0x873625d48c8244c51924bfdee0c6ac, - 0xfcbf5c61a9d3cf2d0e13686af8d0de, - 0xb4345e8b5be7510698390901722861, - 0xba, - ], - [ - 0x51b40d9d6a288a5396a16f9fc85f2a, - 0xbc36a9bf43ffceed626f118da3b290, - 0xdcff05073f93178b589ab93edcfa9d, - 0x42fe8b2c11fb9eb89432cd017ecae3, - 0x7c74c2b03dc0a6ef97319821e6adaa, - 0xf35c6951909aa944366d8e5f8f435f, - 0x211b51cea0e9e9db01a1803ff9d995, - 0xe9632ae2bbff5ecfb13344716976aa, - 0x5ac98d1f7f9796c5f4360a6c53c0ac, - 0x21cad5d27ccd949ab83384e613df0f, - 0x7305d4a53c3121804a7e563663ac19, - 0x42f7f8514dc823f5cec8029950f51d, - 0x88af0d59283ad9e8ceadd7275f9665, - 0xe377f531eb845e3ae55cb1f4f00845, - 0x863da2aa3bd54edc8b6da777626340, - 0xe92dc9d46715752498a8eda776a039, - 0x401e4c6793f0bc7f5da805da5cd5bb, - 0x15f0, - ], - ); - let signature: RBN2048 = RuntimeBigNum { - params, - limbs: [ - 0x835c0b9302499888acedea4013ec92, - 0xe1f4b56b2ca0ad8c1ee3b8a9a85d93, - 0x5d4fecc54034eb1091ca9fc28e3ff1, - 0xab316868780469b1621c789b8d8b75, - 0x13205cae60d93b387ef282c901bb, - 0x776e846d321b59b584c6de6ae6da18, - 0x6170c33330baeaee6a3de84e32f031, - 0x3862d9f28a50c32f0f09a6e5e60560, - 0x83e54c8d5a9522e5addc4cb35078b1, - 0xf4cd91425b0b042fb1cbb81d0ce6d6, - 0x33c49780bb4c00637bfd9f5de1d1cc, - 0xcbd14e26c78a769ff0e47854ff9d72, - 0x459db8d780c5287c894d8d419ec583, - 0x19909716db20e09223fbc169d58ed4, - 0x62efd0331023145d761b8568fc93c9, - 0xcac052c722d08645d4ad31464f665a, - 0x33c6a0e25cd27dbfd1d15fc2197aa5, - 0x89, - ], - }; - - assert(verify_sha1_pss(sha1_hash, signature, 65537)); - } - -} diff --git a/noir-examples/noir-passport-examples/noir_rsa/src/types.nr b/noir-examples/noir-passport-examples/noir_rsa/src/types.nr deleted file mode 100644 index 763d4270..00000000 --- a/noir-examples/noir-passport-examples/noir_rsa/src/types.nr +++ /dev/null @@ -1,14 +0,0 @@ -use bignum::params::BigNumParams; -use bignum::RuntimeBigNum; - -pub type Params1024 = BigNumParams<9, 1024>; -pub type Params1025 = BigNumParams<9, 1025>; -pub type Params1964 = BigNumParams<17, 1946>; -pub type Params2048 = BigNumParams<18, 2048>; -pub type Params4096 = BigNumParams<35, 4096>; - -pub type RBN1024 = RuntimeBigNum<9, 1024>; -pub type RBN1025 = RuntimeBigNum<9, 1025>; -pub type RBN1964 = RuntimeBigNum<17, 1946>; -pub type RBN2048 = RuntimeBigNum<18, 2048>; -pub type RBN4096 = RuntimeBigNum<35, 4096>; diff --git a/noir-examples/noir-passport-examples/passport_validity_check/src/lib.nr b/noir-examples/noir-passport-examples/passport_validity_check/src/lib.nr index 309ea452..80b7793c 100644 --- a/noir-examples/noir-passport-examples/passport_validity_check/src/lib.nr +++ b/noir-examples/noir-passport-examples/passport_validity_check/src/lib.nr @@ -81,6 +81,7 @@ pub fn check_passport_validity(passport_validity_contents: PassportValidityConte passport_validity_contents.dsc_rsa_exponent, passport_validity_contents.signed_attributes, passport_validity_contents.signed_attributes_size as u32, + 0 )); // --- DSC certificate signature check --- @@ -101,6 +102,7 @@ pub fn check_passport_validity(passport_validity_contents: PassportValidityConte passport_validity_contents.csc_rsa_exponent, passport_validity_contents.dsc_cert, // This is `data_to_sign`, i.e. the message passport_validity_contents.dsc_cert_len, + 0 )); } diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/commitment/common/src/lib.nr b/noir-examples/noir-passport-examples/zkpassport_libs/commitment/common/src/lib.nr index 9d74e413..8f82b387 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/commitment/common/src/lib.nr +++ b/noir-examples/noir-passport-examples/zkpassport_libs/commitment/common/src/lib.nr @@ -5,11 +5,30 @@ pub global CSC_CERT_TYPE: u8 = 1; pub global DSC_CERT_TYPE: u8 = 2; pub fn calculate_scoped_nullifier( - private_nullifier: Field, + salted_private_nullifier: utils::types::SaltedValue, service_scope: Field, service_subscope: Field, + nullifier_secret: Field, ) -> Field { - Poseidon2::hash([private_nullifier, service_scope, service_subscope], 3) + if salted_private_nullifier.value == 0 { + // If the private nullifier value is 0, it means it is hidden behind its salted hash + // inside the circuit, so we just return 0 making this proof not usable to derive + // the scoped nullifier + 0 + } + // A nullifier secret set to 0 means it should be ignored and the nullifier should be computed without it + // Otherwise, the nullifier should be computed with the secret + else if nullifier_secret != 0 { + Poseidon2::hash( + [salted_private_nullifier.value, service_scope, service_subscope, nullifier_secret], + 4, + ) + } else { + Poseidon2::hash( + [salted_private_nullifier.value, service_scope, service_subscope], + 3, + ) + } } /// Only used for testing purposes for now @@ -195,20 +214,18 @@ pub fn hash_salt_country_tbs( Poseidon2::hash(result, 2 + ((TBS_MAX_SIZE + 30) / 31)) } -pub fn hash_salt_dg1_private_nullifier( - salt: Field, - dg1: [u8; N], - private_nullifier: Field, +pub fn hash_salt_dg1_private_nullifier( + salted_dg1: utils::types::SaltedValue<[u8; 95]>, + salted_expiry_date: utils::types::SaltedValue, + salted_private_nullifier: utils::types::SaltedValue, ) -> Field { - let mut result: [Field; 2 + ((N + 30) / 31)] = [0; 2 + ((N + 30) / 31)]; - result[0] = salt; + let mut hash_inputs: [Field; 3] = std::mem::zeroed(); - let packed_dg1: [Field; (N + 30) / 31] = pack_be_bytes_into_fields::(dg1); - for i in 0..((N + 30) / 31) { - result[1 + i] = packed_dg1[i]; - } - result[1 + ((N + 30) / 31)] = private_nullifier; - Poseidon2::hash(result, 2 + ((N + 30) / 31)) + hash_inputs[0] = salted_dg1.get_hash(); + hash_inputs[1] = salted_expiry_date.get_hash(); + hash_inputs[2] = salted_private_nullifier.get_hash(); + + Poseidon2::hash(hash_inputs, 3) } pub fn calculate_private_nullifier( diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/commitment/integrity-to-disclosure/src/lib.nr b/noir-examples/noir-passport-examples/zkpassport_libs/commitment/integrity-to-disclosure/src/lib.nr index d7d84794..725ffd2e 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/commitment/integrity-to-disclosure/src/lib.nr +++ b/noir-examples/noir-passport-examples/zkpassport_libs/commitment/integrity-to-disclosure/src/lib.nr @@ -1,7 +1,9 @@ use common::{ - calculate_private_nullifier, get_country_from_dg1, - hash_salt_country_signed_attr_dg1_e_content_private_nullifier, hash_salt_dg1_private_nullifier, + get_country_from_dg1, + hash_salt_country_signed_attr_dg1_e_content_private_nullifier, + hash_salt_dg1_private_nullifier }; +use utils::{get_expiry_date_from_mrz, types::SaltedValue}; /* ############################################################ @@ -28,14 +30,14 @@ comm_out `H(salt, dg1, private_nullifier)` pub fn commit_to_disclosure( comm_in: Field, salt_in: Field, - salt_out: Field, - dg1: [u8; 95], + salted_dg1: SaltedValue<[u8; 95]>, + expiry_date_salt: Field, signed_attributes: [u8; SA_SIZE], signed_attributes_size: Field, e_content: [u8; ECONTENT_SIZE], - private_nullifier: Field, + salted_private_nullifier: SaltedValue, ) -> Field { - let country = get_country_from_dg1(dg1); + let country = get_country_from_dg1(salted_dg1.value); assert( comm_in == hash_salt_country_signed_attr_dg1_e_content_private_nullifier( @@ -43,15 +45,20 @@ pub fn commit_to_disclosure( country, signed_attributes, signed_attributes_size, - dg1, + salted_dg1.value, e_content, - private_nullifier, + salted_private_nullifier.value, ), "Commitment from 2nd subproof doesn't match in 3rd subproof", ); - // println(f"comm_in: {comm_in}"); - // println(f"private_nullifier: {private_nullifier}"); - let comm_out = hash_salt_dg1_private_nullifier(salt_out, dg1, private_nullifier); - // println(f"comm_out: {comm_out}"); + + let salted_expiry_date = + SaltedValue::from_value(expiry_date_salt, get_expiry_date_from_mrz(salted_dg1.value)); + + let comm_out = hash_salt_dg1_private_nullifier( + salted_dg1, + salted_expiry_date, + salted_private_nullifier, + ); comm_out } diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/commitment/scoped-nullifier/src/lib.nr b/noir-examples/noir-passport-examples/zkpassport_libs/commitment/scoped-nullifier/src/lib.nr index 9c5fec16..717026a1 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/commitment/scoped-nullifier/src/lib.nr +++ b/noir-examples/noir-passport-examples/zkpassport_libs/commitment/scoped-nullifier/src/lib.nr @@ -1,5 +1,11 @@ -use common::{calculate_scoped_nullifier, hash_salt_dg1_private_nullifier}; -use utils::get_issuing_country_from_mrz; +use common::{hash_salt_dg1_private_nullifier, calculate_scoped_nullifier}; +use utils::{ + constants::{ + NON_SALTED_MOCK_NULLIFIER, NON_SALTED_NULLIFIER, SALTED_MOCK_NULLIFIER, SALTED_NULLIFIER, + }, + get_issuing_country_from_mrz, + types::{DG1Data, MRZExpiryDate, SaltedValue}, +}; // The ZKR (or Zero Knowledge Republic) is a mock country used for testing purposes global ZKR_COUNTRY_CODE_BYTES: [u8; 3] = [90, 75, 82]; @@ -29,27 +35,56 @@ scoped_nullifier `H(private_nullifier, service_scope, service_subscope)` */ pub fn nullify( comm_in: Field, - salt: Field, - dg1: [u8; 95], - private_nullifier: Field, + salted_dg1: SaltedValue, + salted_expiry_date: SaltedValue, + salted_private_nullifier: SaltedValue, service_scope: Field, service_subscope: Field, -) -> Field { + nullifier_secret: Field, +) -> (Field, Field) { assert( - comm_in == hash_salt_dg1_private_nullifier(salt, dg1, private_nullifier), + comm_in + == hash_salt_dg1_private_nullifier( + salted_dg1, + salted_expiry_date, + salted_private_nullifier, + ), "Commitment from 3rd subproof doesn't match in disclosure proof", ); - let mut scoped_nullifier = - calculate_scoped_nullifier(private_nullifier, service_scope, service_subscope); - let issuing_country = get_issuing_country_from_mrz(dg1); + let mut scoped_nullifier = calculate_scoped_nullifier( + salted_private_nullifier, + service_scope, + service_subscope, + nullifier_secret, + ); + // Determine the nullifier type based on the secret + let mut nullifier_type = if nullifier_secret != 0 { + // Set the nullifier type to the salted nullifier type + // as the secret was used to salt the nullifier + SALTED_NULLIFIER + } else { + // Set the nullifier type to the non-salted nullifier type + // as the secret was not used to salt the nullifier + NON_SALTED_NULLIFIER + }; + let issuing_country = get_issuing_country_from_mrz(salted_dg1.value); // Doesn't matter if we already calculated the scoped nullifier above // cause it's ZK all branches will be evaluated anyway if issuing_country == ZKR_COUNTRY_CODE_BYTES { - // Set the scoped nullifier to 1 to indicate the issuing country is not a real one + // Set the nullifier type to one of the mock nullifier types + // to indicate the issuing country is not a real one // and prevent the use of these proofs in production // Note: ZKPassport's registries on mainnet blockchains will not include // the ZKR certificates but still this distinction can be useful for testnets/devnets - scoped_nullifier = 1; + if nullifier_secret != 0 { + // Set the nullifier type to the salted mock nullifier type + // as the secret was used to salt the nullifier + nullifier_type = SALTED_MOCK_NULLIFIER; + } else { + // Set the nullifier type to the non-salted mock nullifier type + // as the secret was not used to salt the nullifier + nullifier_type = NON_SALTED_MOCK_NULLIFIER; + } } - scoped_nullifier + (scoped_nullifier, nullifier_type) } diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/data-check/integrity/src/lib.nr b/noir-examples/noir-passport-examples/zkpassport_libs/data-check/integrity/src/lib.nr index 5d85dcf4..24bd2da8 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/data-check/integrity/src/lib.nr +++ b/noir-examples/noir-passport-examples/zkpassport_libs/data-check/integrity/src/lib.nr @@ -1,7 +1,13 @@ use sha512::{sha384, sha512}; -use utils::is_id_card; use sha256::sha256_var; - +use utils::{ + check_zero_padding, + constants::{ID_CARD_DG1_LENGTH, PASSPORT_DG1_LENGTH}, + find_subarray_index, + is_id_card, + is_subarray_in_array, + types::{DG1Data, EContentData}, +}; /** * Computes the hash of the MRZ (Data Group 1) and checks it is the same as the one * provided in the SOD file of the ID and then use it along with the rest of the @@ -128,3 +134,70 @@ pub fn check_integrity_of_data_sha512( assert(computed_final_hash[i] == signed_attributes[signed_attributes_size - 64 + i]); } } + +pub fn get_dg1_size(dg1: DG1Data) -> u32 { + if is_id_card(dg1) { + ID_CARD_DG1_LENGTH + } else { + PASSPORT_DG1_LENGTH + } +} + +/** +* Computes the hash (using SHA2-256) of the first data group (containing the MRZ) and checks it is the same as the one +* included in eContent at the offset provided (along with the rest of the data group hashes) +*/ +pub fn check_dg1_sha256(dg1: DG1Data, e_content: EContentData, e_content_size: u32) { + check_zero_padding(e_content, e_content_size); + + // For passports we ignore the last padding characters + let dg1_size: u64 = get_dg1_size(dg1) as u64; + + // We only need to recompute the hash of the MRZ (or more accurately that of Data Group 1) + // within the circuit as this is the only data group we use to build the proof (age, country, etc.) + let dg1_hash = sha256_var(dg1, dg1_size); + + // Find the offset of the hash of dg1 in e_content + let dg1_offset_in_e_content = find_subarray_index(dg1_hash, e_content); + // Check that the hash of dg1 is in the e_content, we use the actual size rather than generic size + // of econtent to ignore the padding bytes at the end + assert( + dg1_offset_in_e_content + dg1_hash.len() <= e_content_size, + "Hash of dg1 not found in eContent", + ); +} +pub fn check_dg1_hash_within_sod( + dg1: [u8; 95], + dg1_padded_length: u64, + econtent: [u8; 200], + econtent_len: u32, + dg1_hash_offset: u32, +) { + // Check zero padding for econtent + check_zero_padding(econtent, econtent_len); + + let dg1_hash = sha256_var(dg1, dg1_padded_length); + + // The DG1 hash is located at the start of the SOD + // (offset is always 0 for DG1) + for i in 0..32 { + assert(dg1_hash[i] == econtent[dg1_hash_offset + i]); + } +} +/** +* Computes the hash (using SHA2-256) of eContent (containing the hashes of the data groups) and checks it is the same as the one +* included in the signed_attributes, which is the message signed by the Document Signing Certificate (DSC) +*/ +pub fn check_signed_attributes_sha256( + signed_attributes: [u8; SA_SIZE], + e_content: EContentData, + e_content_size: u32, +) { + let computed_final_hash = sha256_var(e_content, e_content_size as u64); + + // Check that the computed final hash is in the signed attributes + assert( + is_subarray_in_array(computed_final_hash, signed_attributes), + "Computed final hash not found in signed attributes", + ); +} diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/data-check/tbs-pubkey/src/lib.nr b/noir-examples/noir-passport-examples/zkpassport_libs/data-check/tbs-pubkey/src/lib.nr index ef016b63..6da6d175 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/data-check/tbs-pubkey/src/lib.nr +++ b/noir-examples/noir-passport-examples/zkpassport_libs/data-check/tbs-pubkey/src/lib.nr @@ -11,20 +11,24 @@ pub fn verify_rsa_pubkey_in_tbs( assert(tbs_certificate[i + pubkey_offset] == dsc_pubkey[i]); } } - -pub fn verify_ecdsa_pubkey_in_tbs( - dsc_pubkey_x: [u8; DSC_KEY_SIZE], - dsc_pubkey_y: [u8; DSC_KEY_SIZE], - tbs_certificate: [u8; TBS_CERT_SIZE], - pubkey_offset: u32, +/// Check that an ECDSA public key x and y coord exists in a certificate TBS +pub fn verify_ecdsa_pubkey_in_tbs( + pubkey_x: [u8; PUBKEY_SIZE], + pubkey_y: [u8; PUBKEY_SIZE], + tbs: [u8; TBS_SIZE], ) { - // Check that the public key of the DSC is the same as the one in the TBS certificate. - // And since the TBS certificate is the data signed by the private key of the CSCA certificate - // we can make sure the DSC, which signed the data of the passport, has been signed by the - // root certificate of the issuing State (i.e. CSCA certificate) by verifying the signature below - for i in 0..DSC_KEY_SIZE { - assert(tbs_certificate[i + pubkey_offset] == dsc_pubkey_x[i]); - assert(tbs_certificate[i + pubkey_offset + DSC_KEY_SIZE] == dsc_pubkey_y[i]); + let pubkey_x_offset = utils::find_subarray_index(pubkey_x, tbs); + let pubkey_y_offset = utils::find_subarray_index(pubkey_y, tbs); + for i in 0..PUBKEY_SIZE { + assert( + tbs[i + pubkey_x_offset] == pubkey_x[i], + "Public key x coord of DSC not found in TBS", + ); + } + for i in 0..PUBKEY_SIZE { + assert( + tbs[i + pubkey_y_offset] == pubkey_y[i], + "Public key y coord of DSC not found in TBS", + ); } } - diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/partial-sha256/Nargo.toml b/noir-examples/noir-passport-examples/zkpassport_libs/partial-sha256/Nargo.toml new file mode 100644 index 00000000..bc302dba --- /dev/null +++ b/noir-examples/noir-passport-examples/zkpassport_libs/partial-sha256/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "partial_sha256" +type = "lib" +compiler_version = ">=1.0.0" + +[dependencies] +utils = { path = "../utils" } +poseidon = { tag = "v0.1.1", git = "https://github.com/noir-lang/poseidon" } diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/partial-sha256/src/lib.nr b/noir-examples/noir-passport-examples/zkpassport_libs/partial-sha256/src/lib.nr new file mode 100644 index 00000000..14b775cf --- /dev/null +++ b/noir-examples/noir-passport-examples/zkpassport_libs/partial-sha256/src/lib.nr @@ -0,0 +1,184 @@ +// Partial SHA256 implementation for splitting computation across circuits +// Based on RFC 6234, uses std::hash::sha256_compression for block processing + +use poseidon::poseidon2::Poseidon2; +use std::hash::sha256_compression; + +pub global BLOCK_SIZE: u32 = 64; +pub global SHA256_IV: [u32; 8] = [ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, +]; +pub type SHA256State = [u32; 8]; + +fn build_msg_block(msg: [u8; N], msg_start: u32, valid_bytes: u32) -> [u32; 16] { + let mut block: [u32; 16] = [0; 16]; + for i in 0..16 { + let byte_idx = msg_start + i * 4; + let mut word: u32 = 0; + for j in 0..4 { + word = word << 8; + let idx = byte_idx + j; + if idx < msg_start + valid_bytes { + word = word + msg[idx] as u32; + } + } + block[i] = word; + } + block +} + +fn state_to_hash(state: SHA256State) -> [u8; 32] { + let mut hash: [u8; 32] = [0; 32]; + for i in 0..8 { + let word = state[i]; + hash[i * 4] = ((word >> 24) & 0xff) as u8; + hash[i * 4 + 1] = ((word >> 16) & 0xff) as u8; + hash[i * 4 + 2] = ((word >> 8) & 0xff) as u8; + hash[i * 4 + 3] = (word & 0xff) as u8; + } + hash +} + +/// Process first N bytes (must be multiple of 64), returns intermediate SHA256 state +pub fn sha256_start(msg: [u8; N]) -> SHA256State { + assert(N % BLOCK_SIZE == 0, "Message size must be a multiple of 64 bytes"); + let num_blocks = N / BLOCK_SIZE; + let mut state = SHA256_IV; + + for i in 0..num_blocks { + let block = build_msg_block(msg, i * BLOCK_SIZE, BLOCK_SIZE); + state = sha256_compression(block, state); + } + state +} + +/// Continue processing from previous state (msg_size must be multiple of 64) +pub fn sha256_continue( + state: SHA256State, + msg: [u8; N], + msg_size: u32, +) -> SHA256State { + assert(msg_size % BLOCK_SIZE == 0, "Message size must be a multiple of 64 bytes"); + assert(msg_size <= N, "Message size exceeds buffer size"); + + let max_blocks = N / BLOCK_SIZE; + let mut current_state = state; + + for i in 0..max_blocks { + if (i * BLOCK_SIZE) < msg_size { + let block = build_msg_block(msg, i * BLOCK_SIZE, BLOCK_SIZE); + current_state = sha256_compression(block, current_state); + } + } + current_state +} + +/// Finalize SHA256 hash with RFC 6234 padding (0x80, zeros, 64-bit length) +/// msg_size must be < 64 (use sha256_continue for full blocks first) +pub fn sha256_finalize( + state: SHA256State, + msg: [u8; N], + msg_size: u32, + total_msg_size: u32, +) -> [u8; 32] { + assert(msg_size <= N, "Message size exceeds buffer size"); + assert(msg_size < BLOCK_SIZE, "Use sha256_continue for full blocks first"); + + let mut current_state = state; + let mut final_block: [u32; 16] = [0; 16]; + + for i in 0..16 { + let byte_idx = i * 4; + let mut word: u32 = 0; + for j in 0..4 { + word = word << 8; + let idx = byte_idx + j; + if idx < msg_size { + word = word + msg[idx] as u32; + } else if idx == msg_size { + word = word + 0x80; + } + } + final_block[i] = word; + } + + let total_bits = total_msg_size as u64 * 8; + + if msg_size + 9 > BLOCK_SIZE { + current_state = sha256_compression(final_block, current_state); + let mut length_block: [u32; 16] = [0; 16]; + length_block[14] = (total_bits >> 32) as u32; + length_block[15] = (total_bits & 0xffffffff) as u32; + current_state = sha256_compression(length_block, current_state); + } else { + final_block[14] = (total_bits >> 32) as u32; + final_block[15] = (total_bits & 0xffffffff) as u32; + current_state = sha256_compression(final_block, current_state); + } + + state_to_hash(current_state) +} + +/// Commits to SHA256 state: Poseidon2(salt, state[0..7], processed_bytes) +pub fn commit_to_sha256_state( + salt: Field, + state: SHA256State, + processed_bytes: u32, +) -> Field { + let mut hash_inputs: [Field; 10] = std::mem::zeroed(); + hash_inputs[0] = salt; + for i in 0..8 { + hash_inputs[1 + i] = state[i] as Field; + } + hash_inputs[9] = processed_bytes as Field; + Poseidon2::hash(hash_inputs, 10) +} + +pub fn verify_sha256_state_commitment( + comm_in: Field, + salt: Field, + state: SHA256State, + processed_bytes: u32, +) { + let expected = commit_to_sha256_state(salt, state, processed_bytes); + assert(comm_in == expected, "SHA256 state commitment verification failed"); +} + +/// Commits to SHA256 state + data: Poseidon2(salt, state[0..7], processed_bytes, data_commitment) +pub fn commit_to_sha256_state_and_data( + salt: Field, + state: SHA256State, + processed_bytes: u32, + data_commitment: Field, +) -> Field { + let mut hash_inputs: [Field; 11] = std::mem::zeroed(); + hash_inputs[0] = salt; + for i in 0..8 { + hash_inputs[1 + i] = state[i] as Field; + } + hash_inputs[9] = processed_bytes as Field; + hash_inputs[10] = data_commitment; + Poseidon2::hash(hash_inputs, 11) +} + +pub fn verify_sha256_state_and_data_commitment( + comm_in: Field, + salt: Field, + state: SHA256State, + processed_bytes: u32, + data_commitment: Field, +) { + let expected = commit_to_sha256_state_and_data(salt, state, processed_bytes, data_commitment); + assert(comm_in == expected, "SHA256 state+data commitment verification failed"); +} + +pub fn commit_to_data_chunk(salt: Field, data: [u8; N]) -> Field { + let packed: [Field; (N + 30) / 31] = utils::pack_be_bytes_into_fields::(data); + let mut hash_inputs: [Field; 1 + (N + 30) / 31] = std::mem::zeroed(); + hash_inputs[0] = salt; + for i in 0..((N + 30) / 31) { + hash_inputs[1 + i] = packed[i]; + } + Poseidon2::hash(hash_inputs, 1 + (N + 30) / 31) +} \ No newline at end of file diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/sig-check/rsa/Nargo.toml b/noir-examples/noir-passport-examples/zkpassport_libs/sig-check/rsa/Nargo.toml index 9bc69305..48f80911 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/sig-check/rsa/Nargo.toml +++ b/noir-examples/noir-passport-examples/zkpassport_libs/sig-check/rsa/Nargo.toml @@ -5,7 +5,7 @@ authors = ["Theo Madzou", "Michael Elliot"] compiler_version = ">=1.0.0" [dependencies] -rsa = { path = "../../../noir_rsa" } +rsa = { git = "https://github.com/zkpassport/noir_rsa", tag = "v0.9.2" } bignum = { git = "https://github.com/noir-lang/noir-bignum", tag = "v0.8.0"} utils = { path = "../../utils" } common = { path = "../common" } diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/sig-check/rsa/src/lib.nr b/noir-examples/noir-passport-examples/zkpassport_libs/sig-check/rsa/src/lib.nr index 4e6c08cc..feec8356 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/sig-check/rsa/src/lib.nr +++ b/noir-examples/noir-passport-examples/zkpassport_libs/sig-check/rsa/src/lib.nr @@ -17,6 +17,7 @@ pub fn verify_signature bool { assert( (SIG_BYTES == 768) @@ -37,16 +38,16 @@ pub fn verify_signature(msg_hash, signature, exponent) + verify_sha1_pss::<_, SIG_BYTES * 8>(msg_hash, signature, exponent, pss_salt_len) } else if (HASH_BYTE_SIZE == 32) { let msg_hash = sha256_and_check_data_to_sign(data_to_sign, data_to_sign_len); - verify_sha256_pss::<_, SIG_BYTES * 8>(msg_hash, signature, exponent) + verify_sha256_pss::<_, SIG_BYTES * 8>(msg_hash, signature, exponent, pss_salt_len) } else if (HASH_BYTE_SIZE == 48) { let msg_hash = sha384_and_check_data_to_sign(data_to_sign, data_to_sign_len); - verify_sha384_pss::<_, SIG_BYTES * 8>(msg_hash, signature, exponent) + verify_sha384_pss::<_, SIG_BYTES * 8>(msg_hash, signature, exponent, pss_salt_len) } else if (HASH_BYTE_SIZE == 64) { let msg_hash = sha512_and_check_data_to_sign(data_to_sign, data_to_sign_len); - verify_sha512_pss::<_, SIG_BYTES * 8>(msg_hash, signature, exponent) + verify_sha512_pss::<_, SIG_BYTES * 8>(msg_hash, signature, exponent, pss_salt_len) } else { false } @@ -68,3 +69,29 @@ pub fn verify_signature( + pubkey_bytes: [u8; SIG_BYTES], + sig_bytes: [u8; (((SIG_BYTES * 8) + 7) / 8)], + redc_param_bytes: [u8; SIG_BYTES + 1], + exponent: u32, + msg_hash: [u8; 32] // Pre-computed SHA256 hash +) -> bool { + assert( + (SIG_BYTES == 768) + | (SIG_BYTES == 512) + | (SIG_BYTES == 384) + | (SIG_BYTES == 256) + | (SIG_BYTES == 128), + "Only modulus of bit size 1024, 2048, 3072, 4096 and 6144 are supported", + ); + + let pubkey = + utils::pack_be_bytes_into_u128s::(pubkey_bytes); + let redc_param = utils::pack_be_bytes_into_u128s::(redc_param_bytes); + let params = BigNumParams::new(false, pubkey, redc_param); + + let signature = RuntimeBigNum::from_be_bytes(params, sig_bytes); + verify_sha256_pkcs1v15::<_, SIG_BYTES * 8>(msg_hash, signature, exponent) +} diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/utils/Nargo.toml b/noir-examples/noir-passport-examples/zkpassport_libs/utils/Nargo.toml index 6a9b8021..dc2db2c6 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/utils/Nargo.toml +++ b/noir-examples/noir-passport-examples/zkpassport_libs/utils/Nargo.toml @@ -3,3 +3,6 @@ name = "utils" type = "lib" authors = ["Theo Madzou", "Michael Elliot"] compiler_version = ">=1.0.0" + +[dependencies] +poseidon = { tag = "v0.1.2", git = "https://github.com/zkpassport/noir_poseidon2" } diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/constants.nr b/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/constants.nr new file mode 100644 index 00000000..0e613aa4 --- /dev/null +++ b/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/constants.nr @@ -0,0 +1,10 @@ +pub global SHA256_DIGEST_LENGTH: u32 = 32; +pub global PASSPORT_DG1_LENGTH: u32 = 93; +pub global ID_CARD_DG1_LENGTH: u32 = 95; +pub global YYMMDD_DATE_LENGTH: u32 = 6; + +// Nullifier types +pub global NON_SALTED_NULLIFIER: Field = 0; +pub global SALTED_NULLIFIER: Field = 1; +pub global NON_SALTED_MOCK_NULLIFIER: Field = 2; +pub global SALTED_MOCK_NULLIFIER: Field = 3; diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/lib.nr b/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/lib.nr index 7e2d91ab..bd1e5255 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/lib.nr +++ b/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/lib.nr @@ -5,6 +5,7 @@ */ pub mod tests; pub mod types; +pub mod constants; /** * The structure of the MRZ is well defined and standardized by the ICAO @@ -19,6 +20,7 @@ pub mod types; use types::{ DG1Data, MRZData, MRZName, MRZDOB, MRZYOB, MRZDocumentNumber, MRZNationality, MRZIssuingCountry, + MRZExpiryDate, }; // Index for the country of issuance of the passport @@ -332,6 +334,40 @@ pub fn pack_be_bytes_into_fields( + x: [u8; NUM_BYTES], +) -> [Field; NUM_FIELDS] { + let mut result = [0 as Field; NUM_FIELDS]; + let mut k = 0; + // Pack all fields in little-endian order + for field_index in 0..NUM_FIELDS { + let remaining_bytes = NUM_BYTES - k; + let chunk_size = if remaining_bytes > BYTES_PER_FIELD { + BYTES_PER_FIELD + } else { + remaining_bytes + }; + let mut limb: Field = 0; + // Pack bytes in little-endian order (reverse the chunk) + for j in 0..chunk_size { + limb *= 256; + limb += x[k + chunk_size - 1 - j] as Field; + } + k += chunk_size; + std::as_witness(limb); + result[field_index] = limb; + } + result +} + +pub fn pack_le_bytes_into_fields( + x: [u8; NUM_BYTES], +) -> [Field; (NUM_BYTES + BYTES_PER_FIELD - 1) / BYTES_PER_FIELD] { + pack_le_bytes_into_fields_internal::( + x, + ) +} + pub fn get_mrz_from_dg1(dg1: DG1Data) -> MRZData { let mut mrz: MRZData = [0 as u8; 90]; for i in 0..90 { @@ -581,6 +617,36 @@ pub fn get_document_number_id_card(mrz: MRZData) -> MRZDocumentNumber { ) } +/// Get the expiry date from the MRZ +/// +/// Conditionally calls the correct function based on the type of document +pub fn get_expiry_date_from_mrz(dg1: DG1Data) -> MRZExpiryDate { + let mrz = get_mrz_from_dg1(dg1); + if is_id_card(dg1) { + get_expiry_date_id_card(mrz) + } else { + get_expiry_date_passport(mrz) + } +} + +/// Get the expiry date from the MRZ for a passport +pub fn get_expiry_date_passport(mrz: MRZData) -> MRZExpiryDate { + get_array_slice( + mrz, + PASSPORT_MRZ_EXPIRY_DATE_INDEX, + PASSPORT_MRZ_EXPIRY_DATE_INDEX + 6, + ) +} + +/// Get the expiry date from the MRZ for an ID card +pub fn get_expiry_date_id_card(mrz: MRZData) -> MRZExpiryDate { + get_array_slice( + mrz, + ID_CARD_MRZ_EXPIRY_DATE_INDEX, + ID_CARD_MRZ_EXPIRY_DATE_INDEX + 6, + ) +} + /// Returns total TLV length (tag + length field + content) for any /// ASN.1 element using DER/BER **definite-length** encoding with a /// single-byte tag (tag number field < 31) diff --git a/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/types.nr b/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/types.nr index 001a11a4..06342e1c 100644 --- a/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/types.nr +++ b/noir-examples/noir-passport-examples/zkpassport_libs/utils/src/types.nr @@ -1,7 +1,14 @@ +use poseidon::poseidon2::Poseidon2; +use crate::pack_be_bytes_into_fields; + // DG1 types pub type DG1Data = [u8; 95]; pub type MRZData = [u8; 90]; +// Dates +pub type YYMMDDDate = [u8; 6]; +pub type MRZExpiryDate = YYMMDDDate; + // MRZ types pub type MRZName = [u8; 39]; pub type MRZNameIdCard = [u8; 30]; @@ -10,3 +17,128 @@ pub type MRZYOB = [u8; 2]; pub type MRZDocumentNumber = [u8; 9]; pub type MRZNationality = [u8; 3]; pub type MRZIssuingCountry = [u8; 3]; + +// Country code types +pub type Alpha3CountryCode = str<3>; +pub type Alpha2CountryCode = str<2>; + +// Hash digest types +pub type SHA1Digest = [u8; 20]; +pub type SHA224Digest = [u8; 28]; +pub type SHA256Digest = [u8; 32]; +pub type SHA384Digest = [u8; 48]; +pub type SHA512Digest = [u8; 64]; + +// eContent and SignedAttrs types +pub type EContentData = [u8; 200]; +pub type SignedAttrsData = [u8; 200]; + +/// This struct acts as a wrapper around a value, so it can be specified as either a clear value with +/// a provided salt for hashing or only as its salted hash if its clear value is not needed inside the circuit +pub struct SaltedValue { + pub salt: Field, + pub value: T, + pub hash: Field, +} + +impl Default for SaltedValue +where + T: Default, +{ + fn default() -> Self { + Self { salt: 0, value: T::default(), hash: 0 } + } +} + +impl SaltedValue +where + T: Default, + T: Eq, +{ + /// When the clear value is needed inside the circuit, use this method to create a salted value + pub fn from_value(salt: Field, value: T) -> Self { + assert(salt != 0, "Salt cannot be 0 when creating a salted value from a clear value"); + assert( + value != T::default(), + "Value cannot be the default value when creating a salted value from a clear value", + ); + Self { salt, value, hash: 0 } + } + + /// When the clear value is not needed and is better hidden, use this method to specify the hash only + pub fn from_hash(hash: Field) -> Self { + assert(hash != 0, "Hash cannot be 0 when creating a salted value from a hash"); + Self { salt: 0, value: T::default(), hash } + } +} + +impl SaltedValue { + /// Gets the salted hash of the value + /// If the hash is already specified, it will return the hash directly + /// Otherwise, it will compute the hash from the salt and value + pub fn get_hash(self) -> Field { + if self.hash != 0 { + assert_eq(self.salt, 0, "Salt must be 0 when hash is already specified"); + assert_eq(self.value, 0, "Value must be 0 when hash is already specified"); + self.hash + } else { + assert( + self.value != 0, + "Value must be non-zero when computing the hash from a clear value and its salt", + ); + assert( + self.salt != 0, + "Salt must be non-zero when computing the hash from a clear value and its salt", + ); + Poseidon2::hash([self.salt, self.value as Field], 2) + } + } +} + +impl SaltedValue { + /// Gets the salted hash of the value + /// If the hash is already specified, it will return the hash directly + /// Otherwise, it will compute the hash from the salt and value + pub fn get_hash(self) -> Field { + if self.hash != 0 { + assert_eq(self.salt, 0, "Salt must be 0 when hash is already specified"); + assert_eq(self.value, 0, "Value must be 0 when hash is already specified"); + self.hash + } else { + assert( + self.value != 0, + "Value must be non-zero when computing the hash from a clear value and its salt", + ); + assert( + self.salt != 0, + "Salt must be non-zero when computing the hash from a clear value and its salt", + ); + Poseidon2::hash([self.salt, self.value], 2) + } + } +} + +impl SaltedValue<[u8; N]> { + /// Gets the salted hash of the value + /// If the hash is already specified, it will return the hash directly + /// Otherwise, it will compute the hash from the salt and value + pub fn get_hash(self) -> Field { + if self.hash != 0 { + assert_eq(self.salt, 0, "Salt must be 0 when hash is already specified"); + assert_eq(self.value, [0; N], "Value must be zeroed when hash is already specified"); + self.hash + } else { + assert( + self.value != [0; N], + "Value must be non-zeroed when computing the hash from a clear value and its salt", + ); + assert( + self.salt != 0, + "Salt must be non-zero when computing the hash from a clear value and its salt", + ); + let packed_value: [Field; (N + 30) / 31] = + pack_be_bytes_into_fields::(self.value); + Poseidon2::hash([self.salt].concat(packed_value), (N + 30) / 31 + 1) + } + } +} \ No newline at end of file