Skip to content

Commit 23d743d

Browse files
authored
ed448-goldilocks: reuse types from ed448 (#1224)
1 parent c6efb4e commit 23d743d

File tree

5 files changed

+60
-235
lines changed

5 files changed

+60
-235
lines changed

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ed448-goldilocks/Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@ This crate also includes signing and verifying of Ed448 signatures.
1818
[dependencies]
1919
crypto_signature = { version = "3.0.0-rc.0", default-features = false, features = ["digest", "rand_core"], optional = true, package = "signature" }
2020
elliptic-curve = { version = "0.14.0-rc.5", features = ["arithmetic", "hash2curve", "pkcs8"] }
21+
ed448 = { version = "=0.5.0-pre.0", default-features = false, optional = true }
2122
rand_core = { version = "0.9", default-features = false }
2223
serdect = { version = "0.3.0", optional = true }
2324
sha3 = { version = "0.11.0-rc.0", default-features = false }
2425
subtle = { version = "2.6", default-features = false }
2526

2627
[features]
2728
default = ["std", "signing", "pkcs8"]
28-
alloc = ["crypto_signature/alloc", "elliptic-curve/alloc", "serdect/alloc"]
29+
alloc = ["crypto_signature/alloc", "ed448?/alloc", "elliptic-curve/alloc", "serdect/alloc"]
2930
std = ["alloc"]
30-
3131
bits = ["elliptic-curve/bits"]
32-
pkcs8 = ["elliptic-curve/pkcs8"]
33-
signing = ["dep:crypto_signature"]
34-
serde = ["dep:serdect"]
32+
pkcs8 = ["ed448?/pkcs8", "elliptic-curve/pkcs8"]
33+
signing = ["dep:crypto_signature", "ed448"]
34+
serde = ["dep:serdect", "ed448?/serde_bytes"]
3535

3636
[dev-dependencies]
3737
hex-literal = "1"

ed448-goldilocks/src/curve/edwards/extended.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ impl TryFrom<&[u8]> for CompressedEdwardsY {
148148

149149
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
150150
let bytes = <PointBytes>::try_from(value).map_err(|_| "Invalid length")?;
151-
Self::try_from(&bytes)
151+
Ok(CompressedEdwardsY(bytes))
152152
}
153153
}
154154

@@ -173,24 +173,6 @@ impl From<&CompressedEdwardsY> for PointBytes {
173173
}
174174
}
175175

176-
impl TryFrom<PointBytes> for CompressedEdwardsY {
177-
type Error = &'static str;
178-
179-
fn try_from(value: PointBytes) -> Result<Self, Self::Error> {
180-
let pt = CompressedEdwardsY(value);
181-
let _ = Option::<EdwardsPoint>::from(pt.decompress()).ok_or("Invalid point")?;
182-
Ok(pt)
183-
}
184-
}
185-
186-
impl TryFrom<&PointBytes> for CompressedEdwardsY {
187-
type Error = &'static str;
188-
189-
fn try_from(value: &PointBytes) -> Result<Self, Self::Error> {
190-
Self::try_from(*value)
191-
}
192-
}
193-
194176
#[cfg(feature = "serde")]
195177
impl serdect::serde::Serialize for CompressedEdwardsY {
196178
fn serialize<S: serdect::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
@@ -210,6 +192,12 @@ impl<'de> serdect::serde::Deserialize<'de> for CompressedEdwardsY {
210192
}
211193
}
212194

195+
impl From<PointBytes> for CompressedEdwardsY {
196+
fn from(point: PointBytes) -> Self {
197+
Self(point)
198+
}
199+
}
200+
213201
impl CompressedEdwardsY {
214202
/// The compressed generator point
215203
pub const GENERATOR: Self = Self([
Lines changed: 13 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,24 @@
11
use crate::*;
2-
use elliptic_curve::Group;
2+
use elliptic_curve::array::Array;
33

4-
/// Ed448 signature as defined in [RFC8032 § 5.2.5]
5-
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
6-
pub struct Signature {
7-
pub(crate) r: CompressedEdwardsY,
8-
pub(crate) s: [u8; 57],
9-
}
10-
11-
impl Default for Signature {
12-
fn default() -> Self {
13-
Self {
14-
r: CompressedEdwardsY::default(),
15-
s: [0u8; 57],
16-
}
17-
}
18-
}
19-
20-
#[cfg(feature = "alloc")]
21-
impl TryFrom<Vec<u8>> for Signature {
22-
type Error = SigningError;
23-
24-
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
25-
Self::try_from(value.as_slice())
26-
}
27-
}
28-
29-
#[cfg(feature = "alloc")]
30-
impl TryFrom<&Vec<u8>> for Signature {
31-
type Error = SigningError;
32-
33-
fn try_from(value: &Vec<u8>) -> Result<Self, Self::Error> {
34-
Self::try_from(value.as_slice())
35-
}
36-
}
37-
38-
impl TryFrom<&[u8]> for Signature {
39-
type Error = SigningError;
40-
41-
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
42-
if value.len() != SIGNATURE_LENGTH {
43-
return Err(SigningError::InvalidSignatureLength);
44-
}
45-
46-
let mut bytes = [0u8; SIGNATURE_LENGTH];
47-
bytes.copy_from_slice(value);
48-
Self::from_bytes(&bytes)
49-
}
50-
}
51-
52-
#[cfg(feature = "alloc")]
53-
impl TryFrom<Box<[u8]>> for Signature {
54-
type Error = SigningError;
55-
56-
fn try_from(value: Box<[u8]>) -> Result<Self, Self::Error> {
57-
Self::try_from(value.as_ref())
58-
}
59-
}
60-
61-
#[cfg(feature = "serde")]
62-
impl serdect::serde::Serialize for Signature {
63-
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
64-
where
65-
S: serdect::serde::Serializer,
66-
{
67-
serdect::array::serialize_hex_lower_or_bin(&self.to_bytes(), s)
68-
}
69-
}
70-
71-
#[cfg(feature = "serde")]
72-
impl<'de> serdect::serde::Deserialize<'de> for Signature {
73-
fn deserialize<D>(d: D) -> Result<Self, D::Error>
74-
where
75-
D: serdect::serde::Deserializer<'de>,
76-
{
77-
let mut bytes = [0u8; SIGNATURE_LENGTH];
78-
serdect::array::deserialize_hex_or_bin(&mut bytes, d)?;
79-
Signature::from_bytes(&bytes).map_err(serdect::serde::de::Error::custom)
80-
}
81-
}
82-
83-
impl Signature {
84-
/// Converts [`Signature`] to a byte array.
85-
pub fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] {
86-
let mut bytes = [0u8; SIGNATURE_LENGTH];
87-
bytes[..57].copy_from_slice(self.r.as_bytes());
88-
bytes[57..].copy_from_slice(&self.s);
89-
bytes
90-
}
91-
92-
/// Converts a byte array to a [`Signature`].
93-
pub fn from_bytes(bytes: &[u8; SIGNATURE_LENGTH]) -> Result<Self, SigningError> {
94-
let mut r = [0u8; SECRET_KEY_LENGTH];
95-
r.copy_from_slice(&bytes[..SECRET_KEY_LENGTH]);
96-
let mut s = [0u8; SECRET_KEY_LENGTH];
97-
s.copy_from_slice(&bytes[SECRET_KEY_LENGTH..]);
98-
99-
let r = CompressedEdwardsY(r);
100-
101-
let big_r = r.decompress();
102-
if big_r.is_none().into() {
103-
return Err(SigningError::InvalidSignatureRComponent);
104-
}
105-
106-
let big_r = big_r.expect("big_r is not none");
107-
if big_r.is_identity().into() {
108-
return Err(SigningError::InvalidSignatureRComponent);
109-
}
110-
111-
if s[56] != 0x00 {
112-
return Err(SigningError::InvalidSignatureSComponent);
113-
}
114-
let s_bytes = ScalarBytes::from(s);
115-
let ss = Scalar::from_canonical_bytes(&s_bytes);
116-
117-
if ss.is_none().into() {
118-
return Err(SigningError::InvalidSignatureSComponent);
119-
}
120-
let sc = ss.expect("ss is not none");
121-
if sc.is_zero().into() {
122-
return Err(SigningError::InvalidSignatureSComponent);
123-
}
124-
125-
Ok(Self { r, s })
126-
}
127-
128-
/// The `r` value of the signature.
129-
pub fn r(&self) -> CompressedEdwardsY {
130-
self.r
131-
}
132-
133-
/// The `s` value of the signature.
134-
pub fn s(&self) -> &[u8; SECRET_KEY_LENGTH] {
135-
&self.s
136-
}
137-
}
4+
pub use ed448::Signature;
1385

1396
impl From<InnerSignature> for Signature {
1407
fn from(inner: InnerSignature) -> Self {
1418
let mut s = [0u8; SECRET_KEY_LENGTH];
1429
s.copy_from_slice(&inner.s.to_bytes_rfc_8032());
143-
Self {
144-
r: inner.r.compress(),
145-
s,
146-
}
10+
Self::from_components(inner.r.compress(), s)
14711
}
14812
}
14913

150-
impl TryFrom<Signature> for InnerSignature {
14+
impl TryFrom<&Signature> for InnerSignature {
15115
type Error = SigningError;
15216

153-
fn try_from(signature: Signature) -> Result<Self, Self::Error> {
154-
let s_bytes = ScalarBytes::try_from(&signature.s[..]).expect("invalid length");
155-
let s = Option::from(Scalar::from_canonical_bytes(&s_bytes))
17+
fn try_from(signature: &Signature) -> Result<Self, Self::Error> {
18+
let s_bytes: &Array<u8, _> = (signature.s_bytes()).into();
19+
let s = Option::from(Scalar::from_canonical_bytes(s_bytes))
15620
.ok_or(SigningError::InvalidSignatureSComponent)?;
157-
let r = Option::from(signature.r.decompress())
21+
let r = Option::from(CompressedEdwardsY::from(*signature.r_bytes()).decompress())
15822
.ok_or(SigningError::InvalidSignatureRComponent)?;
15923
Ok(Self { r, s })
16024
}
@@ -165,21 +29,10 @@ pub(crate) struct InnerSignature {
16529
pub(crate) s: Scalar,
16630
}
16731

168-
#[cfg(feature = "serde")]
169-
#[test]
170-
fn serialization() {
171-
use rand_chacha::ChaCha8Rng;
172-
use rand_core::SeedableRng;
173-
174-
let mut rng = ChaCha8Rng::from_seed([0u8; 32]);
175-
let signing_key = super::SigningKey::generate(&mut rng);
176-
let signature = signing_key.sign_raw(b"Hello, World!");
177-
178-
let bytes = serde_bare::to_vec(&signature).unwrap();
179-
let signature2: Signature = serde_bare::from_slice(&bytes).unwrap();
180-
assert_eq!(signature, signature2);
32+
impl TryFrom<Signature> for InnerSignature {
33+
type Error = SigningError;
18134

182-
let string = serde_json::to_string(&signature).unwrap();
183-
let signature3: Signature = serde_json::from_str(&string).unwrap();
184-
assert_eq!(signature, signature3);
35+
fn try_from(signature: Signature) -> Result<Self, Self::Error> {
36+
Self::try_from(&signature)
37+
}
18538
}

0 commit comments

Comments
 (0)