Declare `NonHardenedChildIndex` struct

This commit is contained in:
Andrew Arnott 2024-02-10 11:44:04 -07:00
parent 3cbc4815b6
commit 1733af8718
No known key found for this signature in database
GPG Key ID: 48F18646D6868924
2 changed files with 50 additions and 1 deletions

View File

@ -7,6 +7,7 @@ and this library adheres to Rust's notion of
## [Unreleased]
### Added
- `legacy::keys::NonHardenedChildIndex`
- Dependency on `bellman 0.14`.
- `zcash_primitives::consensus::sapling_zip212_enforcement`
- `zcash_primitives::transaction`:

View File

@ -6,6 +6,7 @@ use hdwallet::{
};
use secp256k1::PublicKey;
use sha2::{Digest, Sha256};
use subtle::{Choice, ConstantTimeEq};
use zcash_spec::PrfExpand;
use crate::{consensus, zip32::AccountId};
@ -291,9 +292,39 @@ impl ExternalOvk {
}
}
/// A child index for a derived transparent address.
///
/// Only NON-hardened derivation is supported.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct NonHardenedChildIndex(u32);
impl ConstantTimeEq for NonHardenedChildIndex {
fn ct_eq(&self, other: &Self) -> Choice {
self.0.ct_eq(&other.0)
}
}
impl NonHardenedChildIndex {
/// Parses the given ZIP 32 child index.
///
/// Returns `None` if the hardened bit is set.
pub fn from_index(i: u32) -> Option<Self> {
if i < (1 << 31) {
Some(NonHardenedChildIndex(i))
} else {
None
}
}
/// Returns the index as a 32-bit integer.
pub fn index(&self) -> u32 {
self.0
}
}
#[cfg(test)]
mod tests {
use super::AccountPubKey;
use super::{AccountPubKey, NonHardenedChildIndex};
#[test]
fn check_ovk_test_vectors() {
@ -540,4 +571,21 @@ mod tests {
assert_eq!(tv.external_ovk, external.as_bytes());
}
}
#[test]
fn nonhardened_indexes_accepted() {
assert_eq!(0, NonHardenedChildIndex::from_index(0).unwrap().index());
assert_eq!(
0x7fffffff,
NonHardenedChildIndex::from_index(0x7fffffff)
.unwrap()
.index()
);
}
#[test]
fn hardened_indexes_rejected() {
assert!(NonHardenedChildIndex::from_index(0x80000000).is_none());
assert!(NonHardenedChildIndex::from_index(0xffffffff).is_none());
}
}