[keys] Less convoluted entropy generation
Since const generics aren't in rust yet you have to find some awkward workarounds. This improves the workaround for specifying entropy length.
This commit is contained in:
parent
eae15563d8
commit
490c88934e
@ -77,14 +77,14 @@ impl<Ctx: ScriptContext> DerivableKey<Ctx> for Mnemonic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Mnemonic {
|
impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Mnemonic {
|
||||||
const ENTROPY_LENGTH: usize = 32;
|
type Entropy = [u8; 32];
|
||||||
|
|
||||||
type Options = (MnemonicType, Language);
|
type Options = (MnemonicType, Language);
|
||||||
type Error = Option<bip39::ErrorKind>;
|
type Error = Option<bip39::ErrorKind>;
|
||||||
|
|
||||||
fn generate_with_entropy<E: AsRef<[u8]>>(
|
fn generate_with_entropy(
|
||||||
(mnemonic_type, language): Self::Options,
|
(mnemonic_type, language): Self::Options,
|
||||||
entropy: E,
|
entropy: Self::Entropy,
|
||||||
) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
|
) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
|
||||||
let entropy = &entropy.as_ref()[..(mnemonic_type.entropy_bits() / 8)];
|
let entropy = &entropy.as_ref()[..(mnemonic_type.entropy_bits() / 8)];
|
||||||
let mnemonic = Mnemonic::from_entropy(entropy, language).map_err(|e| e.downcast().ok())?;
|
let mnemonic = Mnemonic::from_entropy(entropy, language).map_err(|e| e.downcast().ok())?;
|
||||||
|
@ -370,8 +370,8 @@ where
|
|||||||
/// This trait is particularly useful when combined with [`DerivableKey`]: if `Self`
|
/// This trait is particularly useful when combined with [`DerivableKey`]: if `Self`
|
||||||
/// implements it, the returned [`GeneratedKey`] will also implement it.
|
/// implements it, the returned [`GeneratedKey`] will also implement it.
|
||||||
pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
|
pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
|
||||||
/// Lenght in bytes of the required entropy
|
/// Type specifying the amount of entropy required e.g. [u8;32]
|
||||||
const ENTROPY_LENGTH: usize;
|
type Entropy: AsMut<[u8]> + Default;
|
||||||
|
|
||||||
/// Extra options required by the `generate_with_entropy`
|
/// Extra options required by the `generate_with_entropy`
|
||||||
type Options;
|
type Options;
|
||||||
@ -379,37 +379,32 @@ pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
|
|||||||
type Error: std::fmt::Debug;
|
type Error: std::fmt::Debug;
|
||||||
|
|
||||||
/// Generate a key given the extra options and the entropy
|
/// Generate a key given the extra options and the entropy
|
||||||
fn generate_with_entropy<E: AsRef<[u8]>>(
|
fn generate_with_entropy(
|
||||||
options: Self::Options,
|
options: Self::Options,
|
||||||
entropy: E,
|
entropy: Self::Entropy,
|
||||||
) -> Result<GeneratedKey<Self, Ctx>, Self::Error>;
|
) -> Result<GeneratedKey<Self, Ctx>, Self::Error>;
|
||||||
|
|
||||||
/// Generate a key given the options with a random entropy
|
/// Generate a key given the options with a random entropy
|
||||||
fn generate(options: Self::Options) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
|
fn generate(options: Self::Options) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
let mut entropy = Vec::<u8>::with_capacity(Self::ENTROPY_LENGTH);
|
let mut entropy = Self::Entropy::default();
|
||||||
for _ in 0..Self::ENTROPY_LENGTH {
|
thread_rng().fill(entropy.as_mut());
|
||||||
entropy.push(0x00);
|
Self::generate_with_entropy(options, entropy)
|
||||||
}
|
|
||||||
|
|
||||||
thread_rng().fill(&mut entropy[..Self::ENTROPY_LENGTH]);
|
|
||||||
|
|
||||||
Self::generate_with_entropy(options, &entropy)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Ctx: ScriptContext> GeneratableKey<Ctx> for bip32::ExtendedPrivKey {
|
impl<Ctx: ScriptContext> GeneratableKey<Ctx> for bip32::ExtendedPrivKey {
|
||||||
const ENTROPY_LENGTH: usize = 32;
|
type Entropy = [u8; 32];
|
||||||
|
|
||||||
type Options = ();
|
type Options = ();
|
||||||
type Error = bip32::Error;
|
type Error = bip32::Error;
|
||||||
|
|
||||||
fn generate_with_entropy<E: AsRef<[u8]>>(
|
fn generate_with_entropy(
|
||||||
_: Self::Options,
|
_: Self::Options,
|
||||||
entropy: E,
|
entropy: Self::Entropy,
|
||||||
) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
|
) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
|
||||||
// pick a random network here, but say that we support all of them
|
// pick a arbitrary network here, but say that we support all of them
|
||||||
let xprv = bip32::ExtendedPrivKey::new_master(Network::Bitcoin, entropy.as_ref())?;
|
let xprv = bip32::ExtendedPrivKey::new_master(Network::Bitcoin, entropy.as_ref())?;
|
||||||
Ok(GeneratedKey::new(xprv, any_network()))
|
Ok(GeneratedKey::new(xprv, any_network()))
|
||||||
}
|
}
|
||||||
@ -567,14 +562,12 @@ pub mod test {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub fn get_test_entropy() -> Vec<u8> {
|
const test_entropy: [u8; 32] = [0xAA; 32];
|
||||||
[0xAA; 32].to_vec()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_keys_generate_xprv() {
|
fn test_keys_generate_xprv() {
|
||||||
let generated_xprv: GeneratedKey<_, miniscript::Segwitv0> =
|
let generated_xprv: GeneratedKey<_, miniscript::Segwitv0> =
|
||||||
bip32::ExtendedPrivKey::generate_with_entropy((), get_test_entropy()).unwrap();
|
bip32::ExtendedPrivKey::generate_with_entropy((), test_entropy).unwrap();
|
||||||
|
|
||||||
assert_eq!(generated_xprv.valid_networks, any_network());
|
assert_eq!(generated_xprv.valid_networks, any_network());
|
||||||
assert_eq!(generated_xprv.to_string(), "xprv9s21ZrQH143K4Xr1cJyqTvuL2FWR8eicgY9boWqMBv8MDVUZ65AXHnzBrK1nyomu6wdcabRgmGTaAKawvhAno1V5FowGpTLVx3jxzE5uk3Q");
|
assert_eq!(generated_xprv.to_string(), "xprv9s21ZrQH143K4Xr1cJyqTvuL2FWR8eicgY9boWqMBv8MDVUZ65AXHnzBrK1nyomu6wdcabRgmGTaAKawvhAno1V5FowGpTLVx3jxzE5uk3Q");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user