g16 native verifier
This commit is contained in:
parent
80e8f7de43
commit
b55f941831
9 changed files with 208 additions and 203 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -92,6 +92,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||
|
||||
[[package]]
|
||||
name = "bellman_ce"
|
||||
version = "0.3.1"
|
||||
|
@ -1737,6 +1743,7 @@ name = "zokrates_core"
|
|||
version = "0.4.1"
|
||||
dependencies = [
|
||||
"assert_cli",
|
||||
"base64",
|
||||
"bellman_ce 0.3.1 (git+https://github.com/matter-labs/bellman?rev=9e35737)",
|
||||
"bincode",
|
||||
"cc",
|
||||
|
|
|
@ -117,10 +117,10 @@ fn cli() -> Result<(), String> {
|
|||
)
|
||||
.subcommand(SubCommand::with_name("export-verifier")
|
||||
.about("Exports a verifier as Solidity smart contract")
|
||||
.arg(Arg::with_name("input")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.help("Path of the verifier")
|
||||
.arg(Arg::with_name("verification-key-path")
|
||||
.short("v")
|
||||
.long("verification-key-path")
|
||||
.help("Path of the generated verification key file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -217,9 +217,9 @@ fn cli() -> Result<(), String> {
|
|||
.takes_value(true)
|
||||
.required(false)
|
||||
.default_value(PROVING_KEY_DEFAULT_PATH)
|
||||
).arg(Arg::with_name("proofpath")
|
||||
).arg(Arg::with_name("proof-path")
|
||||
.short("j")
|
||||
.long("proofpath")
|
||||
.long("proof-path")
|
||||
.help("Path of the JSON proof file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
|
@ -245,9 +245,9 @@ fn cli() -> Result<(), String> {
|
|||
)
|
||||
.subcommand(SubCommand::with_name("print-proof")
|
||||
.about("Prints proof in chosen format [remix, json]")
|
||||
.arg(Arg::with_name("proofpath")
|
||||
.arg(Arg::with_name("proof-path")
|
||||
.short("j")
|
||||
.long("proofpath")
|
||||
.long("proof-path")
|
||||
.help("Path of the JSON proof file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
|
@ -265,9 +265,9 @@ fn cli() -> Result<(), String> {
|
|||
)
|
||||
.subcommand(SubCommand::with_name("verify")
|
||||
.about("Verifies a given proof with the given constraint system and verification key")
|
||||
.arg(Arg::with_name("proofpath")
|
||||
.arg(Arg::with_name("proof-path")
|
||||
.short("j")
|
||||
.long("proofpath")
|
||||
.long("proof-path")
|
||||
.help("Path of the JSON proof file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
|
@ -544,21 +544,21 @@ fn cli() -> Result<(), String> {
|
|||
{
|
||||
let scheme = get_scheme(sub_matches.value_of("proving-scheme").unwrap())?;
|
||||
|
||||
let is_abiv2 = sub_matches.value_of("solidity-abi").unwrap() == "v2";
|
||||
let is_abi_v2 = sub_matches.value_of("solidity-abi").unwrap() == "v2";
|
||||
println!("Exporting verifier...");
|
||||
|
||||
// read vk file
|
||||
let input_path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let input_file = File::open(&input_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", input_path.display(), why))?;
|
||||
let mut reader = BufReader::new(input_file);
|
||||
let vk_path = Path::new(sub_matches.value_of("verification-key-path").unwrap());
|
||||
let vk_file = File::open(&vk_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", vk_path.display(), why))?;
|
||||
|
||||
let mut vk = String::new();
|
||||
let mut reader = BufReader::new(vk_file);
|
||||
let mut vk = Vec::new();
|
||||
reader
|
||||
.read_to_string(&mut vk)
|
||||
.map_err(|why| format!("couldn't read {}: {}", input_path.display(), why))?;
|
||||
.read_to_end(&mut vk)
|
||||
.map_err(|why| format!("couldn't read {}: {}", vk_path.display(), why))?;
|
||||
|
||||
let verifier = scheme.export_solidity_verifier(vk, is_abiv2);
|
||||
let verifier = scheme.export_solidity_verifier(vk, is_abi_v2);
|
||||
|
||||
//write output file
|
||||
let output_path = Path::new(sub_matches.value_of("output").unwrap());
|
||||
|
@ -589,7 +589,7 @@ fn cli() -> Result<(), String> {
|
|||
.map_err(|why| format!("could not load witness: {:?}", why))?;
|
||||
|
||||
let pk_path = Path::new(sub_matches.value_of("provingkey").unwrap());
|
||||
let proof_path = Path::new(sub_matches.value_of("proofpath").unwrap());
|
||||
let proof_path = Path::new(sub_matches.value_of("proof-path").unwrap());
|
||||
|
||||
let program_path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let program_file = File::open(&program_path)
|
||||
|
@ -621,7 +621,7 @@ fn cli() -> Result<(), String> {
|
|||
("print-proof", Some(sub_matches)) => {
|
||||
let format = sub_matches.value_of("format").unwrap();
|
||||
|
||||
let path = Path::new(sub_matches.value_of("proofpath").unwrap());
|
||||
let path = Path::new(sub_matches.value_of("proof-path").unwrap());
|
||||
|
||||
let file = File::open(&path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", path.display(), why))?;
|
||||
|
@ -658,12 +658,28 @@ fn cli() -> Result<(), String> {
|
|||
("verify", Some(sub_matches)) => {
|
||||
let scheme = get_scheme(sub_matches.value_of("proving-scheme").unwrap())?;
|
||||
|
||||
let proof_path = sub_matches.value_of("proofpath").unwrap();
|
||||
let vk_path = sub_matches.value_of("verification-key-path").unwrap();
|
||||
let vk_path = Path::new(sub_matches.value_of("verification-key-path").unwrap());
|
||||
let vk_file = File::open(&vk_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", vk_path.display(), why))?;
|
||||
|
||||
let mut vk_reader = BufReader::new(vk_file);
|
||||
let mut vk = Vec::new();
|
||||
vk_reader
|
||||
.read_to_end(&mut vk)
|
||||
.map_err(|why| format!("couldn't read {}: {}", vk_path.display(), why))?;
|
||||
|
||||
let proof_path = Path::new(sub_matches.value_of("proof-path").unwrap());
|
||||
let proof_file = File::open(&proof_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", proof_path.display(), why))?;
|
||||
|
||||
let mut proof = String::new();
|
||||
let mut proof_reader = BufReader::new(proof_file);
|
||||
proof_reader
|
||||
.read_to_string(&mut proof)
|
||||
.map_err(|why| format!("couldn't read {}: {}", proof_path.display(), why))?;
|
||||
|
||||
println!("Performing verification...");
|
||||
|
||||
scheme.verify(String::from(vk_path), String::from(proof_path));
|
||||
println!("Verified: {}", scheme.verify(vk, proof));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ serde_derive = "1.0"
|
|||
serde_json = "1.0"
|
||||
serde_bytes = "0.10"
|
||||
bincode = "0.8.0"
|
||||
base64 = "0.11.0"
|
||||
regex = "0.2"
|
||||
pairing_ce = "0.18"
|
||||
ff_ce = "0.7"
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
use std::io::{Cursor, Read};
|
||||
extern crate base64;
|
||||
|
||||
use bellman::groth16::Parameters;
|
||||
use bellman::groth16::*;
|
||||
use bellman::pairing::bn256::{Bn256, Fr};
|
||||
use regex::Regex;
|
||||
|
||||
use zokrates_field::field::FieldPrime;
|
||||
use zokrates_field::field::{Field, FieldPrime};
|
||||
|
||||
use crate::ir;
|
||||
use crate::proof_system::{ProofSystem, SetupKeypair};
|
||||
use crate::proof_system::bn128::utils::bellman::Computation;
|
||||
use crate::proof_system::bn128::utils::parser::KeyValueParser;
|
||||
use crate::proof_system::bn128::utils::bellman::{
|
||||
parse_fr, parse_g1, parse_g1_hex, parse_g2, parse_g2_hex,
|
||||
};
|
||||
use crate::proof_system::bn128::utils::solidity::{
|
||||
SOLIDITY_G2_ADDITION_LIB, SOLIDITY_PAIRING_LIB, SOLIDITY_PAIRING_LIB_V2,
|
||||
};
|
||||
use crate::proof_system::{ProofSystem, SetupKeypair};
|
||||
|
||||
const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/reference/proving_schemes.html#g16-malleability for implications.";
|
||||
|
||||
|
@ -23,6 +26,35 @@ impl G16 {
|
|||
}
|
||||
}
|
||||
|
||||
type G1PairingPoint = (String, String);
|
||||
type G2PairingPoint = (G1PairingPoint, G1PairingPoint);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct G16ProofPoints {
|
||||
a: G1PairingPoint,
|
||||
b: G2PairingPoint,
|
||||
c: G1PairingPoint,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct G16Proof {
|
||||
proof: G16ProofPoints,
|
||||
inputs: Vec<String>,
|
||||
raw: String,
|
||||
}
|
||||
|
||||
impl G16ProofPoints {
|
||||
fn new(a: G1PairingPoint, b: G2PairingPoint, c: G1PairingPoint) -> Self {
|
||||
G16ProofPoints { a, b, c }
|
||||
}
|
||||
}
|
||||
|
||||
impl G16Proof {
|
||||
fn new(proof: G16ProofPoints, inputs: Vec<String>, raw: String) -> Self {
|
||||
G16Proof { proof, inputs, raw }
|
||||
}
|
||||
}
|
||||
|
||||
impl ProofSystem for G16 {
|
||||
fn setup(&self, program: ir::Prog<FieldPrime>) -> SetupKeypair {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
@ -30,16 +62,17 @@ impl ProofSystem for G16 {
|
|||
println!("{}", G16_WARNING);
|
||||
|
||||
let parameters = Computation::without_witness(program).setup();
|
||||
let mut cursor = Cursor::new(Vec::new());
|
||||
|
||||
parameters.write(&mut cursor).unwrap();
|
||||
cursor.set_position(0);
|
||||
|
||||
let vk: String = serialize::serialize_vk(parameters.vk);
|
||||
let mut pk: Vec<u8> = Vec::new();
|
||||
cursor
|
||||
.read_to_end(&mut pk)
|
||||
.expect("Could not read cursor buffer");
|
||||
parameters
|
||||
.write(&mut pk)
|
||||
.expect("Could not write proving key to buffer");
|
||||
|
||||
let mut vk: Vec<u8> = Vec::new();
|
||||
parameters
|
||||
.vk
|
||||
.write(&mut vk)
|
||||
.expect("Could not write verifying key to buffer");
|
||||
|
||||
SetupKeypair::from(vk, pk)
|
||||
}
|
||||
|
@ -59,12 +92,30 @@ impl ProofSystem for G16 {
|
|||
let params = Parameters::read(proving_key.as_slice(), true).unwrap();
|
||||
|
||||
let proof = computation.clone().prove(¶ms);
|
||||
serialize::serialize_proof(&proof, &computation.public_inputs_values())
|
||||
let mut raw: Vec<u8> = Vec::new();
|
||||
proof
|
||||
.write(&mut raw)
|
||||
.expect("Could not write proof to buffer");
|
||||
|
||||
let proof_points =
|
||||
G16ProofPoints::new(parse_g1(&proof.a), parse_g2(&proof.b), parse_g1(&proof.c));
|
||||
|
||||
let g16_proof = G16Proof::new(
|
||||
proof_points,
|
||||
computation
|
||||
.public_inputs_values()
|
||||
.iter()
|
||||
.map(parse_fr)
|
||||
.collect::<Vec<_>>(),
|
||||
base64::encode(&raw),
|
||||
);
|
||||
|
||||
format!("{:#}", serde_json::to_string(&g16_proof).unwrap())
|
||||
}
|
||||
|
||||
fn export_solidity_verifier(&self, vk: String, is_abiv2: bool) -> String {
|
||||
let vk_map = vk.parse_pairs();
|
||||
let (mut template_text, solidity_pairing_lib) = if is_abiv2 {
|
||||
fn export_solidity_verifier(&self, vk: Vec<u8>, abi_v2: bool) -> String {
|
||||
let bellman_vk: VerifyingKey<Bn256> = VerifyingKey::read(vk.as_slice()).unwrap();
|
||||
let (mut template_text, solidity_pairing_lib) = if abi_v2 {
|
||||
(
|
||||
String::from(CONTRACT_TEMPLATE_V2),
|
||||
String::from(SOLIDITY_PAIRING_LIB_V2),
|
||||
|
@ -81,31 +132,55 @@ impl ProofSystem for G16 {
|
|||
let vk_gamma_abc_repeat_regex = Regex::new(r#"(<%vk_gamma_abc_pts%>)"#).unwrap();
|
||||
let vk_input_len_regex = Regex::new(r#"(<%vk_input_length%>)"#).unwrap();
|
||||
|
||||
template_text = vk_regex.replace(template_text.as_str(), vk_map.get("vk.alpha").unwrap().as_str()).into_owned();
|
||||
template_text = vk_regex.replace(template_text.as_str(), vk_map.get("vk.beta").unwrap().as_str()).into_owned();
|
||||
template_text = vk_regex.replace(template_text.as_str(), vk_map.get("vk.gamma").unwrap().as_str()).into_owned();
|
||||
template_text = vk_regex.replace(template_text.as_str(), vk_map.get("vk.delta").unwrap().as_str()).into_owned();
|
||||
template_text = vk_regex
|
||||
.replace(
|
||||
template_text.as_str(),
|
||||
parse_g1_hex(&bellman_vk.alpha_g1).as_str(),
|
||||
)
|
||||
.into_owned();
|
||||
template_text = vk_regex
|
||||
.replace(
|
||||
template_text.as_str(),
|
||||
parse_g2_hex(&bellman_vk.beta_g2).as_str(),
|
||||
)
|
||||
.into_owned();
|
||||
template_text = vk_regex
|
||||
.replace(
|
||||
template_text.as_str(),
|
||||
parse_g2_hex(&bellman_vk.gamma_g2).as_str(),
|
||||
)
|
||||
.into_owned();
|
||||
template_text = vk_regex
|
||||
.replace(
|
||||
template_text.as_str(),
|
||||
parse_g2_hex(&bellman_vk.delta_g2).as_str(),
|
||||
)
|
||||
.into_owned();
|
||||
|
||||
let gamma_abc_count_str = vk_map.get("vk.gamma_abc.len()").unwrap();
|
||||
let gamma_abc_count: i32 = gamma_abc_count_str.parse::<i32>().unwrap();
|
||||
let gamma_abc_count: usize = bellman_vk.ic.len();
|
||||
template_text = vk_gamma_abc_len_regex
|
||||
.replace(
|
||||
template_text.as_str(),
|
||||
format!("{}", gamma_abc_count).as_str(),
|
||||
)
|
||||
.into_owned();
|
||||
|
||||
template_text = vk_gamma_abc_len_regex.replace(
|
||||
template_text.as_str(),
|
||||
format!("{}", gamma_abc_count).as_str()
|
||||
).into_owned();
|
||||
|
||||
template_text = vk_input_len_regex.replace(
|
||||
template_text.as_str(),
|
||||
format!("{}", gamma_abc_count - 1).as_str()
|
||||
).into_owned();
|
||||
template_text = vk_input_len_regex
|
||||
.replace(
|
||||
template_text.as_str(),
|
||||
format!("{}", gamma_abc_count - 1).as_str(),
|
||||
)
|
||||
.into_owned();
|
||||
|
||||
let mut gamma_abc_repeat_text = String::new();
|
||||
for x in 0..gamma_abc_count {
|
||||
gamma_abc_repeat_text.push_str(
|
||||
format!(
|
||||
"vk.gamma_abc[{}] = Pairing.G1Point({});", x,
|
||||
vk_map.get(format!("vk.gamma_abc[{}]", x).as_str()).unwrap()
|
||||
).as_str()
|
||||
"vk.gamma_abc[{}] = Pairing.G1Point({});",
|
||||
x,
|
||||
parse_g1_hex(bellman_vk.ic.get(x).unwrap())
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
if x < gamma_abc_count - 1 {
|
||||
gamma_abc_repeat_text.push_str("\n ");
|
||||
|
@ -125,61 +200,27 @@ impl ProofSystem for G16 {
|
|||
)
|
||||
}
|
||||
|
||||
fn verify(&self, vk: String, proof: String) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
fn verify(&self, vk: Vec<u8>, proof: String) -> bool {
|
||||
let vk: VerifyingKey<Bn256> =
|
||||
VerifyingKey::read(vk.as_slice()).expect("Could not read verifying key");
|
||||
|
||||
mod serialize {
|
||||
use bellman::groth16::{Proof, VerifyingKey};
|
||||
use pairing::bn256::{Bn256, Fr};
|
||||
let pvk: PreparedVerifyingKey<Bn256> = prepare_verifying_key(&vk);
|
||||
let g16_proof: G16Proof = serde_json::from_str(proof.as_str()).unwrap();
|
||||
|
||||
use crate::proof_system::bn128::utils::bellman::{
|
||||
parse_fr_json, parse_g1_hex, parse_g1_json, parse_g2_hex, parse_g2_json,
|
||||
};
|
||||
let proof_bytes = base64::decode(g16_proof.raw.as_str()).unwrap();
|
||||
let bellman_proof: Proof<Bn256> = Proof::read(proof_bytes.as_slice()).unwrap();
|
||||
|
||||
pub fn serialize_vk(vk: VerifyingKey<Bn256>) -> String {
|
||||
format!(
|
||||
"vk.alpha = {}
|
||||
vk.beta = {}
|
||||
vk.gamma = {}
|
||||
vk.delta = {}
|
||||
vk.gamma_abc.len() = {}
|
||||
{}",
|
||||
parse_g1_hex(&vk.alpha_g1),
|
||||
parse_g2_hex(&vk.beta_g2),
|
||||
parse_g2_hex(&vk.gamma_g2),
|
||||
parse_g2_hex(&vk.delta_g2),
|
||||
vk.ic.len(),
|
||||
vk.ic
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, x)| format!("vk.gamma_abc[{}] = {}", i, parse_g1_hex(x)))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
)
|
||||
}
|
||||
let public_inputs: Vec<Fr> = g16_proof
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|s| {
|
||||
FieldPrime::try_from_hex_str(s.as_str())
|
||||
.unwrap()
|
||||
.into_bellman()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
pub fn serialize_proof(p: &Proof<Bn256>, inputs: &Vec<Fr>) -> String {
|
||||
|
||||
format!(
|
||||
"{{
|
||||
\"proof\": {{
|
||||
\"a\": {},
|
||||
\"b\": {},
|
||||
\"c\": {}
|
||||
}},
|
||||
\"inputs\": [{}]
|
||||
}}",
|
||||
parse_g1_json(&p.a),
|
||||
parse_g2_json(&p.b),
|
||||
parse_g1_json(&p.c),
|
||||
inputs
|
||||
.iter()
|
||||
.map(parse_fr_json)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
)
|
||||
verify_proof(&pvk, &bellman_proof, &public_inputs).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -224,69 +224,50 @@ mod parse {
|
|||
|
||||
pub fn parse_g1(e: &<Bn256 as bellman::pairing::Engine>::G1Affine) -> (String, String) {
|
||||
let raw_e = e.to_string();
|
||||
|
||||
let captures = G1_REGEX.captures(&raw_e).unwrap();
|
||||
|
||||
(
|
||||
captures.name(&"x").unwrap().as_str().to_string(),
|
||||
captures.name(&"y").unwrap().as_str().to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_g2(
|
||||
pub fn parse_g2(
|
||||
e: &<Bn256 as bellman::pairing::Engine>::G2Affine,
|
||||
) -> (String, String, String, String) {
|
||||
) -> ((String, String), (String, String)) {
|
||||
let raw_e = e.to_string();
|
||||
|
||||
let captures = G2_REGEX.captures(&raw_e).unwrap();
|
||||
|
||||
(
|
||||
captures.name(&"x1").unwrap().as_str().to_string(),
|
||||
captures.name(&"x0").unwrap().as_str().to_string(),
|
||||
captures.name(&"y1").unwrap().as_str().to_string(),
|
||||
captures.name(&"y0").unwrap().as_str().to_string(),
|
||||
(
|
||||
captures.name(&"x1").unwrap().as_str().to_string(),
|
||||
captures.name(&"x0").unwrap().as_str().to_string(),
|
||||
),
|
||||
(
|
||||
captures.name(&"y1").unwrap().as_str().to_string(),
|
||||
captures.name(&"y0").unwrap().as_str().to_string(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_fr(e: &Fr) -> String {
|
||||
pub fn parse_fr(e: &Fr) -> String {
|
||||
let raw_e = e.to_string();
|
||||
|
||||
let captures = FR_REGEX.captures(&raw_e).unwrap();
|
||||
|
||||
captures.name(&"x").unwrap().as_str().to_string()
|
||||
}
|
||||
|
||||
pub fn parse_g1_json(e: &<Bn256 as bellman::pairing::Engine>::G1Affine) -> String {
|
||||
let parsed = parse_g1(e);
|
||||
|
||||
format!("[\"{}\", \"{}\"]", parsed.0, parsed.1)
|
||||
}
|
||||
|
||||
pub fn parse_g2_json(e: &<Bn256 as bellman::pairing::Engine>::G2Affine) -> String {
|
||||
let parsed = parse_g2(e);
|
||||
|
||||
format!(
|
||||
"[[\"{}\", \"{}\"], [\"{}\", \"{}\"]]",
|
||||
parsed.0, parsed.1, parsed.2, parsed.3,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_fr_json(e: &Fr) -> String {
|
||||
let parsed = parse_fr(e);
|
||||
|
||||
format!("\"{}\"", parsed)
|
||||
}
|
||||
|
||||
pub fn parse_g1_hex(e: &<Bn256 as bellman::pairing::Engine>::G1Affine) -> String {
|
||||
let parsed = parse_g1(e);
|
||||
|
||||
format!("{}, {}", parsed.0, parsed.1)
|
||||
}
|
||||
|
||||
pub fn parse_g2_hex(e: &<Bn256 as bellman::pairing::Engine>::G2Affine) -> String {
|
||||
let parsed = parse_g2(e);
|
||||
|
||||
format!("[{}, {}], [{}, {}]", parsed.0, parsed.1, parsed.2, parsed.3,)
|
||||
format!(
|
||||
"[{}, {}], [{}, {}]",
|
||||
(parsed.0).0,
|
||||
(parsed.0).1,
|
||||
(parsed.1).0,
|
||||
(parsed.1).1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,4 +4,3 @@ pub mod ffi;
|
|||
#[cfg(feature = "libsnark")]
|
||||
pub mod libsnark;
|
||||
pub mod solidity;
|
||||
pub mod parser;
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
pub trait KeyValueParser {
|
||||
fn parse_pairs(&self) -> HashMap<String, String>;
|
||||
}
|
||||
|
||||
impl KeyValueParser for String {
|
||||
|
||||
fn parse_pairs(&self) -> HashMap<String, String> {
|
||||
let mut map = HashMap::new();
|
||||
let mut lines = self.lines();
|
||||
|
||||
while let Some(current_line) = lines.next() {
|
||||
let key_value: Vec<&str> = current_line.split("=").collect();
|
||||
if key_value.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
map.insert(
|
||||
String::from(key_value[0].trim()),
|
||||
String::from(key_value[1].trim_start()));
|
||||
}
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::KeyValueParser;
|
||||
|
||||
#[test]
|
||||
fn parse_example() {
|
||||
let example: &str = r#"
|
||||
a = 1
|
||||
b = 2
|
||||
"#;
|
||||
|
||||
let map = String::from(example).parse_pairs();
|
||||
|
||||
assert_eq!("1", map.get("a").unwrap());
|
||||
assert_eq!("2", map.get("b").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_empty() {
|
||||
let map = String::from("").parse_pairs();
|
||||
assert!(map.is_empty());
|
||||
}
|
||||
}
|
|
@ -11,15 +11,15 @@ pub use self::bn128::PGHR13;
|
|||
use crate::ir;
|
||||
|
||||
// We only need to serialize this struct, there is no need for deserialization as keys are
|
||||
// used separetely in other use cases
|
||||
// used separately in other use cases
|
||||
#[derive(Serialize)]
|
||||
pub struct SetupKeypair {
|
||||
pub vk: String,
|
||||
pub vk: Vec<u8>,
|
||||
pub pk: Vec<u8>,
|
||||
}
|
||||
|
||||
impl SetupKeypair {
|
||||
pub fn from(vk: String, pk: Vec<u8>) -> SetupKeypair {
|
||||
pub fn from(vk: Vec<u8>, pk: Vec<u8>) -> SetupKeypair {
|
||||
SetupKeypair { vk, pk }
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub trait ProofSystem {
|
|||
proving_key: Vec<u8>,
|
||||
) -> String;
|
||||
|
||||
fn export_solidity_verifier(&self, vk: String, is_abiv2: bool) -> String;
|
||||
fn export_solidity_verifier(&self, vk: Vec<u8>, abi_v2: bool) -> String;
|
||||
|
||||
fn verify(&self, vk: String, proof: String) -> bool;
|
||||
fn verify(&self, vk: Vec<u8>, proof: String) -> bool;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ pub trait Field:
|
|||
fn get_required_bits() -> usize;
|
||||
/// Tries to parse a string into this representation
|
||||
fn try_from_dec_str<'a>(s: &'a str) -> Result<Self, ()>;
|
||||
fn try_from_hex_str<'a>(s: &'a str) -> Result<Self, ()>;
|
||||
/// Returns a decimal string representing the member of the equivalence class of this `Field` in Z/pZ
|
||||
/// which lies in [-(p-1)/2, (p-1)/2]
|
||||
fn to_compact_dec_string(&self) -> String;
|
||||
|
@ -139,12 +140,19 @@ impl Field for FieldPrime {
|
|||
fn get_required_bits() -> usize {
|
||||
(*P).bits()
|
||||
}
|
||||
fn try_from_dec_str<'a>(s: &'a str) -> Result<Self, ()> {
|
||||
fn try_from_dec_str(s: &str) -> Result<Self, ()> {
|
||||
let x = BigInt::parse_bytes(s.as_bytes(), 10).ok_or(())?;
|
||||
Ok(FieldPrime {
|
||||
value: &x - x.div_floor(&*P) * &*P,
|
||||
})
|
||||
}
|
||||
fn try_from_hex_str(s: &str) -> Result<Self, ()> {
|
||||
let x = BigInt::parse_bytes(s.trim_start_matches("0x").as_bytes(), 16)
|
||||
.ok_or(())?;
|
||||
Ok(FieldPrime {
|
||||
value: &x - x.div_floor(&*P) * &*P,
|
||||
})
|
||||
}
|
||||
fn to_compact_dec_string(&self) -> String {
|
||||
// values up to (p-1)/2 included are represented as positive, values between (p+1)/2 and p-1 are represented as negative by subtracting p
|
||||
if self.value <= FieldPrime::max_value().value / 2 {
|
||||
|
|
Loading…
Reference in a new issue