1#![cfg_attr(not(feature = "std"), no_std)]
9#[cfg(test)]
10extern crate std;
11
12#[cfg(any(not(feature = "std"), target_has_atomic = "ptr"))]
13#[doc(hidden)]
14extern crate alloc;
15
16mod conversion;
17mod macros;
18mod multi_pairing;
19pub mod par_utils;
20pub mod reed_solomon_code;
21mod serialize;
22
23use ark_ff::{Field, PrimeField};
24use ark_std::{
25 ops::Mul,
26 rand::{self, rngs::StdRng},
27 string::{String, ToString},
28 vec::Vec,
29};
30
31pub use conversion::*;
32#[allow(unused_imports)]
33pub use macros::*;
34pub use multi_pairing::*;
35pub use serialize::*;
36
37#[inline]
38pub fn field_byte_len<F: PrimeField>() -> usize {
39 F::MODULUS_BIT_SIZE.div_ceil(8) as usize
40}
41
42#[inline]
43pub fn field_bit_len<F: PrimeField>() -> usize {
44 F::MODULUS_BIT_SIZE as usize
45}
46
47#[inline]
48pub fn challenge_bit_len<F: PrimeField>() -> usize {
49 (field_byte_len::<F>() - 1) << 3
52}
53
54#[inline]
55pub fn compute_len_to_next_multiple(len: usize, multiple: usize) -> usize {
56 if len % multiple == 0 {
57 len
58 } else {
59 len + multiple - len % multiple
60 }
61}
62
63#[inline]
65pub fn pad_with_zeros<F: Field>(vec: &mut Vec<F>, multiple: usize) {
66 let len = vec.len();
67 let new_len = compute_len_to_next_multiple(len, multiple);
68 vec.resize(new_len, F::zero())
69}
70
71#[inline]
73pub fn hadamard_product<T, B>(a: impl AsRef<[T]>, b: impl AsRef<[B]>) -> Result<Vec<B>, String>
74where
75 B: for<'a> Mul<&'a T, Output = B> + Copy,
76{
77 let (a, b) = (a.as_ref(), b.as_ref());
78 if a.len() != b.len() {
79 return Err(
80 "Cannot compute hadmard product of two vectors of different length".to_string(),
81 );
82 }
83
84 let res: Vec<B> = a.iter().zip(b.iter()).map(|(ai, &bi)| bi * ai).collect();
85 Ok(res)
86}
87
88pub fn test_rng() -> StdRng {
89 use rand::SeedableRng;
90 let seed = [
92 1, 0, 0, 0, 23, 0, 0, 0, 200, 1, 0, 0, 210, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0,
94 ];
95 StdRng::from_seed(seed)
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use ark_ec::CurveGroup;
102
103 fn test_hadamard_template<Fr: PrimeField, G1: CurveGroup<ScalarField = Fr>>() {
104 let mut rng = test_rng();
105 for _ in 0..10 {
106 let a: Vec<Fr> = (0..20).map(|_| Fr::rand(&mut rng)).collect();
107 let b: Vec<Fr> = (0..20).map(|_| Fr::rand(&mut rng)).collect();
108
109 let product = hadamard_product(&a, &b).unwrap();
110 assert!(product.iter().enumerate().all(|(i, &c)| c == a[i] * b[i]));
111
112 let c: Vec<Fr> = (0..21).map(|_| Fr::rand(&mut rng)).collect();
113 assert!(hadamard_product(&a, &c).is_err());
114
115 let d: Vec<G1> = (0..20).map(|_| G1::rand(&mut rng)).collect();
116 let product = hadamard_product(&a, &d).unwrap();
117 assert!(product.iter().enumerate().all(|(i, &c)| c == d[i] * a[i]));
118 }
119 }
120
121 #[test]
122 fn test_hadamard() {
123 test_hadamard_template::<ark_bls12_381::Fr, ark_bls12_381::G1Projective>();
124 test_hadamard_template::<ark_bls12_377::Fr, ark_bls12_377::G1Projective>();
125 test_hadamard_template::<ark_bn254::Fr, ark_bn254::G1Projective>();
126 }
127}