diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9a208d7..be7bc94 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,7 +54,7 @@ jobs: with: repository: AztecProtocol/barretenberg path: barretenberg - ref: 87aeb375d7b434e0faf47abb79f97753ab760987 + ref: 209667624f706be9106acab2cc0f7bfbdc7fa793 - name: Setup Linux environment if: matrix.os == 'ubuntu-latest' diff --git a/README.md b/README.md index a74236c..4b49cbe 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ to install everything globally, you'll need: Linker provided by Clang, but might need to be installed via `apt install lld`. -4. `barretenberg` (preferably at commit `87aeb375d7b434e0faf47abb79f97753ab760987`) +4. `barretenberg` (preferably at commit `209667624f706be9106acab2cc0f7bfbdc7fa793`) Needs to be built and installed following the instructions [in the README](https://github.com/AztecProtocol/barretenberg#getting-started). Note that barretenberg has its own [dependencies](https://github.com/AztecProtocol/barretenberg#dependencies) that will need to be installed, such as `cmake` and `ninja`. diff --git a/build.rs b/build.rs index b73cfcd..cf859d5 100644 --- a/build.rs +++ b/build.rs @@ -80,8 +80,11 @@ fn main() -> Result<()> { .allowlist_function("acir_proofs_get_total_circuit_size") .allowlist_function("acir_proofs_init_proving_key") .allowlist_function("acir_proofs_init_verification_key") + .allowlist_function("acir_serialize_verification_key_into_field_elements") + .allowlist_function("acir_serialize_proof_into_field_elements") .allowlist_function("acir_proofs_new_proof") .allowlist_function("acir_proofs_verify_proof") + .allowlist_function("acir_proofs_verify_recursive_proof") .allowlist_function("pedersen_plookup_compress_fields") .allowlist_function("pedersen_plookup_compress") .allowlist_function("pedersen_plookup_commit") diff --git a/flake.lock b/flake.lock index 7c01326..5fffd69 100644 --- a/flake.lock +++ b/flake.lock @@ -10,11 +10,11 @@ ] }, "locked": { - "lastModified": 1682345890, - "narHash": "sha256-ZsInK9Iy81MaCugouU3ifa5Vw2GKlJK9MxCU/LF8bIw=", + "lastModified": 1684859506, + "narHash": "sha256-OqI5pg6yZLz9YRkRNky3Ezh2kWpwvCdKWPH6ad+DWFU=", "owner": "AztecProtocol", "repo": "barretenberg", - "rev": "87aeb375d7b434e0faf47abb79f97753ab760987", + "rev": "209667624f706be9106acab2cc0f7bfbdc7fa793", "type": "github" }, "original": { diff --git a/src/composer.rs b/src/composer.rs index 3906744..8c9b7a4 100644 --- a/src/composer.rs +++ b/src/composer.rs @@ -57,6 +57,7 @@ pub unsafe fn create_proof_with_pk( cs_ptr: &[u8], witness_ptr: &[u8], proof_data_ptr: *mut *mut u8, + is_recursive: bool, ) -> usize { let cs_ptr = cs_ptr.as_ptr() as *const u8; let pk_ptr = pk_ptr.as_ptr() as *const u8; @@ -67,12 +68,19 @@ pub unsafe fn create_proof_with_pk( cs_ptr, witness_ptr.as_ptr(), proof_data_ptr as *const *mut u8 as *mut *mut u8, + is_recursive, ) } /// # Safety /// cs_prt must point to a valid constraints system structure of type standard_format -pub unsafe fn verify_with_vk(g2_ptr: &[u8], vk_ptr: &[u8], cs_ptr: &[u8], proof: &[u8]) -> bool { +pub unsafe fn verify_with_vk( + g2_ptr: &[u8], + vk_ptr: &[u8], + cs_ptr: &[u8], + proof: &[u8], + is_recursive: bool, +) -> bool { let proof_ptr = proof.as_ptr() as *const u8; acir_proofs_verify_proof( @@ -81,5 +89,39 @@ pub unsafe fn verify_with_vk(g2_ptr: &[u8], vk_ptr: &[u8], cs_ptr: &[u8], proof: cs_ptr.as_ptr() as *const u8, proof_ptr as *mut u8, proof.len() as u32, + is_recursive, + ) +} + +/// # Safety +/// vk_buf must point to a valid verification key previously exported by this composer +pub unsafe fn serialize_verification_key_into_field_elements( + g2_ptr: &[u8], + vk_buf: &[u8], + serialized_vk_buf: *mut *mut u8, + serialized_vk_hash_buf: *mut *mut u8, +) -> usize { + acir_serialize_verification_key_into_field_elements( + g2_ptr.as_ptr() as *const u8, + vk_buf.as_ptr() as *const u8, + serialized_vk_buf as *const *mut u8 as *mut *mut u8, + serialized_vk_hash_buf as *const *mut u8 as *mut *mut u8, + ) +} + +/// # Safety +/// proof must point to a valid proof previously generated by this composer +/// The proof must also have its public inputs prepended in order for the call to be valid +pub unsafe fn serialize_proof_into_field_elements( + proof: &[u8], + serialized_proof_data_buf: *mut *mut u8, + proof_data_length: usize, + num_public_inputs: usize, +) -> usize { + acir_serialize_proof_into_field_elements( + proof.as_ptr() as *const u8, + serialized_proof_data_buf, + proof_data_length, + num_public_inputs, ) } diff --git a/src/lib.rs b/src/lib.rs index e671b2a..71c7ba0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ pub mod blake2s; pub mod composer; pub mod pedersen; pub mod pippenger; +pub mod recursion; pub mod schnorr; #[cfg(test)] @@ -28,7 +29,7 @@ mod tests { f_one[31] = 1; let got = pedersen::compress_native(&f_zero, &f_one); assert_eq!( - "11831f49876c313f2a9ec6d8d521c7ce0b6311c852117e340bfe27fd1ac096ef", + "0c5e1ddecd49de44ed5e5798d3f6fb7c71fe3d37f5bee8664cf88a445b5ba0af", hex::encode(got) ); } diff --git a/src/pedersen.rs b/src/pedersen.rs index 2981bee..a839daf 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -69,17 +69,17 @@ mod tests { Test { input_left: f_zero, input_right: f_one, - expected_hex: "11831f49876c313f2a9ec6d8d521c7ce0b6311c852117e340bfe27fd1ac096ef", + expected_hex: "0c5e1ddecd49de44ed5e5798d3f6fb7c71fe3d37f5bee8664cf88a445b5ba0af", }, Test { input_left: f_one, input_right: f_one, - expected_hex: "1044a769e185fcdf077c8289a6bf87c5c77ff9561cab69d39fadd90a07ee4af4", + expected_hex: "0e1793a0c122887bcb53c84776f4704c26bc093b25eaa9c7847a672c65e314ae", }, Test { input_left: f_one, input_right: f_zero, - expected_hex: "17d213c8fe83e89a2f3190933d437a3e231124e0383e6dc6a7b6e6358833e427", + expected_hex: "0c93b3f27730b2e331e634af15bc9d5a769688921f30b36ca926b35a96b3306c", }, ]; @@ -100,8 +100,8 @@ mod tests { let inputs: Vec<[u8; 32]> = vec![f_zero, f_one]; let (x, y) = encrypt(&inputs); - let expected_x = "11831f49876c313f2a9ec6d8d521c7ce0b6311c852117e340bfe27fd1ac096ef"; - let expected_y = "0ecf9d98be4597a88c46a7e0fa8836b57a7dcb41ee30f8d8787b11cc259c83fa"; + let expected_x = "0c5e1ddecd49de44ed5e5798d3f6fb7c71fe3d37f5bee8664cf88a445b5ba0af"; + let expected_y = "230294a041e26fe80b827c2ef5cb8784642bbaa83842da2714d62b1f3c4f9752"; assert_eq!(expected_x, hex::encode(x)); assert_eq!(expected_y, hex::encode(y)); } diff --git a/src/recursion.rs b/src/recursion.rs new file mode 100644 index 0000000..649a5fd --- /dev/null +++ b/src/recursion.rs @@ -0,0 +1,24 @@ +use crate::*; + +/// # Safety +/// vk_fields_ptr and proof_fields must point to a valid recursion format structure +/// laid out in the acir format recursion constraint +/// input_aggregation_obj_ptr must point to a valid aggregation object whose +/// structure is also laid out in the acir format recursion constraint +pub unsafe fn verify_proof( + vk_fields_ptr: &[u8], + proof_fields: &[u8], + num_public_inputs: u32, + input_aggregation_obj_ptr: &[u8], + output_aggregation_obj_ptr: *mut *mut u8, +) -> usize { + acir_proofs_verify_recursive_proof( + proof_fields.as_ptr() as *const u8, + proof_fields.len() as u32, + vk_fields_ptr.as_ptr() as *const u8, + vk_fields_ptr.len() as u32, + num_public_inputs, + input_aggregation_obj_ptr.as_ptr() as *const u8, + output_aggregation_obj_ptr, + ) +}