diff --git a/proof_of_groth_bn/risc0/prover/Cargo.toml b/proof_of_groth_bn/risc0/prover/Cargo.toml index 0d78777e..d5c5687a 100644 --- a/proof_of_groth_bn/risc0/prover/Cargo.toml +++ b/proof_of_groth_bn/risc0/prover/Cargo.toml @@ -12,12 +12,11 @@ rand = "0.8.5" rand_core = "0.6.0" thiserror = "1.0.62" anyhow = "1" -ark-bn254 = "0.4.0" -ark-ff = "0.4.0" +ark-bn254 = "0.5.0" +ark-ff = "0.5.0" kzgrs = { path = "../../../nomos-da/kzgrs"} once_cell = "1.19.0" -num-bigint = "0.4.6" -ark-groth16 = "0.4.0" -ark-serialize = "0.4.0" +ark-groth16 = "0.5.0" +ark-serialize = "0.5.0" serde = { version = "1.0.213", features = ["derive"] } serde_json = "1.0.132" \ No newline at end of file diff --git a/proof_of_groth_bn/risc0/prover/data/proof_1.json b/proof_of_groth_bn/risc0/prover/data/proof_1.json new file mode 100644 index 00000000..d3737b0d --- /dev/null +++ b/proof_of_groth_bn/risc0/prover/data/proof_1.json @@ -0,0 +1 @@ +{"pi_a":["5950998577632577282126721914641352248516252789122831556656688434596091777040","14411974511655633094592703124912680192238153337219426756289052935918171289648","1"],"pi_b":[["3466008247480879046474291499063397127530567304613574090888573027943689467174","17287016391293236203517769461282758601739668413889640311313211300390456481795"],["18950250134749387371891731213788963801858187766040494708646355337605894494419","4191310646725004775382946732751664729144006090075933928730473696563702096317"],["1","0"]],"pi_c":["16058306167551061322008685265144234395093892226178151486575564046096187701270","21359136236950654781737426933593314473423698529777809567288341094782016270688","1"],"protocol":"groth16","curve":"bn128"} \ No newline at end of file diff --git a/proof_of_groth_bn/risc0/prover/data/proof_2.json b/proof_of_groth_bn/risc0/prover/data/proof_2.json new file mode 100644 index 00000000..b5974d32 --- /dev/null +++ b/proof_of_groth_bn/risc0/prover/data/proof_2.json @@ -0,0 +1 @@ +{"pi_a":["16900523459967454964449430612735216999695085388293510437380163250192584733915","19498829337715745544611839661074543675141604814134686869369096799453985868939","1"],"pi_b":[["5936341616465861486272539620871714729032993520835348789438905581798423627550","18069133006819678811256733025949395175610133255247307398808307192968554617966"],["12025308715087187067393178281966288123128613463555587880750060722149479687394","13406832964712953617491891369564548417044971351344985190613264889170671203080"],["1","0"]],"pi_c":["16664617747629801705252418454687612090199164220156505039755162162960476755683","12412836701754573169429181296904705282180015155007373043662498202302347541985","1"],"protocol":"groth16","curve":"bn128"} \ No newline at end of file diff --git a/proof_of_groth_bn/risc0/prover/data/proof_3.json b/proof_of_groth_bn/risc0/prover/data/proof_3.json new file mode 100644 index 00000000..6ecc7fe1 --- /dev/null +++ b/proof_of_groth_bn/risc0/prover/data/proof_3.json @@ -0,0 +1 @@ +{"pi_a":["15167969919734338320783415953573448412429979489662463642910937013184862661455","1610977708746882509037725144761144998351146945518011333410451848082914319858","1"],"pi_b":[["2413451294104612584702040101388946495096051411969300605362924256899655978260","16748414877999313849456096234985608362001451851298413934342686246600044716276"],["18362565129012126207144041490517569003814723103007433266966590874380189204804","7027521598126111105181781806094493632933412177330433232365142391928485457177"],["1","0"]],"pi_c":["6303098394144051374455595520394663521837362315996292200613059333170950986247","15906256040737319223307068049221540966648481156012438007681609556232964599781","1"],"protocol":"groth16","curve":"bn128"} \ No newline at end of file diff --git a/proof_of_groth_bn/risc0/prover/data/public_1.json b/proof_of_groth_bn/risc0/prover/data/public_1.json new file mode 100644 index 00000000..f09d4cab --- /dev/null +++ b/proof_of_groth_bn/risc0/prover/data/public_1.json @@ -0,0 +1 @@ +["18586133768512220936620570745912940619677854269274689475585506675881198879027"] \ No newline at end of file diff --git a/proof_of_groth_bn/risc0/prover/data/public_2.json b/proof_of_groth_bn/risc0/prover/data/public_2.json new file mode 100644 index 00000000..63cf8cd9 --- /dev/null +++ b/proof_of_groth_bn/risc0/prover/data/public_2.json @@ -0,0 +1 @@ +["8645981980787649023086883978738420856660271013038108762834452721572614684349"] \ No newline at end of file diff --git a/proof_of_groth_bn/risc0/prover/data/public_3.json b/proof_of_groth_bn/risc0/prover/data/public_3.json new file mode 100644 index 00000000..637052e0 --- /dev/null +++ b/proof_of_groth_bn/risc0/prover/data/public_3.json @@ -0,0 +1 @@ +["6018413527099068561047958932369318610297162528491556075919075208700178480084"] \ No newline at end of file diff --git a/proof_of_groth_bn/risc0/prover/data/verification_key.json b/proof_of_groth_bn/risc0/prover/data/verification_key.json index 250823fc..04211cb7 100644 --- a/proof_of_groth_bn/risc0/prover/data/verification_key.json +++ b/proof_of_groth_bn/risc0/prover/data/verification_key.json @@ -37,12 +37,12 @@ ], "vk_delta_2": [ [ - "2382770829579450231937877595813135214627755341163308338559481788618722905625", - "9040926302247894040188704482087249224621680323614760223290765369622797702873" + "810996562703366523945956814968659238317375488831694806240680058934035811475", + "14822556301370320380164395356859429707667462548366900925320018766795769955732" ], [ - "21113171019167140870581514687281577061289301731643345706699116515401076091323", - "3201874119644369618625632439639166311277319924024234206341116264282425882294" + "13292128513018028318041083039576539246990085814869379498168488862560118421758", + "5948037185768629314101446338505615227889925672294427132452121406051246371105" ], [ "1", diff --git a/proof_of_groth_bn/risc0/prover/src/lib.rs b/proof_of_groth_bn/risc0/prover/src/lib.rs index eb2684f4..d92b0ac9 100644 --- a/proof_of_groth_bn/risc0/prover/src/lib.rs +++ b/proof_of_groth_bn/risc0/prover/src/lib.rs @@ -8,9 +8,13 @@ use ark_serialize::CanonicalSerialize; use serde::{Deserialize, Serialize}; use risc0_zkvm::sha::{Digest, Digestible}; -const PROOF: &str = include_str!("../data/proof.json"); -const PUBLIC: &str = include_str!("../data/public.json"); const VERIFICATION_KEY: &str = include_str!("../data/verification_key.json"); +const PROOF1: &str = include_str!("../data/proof_1.json"); +const PUBLIC1: &str = include_str!("../data/public_1.json"); +const PROOF2: &str = include_str!("../data/proof_2.json"); +const PUBLIC2: &str = include_str!("../data/public_2.json"); +const PROOF3: &str = include_str!("../data/proof_3.json"); +const PUBLIC3: &str = include_str!("../data/public_3.json"); #[derive(Error, Debug)] pub enum Error { @@ -50,9 +54,9 @@ pub struct PublicInputsJson { pub fn prove() -> Result { - let proof_json: ProofJson = serde_json::from_str(PROOF).unwrap(); + let proof_json: ProofJson = serde_json::from_str(PROOF1).unwrap(); let public_inputs_json = PublicInputsJson { - values: serde_json::from_str(PUBLIC).unwrap(), + values: serde_json::from_str(PUBLIC1).unwrap(), }; let verifying_key_json: VerifyingKeyJson = serde_json::from_str(VERIFICATION_KEY).unwrap(); @@ -211,6 +215,136 @@ pub fn prove() -> Result { buffer.append(&mut vec_public); eprintln!("buffer size {}",buffer.len()); + let proof_json: ProofJson = serde_json::from_str(PROOF2).unwrap(); + let public_inputs_json = PublicInputsJson { + values: serde_json::from_str(PUBLIC2).unwrap(), + }; + + let proof: Proof = Proof { + a: ark_bn254::G1Affine::new( + Fq::from_str( + &proof_json.pi_a[0] + ) + .unwrap(), + Fq::from_str( + &proof_json.pi_a[1] + ) + .unwrap(), + ), + b: ark_bn254::G2Affine::new( + Fq2::new( + Fq::from_str( + &proof_json.pi_b[0][0] + ) + .unwrap(), + Fq::from_str( + &proof_json.pi_b[0][1] + ) + .unwrap(), + ), + Fq2::new( + Fq::from_str( + &proof_json.pi_b[1][0] + ) + .unwrap(), + Fq::from_str( + &proof_json.pi_b[1][1] + ) + .unwrap(), + ), + ), + c: ark_bn254::G1Affine::new( + Fq::from_str( + &proof_json.pi_c[0] + ) + .unwrap(), + Fq::from_str( + &proof_json.pi_c[1] + ) + .unwrap(), + ), + }; + let mut vec_proof: Vec = vec![]; + proof.serialize_uncompressed(&mut vec_proof).unwrap(); + + + let public: Vec = public_inputs_json.values.iter().map(|x| Fr::from_str( + &x, + ) + .unwrap() ).collect(); + let mut vec_public: Vec = vec![]; + public.serialize_uncompressed(&mut vec_public).unwrap(); + + buffer.append(&mut vec_proof); + eprintln!("buffer size {}",buffer.len()); + buffer.append(&mut vec_public); + eprintln!("buffer size {}",buffer.len()); + + let proof_json: ProofJson = serde_json::from_str(PROOF3).unwrap(); + let public_inputs_json = PublicInputsJson { + values: serde_json::from_str(PUBLIC3).unwrap(), + }; + + let proof: Proof = Proof { + a: ark_bn254::G1Affine::new( + Fq::from_str( + &proof_json.pi_a[0] + ) + .unwrap(), + Fq::from_str( + &proof_json.pi_a[1] + ) + .unwrap(), + ), + b: ark_bn254::G2Affine::new( + Fq2::new( + Fq::from_str( + &proof_json.pi_b[0][0] + ) + .unwrap(), + Fq::from_str( + &proof_json.pi_b[0][1] + ) + .unwrap(), + ), + Fq2::new( + Fq::from_str( + &proof_json.pi_b[1][0] + ) + .unwrap(), + Fq::from_str( + &proof_json.pi_b[1][1] + ) + .unwrap(), + ), + ), + c: ark_bn254::G1Affine::new( + Fq::from_str( + &proof_json.pi_c[0] + ) + .unwrap(), + Fq::from_str( + &proof_json.pi_c[1] + ) + .unwrap(), + ), + }; + let mut vec_proof: Vec = vec![]; + proof.serialize_uncompressed(&mut vec_proof).unwrap(); + + + let public: Vec = public_inputs_json.values.iter().map(|x| Fr::from_str( + &x, + ) + .unwrap() ).collect(); + let mut vec_public: Vec = vec![]; + public.serialize_uncompressed(&mut vec_public).unwrap(); + + buffer.append(&mut vec_proof); + eprintln!("buffer size {}",buffer.len()); + buffer.append(&mut vec_public); + eprintln!("buffer size {}",buffer.len()); + let env = risc0_zkvm::ExecutorEnv::builder() .write_slice(&buffer) .build() diff --git a/proof_of_groth_bn/risc0/risc0_proofs/proof_of_groth/Cargo.toml b/proof_of_groth_bn/risc0/risc0_proofs/proof_of_groth/Cargo.toml index e52c489a..9ccbeb0c 100644 --- a/proof_of_groth_bn/risc0/risc0_proofs/proof_of_groth/Cargo.toml +++ b/proof_of_groth_bn/risc0/risc0_proofs/proof_of_groth/Cargo.toml @@ -8,7 +8,8 @@ edition = "2021" [dependencies] risc0-zkvm = { version = "1.0", default-features = false, features = ['std'] } serde = { version = "1.0", features = ["derive"] } -ark-groth16 = "0.4.0" -ark-bn254 = "0.4.0" -ark-ff = "0.4.0" -ark-serialize = "0.4.0" \ No newline at end of file +ark-groth16 = "0.5.0" +ark-bn254 = "0.5.0" +ark-ff = "0.5.0" +ark-serialize = "0.5.0" +ark-ec = "0.5.0" \ No newline at end of file diff --git a/proof_of_groth_bn/risc0/risc0_proofs/proof_of_groth/src/main.rs b/proof_of_groth_bn/risc0/risc0_proofs/proof_of_groth/src/main.rs index 3bc6aa7a..57354810 100644 --- a/proof_of_groth_bn/risc0/risc0_proofs/proof_of_groth/src/main.rs +++ b/proof_of_groth_bn/risc0/risc0_proofs/proof_of_groth/src/main.rs @@ -1,11 +1,18 @@ -use ark_bn254::{Bn254, Fr}; -use ark_groth16::Proof; +use ark_bn254::{Bn254, Fr, G1Affine}; +use ark_ff::{BigInteger, Field, PrimeField, Zero}; +use ark_groth16::{PreparedVerifyingKey, Proof}; use risc0_zkvm::guest::env; use ark_serialize::CanonicalDeserialize; -use risc0_zkvm::sha::Digestible; +use risc0_zkvm::sha::rust_crypto::{Digest, Sha256}; +use core::ops::AddAssign; +use std::ops::{Add, Div, Mul, MulAssign}; +use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup, PrimeGroup}; +use ark_ec::pairing::PairingOutput; +use ark_groth16::r1cs_to_qap::LibsnarkReduction; const N_INPUTS : usize = 1; -const BUFFER_SIZE : usize = 35930 + 256 + 40 * N_INPUTS; +const N_PROOFS : usize = 3; +const BUFFER_SIZE : usize = 34394 + (256 + 40 * N_INPUTS)*N_PROOFS; fn main() { let start_start = env::cycle_count(); let mut inputs = vec![0u8; BUFFER_SIZE]; @@ -14,30 +21,88 @@ fn main() { eprintln!("load inputs: {}", end - start_start); let start = env::cycle_count(); - let verification_key = ark_groth16::PreparedVerifyingKey::deserialize_uncompressed_unchecked(&inputs[0..35930]).unwrap(); + let verification_key : PreparedVerifyingKey = ark_groth16::PreparedVerifyingKey::deserialize_uncompressed_unchecked(&inputs[0..34394]).unwrap(); let end = env::cycle_count(); eprintln!("load verification key: {}", end - start); let start = env::cycle_count(); - let proof = Proof::deserialize_uncompressed_unchecked(&inputs[35930..36186]).unwrap(); + let proof_1 : Proof = Proof::deserialize_uncompressed_unchecked(&inputs[34394..34650]).unwrap(); + let proof_2 : Proof = Proof::deserialize_uncompressed_unchecked(&inputs[34690..34946]).unwrap(); + let proof_3 : Proof = Proof::deserialize_uncompressed_unchecked(&inputs[34986..35242]).unwrap(); let end = env::cycle_count(); eprintln!("proof load: {}", end - start); let start = env::cycle_count(); - let public : Vec = Vec::deserialize_uncompressed_unchecked(&inputs[36186..BUFFER_SIZE]).unwrap(); + let public_1 : Vec = Vec::deserialize_uncompressed_unchecked(&inputs[34650..34690]).unwrap(); + let public_2 : Vec = Vec::deserialize_uncompressed_unchecked(&inputs[34946..34986]).unwrap(); + let public_3 : Vec = Vec::deserialize_uncompressed_unchecked(&inputs[35242..35282]).unwrap(); let end = env::cycle_count(); eprintln!("public input load: {}", end - start); let start = env::cycle_count(); - // BLS scalar field modulus - let test = ark_groth16::Groth16::::verify_proof(&verification_key, &proof, &public).unwrap(); + let mut hasher = Sha256::new(); + hasher.update(&inputs); + let r = Fr::from_le_bytes_mod_order(&hasher.finalize()); + let r_2 = r.square().into_bigint(); + let r = r.into_bigint(); let end = env::cycle_count(); - eprintln!("proof verification: {}", end - start); + eprintln!("Fiat Shamir : {}", end - start); let start = env::cycle_count(); - assert_eq!(test, true); - env::commit(&(inputs[0..35930].digest(), inputs[36186..BUFFER_SIZE].digest())); + // BLS scalar field modulus + assert_eq!((public_1.len() + 1) ,verification_key.vk.gamma_abc_g1.len()); + assert_eq!((public_2.len() + 1) ,verification_key.vk.gamma_abc_g1.len()); + assert_eq!((public_3.len() + 1) ,verification_key.vk.gamma_abc_g1.len()); + + let start = env::cycle_count(); + let mut g_ic_1 : ::G1 = (verification_key.vk.gamma_abc_g1[0] as ::G1Affine).into_group(); + for (i, b) in public_1.iter().zip(verification_key.vk.gamma_abc_g1.iter().skip(1)) { + g_ic_1.add_assign(&(b as &::G1Affine).mul_bigint(i.into_bigint())); + } + let mut g_ic_2 : ::G1 = (verification_key.vk.gamma_abc_g1[0] as ::G1Affine).into_group(); + for (i, b) in public_2.iter().zip(verification_key.vk.gamma_abc_g1.iter().skip(1)) { + g_ic_2.add_assign(&(b as &::G1Affine).mul_bigint(i.into_bigint())); + } + let mut g_ic_3 : ::G1 = (verification_key.vk.gamma_abc_g1[0] as ::G1Affine).into_group(); + for (i, b) in public_3.iter().zip(verification_key.vk.gamma_abc_g1.iter().skip(1)) { + g_ic_3.add_assign(&(b as &::G1Affine).mul_bigint(i.into_bigint())); + } + let g_ic = g_ic_1 + g_ic_2.mul_bigint(r) + g_ic_3.mul_bigint(r_2); + let end = env::cycle_count(); + eprintln!("public computation : {}", end - start); + + let start = env::cycle_count(); + let qap = Bn254::multi_miller_loop( + [ + <::G1Affine as Into<::G1Prepared>>::into(proof_1.a), + g_ic.into_affine().into(), + (proof_1.c + proof_2.c.mul_bigint(r) + proof_3.c.mul_bigint(r_2)).into(), + ], + [ + proof_1.b.into(), + verification_key.gamma_g2_neg_pc.clone(), + verification_key.delta_g2_neg_pc.clone(), + ], + ); + let end = env::cycle_count(); + eprintln!("Miller loop : {}", end - start); + + let start = env::cycle_count(); + let p = ::pairing(proof_2.a.mul_bigint(r),proof_2.b); + let p_2 = ::pairing(proof_3.a.mul_bigint(r_2),proof_3.b); + let end = env::cycle_count(); + eprintln!("One pairing : {}", end - start); + + let start = env::cycle_count(); + let test = (Bn254::final_exponentiation(qap).unwrap() + p + p_2).mul_bigint((Fr::from_bigint(r_2).unwrap() + Fr::from_bigint(r).unwrap() + Fr::from(1)).inverse().unwrap().into_bigint()); + let end = env::cycle_count(); + eprintln!("final result of pairing sum : {}", end - start); + + let start = env::cycle_count(); + assert_eq!(test.0, verification_key.alpha_g1_beta_g2); + let end_end = env::cycle_count(); - eprintln!("test bool: {}", end_end - start); + eprintln!("verification key combination: {}", end_end - start); + eprintln!("total: {}", end_end - start_start); }