Skip to content

Commit

Permalink
Adds example docs and doc-tests for derived_key() and derived_key_sim…
Browse files Browse the repository at this point in the history
…ple()
  • Loading branch information
alexpArtos committed Aug 11, 2024
1 parent f1db728 commit b1bb201
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,50 @@ pub struct ChainCode(pub [u8; CHAIN_CODE_LENGTH]);
pub trait Derivation: Sized {
/// Derive key with subkey identified by a byte array
/// presented via a `SigningTranscript`, and a chain code.
///
/// This trait allow the derivation of a key from another, according to BIP32 rules.
/// The derivation can be performed on a full Keypair, or each of its constituent keys.
/// These two ways are equivalent.
///
/// # Example:
///
/// ```
/// use schnorrkel::{Keypair,derive::{CHAIN_CODE_LENGTH, ChainCode, Derivation}};
///
/// let t = merlin::Transcript::new(b"SchnorrRistrettoHDKD");
/// let chaincode = ChainCode([0u8; CHAIN_CODE_LENGTH]); // This is an example. In practice, we should use a random value.
///
/// let keypair: Keypair = Keypair::generate();
/// let public_key = &keypair.public;
/// let secret_key = &keypair.secret;
///
/// let (derived_keypair, _) = keypair.derived_key(t.clone(), chaincode);
/// let (derived_public_key, _) = public_key.derived_key(t.clone(), chaincode);
/// let (derived_secret_key, _) = secret_key.derived_key(t.clone(), chaincode);
///
/// assert_eq!(derived_public_key, derived_keypair.public);
/// assert_eq!(derived_secret_key, derived_keypair.secret);
/// ```
fn derived_key<T>(&self, t: T, cc: ChainCode) -> (Self, ChainCode)
where
T: SigningTranscript;

/// Derive key with subkey identified by a byte array
/// and a chain code. We do not include a context here
/// because the chain code could serve this purpose.
///
/// # Example:
///
/// ```
/// use schnorrkel::{Keypair,derive::{CHAIN_CODE_LENGTH, ChainCode, Derivation}};
///
/// let t = merlin::Transcript::new(b"SchnorrRistrettoHDKD");
/// let chaincode = ChainCode([0u8; CHAIN_CODE_LENGTH]); // This is an example. In practice, we should use a random value.
///
/// let keypair: Keypair = Keypair::generate();
/// let bytes = [0u8, 120u8, 243u8, 31u8, 67u8, 8u8];
/// let (derived_keypair, _) = keypair.derived_key_simple(chaincode, &bytes);
/// ```
fn derived_key_simple<B: AsRef<[u8]>>(&self, cc: ChainCode, i: B) -> (Self, ChainCode) {
let mut t = merlin::Transcript::new(b"SchnorrRistrettoHDKD");
t.append_message(b"sign-bytes", i.as_ref());
Expand Down Expand Up @@ -280,6 +317,23 @@ pub struct ExtendedKey<K> {
impl<K: Derivation> ExtendedKey<K> {
/// Derive key with subkey identified by a byte array
/// presented as a hash, and a chain code.
///
/// # Example:
///
/// ```
/// use schnorrkel::{Keypair,derive::{CHAIN_CODE_LENGTH, ChainCode, Derivation, ExtendedKey}};
///
/// let t = merlin::Transcript::new(b"SchnorrRistrettoHDKD");
/// let chaincode = ChainCode([0u8; CHAIN_CODE_LENGTH]); // This is an example. In practice, we should use a random value.
/// let keypair: Keypair = Keypair::generate();
///
/// let extended = ExtendedKey::<Keypair> {key: keypair, chaincode};
/// # let t1 = t.clone();
/// let ExtendedKey {key: extended_derived_keypair, .. } = extended.derived_key(t.clone());
/// # let (derived_keypair, _) = extended.key.derived_key(t1, extended.chaincode);
/// # assert_eq!(derived_keypair.public, extended_derived_keypair.public);
/// # assert_eq!(derived_keypair.secret, extended_derived_keypair.secret);
/// ```
pub fn derived_key<T>(&self, t: T) -> ExtendedKey<K>
where
T: SigningTranscript,
Expand Down

0 comments on commit b1bb201

Please sign in to comment.