Skip to content

Commit f8cd31a

Browse files
committed
x448: api fixups
3 parents 654eb53 + f5fba43 + 5e75386 commit f8cd31a

File tree

5 files changed

+28
-33
lines changed

5 files changed

+28
-33
lines changed

ed448-goldilocks/src/field.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ mod element;
22
mod scalar;
33

44
pub(crate) use element::*;
5-
pub(crate) use scalar::CurveWithScalar;
65
pub use scalar::{
7-
MODULUS_LIMBS, NZ_ORDER, ORDER, Scalar, ScalarBytes, WIDE_ORDER, WideScalarBytes,
6+
CurveWithScalar, MODULUS_LIMBS, NZ_ORDER, ORDER, Scalar, ScalarBytes, WIDE_ORDER,
7+
WideScalarBytes,
88
};
99

1010
use crate::curve::twedwards::extended::ExtendedPoint as TwExtendedPoint;

ed448-goldilocks/src/field/scalar.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,18 @@ pub type ScalarBytes<C> = Array<u8, <C as CurveWithScalar>::ReprSize>;
4141
/// The number of bytes needed to represent the safely create a scalar from a random bytes
4242
pub type WideScalarBytes<C> = Array<u8, Prod<<C as CurveWithScalar>::ReprSize, U2>>;
4343

44+
/// Representation of a curve scalar for either Ed448 or Decaf448
4445
pub trait CurveWithScalar: 'static + CurveArithmetic + Send + Sync {
46+
/// The size of the scalar for the given curve
4547
type ReprSize: ArraySize<ArrayType<u8>: Copy> + Mul<U2, Output: ArraySize<ArrayType<u8>: Copy>>;
4648

49+
/// Create a scalar from the wide representation
4750
fn from_bytes_mod_order_wide(input: &WideScalarBytes<Self>) -> Scalar<Self>;
4851

52+
/// Create a scalar from its serialization
4953
fn from_canonical_bytes(bytes: &ScalarBytes<Self>) -> CtOption<Scalar<Self>>;
5054

55+
/// Return the serialization for a given scalar
5156
fn to_repr(scalar: &Scalar<Self>) -> ScalarBytes<Self>;
5257
}
5358

ed448-goldilocks/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ pub use edwards::{
6060
AffinePoint, CompressedEdwardsY, EdwardsPoint, EdwardsScalar, EdwardsScalarBytes,
6161
WideEdwardsScalarBytes,
6262
};
63-
pub use field::{MODULUS_LIMBS, ORDER, Scalar, WIDE_ORDER};
64-
pub use montgomery::{MontgomeryPoint, ProjectiveMontgomeryPoint};
63+
pub use field::{CurveWithScalar, MODULUS_LIMBS, ORDER, Scalar, WIDE_ORDER};
64+
pub use montgomery::{LOW_A, LOW_B, LOW_C, MontgomeryPoint, ProjectiveMontgomeryPoint};
6565
pub use ristretto::{CompressedRistretto, RistrettoPoint};
6666
#[cfg(feature = "signing")]
6767
pub use sign::*;

ed448-goldilocks/src/montgomery.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,22 @@ use core::fmt;
1818
use core::ops::Mul;
1919
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
2020

21-
// Low order points on Curve448 and it's twist
22-
const LOW_A: MontgomeryPoint = MontgomeryPoint([
21+
/// First low order point on Curve448 and it's twist
22+
pub const LOW_A: MontgomeryPoint = MontgomeryPoint([
2323
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2424
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2525
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2626
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2727
]);
28-
const LOW_B: MontgomeryPoint = MontgomeryPoint([
28+
/// Second low order point on Curve448 and it's twist
29+
pub const LOW_B: MontgomeryPoint = MontgomeryPoint([
2930
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3031
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3132
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3233
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3334
]);
34-
const LOW_C: MontgomeryPoint = MontgomeryPoint([
35+
/// Third low order point on Curve448 and it's twist
36+
pub const LOW_C: MontgomeryPoint = MontgomeryPoint([
3537
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3638
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
3739
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

x448/src/lib.rs

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
#![no_std]
22

3+
use ed448_goldilocks::Ed448;
34
use ed448_goldilocks::MontgomeryPoint;
4-
use ed448_goldilocks::Scalar;
5+
use ed448_goldilocks::elliptic_curve::{bigint::U448, scalar::FromUintUnchecked};
56
use rand_core::{CryptoRng, RngCore};
67
use zeroize::Zeroize;
78

9+
type Scalar = ed448_goldilocks::Scalar<Ed448>;
10+
811
/// Computes a Scalar according to RFC7748
912
/// given a byte array of length 56
1013
impl From<[u8; 56]> for Secret {
@@ -20,16 +23,18 @@ impl From<[u8; 56]> for Secret {
2023
/// XXX: Waiting for upstream PR to use pre-computation
2124
impl From<&Secret> for PublicKey {
2225
fn from(secret: &Secret) -> PublicKey {
23-
let point = &MontgomeryPoint::GENERATOR * &Scalar::from_bytes(&secret.0);
26+
let secret = secret.as_scalar();
27+
let point = &MontgomeryPoint::GENERATOR * &secret;
2428
PublicKey(point)
2529
}
2630
}
2731

2832
/// A PublicKey is a point on Curve448.
33+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
2934
pub struct PublicKey(MontgomeryPoint);
3035

3136
/// A Secret is a Scalar on Curve448.
32-
#[derive(Zeroize)]
37+
#[derive(Clone, Zeroize)]
3338
#[zeroize(drop)]
3439
pub struct Secret([u8; 56]);
3540

@@ -85,7 +90,7 @@ impl Secret {
8590
// Taken from dalek-x25519
8691
pub fn new<T>(csprng: &mut T) -> Self
8792
where
88-
T: RngCore + CryptoRng,
93+
T: RngCore + CryptoRng + ?Sized,
8994
{
9095
let mut bytes = [0u8; 56];
9196

@@ -102,7 +107,8 @@ impl Secret {
102107

103108
/// Views a Secret as a Scalar
104109
fn as_scalar(&self) -> Scalar {
105-
Scalar::from_bytes(&self.0)
110+
let secret = U448::from_le_slice(&self.0);
111+
Scalar::from_uint_unchecked(secret)
106112
}
107113

108114
/// Performs a Diffie-hellman key exchange between the secret key and an external public key
@@ -171,28 +177,10 @@ mod test {
171177
use super::*;
172178
use alloc::vec;
173179

180+
use ed448_goldilocks::{LOW_A, LOW_B, LOW_C};
181+
174182
#[test]
175183
fn test_low_order() {
176-
// These are also in ed448-goldilocks. We could export them, but I cannot see any use except for this test.
177-
const LOW_A: MontgomeryPoint = MontgomeryPoint([
178-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182-
]);
183-
const LOW_B: MontgomeryPoint = MontgomeryPoint([
184-
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188-
]);
189-
const LOW_C: MontgomeryPoint = MontgomeryPoint([
190-
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
191-
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
192-
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
193-
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
194-
]);
195-
196184
// Notice, that this is the only way to add low order points into the system
197185
// and this is not exposed to the user. The user will use `from_bytes` which will check for low order points.
198186
let bad_key_a = PublicKey(LOW_A);

0 commit comments

Comments
 (0)