use crate::{
syscalls::{syscall_arith256_mod, SyscallArith256ModParams},
zisklib::lt,
};
use super::constants::{R, R_MINUS_ONE};
pub fn reduce_fr_bls12_381(
x: &[u64; 4],
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> [u64; 4] {
if lt(x, &R) {
return *x;
}
let mut params = SyscallArith256ModParams {
a: x,
b: &[1, 0, 0, 0],
c: &[0, 0, 0, 0],
module: &R,
d: &mut [0, 0, 0, 0],
};
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn add_fr_bls12_381(
x: &[u64; 4],
y: &[u64; 4],
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> [u64; 4] {
let mut params =
SyscallArith256ModParams { a: x, b: &[1, 0, 0, 0], c: y, module: &R, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn dbl_fr_bls12_381(x: &[u64; 4], #[cfg(feature = "hints")] hints: &mut Vec<u64>) -> [u64; 4] {
let mut params = SyscallArith256ModParams {
a: x,
b: &[2, 0, 0, 0],
c: &[0, 0, 0, 0],
module: &R,
d: &mut [0, 0, 0, 0],
};
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn sub_fr_bls12_381(
x: &[u64; 4],
y: &[u64; 4],
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> [u64; 4] {
let mut params =
SyscallArith256ModParams { a: y, b: &R_MINUS_ONE, c: x, module: &R, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn neg_fr_bls12_381(x: &[u64; 4], #[cfg(feature = "hints")] hints: &mut Vec<u64>) -> [u64; 4] {
let mut params = SyscallArith256ModParams {
a: x,
b: &R_MINUS_ONE,
c: &[0, 0, 0, 0],
module: &R,
d: &mut [0, 0, 0, 0],
};
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn mul_fr_bls12_381(
x: &[u64; 4],
y: &[u64; 4],
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> [u64; 4] {
let mut params =
SyscallArith256ModParams { a: x, b: y, c: &[0, 0, 0, 0], module: &R, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn square_fr_bls12_381(
x: &[u64; 4],
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> [u64; 4] {
let mut params =
SyscallArith256ModParams { a: x, b: x, c: &[0, 0, 0, 0], module: &R, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
pub fn scalar_bytes_be_to_u64_le_bls12_381(bytes: &[u8; 32]) -> [u64; 4] {
let mut result = [0u64; 4];
for i in 0..4 {
for j in 0..8 {
result[3 - i] |= (bytes[i * 8 + j] as u64) << (8 * (7 - j));
}
}
result
}