Skip to content

Commit 19962f7

Browse files
authored
x448: api fixups (#1374)
- remove `to_diffie_hellman` - make `Secret` a newtype for `Array`
1 parent 6b8726d commit 19962f7

File tree

1 file changed

+25
-28
lines changed

1 file changed

+25
-28
lines changed

x448/src/lib.rs

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

3+
use core::array::TryFromSliceError;
34
use ed448_goldilocks::{
45
MontgomeryPoint,
5-
elliptic_curve::{bigint::U448, scalar::FromUintUnchecked},
6+
elliptic_curve::{
7+
array::{Array, typenum::U56},
8+
bigint::U448,
9+
scalar::FromUintUnchecked,
10+
},
611
};
712
use rand_core::{CryptoRng, RngCore};
813
use zeroize::Zeroize;
@@ -13,7 +18,7 @@ type MontgomeryScalar = ed448_goldilocks::Scalar<ed448_goldilocks::Ed448>;
1318
/// given a byte array of length 56
1419
impl From<[u8; 56]> for Secret {
1520
fn from(arr: [u8; 56]) -> Secret {
16-
let mut secret = Secret(arr);
21+
let mut secret = Secret(arr.into());
1722
secret.clamp();
1823
secret
1924
}
@@ -37,7 +42,7 @@ pub struct PublicKey(MontgomeryPoint);
3742
/// A Secret is a Scalar on Curve448.
3843
#[derive(Clone, Zeroize)]
3944
#[zeroize(drop)]
40-
pub struct Secret([u8; 56]);
45+
pub struct Secret(Array<u8, U56>);
4146

4247
/// A SharedSecret is a point on Curve448.
4348
/// This point is the result of a Diffie-Hellman key exchange.
@@ -122,25 +127,19 @@ impl Secret {
122127
Some(SharedSecret(shared_key))
123128
}
124129

125-
/// Performs a Diffie-hellman key exchange once between the secret key and an external public key
126-
pub fn to_diffie_hellman(self, public_key: &PublicKey) -> Option<SharedSecret> {
127-
self.as_diffie_hellman(public_key)
130+
/// Converts a secret into a byte array
131+
pub fn as_bytes(&self) -> &[u8; 56] {
132+
self.0.as_ref()
128133
}
134+
}
129135

130-
/// Converts a byte slice into a secret and clamp
131-
pub fn from_bytes(bytes: &[u8]) -> Option<Secret> {
132-
// First check if we have 56 bytes
133-
if bytes.len() != 56 {
134-
return None;
135-
}
136-
137-
let secret = Secret::from(slice_to_array(bytes));
138-
Some(secret)
139-
}
136+
impl TryFrom<&[u8]> for Secret {
137+
type Error = TryFromSliceError;
140138

141-
/// Converts a secret into a byte array
142-
pub fn as_bytes(&self) -> &[u8; 56] {
143-
&self.0
139+
fn try_from(bytes: &[u8]) -> Result<Secret, TryFromSliceError> {
140+
let mut secret = Secret(Array::try_from(bytes)?);
141+
secret.clamp();
142+
Ok(secret)
144143
}
145144
}
146145

@@ -234,13 +233,12 @@ mod test {
234233

235234
#[test]
236235
fn test_rfc_test_vectors_alice_bob() {
237-
let alice_priv = Secret::from_bytes(&[
236+
let alice_priv = Secret::from([
238237
0x9a, 0x8f, 0x49, 0x25, 0xd1, 0x51, 0x9f, 0x57, 0x75, 0xcf, 0x46, 0xb0, 0x4b, 0x58,
239238
0x0, 0xd4, 0xee, 0x9e, 0xe8, 0xba, 0xe8, 0xbc, 0x55, 0x65, 0xd4, 0x98, 0xc2, 0x8d,
240239
0xd9, 0xc9, 0xba, 0xf5, 0x74, 0xa9, 0x41, 0x97, 0x44, 0x89, 0x73, 0x91, 0x0, 0x63,
241240
0x82, 0xa6, 0xf1, 0x27, 0xab, 0x1d, 0x9a, 0xc2, 0xd8, 0xc0, 0xa5, 0x98, 0x72, 0x6b,
242-
])
243-
.unwrap();
241+
]);
244242
let got_alice_pub = PublicKey::from(&alice_priv);
245243

246244
let expected_alice_pub = [
@@ -251,13 +249,12 @@ mod test {
251249
];
252250
assert_eq!(got_alice_pub.as_bytes()[..], expected_alice_pub[..]);
253251

254-
let bob_priv = Secret::from_bytes(&[
252+
let bob_priv = Secret::from([
255253
0x1c, 0x30, 0x6a, 0x7a, 0xc2, 0xa0, 0xe2, 0xe0, 0x99, 0xb, 0x29, 0x44, 0x70, 0xcb,
256254
0xa3, 0x39, 0xe6, 0x45, 0x37, 0x72, 0xb0, 0x75, 0x81, 0x1d, 0x8f, 0xad, 0xd, 0x1d,
257255
0x69, 0x27, 0xc1, 0x20, 0xbb, 0x5e, 0xe8, 0x97, 0x2b, 0xd, 0x3e, 0x21, 0x37, 0x4c,
258256
0x9c, 0x92, 0x1b, 0x9, 0xd1, 0xb0, 0x36, 0x6f, 0x10, 0xb6, 0x51, 0x73, 0x99, 0x2d,
259-
])
260-
.unwrap();
257+
]);
261258
let got_bob_pub = PublicKey::from(&bob_priv);
262259

263260
let expected_bob_pub = [
@@ -268,8 +265,8 @@ mod test {
268265
];
269266
assert_eq!(got_bob_pub.as_bytes()[..], expected_bob_pub[..]);
270267

271-
let bob_shared = bob_priv.to_diffie_hellman(&got_alice_pub).unwrap();
272-
let alice_shared = alice_priv.to_diffie_hellman(&got_bob_pub).unwrap();
268+
let bob_shared = bob_priv.as_diffie_hellman(&got_alice_pub).unwrap();
269+
let alice_shared = alice_priv.as_diffie_hellman(&got_bob_pub).unwrap();
273270
assert_eq!(bob_shared.as_bytes()[..], alice_shared.as_bytes()[..]);
274271

275272
let expected_shared = [
@@ -341,7 +338,7 @@ mod test {
341338

342339
for vector in test_vectors {
343340
let public_key = PublicKey::from_bytes(&vector.point).unwrap();
344-
let secret = Secret::from_bytes(&vector.secret).unwrap();
341+
let secret = Secret::try_from(&vector.secret[..]).unwrap();
345342

346343
let got = secret.as_diffie_hellman(&public_key).unwrap();
347344

0 commit comments

Comments
 (0)