use std::io::Read;
use ark_ec::pairing::Pairing;
use ark_groth16::VerifyingKey;
use ark_serde_compat::CanonicalJsonSerialize;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct VerificationKey<P: Pairing + CanonicalJsonSerialize> {
pub protocol: String,
#[serde(rename = "nPublic")]
pub n_public: usize,
#[serde(rename = "vk_alpha_1")]
#[serde(serialize_with = "P::serialize_g1::<_>")]
#[serde(deserialize_with = "P::deserialize_g1::<_>")]
pub alpha_1: P::G1Affine,
#[serde(rename = "vk_beta_2")]
#[serde(serialize_with = "P::serialize_g2::<_>")]
#[serde(deserialize_with = "P::deserialize_g2::<_>")]
pub beta_2: P::G2Affine,
#[serde(rename = "vk_gamma_2")]
#[serde(serialize_with = "P::serialize_g2::<_>")]
#[serde(deserialize_with = "P::deserialize_g2::<_>")]
pub gamma_2: P::G2Affine,
#[serde(rename = "vk_delta_2")]
#[serde(serialize_with = "P::serialize_g2::<_>")]
#[serde(deserialize_with = "P::deserialize_g2::<_>")]
pub delta_2: P::G2Affine,
#[serde(rename = "vk_alphabeta_12")]
#[serde(serialize_with = "P::serialize_gt::<_>")]
#[serde(deserialize_with = "P::deserialize_gt::<_>")]
pub alpha_beta_gt: P::TargetField,
#[serde(rename = "IC")]
#[serde(serialize_with = "P::serialize_g1_seq::<_>")]
#[serde(deserialize_with = "P::deserialize_g1_seq::<_>")]
pub ic: Vec<P::G1Affine>,
}
impl<P: Pairing + CanonicalJsonSerialize> VerificationKey<P> {
pub fn from_reader<R: Read>(r: R) -> Result<Self, serde_json::Error> {
serde_json::from_reader(r)
}
}
impl<P: Pairing + CanonicalJsonSerialize> From<VerificationKey<P>> for VerifyingKey<P> {
fn from(vk: VerificationKey<P>) -> Self {
VerifyingKey {
alpha_g1: vk.alpha_1,
beta_g2: vk.beta_2,
gamma_g2: vk.gamma_2,
delta_g2: vk.delta_2,
gamma_abc_g1: vk.ic,
}
}
}
#[cfg(test)]
#[cfg(feature = "bn254")]
mod bn254_test {
use crate::test_utils;
use ark_bn254::Bn254;
use crate::{groth16::VerificationKey, tests::groth16_bn254_kats};
use std::str::FromStr;
#[test]
fn can_serde_vk_bn254() {
let groth16_bn254_kats = groth16_bn254_kats();
let vk_string =
std::fs::read_to_string(groth16_bn254_kats.join("verification_key.json")).unwrap();
let vk = serde_json::from_str::<VerificationKey<Bn254>>(&vk_string).unwrap();
let alpha_1 = test_utils::to_g1_bn254!(
"16899422092493380665487369855810985762968608626455123789954325961085508316984",
"11126583514615198837401836505802377658281069969464374246623821884538475740573"
);
let beta_2 = test_utils::to_g2_bn254!(
{ "10507543441632391771444308193378912964353702039245296649929512844719350719061", "18201322790656668038537601329094316169506292175603805191741014817443184049262"},
{ "5970405197328671009015216309153477729292937823545171027250144292199028398006", "207690659672174295265842461226025308763643182574816306177651013602294932409"}
);
let gamma_2 = test_utils::to_g2_bn254!(
{ "10857046999023057135944570762232829481370756359578518086990519993285655852781", "11559732032986387107991004021392285783925812861821192530917403151452391805634"},
{ "8495653923123431417604973247489272438418190587263600148770280649306958101930", "4082367875863433681332203403145435568316851327593401208105741076214120093531"}
);
let delta_2 = test_utils::to_g2_bn254!(
{ "16155635570759079539128338844496116072647798864000233687303657902717776158999", "146722472349298011683444548694315820674090918095096001856936731325601586110"},
{ "7220557679759413200896918190625936046017159618724594116959480938714251928850", "3740741795440491235944811815904112252316619638122978144672498770442910025884"}
);
let ic = vec![
test_utils::to_g1_bn254!(
"17064056514210178269621297150176790945669784643731237949186503569701111845663",
"5160771857172547017310246971961987180872028348077571247747329170768684330052"
),
test_utils::to_g1_bn254!(
"19547536507588365344778723326587455846790642159887261127893730469532513538882",
"10737415594461993507153866894812637432840367562913937920244709428556226500845"
),
];
let alpha_beta_gt = ark_bn254::Fq12::new(
ark_bn254::Fq6::new(
ark_bn254::Fq2::new(
ark_bn254::Fq::from_str("16538785791976368996028573001047494279971959674976400375908002449802111164210").unwrap(),
ark_bn254::Fq::from_str("17311099400175814384162244991310888068564323701034150916749873601372080366545").unwrap(),
),
ark_bn254::Fq2::new(
ark_bn254::Fq::from_str("6190374261283519082602974907779713353906416008756241816830276080558497621488").unwrap(),
ark_bn254::Fq::from_str("5946497939975323131559609840334502947229444050838397884136261522455069934142").unwrap(),
),
ark_bn254::Fq2::new(
ark_bn254::Fq::from_str("18660892217118600624251818120445899943943785636603359483071997396426302577570").unwrap(),
ark_bn254::Fq::from_str("18531687330071011377875481700311081568396123435430215454992195853578365394388").unwrap(),
)),
ark_bn254::Fq6::new(
ark_bn254::Fq2::new(
ark_bn254::Fq::from_str("5476127288440774450864859467181646064764995969290605718134676080503271266731").unwrap(),
ark_bn254::Fq::from_str("3399564724672231262367838805943403806290653366654941312613814022309517035043").unwrap(),
),
ark_bn254::Fq2::new(
ark_bn254::Fq::from_str("4672701693668323185944980624424920973243633836894733786127181806645734926322").unwrap(),
ark_bn254::Fq::from_str("7402927066587580894909225234727377776130731489482028867669208914818027294939").unwrap(),
),
ark_bn254::Fq2::new(
ark_bn254::Fq::from_str("11345717037360228259307455612221550284384863263968564709545071871541242621150").unwrap(),
ark_bn254::Fq::from_str("13027534640849390915265700715948188003828506929766238127775224004400946253786").unwrap(),
)));
assert_eq!(vk.protocol, "groth16");
assert_eq!(vk.n_public, 1);
assert_eq!(vk.alpha_1, alpha_1);
assert_eq!(vk.beta_2, beta_2);
assert_eq!(vk.gamma_2, gamma_2);
assert_eq!(vk.delta_2, delta_2);
assert_eq!(vk.alpha_beta_gt, alpha_beta_gt);
assert_eq!(vk.ic, ic);
let ser_vk = serde_json::to_string(&vk).unwrap();
let der_vk = serde_json::from_str::<VerificationKey<Bn254>>(&ser_vk).unwrap();
assert_eq!(der_vk, vk);
}
}
#[cfg(test)]
#[cfg(feature = "bls12-381")]
mod bls12_381_test {
use std::str::FromStr;
use crate::test_utils;
use super::VerificationKey;
use crate::tests::groth16_bls12_381_kats;
use ark_bls12_381::Bls12_381;
#[test]
#[cfg(feature = "bls12-381")]
fn can_serde_vk_bls12_381() {
let groth16_bls12_381_kats = groth16_bls12_381_kats();
let vk_string =
std::fs::read_to_string(groth16_bls12_381_kats.join("verification_key.json")).unwrap();
let vk = serde_json::from_str::<VerificationKey<Bls12_381>>(&vk_string).unwrap();
let alpha_1 = test_utils::to_g1_bls12_381!(
"573513743870798705896078935465463988747193691665514373553428213826028808426481266659437596949247877550493216010640",
"3195692015363680281472407569911592878057544540747596023043039898101401350267601241530895953964131482377769738361054"
);
let beta_2 = test_utils::to_g2_bls12_381!(
{ "1213509159032791114787919253810063723698125343911375817823407964507894154588429618034348468252648939670896208579873", "1573371412929811557753878280884507253544333246060733954030366147593600651713802914366664802456680232238300886611563"},
{ "227372997676533734391726211114649274508389438640619116602997243907961458158899171192162581346407208971296972028627", "3173649281634920042594077931157174670855523098488107297282865037955359011267273317056899941445467620214571651786849"}
);
let gamma_2 = test_utils::to_g2_bls12_381!(
{ "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160", "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758"},
{ "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905", "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582"}
);
let delta_2 = test_utils::to_g2_bls12_381!(
{ "1225439548733361287866553883695456824469134186836570397762131498241583159823035296217074111710636342557133382852358", "2605368487020759648403319793196297851010839805929073625099854787778388904778675959353258883417612421791844637077008"},
{ "1154742119857928659368603772369477002539216605293799365584478673152507602473688973931247635774944414206241097299617", "3083613843092389681361977317882198510817133309742782178582263450336527557948727917944434768179612190551923309894740"}
);
let ic = vec![
test_utils::to_g1_bls12_381!(
"1496325678302426440401133733502043551289869837205655668080008848699551523921245028359850882036392240986058622892606",
"1817947725837285375871533104780166089829860102882637736910105269739240593327578312097322455849119517519139026844600"
),
test_utils::to_g1_bls12_381!(
"1718008724910268123339696488143341961797261917931626884153637247409759465219924679458496161324559634841879674394994",
"1374573688907712469603830822734104311026384172354584262904362700919219617284680686401889337872942140366529825919103"
),
];
let alpha_beta_gt = ark_bls12_381::Fq12::new(
ark_bls12_381::Fq6::new(
ark_bls12_381::Fq2::new(
ark_bls12_381::Fq::from_str("3426206260164739717251301050836450446272788847665758859792043696763965142214765873633538485020729400216151666369916").unwrap(),
ark_bls12_381::Fq::from_str("3302905821964069651826570399970992298757253274554755094428043026707855995911990478373290331459067497769869076804692").unwrap(),
),
ark_bls12_381::Fq2::new(
ark_bls12_381::Fq::from_str("3341741925197178969628078584898626374239424719347918618051814256401232214624764228918336903295697250041874183026953").unwrap(),
ark_bls12_381::Fq::from_str("3049530629856295411922538290278377288433683510160899068732135510374047492051320353748966405581434200795943001265698").unwrap(),
),
ark_bls12_381::Fq2::new(
ark_bls12_381::Fq::from_str("119957832779228556734893577556894434260913253291862526433137528213961786701320640345096805403160954913056649513659").unwrap(),
ark_bls12_381::Fq::from_str("3449648129239458233379559341036050782107226110618632498004835099130249815018931424285727567073991590904426359911010").unwrap(),
)),
ark_bls12_381::Fq6::new(
ark_bls12_381::Fq2::new(
ark_bls12_381::Fq::from_str("782679613215087138195107428934265275754328138002469766499180898383795360891987634262285201345126183624241376694383").unwrap(),
ark_bls12_381::Fq::from_str("2292345180186296398615963393473076941560700467992311445603207795848142440522290136219412300965109286381992330148").unwrap(),
),
ark_bls12_381::Fq2::new(
ark_bls12_381::Fq::from_str("960143589460992063893724434040957098401339018007122975228797469321024716444113662816346644525584332133943576279012").unwrap(),
ark_bls12_381::Fq::from_str("3729324641017761386323645877587187523466589607676793132334511964903429670740473430270328545717478877434534869350645").unwrap(),
),
ark_bls12_381::Fq2::new(
ark_bls12_381::Fq::from_str("1870388516961111788736169836636048611100105041008953211013579724636674061079883646738605250003717737291366865842426").unwrap(),
ark_bls12_381::Fq::from_str("3988361102892232342629689285346924532881936157425416548691446154501639146823564430648915954890776187454089346713099").unwrap(),
)));
assert_eq!(vk.protocol, "groth16");
assert_eq!(vk.n_public, 1);
assert_eq!(vk.alpha_1, alpha_1);
assert_eq!(vk.beta_2, beta_2);
assert_eq!(vk.gamma_2, gamma_2);
assert_eq!(vk.delta_2, delta_2);
assert_eq!(vk.alpha_beta_gt, alpha_beta_gt);
assert_eq!(vk.ic, ic);
let ser_vk = serde_json::to_string(&vk).unwrap();
let der_vk = serde_json::from_str::<VerificationKey<Bls12_381>>(&ser_vk).unwrap();
assert_eq!(der_vk, vk);
}
}
#[cfg(test)]
mod test {}