#![allow(clippy::arithmetic_side_effects)]
use crate::{BignP256, ORDER_HEX, U256};
use elliptic_curve::{
Curve as _,
bigint::cpubits,
ff::PrimeField,
scalar::{FromUintUnchecked, IsHigh},
subtle::{Choice, ConstantTimeEq, ConstantTimeGreater, CtOption},
};
cpubits! {
32 => {
#[path = "scalar/bignp256_scalar_32.rs"]
#[allow(
dead_code,
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_sign_loss,
clippy::identity_op,
clippy::needless_lifetimes,
clippy::too_many_arguments,
clippy::unnecessary_cast
)]
mod scalar_impl;
}
64 => {
#[path = "scalar/bignp256_scalar_64.rs"]
#[allow(
dead_code,
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_sign_loss,
clippy::identity_op,
clippy::needless_lifetimes,
clippy::too_many_arguments,
clippy::unnecessary_cast
)]
mod scalar_impl;
}
}
use self::scalar_impl::*;
#[cfg(doc)]
use core::ops::{Add, Mul, Neg, Sub};
primefield::monty_field_params! {
name: ScalarParams,
modulus: ORDER_HEX,
uint: U256,
byte_order: primefield::ByteOrder::LittleEndian,
multiplicative_generator: 3,
doc: "Montgomery parameters for the bign-curve256v1 scalar modulus"
}
primefield::monty_field_element! {
name: Scalar,
params: ScalarParams,
uint: U256,
doc: "Element in the bign-curve256v1 scalar field modulo n"
}
primefield::fiat_monty_field_arithmetic! {
name: Scalar,
params: ScalarParams,
uint: U256,
non_mont: fiat_bignp256_scalar_non_montgomery_domain_field_element,
mont: fiat_bignp256_scalar_montgomery_domain_field_element,
from_mont: fiat_bignp256_scalar_from_montgomery,
to_mont: fiat_bignp256_scalar_to_montgomery,
add: fiat_bignp256_scalar_add,
sub: fiat_bignp256_scalar_sub,
mul: fiat_bignp256_scalar_mul,
neg: fiat_bignp256_scalar_opp,
square: fiat_bignp256_scalar_square,
divstep_precomp: fiat_bignp256_scalar_divstep_precomp,
divstep: fiat_bignp256_scalar_divstep,
msat: fiat_bignp256_scalar_msat,
selectnz: fiat_bignp256_scalar_selectznz
}
primefield::monty_field_reduce! {
name: Scalar,
params: ScalarParams,
uint: U256,
}
elliptic_curve::scalar_impls!(BignP256, Scalar);
impl AsRef<Scalar> for Scalar {
fn as_ref(&self) -> &Scalar {
self
}
}
impl FromUintUnchecked for Scalar {
type Uint = U256;
fn from_uint_unchecked(uint: Self::Uint) -> Self {
Self::from_uint_unchecked(uint)
}
}
impl IsHigh for Scalar {
fn is_high(&self) -> Choice {
const MODULUS_SHR1: U256 = BignP256::ORDER.as_ref().shr_vartime(1);
self.to_canonical().ct_gt(&MODULUS_SHR1)
}
}
#[cfg(test)]
mod tests {
use super::{Scalar, U256};
use super::{
ScalarParams, fiat_bignp256_scalar_montgomery_domain_field_element,
fiat_bignp256_scalar_msat, fiat_bignp256_scalar_non_montgomery_domain_field_element,
fiat_bignp256_scalar_to_montgomery,
};
primefield::test_primefield!(Scalar, U256);
primefield::test_fiat_monty_field_arithmetic!(
name: Scalar,
params: ScalarParams,
uint: U256,
non_mont: fiat_bignp256_scalar_non_montgomery_domain_field_element,
mont: fiat_bignp256_scalar_montgomery_domain_field_element,
to_mont: fiat_bignp256_scalar_to_montgomery,
msat: fiat_bignp256_scalar_msat
);
}