From ca879be8b3254a6dde9c85c33e68dfd6e7cb3f21 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 10:00:20 +0100 Subject: [PATCH 01/10] Use ArkTranscript by default --- w3f-ring-proof/src/ring_prover.rs | 4 ++-- w3f-ring-proof/src/ring_verifier.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/w3f-ring-proof/src/ring_prover.rs b/w3f-ring-proof/src/ring_prover.rs index 65837d5..5e951b2 100644 --- a/w3f-ring-proof/src/ring_prover.rs +++ b/w3f-ring-proof/src/ring_prover.rs @@ -7,9 +7,9 @@ use w3f_plonk_common::transcript::PlonkTranscript; use crate::piop::params::PiopParams; use crate::piop::{FixedColumns, PiopProver, ProverKey}; -use crate::RingProof; +use crate::{ArkTranscript, RingProof}; -pub struct RingProver +pub struct RingProver where F: PrimeField, CS: PCS, diff --git a/w3f-ring-proof/src/ring_verifier.rs b/w3f-ring-proof/src/ring_verifier.rs index 296392f..0394854 100644 --- a/w3f-ring-proof/src/ring_verifier.rs +++ b/w3f-ring-proof/src/ring_verifier.rs @@ -10,9 +10,9 @@ use w3f_plonk_common::verifier::PlonkVerifier; use crate::piop::params::PiopParams; use crate::piop::{FixedColumnsCommitted, PiopVerifier, VerifierKey}; -use crate::RingProof; +use crate::{ArkTranscript, RingProof}; -pub struct RingVerifier +pub struct RingVerifier where F: PrimeField, CS: PCS, From c472991a6afda46fdfc172e2460396f82fe5f0b3 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 10:00:29 +0100 Subject: [PATCH 02/10] Test vectors feat --- w3f-ring-proof/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/w3f-ring-proof/Cargo.toml b/w3f-ring-proof/Cargo.toml index c7e1c1f..ecd228a 100644 --- a/w3f-ring-proof/Cargo.toml +++ b/w3f-ring-proof/Cargo.toml @@ -49,3 +49,4 @@ print-trace = [ "w3f-plonk-common/print-trace" ] asm = [ "w3f-pcs/asm" ] +test-vectors = [] From 23b0a00c66b99b259d61eca0a589435ef328e797 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 10:16:12 +0100 Subject: [PATCH 03/10] verify_ring_proof -> verify --- w3f-ring-proof/src/lib.rs | 2 +- w3f-ring-proof/src/ring_verifier.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/w3f-ring-proof/src/lib.rs b/w3f-ring-proof/src/lib.rs index 79ed917..50dc86b 100644 --- a/w3f-ring-proof/src/lib.rs +++ b/w3f-ring-proof/src/lib.rs @@ -121,7 +121,7 @@ mod tests { ArkTranscript::new(b"w3f-ring-proof-test"), ); let t_verify = start_timer!(|| "Verify"); - let res = ring_verifier.verify_ring_proof(proof, result.into_affine()); + let res = ring_verifier.verify(proof, result.into_affine()); end_timer!(t_verify); assert!(res); } diff --git a/w3f-ring-proof/src/ring_verifier.rs b/w3f-ring-proof/src/ring_verifier.rs index 4e71765..322c18f 100644 --- a/w3f-ring-proof/src/ring_verifier.rs +++ b/w3f-ring-proof/src/ring_verifier.rs @@ -45,7 +45,7 @@ where } } - pub fn verify_ring_proof(&self, proof: RingProof, result: Affine) -> bool { + pub fn verify(&self, proof: RingProof, result: Affine) -> bool { let (challenges, mut rng) = self.plonk_verifier.restore_challenges( &result, &proof, From 88cc2fd2f2b214421aef104cd24f330a94bbe77a Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 11:24:32 +0100 Subject: [PATCH 04/10] User supplied padding point --- w3f-ring-proof/Cargo.toml | 2 +- w3f-ring-proof/src/lib.rs | 81 ++++++++++++++++--------------- w3f-ring-proof/src/piop/params.rs | 13 +++-- w3f-ring-proof/src/ring.rs | 7 ++- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/w3f-ring-proof/Cargo.toml b/w3f-ring-proof/Cargo.toml index ecd228a..481d530 100644 --- a/w3f-ring-proof/Cargo.toml +++ b/w3f-ring-proof/Cargo.toml @@ -16,12 +16,12 @@ ark-serialize.workspace = true w3f-pcs.workspace = true rayon = { workspace = true, optional = true } w3f-plonk-common = { path="../w3f-plonk-common", default-features = false } -blake2 = { version = "0.10", default-features = false } ark-transcript = { version = "0.0.3", default-features = false } [dev-dependencies] ark-bls12-381 = { version = "0.5", default-features = false, features = ["curve"] } ark-ed-on-bls12-381-bandersnatch = { version = "0.5", default-features = false } +blake2 = { version = "0.10", default-features = false } [features] default = [ "std" ] diff --git a/w3f-ring-proof/src/lib.rs b/w3f-ring-proof/src/lib.rs index 50dc86b..637b69d 100644 --- a/w3f-ring-proof/src/lib.rs +++ b/w3f-ring-proof/src/lib.rs @@ -1,7 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -use ark_ec::twisted_edwards::{Affine, TECurveConfig}; -use ark_ec::AffineRepr; use ark_ff::PrimeField; use ark_serialize::CanonicalSerialize; use ark_std::rand::RngCore; @@ -24,26 +22,6 @@ pub type RingProof = Proof>::C>, /// Polynomial Commitment Schemes. pub use w3f_pcs::pcs; -// Try and increment hash to curve. -pub(crate) fn hash_to_curve>( - message: &[u8], -) -> Affine { - use blake2::Digest; - let mut seed = message.to_vec(); - let cnt_offset = seed.len(); - seed.push(0); - loop { - let hash: [u8; 64] = blake2::Blake2b::digest(&seed[..]).into(); - let x = F::from_le_bytes_mod_order(&hash); - if let Some(point) = Affine::::get_point_from_y_unchecked(x, false) { - let point = point.clear_cofactor(); - assert!(point.is_in_correct_subgroup_assuming_on_curve()); - return point; - } - seed[cnt_offset] += 1; - } -} - #[derive(Clone)] pub struct ArkTranscript(ark_transcript::Transcript); @@ -73,7 +51,8 @@ impl ArkTranscript { #[cfg(test)] mod tests { use ark_bls12_381::Bls12_381; - use ark_ec::CurveGroup; + use ark_ec::twisted_edwards::{Affine, TECurveConfig}; + use ark_ec::{AffineRepr, CurveGroup}; use ark_ed_on_bls12_381_bandersnatch::{BandersnatchConfig, EdwardsAffine, Fq, Fr}; use ark_std::ops::Mul; use ark_std::rand::Rng; @@ -89,6 +68,47 @@ mod tests { use super::*; + // Try and increment hash to curve. + fn hash_to_curve>( + message: &[u8], + ) -> Affine { + use blake2::Digest; + let mut seed = message.to_vec(); + let cnt_offset = seed.len(); + seed.push(0); + loop { + let hash: [u8; 64] = blake2::Blake2b::digest(&seed[..]).into(); + let x = F::from_le_bytes_mod_order(&hash); + if let Some(point) = Affine::::get_point_from_y_unchecked(x, false) { + let point = point.clear_cofactor(); + assert!(point.is_in_correct_subgroup_assuming_on_curve()); + return point; + } + seed[cnt_offset] += 1; + } + } + + pub(crate) fn padding_point>( + ) -> Affine { + hash_to_curve(b"/w3f/w3f-ring-proof/padding") + } + + fn setup>( + rng: &mut R, + domain_size: usize, + ) -> (CS::Params, PiopParams) { + let setup_degree = 3 * domain_size; + let pcs_params = CS::setup(setup_degree, rng); + + let domain = Domain::new(domain_size, true); + let h = EdwardsAffine::rand(rng); + let seed = EdwardsAffine::rand(rng); + let pad = padding_point(); + let piop_params = PiopParams::setup(domain, h, seed, pad); + + (pcs_params, piop_params) + } + fn _test_ring_proof>(domain_size: usize) { let rng = &mut test_rng(); @@ -150,21 +170,6 @@ mod tests { ); } - fn setup>( - rng: &mut R, - domain_size: usize, - ) -> (CS::Params, PiopParams) { - let setup_degree = 3 * domain_size; - let pcs_params = CS::setup(setup_degree, rng); - - let domain = Domain::new(domain_size, true); - let h = EdwardsAffine::rand(rng); - let seed = EdwardsAffine::rand(rng); - let piop_params = PiopParams::setup(domain, h, seed); - - (pcs_params, piop_params) - } - #[test] fn test_ring_proof_kzg() { _test_ring_proof::>(2usize.pow(10)); diff --git a/w3f-ring-proof/src/piop/params.rs b/w3f-ring-proof/src/piop/params.rs index b5a7111..3ae2924 100644 --- a/w3f-ring-proof/src/piop/params.rs +++ b/w3f-ring-proof/src/piop/params.rs @@ -31,8 +31,12 @@ pub struct PiopParams> { } impl> PiopParams { - pub fn setup(domain: Domain, h: Affine, seed: Affine) -> Self { - let padding_point = crate::hash_to_curve(b"/w3f/w3f-ring-proof/padding"); + pub fn setup( + domain: Domain, + h: Affine, + seed: Affine, + padding_point: Affine, + ) -> Self { let scalar_bitlen = Curve::ScalarField::MODULUS_BIT_SIZE as usize; // 1 accounts for the last cells of the points and bits columns that remain unconstrained let keyset_part_size = domain.capacity - scalar_bitlen - 1; @@ -101,14 +105,17 @@ mod tests { use w3f_plonk_common::test_helpers::cond_sum; use crate::piop::params::PiopParams; + use crate::tests::padding_point; #[test] fn test_powers_of_h() { let rng = &mut test_rng(); let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); + let pad = padding_point(); let domain = Domain::new(1024, false); - let params = PiopParams::::setup(domain, h, seed); + + let params = PiopParams::::setup(domain, h, seed, pad); let t = Fr::rand(rng); let t_bits = params.scalar_part(t); let th = cond_sum(&t_bits, ¶ms.power_of_2_multiples_of_h()); diff --git a/w3f-ring-proof/src/ring.rs b/w3f-ring-proof/src/ring.rs index a1d9350..dc99d4f 100644 --- a/w3f-ring-proof/src/ring.rs +++ b/w3f-ring-proof/src/ring.rs @@ -265,6 +265,7 @@ mod tests { use w3f_plonk_common::test_helpers::random_vec; use crate::ring::Ring; + use crate::tests::padding_point; use crate::PiopParams; use super::*; @@ -285,7 +286,8 @@ mod tests { let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); let domain = Domain::new(domain_size, true); - let piop_params = PiopParams::setup(domain, h, seed); + let pad = padding_point(); + let piop_params = PiopParams::setup(domain, h, seed, pad); let mut ring = TestRing::empty(&piop_params, srs, ring_builder_key.g1); let (monimial_cx, monimial_cy) = get_monomial_commitment(&pcs_params, &piop_params, &[]); @@ -315,8 +317,9 @@ mod tests { // piop params let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); + let pad = padding_point(); let domain = Domain::new(domain_size, true); - let piop_params = PiopParams::setup(domain, h, seed); + let piop_params = PiopParams::setup(domain, h, seed, pad); let ring = TestRing::empty(&piop_params, srs, ring_builder_key.g1); let same_ring = TestRing::with_keys(&piop_params, &[], &ring_builder_key); From 8b2cab8784ad75c735a86291b9b6c58a3062e6fa Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 12:23:11 +0100 Subject: [PATCH 05/10] Test vectors feature was not used --- w3f-plonk-common/Cargo.toml | 1 + w3f-plonk-common/src/domain.rs | 2 +- w3f-ring-proof/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/w3f-plonk-common/Cargo.toml b/w3f-plonk-common/Cargo.toml index 116b450..f1795f2 100644 --- a/w3f-plonk-common/Cargo.toml +++ b/w3f-plonk-common/Cargo.toml @@ -44,3 +44,4 @@ parallel = [ ] print-trace = ["ark-std/print-trace"] asm = ["w3f-pcs/asm"] +test-vectors = [] diff --git a/w3f-plonk-common/src/domain.rs b/w3f-plonk-common/src/domain.rs index f373b41..a096cd9 100644 --- a/w3f-plonk-common/src/domain.rs +++ b/w3f-plonk-common/src/domain.rs @@ -109,7 +109,7 @@ impl Domain { pub(crate) fn column(&self, mut evals: Vec, hidden: bool) -> FieldColumn { let len = evals.len(); assert!(len <= self.capacity); - if self.hiding && hidden { + if self.hiding && hidden && !cfg!(feature = "test-vectors") { evals.resize(self.capacity, F::zero()); evals.resize_with(self.domains.x1.size(), || { F::rand(&mut getrandom_or_panic::getrandom_or_panic()) diff --git a/w3f-ring-proof/Cargo.toml b/w3f-ring-proof/Cargo.toml index 481d530..e070151 100644 --- a/w3f-ring-proof/Cargo.toml +++ b/w3f-ring-proof/Cargo.toml @@ -49,4 +49,4 @@ print-trace = [ "w3f-plonk-common/print-trace" ] asm = [ "w3f-pcs/asm" ] -test-vectors = [] +test-vectors = [ "w3f-plonk-common/test-vectors" ] From d3610b2cba1a9c427894910afe1f83ac7c73bde1 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 13:02:19 +0100 Subject: [PATCH 06/10] try and incr hash2curve is not necessary --- w3f-ring-proof/Cargo.toml | 1 - w3f-ring-proof/src/lib.rs | 30 ++---------------------------- w3f-ring-proof/src/piop/params.rs | 3 +-- w3f-ring-proof/src/ring.rs | 5 ++--- 4 files changed, 5 insertions(+), 34 deletions(-) diff --git a/w3f-ring-proof/Cargo.toml b/w3f-ring-proof/Cargo.toml index e070151..b37b86e 100644 --- a/w3f-ring-proof/Cargo.toml +++ b/w3f-ring-proof/Cargo.toml @@ -21,7 +21,6 @@ ark-transcript = { version = "0.0.3", default-features = false } [dev-dependencies] ark-bls12-381 = { version = "0.5", default-features = false, features = ["curve"] } ark-ed-on-bls12-381-bandersnatch = { version = "0.5", default-features = false } -blake2 = { version = "0.10", default-features = false } [features] default = [ "std" ] diff --git a/w3f-ring-proof/src/lib.rs b/w3f-ring-proof/src/lib.rs index 637b69d..a79f98e 100644 --- a/w3f-ring-proof/src/lib.rs +++ b/w3f-ring-proof/src/lib.rs @@ -51,8 +51,7 @@ impl ArkTranscript { #[cfg(test)] mod tests { use ark_bls12_381::Bls12_381; - use ark_ec::twisted_edwards::{Affine, TECurveConfig}; - use ark_ec::{AffineRepr, CurveGroup}; + use ark_ec::CurveGroup; use ark_ed_on_bls12_381_bandersnatch::{BandersnatchConfig, EdwardsAffine, Fq, Fr}; use ark_std::ops::Mul; use ark_std::rand::Rng; @@ -68,31 +67,6 @@ mod tests { use super::*; - // Try and increment hash to curve. - fn hash_to_curve>( - message: &[u8], - ) -> Affine { - use blake2::Digest; - let mut seed = message.to_vec(); - let cnt_offset = seed.len(); - seed.push(0); - loop { - let hash: [u8; 64] = blake2::Blake2b::digest(&seed[..]).into(); - let x = F::from_le_bytes_mod_order(&hash); - if let Some(point) = Affine::::get_point_from_y_unchecked(x, false) { - let point = point.clear_cofactor(); - assert!(point.is_in_correct_subgroup_assuming_on_curve()); - return point; - } - seed[cnt_offset] += 1; - } - } - - pub(crate) fn padding_point>( - ) -> Affine { - hash_to_curve(b"/w3f/w3f-ring-proof/padding") - } - fn setup>( rng: &mut R, domain_size: usize, @@ -103,7 +77,7 @@ mod tests { let domain = Domain::new(domain_size, true); let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); - let pad = padding_point(); + let pad = EdwardsAffine::rand(rng); let piop_params = PiopParams::setup(domain, h, seed, pad); (pcs_params, piop_params) diff --git a/w3f-ring-proof/src/piop/params.rs b/w3f-ring-proof/src/piop/params.rs index 3ae2924..19a33ea 100644 --- a/w3f-ring-proof/src/piop/params.rs +++ b/w3f-ring-proof/src/piop/params.rs @@ -105,14 +105,13 @@ mod tests { use w3f_plonk_common::test_helpers::cond_sum; use crate::piop::params::PiopParams; - use crate::tests::padding_point; #[test] fn test_powers_of_h() { let rng = &mut test_rng(); let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); - let pad = padding_point(); + let pad = EdwardsAffine::rand(rng); let domain = Domain::new(1024, false); let params = PiopParams::::setup(domain, h, seed, pad); diff --git a/w3f-ring-proof/src/ring.rs b/w3f-ring-proof/src/ring.rs index dc99d4f..10ddbc9 100644 --- a/w3f-ring-proof/src/ring.rs +++ b/w3f-ring-proof/src/ring.rs @@ -265,7 +265,6 @@ mod tests { use w3f_plonk_common::test_helpers::random_vec; use crate::ring::Ring; - use crate::tests::padding_point; use crate::PiopParams; use super::*; @@ -285,8 +284,8 @@ mod tests { // piop params let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); + let pad = EdwardsAffine::rand(rng); let domain = Domain::new(domain_size, true); - let pad = padding_point(); let piop_params = PiopParams::setup(domain, h, seed, pad); let mut ring = TestRing::empty(&piop_params, srs, ring_builder_key.g1); @@ -317,7 +316,7 @@ mod tests { // piop params let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); - let pad = padding_point(); + let pad = EdwardsAffine::rand(rng); let domain = Domain::new(domain_size, true); let piop_params = PiopParams::setup(domain, h, seed, pad); From 6aa03a394d39335500eefa78010baeac0cb88dcd Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 13:13:44 +0100 Subject: [PATCH 07/10] Restore 'setup' position --- w3f-ring-proof/src/lib.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/w3f-ring-proof/src/lib.rs b/w3f-ring-proof/src/lib.rs index a79f98e..bfcc10a 100644 --- a/w3f-ring-proof/src/lib.rs +++ b/w3f-ring-proof/src/lib.rs @@ -67,22 +67,6 @@ mod tests { use super::*; - fn setup>( - rng: &mut R, - domain_size: usize, - ) -> (CS::Params, PiopParams) { - let setup_degree = 3 * domain_size; - let pcs_params = CS::setup(setup_degree, rng); - - let domain = Domain::new(domain_size, true); - let h = EdwardsAffine::rand(rng); - let seed = EdwardsAffine::rand(rng); - let pad = EdwardsAffine::rand(rng); - let piop_params = PiopParams::setup(domain, h, seed, pad); - - (pcs_params, piop_params) - } - fn _test_ring_proof>(domain_size: usize) { let rng = &mut test_rng(); @@ -144,6 +128,22 @@ mod tests { ); } + fn setup>( + rng: &mut R, + domain_size: usize, + ) -> (CS::Params, PiopParams) { + let setup_degree = 3 * domain_size; + let pcs_params = CS::setup(setup_degree, rng); + + let domain = Domain::new(domain_size, true); + let h = EdwardsAffine::rand(rng); + let seed = EdwardsAffine::rand(rng); + let pad = EdwardsAffine::rand(rng); + let piop_params = PiopParams::setup(domain, h, seed, pad); + + (pcs_params, piop_params) + } + #[test] fn test_ring_proof_kzg() { _test_ring_proof::>(2usize.pow(10)); From c44029ac682ba93089a0958015576e5e3a978f10 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 13:17:15 +0100 Subject: [PATCH 08/10] Add repo reference --- w3f-plonk-common/Cargo.toml | 1 + w3f-ring-proof/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/w3f-plonk-common/Cargo.toml b/w3f-plonk-common/Cargo.toml index f1795f2..200bc42 100644 --- a/w3f-plonk-common/Cargo.toml +++ b/w3f-plonk-common/Cargo.toml @@ -6,6 +6,7 @@ authors = ["Sergey Vasilyev "] license = "MIT/Apache-2.0" description = "Infrastructure for creating plonk-like proofs" keywords = ["cryptography", "plonk"] +repository = "https://github.com/w3f/ring-proof" [dependencies] ark-std.workspace = true diff --git a/w3f-ring-proof/Cargo.toml b/w3f-ring-proof/Cargo.toml index b37b86e..d2a2904 100644 --- a/w3f-ring-proof/Cargo.toml +++ b/w3f-ring-proof/Cargo.toml @@ -6,6 +6,7 @@ authors = ["Sergey Vasilyev "] license = "MIT/Apache-2.0" description = "zk-proof of knowledge of the blinding factor for a Pedersen commitment" keywords = ["cryptography", "ring-vrf"] +repository = "https://github.com/w3f/ring-proof" [dependencies] ark-std.workspace = true From 5c9864922b9a46be19eb0b8f86676da06bb89f19 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 20 Feb 2025 13:19:24 +0100 Subject: [PATCH 09/10] Bump versions --- w3f-plonk-common/Cargo.toml | 2 +- w3f-ring-proof/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/w3f-plonk-common/Cargo.toml b/w3f-plonk-common/Cargo.toml index 200bc42..70d1638 100644 --- a/w3f-plonk-common/Cargo.toml +++ b/w3f-plonk-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "w3f-plonk-common" -version = "0.0.1" +version = "0.0.2" edition = "2021" authors = ["Sergey Vasilyev "] license = "MIT/Apache-2.0" diff --git a/w3f-ring-proof/Cargo.toml b/w3f-ring-proof/Cargo.toml index d2a2904..cc1cd8b 100644 --- a/w3f-ring-proof/Cargo.toml +++ b/w3f-ring-proof/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "w3f-ring-proof" -version = "0.0.1" +version = "0.0.2" edition = "2021" authors = ["Sergey Vasilyev "] license = "MIT/Apache-2.0" From a63011db0ddf6dc492938d2442e5474fdf3bb66b Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Fri, 21 Feb 2025 07:57:52 +0100 Subject: [PATCH 10/10] Some docs --- w3f-ring-proof/src/lib.rs | 4 +- w3f-ring-proof/src/piop/params.rs | 39 +++++++------- w3f-ring-proof/src/ring.rs | 84 ++++++++++++++++--------------- 3 files changed, 66 insertions(+), 61 deletions(-) diff --git a/w3f-ring-proof/src/lib.rs b/w3f-ring-proof/src/lib.rs index bfcc10a..ca45992 100644 --- a/w3f-ring-proof/src/lib.rs +++ b/w3f-ring-proof/src/lib.rs @@ -138,8 +138,8 @@ mod tests { let domain = Domain::new(domain_size, true); let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); - let pad = EdwardsAffine::rand(rng); - let piop_params = PiopParams::setup(domain, h, seed, pad); + let padding = EdwardsAffine::rand(rng); + let piop_params = PiopParams::setup(domain, h, seed, padding); (pcs_params, piop_params) } diff --git a/w3f-ring-proof/src/piop/params.rs b/w3f-ring-proof/src/piop/params.rs index 19a33ea..22bd21e 100644 --- a/w3f-ring-proof/src/piop/params.rs +++ b/w3f-ring-proof/src/piop/params.rs @@ -8,34 +8,37 @@ use w3f_plonk_common::gadgets::ec::AffineColumn; use crate::piop::FixedColumns; +/// Plonk Interactive Oracle Proofs (PIOP) parameters. #[derive(Clone)] pub struct PiopParams> { - // Domain over which the piop is represented. + /// Domain over which the piop is represented. pub(crate) domain: Domain, - - // Number of bits used to represent a jubjub scalar. + /// Number of bits used to represent a jubjub scalar. pub(crate) scalar_bitlen: usize, - - // Length of the part of the column representing the public keys (including the padding). + /// Length of the part of the column representing the public keys (including the padding). pub keyset_part_size: usize, - - // The blinding base, a point from jubjub. + /// Blinding base point. pub(crate) h: Affine, - - // The point to start the summation from (as zero doesn't have a SW affine representation), - // should be from the jubjub prime-order subgroup complement. + /// Summation base point. pub(crate) seed: Affine, - - // The point used to pad the actual list of public keys. Should be of an unknown dlog. - pub(crate) padding_point: Affine, + /// The point used to pad the list of public keys. + pub(crate) padding: Affine, } impl> PiopParams { + /// Initialize PIOP parameters. + /// + /// - `domain`: polynomials evaluation domain. + /// - `h`: Blinding base point. + /// - `seed`: Accumulation base point + /// - `padding`: The point used to pad the list of public keys. + /// + /// All points should be of an unknown discrete log. pub fn setup( domain: Domain, h: Affine, seed: Affine, - padding_point: Affine, + padding: Affine, ) -> Self { let scalar_bitlen = Curve::ScalarField::MODULUS_BIT_SIZE as usize; // 1 accounts for the last cells of the points and bits columns that remain unconstrained @@ -46,7 +49,7 @@ impl> PiopParams { keyset_part_size, h, seed, - padding_point, + padding, } } @@ -63,7 +66,7 @@ impl> PiopParams { pub fn points_column(&self, keys: &[Affine]) -> AffineColumn> { assert!(keys.len() <= self.keyset_part_size); let padding_len = self.keyset_part_size - keys.len(); - let padding = vec![self.padding_point; padding_len]; + let padding = vec![self.padding; padding_len]; let points = [keys, &padding, &self.power_of_2_multiples_of_h()].concat(); assert_eq!(points.len(), self.domain.capacity - 1); AffineColumn::public_column(points, &self.domain) @@ -111,10 +114,10 @@ mod tests { let rng = &mut test_rng(); let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); - let pad = EdwardsAffine::rand(rng); + let padding = EdwardsAffine::rand(rng); let domain = Domain::new(1024, false); - let params = PiopParams::::setup(domain, h, seed, pad); + let params = PiopParams::::setup(domain, h, seed, padding); let t = Fr::rand(rng); let t_bits = params.scalar_part(t); let th = cond_sum(&t_bits, ¶ms.power_of_2_multiples_of_h()); diff --git a/w3f-ring-proof/src/ring.rs b/w3f-ring-proof/src/ring.rs index 10ddbc9..600455d 100644 --- a/w3f-ring-proof/src/ring.rs +++ b/w3f-ring-proof/src/ring.rs @@ -18,41 +18,38 @@ use crate::PiopParams; const IDLE_ROWS: usize = ZK_ROWS + 1; /// Commitment to a list of VRF public keys as is used as a public input to the ring proof SNARK verifier. - -/// The VRF keys are (inner) curve points that we represent in the affine short Weierstrass coordinates. +/// +/// The VRF keys are (inner) curve points that we represent in the affine Twisted Edwards coordinates. /// We commit to the coordinate vectors independently using KZG on the outer curve. To make the commitment /// updatable we use SRS in the Lagrangian form: `L1, ..., Ln`, where `Li = L_i(t)G`. /// The commitment to a vector `a1, ..., an` is then `a1L1 + ... + anLn`. - +/// /// We pad the list of keys with a `padding` point with unknown dlog up to a certain size. /// Additionally, to make the commitment compatible with the snark, /// we append the power-of-2 powers of the VRF blinding Pedersen base /// `H, 2H, 4H, ..., 2^(s-1)H`, where `s` is the bitness of the VRF curve scalar field. /// The last `IDLE_ROWS = 4` elements are set to `(0, 0)`. - +/// /// Thus, the vector of points we commit to coordinatewise is /// `pk1, ..., pkn, padding, ..., padding, H, 2H, ..., 2^(s-1)H, 0, 0, 0, 0` - -// `KzgCurve` -- outer curve, subgroup of a pairing-friendly curve. We instantiate it with bls12-381 G1. -// `VrfCurveConfig` -- inner curve, the curve used by the VRF, in SW form. We instantiate it with Bandersnatch. -// `F` shared scalar field of the outer and the base field of the inner curves. #[derive(Clone, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)] pub struct Ring< F: PrimeField, KzgCurve: Pairing, VrfCurveConfig: TECurveConfig, > { - // KZG commitments to the coordinates of the vector described above + /// KZG commitment to the x coordinates of the described vector. pub cx: KzgCurve::G1Affine, + /// KZG commitment to the y coordinates of the described vector. pub cy: KzgCurve::G1Affine, - // KZG commitment to a bitvector highlighting the part of the vector corresponding to the public keys. + /// KZG commitment to a bitvector highlighting the part of the vector corresponding to the public keys. pub selector: KzgCurve::G1Affine, - // maximal number of keys the commitment can "store". For domain of size `N` it is `N - (s + IDLE_ROWS)` + /// Maximal number of keys the commitment can "store". For domain of size `N` it is `N - (s + IDLE_ROWS)`. pub max_keys: usize, - // the number of keys "stored" in this commitment + /// Number of keys "stored" in this commitment. pub curr_keys: usize, - // a parameter - pub padding_point: Affine, + // Padding point. + pub padding: Affine, } impl< @@ -76,22 +73,23 @@ impl< VrfCurveConfig: TECurveConfig, > Ring { - // Builds the commitment to the vector - // `padding, ..., padding, H, 2H, ..., 2^(s-1)H, 0, 0, 0, 0`. - // We compute it as a sum of commitments of 2 vectors: - // `padding, ..., padding`, and - // `0, ..., 0, (H - padding), (2H - padding), ..., (2^(s-1)H - padding), -padding, -padding, -padding, -padding`. - // The first one is `padding * G`, the second requires an `(IDLE_ROWS + s)`-msm to compute. + /// Builds the commitment to the vector + /// `padding, ..., padding, H, 2H, ..., 2^(s-1)H, 0, 0, 0, 0`. + /// + /// We compute it as a sum of commitments of 2 vectors: + /// `padding, ..., padding`, and + /// `0, ..., 0, (H - padding), (2H - padding), ..., (2^(s-1)H - padding), -padding, -padding, -padding, -padding`. + /// The first one is `padding * G`, the second requires an `(IDLE_ROWS + s)`-msm to compute. + /// + /// - `piop_params`: SNARK parameters + /// - `srs`: Should return `srs[range]` for `range = (piop_params.keyset_part_size..domain_size)` + /// - `g`: Generator used in the SRS pub fn empty( - // SNARK parameters piop_params: &PiopParams, - // Should return `srs[range]` for `range = (piop_params.keyset_part_size..domain_size)` srs: impl Fn(Range) -> Result, ()>, - // generator used in the SRS g: KzgCurve::G1, ) -> Self { - let padding_point = piop_params.padding_point; - let (padding_x, padding_y) = padding_point.xy().unwrap(); // panics on inf, never happens + let (padding_x, padding_y) = piop_params.padding.xy().unwrap(); // panics on inf, never happens let c1x = g * padding_x; let c1y = g * padding_y; @@ -122,19 +120,22 @@ impl< selector, max_keys: piop_params.keyset_part_size, curr_keys: 0, - padding_point, + padding: piop_params.padding, } } + /// Appends a set key sequence to the ring. + /// + /// - `keys`: Keys to append. + /// - `srs`: Should return `srs[range]` for `range = (self.curr_keys..self.curr_keys + keys.len())` pub fn append( &mut self, keys: &[Affine], - // Should return `srs[range]` for `range = (self.curr_keys..self.curr_keys + keys.len())` srs: impl Fn(Range) -> Result, ()>, ) { let new_size = self.curr_keys + keys.len(); assert!(new_size <= self.max_keys); - let (padding_x, padding_y) = self.padding_point.xy().unwrap(); + let (padding_x, padding_y) = self.padding.xy().unwrap(); let (xs, ys): (Vec, Vec) = keys .iter() .map(|p| p.xy().unwrap()) @@ -154,17 +155,18 @@ impl< self.curr_keys = new_size; } - // Builds the ring from the keys provided with 2 MSMs of size `keys.len() + scalar_bitlen + 5`. - // In some cases it may be beneficial to cash the empty ring, as updating it costs 2 MSMs of size `keys.len()`. + /// Builds the ring from the keys provided with 2 MSMs of size `keys.len() + scalar_bitlen + 5`. + /// + /// In some cases it may be beneficial to cash the empty ring, as updating it costs 2 MSMs of size `keys.len()`. + /// + /// - `piop_params`: SNARK parameters. + /// - `srs`: full-size Lagrangian SRS. pub fn with_keys( - // SNARK parameters piop_params: &PiopParams, keys: &[Affine], - // full-size Lagrangian srs srs: &RingBuilderKey, ) -> Self { - let padding_point = piop_params.padding_point; - let (padding_x, padding_y) = padding_point.xy().unwrap(); // panics on inf, never happens + let (padding_x, padding_y) = piop_params.padding.xy().unwrap(); // panics on inf, never happens let powers_of_h = piop_params.power_of_2_multiples_of_h(); // Computes @@ -207,7 +209,7 @@ impl< selector, max_keys: piop_params.keyset_part_size, curr_keys: keys.len(), - padding_point, + padding: piop_params.padding, } } @@ -220,7 +222,7 @@ impl< cx: KzgCurve::G1Affine, cy: KzgCurve::G1Affine, selector: KzgCurve::G1Affine, - padding_point: Affine, + padding: Affine, ) -> Self { let max_keys = domain_size - (VrfCurveConfig::ScalarField::MODULUS_BIT_SIZE as usize + IDLE_ROWS); @@ -230,7 +232,7 @@ impl< selector, max_keys, curr_keys: 0, - padding_point, + padding, } } } @@ -284,9 +286,9 @@ mod tests { // piop params let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); - let pad = EdwardsAffine::rand(rng); + let padding = EdwardsAffine::rand(rng); let domain = Domain::new(domain_size, true); - let piop_params = PiopParams::setup(domain, h, seed, pad); + let piop_params = PiopParams::setup(domain, h, seed, padding); let mut ring = TestRing::empty(&piop_params, srs, ring_builder_key.g1); let (monimial_cx, monimial_cy) = get_monomial_commitment(&pcs_params, &piop_params, &[]); @@ -316,9 +318,9 @@ mod tests { // piop params let h = EdwardsAffine::rand(rng); let seed = EdwardsAffine::rand(rng); - let pad = EdwardsAffine::rand(rng); + let padding = EdwardsAffine::rand(rng); let domain = Domain::new(domain_size, true); - let piop_params = PiopParams::setup(domain, h, seed, pad); + let piop_params = PiopParams::setup(domain, h, seed, padding); let ring = TestRing::empty(&piop_params, srs, ring_builder_key.g1); let same_ring = TestRing::with_keys(&piop_params, &[], &ring_builder_key);