mirror of
https://github.com/fluencelabs/trust-graph
synced 2025-04-24 15:22:13 +00:00
feat(keypair)!: keypair ed25519 only
We do not use RSA and Secp256k1, and they limit portability. This pull requests removes their support, keeping, however, the enum-based implementation of many `fluence-keypair` types.
This commit is contained in:
parent
d378fe2509
commit
3f37ed0920
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -105,12 +105,6 @@ dependencies = [
|
||||
"asn1_der_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asn1_der"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247"
|
||||
|
||||
[[package]]
|
||||
name = "asn1_der_derive"
|
||||
version = "0.1.2"
|
||||
@ -929,7 +923,7 @@ dependencies = [
|
||||
name = "fluence-keypair"
|
||||
version = "0.10.3"
|
||||
dependencies = [
|
||||
"asn1_der 0.6.3",
|
||||
"asn1_der",
|
||||
"bs58 0.5.0",
|
||||
"ed25519-dalek",
|
||||
"eyre",
|
||||
@ -1376,15 +1370,12 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2874d9c6575f1d7a151022af5c42bb0ffdcdfbafe0a6fd039de870b384835a2"
|
||||
dependencies = [
|
||||
"asn1_der 0.7.6",
|
||||
"bs58 0.5.0",
|
||||
"ed25519-dalek",
|
||||
"libsecp256k1",
|
||||
"log",
|
||||
"multihash 0.19.0",
|
||||
"quick-protobuf",
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"sha2 0.10.7",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
|
@ -20,7 +20,7 @@ sha2 = "0.10.6"
|
||||
zeroize = "1"
|
||||
serde_bytes = "0.11"
|
||||
eyre = "0.6.5"
|
||||
libp2p-identity = { workspace = true, default-features = false, features = ["peerid", "rsa", "ed25519", "secp256k1"] }
|
||||
libp2p-identity = { workspace = true, default-features = false, features = ["peerid", "ed25519"] }
|
||||
multihash = { version = "0.18.0", features = ["identity"] }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
|
@ -22,9 +22,6 @@
|
||||
use crate::ed25519;
|
||||
use crate::error::{DecodingError, Error, SigningError, VerificationError};
|
||||
use crate::public_key::PublicKey;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::rsa;
|
||||
use crate::secp256k1;
|
||||
use crate::signature::Signature;
|
||||
use libp2p_identity::{KeyType, Keypair, PeerId};
|
||||
use std::convert::TryFrom;
|
||||
@ -50,9 +47,6 @@ use std::str::FromStr;
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum KeyFormat {
|
||||
Ed25519,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa,
|
||||
Secp256k1,
|
||||
}
|
||||
|
||||
impl FromStr for KeyFormat {
|
||||
@ -62,9 +56,6 @@ impl FromStr for KeyFormat {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"ed25519" => Ok(KeyFormat::Ed25519),
|
||||
"secp256k1" => Ok(KeyFormat::Secp256k1),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
"rsa" => Ok(KeyFormat::Rsa),
|
||||
_ => Err(Error::InvalidKeyFormat(s.to_string())),
|
||||
}
|
||||
}
|
||||
@ -76,9 +67,6 @@ impl TryFrom<u8> for KeyFormat {
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(KeyFormat::Ed25519),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
1 => Ok(KeyFormat::Rsa),
|
||||
2 => Ok(KeyFormat::Secp256k1),
|
||||
_ => Err(DecodingError::InvalidTypeByte),
|
||||
}
|
||||
}
|
||||
@ -88,9 +76,6 @@ impl From<KeyFormat> for u8 {
|
||||
fn from(kf: KeyFormat) -> Self {
|
||||
match kf {
|
||||
KeyFormat::Ed25519 => 0,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyFormat::Rsa => 1,
|
||||
KeyFormat::Secp256k1 => 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -99,9 +84,6 @@ impl From<KeyFormat> for String {
|
||||
fn from(kf: KeyFormat) -> Self {
|
||||
match kf {
|
||||
KeyFormat::Ed25519 => "ed25519".to_string(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyFormat::Rsa => "rsa".to_string(),
|
||||
KeyFormat::Secp256k1 => "secp256k1".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -110,20 +92,12 @@ impl From<KeyFormat> for String {
|
||||
pub enum KeyPair {
|
||||
/// An Ed25519 keypair.
|
||||
Ed25519(ed25519::Keypair),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
/// An RSA keypair.
|
||||
Rsa(rsa::Keypair),
|
||||
/// A Secp256k1 keypair.
|
||||
Secp256k1(secp256k1::Keypair),
|
||||
}
|
||||
|
||||
impl KeyPair {
|
||||
pub fn generate(format: KeyFormat) -> KeyPair {
|
||||
match format {
|
||||
KeyFormat::Ed25519 => KeyPair::generate_ed25519(),
|
||||
KeyFormat::Secp256k1 => KeyPair::generate_secp256k1(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyFormat::Rsa => todo!("rsa generation is not supported yet!"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,40 +106,12 @@ impl KeyPair {
|
||||
KeyPair::Ed25519(ed25519::Keypair::generate())
|
||||
}
|
||||
|
||||
/// Generate a new Secp256k1 keypair.
|
||||
pub fn generate_secp256k1() -> KeyPair {
|
||||
KeyPair::Secp256k1(secp256k1::Keypair::generate())
|
||||
}
|
||||
|
||||
/// Decode an keypair from a DER-encoded secret key in PKCS#8 PrivateKeyInfo
|
||||
/// format (i.e. unencrypted) as defined in [RFC5208].
|
||||
///
|
||||
/// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<KeyPair, DecodingError> {
|
||||
rsa::Keypair::from_pkcs8(pkcs8_der).map(KeyPair::Rsa)
|
||||
}
|
||||
|
||||
/// Decode a keypair from a DER-encoded Secp256k1 secret key in an ECPrivateKey
|
||||
/// structure as defined in [RFC5915].
|
||||
///
|
||||
/// [RFC5915]: https://tools.ietf.org/html/rfc5915
|
||||
pub fn secp256k1_from_der(der: &mut [u8]) -> Result<KeyPair, DecodingError> {
|
||||
secp256k1::SecretKey::from_der(der)
|
||||
.map(|sk| KeyPair::Secp256k1(secp256k1::Keypair::from(sk)))
|
||||
}
|
||||
|
||||
/// Sign a message using the private key of this keypair, producing
|
||||
/// a signature that can be verified using the corresponding public key.
|
||||
pub fn sign(&self, msg: &[u8]) -> Result<Signature, SigningError> {
|
||||
use KeyPair::*;
|
||||
match self {
|
||||
Ed25519(ref pair) => Ok(Signature::Ed25519(ed25519::Signature(pair.sign(msg)?))),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(ref pair) => Ok(Signature::Rsa(rsa::Signature(pair.sign(msg)?))),
|
||||
Secp256k1(ref pair) => Ok(Signature::Secp256k1(secp256k1::Signature(
|
||||
pair.secret().sign(msg)?,
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,9 +121,6 @@ impl KeyPair {
|
||||
|
||||
match self {
|
||||
Ed25519(_) => KeyFormat::Ed25519,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(_) => KeyFormat::Rsa,
|
||||
Secp256k1(_) => KeyFormat::Secp256k1,
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,9 +129,6 @@ impl KeyPair {
|
||||
use KeyPair::*;
|
||||
match self {
|
||||
Ed25519(pair) => PublicKey::Ed25519(pair.public()),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(pair) => PublicKey::Rsa(pair.public()),
|
||||
Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,9 +136,6 @@ impl KeyPair {
|
||||
use KeyPair::*;
|
||||
match self {
|
||||
Ed25519(pair) => Ok(pair.secret().0.to_bytes().to_vec()),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(_) => Err(eyre::eyre!("secret key is not available for RSA")),
|
||||
Secp256k1(pair) => Ok(pair.secret().to_bytes().to_vec()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,9 +152,6 @@ impl KeyPair {
|
||||
use KeyPair::*;
|
||||
match self {
|
||||
Ed25519(kp) => kp.encode().to_vec(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(_) => todo!("rsa encoding is not supported yet!"),
|
||||
Secp256k1(kp) => kp.secret().to_bytes().to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,9 +160,6 @@ impl KeyPair {
|
||||
|
||||
match format {
|
||||
KeyFormat::Ed25519 => Ok(Ed25519(ed25519::Keypair::decode(&mut bytes)?)),
|
||||
KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported),
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,9 +168,6 @@ impl KeyPair {
|
||||
|
||||
match format {
|
||||
KeyFormat::Ed25519 => Ok(Ed25519(ed25519::SecretKey::from_bytes(bytes)?.into())),
|
||||
KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported),
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,19 +185,6 @@ impl From<libp2p_identity::Keypair> for KeyPair {
|
||||
let raw_kp = ed25519::Keypair::decode(&mut kp.to_bytes())?;
|
||||
Ok(KeyPair::Ed25519(raw_kp))
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyType::RSA => {
|
||||
let kp = key.try_into_rsa()?;
|
||||
let raw_kp = unsafe {
|
||||
std::mem::transmute::<libp2p_identity::rsa::Keypair, rsa::Keypair>(kp)
|
||||
};
|
||||
Ok(KeyPair::Rsa(raw_kp))
|
||||
}
|
||||
KeyType::Secp256k1 => {
|
||||
let kp = key.try_into_secp256k1()?;
|
||||
let raw_kp = secp256k1::SecretKey::from_bytes(kp.secret().to_bytes())?;
|
||||
Ok(KeyPair::Secp256k1(secp256k1::Keypair::from(raw_kp)))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -288,23 +203,6 @@ impl From<KeyPair> for libp2p_identity::Keypair {
|
||||
let kp = libp2p_identity::Keypair::ed25519_from_bytes(secret_bytes)?;
|
||||
Ok(kp)
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
// safety: these Keypair structures are identical
|
||||
KeyPair::Rsa(kp) => {
|
||||
let kp = unsafe {
|
||||
std::mem::transmute::<rsa::Keypair, libp2p_identity::rsa::Keypair>(kp)
|
||||
};
|
||||
let kp = Keypair::from(kp);
|
||||
Ok(kp)
|
||||
}
|
||||
KeyPair::Secp256k1(kp) => {
|
||||
let sk = libp2p_identity::secp256k1::SecretKey::try_from_bytes(
|
||||
kp.secret().to_bytes(),
|
||||
)?;
|
||||
let kp = libp2p_identity::secp256k1::Keypair::from(sk);
|
||||
let kp = Keypair::from(kp);
|
||||
Ok(kp)
|
||||
}
|
||||
}
|
||||
}
|
||||
convert_keypair(key).expect("Could not convert key pair")
|
||||
|
@ -30,9 +30,6 @@ mod ed25519;
|
||||
pub mod error;
|
||||
pub mod key_pair;
|
||||
pub mod public_key;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod rsa;
|
||||
mod secp256k1;
|
||||
pub mod signature;
|
||||
|
||||
pub use crate::public_key::PublicKey;
|
||||
|
@ -15,9 +15,6 @@
|
||||
*/
|
||||
use crate::ed25519;
|
||||
use crate::error::{DecodingError, VerificationError};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::rsa;
|
||||
use crate::secp256k1;
|
||||
use crate::signature::Signature;
|
||||
|
||||
use crate::key_pair::KeyFormat;
|
||||
@ -30,11 +27,6 @@ use std::convert::TryFrom;
|
||||
pub enum PublicKey {
|
||||
/// A public Ed25519 key.
|
||||
Ed25519(ed25519::PublicKey),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
/// A public RSA key.
|
||||
Rsa(rsa::PublicKey),
|
||||
/// A public Secp256k1 key.
|
||||
Secp256k1(secp256k1::PublicKey),
|
||||
}
|
||||
|
||||
impl PublicKey {
|
||||
@ -47,9 +39,6 @@ impl PublicKey {
|
||||
use PublicKey::*;
|
||||
match self {
|
||||
Ed25519(pk) => pk.verify(msg, sig.to_vec()),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(pk) => pk.verify(msg, sig.to_vec()),
|
||||
Secp256k1(pk) => pk.verify(msg, sig.to_vec()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,9 +48,6 @@ impl PublicKey {
|
||||
|
||||
match self {
|
||||
Ed25519(pk) => result.extend(pk.encode().to_vec()),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(pk) => result.extend(pk.to_pkcs1()),
|
||||
Secp256k1(pk) => result.extend(pk.encode().to_vec()),
|
||||
};
|
||||
|
||||
result
|
||||
@ -70,13 +56,6 @@ impl PublicKey {
|
||||
pub fn decode(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
|
||||
match KeyFormat::try_from(bytes[0])? {
|
||||
KeyFormat::Ed25519 => Ok(PublicKey::Ed25519(ed25519::PublicKey::decode(&bytes[1..])?)),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyFormat::Rsa => Ok(PublicKey::Rsa(rsa::PublicKey::from_pkcs1(
|
||||
bytes[1..].to_owned(),
|
||||
)?)),
|
||||
KeyFormat::Secp256k1 => Ok(PublicKey::Secp256k1(secp256k1::PublicKey::decode(
|
||||
&bytes[1..],
|
||||
)?)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,9 +63,6 @@ impl PublicKey {
|
||||
use PublicKey::*;
|
||||
match self {
|
||||
Ed25519(_) => KeyFormat::Ed25519.into(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(_) => KeyFormat::Rsa.into(),
|
||||
Secp256k1(_) => KeyFormat::Secp256k1.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,9 +78,6 @@ impl PublicKey {
|
||||
|
||||
match self {
|
||||
Ed25519(pk) => pk.encode().to_vec(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(pk) => pk.to_pkcs1().to_vec(),
|
||||
Secp256k1(pk) => pk.encode().to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,9 +90,6 @@ impl PublicKey {
|
||||
|
||||
match self {
|
||||
Ed25519(_) => KeyFormat::Ed25519,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(_) => KeyFormat::Rsa,
|
||||
Secp256k1(_) => KeyFormat::Secp256k1,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,17 +103,6 @@ impl From<libp2p_identity::PublicKey> for PublicKey {
|
||||
let raw_pk = ed25519::PublicKey::decode(&pk.to_bytes())?;
|
||||
Ok(PublicKey::Ed25519(raw_pk))
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyType::RSA => {
|
||||
let pk = key.try_into_rsa()?;
|
||||
let raw_pk = rsa::PublicKey::from_pkcs1(pk.encode_pkcs1())?;
|
||||
Ok(PublicKey::Rsa(raw_pk))
|
||||
}
|
||||
KeyType::Secp256k1 => {
|
||||
let pk = key.try_into_secp256k1()?;
|
||||
let raw_pk = secp256k1::PublicKey::decode(&pk.to_bytes())?;
|
||||
Ok(PublicKey::Secp256k1(raw_pk))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -162,19 +121,6 @@ impl From<PublicKey> for libp2p_identity::PublicKey {
|
||||
let pk = libp2p_identity::PublicKey::from(raw_pk);
|
||||
Ok(pk)
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
PublicKey::Rsa(key) => {
|
||||
let raw_pk =
|
||||
libp2p_identity::rsa::PublicKey::try_decode_x509(&key.encode_x509())?;
|
||||
let pk = libp2p_identity::PublicKey::from(raw_pk);
|
||||
Ok(pk)
|
||||
}
|
||||
PublicKey::Secp256k1(key) => {
|
||||
let raw_pk =
|
||||
libp2p_identity::secp256k1::PublicKey::try_from_bytes(&key.encode())?;
|
||||
let pk = libp2p_identity::PublicKey::from(raw_pk);
|
||||
Ok(pk)
|
||||
}
|
||||
}
|
||||
}
|
||||
convert_key(key).expect("Could not convert key")
|
||||
@ -216,17 +162,9 @@ mod tests {
|
||||
assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_key_encode_decode_secp256k1() {
|
||||
let kp = KeyPair::generate_secp256k1();
|
||||
let pk = kp.public();
|
||||
let encoded_pk = pk.encode();
|
||||
assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_key_peer_id_conversions() {
|
||||
let kp = KeyPair::generate_secp256k1();
|
||||
let kp = KeyPair::generate_ed25519();
|
||||
let fluence_pk = kp.public();
|
||||
let libp2p_pk: libp2p_identity::PublicKey = fluence_pk.clone().into();
|
||||
let peer_id = PeerId::from_public_key(&libp2p_pk);
|
||||
|
@ -1,286 +0,0 @@
|
||||
// Copyright 2019 Parity Technologies (UK) Ltd.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
//! RSA keys.
|
||||
use crate::error::{DecodingError, SigningError, VerificationError};
|
||||
|
||||
use asn1_der::{Asn1Der, Asn1DerError, DerObject, DerTag, DerValue, FromDerObject, IntoDerObject};
|
||||
use lazy_static::lazy_static;
|
||||
use ring::rand::SystemRandom;
|
||||
use ring::signature::KeyPair;
|
||||
use ring::signature::{self, RsaKeyPair, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_SHA256};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt::{self, Write},
|
||||
sync::Arc,
|
||||
};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
/// An RSA keypair.
|
||||
#[derive(Clone)]
|
||||
pub struct Keypair(Arc<RsaKeyPair>);
|
||||
|
||||
impl Keypair {
|
||||
/// Decode an RSA keypair from a DER-encoded private key in PKCS#8 PrivateKeyInfo
|
||||
/// format (i.e. unencrypted) as defined in [RFC5208].
|
||||
///
|
||||
/// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
|
||||
pub fn from_pkcs8(der: &mut [u8]) -> Result<Self, DecodingError> {
|
||||
let kp = RsaKeyPair::from_pkcs8(der).map_err(|_| DecodingError::Rsa)?;
|
||||
der.zeroize();
|
||||
Ok(Keypair(Arc::new(kp)))
|
||||
}
|
||||
|
||||
/// Get the public key from the keypair.
|
||||
pub fn public(&self) -> PublicKey {
|
||||
PublicKey(self.0.public_key().as_ref().to_vec())
|
||||
}
|
||||
|
||||
/// Sign a message with this keypair.
|
||||
pub fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SigningError> {
|
||||
let mut signature = vec![0; self.0.public_modulus_len()];
|
||||
let rng = SystemRandom::new();
|
||||
match self.0.sign(&RSA_PKCS1_SHA256, &rng, data, &mut signature) {
|
||||
Ok(()) => Ok(signature),
|
||||
Err(_) => Err(SigningError::Rsa),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An RSA public key.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct PublicKey(Vec<u8>);
|
||||
|
||||
impl PublicKey {
|
||||
/// Verify an RSA signature on a message using the public key.
|
||||
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
|
||||
let key = signature::UnparsedPublicKey::new(&RSA_PKCS1_2048_8192_SHA256, &self.0);
|
||||
key.verify(msg, sig).map_err(|e| {
|
||||
VerificationError::Rsa(
|
||||
e,
|
||||
bs58::encode(sig).into_string(),
|
||||
bs58::encode(&self.0).into_string(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Encode the RSA public key in DER as a PKCS#1 RSAPublicKey structure,
|
||||
/// as defined in [RFC3447].
|
||||
///
|
||||
/// [RFC3447]: https://tools.ietf.org/html/rfc3447#appendix-A.1.1
|
||||
pub fn to_pkcs1(&self) -> &[u8] {
|
||||
// This is the encoding currently used in-memory, so it is trivial.
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn from_pkcs1(pk: Vec<u8>) -> Result<Self, DecodingError> {
|
||||
Ok(PublicKey(pk))
|
||||
}
|
||||
|
||||
/// Encode the RSA public key in DER as a X.509 SubjectPublicKeyInfo structure,
|
||||
/// as defined in [RFC5280].
|
||||
///
|
||||
/// [RFC5280]: https://tools.ietf.org/html/rfc5280#section-4.1
|
||||
pub fn encode_x509(&self) -> Vec<u8> {
|
||||
let spki = Asn1SubjectPublicKeyInfo {
|
||||
algorithmIdentifier: Asn1RsaEncryption {
|
||||
algorithm: Asn1OidRsaEncryption(),
|
||||
parameters: (),
|
||||
},
|
||||
subjectPublicKey: Asn1SubjectPublicKey(self.clone()),
|
||||
};
|
||||
let mut buf = vec![0u8; spki.serialized_len()];
|
||||
spki.serialize(buf.iter_mut())
|
||||
.map(|_| buf)
|
||||
.expect("RSA X.509 public key encoding failed.")
|
||||
}
|
||||
|
||||
/// Decode an RSA public key from a DER-encoded X.509 SubjectPublicKeyInfo
|
||||
/// structure. See also `encode_x509`.
|
||||
pub fn decode_x509(pk: &[u8]) -> Result<Self, DecodingError> {
|
||||
Asn1SubjectPublicKeyInfo::deserialize(pk.iter())
|
||||
.map_err(|_| DecodingError::Rsa)
|
||||
.map(|spki| spki.subjectPublicKey.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PublicKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let bytes = &self.0;
|
||||
let mut hex = String::with_capacity(bytes.len() * 2);
|
||||
|
||||
for byte in bytes {
|
||||
write!(hex, "{byte:02x}").expect("Can't fail on writing to string");
|
||||
}
|
||||
|
||||
f.debug_struct("PublicKey").field("pkcs1", &hex).finish()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// DER encoding / decoding of public keys
|
||||
//
|
||||
// Primer: http://luca.ntop.org/Teaching/Appunti/asn1.html
|
||||
// Playground: https://lapo.it/asn1js/
|
||||
|
||||
lazy_static! {
|
||||
/// The DER encoding of the object identifier (OID) 'rsaEncryption' for
|
||||
/// RSA public keys defined for X.509 in [RFC-3279] and used in
|
||||
/// SubjectPublicKeyInfo structures defined in [RFC-5280].
|
||||
///
|
||||
/// [RFC-3279]: https://tools.ietf.org/html/rfc3279#section-2.3.1
|
||||
/// [RFC-5280]: https://tools.ietf.org/html/rfc5280#section-4.1
|
||||
static ref OID_RSA_ENCRYPTION_DER: DerObject =
|
||||
DerObject {
|
||||
tag: DerTag::x06,
|
||||
value: DerValue {
|
||||
data: vec![ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 ]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// The ASN.1 OID for "rsaEncryption".
|
||||
#[derive(Clone)]
|
||||
struct Asn1OidRsaEncryption();
|
||||
|
||||
impl IntoDerObject for Asn1OidRsaEncryption {
|
||||
fn into_der_object(self) -> DerObject {
|
||||
OID_RSA_ENCRYPTION_DER.clone()
|
||||
}
|
||||
fn serialized_len(&self) -> usize {
|
||||
OID_RSA_ENCRYPTION_DER.serialized_len()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromDerObject for Asn1OidRsaEncryption {
|
||||
fn from_der_object(o: DerObject) -> Result<Self, Asn1DerError> {
|
||||
if o.tag != DerTag::x06 {
|
||||
return Err(Asn1DerError::InvalidTag);
|
||||
}
|
||||
if o.value != OID_RSA_ENCRYPTION_DER.value {
|
||||
return Err(Asn1DerError::InvalidEncoding);
|
||||
}
|
||||
Ok(Asn1OidRsaEncryption())
|
||||
}
|
||||
}
|
||||
|
||||
/// The ASN.1 AlgorithmIdentifier for "rsaEncryption".
|
||||
#[derive(Asn1Der)]
|
||||
struct Asn1RsaEncryption {
|
||||
algorithm: Asn1OidRsaEncryption,
|
||||
parameters: (),
|
||||
}
|
||||
|
||||
/// The ASN.1 SubjectPublicKey inside a SubjectPublicKeyInfo,
|
||||
/// i.e. encoded as a DER BIT STRING.
|
||||
struct Asn1SubjectPublicKey(PublicKey);
|
||||
|
||||
impl IntoDerObject for Asn1SubjectPublicKey {
|
||||
fn into_der_object(self) -> DerObject {
|
||||
let pk_der = (self.0).0;
|
||||
let mut bit_string = Vec::with_capacity(pk_der.len() + 1);
|
||||
// The number of bits in pk_der is trivially always a multiple of 8,
|
||||
// so there are always 0 "unused bits" signaled by the first byte.
|
||||
bit_string.push(0u8);
|
||||
bit_string.extend(pk_der);
|
||||
DerObject::new(DerTag::x03, bit_string.into())
|
||||
}
|
||||
fn serialized_len(&self) -> usize {
|
||||
DerObject::compute_serialized_len((self.0).0.len() + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromDerObject for Asn1SubjectPublicKey {
|
||||
fn from_der_object(o: DerObject) -> Result<Self, Asn1DerError> {
|
||||
if o.tag != DerTag::x03 {
|
||||
return Err(Asn1DerError::InvalidTag);
|
||||
}
|
||||
let pk_der: Vec<u8> = o.value.data.into_iter().skip(1).collect();
|
||||
// We don't parse pk_der further as an ASN.1 RsaPublicKey, since
|
||||
// we only need the DER encoding for `verify`.
|
||||
Ok(Asn1SubjectPublicKey(PublicKey(pk_der)))
|
||||
}
|
||||
}
|
||||
|
||||
/// ASN.1 SubjectPublicKeyInfo
|
||||
#[derive(Asn1Der)]
|
||||
#[allow(non_snake_case)]
|
||||
struct Asn1SubjectPublicKeyInfo {
|
||||
algorithmIdentifier: Asn1RsaEncryption,
|
||||
subjectPublicKey: Asn1SubjectPublicKey,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Signature(pub Vec<u8>);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use quickcheck::*;
|
||||
use std::fmt;
|
||||
|
||||
const KEY1: &'static [u8] = include_bytes!("test/rsa-2048.pk8");
|
||||
const KEY2: &'static [u8] = include_bytes!("test/rsa-3072.pk8");
|
||||
const KEY3: &'static [u8] = include_bytes!("test/rsa-4096.pk8");
|
||||
|
||||
#[derive(Clone)]
|
||||
struct SomeKeypair(Keypair);
|
||||
|
||||
impl fmt::Debug for SomeKeypair {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "SomeKeypair")
|
||||
}
|
||||
}
|
||||
|
||||
impl Arbitrary for SomeKeypair {
|
||||
fn arbitrary(g: &mut Gen) -> SomeKeypair {
|
||||
let mut key = g.choose(&[KEY1, KEY2, KEY3]).unwrap().to_vec();
|
||||
SomeKeypair(Keypair::from_pkcs8(&mut key).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rsa_from_pkcs8() {
|
||||
assert!(Keypair::from_pkcs8(&mut KEY1.to_vec()).is_ok());
|
||||
assert!(Keypair::from_pkcs8(&mut KEY2.to_vec()).is_ok());
|
||||
assert!(Keypair::from_pkcs8(&mut KEY3.to_vec()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rsa_x509_encode_decode() {
|
||||
fn prop(SomeKeypair(kp): SomeKeypair) -> Result<bool, String> {
|
||||
let pk = kp.public();
|
||||
PublicKey::decode_x509(&pk.encode_x509())
|
||||
.map_err(|e| e.to_string())
|
||||
.map(|pk2| pk2 == pk)
|
||||
}
|
||||
QuickCheck::new().tests(10).quickcheck(prop as fn(_) -> _);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rsa_sign_verify() {
|
||||
fn prop(SomeKeypair(kp): SomeKeypair, msg: Vec<u8>) -> Result<bool, SigningError> {
|
||||
kp.sign(&msg).map(|s| kp.public().verify(&msg, &s).is_ok())
|
||||
}
|
||||
QuickCheck::new()
|
||||
.tests(10)
|
||||
.quickcheck(prop as fn(_, _) -> _);
|
||||
}
|
||||
}
|
@ -1,259 +0,0 @@
|
||||
// Copyright 2019 Parity Technologies (UK) Ltd.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
//! Secp256k1 keys.
|
||||
use crate::error::{DecodingError, SigningError, VerificationError};
|
||||
|
||||
use asn1_der::{DerObject, FromDerObject};
|
||||
use core::fmt;
|
||||
use libsecp256k1::Message;
|
||||
use rand::RngCore;
|
||||
use serde::de::Error as SerdeError;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes};
|
||||
use sha2::{Digest as ShaDigestTrait, Sha256};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
/// A Secp256k1 keypair.
|
||||
#[derive(Clone)]
|
||||
pub struct Keypair {
|
||||
secret: SecretKey,
|
||||
public: PublicKey,
|
||||
}
|
||||
|
||||
impl Keypair {
|
||||
/// Generate a new sec256k1 `Keypair`.
|
||||
pub fn generate() -> Self {
|
||||
Keypair::from(SecretKey::generate())
|
||||
}
|
||||
|
||||
/// Get the public key of this keypair.
|
||||
pub fn public(&self) -> &PublicKey {
|
||||
&self.public
|
||||
}
|
||||
|
||||
/// Get the secret key of this keypair.
|
||||
pub fn secret(&self) -> &SecretKey {
|
||||
&self.secret
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Keypair {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Keypair")
|
||||
.field("public", &self.public)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Promote a Secp256k1 secret key into a keypair.
|
||||
impl From<SecretKey> for Keypair {
|
||||
fn from(secret: SecretKey) -> Self {
|
||||
let public = PublicKey(libsecp256k1::PublicKey::from_secret_key(&secret.0));
|
||||
Keypair { secret, public }
|
||||
}
|
||||
}
|
||||
|
||||
/// Demote a Secp256k1 keypair into a secret key.
|
||||
impl From<Keypair> for SecretKey {
|
||||
fn from(kp: Keypair) -> Self {
|
||||
kp.secret
|
||||
}
|
||||
}
|
||||
|
||||
/// A Secp256k1 secret key.
|
||||
#[derive(Clone)]
|
||||
pub struct SecretKey(libsecp256k1::SecretKey);
|
||||
|
||||
impl fmt::Debug for SecretKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "SecretKey")
|
||||
}
|
||||
}
|
||||
|
||||
impl SecretKey {
|
||||
/// Generate a new Secp256k1 secret key.
|
||||
pub fn generate() -> Self {
|
||||
let mut r = rand::thread_rng();
|
||||
let mut b = [0; libsecp256k1::util::SECRET_KEY_SIZE];
|
||||
// This is how it is done in `secp256k1::SecretKey::random` which
|
||||
// we do not use here because it uses `rand::Rng` from rand-0.4.
|
||||
loop {
|
||||
r.fill_bytes(&mut b);
|
||||
if let Ok(k) = libsecp256k1::SecretKey::parse(&b) {
|
||||
return SecretKey(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a secret key from a byte slice, zeroing the slice on success.
|
||||
/// If the bytes do not constitute a valid Secp256k1 secret key, an
|
||||
/// error is returned.
|
||||
pub fn from_bytes(mut sk: impl AsMut<[u8]>) -> Result<Self, DecodingError> {
|
||||
let sk_bytes = sk.as_mut();
|
||||
let secret = libsecp256k1::SecretKey::parse_slice(&*sk_bytes)
|
||||
.map_err(|_| DecodingError::Secp256k1)?;
|
||||
sk_bytes.zeroize();
|
||||
Ok(SecretKey(secret))
|
||||
}
|
||||
|
||||
/// Decode a DER-encoded Secp256k1 secret key in an ECPrivateKey
|
||||
/// structure as defined in [RFC5915].
|
||||
///
|
||||
/// [RFC5915]: https://tools.ietf.org/html/rfc5915
|
||||
pub fn from_der(mut der: impl AsMut<[u8]>) -> Result<SecretKey, DecodingError> {
|
||||
// TODO: Stricter parsing.
|
||||
let der_obj = der.as_mut();
|
||||
let obj: Vec<DerObject> =
|
||||
FromDerObject::deserialize((*der_obj).iter()).map_err(|_| DecodingError::Secp256k1)?;
|
||||
der_obj.zeroize();
|
||||
let sk_obj = obj.into_iter().nth(1).ok_or(DecodingError::Secp256k1)?;
|
||||
let mut sk_bytes: Vec<u8> =
|
||||
FromDerObject::from_der_object(sk_obj).map_err(|_| DecodingError::Secp256k1)?;
|
||||
let sk = SecretKey::from_bytes(&mut sk_bytes)?;
|
||||
sk_bytes.zeroize();
|
||||
Ok(sk)
|
||||
}
|
||||
|
||||
/// Sign a message with this secret key, producing a DER-encoded
|
||||
/// ECDSA signature, as defined in [RFC3278].
|
||||
///
|
||||
/// [RFC3278]: https://tools.ietf.org/html/rfc3278#section-8.2
|
||||
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
|
||||
self.sign_hashed(Sha256::digest(msg).as_ref())
|
||||
}
|
||||
|
||||
/// Returns the raw bytes of the secret key.
|
||||
pub fn to_bytes(&self) -> [u8; 32] {
|
||||
self.0.serialize()
|
||||
}
|
||||
|
||||
/// Sign a raw message of length 256 bits with this secret key, produces a DER-encoded
|
||||
/// ECDSA signature.
|
||||
pub fn sign_hashed(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
|
||||
let m = Message::parse_slice(msg).map_err(SigningError::Secp256k1)?;
|
||||
Ok(libsecp256k1::sign(&m, &self.0)
|
||||
.0
|
||||
.serialize_der()
|
||||
.as_ref()
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// A Secp256k1 public key.
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct PublicKey(libsecp256k1::PublicKey);
|
||||
|
||||
impl PublicKey {
|
||||
/// Verify the Secp256k1 signature on a message using the public key.
|
||||
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
|
||||
self.verify_hashed(Sha256::digest(msg).as_ref(), sig)
|
||||
}
|
||||
|
||||
/// Verify the Secp256k1 DER-encoded signature on a raw 256-bit message using the public key.
|
||||
pub fn verify_hashed(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
|
||||
Message::parse_slice(msg)
|
||||
.and_then(|m| {
|
||||
libsecp256k1::Signature::parse_der(sig)
|
||||
.map(|s| libsecp256k1::verify(&m, &s, &self.0))
|
||||
})
|
||||
.map_err(|e| {
|
||||
VerificationError::Secp256k1(
|
||||
e,
|
||||
bs58::encode(sig).into_string(),
|
||||
bs58::encode(self.0.serialize_compressed()).into_string(),
|
||||
)
|
||||
})
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
/// Encode the public key in compressed form, i.e. with one coordinate
|
||||
/// represented by a single bit.
|
||||
pub fn encode(&self) -> [u8; 33] {
|
||||
self.0.serialize_compressed()
|
||||
}
|
||||
|
||||
/// Encode the public key in uncompressed form.
|
||||
pub fn encode_uncompressed(&self) -> [u8; 65] {
|
||||
self.0.serialize()
|
||||
}
|
||||
|
||||
/// Decode a public key from a byte slice in the the format produced
|
||||
/// by `encode`.
|
||||
pub fn decode(bytes: &[u8]) -> Result<Self, DecodingError> {
|
||||
libsecp256k1::PublicKey::parse_slice(bytes, Some(libsecp256k1::PublicKeyFormat::Compressed))
|
||||
.map_err(|_| DecodingError::Secp256k1)
|
||||
.map(PublicKey)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for PublicKey {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
SerdeBytes::new(self.encode().to_vec().as_slice()).serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> Deserialize<'d> for PublicKey {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'d>,
|
||||
{
|
||||
let bytes = <SerdeByteBuf>::deserialize(deserializer)?;
|
||||
PublicKey::decode(bytes.as_slice()).map_err(SerdeError::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Signature(pub Vec<u8>);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{key_pair, KeyFormat};
|
||||
use quickcheck::QuickCheck;
|
||||
|
||||
fn eq_keypairs(kp1: key_pair::KeyPair, kp2: key_pair::KeyPair) -> bool {
|
||||
kp1.public() == kp2.public() && kp1.secret().unwrap() == kp2.secret().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn secp256k1_secret_from_bytes() {
|
||||
let sk1 = SecretKey::generate();
|
||||
let mut sk_bytes = [0; 32];
|
||||
sk_bytes.copy_from_slice(&sk1.0.serialize()[..]);
|
||||
let sk2 = SecretKey::from_bytes(&mut sk_bytes).unwrap();
|
||||
assert_eq!(sk1.0.serialize(), sk2.0.serialize());
|
||||
assert_eq!(sk_bytes, [0; 32]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn secp256k1_keypair_encode_decode() {
|
||||
fn prop() -> bool {
|
||||
let kp1 = key_pair::KeyPair::generate(KeyFormat::Secp256k1);
|
||||
let kp1_enc = libp2p_identity::Keypair::from(kp1.clone());
|
||||
let kp2 = key_pair::KeyPair::from(kp1_enc);
|
||||
eq_keypairs(kp1, kp2)
|
||||
}
|
||||
QuickCheck::new().tests(10).quickcheck(prop as fn() -> _);
|
||||
}
|
||||
}
|
@ -16,18 +16,12 @@
|
||||
use crate::ed25519;
|
||||
use crate::error::DecodingError;
|
||||
use crate::key_pair::KeyFormat;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::rsa;
|
||||
use crate::secp256k1;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub enum Signature {
|
||||
Ed25519(ed25519::Signature),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(rsa::Signature),
|
||||
Secp256k1(secp256k1::Signature),
|
||||
}
|
||||
|
||||
pub struct RawSignature {
|
||||
@ -40,9 +34,6 @@ impl Signature {
|
||||
use Signature::*;
|
||||
match self {
|
||||
Ed25519(_) => KeyFormat::Ed25519.into(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(_) => KeyFormat::Rsa.into(),
|
||||
Secp256k1(_) => KeyFormat::Secp256k1.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,9 +45,6 @@ impl Signature {
|
||||
|
||||
match self {
|
||||
Ed25519(sig) => result.extend(sig.0.clone()),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(sig) => result.extend(sig.0.clone()),
|
||||
Secp256k1(sig) => result.extend(sig.0.clone()),
|
||||
}
|
||||
|
||||
result
|
||||
@ -66,11 +54,6 @@ impl Signature {
|
||||
pub fn decode(bytes: Vec<u8>) -> Result<Self, DecodingError> {
|
||||
match KeyFormat::try_from(bytes[0])? {
|
||||
KeyFormat::Ed25519 => Ok(Signature::Ed25519(ed25519::Signature(bytes[1..].to_vec()))),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyFormat::Rsa => Ok(Signature::Rsa(rsa::Signature(bytes[1..].to_vec()))),
|
||||
KeyFormat::Secp256k1 => Ok(Signature::Secp256k1(secp256k1::Signature(
|
||||
bytes[1..].to_vec(),
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,9 +62,6 @@ impl Signature {
|
||||
|
||||
match self {
|
||||
Ed25519(sig) => &sig.0,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(sig) => &sig.0,
|
||||
Secp256k1(sig) => &sig.0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,9 +70,6 @@ impl Signature {
|
||||
|
||||
match self {
|
||||
Ed25519(_) => KeyFormat::Ed25519,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Rsa(_) => KeyFormat::Rsa,
|
||||
Secp256k1(_) => KeyFormat::Secp256k1,
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,9 +83,6 @@ impl Signature {
|
||||
pub fn from_bytes(key_format: KeyFormat, bytes: Vec<u8>) -> Self {
|
||||
match key_format {
|
||||
KeyFormat::Ed25519 => Signature::Ed25519(ed25519::Signature(bytes)),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
KeyFormat::Rsa => Signature::Rsa(rsa::Signature(bytes)),
|
||||
KeyFormat::Secp256k1 => Signature::Secp256k1(secp256k1::Signature(bytes)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,19 +95,10 @@ mod tests {
|
||||
fn signature_encode_decode() {
|
||||
let bytes: Vec<u8> = (0..10).collect();
|
||||
let ed25519_sig = Signature::Ed25519(crate::ed25519::Signature(bytes.clone()));
|
||||
let secp256k1_sig = Signature::Secp256k1(crate::secp256k1::Signature(bytes.clone()));
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let rsa_sig = Signature::Rsa(crate::rsa::Signature(bytes.clone()));
|
||||
|
||||
assert_eq!(
|
||||
Signature::decode(ed25519_sig.encode()).unwrap(),
|
||||
ed25519_sig
|
||||
);
|
||||
assert_eq!(
|
||||
Signature::decode(secp256k1_sig.encode()).unwrap(),
|
||||
secp256k1_sig
|
||||
);
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
assert_eq!(Signature::decode(rsa_sig.encode()).unwrap(), rsa_sig);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user