mirror of https://github.com/zcash/zip32.git
Merge pull request #3 from zcash-hackworks/generalized-refactor
Bring in refactor of the crate
This commit is contained in:
commit
b735e0817f
25
Cargo.toml
25
Cargo.toml
|
@ -2,26 +2,21 @@
|
|||
name = "zip32"
|
||||
version = "0.0.0"
|
||||
authors = [
|
||||
"Jack Grigg <jack@z.cash>",
|
||||
"Jack Grigg <jack@electriccoin.co>",
|
||||
"Kris Nuttycombe <kris@electriccoin.co>",
|
||||
]
|
||||
license = "MIT/Apache-2.0"
|
||||
|
||||
description = "Library for implementing shielded hierarchical deterministic wallets"
|
||||
documentation = "https://docs.rs/zip32/"
|
||||
homepage = "https://github.com/zcash-hackworks/zip32"
|
||||
repository = "https://github.com/zcash-hackworks/zip32"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.65"
|
||||
|
||||
[dependencies]
|
||||
aes = "0.2"
|
||||
byteorder = "1"
|
||||
fpe = "0.1"
|
||||
lazy_static = "1.0"
|
||||
pairing = "0.14.2"
|
||||
blake2b_simd = "1"
|
||||
memuse = "0.2.1"
|
||||
subtle = "2.2.3"
|
||||
|
||||
[dependencies.blake2-rfc]
|
||||
git = "https://github.com/gtank/blake2-rfc"
|
||||
rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
||||
|
||||
[dependencies.sapling-crypto]
|
||||
git = "https://github.com/zcash-hackworks/sapling-crypto"
|
||||
rev = "21084bde2019c04bd34208e63c3560fe2c02fb0e"
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5"
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
//! Seed Fingerprints according to ZIP 32
|
||||
//!
|
||||
//! Implements section `Seed Fingerprints` of Shielded Hierarchical Deterministic Wallets (ZIP 32)
|
||||
//!
|
||||
//! [Section Seed Fingerprints]: https://zips.z.cash/zip-0032#seed-fingerprints
|
||||
use blake2b_simd::Params as Blake2bParams;
|
||||
|
||||
pub const ZIP32_SEED_FP_PERSONALIZATION: &[u8; 16] = b"Zcash_HD_Seed_FP";
|
||||
pub struct SeedFingerprint([u8; 32]);
|
||||
|
||||
impl SeedFingerprint {
|
||||
/// Return the seed fingerprint of the wallet as defined in
|
||||
/// <https://zips.z.cash/zip-0032#seed-fingerprints> or None
|
||||
/// if the length of `seed_bytes` is less than 32 or
|
||||
/// greater than 252.
|
||||
pub fn from_seed(seed_bytes: &[u8]) -> Option<SeedFingerprint> {
|
||||
let seed_len = seed_bytes.len();
|
||||
|
||||
if (32..=252).contains(&seed_len) {
|
||||
let seed_len: u8 = seed_len.try_into().unwrap();
|
||||
Some(SeedFingerprint(
|
||||
Blake2bParams::new()
|
||||
.hash_length(32)
|
||||
.personal(ZIP32_SEED_FP_PERSONALIZATION)
|
||||
.to_state()
|
||||
.update(&[seed_len])
|
||||
.update(seed_bytes)
|
||||
.finalize()
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("hash length should be 32 bytes"),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the fingerprint as a byte array.
|
||||
pub fn to_bytes(&self) -> [u8; 32] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_seed_fingerprint() {
|
||||
struct TestVector {
|
||||
root_seed: Vec<u8>,
|
||||
fingerprint: Vec<u8>,
|
||||
}
|
||||
|
||||
let test_vectors = vec![TestVector {
|
||||
root_seed: vec![
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
|
||||
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
|
||||
0x1c, 0x1d, 0x1e, 0x1f,
|
||||
],
|
||||
fingerprint: vec![
|
||||
0xde, 0xff, 0x60, 0x4c, 0x24, 0x67, 0x10, 0xf7, 0x17, 0x6d, 0xea, 0xd0, 0x2a, 0xa7,
|
||||
0x46, 0xf2, 0xfd, 0x8d, 0x53, 0x89, 0xf7, 0x7, 0x25, 0x56, 0xdc, 0xb5, 0x55, 0xfd,
|
||||
0xbe, 0x5e, 0x3a, 0xe3,
|
||||
],
|
||||
}];
|
||||
|
||||
for tv in test_vectors {
|
||||
let fp = SeedFingerprint::from_seed(&tv.root_seed).expect("root_seed has valid length");
|
||||
assert_eq!(&fp.to_bytes(), &tv.fingerprint[..]);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_seed_fingerprint_is_none() {
|
||||
let odd_seed = vec![
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
||||
0x0f,
|
||||
];
|
||||
|
||||
assert!(
|
||||
SeedFingerprint::from_seed(&odd_seed).is_none(),
|
||||
"fingerprint from short seed should be `None`"
|
||||
);
|
||||
}
|
1303
src/lib.rs
1303
src/lib.rs
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue