Skip to content

Commit 7368a67

Browse files
committed
x448: api fixups
3 parents 654eb53 + f5fba43 + 8b9ed18 commit 7368a67

File tree

5 files changed

+49
-32
lines changed

5 files changed

+49
-32
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: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
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::{
6+
bigint::U448, group::GroupEncoding, scalar::FromUintUnchecked,
7+
};
58
use rand_core::{CryptoRng, RngCore};
69
use zeroize::Zeroize;
710

11+
type Scalar = ed448_goldilocks::Scalar<Ed448>;
12+
813
/// Computes a Scalar according to RFC7748
914
/// given a byte array of length 56
1015
impl From<[u8; 56]> for Secret {
1116
fn from(arr: [u8; 56]) -> Secret {
12-
let mut secret = Secret(arr);
17+
let mut secret = Secret(arr.into());
1318
secret.clamp();
1419
secret
1520
}
@@ -20,16 +25,18 @@ impl From<[u8; 56]> for Secret {
2025
/// XXX: Waiting for upstream PR to use pre-computation
2126
impl From<&Secret> for PublicKey {
2227
fn from(secret: &Secret) -> PublicKey {
23-
let point = &MontgomeryPoint::GENERATOR * &Scalar::from_bytes(&secret.0);
28+
let secret = secret.as_scalar();
29+
let point = &MontgomeryPoint::GENERATOR * &secret;
2430
PublicKey(point)
2531
}
2632
}
2733

2834
/// A PublicKey is a point on Curve448.
35+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
2936
pub struct PublicKey(MontgomeryPoint);
3037

3138
/// A Secret is a Scalar on Curve448.
32-
#[derive(Zeroize)]
39+
#[derive(Clone, Zeroize)]
3340
#[zeroize(drop)]
3441
pub struct Secret([u8; 56]);
3542

@@ -85,7 +92,7 @@ impl Secret {
8592
// Taken from dalek-x25519
8693
pub fn new<T>(csprng: &mut T) -> Self
8794
where
88-
T: RngCore + CryptoRng,
95+
T: RngCore + CryptoRng + ?Sized,
8996
{
9097
let mut bytes = [0u8; 56];
9198

@@ -102,7 +109,8 @@ impl Secret {
102109

103110
/// Views a Secret as a Scalar
104111
fn as_scalar(&self) -> Scalar {
105-
Scalar::from_bytes(&self.0)
112+
let secret = U448::from_le_slice(&self.0);
113+
Scalar::from_uint_unchecked(secret)
106114
}
107115

108116
/// Performs a Diffie-hellman key exchange between the secret key and an external public key
@@ -171,27 +179,29 @@ mod test {
171179
use super::*;
172180
use alloc::vec;
173181

182+
use ed448_goldilocks::{LOW_A, LOW_B, LOW_C};
183+
174184
#[test]
175185
fn test_low_order() {
176186
// 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-
]);
187+
//const LOW_A: MontgomeryPoint = MontgomeryPoint([
188+
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189+
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190+
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191+
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192+
//]);
193+
//const LOW_B: MontgomeryPoint = MontgomeryPoint([
194+
// 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195+
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196+
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197+
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198+
//]);
199+
//const LOW_C: MontgomeryPoint = MontgomeryPoint([
200+
// 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
201+
// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
202+
// 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
203+
// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
204+
//]);
195205

196206
// Notice, that this is the only way to add low order points into the system
197207
// and this is not exposed to the user. The user will use `from_bytes` which will check for low order points.

0 commit comments

Comments
 (0)