Merge branch 'feature/deployContract' into cli
This commit is contained in:
commit
f11334a71b
4 changed files with 409 additions and 2 deletions
75
Cargo.lock
generated
75
Cargo.lock
generated
|
@ -9,10 +9,19 @@ dependencies = [
|
|||
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.9.0"
|
||||
|
@ -88,11 +97,24 @@ name = "lazy_static"
|
|||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.36"
|
||||
|
@ -185,6 +207,23 @@ dependencies = [
|
|||
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.22"
|
||||
|
@ -266,6 +305,15 @@ dependencies = [
|
|||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.4"
|
||||
|
@ -276,11 +324,29 @@ name = "unicode-xid"
|
|||
version = "0.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
|
@ -292,6 +358,7 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
|
||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||
"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860"
|
||||
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
|
||||
|
@ -302,7 +369,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417"
|
||||
"checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5"
|
||||
"checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5"
|
||||
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
|
||||
"checksum num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "bde7c03b09e7c6a301ee81f6ddf66d7a28ec305699e3d3b056d2fc56470e3120"
|
||||
"checksum num-bigint 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "88b14378471f7c2adc5262f05b4701ef53e8da376453a8d8fee48e51db745e49"
|
||||
"checksum num-complex 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c78e054dd19c3fd03419ade63fa661e9c49bb890ce3beb4eee5b7baf93f92f"
|
||||
|
@ -314,6 +383,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
|
||||
"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
|
||||
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
|
||||
"checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
|
||||
"checksum serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7046c9d4c6c522d10b2d098f9bebe2bef227e0e74044d8c1bfcf6b476af799"
|
||||
"checksum serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1afcaae083fd1c46952a315062326bc9957f182358eb7da03b57ef1c688f7aa9"
|
||||
|
@ -324,8 +395,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8e08afc40ae3459e4838f303e465aa50d823df8d7f83ca88108f6d3afe7edd"
|
||||
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
|
|
|
@ -19,6 +19,7 @@ clap = "2.26.2"
|
|||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
bincode = "0.8.0"
|
||||
regex = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.2.11"
|
||||
|
|
59
src/main.rs
59
src/main.rs
|
@ -14,6 +14,7 @@ extern crate serde; // serialization deserialization
|
|||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate bincode;
|
||||
extern crate regex;
|
||||
|
||||
mod absy;
|
||||
mod parser;
|
||||
|
@ -27,6 +28,8 @@ use std::fs::File;
|
|||
use std::path::Path;
|
||||
use std::io::{BufWriter, Write, BufReader, BufRead};
|
||||
use std::collections::HashMap;
|
||||
use std::string::String;
|
||||
use std::io::prelude::*;
|
||||
use field::{Field, FieldPrime};
|
||||
use absy::Prog;
|
||||
use parser::parse_program;
|
||||
|
@ -36,6 +39,7 @@ use clap::{App, AppSettings, Arg, SubCommand};
|
|||
#[cfg(not(feature = "nolibsnark"))]
|
||||
use libsnark::{run_libsnark, setup};
|
||||
use bincode::{serialize_into, deserialize_from , Infinite};
|
||||
use regex::Regex;
|
||||
|
||||
fn main() {
|
||||
const FLATTENED_CODE_DEFAULT_PATH: &str = "out";
|
||||
|
@ -447,9 +451,60 @@ fn main() {
|
|||
println!("run_libsnark = {:?}", run_libsnark(variables, a, b, c, witness, num_inputs));
|
||||
}
|
||||
}
|
||||
("export-verifier", Some(_)) => {
|
||||
("export-verifier", Some(sub_matches)) => {
|
||||
println!("Exporting verifier...");
|
||||
//TODO
|
||||
// read vk file
|
||||
let input_path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let mut file = match File::open(&input_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", input_path.display(), why),
|
||||
};
|
||||
|
||||
//TODO: Parse input file!
|
||||
|
||||
//read template
|
||||
let template_path = Path::new("templates/sol_verification.template");
|
||||
let mut template_file = match File::open(&template_path) {
|
||||
Ok(template_file) => template_file,
|
||||
Err(why) => panic!("couldn't open {}: {}", template_path.display(), why)
|
||||
};
|
||||
let mut template_text = String::new();
|
||||
template_file.read_to_string(&mut template_text).unwrap();
|
||||
let ic_template = String::from("vk.IC[index] = Pairing.G1Point(point0, point1);"); //copy this for each entry
|
||||
|
||||
//replace things in template
|
||||
let vk_regex = Regex::new(r#"(<%vk_[^i%]*%>)"#).unwrap();
|
||||
let vk_ic_len_regex = Regex::new(r#"(<%vk_ic_length%>)"#).unwrap();
|
||||
let vk_ic_index_regex = Regex::new(r#"index"#).unwrap();
|
||||
let vk_ic_point0_regex = Regex::new(r#"point0"#).unwrap();
|
||||
let vk_ic_point1_regex = Regex::new(r#"point1"#).unwrap();
|
||||
let vk_ic_repeat_regex = Regex::new(r#"(<%vk_ic_pts%>)"#).unwrap();
|
||||
|
||||
for x in 0..24 {
|
||||
template_text = vk_regex.replace(template_text.as_str(), "0x123").into_owned();
|
||||
}
|
||||
|
||||
let ic_count = 5;
|
||||
template_text = vk_ic_len_regex.replace_all(template_text.as_str(), format!("{}", ic_count).as_str()).into_owned();
|
||||
let mut ic_repeat_text = String::new();
|
||||
for x in 0..ic_count {
|
||||
let mut curr_template = ic_template.clone();
|
||||
curr_template = vk_ic_index_regex.replace(curr_template.as_str(), format!("{}", x).as_str()).into_owned();
|
||||
curr_template = vk_ic_point0_regex.replace(curr_template.as_str(), "0x1").into_owned();
|
||||
curr_template = vk_ic_point1_regex.replace(curr_template.as_str(), "0x2").into_owned();
|
||||
ic_repeat_text.push_str(curr_template.as_str());
|
||||
if x < ic_count - 1 {
|
||||
ic_repeat_text.push_str("\n ");
|
||||
}
|
||||
}
|
||||
template_text = vk_ic_repeat_regex.replace(template_text.as_str(), ic_repeat_text.as_str()).into_owned();
|
||||
//write output file
|
||||
let output_path = Path::new(sub_matches.value_of("output").unwrap());
|
||||
let mut output_file = match File::create(&output_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't create {}: {}", output_path.display(), why),
|
||||
};
|
||||
output_file.write_all(&template_text.as_bytes());
|
||||
}
|
||||
("generate-proof", Some(sub_matches)) => {
|
||||
println!("Generating proof...");
|
||||
|
|
276
templates/sol_verification.template
Normal file
276
templates/sol_verification.template
Normal file
|
@ -0,0 +1,276 @@
|
|||
pragma solidity ^0.4.14;
|
||||
library Pairing {
|
||||
struct G1Point {
|
||||
uint X;
|
||||
uint Y;
|
||||
}
|
||||
// Encoding of field elements is: X[0] * z + X[1]
|
||||
struct G2Point {
|
||||
uint[2] X;
|
||||
uint[2] Y;
|
||||
}
|
||||
/// @return the generator of G1
|
||||
function P1() internal returns (G1Point) {
|
||||
return G1Point(1, 2);
|
||||
}
|
||||
/// @return the generator of G2
|
||||
function P2() internal returns (G2Point) {
|
||||
return G2Point(
|
||||
[11559732032986387107991004021392285783925812861821192530917403151452391805634,
|
||||
10857046999023057135944570762232829481370756359578518086990519993285655852781],
|
||||
[4082367875863433681332203403145435568316851327593401208105741076214120093531,
|
||||
8495653923123431417604973247489272438418190587263600148770280649306958101930]
|
||||
);
|
||||
}
|
||||
/// @return the negation of p, i.e. p.add(p.negate()) should be zero.
|
||||
function negate(G1Point p) internal returns (G1Point) {
|
||||
// The prime q in the base field F_q for G1
|
||||
uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
|
||||
if (p.X == 0 && p.Y == 0)
|
||||
return G1Point(0, 0);
|
||||
return G1Point(p.X, q - (p.Y % q));
|
||||
}
|
||||
/// @return the sum of two points of G1
|
||||
function add(G1Point p1, G1Point p2) internal returns (G1Point r) {
|
||||
uint[4] memory input;
|
||||
input[0] = p1.X;
|
||||
input[1] = p1.Y;
|
||||
input[2] = p2.X;
|
||||
input[3] = p2.Y;
|
||||
bool success;
|
||||
assembly {
|
||||
success := call(sub(gas, 2000), 6, 0, input, 0xc0, r, 0x60)
|
||||
// Use "invalid" to make gas estimation work
|
||||
switch success case 0 { invalid }
|
||||
}
|
||||
require(success);
|
||||
}
|
||||
/// @return the product of a point on G1 and a scalar, i.e.
|
||||
/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.
|
||||
function mul(G1Point p, uint s) internal returns (G1Point r) {
|
||||
uint[3] memory input;
|
||||
input[0] = p.X;
|
||||
input[1] = p.Y;
|
||||
input[2] = s;
|
||||
bool success;
|
||||
assembly {
|
||||
success := call(sub(gas, 2000), 7, 0, input, 0x80, r, 0x60)
|
||||
// Use "invalid" to make gas estimation work
|
||||
switch success case 0 { invalid }
|
||||
}
|
||||
require (success);
|
||||
}
|
||||
/// @return the result of computing the pairing check
|
||||
/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1
|
||||
/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should
|
||||
/// return true.
|
||||
function pairing(G1Point[] p1, G2Point[] p2) internal returns (bool) {
|
||||
require(p1.length == p2.length);
|
||||
uint elements = p1.length;
|
||||
uint inputSize = elements * 6;
|
||||
uint[] memory input = new uint[](inputSize);
|
||||
for (uint i = 0; i < elements; i++)
|
||||
{
|
||||
input[i * 6 + 0] = p1[i].X;
|
||||
input[i * 6 + 1] = p1[i].Y;
|
||||
input[i * 6 + 2] = p2[i].X[0];
|
||||
input[i * 6 + 3] = p2[i].X[1];
|
||||
input[i * 6 + 4] = p2[i].Y[0];
|
||||
input[i * 6 + 5] = p2[i].Y[1];
|
||||
}
|
||||
uint[1] memory out;
|
||||
bool success;
|
||||
assembly {
|
||||
success := call(sub(gas, 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
|
||||
// Use "invalid" to make gas estimation work
|
||||
switch success case 0 { invalid }
|
||||
}
|
||||
require(success);
|
||||
return out[0] != 0;
|
||||
}
|
||||
/// Convenience method for a pairing check for two pairs.
|
||||
function pairingProd2(G1Point a1, G2Point a2, G1Point b1, G2Point b2) internal returns (bool) {
|
||||
G1Point[] memory p1 = new G1Point[](2);
|
||||
G2Point[] memory p2 = new G2Point[](2);
|
||||
p1[0] = a1;
|
||||
p1[1] = b1;
|
||||
p2[0] = a2;
|
||||
p2[1] = b2;
|
||||
return pairing(p1, p2);
|
||||
}
|
||||
/// Convenience method for a pairing check for three pairs.
|
||||
function pairingProd3(
|
||||
G1Point a1, G2Point a2,
|
||||
G1Point b1, G2Point b2,
|
||||
G1Point c1, G2Point c2
|
||||
) internal returns (bool) {
|
||||
G1Point[] memory p1 = new G1Point[](3);
|
||||
G2Point[] memory p2 = new G2Point[](3);
|
||||
p1[0] = a1;
|
||||
p1[1] = b1;
|
||||
p1[2] = c1;
|
||||
p2[0] = a2;
|
||||
p2[1] = b2;
|
||||
p2[2] = c2;
|
||||
return pairing(p1, p2);
|
||||
}
|
||||
/// Convenience method for a pairing check for four pairs.
|
||||
function pairingProd4(
|
||||
G1Point a1, G2Point a2,
|
||||
G1Point b1, G2Point b2,
|
||||
G1Point c1, G2Point c2,
|
||||
G1Point d1, G2Point d2
|
||||
) internal returns (bool) {
|
||||
G1Point[] memory p1 = new G1Point[](4);
|
||||
G2Point[] memory p2 = new G2Point[](4);
|
||||
p1[0] = a1;
|
||||
p1[1] = b1;
|
||||
p1[2] = c1;
|
||||
p1[3] = d1;
|
||||
p2[0] = a2;
|
||||
p2[1] = b2;
|
||||
p2[2] = c2;
|
||||
p2[3] = d2;
|
||||
return pairing(p1, p2);
|
||||
}
|
||||
}
|
||||
contract Test {
|
||||
using Pairing for *;
|
||||
struct VerifyingKey {
|
||||
Pairing.G2Point A;
|
||||
Pairing.G1Point B;
|
||||
Pairing.G2Point C;
|
||||
Pairing.G2Point gamma;
|
||||
Pairing.G1Point gammaBeta1;
|
||||
Pairing.G2Point gammaBeta2;
|
||||
Pairing.G2Point Z;
|
||||
Pairing.G1Point[] IC;
|
||||
}
|
||||
struct Proof {
|
||||
Pairing.G1Point A;
|
||||
Pairing.G1Point A_p;
|
||||
Pairing.G2Point B;
|
||||
Pairing.G1Point B_p;
|
||||
Pairing.G1Point C;
|
||||
Pairing.G1Point C_p;
|
||||
Pairing.G1Point K;
|
||||
Pairing.G1Point H;
|
||||
}
|
||||
function f() returns (bool) {
|
||||
Pairing.G1Point memory p1;
|
||||
Pairing.G1Point memory p2;
|
||||
p1.X = 1; p1.Y = 2;
|
||||
p2.X = 1; p2.Y = 2;
|
||||
var explict_sum = Pairing.add(p1, p2);
|
||||
var scalar_prod = Pairing.mul(p1, 2);
|
||||
return (explict_sum.X == scalar_prod.X &&
|
||||
explict_sum.Y == scalar_prod.Y);
|
||||
}
|
||||
function g() returns (bool) {
|
||||
Pairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1()));
|
||||
// should be zero
|
||||
return (x.X == 0 && x.Y == 0);
|
||||
}
|
||||
function testMul() returns (bool) {
|
||||
Pairing.G1Point memory p;
|
||||
// @TODO The points here are reported to be not well-formed
|
||||
p.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726;
|
||||
p.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057;
|
||||
p = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521);
|
||||
return
|
||||
p.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 &&
|
||||
p.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803;
|
||||
}
|
||||
function pair() returns (bool) {
|
||||
Pairing.G2Point memory fiveTimesP2 = Pairing.G2Point(
|
||||
[4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072],
|
||||
[11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846]
|
||||
);
|
||||
// The prime p in the base field F_p for G1
|
||||
uint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
|
||||
Pairing.G1Point[] memory g1points = new Pairing.G1Point[](2);
|
||||
Pairing.G2Point[] memory g2points = new Pairing.G2Point[](2);
|
||||
// // check e(5 P1, P2)e(-P1, 5 P2) == 1
|
||||
g1points[0] = Pairing.P1().mul(5);
|
||||
g1points[1] = Pairing.P1();
|
||||
g1points[1].Y = p - g1points[1].Y;
|
||||
g2points[0] = Pairing.P2();
|
||||
g2points[1] = fiveTimesP2;
|
||||
if (!Pairing.pairing(g1points, g2points))
|
||||
return false;
|
||||
// check e(P1, P2)e(-P1, P2) == 0
|
||||
g1points[0] = Pairing.P1();
|
||||
g1points[1] = Pairing.P1().negate();
|
||||
g2points[0] = Pairing.P2();
|
||||
g2points[1] = Pairing.P2();
|
||||
if (!Pairing.pairing(g1points, g2points))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function verifyingKey() internal returns (VerifyingKey vk) {
|
||||
vk.A = Pairing.G2Point([<%vk_a_0%>, <%vk_a_1%>], [<%vk_a_2%>, <%vk_a_3%>]);
|
||||
vk.B = Pairing.G1Point(<%vk_b_0%>, <%vk_b_1%>);
|
||||
vk.C = Pairing.G2Point([<%vk_c_0%>, <%vk_c_1%>], [<%vk_c_2%>, <%vk_c_3%>]);
|
||||
vk.gamma = Pairing.G2Point([<%vk_g_0%>, <%vk_g_1%>], [<%vk_g_2%>, <%vk_g_3%>]);
|
||||
vk.gammaBeta1 = Pairing.G1Point(<%vk_gb1_0%>, <%vk_gb1_1%>);
|
||||
vk.gammaBeta2 = Pairing.G2Point([<%vk_gb2_0%>, <%vk_gb2_1%>], [<%vk_gb2_2%>, <%vk_gb2_3%>]);
|
||||
vk.Z = Pairing.G2Point([<%vk_z_0%>, <%vk_z_1%>], [<%vk_z_2%>, <%vk_z_3%>]);
|
||||
vk.IC = new Pairing.G1Point[](<%vk_ic_length%>);
|
||||
<%vk_ic_pts%>
|
||||
}
|
||||
function verify(uint[] input, Proof proof) internal returns (uint) {
|
||||
VerifyingKey memory vk = verifyingKey();
|
||||
require(input.length + 1 == vk.IC.length);
|
||||
// Compute the linear combination vk_x
|
||||
Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);
|
||||
for (uint i = 0; i < input.length; i++)
|
||||
vk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i]));
|
||||
vk_x = Pairing.add(vk_x, vk.IC[0]);
|
||||
if (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1;
|
||||
if (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2;
|
||||
if (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3;
|
||||
if (!Pairing.pairingProd3(
|
||||
proof.K, vk.gamma,
|
||||
Pairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2,
|
||||
Pairing.negate(vk.gammaBeta1), proof.B
|
||||
)) return 4;
|
||||
if (!Pairing.pairingProd3(
|
||||
Pairing.add(vk_x, proof.A), proof.B,
|
||||
Pairing.negate(proof.H), vk.Z,
|
||||
Pairing.negate(proof.C), Pairing.P2()
|
||||
)) return 5;
|
||||
return 0;
|
||||
}
|
||||
event Verified(string);
|
||||
function verifyTx(
|
||||
uint[2] a,
|
||||
uint[2] a_p,
|
||||
uint[2][2] b,
|
||||
uint[2] b_p,
|
||||
uint[2] c,
|
||||
uint[2] c_p,
|
||||
uint[2] h,
|
||||
uint[2] k,
|
||||
uint[<%vk_ic_length%>] input
|
||||
) returns (bool r) {
|
||||
Proof memory proof;
|
||||
proof.A = Pairing.G1Point(a[0], a[1]);
|
||||
proof.A_p = Pairing.G1Point(a_p[0], a_p[1]);
|
||||
proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);
|
||||
proof.B_p = Pairing.G1Point(b_p[0], b_p[1]);
|
||||
proof.C = Pairing.G1Point(c[0], c[1]);
|
||||
proof.C_p = Pairing.G1Point(c_p[0], c_p[1]);
|
||||
proof.H = Pairing.G1Point(h[0], h[1]);
|
||||
proof.K = Pairing.G1Point(k[0], k[1]);
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
Verified("Transaction successfully verified.");
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue