Skip to content

Commit f01db66

Browse files
authored
Merge pull request #2 from penumbra-zone/ed25519-consensus
Use ed25519-consensus instead of ed25519-dalek
2 parents f739e86 + 0cf605d commit f01db66

23 files changed

+117
-107
lines changed

config/src/node_key.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl NodeKey {
3636
pub fn public_key(&self) -> PublicKey {
3737
#[allow(unreachable_patterns)]
3838
match &self.priv_key {
39-
PrivateKey::Ed25519(keypair) => keypair.public.into(),
39+
PrivateKey::Ed25519(signing_key) => PublicKey::Ed25519(signing_key.verification_key()),
4040
_ => unreachable!(),
4141
}
4242
}

p2p/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ amino = ["prost-derive"]
2828

2929
[dependencies]
3030
chacha20poly1305 = { version = "0.8", default-features = false, features = ["reduced-round"] }
31-
ed25519-dalek = { version = "1", default-features = false }
31+
ed25519-consensus = { version = "1.2", default-features = false }
3232
eyre = { version = "0.6", default-features = false }
3333
flume = { version = "0.10.7", default-features = false }
3434
hkdf = { version = "0.10.0", default-features = false }
@@ -37,7 +37,7 @@ prost = { version = "0.9", default-features = false }
3737
rand_core = { version = "0.5", default-features = false, features = ["std"] }
3838
sha2 = { version = "0.9", default-features = false }
3939
subtle = { version = "2", default-features = false }
40-
x25519-dalek = { version = "1.1", default-features = false }
40+
x25519-dalek = { version = "1.1", default-features = false, features = ["u64_backend"] }
4141
zeroize = { version = "1", default-features = false }
4242
signature = { version = "1.3.0", default-features = false }
4343
aead = { version = "0.4.1", default-features = false }

p2p/src/error.rs

-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use flex_error::{define_error, DisplayOnly};
44
use prost::DecodeError;
5-
use signature::Error as SignatureError;
65

76
define_error! {
87
Error {
@@ -36,7 +35,6 @@ define_error! {
3635
| _ | { "public key missing" },
3736

3837
Signature
39-
[ DisplayOnly<SignatureError> ]
4038
| _ | { "signature error" },
4139

4240
UnsupportedKey

p2p/src/secret_connection.rs

+16-24
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use chacha20poly1305::{
1313
aead::{generic_array::GenericArray, AeadInPlace, NewAead},
1414
ChaCha20Poly1305,
1515
};
16-
use ed25519_dalek::{self as ed25519, Signer, Verifier};
1716
use merlin::Transcript;
1817
use rand_core::OsRng;
1918
use subtle::ConstantTimeEq;
@@ -58,7 +57,7 @@ pub struct Handshake<S> {
5857
5958
/// `AwaitingEphKey` means we're waiting for the remote ephemeral pubkey.
6059
pub struct AwaitingEphKey {
61-
local_privkey: ed25519::Keypair,
60+
local_privkey: ed25519_consensus::SigningKey,
6261
local_eph_privkey: Option<EphemeralSecret>,
6362
}
6463

@@ -68,15 +67,15 @@ pub struct AwaitingAuthSig {
6867
kdf: Kdf,
6968
recv_cipher: ChaCha20Poly1305,
7069
send_cipher: ChaCha20Poly1305,
71-
local_signature: ed25519::Signature,
70+
local_signature: ed25519_consensus::Signature,
7271
}
7372

7473
#[allow(clippy::use_self)]
7574
impl Handshake<AwaitingEphKey> {
7675
/// Initiate a handshake.
7776
#[must_use]
7877
pub fn new(
79-
local_privkey: ed25519::Keypair,
78+
local_privkey: ed25519_consensus::SigningKey,
8079
protocol_version: Version,
8180
) -> (Self, EphemeralPublic) {
8281
// Generate an ephemeral key for perfect forward secrecy.
@@ -148,9 +147,9 @@ impl Handshake<AwaitingEphKey> {
148147

149148
// Sign the challenge bytes for authentication.
150149
let local_signature = if self.protocol_version.has_transcript() {
151-
sign_challenge(&sc_mac, &self.state.local_privkey)?
150+
self.state.local_privkey.sign(&sc_mac)
152151
} else {
153-
sign_challenge(&kdf.challenge, &self.state.local_privkey)?
152+
self.state.local_privkey.sign(&kdf.challenge)
154153
};
155154

156155
Ok(Handshake {
@@ -183,22 +182,23 @@ impl Handshake<AwaitingAuthSig> {
183182

184183
let remote_pubkey = match pk_sum {
185184
proto::crypto::public_key::Sum::Ed25519(ref bytes) => {
186-
ed25519::PublicKey::from_bytes(bytes).map_err(Error::signature)
185+
ed25519_consensus::VerificationKey::try_from(&bytes[..])
186+
.map_err(|_| Error::signature())
187187
}
188188
_ => Err(Error::unsupported_key()),
189189
}?;
190190

191-
let remote_sig =
192-
ed25519::Signature::try_from(auth_sig_msg.sig.as_slice()).map_err(Error::signature)?;
191+
let remote_sig = ed25519_consensus::Signature::try_from(auth_sig_msg.sig.as_slice())
192+
.map_err(|_| Error::signature())?;
193193

194194
if self.protocol_version.has_transcript() {
195195
remote_pubkey
196-
.verify(&self.state.sc_mac, &remote_sig)
197-
.map_err(Error::signature)?;
196+
.verify(&remote_sig, &self.state.sc_mac)
197+
.map_err(|_| Error::signature())?;
198198
} else {
199199
remote_pubkey
200-
.verify(&self.state.kdf.challenge, &remote_sig)
201-
.map_err(Error::signature)?;
200+
.verify(&remote_sig, &self.state.kdf.challenge)
201+
.map_err(|_| Error::signature())?;
202202
}
203203

204204
// We've authorized.
@@ -276,7 +276,7 @@ impl<IoHandler: Read + Write + Send + Sync> SecretConnection<IoHandler> {
276276
/// * if receiving the signature fails
277277
pub fn new(
278278
mut io_handler: IoHandler,
279-
local_privkey: ed25519::Keypair,
279+
local_privkey: ed25519_consensus::SigningKey,
280280
protocol_version: Version,
281281
) -> Result<Self, Error> {
282282
// Start a handshake process.
@@ -467,20 +467,12 @@ fn share_eph_pubkey<IoHandler: Read + Write + Send + Sync>(
467467
protocol_version.decode_initial_handshake(&buf)
468468
}
469469

470-
/// Sign the challenge with the local private key
471-
fn sign_challenge(
472-
challenge: &[u8; 32],
473-
local_privkey: &dyn Signer<ed25519::Signature>,
474-
) -> Result<ed25519::Signature, Error> {
475-
local_privkey.try_sign(challenge).map_err(Error::signature)
476-
}
477-
478470
// TODO(ismail): change from DecodeError to something more generic
479471
// this can also fail while writing / sending
480472
fn share_auth_signature<IoHandler: Read + Write + Send + Sync>(
481473
sc: &mut SecretConnection<IoHandler>,
482-
pubkey: &ed25519::PublicKey,
483-
local_signature: &ed25519::Signature,
474+
pubkey: &ed25519_consensus::VerificationKey,
475+
local_signature: &ed25519_consensus::Signature,
484476
) -> Result<proto::p2p::AuthSigMessage, Error> {
485477
let buf = sc
486478
.protocol_version

p2p/src/secret_connection/amino_types.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use crate::error::Error;
44
use core::convert::TryFrom;
5-
use ed25519_dalek as ed25519;
65
use prost_derive::Message;
76
use tendermint_proto as proto;
87

@@ -22,13 +21,16 @@ pub struct AuthSigMessage {
2221
}
2322

2423
impl AuthSigMessage {
25-
pub fn new(pub_key: &ed25519::PublicKey, sig: &ed25519::Signature) -> Self {
24+
pub fn new(
25+
pub_key: &ed25519_consensus::VerificationKey,
26+
sig: &ed25519_consensus::Signature,
27+
) -> Self {
2628
let mut pub_key_bytes = Vec::from(PUB_KEY_ED25519_AMINO_PREFIX);
27-
pub_key_bytes.extend_from_slice(pub_key.as_ref());
29+
pub_key_bytes.extend_from_slice(pub_key.as_bytes());
2830

2931
Self {
3032
pub_key: pub_key_bytes,
31-
sig: sig.as_ref().to_vec(),
33+
sig: sig.to_bytes().to_vec(),
3234
}
3335
}
3436
}

p2p/src/secret_connection/protocol.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use std::convert::TryInto;
44

5-
use ed25519_dalek as ed25519;
65
use prost::Message as _;
76

87
use x25519_dalek::PublicKey as EphemeralPublic;
@@ -113,8 +112,8 @@ impl Version {
113112
#[must_use]
114113
pub fn encode_auth_signature(
115114
self,
116-
pub_key: &ed25519::PublicKey,
117-
signature: &ed25519::Signature,
115+
pub_key: &ed25519_consensus::VerificationKey,
116+
signature: &ed25519_consensus::Signature,
118117
) -> Vec<u8> {
119118
if self.is_protobuf() {
120119
// Protobuf `AuthSigMessage`
@@ -126,7 +125,7 @@ impl Version {
126125

127126
let msg = proto::p2p::AuthSigMessage {
128127
pub_key: Some(pub_key),
129-
sig: signature.as_ref().to_vec(),
128+
sig: signature.to_bytes().to_vec(),
130129
};
131130

132131
let mut buf = Vec::new();
@@ -168,8 +167,8 @@ impl Version {
168167
#[cfg(feature = "amino")]
169168
fn encode_auth_signature_amino(
170169
self,
171-
pub_key: &ed25519::PublicKey,
172-
signature: &ed25519::Signature,
170+
pub_key: &ed25519_consensus::VerificationKey,
171+
signature: &ed25519_consensus::Signature,
173172
) -> Vec<u8> {
174173
// Legacy Amino encoded `AuthSigMessage`
175174
let msg = amino_types::AuthSigMessage::new(pub_key, signature);
@@ -184,8 +183,8 @@ impl Version {
184183
#[cfg(not(feature = "amino"))]
185184
fn encode_auth_signature_amino(
186185
self,
187-
_: &ed25519::PublicKey,
188-
_: &ed25519::Signature,
186+
_: &ed25519_consensus::VerificationKey,
187+
_: &ed25519_consensus::Signature,
189188
) -> Vec<u8> {
190189
panic!("attempted to encode auth signature using amino, but 'amino' feature is not present")
191190
}

p2p/src/secret_connection/public_key.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
//! Secret Connection peer public keys
22
3-
use ed25519_dalek as ed25519;
43
use sha2::{digest::Digest, Sha256};
5-
use std::fmt::{self, Display};
4+
use std::{
5+
convert::TryFrom,
6+
fmt::{self, Display},
7+
};
68
use tendermint::{error::Error, node};
79

810
/// Secret Connection peer public keys (signing, presently Ed25519-only)
911
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1012
pub enum PublicKey {
1113
/// Ed25519 Secret Connection Keys
12-
Ed25519(ed25519::PublicKey),
14+
Ed25519(ed25519_consensus::VerificationKey),
1315
}
1416

1517
impl PublicKey {
@@ -19,14 +21,14 @@ impl PublicKey {
1921
///
2022
/// * if the bytes given are invalid
2123
pub fn from_raw_ed25519(bytes: &[u8]) -> Result<Self, Error> {
22-
ed25519::PublicKey::from_bytes(bytes)
24+
ed25519_consensus::VerificationKey::try_from(bytes)
2325
.map(Self::Ed25519)
24-
.map_err(Error::signature)
26+
.map_err(|_| Error::signature())
2527
}
2628

2729
/// Get Ed25519 public key
2830
#[must_use]
29-
pub const fn ed25519(self) -> Option<ed25519::PublicKey> {
31+
pub const fn ed25519(self) -> Option<ed25519_consensus::VerificationKey> {
3032
match self {
3133
Self::Ed25519(pk) => Some(pk),
3234
}
@@ -53,14 +55,14 @@ impl Display for PublicKey {
5355
}
5456
}
5557

56-
impl From<&ed25519::Keypair> for PublicKey {
57-
fn from(sk: &ed25519::Keypair) -> Self {
58-
Self::Ed25519(sk.public)
58+
impl From<&ed25519_consensus::SigningKey> for PublicKey {
59+
fn from(sk: &ed25519_consensus::SigningKey) -> Self {
60+
Self::Ed25519(sk.verification_key())
5961
}
6062
}
6163

62-
impl From<ed25519::PublicKey> for PublicKey {
63-
fn from(pk: ed25519::PublicKey) -> Self {
64+
impl From<ed25519_consensus::VerificationKey> for PublicKey {
65+
fn from(pk: ed25519_consensus::VerificationKey) -> Self {
6466
Self::Ed25519(pk)
6567
}
6668
}

pbt-gen/src/time.rs

-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ pub const MAX_NANO_SECS: u32 = 999_999_999u32;
2121
/// let timestamp = pbt_gen::time::min_time().unix_timestamp_nanos();
2222
/// assert!(OffsetDateTime::from_unix_timestamp_nanos(timestamp).is_ok());
2323
/// assert!(OffsetDateTime::from_unix_timestamp_nanos(timestamp - 1).is_err());
24-
///
2524
/// ```
2625
pub fn min_time() -> OffsetDateTime {
2726
Date::MIN.midnight().assume_utc()
@@ -49,7 +48,6 @@ pub fn max_time() -> OffsetDateTime {
4948
/// Google's well-known [`Timestamp`] protobuf message format.
5049
///
5150
/// [`Timestamp`]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp
52-
///
5351
pub const fn min_protobuf_time() -> OffsetDateTime {
5452
datetime!(0001-01-01 00:00:00 UTC)
5553
}
@@ -58,7 +56,6 @@ pub const fn min_protobuf_time() -> OffsetDateTime {
5856
/// Google's well-known [`Timestamp`] protobuf message format.
5957
///
6058
/// [`Timestamp`]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp
61-
///
6259
pub const fn max_protobuf_time() -> OffsetDateTime {
6360
datetime!(9999-12-31 23:59:59.999999999 UTC)
6461
}
@@ -248,7 +245,6 @@ prop_compose! {
248245
/// Google's well-known [`Timestamp`] protobuf message format.
249246
///
250247
/// [`Timestamp`]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp
251-
///
252248
pub fn arb_protobuf_safe_rfc3339_timestamp() -> impl Strategy<Value = String> {
253249
arb_rfc3339_timestamp().prop_filter("timestamp out of protobuf range", |ts| {
254250
let t = OffsetDateTime::parse(ts, &Rfc3339).unwrap();

proto/src/serializers/timestamp.rs

-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ pub fn to_rfc3339_nanos(t: OffsetDateTime) -> String {
9090
///
9191
/// [`Display`]: core::fmt::Display
9292
/// [`Debug`]: core::fmt::Debug
93-
///
9493
pub fn fmt_as_rfc3339_nanos(t: OffsetDateTime, f: &mut impl fmt::Write) -> fmt::Result {
9594
let t = t.to_offset(offset!(UTC));
9695
let nanos = t.nanosecond();

tendermint/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ crate-type = ["cdylib", "rlib"]
3636
async-trait = { version = "0.1", default-features = false }
3737
bytes = { version = "1.0", default-features = false, features = ["serde"] }
3838
ed25519 = { version = "1.3", default-features = false }
39-
ed25519-dalek = { version = "1", default-features = false, features = ["u64_backend"] }
39+
ed25519-consensus = { version = "1.2", default-features = false }
4040
futures = { version = "0.3", default-features = false }
4141
num-traits = { version = "0.2", default-features = false }
4242
once_cell = { version = "1.3", default-features = false }

tendermint/src/account.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ mod tests {
162162
let id_bytes = Id::from_str(id_hex).expect("expected id_hex to decode properly");
163163

164164
// get id for pubkey
165-
let pubkey = Ed25519::from_bytes(pubkey_bytes).unwrap();
165+
let pubkey = Ed25519::try_from(&pubkey_bytes[..]).unwrap();
166166
let id = Id::from(pubkey);
167167

168168
assert_eq!(id_bytes.ct_eq(&id).unwrap_u8(), 1);

tendermint/src/error.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,7 @@ define_error! {
208208
|_| { format_args!("subtle encoding error") },
209209

210210
Signature
211-
[ DisplayOnly<signature::Error> ]
212-
|_| { format_args!("signature error") },
211+
|_| { "signature error" },
213212

214213
TrustThresholdTooLarge
215214
|_| { "trust threshold is too large (must be <= 1)" },

0 commit comments

Comments
 (0)