w3f_ring_proof/piop/
params.rs1use ark_ec::twisted_edwards::{Affine, TECurveConfig};
2use ark_ec::{AdditiveGroup, AffineRepr, CurveGroup};
3use ark_ff::{BigInteger, PrimeField};
4use ark_std::{vec, vec::Vec};
5
6use w3f_plonk_common::domain::Domain;
7use w3f_plonk_common::gadgets::ec::AffineColumn;
8
9use crate::piop::FixedColumns;
10
11#[derive(Clone)]
13pub struct PiopParams<F: PrimeField, Curve: TECurveConfig<BaseField = F>> {
14 pub(crate) domain: Domain<F>,
16 pub(crate) scalar_bitlen: usize,
18 pub keyset_part_size: usize,
20 pub(crate) h: Affine<Curve>,
22 pub(crate) seed: Affine<Curve>,
24 pub(crate) padding: Affine<Curve>,
26}
27
28impl<F: PrimeField, Curve: TECurveConfig<BaseField = F>> PiopParams<F, Curve> {
29 pub fn setup(
38 domain: Domain<F>,
39 h: Affine<Curve>,
40 seed: Affine<Curve>,
41 padding: Affine<Curve>,
42 ) -> Self {
43 let scalar_bitlen = Curve::ScalarField::MODULUS_BIT_SIZE as usize;
44 let keyset_part_size = domain.capacity - scalar_bitlen - 1;
46 Self {
47 domain,
48 scalar_bitlen,
49 keyset_part_size,
50 h,
51 seed,
52 padding,
53 }
54 }
55
56 pub fn fixed_columns(&self, keys: &[Affine<Curve>]) -> FixedColumns<F, Affine<Curve>> {
57 let ring_selector = self.keyset_part_selector();
58 let ring_selector = self.domain.public_column(ring_selector);
59 let points = self.points_column(&keys);
60 FixedColumns {
61 points,
62 ring_selector,
63 }
64 }
65
66 pub fn points_column(&self, keys: &[Affine<Curve>]) -> AffineColumn<F, Affine<Curve>> {
67 assert!(keys.len() <= self.keyset_part_size);
68 let padding_len = self.keyset_part_size - keys.len();
69 let padding = vec![self.padding; padding_len];
70 let points = [keys, &padding, &self.power_of_2_multiples_of_h()].concat();
71 assert_eq!(points.len(), self.domain.capacity - 1);
72 AffineColumn::public_column(points, &self.domain)
73 }
74
75 pub fn power_of_2_multiples_of_h(&self) -> Vec<Affine<Curve>> {
76 let mut h = self.h.into_group();
77 let mut multiples = Vec::with_capacity(self.scalar_bitlen);
78 multiples.push(h);
79 for _ in 1..self.scalar_bitlen {
80 h.double_in_place();
81 multiples.push(h);
82 }
83 CurveGroup::normalize_batch(&multiples)
84 }
85
86 pub fn scalar_part(&self, e: Curve::ScalarField) -> Vec<bool> {
87 let bits_with_trailing_zeroes = e.into_bigint().to_bits_le();
88 let significant_bits = &bits_with_trailing_zeroes[..self.scalar_bitlen];
89 significant_bits.to_vec()
90 }
91
92 pub fn keyset_part_selector(&self) -> Vec<F> {
93 [
94 vec![F::one(); self.keyset_part_size],
95 vec![F::zero(); self.scalar_bitlen],
96 ]
97 .concat()
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use ark_ed_on_bls12_381_bandersnatch::{BandersnatchConfig, EdwardsAffine, Fq, Fr};
104 use ark_std::ops::Mul;
105 use ark_std::{test_rng, UniformRand};
106
107 use w3f_plonk_common::domain::Domain;
108 use w3f_plonk_common::test_helpers::cond_sum;
109
110 use crate::piop::params::PiopParams;
111
112 #[test]
113 fn test_powers_of_h() {
114 let rng = &mut test_rng();
115 let h = EdwardsAffine::rand(rng);
116 let seed = EdwardsAffine::rand(rng);
117 let padding = EdwardsAffine::rand(rng);
118 let domain = Domain::new(1024, false);
119
120 let params = PiopParams::<Fq, BandersnatchConfig>::setup(domain, h, seed, padding);
121 let t = Fr::rand(rng);
122 let t_bits = params.scalar_part(t);
123 let th = cond_sum(&t_bits, ¶ms.power_of_2_multiples_of_h());
124 assert_eq!(th, params.h.mul(t));
125 }
126}