mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Remove crypto-bigint from the public API of prime-field
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2458,6 +2458,7 @@ version = "0.4.6"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ciphersuite 0.4.2",
|
"ciphersuite 0.4.2",
|
||||||
"crypto-bigint 0.5.5",
|
"crypto-bigint 0.5.5",
|
||||||
|
"crypto-bigint 0.6.1",
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
"digest 0.10.7",
|
"digest 0.10.7",
|
||||||
"ff-group-tests",
|
"ff-group-tests",
|
||||||
@@ -6005,6 +6006,7 @@ name = "minimal-ed448"
|
|||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ciphersuite 0.4.2",
|
"ciphersuite 0.4.2",
|
||||||
|
"crypto-bigint 0.6.1",
|
||||||
"ff-group-tests",
|
"ff-group-tests",
|
||||||
"hex",
|
"hex",
|
||||||
"prime-field",
|
"prime-field",
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ sha2 = { version = "0.11.0-rc.0", default-features = false }
|
|||||||
prime-field = { path = "../prime-field", default-features = false }
|
prime-field = { path = "../prime-field", default-features = false }
|
||||||
ciphersuite = { version = "0.4.2", path = "../ciphersuite", default-features = false }
|
ciphersuite = { version = "0.4.2", path = "../ciphersuite", default-features = false }
|
||||||
|
|
||||||
crypto-bigint = { version = "0.5", default-features = false, features = ["zeroize"] }
|
crypto-bigint-05 = { package = "crypto-bigint", version = "0.5", default-features = false, features = ["zeroize"] }
|
||||||
|
crypto-bigint = { version = "0.6", default-features = false, features = ["zeroize"] }
|
||||||
|
|
||||||
curve25519-dalek = { version = ">= 4.0, < 4.2", default-features = false, features = ["zeroize", "digest", "group", "precomputed-tables"] }
|
curve25519-dalek = { version = ">= 4.0, < 4.2", default-features = false, features = ["zeroize", "digest", "group", "precomputed-tables"] }
|
||||||
|
|
||||||
|
|||||||
@@ -500,8 +500,18 @@ impl FieldElement {
|
|||||||
///
|
///
|
||||||
/// This will reduce the `U256` by the modulus, into a member of the field.
|
/// This will reduce the `U256` by the modulus, into a member of the field.
|
||||||
#[deprecated]
|
#[deprecated]
|
||||||
pub const fn from_u256(u256: &crypto_bigint::U256) -> Self {
|
pub const fn from_u256(u256: &crypto_bigint_05::U256) -> Self {
|
||||||
FieldElement::from(&prime_field::crypto_bigint::U256::from_words(*u256.as_words()))
|
const MODULUS: crypto_bigint::U256 = crypto_bigint::U256::from_be_hex(
|
||||||
|
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed",
|
||||||
|
);
|
||||||
|
let mut u256 = crypto_bigint::U256::from_words(*u256.as_words());
|
||||||
|
loop {
|
||||||
|
let result = FieldElement::from_bytes(&u256.to_le_bytes());
|
||||||
|
if let Some(result) = result {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
u256 = u256.wrapping_sub(&MODULUS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a `FieldElement` from the reduction of a 512-bit number.
|
/// Create a `FieldElement` from the reduction of a 512-bit number.
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ zeroize = { version = "1", default-features = false, features = ["zeroize_derive
|
|||||||
|
|
||||||
sha3 = { version = "0.11.0-rc.0", default-features = false }
|
sha3 = { version = "0.11.0-rc.0", default-features = false }
|
||||||
|
|
||||||
|
crypto-bigint = { version = "0.6", default-features = false, features = ["zeroize"] }
|
||||||
prime-field = { path = "../prime-field", default-features = false }
|
prime-field = { path = "../prime-field", default-features = false }
|
||||||
ciphersuite = { path = "../ciphersuite", default-features = false }
|
ciphersuite = { path = "../ciphersuite", default-features = false }
|
||||||
|
|
||||||
@@ -32,6 +33,6 @@ rand_core = { version = "0.6", default-features = false, features = ["std"] }
|
|||||||
ff-group-tests = { path = "../ff-group-tests" }
|
ff-group-tests = { path = "../ff-group-tests" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
alloc = ["zeroize/alloc", "sha3/alloc", "prime-field/alloc", "ciphersuite/alloc"]
|
alloc = ["zeroize/alloc", "sha3/alloc", "crypto-bigint/alloc", "prime-field/alloc", "ciphersuite/alloc"]
|
||||||
std = ["alloc", "zeroize/std", "prime-field/std", "ciphersuite/std"]
|
std = ["alloc", "zeroize/std", "prime-field/std", "ciphersuite/std"]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use prime_field::{
|
|||||||
subtle::{Choice, CtOption, ConstantTimeEq, ConditionallySelectable, ConditionallyNegatable},
|
subtle::{Choice, CtOption, ConstantTimeEq, ConditionallySelectable, ConditionallyNegatable},
|
||||||
zeroize::Zeroize,
|
zeroize::Zeroize,
|
||||||
rand_core::RngCore,
|
rand_core::RngCore,
|
||||||
crypto_bigint::U512,
|
|
||||||
};
|
};
|
||||||
|
use crypto_bigint::U512;
|
||||||
|
|
||||||
use ciphersuite::group::{
|
use ciphersuite::group::{
|
||||||
ff::{Field, PrimeField, PrimeFieldBits},
|
ff::{Field, PrimeField, PrimeFieldBits},
|
||||||
@@ -18,17 +18,37 @@ use ciphersuite::group::{
|
|||||||
|
|
||||||
use crate::{u8_from_bool, Scalar, FieldElement};
|
use crate::{u8_from_bool, Scalar, FieldElement};
|
||||||
|
|
||||||
const G_Y: FieldElement = FieldElement::from(&U512::from_be_hex(concat!(
|
const G_Y: FieldElement = {
|
||||||
"0000000000000000",
|
let bytes = U512::from_be_hex(concat!(
|
||||||
"693f46716eb6bc248876203756c9c7624bea73736ca3984087789c1e",
|
"0000000000000000",
|
||||||
"05a0c2d73ad3ff1ce67c39c4fdbd132c4ed7c8ad9808795bf230fa14",
|
"693f46716eb6bc248876203756c9c7624bea73736ca3984087789c1e",
|
||||||
)));
|
"05a0c2d73ad3ff1ce67c39c4fdbd132c4ed7c8ad9808795bf230fa14",
|
||||||
|
))
|
||||||
|
.to_le_bytes();
|
||||||
|
let mut dest = [0; 57];
|
||||||
|
let mut i = 0;
|
||||||
|
while i < dest.len() {
|
||||||
|
dest[i] = bytes[i];
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
FieldElement::from_bytes(&dest).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
const G_X: FieldElement = FieldElement::from(&U512::from_be_hex(concat!(
|
const G_X: FieldElement = {
|
||||||
"0000000000000000",
|
let bytes = U512::from_be_hex(concat!(
|
||||||
"4f1970c66bed0ded221d15a622bf36da9e146570470f1767ea6de324",
|
"0000000000000000",
|
||||||
"a3d3a46412ae1af72ab66511433b80e18b00938e2626a82bc70cc05e",
|
"4f1970c66bed0ded221d15a622bf36da9e146570470f1767ea6de324",
|
||||||
)));
|
"a3d3a46412ae1af72ab66511433b80e18b00938e2626a82bc70cc05e",
|
||||||
|
))
|
||||||
|
.to_le_bytes();
|
||||||
|
let mut dest = [0; 57];
|
||||||
|
let mut i = 0;
|
||||||
|
while i < dest.len() {
|
||||||
|
dest[i] = bytes[i];
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
FieldElement::from_bytes(&dest).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
fn recover_x(y: FieldElement) -> CtOption<FieldElement> {
|
fn recover_x(y: FieldElement) -> CtOption<FieldElement> {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
pub use subtle;
|
pub use subtle;
|
||||||
pub use zeroize;
|
pub use zeroize;
|
||||||
pub use rand_core;
|
pub use rand_core;
|
||||||
pub use crypto_bigint;
|
|
||||||
pub use ff;
|
pub use ff;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod __prime_field_private {
|
pub mod __prime_field_private {
|
||||||
|
pub use crypto_bigint;
|
||||||
pub use paste;
|
pub use paste;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use ff_group_tests;
|
pub use ff_group_tests;
|
||||||
@@ -94,6 +94,8 @@ pub mod __prime_field_private {
|
|||||||
/// less than `modulus_as_be_hex`.
|
/// less than `modulus_as_be_hex`.
|
||||||
///
|
///
|
||||||
/// `big_endian` controls if the encoded representation will be big-endian or not.
|
/// `big_endian` controls if the encoded representation will be big-endian or not.
|
||||||
|
///
|
||||||
|
/// `repr` must satisfy the requirements for `PrimeField::Repr`.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! odd_prime_field_with_specific_repr {
|
macro_rules! odd_prime_field_with_specific_repr {
|
||||||
@@ -116,13 +118,15 @@ macro_rules! odd_prime_field_with_specific_repr {
|
|||||||
},
|
},
|
||||||
zeroize::Zeroize,
|
zeroize::Zeroize,
|
||||||
rand_core::RngCore,
|
rand_core::RngCore,
|
||||||
crypto_bigint::{
|
|
||||||
Limb, Encoding, Integer, Uint,
|
|
||||||
modular::{ConstMontyParams, ConstMontyForm},
|
|
||||||
impl_modulus,
|
|
||||||
},
|
|
||||||
ff::*,
|
ff::*,
|
||||||
__prime_field_private::*,
|
__prime_field_private::{
|
||||||
|
crypto_bigint::{
|
||||||
|
Limb, Encoding, Integer, Uint,
|
||||||
|
modular::{ConstMontyParams, ConstMontyForm},
|
||||||
|
impl_modulus,
|
||||||
|
},
|
||||||
|
*,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const MODULUS_WITHOUT_PREFIX: &str = hex_str_without_prefix($modulus_as_be_hex);
|
const MODULUS_WITHOUT_PREFIX: &str = hex_str_without_prefix($modulus_as_be_hex);
|
||||||
@@ -180,7 +184,7 @@ macro_rules! odd_prime_field_with_specific_repr {
|
|||||||
const MODULUS_MINUS_TWO: UnderlyingUint = MODULUS.wrapping_sub(&UnderlyingUint::from_u8(2));
|
const MODULUS_MINUS_TWO: UnderlyingUint = MODULUS.wrapping_sub(&UnderlyingUint::from_u8(2));
|
||||||
const T: UnderlyingUint = MODULUS_MINUS_ONE.shr_vartime($name::S);
|
const T: UnderlyingUint = MODULUS_MINUS_ONE.shr_vartime($name::S);
|
||||||
|
|
||||||
/// A field automatically generated with `short-weierstrass`.
|
/// A field automatically generated with `prime-field`.
|
||||||
#[derive(Clone, Copy, Eq, Debug)]
|
#[derive(Clone, Copy, Eq, Debug)]
|
||||||
pub struct $name(Underlying);
|
pub struct $name(Underlying);
|
||||||
|
|
||||||
@@ -192,9 +196,47 @@ macro_rules! odd_prime_field_with_specific_repr {
|
|||||||
|
|
||||||
impl $name {
|
impl $name {
|
||||||
/// Create a `$name` from the `Uint` type underlying it.
|
/// Create a `$name` from the `Uint` type underlying it.
|
||||||
pub const fn from(value: &UnderlyingUint) -> Self {
|
const fn from(value: &UnderlyingUint) -> Self {
|
||||||
$name(Underlying::new(value))
|
$name(Underlying::new(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a `$name` from bytes within a `const` context.
|
||||||
|
///
|
||||||
|
/// This function executes in variable time. `<$name as PrimeField>::from_repr` SHOULD
|
||||||
|
/// be used instead.
|
||||||
|
pub const fn from_bytes(value: &[u8; MODULUS_BYTES]) -> Option<Self> {
|
||||||
|
let mut expanded_repr = [0; UnderlyingUint::BYTES];
|
||||||
|
let repr: &[u8] = value.as_slice();
|
||||||
|
let (uint, repr) = if $big_endian {
|
||||||
|
let start = UnderlyingUint::BYTES - MODULUS_BYTES;
|
||||||
|
let mut i = 0;
|
||||||
|
while i < repr.len() {
|
||||||
|
expanded_repr[start + i] = repr[i];
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
let uint = Underlying::new(&UnderlyingUint::from_be_slice(&expanded_repr));
|
||||||
|
(uint, uint.retrieve().to_be_bytes())
|
||||||
|
} else {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < repr.len() {
|
||||||
|
expanded_repr[i] = repr[i];
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
let uint = Underlying::new(&UnderlyingUint::from_le_slice(&expanded_repr));
|
||||||
|
(uint, uint.retrieve().to_le_bytes())
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ensure the representations match
|
||||||
|
let mut i = 0;
|
||||||
|
while i < expanded_repr.len() {
|
||||||
|
if repr[i] != expanded_repr[i] {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Self(uint))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl From<u8> for $name {
|
impl From<u8> for $name {
|
||||||
fn from(value: u8) -> Self {
|
fn from(value: u8) -> Self {
|
||||||
@@ -416,6 +458,7 @@ macro_rules! odd_prime_field_with_specific_repr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The encoded representation of a `$name`.
|
/// The encoded representation of a `$name`.
|
||||||
|
// This is required to be bespoke to satisfy `Default`.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Repr([u8; MODULUS_BYTES]);
|
pub struct Repr([u8; MODULUS_BYTES]);
|
||||||
impl Default for Repr {
|
impl Default for Repr {
|
||||||
|
|||||||
Reference in New Issue
Block a user