use super::{bignum, p256, p384, p521};
use crate::low::{bignum_eq, ct};
pub(crate) fn bignum_montmul(z: &mut [u64], x: &[u64], y: &[u64], m: &[u64]) {
match m.len() {
4 => p256::bignum_montmul(z, x, y, m),
6 => p384::bignum_montmul(z, x, y, m),
_ => p521::bignum_montmul(z, x, y, m),
}
}
pub(crate) fn bignum_demont(z: &mut [u64], x: &[u64], m: &[u64]) {
match m.len() {
4 => p256::bignum_demont(z, x, m),
6 => p384::bignum_demont(z, x, m),
_ => p521::bignum_demont(z, x, m),
}
}
pub(crate) fn bignum_modadd(z: &mut [u64], x: &[u64], y: &[u64], m: &[u64]) {
match order(m) {
Some(Order::N256) => p256::bignum_modadd(z, x, y, m),
Some(Order::N384) => p384::bignum_modadd(z, x, y, m),
Some(Order::N521) => p521::bignum_modadd(z, x, y, m),
None => bignum::bignum_modadd(z, x, y, m),
}
}
pub(crate) fn bignum_modinv(z: &mut [u64], a: &[u64], b: &[u64], t: &mut [u64]) {
match order(b) {
Some(Order::N256) => p256::bignum_modinv(z, a, b, t),
Some(Order::N384) => p384::bignum_modinv(z, a, b, t),
Some(Order::N521) => p521::bignum_modinv(z, a, b, t),
None => bignum::bignum_modinv(z, a, b, t),
}
}
enum Order {
N256,
N384,
N521,
}
fn order(m: &[u64]) -> Option<Order> {
let is = |n: &[u64]| m.len() == n.len() && ct::into_public(bignum_eq(m, n));
if is(&p256::N) {
Some(Order::N256)
} else if is(&p384::N) {
Some(Order::N384)
} else if is(&p521::N) {
Some(Order::N521)
} else {
None
}
}