1use crate::{
4 bls12_377::G1PTEAffine, preprocess::preprocess_points, timing::timed, Digit, Fr, Scalar,
5};
6use ark_bls12_377::{G1Affine, G1Projective};
7use ark_ec::AffineRepr as _;
8
9pub fn random_digits(size: u8) -> Vec<Digit> {
10 use rand_core::{RngCore, SeedableRng};
11 let mut rng = rand::prelude::StdRng::from_entropy();
12
13 (0..(1 << size)).map(|_| rng.next_u32() as i16).collect()
14}
15
16pub fn random_fr(size: u8) -> Vec<Fr> {
17 use ark_std::UniformRand;
18 use rand_core::SeedableRng;
19 let mut rng = rand::prelude::StdRng::from_entropy();
20
21 (0..(1 << size)).map(|_| Fr::rand(&mut rng)).collect()
22}
23
24pub fn random_points(size: u8) -> Vec<G1Affine> {
25 use rand_core::SeedableRng;
26 let mut rng = rand::prelude::StdRng::from_entropy();
27
28 use ark_std::UniformRand;
29 let points: Vec<_> = timed("generating random projective points", || {
30 (0..(1 << size))
31 .map(|_| G1Projective::rand(&mut rng))
32 .collect()
33 });
34
35 use ark_ec::CurveGroup as _;
36 timed("batch converting to affine", || {
37 G1Projective::normalize_batch(&points)
38 })
39}
40pub fn random_scalars(size: u8) -> Vec<Scalar> {
41 use rand_core::{RngCore, SeedableRng};
42 let mut rng = rand::prelude::StdRng::from_entropy();
43
44 (0..(1 << size))
45 .map(|_| {
46 let mut scalar = Scalar::default();
47 for limb in scalar.iter_mut() {
48 *limb = rng.next_u64();
49 }
50 scalar
51 })
52 .collect()
53}
54
55pub fn zero_scalars(size: u8) -> Vec<Scalar> {
56 (0..(1 << size))
57 .map(|_| {
58 let mut scalar = Scalar::default();
59 for limb in scalar.iter_mut() {
60 *limb = 0;
61 }
62 scalar
63 })
64 .collect()
65}
66
67pub fn noconflict_scalars(size: u8) -> Vec<Scalar> {
68 (0..(1 << size))
69 .map(|i| {
70 let mut scalar = Scalar::default();
71 for limb in scalar.iter_mut() {
72 let i = (i as u16 % 1024) as u64;
73 *limb = (i << 48) | (i << 32) | (i << 16) | i
74 }
75 scalar
76 })
77 .collect()
78}
79
80pub fn harness_points(size: u8) -> (Fr, Vec<G1PTEAffine>) {
82 use rand_core::SeedableRng;
83 let length = 1 << size;
84
85 use ark_std::{One, UniformRand};
86 let mut rng = rand::prelude::StdRng::from_entropy();
87
88 let beta = Fr::rand(&mut rng);
89 eprintln!("using beta: {}", beta);
90
91 let scalars = timed("scalar gen", || {
92 let mut scalars = Vec::with_capacity(length as _);
93 scalars.push(Fr::one());
94 scalars.push(beta);
95 let mut last = beta;
96 for _ in 2..length {
97 last *= beta;
98 scalars.push(last);
99 }
100 scalars
101 });
102
103 use ark_ec::scalar_mul::fixed_base::FixedBase;
104
105 let points = timed("point gen", || {
106 let scalar_bits = 256;
107 let g = G1Affine::generator();
108 let window = FixedBase::get_mul_window_size(length);
109 let table = FixedBase::get_window_table::<G1Projective>(scalar_bits, window, g.into());
110 FixedBase::msm::<G1Projective>(scalar_bits, window, &table, &scalars)
111 });
112
113 use ark_ec::CurveGroup as _;
114 let points = timed("Projective -> Affine", || {
115 G1Projective::normalize_batch(&points)
116 });
117
118 (
120 beta,
121 timed("Affine -> PTEAffine", || preprocess_points(&points)),
122 )
123}
124
125pub fn harness_fr(beta: &Fr, size: u8) -> (Vec<Fr>, G1Projective) {
126 use ark_std::{One, Zero};
127
128 let g = G1Affine::generator();
129
130 let scalars = random_fr(size as u8);
131
132 let result = timed("SW MSM via betas", || {
135 let mut beta_i = Fr::one();
136 let mut prod = Fr::zero();
137 for &scalar in &scalars {
138 prod += scalar * beta_i;
139 beta_i *= beta;
140 }
141 g * prod
142 });
143
144 (scalars, result)
145}
146
147pub fn harness_bigints(beta: &Fr, size: u8) -> (Vec<ark_ff::BigInt<4>>, G1Projective) {
148 use ark_std::{One, Zero};
149
150 use ark_ff::PrimeField;
151 let g = G1Affine::generator();
152
153 let scalars = random_fr(size as u8);
154
155 let result = timed("SW MSM via betas", || {
158 let mut beta_i = Fr::one();
159 let mut prod = Fr::zero();
160 for &scalar in &scalars {
161 prod += scalar * beta_i;
162 beta_i *= beta;
163 }
164 g * prod
165 });
166
167 let scalars: Vec<_> = scalars.iter().map(|scalar| scalar.into_bigint()).collect();
168
169 (scalars, result)
170}
171
172pub fn harness_scalars(beta: &Fr, size: u8) -> (Vec<Scalar>, G1Projective) {
173 use ark_std::{One, Zero};
174
175 use ark_ff::PrimeField;
176 let g = G1Affine::generator();
177
178 let scalars = random_fr(size as u8);
179
180 let result = timed("SW MSM via betas", || {
183 let mut beta_i = Fr::one();
184 let mut prod = Fr::zero();
185 for &scalar in &scalars {
186 prod += scalar * beta_i;
187 beta_i *= beta;
188 }
189 g * prod
190 });
191
192 let scalars: Vec<Scalar> = scalars
193 .iter()
194 .map(|scalar| scalar.into_bigint().0)
195 .collect();
196
197 (scalars, result)
198}
199
200pub fn digits_to_scalars(digits: &[Digit]) -> Vec<Fr> {
201 digits
202 .iter()
203 .copied()
204 .map(|digit| {
205 if digit >= 0 {
206 Fr::from(digit as u16)
207 } else {
208 -Fr::from((-(digit as i32)) as u16)
209 }
210 })
211 .collect()
212}
213
214pub fn harness_digits(beta: &Fr, size: u8) -> (Vec<i16>, G1Projective) {
215 use ark_std::{One, Zero};
216
217 let g = G1Affine::generator();
219
220 let digits = random_digits(size as u8);
221 let scalars = digits_to_scalars(&digits);
222
223 let result = timed("SW MSM via betas", || {
226 let mut beta_i = Fr::one();
227 let mut prod = Fr::zero();
228 for &scalar in &scalars {
229 prod += scalar * beta_i;
230 beta_i *= beta;
231 }
232 g * prod
233 });
234
235 (digits, result)
236}
237
238pub fn noconflict_digits(size: u8) -> Vec<i16> {
239 (0..(1usize << size)).map(|i| (i % 1024) as i16).collect()
240}
241
242pub fn harness_digits_conflictfree(beta: &Fr, size: usize) -> (Vec<i16>, G1Projective) {
244 use ark_std::{One, Zero};
245
246 let g = G1Affine::generator();
248
249 let digits = noconflict_digits(size as u8);
250 let scalars = digits_to_scalars(&digits);
251
252 let result = timed("SW MSM via betas", || {
254 let mut beta_i = Fr::one();
255 let mut prod = Fr::zero();
256 for &scalar in &scalars {
257 prod += scalar * beta_i;
258 beta_i *= beta;
259 }
260 g * prod
261 });
262
263 (digits, result)
264}