diff --git a/plonk-napi/src/lib.rs b/plonk-napi/src/lib.rs index f0c304a7b9..00400e52b0 100644 --- a/plonk-napi/src/lib.rs +++ b/plonk-napi/src/lib.rs @@ -1,4 +1,5 @@ mod circuit; +pub mod plonk_verifier_index; mod poseidon; mod types; diff --git a/plonk-napi/src/plonk_verifier_index/fp.rs b/plonk-napi/src/plonk_verifier_index/fp.rs new file mode 100644 index 0000000000..147a656c43 --- /dev/null +++ b/plonk-napi/src/plonk_verifier_index/fp.rs @@ -0,0 +1,121 @@ +use ark_poly::{EvaluationDomain, Radix2EvaluationDomain as Domain}; +use ark_serialize::CanonicalSerialize; +use kimchi::circuits::polynomials::permutation::Shifts as KimchiShifts; +use mina_curves::pasta::Fp; +use napi::bindgen_prelude::{Error, Result as NapiResult, Status}; +use napi_derive::napi; +use serde::{Deserialize, Serialize}; + +use super::WasmLookupInfo; + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFpDomain { + pub log_size_of_group: i32, + pub group_gen: Vec, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFpPolyComm { + pub unshifted: Vec>, + pub shifted: Option>, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFpShifts { + pub s0: Vec, + pub s1: Vec, + pub s2: Vec, + pub s3: Vec, + pub s4: Vec, + pub s5: Vec, + pub s6: Vec, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFpLookupSelectors { + pub xor: Option, + pub lookup: Option, + pub range_check: Option, + pub ffmul: Option, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFpLookupVerifierIndex { + pub joint_lookup_used: bool, + pub lookup_table: Vec, + pub lookup_selectors: WasmFpLookupSelectors, + pub table_ids: Option, + pub lookup_info: WasmLookupInfo, + pub runtime_tables_selector: Option, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFpPlonkVerificationEvals { + pub sigma_comm: Vec, + pub coefficients_comm: Vec, + pub generic_comm: WasmFpPolyComm, + pub psm_comm: WasmFpPolyComm, + pub complete_add_comm: WasmFpPolyComm, + pub mul_comm: WasmFpPolyComm, + pub emul_comm: WasmFpPolyComm, + pub endomul_scalar_comm: WasmFpPolyComm, + pub xor_comm: Option, + pub range_check0_comm: Option, + pub range_check1_comm: Option, + pub foreign_field_add_comm: Option, + pub foreign_field_mul_comm: Option, + pub rot_comm: Option, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFpPlonkVerifierIndex { + pub domain: WasmFpDomain, + pub max_poly_size: i32, + pub public_: i32, + pub prev_challenges: i32, + pub srs: Vec, + pub evals: WasmFpPlonkVerificationEvals, + pub shifts: WasmFpShifts, + pub lookup_index: Option, + pub zk_rows: i32, +} + +#[napi] +pub fn caml_pasta_fp_plonk_verifier_index_shifts(log2_size: i32) -> NapiResult { + println!( + "from napi! caml_pasta_fp_plonk_verifier_index_shifts with log2_size {}", + log2_size + ); + + let size = 1usize << (log2_size as u32); + let domain = Domain::::new(size) + .ok_or_else(|| Error::new(Status::InvalidArg, "failed to create evaluation domain"))?; + + let shifts = KimchiShifts::new(&domain); + let s = shifts.shifts(); + + Ok(WasmFpShifts { + s0: serialize_fp(&s[0])?, + s1: serialize_fp(&s[1])?, + s2: serialize_fp(&s[2])?, + s3: serialize_fp(&s[3])?, + s4: serialize_fp(&s[4])?, + s5: serialize_fp(&s[5])?, + s6: serialize_fp(&s[6])?, + }) +} + +fn serialize_fp(value: &Fp) -> NapiResult> { + let mut bytes = Vec::new(); + value + .serialize_compressed(&mut bytes) + .map_err(|err| Error::new(Status::GenericFailure, format!("serialize_fp: {err}")))?; + Ok(bytes) +} diff --git a/plonk-napi/src/plonk_verifier_index/fq.rs b/plonk-napi/src/plonk_verifier_index/fq.rs new file mode 100644 index 0000000000..efcfc72508 --- /dev/null +++ b/plonk-napi/src/plonk_verifier_index/fq.rs @@ -0,0 +1,121 @@ +use ark_poly::{EvaluationDomain, Radix2EvaluationDomain as Domain}; +use ark_serialize::CanonicalSerialize; +use kimchi::circuits::polynomials::permutation::Shifts as KimchiShifts; +use mina_curves::pasta::Fq; +use napi::bindgen_prelude::{Error, Result as NapiResult, Status}; +use napi_derive::napi; +use serde::{Deserialize, Serialize}; + +use super::WasmLookupInfo; + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFqDomain { + pub log_size_of_group: i32, + pub group_gen: Vec, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFqPolyComm { + pub unshifted: Vec>, + pub shifted: Option>, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFqShifts { + pub s0: Vec, + pub s1: Vec, + pub s2: Vec, + pub s3: Vec, + pub s4: Vec, + pub s5: Vec, + pub s6: Vec, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFqLookupSelectors { + pub xor: Option, + pub lookup: Option, + pub range_check: Option, + pub ffmul: Option, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFqLookupVerifierIndex { + pub joint_lookup_used: bool, + pub lookup_table: Vec, + pub lookup_selectors: WasmFqLookupSelectors, + pub table_ids: Option, + pub lookup_info: WasmLookupInfo, + pub runtime_tables_selector: Option, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFqPlonkVerificationEvals { + pub sigma_comm: Vec, + pub coefficients_comm: Vec, + pub generic_comm: WasmFqPolyComm, + pub psm_comm: WasmFqPolyComm, + pub complete_add_comm: WasmFqPolyComm, + pub mul_comm: WasmFqPolyComm, + pub emul_comm: WasmFqPolyComm, + pub endomul_scalar_comm: WasmFqPolyComm, + pub xor_comm: Option, + pub range_check0_comm: Option, + pub range_check1_comm: Option, + pub foreign_field_add_comm: Option, + pub foreign_field_mul_comm: Option, + pub rot_comm: Option, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmFqPlonkVerifierIndex { + pub domain: WasmFqDomain, + pub max_poly_size: i32, + pub public_: i32, + pub prev_challenges: i32, + pub srs: Vec, + pub evals: WasmFqPlonkVerificationEvals, + pub shifts: WasmFqShifts, + pub lookup_index: Option, + pub zk_rows: i32, +} + +#[napi] +pub fn caml_pasta_fq_plonk_verifier_index_shifts(log2_size: i32) -> NapiResult { + println!( + "from napi! caml_pasta_fp_plonk_verifier_index_shifts with log2_size {}", + log2_size + ); + + let size = 1usize << (log2_size as u32); + let domain = Domain::::new(size) + .ok_or_else(|| Error::new(Status::InvalidArg, "failed to create evaluation domain"))?; + + let shifts = KimchiShifts::new(&domain); + let s = shifts.shifts(); + + Ok(WasmFqShifts { + s0: serialize_fp(&s[0])?, + s1: serialize_fp(&s[1])?, + s2: serialize_fp(&s[2])?, + s3: serialize_fp(&s[3])?, + s4: serialize_fp(&s[4])?, + s5: serialize_fp(&s[5])?, + s6: serialize_fp(&s[6])?, + }) +} + +fn serialize_fp(value: &Fq) -> NapiResult> { + let mut bytes = Vec::new(); + value + .serialize_uncompressed(&mut bytes) + .map_err(|err| Error::new(Status::GenericFailure, format!("serialize_fp: {err}")))?; + Ok(bytes) +} diff --git a/plonk-napi/src/plonk_verifier_index/mod.rs b/plonk-napi/src/plonk_verifier_index/mod.rs new file mode 100644 index 0000000000..2ed532c7d4 --- /dev/null +++ b/plonk-napi/src/plonk_verifier_index/mod.rs @@ -0,0 +1,35 @@ +use napi_derive::napi; +use serde::{Deserialize, Serialize}; + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmLookupPatterns { + pub xor: bool, + pub lookup: bool, + pub range_check: bool, + pub foreign_field_mul: bool, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmLookupFeatures { + pub patterns: WasmLookupPatterns, + pub joint_lookup_used: bool, + pub uses_runtime_tables: bool, +} + +#[napi(object)] +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct WasmLookupInfo { + pub max_per_row: i32, + pub max_joint_size: i32, + pub features: WasmLookupFeatures, +} + +pub mod fp; +pub mod fq; + +#[allow(unused_imports)] +pub use fp::*; +#[allow(unused_imports)] +pub use fq::*;