Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions fastcrypto/src/bls12381/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,14 +469,18 @@ macro_rules! define_bls12381 {
}

fn private(self) -> Self::PrivKey {
BLS12381PrivateKey::from_bytes(self.private.as_ref()).unwrap()
self.private
}

#[cfg(feature = "copy_key")]
fn copy(&self) -> Self {
// Note: The copy_key feature explicitly allows copying private keys for specific use cases.
// This reconstructs the private key from bytes, which should never fail for a valid keypair.
let private_bytes = self.private.as_ref();
BLS12381KeyPair {
public: self.public.clone(),
private: BLS12381PrivateKey::from_bytes(self.private.as_ref()).unwrap(),
private: BLS12381PrivateKey::from_bytes(private_bytes)
.expect("KeyPair should always contain valid private key bytes"),
}
}

Expand Down
10 changes: 7 additions & 3 deletions fastcrypto/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,18 @@ impl KeyPair for Ed25519KeyPair {
}

fn private(self) -> Self::PrivKey {
Ed25519PrivateKey::from_bytes(self.private.as_ref()).unwrap()
self.private
}

#[cfg(feature = "copy_key")]
fn copy(&self) -> Self {
// Note: The copy_key feature explicitly allows copying private keys for specific use cases.
// This reconstructs the private key from bytes, which should never fail for a valid keypair.
let private_bytes = self.private.as_ref();
Self {
public: Ed25519PublicKey::from_bytes(self.public.as_ref()).unwrap(),
private: Ed25519PrivateKey::from_bytes(self.private.as_ref()).unwrap(),
public: self.public.clone(),
private: Ed25519PrivateKey::from_bytes(private_bytes)
.expect("KeyPair should always contain valid private key bytes"),
}
}

Expand Down
45 changes: 35 additions & 10 deletions fastcrypto/src/secp256k1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,27 @@ impl AsRef<[u8]> for Secp256k1PrivateKey {

impl zeroize::ZeroizeOnDrop for Secp256k1PrivateKey {}

impl Secp256k1PrivateKey {
/// Create a new signature using the given hash function to hash the message.
pub fn sign_with_hash<H: HashFunction<32>>(&self, msg: &[u8]) -> Secp256k1Signature {
let message = Message::from_slice(H::digest(msg).as_ref()).unwrap();

// Creates a 64-bytes signature of shape [r, s].
// Pseudo-random deterministic nonce generation is used according to RFC6979.
Secp256k1Signature {
sig: Secp256k1::signing_only().sign_ecdsa(&message, &self.privkey),
bytes: OnceCell::new(),
}
}
}

impl Signer<Secp256k1Signature> for Secp256k1PrivateKey {
fn sign(&self, msg: &[u8]) -> Secp256k1Signature {
// Sha256 is used by default
self.sign_with_hash::<DefaultHash>(msg)
}
}

impl Drop for Secp256k1PrivateKey {
fn drop(&mut self) {
// bytes is zeroized on drop indirectly via OnceCell
Expand Down Expand Up @@ -282,22 +303,22 @@ impl From<&Secp256k1RecoverableSignature> for Secp256k1Signature {
/// Secp256k1 public/private key pair.
#[derive(Debug, PartialEq, Eq)]
pub struct Secp256k1KeyPair {
pub public: Secp256k1PublicKey,
pub secret: Secp256k1PrivateKey,
public: Secp256k1PublicKey,
private: Secp256k1PrivateKey,
}

/// The bytes form of the keypair always only contain the private key bytes
impl ToFromBytes for Secp256k1KeyPair {
fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
Secp256k1PrivateKey::from_bytes(bytes).map(|secret| secret.into())
Secp256k1PrivateKey::from_bytes(bytes).map(|private| private.into())
}
}

serialize_deserialize_with_to_from_bytes!(Secp256k1KeyPair, SECP256K1_KEYPAIR_LENGTH);

impl AsRef<[u8]> for Secp256k1KeyPair {
fn as_ref(&self) -> &[u8] {
self.secret.as_ref()
self.private.as_ref()
}
}

Expand All @@ -311,14 +332,18 @@ impl KeyPair for Secp256k1KeyPair {
}

fn private(self) -> Self::PrivKey {
Secp256k1PrivateKey::from_bytes(self.secret.as_ref()).unwrap()
self.private
}

#[cfg(feature = "copy_key")]
fn copy(&self) -> Self {
// Note: The copy_key feature explicitly allows copying private keys for specific use cases.
// This reconstructs the private key from bytes, which should never fail for a valid keypair.
let private_bytes = self.private.as_ref();
Secp256k1KeyPair {
public: self.public.clone(),
secret: Secp256k1PrivateKey::from_bytes(self.secret.as_ref()).unwrap(),
private: Secp256k1PrivateKey::from_bytes(private_bytes)
.expect("KeyPair should always contain valid private key bytes"),
}
}

Expand All @@ -330,7 +355,7 @@ impl KeyPair for Secp256k1KeyPair {
pubkey,
bytes: OnceCell::new(),
},
secret: Secp256k1PrivateKey {
private: Secp256k1PrivateKey {
privkey,
bytes: OnceCell::new(),
},
Expand Down Expand Up @@ -368,8 +393,8 @@ impl Signer<Secp256k1Signature> for Secp256k1KeyPair {
}

impl From<Secp256k1PrivateKey> for Secp256k1KeyPair {
fn from(secret: Secp256k1PrivateKey) -> Self {
let public = Secp256k1PublicKey::from(&secret);
Secp256k1KeyPair { public, secret }
fn from(private: Secp256k1PrivateKey) -> Self {
let public = Secp256k1PublicKey::from(&private);
Secp256k1KeyPair { public, private }
}
}