Fix encode/decode of ChildNumber so that hardened keys do not become normal ones
This commit is contained in:
parent
a240d25611
commit
2aeb373e73
|
@ -18,6 +18,7 @@
|
|||
|
||||
use std::default::Default;
|
||||
use std::io::extensions::{u64_to_be_bytes, u64_from_be_bytes};
|
||||
use serialize::{Decoder, Decodable, Encoder, Encodable};
|
||||
|
||||
use crypto::digest::Digest;
|
||||
use crypto::hmac::Hmac;
|
||||
|
@ -84,7 +85,7 @@ pub struct ExtendedPubKey {
|
|||
}
|
||||
|
||||
/// A child number for a derived key
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Show)]
|
||||
#[deriving(Clone, PartialEq, Eq, Show)]
|
||||
pub enum ChildNumber {
|
||||
/// Hardened key index, within [0, 2^31 - 1]
|
||||
Hardened(u32),
|
||||
|
@ -92,6 +93,26 @@ pub enum ChildNumber {
|
|||
Normal(u32),
|
||||
}
|
||||
|
||||
impl<S: Encoder<E>, E> Encodable<S, E> for ChildNumber {
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
match *self {
|
||||
Hardened(n) => (n + (1 << 31)).encode(s),
|
||||
Normal(n) => n.encode(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Decoder<E>, E> Decodable<D, E> for ChildNumber {
|
||||
fn decode(d: &mut D) -> Result<ChildNumber, E> {
|
||||
let n: u32 = try!(Decodable::decode(d));
|
||||
if n < (1 << 31) {
|
||||
Ok(Normal(n))
|
||||
} else {
|
||||
Ok(Hardened(n - (1 << 31)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A BIP32 error
|
||||
#[deriving(Clone, PartialEq, Eq, Show)]
|
||||
pub enum Error {
|
||||
|
@ -476,6 +497,25 @@ mod tests {
|
|||
"xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn encode_decode_childnumber() {
|
||||
use serialize::json;
|
||||
|
||||
let h1 = Hardened(1);
|
||||
let n1 = Normal(1);
|
||||
|
||||
let h1_str = json::encode(&h1);
|
||||
let n1_str = json::encode(&n1);
|
||||
|
||||
assert!(h1 != n1);
|
||||
assert!(h1_str != n1_str);
|
||||
|
||||
let h1_dec = json::decode(h1_str.as_slice()).unwrap();
|
||||
let n1_dec = json::decode(n1_str.as_slice()).unwrap();
|
||||
assert_eq!(h1, h1_dec);
|
||||
assert_eq!(n1, n1_dec);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn generate_sequential_normal_children(bh: &mut Bencher) {
|
||||
let seed = "000102030405060708090a0b0c0d0e0f".from_hex().unwrap();
|
||||
|
|
|
@ -30,6 +30,7 @@ use wallet::bip32::{mod, ChildNumber, ExtendedPrivKey, Normal, Hardened};
|
|||
use wallet::address::Address;
|
||||
|
||||
/// A Wallet error
|
||||
#[deriving(Clone, PartialEq, Eq, Show)]
|
||||
pub enum Error {
|
||||
/// Tried to lookup an account by name, but none was found
|
||||
AccountNotFound,
|
||||
|
@ -97,9 +98,6 @@ impl<S: Encoder<E>, E> Encodable<S, E> for Wallet {
|
|||
}
|
||||
}
|
||||
|
||||
impl Account {
|
||||
}
|
||||
|
||||
impl<D: Decoder<E>, E> Decodable<D, E> for Wallet {
|
||||
fn decode(d: &mut D) -> Result<Wallet, E> {
|
||||
d.read_struct("wallet", 2, |d| {
|
||||
|
|
Loading…
Reference in New Issue