From b1bb2010e144a7c5ecd3f7b351ba2ad436c97c55 Mon Sep 17 00:00:00 2001 From: Alex Pinto Date: Sun, 11 Aug 2024 22:31:42 +0100 Subject: [PATCH] Adds example docs and doc-tests for derived_key() and derived_key_simple() --- src/derive.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/derive.rs b/src/derive.rs index 3204f5d..b602e58 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -54,6 +54,30 @@ 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(&self, t: T, cc: ChainCode) -> (Self, ChainCode) where T: SigningTranscript; @@ -61,6 +85,19 @@ pub trait Derivation: Sized { /// 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>(&self, cc: ChainCode, i: B) -> (Self, ChainCode) { let mut t = merlin::Transcript::new(b"SchnorrRistrettoHDKD"); t.append_message(b"sign-bytes", i.as_ref()); @@ -280,6 +317,23 @@ pub struct ExtendedKey { impl ExtendedKey { /// 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:: {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(&self, t: T) -> ExtendedKey where T: SigningTranscript,