#![allow(unused)]
use crate::PlonkBn254Proof;
use cfg_if::cfg_if;
use sp1_core::SP1_CIRCUIT_VERSION;
use std::ffi::{c_char, CString};
#[allow(warnings, clippy::all)]
mod bind {
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
use bind::*;
pub fn prove_plonk_bn254(data_dir: &str, witness_path: &str) -> PlonkBn254Proof {
let data_dir = CString::new(data_dir).expect("CString::new failed");
let witness_path = CString::new(witness_path).expect("CString::new failed");
let proof = unsafe {
let proof = bind::ProvePlonkBn254(
data_dir.as_ptr() as *mut c_char,
witness_path.as_ptr() as *mut c_char,
);
*proof
};
proof.into_rust()
}
pub fn build_plonk_bn254(data_dir: &str) {
let data_dir = CString::new(data_dir).expect("CString::new failed");
unsafe {
bind::BuildPlonkBn254(data_dir.as_ptr() as *mut c_char);
}
}
pub fn verify_plonk_bn254(
data_dir: &str,
proof: &str,
vkey_hash: &str,
committed_values_digest: &str,
) -> Result<(), String> {
let data_dir = CString::new(data_dir).expect("CString::new failed");
let proof = CString::new(proof).expect("CString::new failed");
let vkey_hash = CString::new(vkey_hash).expect("CString::new failed");
let committed_values_digest =
CString::new(committed_values_digest).expect("CString::new failed");
let err_ptr = unsafe {
bind::VerifyPlonkBn254(
data_dir.as_ptr() as *mut c_char,
proof.as_ptr() as *mut c_char,
vkey_hash.as_ptr() as *mut c_char,
committed_values_digest.as_ptr() as *mut c_char,
)
};
if err_ptr.is_null() {
Ok(())
} else {
let err = unsafe { CString::from_raw(err_ptr) };
Err(err.into_string().unwrap())
}
}
pub fn test_plonk_bn254(witness_json: &str, constraints_json: &str) {
unsafe {
let witness_json = CString::new(witness_json).expect("CString::new failed");
let build_dir = CString::new(constraints_json).expect("CString::new failed");
let err_ptr = bind::TestPlonkBn254(
witness_json.as_ptr() as *mut c_char,
build_dir.as_ptr() as *mut c_char,
);
if !err_ptr.is_null() {
let err = CString::from_raw(err_ptr);
panic!("TestPlonkBn254 failed: {}", err.into_string().unwrap());
}
}
}
pub fn test_babybear_poseidon2() {
unsafe {
let err_ptr = bind::TestPoseidonBabyBear2();
if !err_ptr.is_null() {
let err = CString::from_raw(err_ptr);
panic!("TestPlonkBn254 failed: {}", err.into_string().unwrap());
}
}
}
unsafe fn c_char_ptr_to_string(input: *mut c_char) -> String {
unsafe {
CString::from_raw(input) .into_string()
.expect("CString::into_string failed")
}
}
impl C_PlonkBn254Proof {
fn into_rust(self) -> PlonkBn254Proof {
unsafe {
PlonkBn254Proof {
public_inputs: [
c_char_ptr_to_string(self.PublicInputs[0]),
c_char_ptr_to_string(self.PublicInputs[1]),
],
encoded_proof: c_char_ptr_to_string(self.EncodedProof),
raw_proof: c_char_ptr_to_string(self.RawProof),
plonk_vkey_hash: [0; 32],
}
}
}
}
#[cfg(test)]
mod tests {
use p3_baby_bear::BabyBear;
use p3_field::AbstractField;
use p3_symmetric::Permutation;
#[test]
pub fn test_babybear_poseidon2() {
let perm = sp1_core::utils::inner_perm();
let zeros = [BabyBear::zero(); 16];
let result = perm.permute(zeros);
println!("{:?}", result);
super::test_babybear_poseidon2();
}
}