Use ed25519-compact crate instead of ed25519-dalek

ed25519-dalek does not implement Clone and Eq for secret keys, and
relevant PR in its repository wait for merge from long time ago, leading
to potential problems with maintainability
This commit is contained in:
Egor Duda
2022-05-16 21:48:43 +03:00
parent 0ef0bb23f4
commit 55056b721c
3 changed files with 18 additions and 45 deletions

View File

@@ -25,7 +25,7 @@ serde_json = { version = "=1.0.69", default-features = false, features = ["alloc
embedded-time = "0.12.1" embedded-time = "0.12.1"
arbitrary = { version = "0.4.7", features = ["derive"], optional = true } arbitrary = { version = "0.4.7", features = ["derive"], optional = true }
rand = { version = "0.8.4", optional = true } rand = { version = "0.8.4", optional = true }
ed25519-dalek = { version = "1", default-features = false, features = ["u32_backend", "rand"], optional = true } ed25519-compact = { version = "1", default-features = false, optional = true }
[features] [features]
debug_allocations = ["lang_items/debug_allocations"] debug_allocations = ["lang_items/debug_allocations"]
@@ -37,7 +37,7 @@ with_ctap1 = ["crypto/with_ctap1"]
with_nfc = ["libtock_drivers/with_nfc"] with_nfc = ["libtock_drivers/with_nfc"]
vendor_hid = ["libtock_drivers/vendor_hid"] vendor_hid = ["libtock_drivers/vendor_hid"]
fuzz = ["arbitrary", "std"] fuzz = ["arbitrary", "std"]
ed25519 = ["ed25519-dalek"] ed25519 = ["ed25519-compact"]
[dev-dependencies] [dev-dependencies]
enum-iterator = "0.6.0" enum-iterator = "0.6.0"

View File

@@ -14,8 +14,10 @@
use crate::ctap::data_formats::{ use crate::ctap::data_formats::{
extract_array, extract_byte_string, CoseKey, PublicKeyCredentialSource, extract_array, extract_byte_string, CoseKey, PublicKeyCredentialSource,
PublicKeyCredentialType, SignatureAlgorithm, ES256_ALGORITHM, EDDSA_ALGORITHM, PublicKeyCredentialType, SignatureAlgorithm, ES256_ALGORITHM,
}; };
#[cfg(feature="ed25519")]
use crate::ctap::data_formats::EDDSA_ALGORITHM;
use crate::ctap::status_code::Ctap2StatusCode; use crate::ctap::status_code::Ctap2StatusCode;
use crate::ctap::storage; use crate::ctap::storage;
use crate::env::Env; use crate::env::Env;
@@ -30,8 +32,6 @@ use crypto::sha256::Sha256;
use rng256::Rng256; use rng256::Rng256;
use sk_cbor as cbor; use sk_cbor as cbor;
use sk_cbor::{cbor_array, cbor_bytes, cbor_int}; use sk_cbor::{cbor_array, cbor_bytes, cbor_int};
#[cfg(feature = "ed25519")]
use ed25519_dalek::Signer;
// Legacy credential IDs consist of // Legacy credential IDs consist of
// - 16 bytes: initialization vector for AES-256, // - 16 bytes: initialization vector for AES-256,
@@ -101,37 +101,13 @@ pub fn aes256_cbc_decrypt(
} }
/// An asymmetric private key that can sign messages. /// An asymmetric private key that can sign messages.
#[derive(Debug)] #[derive(Clone,Debug,PartialEq,Eq)]
pub enum PrivateKey { pub enum PrivateKey {
Ecdsa(ecdsa::SecKey), Ecdsa(ecdsa::SecKey),
#[cfg(feature = "ed25519")] #[cfg(feature = "ed25519")]
Ed25519(ed25519_dalek::Keypair), Ed25519(ed25519_compact::SecretKey),
} }
impl Clone for PrivateKey {
fn clone(&self) -> Self {
match self {
Self::Ecdsa(sk) => Self::Ecdsa (sk.clone ()),
#[cfg(feature = "ed25519")]
Self::Ed25519(keypair) => Self::Ed25519 (ed25519_dalek::Keypair::from_bytes (&keypair.to_bytes()).unwrap()),
}
}
}
impl PartialEq for PrivateKey {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(&Self::Ecdsa(ref a), &Self::Ecdsa(ref b)) => a == b,
#[cfg(feature = "ed25519")]
(&Self::Ed25519(ref a), &Self::Ed25519(ref b)) => a.to_bytes() == b.to_bytes(),
#[cfg(feature = "ed25519")]
_ => false,
}
}
}
impl Eq for PrivateKey {}
impl PrivateKey { impl PrivateKey {
/// Creates a new private key for the given algorithm. /// Creates a new private key for the given algorithm.
/// ///
@@ -165,12 +141,8 @@ impl PrivateKey {
if bytes.len() != 32 { if bytes.len() != 32 {
return None; return None;
} }
if let Ok(secret) = ed25519_dalek::SecretKey::from_bytes(bytes) { let seed = ed25519_compact::Seed::from_slice(bytes).unwrap();
let public = ed25519_dalek::PublicKey::from (&secret); Some(Self::Ed25519(ed25519_compact::KeyPair::from_seed(seed).sk))
Some(Self::Ed25519(ed25519_dalek::Keypair{secret, public}))
} else {
None
}
} }
/// Returns the corresponding public key. /// Returns the corresponding public key.
@@ -178,7 +150,7 @@ impl PrivateKey {
match self { match self {
PrivateKey::Ecdsa(ecdsa_key) => CoseKey::from(ecdsa_key.genpk()), PrivateKey::Ecdsa(ecdsa_key) => CoseKey::from(ecdsa_key.genpk()),
#[cfg(feature = "ed25519")] #[cfg(feature = "ed25519")]
PrivateKey::Ed25519(ed25519_keypair) => CoseKey::from(ed25519_keypair.public), PrivateKey::Ed25519(ed25519_key) => CoseKey::from(ed25519_key.public_key()),
} }
} }
@@ -187,7 +159,7 @@ impl PrivateKey {
match self { match self {
PrivateKey::Ecdsa(ecdsa_key) => ecdsa_key.sign_rfc6979::<Sha256>(message).to_asn1_der(), PrivateKey::Ecdsa(ecdsa_key) => ecdsa_key.sign_rfc6979::<Sha256>(message).to_asn1_der(),
#[cfg(feature = "ed25519")] #[cfg(feature = "ed25519")]
PrivateKey::Ed25519(ed25519_keypair) => ed25519_keypair.try_sign(message).unwrap().to_bytes().to_vec(), PrivateKey::Ed25519(ed25519_key) => ed25519_key.sign(message,None).to_vec(),
} }
} }
@@ -209,7 +181,7 @@ impl PrivateKey {
key_bytes key_bytes
} }
#[cfg(feature = "ed25519")] #[cfg(feature = "ed25519")]
PrivateKey::Ed25519(ed25519_keypair) => ed25519_keypair.secret.to_bytes().to_vec(), PrivateKey::Ed25519(ed25519_key) => ed25519_key.seed().to_vec(),
} }
} }
} }
@@ -285,8 +257,9 @@ pub fn encrypt_key_handle(
ECDSA_CREDENTIAL_ID_VERSION ECDSA_CREDENTIAL_ID_VERSION
} }
#[cfg(feature = "ed25519")] #[cfg(feature = "ed25519")]
PrivateKey::Ed25519(keypair) => { PrivateKey::Ed25519(ed25519_key) => {
plaintext[0..32].copy_from_slice(&keypair.secret.to_bytes()); let sk_bytes = *ed25519_key.seed();
plaintext[0..32].copy_from_slice(&sk_bytes);
ED25519_CREDENTIAL_ID_VERSION ED25519_CREDENTIAL_ID_VERSION
} }
}; };

View File

@@ -844,10 +844,10 @@ impl From<ecdsa::PubKey> for CoseKey {
} }
#[cfg(feature = "ed25519")] #[cfg(feature = "ed25519")]
impl From<ed25519_dalek::PublicKey> for CoseKey { impl From<ed25519_compact::PublicKey> for CoseKey {
fn from(pk: ed25519_dalek::PublicKey) -> Self { fn from(pk: ed25519_compact::PublicKey) -> Self {
CoseKey { CoseKey {
x_bytes: pk.to_bytes(), x_bytes: *pk,
y_bytes: [0u8; 32], y_bytes: [0u8; 32],
key_type: CoseKey::OKP_KEY_TYPE, key_type: CoseKey::OKP_KEY_TYPE,
curve: CoseKey::ED25519_CURVE, curve: CoseKey::ED25519_CURVE,