use crate::{
syscalls::{syscall_arith256_mod, SyscallArith256ModParams},
zisklib::{eq, fcall_bn254_fp_inv, is_one, lt},
};
use super::constants::{P, P_MINUS_ONE};
#[inline]
pub fn add_fp_bn254(
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: &P, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn neg_fp_bn254(x: &[u64; 4], #[cfg(feature = "hints")] hints: &mut Vec<u64>) -> [u64; 4] {
let mut params = SyscallArith256ModParams {
a: x,
b: &P_MINUS_ONE,
c: &[0, 0, 0, 0],
module: &P,
d: &mut [0, 0, 0, 0],
};
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn mul_fp_bn254(
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: &P, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn square_fp_bn254(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: &P, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
#[inline]
pub fn inv_fp_bn254(x: &[u64; 4], #[cfg(feature = "hints")] hints: &mut Vec<u64>) -> [u64; 4] {
if eq(x, &[0, 0, 0, 0]) {
return [0, 0, 0, 0];
}
let inv = fcall_bn254_fp_inv(
x,
#[cfg(feature = "hints")]
hints,
);
assert!(lt(&inv, &P), "Inverse is not canonical");
let mut params = SyscallArith256ModParams {
a: x,
b: &inv,
c: &[0, 0, 0, 0],
module: &P,
d: &mut [0, 0, 0, 0],
};
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
assert!(is_one(params.d), "Inverse verification failed");
inv
}