use crate::error_type::AppResult; use crate::request_response::Response; use bellman_ce::groth16::*; use linked_hash_map::LinkedHashMap; use serde_json::Value; pub struct ProofManager { // map from job id to verify status proofs: LinkedHashMap, } impl ProofManager { pub fn new() -> Self { ProofManager { proofs: LinkedHashMap::new(), } } pub fn verify(&mut self, proof_id: u64, public_par: [u64; 5], proof: [u64; 8]) -> AppResult { // verify mock let result: u8 = 1; //test_xordemo(); // update proof status self.proofs.insert(proof_id, result); let response = Response::Verify { result : result, }; serde_json::to_value(response).map_err(Into::into) } pub fn check(&self, proof_id: u64) -> AppResult { let status = self.proof_status(proof_id)?; let response = Response::Check { verifed: status }; serde_json::to_value(response).map_err(Into::into) } fn proof_status(&self, proof_id: u64) -> AppResult { let status = self .proofs .get(&proof_id) .ok_or_else(|| format!("Proof with id {} wasn't found", proof_id))?; Ok(*status) } /* fn test_xordemo() { let g1 = Fr::one(); let g2 = Fr::one(); let alpha = Fr::from_str("48577").unwrap(); let beta = Fr::from_str("22580").unwrap(); let gamma = Fr::from_str("53332").unwrap(); let delta = Fr::from_str("5481").unwrap(); let tau = Fr::from_str("3673").unwrap(); let params = { let c = XORDemo:: { a: None, b: None, _marker: PhantomData }; generate_parameters( c, g1, g2, alpha, beta, gamma, delta, tau ).unwrap() }; // This will synthesize the constraint system: // // public inputs: a_0 = 1, a_1 = c // aux inputs: a_2 = a, a_3 = b // constraints: // (a_0 - a_2) * (a_2) = 0 // (a_0 - a_3) * (a_3) = 0 // (a_2 + a_2) * (a_3) = (a_2 + a_3 - a_1) // (a_0) * 0 = 0 // (a_1) * 0 = 0 // The evaluation domain is 8. The H query should // have 7 elements (it's a quotient polynomial) assert_eq!(7, params.h.len()); let mut root_of_unity = Fr::root_of_unity(); // We expect this to be a 2^10 root of unity assert_eq!(Fr::one(), root_of_unity.pow(&[1 << 10])); // Let's turn it into a 2^3 root of unity. root_of_unity = root_of_unity.pow(&[1 << 7]); assert_eq!(Fr::one(), root_of_unity.pow(&[1 << 3])); assert_eq!(Fr::from_str("20201").unwrap(), root_of_unity); // Let's compute all the points in our evaluation domain. let mut points = Vec::with_capacity(8); for i in 0..8 { points.push(root_of_unity.pow(&[i])); } // Let's compute t(tau) = (tau - p_0)(tau - p_1)... // = tau^8 - 1 let mut t_at_tau = tau.pow(&[8]); t_at_tau.sub_assign(&Fr::one()); { let mut tmp = Fr::one(); for p in &points { let mut term = tau; term.sub_assign(p); tmp.mul_assign(&term); } assert_eq!(tmp, t_at_tau); } // We expect our H query to be 7 elements of the form... // {tau^i t(tau) / delta} let delta_inverse = delta.inverse().unwrap(); let gamma_inverse = gamma.inverse().unwrap(); { let mut coeff = delta_inverse; coeff.mul_assign(&t_at_tau); let mut cur = Fr::one(); for h in params.h.iter() { let mut tmp = cur; tmp.mul_assign(&coeff); assert_eq!(*h, tmp); cur.mul_assign(&tau); } } // The density of the IC query is 2 (2 inputs) assert_eq!(2, params.vk.ic.len()); // The density of the L query is 2 (2 aux variables) assert_eq!(2, params.l.len()); // The density of the A query is 4 (each variable is in at least one A term) assert_eq!(4, params.a.len()); // The density of the B query is 2 (two variables are in at least one B term) assert_eq!(2, params.b_g1.len()); assert_eq!(2, params.b_g2.len()); /* Lagrange interpolation polynomials in our evaluation domain: ,-------------------------------. ,-------------------------------. ,-------------------------------. | A TERM | | B TERM | | C TERM | `-------------------------------. `-------------------------------' `-------------------------------' | a_0 | a_1 | a_2 | a_3 | | a_0 | a_1 | a_2 | a_3 | | a_0 | a_1 | a_2 | a_3 | | 1 | 0 | 64512 | 0 | | 0 | 0 | 1 | 0 | | 0 | 0 | 0 | 0 | | 1 | 0 | 0 | 64512 | | 0 | 0 | 0 | 1 | | 0 | 0 | 0 | 0 | | 0 | 0 | 2 | 0 | | 0 | 0 | 0 | 1 | | 0 | 64512 | 1 | 1 | | 1 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 | | 0 | 1 | 0 | 0 | | 0 | 0 | 0 | 0 | | 0 | 0 | 0 | 0 | `-------'-------'-------'-------' `-------'-------'-------'-------' `-------'-------'-------'-------' Example for u_0: sage: r = 64513 sage: Fr = GF(r) sage: omega = (Fr(5)^63)^(2^7) sage: tau = Fr(3673) sage: R. = PolynomialRing(Fr, 'x') sage: def eval(tau, c0, c1, c2, c3, c4): ....: p = R.lagrange_polynomial([(omega^0, c0), (omega^1, c1), (omega^2, c2), (omega^3, c3), (omega^4, c4), (omega^5, 0), (omega^6, 0), (omega^7, 0)]) ....: return p.substitute(tau) sage: eval(tau, 1, 1, 0, 1, 0) 59158 */ let u_i = [59158, 48317, 21767, 10402].iter().map(|e| { Fr::from_str(&format!("{}", e)).unwrap() }).collect::>(); let v_i = [0, 0, 60619, 30791].iter().map(|e| { Fr::from_str(&format!("{}", e)).unwrap() }).collect::>(); let w_i = [0, 23320, 41193, 41193].iter().map(|e| { Fr::from_str(&format!("{}", e)).unwrap() }).collect::>(); for (u, a) in u_i.iter() .zip(¶ms.a[..]) { assert_eq!(u, a); } for (v, b) in v_i.iter() .filter(|&&e| e != Fr::zero()) .zip(¶ms.b_g1[..]) { assert_eq!(v, b); } for (v, b) in v_i.iter() .filter(|&&e| e != Fr::zero()) .zip(¶ms.b_g2[..]) { assert_eq!(v, b); } for i in 0..4 { let mut tmp1 = beta; tmp1.mul_assign(&u_i[i]); let mut tmp2 = alpha; tmp2.mul_assign(&v_i[i]); tmp1.add_assign(&tmp2); tmp1.add_assign(&w_i[i]); if i < 2 { // Check the correctness of the IC query elements tmp1.mul_assign(&gamma_inverse); assert_eq!(tmp1, params.vk.ic[i]); } else { // Check the correctness of the L query elements tmp1.mul_assign(&delta_inverse); assert_eq!(tmp1, params.l[i - 2]); } } // Check consistency of the other elements assert_eq!(alpha, params.vk.alpha_g1); assert_eq!(beta, params.vk.beta_g1); assert_eq!(beta, params.vk.beta_g2); assert_eq!(gamma, params.vk.gamma_g2); assert_eq!(delta, params.vk.delta_g1); assert_eq!(delta, params.vk.delta_g2); let pvk = prepare_verifying_key(¶ms.vk); let r = Fr::from_str("27134").unwrap(); let s = Fr::from_str("17146").unwrap(); let proof = { let c = XORDemo { a: Some(true), b: Some(false), _marker: PhantomData }; create_proof( c, ¶ms, r, s ).unwrap() }; // A(x) = // a_0 * (44865*x^7 + 56449*x^6 + 44865*x^5 + 8064*x^4 + 3520*x^3 + 56449*x^2 + 3520*x + 40321) + // a_1 * (8064*x^7 + 56449*x^6 + 8064*x^5 + 56449*x^4 + 8064*x^3 + 56449*x^2 + 8064*x + 56449) + // a_2 * (16983*x^7 + 24192*x^6 + 63658*x^5 + 56449*x^4 + 16983*x^3 + 24192*x^2 + 63658*x + 56449) + // a_3 * (5539*x^7 + 27797*x^6 + 6045*x^5 + 56449*x^4 + 58974*x^3 + 36716*x^2 + 58468*x + 8064) + { // proof A = alpha + A(tau) + delta * r let mut expected_a = delta; expected_a.mul_assign(&r); expected_a.add_assign(&alpha); expected_a.add_assign(&u_i[0]); // a_0 = 1 expected_a.add_assign(&u_i[1]); // a_1 = 1 expected_a.add_assign(&u_i[2]); // a_2 = 1 // a_3 = 0 assert_eq!(proof.a, expected_a); } // B(x) = // a_0 * (0) + // a_1 * (0) + // a_2 * (56449*x^7 + 56449*x^6 + 56449*x^5 + 56449*x^4 + 56449*x^3 + 56449*x^2 + 56449*x + 56449) + // a_3 * (31177*x^7 + 44780*x^6 + 21752*x^5 + 42255*x^3 + 35861*x^2 + 33842*x + 48385) { // proof B = beta + B(tau) + delta * s let mut expected_b = delta; expected_b.mul_assign(&s); expected_b.add_assign(&beta); expected_b.add_assign(&v_i[0]); // a_0 = 1 expected_b.add_assign(&v_i[1]); // a_1 = 1 expected_b.add_assign(&v_i[2]); // a_2 = 1 // a_3 = 0 assert_eq!(proof.b, expected_b); } // C(x) = // a_0 * (0) + // a_1 * (27797*x^7 + 56449*x^6 + 36716*x^5 + 8064*x^4 + 27797*x^3 + 56449*x^2 + 36716*x + 8064) + // a_2 * (36716*x^7 + 8064*x^6 + 27797*x^5 + 56449*x^4 + 36716*x^3 + 8064*x^2 + 27797*x + 56449) + // a_3 * (36716*x^7 + 8064*x^6 + 27797*x^5 + 56449*x^4 + 36716*x^3 + 8064*x^2 + 27797*x + 56449) // // If A * B = C at each point in the domain, then the following polynomial... // P(x) = A(x) * B(x) - C(x) // = 49752*x^14 + 13914*x^13 + 29243*x^12 + 27227*x^11 + 62362*x^10 + 35703*x^9 + 4032*x^8 + 14761*x^6 + 50599*x^5 + 35270*x^4 + 37286*x^3 + 2151*x^2 + 28810*x + 60481 // // ... should be divisible by t(x), producing the quotient polynomial: // h(x) = P(x) / t(x) // = 49752*x^6 + 13914*x^5 + 29243*x^4 + 27227*x^3 + 62362*x^2 + 35703*x + 4032 { let mut expected_c = Fr::zero(); // A * s let mut tmp = proof.a; tmp.mul_assign(&s); expected_c.add_assign(&tmp); // B * r let mut tmp = proof.b; tmp.mul_assign(&r); expected_c.add_assign(&tmp); // delta * r * s let mut tmp = delta; tmp.mul_assign(&r); tmp.mul_assign(&s); expected_c.sub_assign(&tmp); // L query answer // a_2 = 1, a_3 = 0 expected_c.add_assign(¶ms.l[0]); // H query answer for (i, coeff) in [5040, 11763, 10755, 63633, 128, 9747, 8739].iter().enumerate() { let coeff = Fr::from_str(&format!("{}", coeff)).unwrap(); let mut tmp = params.h[i]; tmp.mul_assign(&coeff); expected_c.add_assign(&tmp); } assert_eq!(expected_c, proof.c); } assert!(verify_proof( &pvk, &proof, &[Fr::one()] ).unwrap()); }*/ }