2023-09-01 04:10:56 +00:00
|
|
|
use crate::PublicKey;
|
|
|
|
|
|
|
|
use thiserror::Error;
|
|
|
|
|
2024-02-21 01:39:28 +00:00
|
|
|
use keyfork_bug::bug;
|
|
|
|
|
2023-09-01 04:57:05 +00:00
|
|
|
pub(crate) type PrivateKeyBytes = [u8; 32];
|
2023-09-01 04:10:56 +00:00
|
|
|
|
2023-09-01 04:49:35 +00:00
|
|
|
/// Functions required to use an `ExtendedPrivateKey`.
|
2023-09-01 04:10:56 +00:00
|
|
|
pub trait PrivateKey: Sized {
|
2023-09-01 04:49:35 +00:00
|
|
|
/// A type implementing [`PublicKey`] associated with Self.
|
2023-09-01 04:10:56 +00:00
|
|
|
type PublicKey: PublicKey;
|
2023-09-01 04:49:35 +00:00
|
|
|
|
|
|
|
/// The error returned by [`PrivateKey::derive_child()`].
|
2023-09-01 04:10:56 +00:00
|
|
|
type Err: std::error::Error;
|
|
|
|
|
2023-09-01 04:49:35 +00:00
|
|
|
/// Create a Self from bytes.
|
2024-02-10 08:50:55 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```rust
|
|
|
|
/// # use keyfork_derive_util::{
|
|
|
|
/// # *,
|
|
|
|
/// # private_key::TestPrivateKey as OurPrivateKey,
|
|
|
|
/// # };
|
|
|
|
/// let key_data: &[u8; 32] = //
|
|
|
|
/// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
|
|
|
/// let private_key = OurPrivateKey::from_bytes(key_data);
|
|
|
|
/// ```
|
2023-09-01 04:10:56 +00:00
|
|
|
fn from_bytes(b: &PrivateKeyBytes) -> Self;
|
2023-09-01 04:49:35 +00:00
|
|
|
|
|
|
|
/// Convert a &Self to bytes.
|
2024-02-10 08:50:55 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```rust
|
|
|
|
/// # use keyfork_derive_util::{
|
|
|
|
/// # *,
|
|
|
|
/// # private_key::TestPrivateKey as OurPrivateKey,
|
|
|
|
/// # };
|
|
|
|
/// let key_data: &[u8; 32] = //
|
|
|
|
/// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
|
|
|
/// let private_key = OurPrivateKey::from_bytes(key_data);
|
|
|
|
/// assert_eq!(key_data, &private_key.to_bytes());
|
|
|
|
/// ```
|
2023-09-01 04:10:56 +00:00
|
|
|
fn to_bytes(&self) -> PrivateKeyBytes;
|
|
|
|
|
2023-09-06 15:21:47 +00:00
|
|
|
/*
|
|
|
|
* Freak of nature, unsupported?
|
2023-09-01 04:49:35 +00:00
|
|
|
/// Whether or not zero is a valid public key (such as with ed25519 keys).
|
2023-09-01 04:10:56 +00:00
|
|
|
fn is_zero_valid_public_key() -> bool {
|
|
|
|
false
|
|
|
|
}
|
2023-09-06 15:21:47 +00:00
|
|
|
*/
|
2023-09-01 04:49:35 +00:00
|
|
|
|
|
|
|
/// The initial key for BIP-0032 and SLIP-0010 derivation, such as secp256k1's "Bitcoin seed".
|
2024-02-10 08:50:55 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```rust
|
|
|
|
/// # use keyfork_derive_util::{
|
|
|
|
/// # *,
|
|
|
|
/// # private_key::TestPrivateKey as OurPrivateKey,
|
|
|
|
/// # };
|
|
|
|
/// assert_eq!(OurPrivateKey::key(), "testing seed");
|
|
|
|
/// ```
|
2023-09-01 04:10:56 +00:00
|
|
|
fn key() -> &'static str;
|
|
|
|
|
2023-09-01 04:49:35 +00:00
|
|
|
/// Generate a [`Self::PublicKey`].
|
2024-02-10 08:50:55 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```rust
|
|
|
|
/// # use keyfork_derive_util::{
|
|
|
|
/// # *,
|
|
|
|
/// # private_key::TestPrivateKey as OurPrivateKey,
|
|
|
|
/// # };
|
|
|
|
/// let key_data: &[u8; 32] = //
|
|
|
|
/// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
|
|
|
/// let private_key = OurPrivateKey::from_bytes(key_data);
|
|
|
|
/// let public_key = private_key.public_key();
|
|
|
|
/// ```
|
2023-09-01 04:10:56 +00:00
|
|
|
fn public_key(&self) -> Self::PublicKey;
|
|
|
|
|
2024-02-10 08:50:55 +00:00
|
|
|
/// Derive a child [`PrivateKey`] with given `PrivateKeyBytes`. The implementation of
|
|
|
|
/// derivation is algorithm-specific and a specification should be consulted when implementing
|
|
|
|
/// this method.
|
2023-09-01 04:10:56 +00:00
|
|
|
///
|
|
|
|
/// # Errors
|
|
|
|
///
|
|
|
|
/// An error may be returned if:
|
2024-04-12 20:23:24 +00:00
|
|
|
/// * An all-zero `other` is provided.
|
2023-09-01 04:10:56 +00:00
|
|
|
/// * An error specific to the given algorithm was encountered.
|
|
|
|
fn derive_child(&self, other: &PrivateKeyBytes) -> Result<Self, Self::Err>;
|
2023-09-06 15:21:47 +00:00
|
|
|
|
|
|
|
/// Whether the algorithm requires hardened derivation, such as for ed25519.
|
|
|
|
fn requires_hardened_derivation() -> bool {
|
|
|
|
false
|
|
|
|
}
|
2023-09-01 04:10:56 +00:00
|
|
|
}
|
|
|
|
|
2023-09-01 04:49:35 +00:00
|
|
|
/// Errors associated with creating and arithmetic on private keys. This specific error is only
|
|
|
|
/// intended to be used by the implementations in this crate.
|
2023-09-01 04:10:56 +00:00
|
|
|
#[derive(Clone, Debug, Error)]
|
|
|
|
pub enum PrivateKeyError {
|
2023-09-01 04:49:35 +00:00
|
|
|
/// For the given algorithm, the private key must be nonzero.
|
2023-09-01 04:10:56 +00:00
|
|
|
#[error("The provided private key must be nonzero, but is not")]
|
|
|
|
NonZero,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "secp256k1")]
|
|
|
|
use k256::NonZeroScalar;
|
|
|
|
|
|
|
|
#[cfg(feature = "secp256k1")]
|
|
|
|
impl PrivateKey for k256::SecretKey {
|
|
|
|
type Err = PrivateKeyError;
|
|
|
|
type PublicKey = k256::PublicKey;
|
|
|
|
|
|
|
|
fn key() -> &'static str {
|
|
|
|
"Bitcoin seed"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_bytes(b: &PrivateKeyBytes) -> Self {
|
2024-02-21 01:39:28 +00:00
|
|
|
Self::from_slice(b).expect(bug!("Invalid private key bytes"))
|
2023-09-01 04:10:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn to_bytes(&self) -> PrivateKeyBytes {
|
|
|
|
// Note: Safety assured by type returned from EncodedPoint
|
|
|
|
self.to_bytes().into()
|
|
|
|
}
|
|
|
|
|
2023-09-06 15:21:47 +00:00
|
|
|
fn public_key(&self) -> Self::PublicKey {
|
|
|
|
self.public_key()
|
|
|
|
}
|
|
|
|
|
2023-09-01 04:10:56 +00:00
|
|
|
fn derive_child(&self, other: &PrivateKeyBytes) -> Result<Self, Self::Err> {
|
|
|
|
if other.iter().all(|n| n == &0) {
|
|
|
|
return Err(PrivateKeyError::NonZero);
|
|
|
|
}
|
|
|
|
let other = *other;
|
|
|
|
// Checked: See above nonzero check
|
|
|
|
let scalar = Option::<NonZeroScalar>::from(NonZeroScalar::from_repr(other.into()))
|
2024-02-21 01:39:28 +00:00
|
|
|
.expect(bug!("Should have been able to get a NonZeroScalar"));
|
2023-09-01 04:10:56 +00:00
|
|
|
|
|
|
|
let derived_scalar = self.to_nonzero_scalar().as_ref() + scalar.as_ref();
|
|
|
|
Ok(
|
|
|
|
Option::<NonZeroScalar>::from(NonZeroScalar::new(derived_scalar))
|
|
|
|
.map(Into::into)
|
2024-02-21 01:39:28 +00:00
|
|
|
.expect(bug!("Should be able to make Key")),
|
2023-09-01 04:10:56 +00:00
|
|
|
)
|
|
|
|
}
|
2023-09-06 15:21:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "ed25519")]
|
|
|
|
impl PrivateKey for ed25519_dalek::SigningKey {
|
|
|
|
type Err = PrivateKeyError;
|
|
|
|
type PublicKey = ed25519_dalek::VerifyingKey;
|
|
|
|
|
|
|
|
fn key() -> &'static str {
|
|
|
|
"ed25519 seed"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_bytes(b: &PrivateKeyBytes) -> Self {
|
|
|
|
Self::from_bytes(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_bytes(&self) -> PrivateKeyBytes {
|
|
|
|
self.to_bytes()
|
|
|
|
}
|
2023-09-01 04:10:56 +00:00
|
|
|
|
|
|
|
fn public_key(&self) -> Self::PublicKey {
|
2023-09-06 15:21:47 +00:00
|
|
|
self.verifying_key()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn derive_child(&self, other: &PrivateKeyBytes) -> Result<Self, Self::Err> {
|
|
|
|
// SLIP-0010: No arithmetic required for ed25519 keys.
|
|
|
|
Ok(Self::from_bytes(other))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn requires_hardened_derivation() -> bool {
|
|
|
|
true
|
2023-09-01 04:10:56 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-10 08:50:55 +00:00
|
|
|
|
|
|
|
use crate::public_key::TestPublicKey;
|
|
|
|
|
2024-04-15 01:26:44 +00:00
|
|
|
/// A private key that can be used for testing purposes. Does not utilize any significant
|
|
|
|
/// cryptographic operations.
|
2024-02-10 08:50:55 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub struct TestPrivateKey {
|
|
|
|
key: [u8; 32],
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TestPrivateKey {
|
|
|
|
pub(crate) fn public_key(&self) -> TestPublicKey {
|
|
|
|
let mut bytes = [0u8; 33];
|
|
|
|
for (i, byte) in self.key.iter().enumerate() {
|
|
|
|
bytes[i + 1] = byte ^ 0xFF;
|
|
|
|
}
|
|
|
|
TestPublicKey { key: bytes }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PrivateKey for TestPrivateKey {
|
|
|
|
type PublicKey = TestPublicKey;
|
|
|
|
type Err = PrivateKeyError;
|
|
|
|
|
|
|
|
fn from_bytes(b: &PrivateKeyBytes) -> Self {
|
|
|
|
Self {
|
|
|
|
key: *b
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_bytes(&self) -> PrivateKeyBytes {
|
|
|
|
self.key
|
|
|
|
}
|
|
|
|
|
|
|
|
fn key() -> &'static str {
|
|
|
|
"testing seed"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn public_key(&self) -> Self::PublicKey {
|
|
|
|
self.public_key()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn derive_child(&self, other: &PrivateKeyBytes) -> Result<Self, Self::Err> {
|
|
|
|
Ok(Self { key: *other })
|
|
|
|
}
|
|
|
|
}
|