From 16ff53f4bb20bfabe9287d97908d586aa1c01ff0 Mon Sep 17 00:00:00 2001 From: vms Date: Tue, 9 Jul 2019 12:30:42 +0300 Subject: [PATCH] sime minor improvements --- backend_fluence/Cargo.lock | 1 + backend_fluence/Cargo.toml | 1 + backend_fluence/src/lib.rs | 8 +- backend_fluence/src/proof_manager.rs | 273 +++++++++++++----------- backend_fluence/src/request_response.rs | 1 - 5 files changed, 151 insertions(+), 133 deletions(-) diff --git a/backend_fluence/Cargo.lock b/backend_fluence/Cargo.lock index d62e602..b46e439 100644 --- a/backend_fluence/Cargo.lock +++ b/backend_fluence/Cargo.lock @@ -405,6 +405,7 @@ name = "verifier" version = "0.0.1" dependencies = [ "bellman 0.2.0 (git+https://github.com/matterinc/bellman?tag=0.2.0)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "fluence 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/backend_fluence/Cargo.toml b/backend_fluence/Cargo.toml index c349abb..12a8617 100644 --- a/backend_fluence/Cargo.toml +++ b/backend_fluence/Cargo.toml @@ -24,4 +24,5 @@ log = "0.4" fluence = { version = "0.1.5", features = ["wasm_logger"] } hex = "0.3.2" +byteorder = "1.3.2" bellman = { git = 'https://github.com/matterinc/bellman', tag = "0.2.0" } diff --git a/backend_fluence/src/lib.rs b/backend_fluence/src/lib.rs index ada1b69..cf34567 100644 --- a/backend_fluence/src/lib.rs +++ b/backend_fluence/src/lib.rs @@ -7,9 +7,9 @@ use crate::proof_manager::ProofManager; use crate::request_response::{Request, Response}; use fluence::sdk::*; +use log::info; use serde_json::Value; use std::cell::RefCell; -use log::info; fn init() { logger::WasmLogger::init_with_level(log::Level::Info).unwrap(); @@ -23,17 +23,13 @@ fn do_request(req: String) -> AppResult { let request: Request = serde_json::from_str(req.as_str())?; match request { - Request::Verify { proof_id, public_par, proof, } => PROOF_MANAGER.with(|gm| gm.borrow_mut().verify(proof_id, public_par, proof)), - Request::Check { - proof_id, - } => PROOF_MANAGER.with(|gm| gm.borrow_mut().check(proof_id)) - + Request::Check { proof_id } => PROOF_MANAGER.with(|gm| gm.borrow_mut().check(proof_id)), } } diff --git a/backend_fluence/src/proof_manager.rs b/backend_fluence/src/proof_manager.rs index 881c5a3..f459f6e 100644 --- a/backend_fluence/src/proof_manager.rs +++ b/backend_fluence/src/proof_manager.rs @@ -3,115 +3,125 @@ use crate::request_response::Response; use linked_hash_map::LinkedHashMap; use serde_json::Value; -use log::info; + +use bellman::groth16::{ + prepare_verifying_key, verify_proof, PreparedVerifyingKey, Proof, VerifyingKey, +}; +use bellman::pairing::bn256::*; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; +use bellman::pairing::{CurveAffine, EncodedPoint}; + +use byteorder::{BigEndian, WriteBytesExt}; +use std::io::{self, Cursor, Read, Seek, SeekFrom, Write}; pub struct ProofManager { - // map from job id to verify status + // map from proof id to verify status proofs: LinkedHashMap, + + // prepared verifying key for proof + prepared_vk: PreparedVerifyingKey, } impl ProofManager { - pub fn new() -> Self { + let vk_alpha_g1 = hex::decode( + "2e0a814dd75e4118233ddf6a916a813c40bae07d976fdcd01dbfa22bea641a96 + 1779e77cff5e54cf2cdc237e51cd6d95ef2c37ab6a7d5f9ce0a242188e1a1fe3", + ) + .unwrap(); + + //vk.beta_g1 = vk.alpha_g1 - ZoKrates does not return that and it is not needed for verification + let vk_beta_g1 = hex::decode( + "1fea09defec64586a976a33dbfb70961fc7e03fb6f4d5a1e074f97312ce789cd + 006653d8d2e65ab55fa795c44971eabcc6dbb1dd383c7a8a20de68486eb28154", + ) + .unwrap(); + + let vk_beta_g2 = hex::decode( + "021548b93199574bdef2be8cb1908a1079b1664d8a041d2e297c3aa6c554855c + 190b2d5d03854400e2c2a702f502813677a1d4be920d79648f810e320a30f2c5 + 0bc956fa715451d64e20b260759c2ae74a82b68f1eef86504051cd3ae547f282 + 011192ee83c0347e363b7c5fffe156fbadd91591b35dc8fe912d2b498c3a9301", + ) + .unwrap(); + + let vk_gamma_g2 = hex::decode( + "1c4c46720835faf06e35cd85f05c589a1a98f58112ecf7aacf0deac60681f5a4 + 1b438f01daf6402ff298981b74f80a5e79c39cce21c67770f74b89e65eb3b9ca + 101b8c9c29aa1ac1a709878f6eb4d4a74f4ed1368a18f29c2762b76b8c389f4d + 009538b3640e10082d0bf4b18b997fef6af2e7cceb942ebb26bd263e8805fedd", + ) + .unwrap(); + + //vk.delta_g1 = vk.alpha_g1 - ZoKrates does not return that and it is not needed for verification + let vk_delta_g1 = hex::decode( + "1fea09defec64586a976a33dbfb70961fc7e03fb6f4d5a1e074f97312ce789cd + 006653d8d2e65ab55fa795c44971eabcc6dbb1dd383c7a8a20de68486eb28154", + ) + .unwrap(); + + let vk_delta_g2 = hex::decode( + "25161a4cc549ffabd2c4508038c12d49447c15e9c565b025183ff6114ffcc58b + 110f2b773f6d9632162bc2c629467a58e7539ed0f0dc64ff4fd8f63baf4b5a32 + 0eb80be9e5a3f3f4cb0e39edc1db88dbf8de59b0c800b72dcc34d9c0fae14d55 + 0839d69bfc27640a59af741138d4f34500d925eb1a4e9fd57fcda269a7411c33", + ) + .unwrap(); + + //vk.ic len + let vk_ic_len = 6; + + //vk.ic + let vk_ic = hex::decode( + "2bb604557c5f1096973ab8afe980ea3ae23bd7457f3f11f67fb395f2d1f3b568 + 0f12fdb646ea572637ea6e1bbf04158bcabe6947cf614c67efb3f0278279f866 + 228bbefb9d7457c97766bcae9412c6ddd1de8e3dbcf1606ca6b8f027836affee + 01bf2712a663f5a72a469ea83a4c3d453c6023a0cd5d5f86330157f1505d62b3 + 23af3409b4b3fb3f194dc683be70c5e442de55544edeace8f891a891a4701ca3 + 1d13edb38da07247e70158557cfa93097d90d92b9a2c99f190c1413f3fdf8828 + 00572fbfedfe16fd1dcae266bf009907451cd8db485325ad322fb658cb0c30ff + 25415b150b181b2cbecc6f84382b0bd8fd49f2cf498da1c775ad624e5e7b7eaf + 1a294f13fbf284a6e11c2f54ed2946fc5fd732dafbf49ac01ce741f224b57c29 + 182d4a788849c87d27548cbe3a511a0237cb0d4595425eee878d78c4eb4e5529 + 10ec12d1090de44b1aecb41030d123df2d61318c1928d6de10f916c9bfc2f681 + 0621a1ea9bbbfa893358dfaa206ba1cb8af2ecca483c3c36f2a0c302da401c8f", + ) + .unwrap(); + + let mut c = Cursor::new(Vec::new()); + + c.write_all(vk_alpha_g1.as_slice()).unwrap(); + c.write_all(vk_beta_g1.as_slice()).unwrap(); + c.write_all(vk_beta_g2.as_slice()).unwrap(); + c.write_all(vk_gamma_g2.as_slice()).unwrap(); + c.write_all(vk_delta_g1.as_slice()).unwrap(); + c.write_all(vk_delta_g2.as_slice()).unwrap(); + c.write_i32::(vk_ic_len).unwrap(); + c.write_all(vk_ic.as_slice()).unwrap(); + + c.seek(SeekFrom::Start(0)).unwrap(); + + let vk: VerifyingKey = VerifyingKey::read(c).unwrap(); + let prepared_vk: PreparedVerifyingKey = prepare_verifying_key(&vk); + ProofManager { proofs: LinkedHashMap::new(), + prepared_vk, } } - pub fn verify(&mut self, proof_id: u64, public_par: [String; 5], proof: [String; 8]) -> AppResult { - - use bellman::pairing::bn256::*; - use bellman::groth16::{ - Proof, - VerifyingKey, - verify_proof, - prepare_verifying_key - }; - - use bellman::pairing::ff::{ - PrimeField, - PrimeFieldRepr, - Field - }; - - use bellman::pairing::{ - CurveAffine, - EncodedPoint - }; - - use std::io::{self, Read, Cursor, Seek, SeekFrom, Write}; - - // verify proof ------------------------------------------------------------------------------------- - - // import verification key -------------------------------------------- - - //vk.alpha_g1 - let mut hex_string = hex::decode("2e0a814dd75e4118233ddf6a916a813c40bae07d976fdcd01dbfa22bea641a96").unwrap(); - hex_string.append(hex::decode("1779e77cff5e54cf2cdc237e51cd6d95ef2c37ab6a7d5f9ce0a242188e1a1fe3").unwrap().as_mut()); - //vk.beta_g1 = vk.alpha_g1 - ZoKrates does not return that and it is not neaded for verification - hex_string.append(hex::decode("1fea09defec64586a976a33dbfb70961fc7e03fb6f4d5a1e074f97312ce789cd").unwrap().as_mut()); - hex_string.append(hex::decode("006653d8d2e65ab55fa795c44971eabcc6dbb1dd383c7a8a20de68486eb28154").unwrap().as_mut()); - //vk.beta_g2 - hex_string.append(hex::decode("021548b93199574bdef2be8cb1908a1079b1664d8a041d2e297c3aa6c554855c").unwrap().as_mut()); - hex_string.append(hex::decode("190b2d5d03854400e2c2a702f502813677a1d4be920d79648f810e320a30f2c5").unwrap().as_mut()); - hex_string.append(hex::decode("0bc956fa715451d64e20b260759c2ae74a82b68f1eef86504051cd3ae547f282").unwrap().as_mut()); - hex_string.append(hex::decode("011192ee83c0347e363b7c5fffe156fbadd91591b35dc8fe912d2b498c3a9301").unwrap().as_mut()); - //vk.gamma_g2 - hex_string.append(hex::decode("1c4c46720835faf06e35cd85f05c589a1a98f58112ecf7aacf0deac60681f5a4").unwrap().as_mut()); - hex_string.append(hex::decode("1b438f01daf6402ff298981b74f80a5e79c39cce21c67770f74b89e65eb3b9ca").unwrap().as_mut()); - hex_string.append(hex::decode("101b8c9c29aa1ac1a709878f6eb4d4a74f4ed1368a18f29c2762b76b8c389f4d").unwrap().as_mut()); - hex_string.append(hex::decode("009538b3640e10082d0bf4b18b997fef6af2e7cceb942ebb26bd263e8805fedd").unwrap().as_mut()); - //vk.delta_g1 = vk.alpha_g1 - ZoKrates does not return that and it is not neaded for verification - hex_string.append(hex::decode("1fea09defec64586a976a33dbfb70961fc7e03fb6f4d5a1e074f97312ce789cd").unwrap().as_mut()); - hex_string.append(hex::decode("006653d8d2e65ab55fa795c44971eabcc6dbb1dd383c7a8a20de68486eb28154").unwrap().as_mut()); - //vk.delta_g2 - hex_string.append(hex::decode("25161a4cc549ffabd2c4508038c12d49447c15e9c565b025183ff6114ffcc58b").unwrap().as_mut()); - hex_string.append(hex::decode("110f2b773f6d9632162bc2c629467a58e7539ed0f0dc64ff4fd8f63baf4b5a32").unwrap().as_mut()); - hex_string.append(hex::decode("0eb80be9e5a3f3f4cb0e39edc1db88dbf8de59b0c800b72dcc34d9c0fae14d55").unwrap().as_mut()); - hex_string.append(hex::decode("0839d69bfc27640a59af741138d4f34500d925eb1a4e9fd57fcda269a7411c33").unwrap().as_mut()); - //vk.ic len - hex_string.append(6u32.to_be_bytes().to_vec().as_mut()); - //vk.ic - hex_string.append(hex::decode("2bb604557c5f1096973ab8afe980ea3ae23bd7457f3f11f67fb395f2d1f3b568").unwrap().as_mut()); - hex_string.append(hex::decode("0f12fdb646ea572637ea6e1bbf04158bcabe6947cf614c67efb3f0278279f866").unwrap().as_mut()); - hex_string.append(hex::decode("228bbefb9d7457c97766bcae9412c6ddd1de8e3dbcf1606ca6b8f027836affee").unwrap().as_mut()); - hex_string.append(hex::decode("01bf2712a663f5a72a469ea83a4c3d453c6023a0cd5d5f86330157f1505d62b3").unwrap().as_mut()); - hex_string.append(hex::decode("23af3409b4b3fb3f194dc683be70c5e442de55544edeace8f891a891a4701ca3").unwrap().as_mut()); - hex_string.append(hex::decode("1d13edb38da07247e70158557cfa93097d90d92b9a2c99f190c1413f3fdf8828").unwrap().as_mut()); - - hex_string.append(hex::decode("00572fbfedfe16fd1dcae266bf009907451cd8db485325ad322fb658cb0c30ff").unwrap().as_mut()); - hex_string.append(hex::decode("25415b150b181b2cbecc6f84382b0bd8fd49f2cf498da1c775ad624e5e7b7eaf").unwrap().as_mut()); - hex_string.append(hex::decode("1a294f13fbf284a6e11c2f54ed2946fc5fd732dafbf49ac01ce741f224b57c29").unwrap().as_mut()); - hex_string.append(hex::decode("182d4a788849c87d27548cbe3a511a0237cb0d4595425eee878d78c4eb4e5529").unwrap().as_mut()); - hex_string.append(hex::decode("10ec12d1090de44b1aecb41030d123df2d61318c1928d6de10f916c9bfc2f681").unwrap().as_mut()); - hex_string.append(hex::decode("0621a1ea9bbbfa893358dfaa206ba1cb8af2ecca483c3c36f2a0c302da401c8f").unwrap().as_mut()); - + pub fn verify( + &mut self, + proof_id: u64, + public_par: [String; 5], + proof: [String; 8], + ) -> AppResult { let mut c = Cursor::new(Vec::new()); - c.write_all(hex_string.as_slice()).unwrap(); - c.seek(SeekFrom::Start(0)).unwrap(); - - let vk : VerifyingKey = VerifyingKey::read(c).unwrap(); - - let prepared_vk = prepare_verifying_key(&vk); - - // import proof ------------------------------------------------------- - - // a - let mut hex_string = hex::decode(&proof[0])?; - hex_string.append(hex::decode(&proof[1])?.as_mut()); - // b - hex_string.append(hex::decode(&proof[2])?.as_mut()); - hex_string.append(hex::decode(&proof[3])?.as_mut()); - hex_string.append(hex::decode(&proof[4])?.as_mut()); - hex_string.append(hex::decode(&proof[5])?.as_mut()); - // c - hex_string.append(hex::decode(&proof[6])?.as_mut()); - hex_string.append(hex::decode(&proof[7])?.as_mut()); - - let mut c = Cursor::new(Vec::new()); - - c.write_all(hex_string.as_slice()).unwrap(); + // write a, b, c + for proof_part in &proof { + c.write_all(hex::decode(proof_part)?.as_slice())?; + } c.seek(SeekFrom::Start(0)).unwrap(); let mut g1_repr = ::Uncompressed::empty(); @@ -119,35 +129,50 @@ impl ProofManager { c.read_exact(g1_repr.as_mut())?; let a = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + .into_affine() + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + .and_then(|e| { + if e.is_zero() { + Err(io::Error::new( + io::ErrorKind::InvalidData, + "point at infinity", + )) + } else { + Ok(e) + } + })?; c.read_exact(g2_repr.as_mut())?; let b = g2_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + .into_affine() + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + .and_then(|e| { + if e.is_zero() { + Err(io::Error::new( + io::ErrorKind::InvalidData, + "point at infinity", + )) + } else { + Ok(e) + } + })?; c.read_exact(g1_repr.as_mut())?; let c = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + .into_affine() + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + .and_then(|e| { + if e.is_zero() { + Err(io::Error::new( + io::ErrorKind::InvalidData, + "point at infinity", + )) + } else { + Ok(e) + } + })?; - let proof : Proof = Proof {a: a, b: b, c: c}; + let proof: Proof = Proof { a, b, c }; // import public inputs ----------------------------------------------- @@ -179,20 +204,16 @@ impl ProofManager { let public_inputs = vec![in_1_fr, in_2_fr, in_3_fr, in_4_fr, in_5_fr]; - let is_valid = verify_proof(&prepared_vk, &proof, &public_inputs)?; + let is_valid = verify_proof(&self.prepared_vk, &proof, &public_inputs)?; // update proof status ------------------------------------------------ - let mut result: u8 = 1; - if !is_valid { - result = 0 - } + let result: u8 = is_valid.into(); + + // TODO: check that such proof is already in the map (?) self.proofs.insert(proof_id, result); - let response = Response::Verify { - result : result, - }; - + let response = Response::Verify { result }; serde_json::to_value(response).map_err(Into::into) } diff --git a/backend_fluence/src/request_response.rs b/backend_fluence/src/request_response.rs index b9ae4d5..2cbc730 100644 --- a/backend_fluence/src/request_response.rs +++ b/backend_fluence/src/request_response.rs @@ -1,6 +1,5 @@ use serde::{Deserialize, Serialize}; - #[derive(Serialize, Deserialize)] #[serde(tag = "action")] pub enum Request {