Compare commits
12 Commits
176470ef41
...
0aff4887a2
Author | SHA1 | Date |
---|---|---|
str4d | 0aff4887a2 | |
Jack Grigg | a449126293 | |
str4d | 3e762d416e | |
Jack Grigg | ceb970c211 | |
Jack Grigg | 4365a10003 | |
Jack Grigg | 6a0c9639af | |
Jack Grigg | ce3830f277 | |
Jack Grigg | ea3e731868 | |
Jack Grigg | feea7316ea | |
Jack Grigg | e512159fed | |
str4d | b735e0817f | |
Jack Grigg | 69adc6df83 |
|
@ -0,0 +1,10 @@
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: daily
|
||||||
|
timezone: Etc/UTC
|
||||||
|
open-pull-requests-limit: 10
|
||||||
|
labels:
|
||||||
|
- "A-CI"
|
|
@ -0,0 +1,79 @@
|
||||||
|
name: CI checks
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test on ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Run tests
|
||||||
|
run: cargo test --all-features --verbose
|
||||||
|
- name: Verify working directory is clean
|
||||||
|
run: git diff --exit-code
|
||||||
|
|
||||||
|
build-latest:
|
||||||
|
name: Latest build on ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
id: toolchain
|
||||||
|
- run: rustup override set ${{steps.toolchain.outputs.name}}
|
||||||
|
- name: Remove lockfile to build with latest dependencies
|
||||||
|
run: rm Cargo.lock
|
||||||
|
- name: Build crate
|
||||||
|
run: cargo build --all-targets --all-features --verbose
|
||||||
|
- name: Verify working directory is clean (excluding lockfile)
|
||||||
|
run: git diff --exit-code ':!Cargo.lock'
|
||||||
|
|
||||||
|
build-nodefault:
|
||||||
|
name: Build target ${{ matrix.target }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
target:
|
||||||
|
- wasm32-wasi
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Add target
|
||||||
|
run: rustup target add ${{ matrix.target }}
|
||||||
|
- name: Build crate
|
||||||
|
run: cargo build --no-default-features --verbose --target ${{ matrix.target }}
|
||||||
|
|
||||||
|
clippy:
|
||||||
|
name: Clippy (MSRV)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Run Clippy
|
||||||
|
uses: auguwu/clippy-action@1.3.0
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
working-directory: ${{ inputs.target }}
|
||||||
|
deny: warnings
|
||||||
|
|
||||||
|
doc-links:
|
||||||
|
name: Intra-doc links
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: cargo fetch
|
||||||
|
# Requires #![deny(rustdoc::broken_intra_doc_links)] in crate.
|
||||||
|
- name: Check intra-doc links
|
||||||
|
run: cargo doc --all-features --document-private-items
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
name: Rustfmt
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check formatting
|
||||||
|
run: cargo fmt -- --check
|
|
@ -1,3 +1,2 @@
|
||||||
/target
|
/target
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
Cargo.lock
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayref"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "assert_matches"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blake2b_simd"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc"
|
||||||
|
dependencies = [
|
||||||
|
"arrayref",
|
||||||
|
"arrayvec",
|
||||||
|
"constant_time_eq",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "constant_time_eq"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memuse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zip32"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"assert_matches",
|
||||||
|
"blake2b_simd",
|
||||||
|
"memuse",
|
||||||
|
"subtle",
|
||||||
|
]
|
33
Cargo.toml
33
Cargo.toml
|
@ -2,26 +2,25 @@
|
||||||
name = "zip32"
|
name = "zip32"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
authors = [
|
authors = [
|
||||||
"Jack Grigg <jack@z.cash>",
|
"Jack Grigg <jack@electriccoin.co>",
|
||||||
|
"Kris Nuttycombe <kris@electriccoin.co>",
|
||||||
]
|
]
|
||||||
license = "MIT/Apache-2.0"
|
description = "Common types for implementing shielded hierarchical deterministic wallets"
|
||||||
|
|
||||||
description = "Library for implementing shielded hierarchical deterministic wallets"
|
|
||||||
documentation = "https://docs.rs/zip32/"
|
documentation = "https://docs.rs/zip32/"
|
||||||
homepage = "https://github.com/zcash-hackworks/zip32"
|
homepage = "https://github.com/zcash/zip32"
|
||||||
repository = "https://github.com/zcash-hackworks/zip32"
|
repository = "https://github.com/zcash/zip32"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.60"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aes = "0.2"
|
blake2b_simd = "1"
|
||||||
byteorder = "1"
|
memuse = "0.2.1"
|
||||||
fpe = "0.1"
|
subtle = "2.2.3"
|
||||||
lazy_static = "1.0"
|
|
||||||
pairing = "0.14.2"
|
|
||||||
|
|
||||||
[dependencies.blake2-rfc]
|
[dev-dependencies]
|
||||||
git = "https://github.com/gtank/blake2-rfc"
|
assert_matches = "1.5"
|
||||||
rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
|
||||||
|
|
||||||
[dependencies.sapling-crypto]
|
[features]
|
||||||
git = "https://github.com/zcash-hackworks/sapling-crypto"
|
default = ["std"]
|
||||||
rev = "21084bde2019c04bd34208e63c3560fe2c02fb0e"
|
std = []
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "1.60.0"
|
||||||
|
components = ["clippy", "rustfmt"]
|
|
@ -0,0 +1,83 @@
|
||||||
|
//! Seed Fingerprints according to ZIP 32
|
||||||
|
//!
|
||||||
|
//! Implements section [Seed Fingerprints] of Shielded Hierarchical Deterministic Wallets (ZIP 32).
|
||||||
|
//!
|
||||||
|
//! [Seed Fingerprints]: https://zips.z.cash/zip-0032#seed-fingerprints
|
||||||
|
use blake2b_simd::Params as Blake2bParams;
|
||||||
|
|
||||||
|
const ZIP32_SEED_FP_PERSONALIZATION: &[u8; 16] = b"Zcash_HD_Seed_FP";
|
||||||
|
|
||||||
|
/// The fingerprint for a wallet's seed bytes, as defined in [ZIP 32].
|
||||||
|
///
|
||||||
|
/// [ZIP 32]: https://zips.z.cash/zip-0032#seed-fingerprints
|
||||||
|
pub struct SeedFingerprint([u8; 32]);
|
||||||
|
|
||||||
|
impl SeedFingerprint {
|
||||||
|
/// Derives the fingerprint of the given seed bytes.
|
||||||
|
///
|
||||||
|
/// Returns `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: [u8; 32],
|
||||||
|
fingerprint: [u8; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
let test_vectors = [TestVector {
|
||||||
|
root_seed: [
|
||||||
|
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: [
|
||||||
|
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 = [
|
||||||
|
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`"
|
||||||
|
);
|
||||||
|
}
|
1361
src/lib.rs
1361
src/lib.rs
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue