From 334873b6a53c7bfbd43258ca72a25d6cd9abad31 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 19 Apr 2023 02:25:19 -0400 Subject: [PATCH] Use crypto-bigint's reduction in ed448 Achieves feasible performance in the ed448 which makes it potentially viable for real world usage. Accordingly prepares a new release, updating the README. --- Cargo.lock | 2 +- crypto/ed448/Cargo.toml | 2 +- crypto/ed448/README.md | 10 +++++----- crypto/ed448/src/backend.rs | 14 ++++++++++---- crypto/ed448/src/field.rs | 8 ++++++++ crypto/ed448/src/scalar.rs | 8 ++++++++ 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b44e173..3ac9b224 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5091,7 +5091,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minimal-ed448" -version = "0.3.0" +version = "0.3.1" dependencies = [ "crypto-bigint 0.5.1", "ff 0.13.0", diff --git a/crypto/ed448/Cargo.toml b/crypto/ed448/Cargo.toml index 72dfbf94..779eddec 100644 --- a/crypto/ed448/Cargo.toml +++ b/crypto/ed448/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minimal-ed448" -version = "0.3.0" +version = "0.3.1" description = "Unaudited, inefficient implementation of Ed448 in Rust" license = "MIT" repository = "https://github.com/serai-dex/serai/tree/develop/crypto/ed448" diff --git a/crypto/ed448/README.md b/crypto/ed448/README.md index ed2189a9..86b2b25d 100644 --- a/crypto/ed448/README.md +++ b/crypto/ed448/README.md @@ -1,9 +1,9 @@ # Minimal Ed448 -Inefficient, barebones implementation of Ed448 bound to the ff/group API, -rejecting torsion to achieve a PrimeGroup definition. This likely should not be -used and was only done so another library under Serai could confirm its -completion. It is minimally tested, yet should be correct for what it has. This -has not undergone auditing. +Barebones implementation of Ed448 bound to the ff/group API, rejecting torsion +to achieve a PrimeGroup definition. + +This library has not been audited. While it is complete, and decently tested, +any usage of it should be carefully considered. constant time and no_std. diff --git a/crypto/ed448/src/backend.rs b/crypto/ed448/src/backend.rs index 002c338f..ad17409b 100644 --- a/crypto/ed448/src/backend.rs +++ b/crypto/ed448/src/backend.rs @@ -69,6 +69,7 @@ macro_rules! field { ( $FieldName: ident, + $MODULUS_PADDED_STR: ident, $MODULUS_STR: ident, $MODULUS: ident, $WIDE_MODULUS: ident, @@ -89,12 +90,14 @@ macro_rules! field { use rand_core::RngCore; use generic_array::{typenum::U57, GenericArray}; - use crypto_bigint::{Integer, NonZero, Encoding}; + use crypto_bigint::{Integer, NonZero, Encoding, impl_modulus}; use ff::{Field, PrimeField, FieldBits, PrimeFieldBits, helpers::sqrt_ratio_generic}; use $crate::backend::u8_from_bool; + impl_modulus!(CryptoBigIntModulus, U512, $MODULUS_PADDED_STR); + fn reduce(x: U1024) -> U512 { U512::from_le_slice(&x.rem(&NonZero::new($WIDE_MODULUS).unwrap()).to_le_bytes()[.. 64]) } @@ -121,9 +124,12 @@ macro_rules! field { &y, &$MODULUS.0 )); - math_op!($FieldName, $FieldName, Mul, mul, MulAssign, mul_assign, |x, y| reduce(U1024::from( - U512::mul_wide(&x, &y) - ))); + math_op!($FieldName, $FieldName, Mul, mul, MulAssign, mul_assign, |x, y| { + use crypto_bigint::modular::constant_mod::{ResidueParams, Residue}; + Residue::::new(&x) + .mul(&Residue::::new(&y)) + .retrieve() + }); from_wrapper!($FieldName, U512, u8); from_wrapper!($FieldName, U512, u16); diff --git a/crypto/ed448/src/field.rs b/crypto/ed448/src/field.rs index 5766ee8b..47d73e33 100644 --- a/crypto/ed448/src/field.rs +++ b/crypto/ed448/src/field.rs @@ -6,6 +6,13 @@ use crypto_bigint::{U512, U1024}; #[derive(Clone, Copy, PartialEq, Eq, Default, Debug, Zeroize)] pub struct FieldElement(pub(crate) U512); +const MODULUS_PADDED_STR: &str = concat!( + "00000000000000", + "00", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +); + const MODULUS_STR: &str = concat!( "fffffffffffffffffffffffffffffffffffffffffffffffffffffffe", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -33,6 +40,7 @@ pub(crate) const Q_4: FieldElement = field!( FieldElement, + MODULUS_PADDED_STR, MODULUS_STR, MODULUS, WIDE_MODULUS, diff --git a/crypto/ed448/src/scalar.rs b/crypto/ed448/src/scalar.rs index ff3dc7a3..b64e2f94 100644 --- a/crypto/ed448/src/scalar.rs +++ b/crypto/ed448/src/scalar.rs @@ -6,6 +6,13 @@ use crypto_bigint::{U512, U1024}; #[derive(Clone, Copy, PartialEq, Eq, Default, Debug, Zeroize)] pub struct Scalar(pub(crate) U512); +const MODULUS_PADDED_STR: &str = concat!( + "00000000000000", + "00", + "3fffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3", +); + const MODULUS_STR: &str = concat!( "3fffffffffffffffffffffffffffffffffffffffffffffffffffffff", "7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3", @@ -30,6 +37,7 @@ const WIDE_MODULUS: U1024 = U1024::from_be_hex(concat!( field!( Scalar, + MODULUS_PADDED_STR, MODULUS_STR, MODULUS, WIDE_MODULUS,