use crate::{
syscalls::{syscall_arith256_mod, SyscallArith256ModParams},
zisklib::{fcall_secp256r1_fn_inv, is_one, is_zero, lt},
};
use super::constants::{N, N_MINUS_ONE};
pub fn reduce_fn_secp256r1(
x: &[u64; 4],
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> [u64; 4] {
if lt(x, &N) {
return *x;
}
let mut params = SyscallArith256ModParams {
a: x,
b: &[1, 0, 0, 0],
c: &[0, 0, 0, 0],
module: &N,
d: &mut [0, 0, 0, 0],
};
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
pub fn add_fn_secp256r1(
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: &N, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
pub fn neg_fn_secp256r1(x: &[u64; 4], #[cfg(feature = "hints")] hints: &mut Vec<u64>) -> [u64; 4] {
let mut params = SyscallArith256ModParams {
a: x,
b: &N_MINUS_ONE,
c: &[0, 0, 0, 0],
module: &N,
d: &mut [0, 0, 0, 0],
};
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
pub fn sub_fn_secp256r1(
x: &[u64; 4],
y: &[u64; 4],
#[cfg(feature = "hints")] hints: &mut Vec<u64>,
) -> [u64; 4] {
let mut params =
SyscallArith256ModParams { a: y, b: &N_MINUS_ONE, c: x, module: &N, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
pub fn mul_fn_secp256r1(
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: &N, d: &mut [0, 0, 0, 0] };
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
*params.d
}
pub fn inv_fn_secp256r1(x: &[u64; 4], #[cfg(feature = "hints")] hints: &mut Vec<u64>) -> [u64; 4] {
if is_zero(x) {
return *x;
}
let inv = fcall_secp256r1_fn_inv(
x,
#[cfg(feature = "hints")]
hints,
);
assert!(lt(&inv, &N), "Inverse is not canonical");
let mut params = SyscallArith256ModParams {
a: x,
b: &inv,
c: &[0, 0, 0, 0],
module: &N,
d: &mut [0, 0, 0, 0],
};
syscall_arith256_mod(
&mut params,
#[cfg(feature = "hints")]
hints,
);
assert!(is_one(params.d), "Inverse verification failed");
inv
}