remove pghr13
This commit is contained in:
parent
9e1cb8a07e
commit
792ce87561
10 changed files with 4 additions and 299 deletions
1
changelogs/unreleased/1181-schaeff
Normal file
1
changelogs/unreleased/1181-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Drop support for PGHR13 proving scheme
|
|
@ -28,7 +28,6 @@ ZoKrates supports different proving schemes. We identify the schemes by the refe
|
|||
| [G16](https://eprint.iacr.org/2016/260) | `--proving-scheme g16` | ALTBN_128, BLS12_381 | No |
|
||||
| [GM17](https://eprint.iacr.org/2017/540) | `--proving-scheme gm17` | ALTBN_128, BLS12_381, BLS12_377, BW6_761 | No |
|
||||
| [Marlin](https://eprint.iacr.org/2019/1047) | `--proving-scheme marlin` | ALTBN_128, BLS12_381, BLS12_377, BW6_761 | Yes |
|
||||
| [PGHR13](https://eprint.iacr.org/2013/279) | `--proving-scheme pghr13` | ALTBN_128 | No |
|
||||
|
||||
All schemes have a circuit-specific setup phase called `setup`. Universal schemes also feature a preliminary, circuit-agnostic step called `universal-setup`. The advantage of universal schemes is that only the `universal-setup` step requires trust, so that it can be run a single time and reused trustlessly for many programs.
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::path::Path;
|
|||
use zokrates_common::helpers::{CurveParameter, SchemeParameter};
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_proof_systems::{
|
||||
Marlin, Proof, SolidityCompatibleField, SolidityCompatibleScheme, G16, GM17, PGHR13,
|
||||
Marlin, Proof, SolidityCompatibleField, SolidityCompatibleScheme, G16, GM17,
|
||||
};
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
|
@ -62,9 +62,6 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
(curve.try_into().unwrap(), scheme.try_into().unwrap());
|
||||
|
||||
match parameters {
|
||||
(CurveParameter::Bn128, SchemeParameter::PGHR13) => {
|
||||
cli_print_proof::<Bn128Field, PGHR13>(sub_matches, proof)
|
||||
}
|
||||
(CurveParameter::Bn128, SchemeParameter::G16) => {
|
||||
cli_print_proof::<Bn128Field, G16>(sub_matches, proof)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ mod integration {
|
|||
use zokrates_ast::typed::abi::Abi;
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_proof_systems::{
|
||||
to_token::ToToken, Marlin, Proof, SolidityCompatibleScheme, G16, GM17, PGHR13,
|
||||
to_token::ToToken, Marlin, Proof, SolidityCompatibleScheme, G16, GM17,
|
||||
SOLIDITY_G2_ADDITION_LIB,
|
||||
};
|
||||
|
||||
|
@ -343,15 +343,6 @@ mod integration {
|
|||
|
||||
test_solidity_verifier(contract_str, proof);
|
||||
}
|
||||
"pghr13" => {
|
||||
// Get the proof
|
||||
let proof: Proof<Bn128Field, PGHR13> = serde_json::from_reader(
|
||||
File::open(proof_path.to_str().unwrap()).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
test_solidity_verifier(contract_str, proof);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,4 +9,3 @@ pub const BW6_761: &str = "bw6_761";
|
|||
pub const G16: &str = "g16";
|
||||
pub const GM17: &str = "gm17";
|
||||
pub const MARLIN: &str = "marlin";
|
||||
pub const PGHR13: &str = "pghr13";
|
||||
|
|
|
@ -48,7 +48,6 @@ impl std::fmt::Display for BackendParameter {
|
|||
pub enum SchemeParameter {
|
||||
G16,
|
||||
GM17,
|
||||
PGHR13,
|
||||
MARLIN,
|
||||
}
|
||||
|
||||
|
@ -59,7 +58,6 @@ impl std::fmt::Display for SchemeParameter {
|
|||
match self {
|
||||
G16 => write!(f, "g16"),
|
||||
GM17 => write!(f, "gm17"),
|
||||
PGHR13 => write!(f, "pghr13"),
|
||||
MARLIN => write!(f, "marlin"),
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +98,6 @@ impl TryFrom<&str> for SchemeParameter {
|
|||
match s {
|
||||
G16 => Ok(SchemeParameter::G16),
|
||||
GM17 => Ok(SchemeParameter::GM17),
|
||||
PGHR13 => Ok(SchemeParameter::PGHR13),
|
||||
MARLIN => Ok(SchemeParameter::MARLIN),
|
||||
_ => Err(format!("Unknown proving scheme {}", s)),
|
||||
}
|
||||
|
@ -151,6 +148,7 @@ impl TryFrom<(&str, &str, &str)> for Parameters {
|
|||
(BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::MARLIN) => Ok(()),
|
||||
#[cfg(feature = "ark")]
|
||||
(BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::MARLIN) => Ok(()),
|
||||
#[cfg(feature = "bellman")]
|
||||
_ => Err(format!(
|
||||
"Unsupported combination of parameters (backend: {}, curve: {}, proving scheme: {})",
|
||||
s.0, s.1, s.2
|
||||
|
|
|
@ -551,7 +551,6 @@ pub fn generate_proof(
|
|||
internal::generate_proof::<_, Marlin, Ark>(p, witness, pk)
|
||||
}
|
||||
},
|
||||
_ => Err(JsValue::from_str("Unsupported scheme")),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -620,7 +619,6 @@ pub fn verify(vk: JsValue, proof: JsValue) -> Result<JsValue, JsValue> {
|
|||
CurveParameter::Bls12_377 => internal::verify::<Bls12_377Field, Marlin, Ark>(vk, proof),
|
||||
CurveParameter::Bw6_761 => internal::verify::<Bw6_761Field, Marlin, Ark>(vk, proof),
|
||||
},
|
||||
_ => Err(JsValue::from_str("Unsupported scheme")),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,10 @@ use zokrates_field::Field;
|
|||
pub mod gm17;
|
||||
pub mod groth16;
|
||||
pub mod marlin;
|
||||
pub mod pghr13;
|
||||
|
||||
pub use self::gm17::GM17;
|
||||
pub use self::groth16::G16;
|
||||
pub use self::marlin::Marlin;
|
||||
pub use self::pghr13::PGHR13;
|
||||
|
||||
pub trait Scheme<T: Field>: Serialize {
|
||||
const NAME: &'static str;
|
||||
|
|
|
@ -1,219 +0,0 @@
|
|||
use crate::scheme::{NonUniversalScheme, Scheme};
|
||||
use crate::solidity::solidity_pairing_lib;
|
||||
use crate::{G1Affine, G2Affine, SolidityCompatibleField, SolidityCompatibleScheme};
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zokrates_field::Field;
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(Serialize)]
|
||||
pub struct PGHR13;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct ProofPoints<G1, G2> {
|
||||
pub a: G1,
|
||||
pub a_p: G1,
|
||||
pub b: G2,
|
||||
pub b_p: G1,
|
||||
pub c: G1,
|
||||
pub c_p: G1,
|
||||
pub h: G1,
|
||||
pub k: G1,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct VerificationKey<G1, G2> {
|
||||
pub a: G2,
|
||||
pub b: G1,
|
||||
pub c: G2,
|
||||
pub gamma: G2,
|
||||
pub gamma_beta_1: G1,
|
||||
pub gamma_beta_2: G2,
|
||||
pub z: G2,
|
||||
pub ic: Vec<G1>,
|
||||
}
|
||||
|
||||
impl<T: Field> Scheme<T> for PGHR13 {
|
||||
const NAME: &'static str = "pghr13";
|
||||
|
||||
type VerificationKey = VerificationKey<G1Affine, G2Affine>;
|
||||
type ProofPoints = ProofPoints<G1Affine, G2Affine>;
|
||||
}
|
||||
|
||||
impl<T: Field> NonUniversalScheme<T> for PGHR13 {}
|
||||
|
||||
impl<T: SolidityCompatibleField> SolidityCompatibleScheme<T> for PGHR13 {
|
||||
type Proof = Self::ProofPoints;
|
||||
|
||||
fn export_solidity_verifier(vk: <PGHR13 as Scheme<T>>::VerificationKey) -> String {
|
||||
let (mut template_text, solidity_pairing_lib) =
|
||||
(String::from(CONTRACT_TEMPLATE), solidity_pairing_lib(false));
|
||||
|
||||
// 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_repeat_regex = Regex::new(r#"(<%vk_ic_pts%>)"#).unwrap();
|
||||
let vk_input_len_regex = Regex::new(r#"(<%vk_input_length%>)"#).unwrap();
|
||||
let input_loop = Regex::new(r#"(<%input_loop%>)"#).unwrap();
|
||||
let input_argument = Regex::new(r#"(<%input_argument%>)"#).unwrap();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.a.to_string().as_str())
|
||||
.into_owned();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.b.to_string().as_str())
|
||||
.into_owned();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.c.to_string().as_str())
|
||||
.into_owned();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.gamma.to_string().as_str())
|
||||
.into_owned();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.gamma_beta_1.to_string().as_str())
|
||||
.into_owned();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.gamma_beta_2.to_string().as_str())
|
||||
.into_owned();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.z.to_string().as_str())
|
||||
.into_owned();
|
||||
|
||||
let ic_count: usize = vk.ic.len();
|
||||
template_text = vk_ic_len_regex
|
||||
.replace(template_text.as_str(), format!("{}", ic_count).as_str())
|
||||
.into_owned();
|
||||
|
||||
template_text = vk_input_len_regex
|
||||
.replace(template_text.as_str(), format!("{}", ic_count - 1).as_str())
|
||||
.into_owned();
|
||||
|
||||
// feed input values only if there are any
|
||||
template_text = if ic_count > 1 {
|
||||
input_loop.replace(
|
||||
template_text.as_str(),
|
||||
r#"
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}"#,
|
||||
)
|
||||
} else {
|
||||
input_loop.replace(template_text.as_str(), "")
|
||||
}
|
||||
.to_string();
|
||||
|
||||
// take input values as argument only if there are any
|
||||
template_text = if ic_count > 1 {
|
||||
input_argument.replace(
|
||||
template_text.as_str(),
|
||||
format!(", uint[{}] memory input", ic_count - 1).as_str(),
|
||||
)
|
||||
} else {
|
||||
input_argument.replace(template_text.as_str(), "")
|
||||
}
|
||||
.to_string();
|
||||
|
||||
let mut ic_repeat_text = String::new();
|
||||
for (i, g1) in vk.ic.iter().enumerate() {
|
||||
ic_repeat_text.push_str(
|
||||
format!(
|
||||
"vk.ic[{}] = Pairing.G1Point({});",
|
||||
i,
|
||||
g1.to_string().as_str()
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
if i < 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();
|
||||
|
||||
let re = Regex::new(r"(?P<v>0[xX][0-9a-fA-F]{64})").unwrap();
|
||||
template_text = re.replace_all(&template_text, "uint256($v)").to_string();
|
||||
|
||||
format!("{}{}", solidity_pairing_lib, template_text)
|
||||
}
|
||||
}
|
||||
|
||||
const CONTRACT_TEMPLATE: &str = r#"contract Verifier {
|
||||
using Pairing for *;
|
||||
struct VerifyingKey {
|
||||
Pairing.G2Point a;
|
||||
Pairing.G1Point b;
|
||||
Pairing.G2Point c;
|
||||
Pairing.G2Point gamma;
|
||||
Pairing.G1Point gamma_beta_1;
|
||||
Pairing.G2Point gamma_beta_2;
|
||||
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 h;
|
||||
Pairing.G1Point k;
|
||||
}
|
||||
function verifyingKey() pure internal returns (VerifyingKey memory vk) {
|
||||
vk.a = Pairing.G2Point(<%vk_a%>);
|
||||
vk.b = Pairing.G1Point(<%vk_b%>);
|
||||
vk.c = Pairing.G2Point(<%vk_c%>);
|
||||
vk.gamma = Pairing.G2Point(<%vk_g%>);
|
||||
vk.gamma_beta_1 = Pairing.G1Point(<%vk_gb1%>);
|
||||
vk.gamma_beta_2 = Pairing.G2Point(<%vk_gb2%>);
|
||||
vk.z = Pairing.G2Point(<%vk_z%>);
|
||||
vk.ic = new Pairing.G1Point[](<%vk_ic_length%>);
|
||||
<%vk_ic_pts%>
|
||||
}
|
||||
function verify(uint[] memory input, Proof memory proof) internal view returns (uint) {
|
||||
uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||
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++) {
|
||||
require(input[i] < snark_scalar_field);
|
||||
vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.ic[i + 1], input[i]));
|
||||
}
|
||||
vk_x = Pairing.addition(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.addition(vk_x, Pairing.addition(proof.a, proof.c))), vk.gamma_beta_2,
|
||||
Pairing.negate(vk.gamma_beta_1), proof.b
|
||||
)) return 4;
|
||||
if (!Pairing.pairingProd3(
|
||||
Pairing.addition(vk_x, proof.a), proof.b,
|
||||
Pairing.negate(proof.h), vk.z,
|
||||
Pairing.negate(proof.c), Pairing.P2()
|
||||
)) return 5;
|
||||
return 0;
|
||||
}
|
||||
function verifyTx(
|
||||
Proof memory proof<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
uint[] memory inputValues = new uint[](<%vk_input_length%>);
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
|
@ -3,7 +3,6 @@ use primitive_types::U256;
|
|||
|
||||
use super::{
|
||||
Fr, G1Affine, G2Affine, Marlin, SolidityCompatibleField, SolidityCompatibleScheme, G16, GM17,
|
||||
PGHR13,
|
||||
};
|
||||
|
||||
/// Helper methods for parsing group structure
|
||||
|
@ -40,62 +39,6 @@ pub trait ToToken<T: SolidityCompatibleField>: SolidityCompatibleScheme<T> {
|
|||
fn modify(proof: Self::Proof) -> Self::Proof;
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField> ToToken<T> for PGHR13 {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let a = {
|
||||
let (x, y) = encode_g1_element(&proof.a);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let a_p = {
|
||||
let (x, y) = encode_g1_element(&proof.a_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let b = {
|
||||
let ((x0, y0), (x1, y1)) = encode_g2_element(&proof.b);
|
||||
Token::Tuple(vec![
|
||||
Token::FixedArray(vec![Token::Uint(x0), Token::Uint(y0)]),
|
||||
Token::FixedArray(vec![Token::Uint(x1), Token::Uint(y1)]),
|
||||
])
|
||||
};
|
||||
|
||||
let b_p = {
|
||||
let (x, y) = encode_g1_element(&proof.b_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let c = {
|
||||
let (x, y) = encode_g1_element(&proof.c);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let c_p = {
|
||||
let (x, y) = encode_g1_element(&proof.c_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let h = {
|
||||
let (x, y) = encode_g1_element(&proof.h);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let k = {
|
||||
let (x, y) = encode_g1_element(&proof.k);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![a, a_p, b, b_p, c, c_p, h, k];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
|
||||
fn modify(mut proof: Self::Proof) -> Self::Proof {
|
||||
proof.a.0 = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".into();
|
||||
proof
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField> ToToken<T> for G16 {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let a = {
|
||||
|
|
Loading…
Reference in a new issue