1#![deny(missing_docs)]
2#![allow(non_snake_case)]
3
4use ark_ec::AffineRepr;
5use ark_std::{vec, vec::Vec, One, Zero};
6use clear_on_drop::clear::Clear;
7
8use crate::inner_product_proof::inner_product;
9
10#[cfg(feature = "yoloproofs")]
13pub struct VecPoly3<G: AffineRepr>(
14 pub Vec<G::ScalarField>,
15 pub Vec<G::ScalarField>,
16 pub Vec<G::ScalarField>,
17 pub Vec<G::ScalarField>,
18);
19
20#[cfg(feature = "yoloproofs")]
23pub struct Poly6<G: AffineRepr> {
24 pub t1: G::ScalarField,
25 pub t2: G::ScalarField,
26 pub t3: G::ScalarField,
27 pub t4: G::ScalarField,
28 pub t5: G::ScalarField,
29 pub t6: G::ScalarField,
30}
31
32pub struct FrExp<G: AffineRepr> {
36 x: G::ScalarField,
37 next_exp_x: G::ScalarField,
38}
39
40impl<G: AffineRepr> Iterator for FrExp<G> {
41 type Item = G::ScalarField;
42
43 fn next(&mut self) -> Option<G::ScalarField> {
44 let exp_x = self.next_exp_x;
45 self.next_exp_x *= self.x;
46 Some(exp_x)
47 }
48
49 fn size_hint(&self) -> (usize, Option<usize>) {
50 (usize::MAX, None)
51 }
52}
53
54pub fn exp_iter<G: AffineRepr>(x: G::ScalarField) -> FrExp<G> {
56 let next_exp_x = G::ScalarField::one();
57 FrExp { x, next_exp_x }
58}
59
60#[cfg(feature = "yoloproofs")]
61impl<G: AffineRepr> VecPoly3<G> {
62 pub fn zero(n: usize) -> Self {
63 VecPoly3(
64 vec![G::ScalarField::zero(); n],
65 vec![G::ScalarField::zero(); n],
66 vec![G::ScalarField::zero(); n],
67 vec![G::ScalarField::zero(); n],
68 )
69 }
70
71 pub fn special_inner_product(lhs: &Self, rhs: &Self) -> Poly6<G> {
76 let t1 = inner_product(&lhs.1, &rhs.0);
79 let t2 = inner_product(&lhs.1, &rhs.1) + inner_product(&lhs.2, &rhs.0);
80 let t3 = inner_product(&lhs.2, &rhs.1) + inner_product(&lhs.3, &rhs.0);
81 let t4 = inner_product(&lhs.1, &rhs.3) + inner_product(&lhs.3, &rhs.1);
82 let t5 = inner_product(&lhs.2, &rhs.3);
83 let t6 = inner_product(&lhs.3, &rhs.3);
84
85 Poly6 {
86 t1,
87 t2,
88 t3,
89 t4,
90 t5,
91 t6,
92 }
93 }
94
95 pub fn eval(&self, x: G::ScalarField) -> Vec<G::ScalarField> {
96 let n = self.0.len();
97 let mut out = vec![G::ScalarField::zero(); n];
98 for i in 0..n {
99 out[i] = self.0[i] + x * (self.1[i] + x * (self.2[i] + x * self.3[i]));
100 }
101 out
102 }
103}
104
105#[cfg(feature = "yoloproofs")]
106impl<G: AffineRepr> Poly6<G> {
107 pub fn eval(&self, x: G::ScalarField) -> G::ScalarField {
108 x * (self.t1 + x * (self.t2 + x * (self.t3 + x * (self.t4 + x * (self.t5 + x * self.t6)))))
109 }
110}
111
112#[cfg(feature = "yoloproofs")]
113impl<G: AffineRepr> Drop for VecPoly3<G> {
114 fn drop(&mut self) {
115 for e in self.0.iter_mut() {
116 e.clear();
117 }
118 for e in self.1.iter_mut() {
119 e.clear();
120 }
121 for e in self.2.iter_mut() {
122 e.clear();
123 }
124 for e in self.3.iter_mut() {
125 e.clear();
126 }
127 }
128}
129
130#[cfg(feature = "yoloproofs")]
131impl<G: AffineRepr> Drop for Poly6<G> {
132 fn drop(&mut self) {
133 self.t1.clear();
134 self.t2.clear();
135 self.t3.clear();
136 self.t4.clear();
137 self.t5.clear();
138 self.t6.clear();
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145
146 #[test]
147 fn exp_2_is_powers_of_2() {
148 type G = ark_secq256k1::Affine;
149 type F = ark_secq256k1::Fr;
150
151 let exp_2: Vec<_> = exp_iter::<G>(F::from(2u64)).take(4).collect();
152
153 assert_eq!(exp_2[0], F::from(1u64));
154 assert_eq!(exp_2[1], F::from(2u64));
155 assert_eq!(exp_2[2], F::from(4u64));
156 assert_eq!(exp_2[3], F::from(8u64));
157 }
158
159 #[test]
160 fn test_inner_product() {
161 type F = ark_secq256k1::Fr;
162
163 let a = vec![F::from(1u64), F::from(2u64), F::from(3u64), F::from(4u64)];
164 let b = vec![F::from(2u64), F::from(3u64), F::from(4u64), F::from(5u64)];
165 assert_eq!(F::from(40u64), inner_product(&a, &b));
166 }
167
168 #[test]
169 fn vec_of_scalars_clear_on_drop() {
170 type F = ark_secq256k1::Fr;
171
172 let mut v = vec![F::from(24u64), F::from(42u64)];
173
174 for e in v.iter_mut() {
175 e.clear();
176 }
177
178 fn flat_slice<T>(x: &[T]) -> &[u8] {
179 use core::mem;
180 use core::slice;
181
182 unsafe { slice::from_raw_parts(x.as_ptr() as *const u8, mem::size_of_val(x)) }
183 }
184
185 assert_eq!(flat_slice(&v.as_slice()), &[0u8; 64][..]);
186 assert_eq!(v[0], F::zero());
187 assert_eq!(v[1], F::zero());
188 }
189}