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