feat(fluence-keypair): bump ed25519-dalek to 0.2.0 (#127)

This commit is contained in:
Aleksey Proshutisnkiy 2023-10-10 15:01:07 +02:00 committed by GitHub
parent 2f336f73cf
commit ed5bd2c0ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 64 deletions

View File

@ -33,11 +33,8 @@ jobs:
command: clippy command: clippy
args: -Z unstable-options --all args: -Z unstable-options --all
- name: Install cargo-nextest - name: Setup nextest
uses: baptiste0928/cargo-install@v1.3.0 uses: taiki-e/install-action@nextest
with:
crate: cargo-nextest
version: 0.9.22
- name: Run cargo nextest - name: Run cargo nextest
env: env:

132
Cargo.lock generated
View File

@ -159,6 +159,12 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64ct"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]] [[package]]
name = "bincode" name = "bincode"
version = "1.3.3" version = "1.3.3"
@ -378,6 +384,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "const-oid"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
[[package]] [[package]]
name = "constant_time_eq" name = "constant_time_eq"
version = "0.2.5" version = "0.2.5"
@ -607,6 +619,34 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "curve25519-dalek"
version = "4.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c"
dependencies = [
"cfg-if",
"cpufeatures",
"curve25519-dalek-derive",
"digest 0.10.7",
"fiat-crypto",
"platforms",
"rustc_version",
"subtle",
"zeroize",
]
[[package]]
name = "curve25519-dalek-derive"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.18",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.14.4" version = "0.14.4"
@ -677,6 +717,16 @@ dependencies = [
"syn 2.0.18", "syn 2.0.18",
] ]
[[package]]
name = "der"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
dependencies = [
"const-oid",
"zeroize",
]
[[package]] [[package]]
name = "derivative" name = "derivative"
version = "2.2.0" version = "2.2.0"
@ -754,8 +804,18 @@ version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7"
dependencies = [ dependencies = [
"signature 1.6.4",
]
[[package]]
name = "ed25519"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d"
dependencies = [
"pkcs8",
"serde", "serde",
"signature", "signature 2.1.0",
] ]
[[package]] [[package]]
@ -764,15 +824,28 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
dependencies = [ dependencies = [
"curve25519-dalek", "curve25519-dalek 3.2.0",
"ed25519", "ed25519 1.5.3",
"rand 0.7.3", "rand 0.7.3",
"serde", "serde",
"serde_bytes",
"sha2 0.9.9", "sha2 0.9.9",
"zeroize", "zeroize",
] ]
[[package]]
name = "ed25519-dalek"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980"
dependencies = [
"curve25519-dalek 4.1.1",
"ed25519 2.2.2",
"rand_core 0.6.4",
"serde",
"sha2 0.10.7",
"zeroize",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.8.1" version = "1.8.1"
@ -884,6 +957,12 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "fiat-crypto"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d"
[[package]] [[package]]
name = "file-per-thread-logger" name = "file-per-thread-logger"
version = "0.1.6" version = "0.1.6"
@ -931,7 +1010,7 @@ version = "0.10.3"
dependencies = [ dependencies = [
"asn1_der 0.6.3", "asn1_der 0.6.3",
"bs58 0.5.0", "bs58 0.5.0",
"ed25519-dalek", "ed25519-dalek 2.0.0",
"eyre", "eyre",
"lazy_static", "lazy_static",
"libp2p-identity", "libp2p-identity",
@ -1378,7 +1457,7 @@ checksum = "d2874d9c6575f1d7a151022af5c42bb0ffdcdfbafe0a6fd039de870b384835a2"
dependencies = [ dependencies = [
"asn1_der 0.7.6", "asn1_der 0.7.6",
"bs58 0.5.0", "bs58 0.5.0",
"ed25519-dalek", "ed25519-dalek 1.0.1",
"libsecp256k1", "libsecp256k1",
"log", "log",
"multihash 0.19.0", "multihash 0.19.0",
@ -2009,12 +2088,28 @@ version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"spki",
]
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.27" version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "platforms"
version = "3.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8"
[[package]] [[package]]
name = "polyplets" name = "polyplets"
version = "0.3.2" version = "0.3.2"
@ -2332,6 +2427,15 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.36.14" version = "0.36.14"
@ -2515,6 +2619,12 @@ version = "1.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
[[package]]
name = "signature"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500"
[[package]] [[package]]
name = "slice-group-by" name = "slice-group-by"
version = "0.3.1" version = "0.3.1"
@ -2533,6 +2643,16 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spki"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a"
dependencies = [
"base64ct",
"der",
]
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.2.0" version = "1.2.0"

View File

@ -10,7 +10,7 @@ repository = "https://github.com/fluencelabs/trust-graph"
[dependencies] [dependencies]
serde = { version = "1.0.118", features = ["derive"] } serde = { version = "1.0.118", features = ["derive"] }
bs58 = "0.5.0" bs58 = "0.5.0"
ed25519-dalek = { version = "1.0.1", features = ["serde", "std"] } ed25519-dalek = { version = "2.0.0", features = ["serde", "std", "rand_core"] }
rand = "0.8.5" rand = "0.8.5"
thiserror = "1.0.23" thiserror = "1.0.23"
lazy_static = "1.4" lazy_static = "1.4"

View File

@ -19,16 +19,16 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
//! Ed25519 keys. //! Ed25519 keys.
use crate::error::{DecodingError, SigningError, VerificationError}; use crate::error::{DecodingError, DecodingError::InvalidLength, SigningError, VerificationError};
use core::fmt; use core::fmt;
use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _}; use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _};
use rand::RngCore;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::convert::TryFrom; use std::convert::TryFrom;
use zeroize::Zeroize; use zeroize::Zeroize;
/// An Ed25519 keypair. /// An Ed25519 keypair
pub struct Keypair(ed25519::Keypair); #[derive(Clone)]
pub struct Keypair(ed25519::SigningKey);
impl Keypair { impl Keypair {
/// Generate a new Ed25519 keypair. /// Generate a new Ed25519 keypair.
@ -40,13 +40,15 @@ impl Keypair {
/// of the secret scalar and the compressed public point, /// of the secret scalar and the compressed public point,
/// an informal standard for encoding Ed25519 keypairs. /// an informal standard for encoding Ed25519 keypairs.
pub fn encode(&self) -> [u8; 64] { pub fn encode(&self) -> [u8; 64] {
self.0.to_bytes() self.0.to_keypair_bytes()
} }
/// Decode a keypair from the format produced by `encode`, /// Decode a keypair from the format produced by `encode`,
/// zeroing the input on success. /// zeroing the input on success.
pub fn decode(kp: &mut [u8]) -> Result<Self, DecodingError> { pub fn decode(kp: &mut [u8]) -> Result<Self, DecodingError> {
ed25519::Keypair::from_bytes(kp) let bytes = <[u8; 64]>::try_from(&*kp).map_err(InvalidLength)?;
ed25519::SigningKey::from_keypair_bytes(&bytes)
.map(|k| { .map(|k| {
kp.zeroize(); kp.zeroize();
Keypair(k) Keypair(k)
@ -61,12 +63,12 @@ impl Keypair {
/// Get the public key of this keypair. /// Get the public key of this keypair.
pub fn public(&self) -> PublicKey { pub fn public(&self) -> PublicKey {
PublicKey(self.0.public) PublicKey(self.0.verifying_key())
} }
/// Get the secret key of this keypair. /// Get the secret key of this keypair.
pub fn secret(&self) -> SecretKey { pub fn secret(&self) -> SecretKey {
SecretKey::from_bytes(&mut self.0.secret.to_bytes()) SecretKey::from_bytes(&mut self.0.to_bytes())
.expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k") .expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k")
} }
} }
@ -74,26 +76,14 @@ impl Keypair {
impl fmt::Debug for Keypair { impl fmt::Debug for Keypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Keypair") f.debug_struct("Keypair")
.field("public", &self.0.public) .field("public", &self.0.verifying_key())
.finish() .finish()
} }
} }
impl Clone for Keypair {
fn clone(&self) -> Self {
let mut sk_bytes = self.0.secret.to_bytes();
let secret = SecretKey::from_bytes(&mut sk_bytes)
.expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k")
.0;
let public = ed25519::PublicKey::from_bytes(&self.0.public.to_bytes())
.expect("ed25519::PublicKey::from_bytes(to_bytes(k)) != k");
Keypair(ed25519::Keypair { secret, public })
}
}
/// Build keypair from existing ed25519 keypair /// Build keypair from existing ed25519 keypair
impl From<ed25519::Keypair> for Keypair { impl From<ed25519::SigningKey> for Keypair {
fn from(kp: ed25519::Keypair) -> Self { fn from(kp: ed25519::SigningKey) -> Self {
Keypair(kp) Keypair(kp)
} }
} }
@ -101,25 +91,21 @@ impl From<ed25519::Keypair> for Keypair {
/// Demote an Ed25519 keypair to a secret key. /// Demote an Ed25519 keypair to a secret key.
impl From<Keypair> for SecretKey { impl From<Keypair> for SecretKey {
fn from(kp: Keypair) -> Self { fn from(kp: Keypair) -> Self {
SecretKey(kp.0.secret) SecretKey(kp.0.to_bytes())
} }
} }
/// Promote an Ed25519 secret key into a keypair. /// Promote an Ed25519 secret key into a keypair.
impl From<SecretKey> for Keypair { impl From<SecretKey> for Keypair {
fn from(sk: SecretKey) -> Self { fn from(sk: SecretKey) -> Self {
let secret: ed25519::ExpandedSecretKey = (&sk.0).into(); let signing = ed25519::SigningKey::from_bytes(&sk.0);
let public = ed25519::PublicKey::from(&secret); Keypair(signing)
Keypair(ed25519::Keypair {
secret: sk.0,
public,
})
} }
} }
/// An Ed25519 public key. /// An Ed25519 public key.
#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)] #[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)]
pub struct PublicKey(ed25519::PublicKey); pub struct PublicKey(ed25519::VerifyingKey);
impl PublicKey { impl PublicKey {
/// Verify the Ed25519 signature on a message using the public key. /// Verify the Ed25519 signature on a message using the public key.
@ -143,26 +129,21 @@ impl PublicKey {
/// Decode a public key from a byte array as produced by `encode`. /// Decode a public key from a byte array as produced by `encode`.
pub fn decode(bytes: &[u8]) -> Result<Self, DecodingError> { pub fn decode(bytes: &[u8]) -> Result<Self, DecodingError> {
ed25519::PublicKey::from_bytes(bytes) let bytes = <[u8; 32]>::try_from(bytes).map_err(InvalidLength)?;
ed25519::VerifyingKey::from_bytes(&bytes)
.map_err(DecodingError::Ed25519) .map_err(DecodingError::Ed25519)
.map(PublicKey) .map(PublicKey)
} }
} }
/// An Ed25519 secret key. /// An Ed25519 secret key.
#[derive(Clone)]
pub struct SecretKey(pub ed25519::SecretKey); pub struct SecretKey(pub ed25519::SecretKey);
/// View the bytes of the secret key. /// View the bytes of the secret key.
impl AsRef<[u8]> for SecretKey { impl AsRef<[u8]> for SecretKey {
fn as_ref(&self) -> &[u8] { fn as_ref(&self) -> &[u8] {
self.0.as_bytes() &self.0[..]
}
}
impl Clone for SecretKey {
fn clone(&self) -> Self {
let mut sk_bytes = self.0.to_bytes();
Self::from_bytes(&mut sk_bytes).expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k")
} }
} }
@ -175,13 +156,8 @@ impl fmt::Debug for SecretKey {
impl SecretKey { impl SecretKey {
/// Generate a new Ed25519 secret key. /// Generate a new Ed25519 secret key.
pub fn generate() -> Self { pub fn generate() -> Self {
let mut bytes = [0u8; 32]; let signing = ed25519::SigningKey::generate(&mut rand::rngs::OsRng);
rand::thread_rng().fill_bytes(&mut bytes); SecretKey(signing.to_bytes())
SecretKey(
ed25519::SecretKey::from_bytes(&bytes).expect(
"this returns `Err` only if the length is wrong; the length is correct; qed",
),
)
} }
/// Create an Ed25519 secret key from a byte slice, zeroing the input on success. /// Create an Ed25519 secret key from a byte slice, zeroing the input on success.
@ -189,7 +165,7 @@ impl SecretKey {
/// returned. /// returned.
pub fn from_bytes(mut sk_bytes: impl AsMut<[u8]>) -> Result<Self, DecodingError> { pub fn from_bytes(mut sk_bytes: impl AsMut<[u8]>) -> Result<Self, DecodingError> {
let sk_bytes = sk_bytes.as_mut(); let sk_bytes = sk_bytes.as_mut();
let secret = ed25519::SecretKey::from_bytes(&*sk_bytes).map_err(DecodingError::Ed25519)?; let secret = <[u8; 32]>::try_from(&*sk_bytes).map_err(InvalidLength)?;
sk_bytes.zeroize(); sk_bytes.zeroize();
Ok(SecretKey(secret)) Ok(SecretKey(secret))
} }
@ -205,7 +181,7 @@ mod tests {
use quickcheck::*; use quickcheck::*;
fn eq_keypairs(kp1: &Keypair, kp2: &Keypair) -> bool { fn eq_keypairs(kp1: &Keypair, kp2: &Keypair) -> bool {
kp1.public() == kp2.public() && kp1.0.secret.as_bytes() == kp2.0.secret.as_bytes() kp1.public() == kp2.public() && kp1.0.to_bytes() == kp2.0.to_bytes()
} }
#[test] #[test]
@ -234,7 +210,7 @@ mod tests {
fn ed25519_keypair_from_secret() { fn ed25519_keypair_from_secret() {
fn prop() -> bool { fn prop() -> bool {
let kp1 = Keypair::generate(); let kp1 = Keypair::generate();
let mut sk = kp1.0.secret.to_bytes(); let mut sk = kp1.0.to_bytes();
let kp2 = Keypair::from(SecretKey::from_bytes(&mut sk).unwrap()); let kp2 = Keypair::from(SecretKey::from_bytes(&mut sk).unwrap());
eq_keypairs(&kp1, &kp2) && sk == [0u8; 32] eq_keypairs(&kp1, &kp2) && sk == [0u8; 32]
} }

View File

@ -31,6 +31,8 @@ pub enum Error {
/// An error during decoding of key material. /// An error during decoding of key material.
#[derive(ThisError, Debug)] #[derive(ThisError, Debug)]
pub enum DecodingError { pub enum DecodingError {
#[error("Failed to decode, invalid length: {0}")]
InvalidLength(#[from] std::array::TryFromSliceError),
#[error("Failed to decode with ed25519: {0}")] #[error("Failed to decode with ed25519: {0}")]
Ed25519( Ed25519(
#[from] #[from]

View File

@ -195,7 +195,7 @@ impl KeyPair {
pub fn secret(&self) -> eyre::Result<Vec<u8>> { pub fn secret(&self) -> eyre::Result<Vec<u8>> {
use KeyPair::*; use KeyPair::*;
match self { match self {
Ed25519(pair) => Ok(pair.secret().0.to_bytes().to_vec()), Ed25519(pair) => Ok(pair.secret().0.to_vec()),
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
Rsa(_) => Err(eyre::eyre!("secret key is not available for RSA")), Rsa(_) => Err(eyre::eyre!("secret key is not available for RSA")),
Secp256k1(pair) => Ok(pair.secret().to_bytes().to_vec()), Secp256k1(pair) => Ok(pair.secret().to_bytes().to_vec()),
@ -284,7 +284,7 @@ impl From<KeyPair> for libp2p_identity::Keypair {
match key { match key {
KeyPair::Ed25519(kp) => { KeyPair::Ed25519(kp) => {
// for some reason, libp2p takes SecretKey's 32 bytes here instead of Keypair's 64 bytes // for some reason, libp2p takes SecretKey's 32 bytes here instead of Keypair's 64 bytes
let secret_bytes = kp.secret().0.to_bytes(); let secret_bytes = kp.secret().0;
let kp = libp2p_identity::Keypair::ed25519_from_bytes(secret_bytes)?; let kp = libp2p_identity::Keypair::ed25519_from_bytes(secret_bytes)?;
Ok(kp) Ok(kp)
} }