Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Recursion bindings #26

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
with:
repository: AztecProtocol/barretenberg
path: barretenberg
ref: 87aeb375d7b434e0faf47abb79f97753ab760987
ref: 209667624f706be9106acab2cc0f7bfbdc7fa793

- name: Setup Linux environment
if: matrix.os == 'ubuntu-latest'
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down
3 changes: 3 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 43 additions & 1 deletion src/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(
Expand All @@ -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,
)
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod blake2s;
pub mod composer;
pub mod pedersen;
pub mod pippenger;
pub mod recursion;
pub mod schnorr;

#[cfg(test)]
Expand All @@ -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)
);
}
Expand Down
10 changes: 5 additions & 5 deletions src/pedersen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
];

Expand All @@ -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));
}
Expand Down
24 changes: 24 additions & 0 deletions src/recursion.rs
Original file line number Diff line number Diff line change
@@ -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,
)
}