Skip to content

Commit

Permalink
zcash_primitives: Add constructor and getter to zip32::ChainCode
Browse files Browse the repository at this point in the history
  • Loading branch information
str4d committed Nov 22, 2023
1 parent 069f771 commit 7e07be6
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 16 deletions.
2 changes: 2 additions & 0 deletions zcash_primitives/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ and this library adheres to Rust's notion of
- `zcash_primitives::zip32`:
- `ChildIndex::hardened`
- `ChildIndex::index`
- `ChainCode::new`
- `ChainCode::as_bytes`
- `impl From<AccountId> for ChildIndex`
- Test helpers, behind the `test-dependencies` feature flag:
- `zcash_primitives::sapling::prover::mock::{MockSpendProver, MockOutputProver}`
Expand Down
12 changes: 9 additions & 3 deletions zcash_primitives/src/zip32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,20 @@ impl ChildIndex {
}
}

/// A BIP-32 chain code
/// A value that is needed, in addition to a spending key, in order to derive descendant
/// keys and addresses of that key.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ChainCode([u8; 32]);

impl ChainCode {
/// Returns byte representation of the chain code, as required for
/// Constructs a `ChainCode` from the given array.
pub fn new(c: [u8; 32]) -> Self {
Self(c)
}

/// Returns the byte representation of the chain code, as required for
/// [ZIP 32](https://zips.z.cash/zip-0032) encoding.
fn as_bytes(&self) -> &[u8; 32] {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
Expand Down
26 changes: 13 additions & 13 deletions zcash_primitives/src/zip32/sapling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ impl ExtendedSpendingKey {
depth: 0,
parent_fvk_tag: FvkTag::master(),
child_index: KeyIndex::Master,
chain_code: ChainCode(c_m),
chain_code: ChainCode::new(c_m),
expsk: ExpandedSpendingKey::from_spending_key(sk_m),
dk: DiversifierKey::master(sk_m),
}
Expand All @@ -328,8 +328,8 @@ impl ExtendedSpendingKey {
let child_index = KeyIndex::new(depth, u32::from_le_bytes(ci_bytes))
.ok_or(DecodingError::UnsupportedChildIndex)?;

let mut chain_code = ChainCode([0u8; 32]);
chain_code.0[..].copy_from_slice(&b[9..41]);
let mut c = [0u8; 32];
c[..].copy_from_slice(&b[9..41]);

let expsk = ExpandedSpendingKey::from_bytes(&b[41..137])?;

Expand All @@ -340,7 +340,7 @@ impl ExtendedSpendingKey {
depth,
parent_fvk_tag,
child_index,
chain_code,
chain_code: ChainCode::new(c),
expsk,
dk,
})
Expand Down Expand Up @@ -370,7 +370,7 @@ impl ExtendedSpendingKey {
depth,
parent_fvk_tag: FvkTag(tag),
child_index,
chain_code: ChainCode(c),
chain_code: ChainCode::new(c),
expsk,
dk: DiversifierKey(dk),
})
Expand Down Expand Up @@ -411,7 +411,7 @@ impl ExtendedSpendingKey {
let mut le_i = [0; 4];
LittleEndian::write_u32(&mut le_i, i.index());
prf_expand_vec(
&self.chain_code.0,
self.chain_code.as_bytes(),
&[&[0x11], &self.expsk.to_bytes(), &self.dk.0, &le_i],
)
};
Expand All @@ -423,7 +423,7 @@ impl ExtendedSpendingKey {
depth: self.depth + 1,
parent_fvk_tag: FvkFingerprint::from(&fvk).tag(),
child_index: KeyIndex::Child(i),
chain_code: ChainCode(c_i),
chain_code: ChainCode::new(c_i),
expsk: {
let mut ask = jubjub::Fr::from_bytes_wide(prf_expand(i_l, &[0x13]).as_array());
let mut nsk = jubjub::Fr::from_bytes_wide(prf_expand(i_l, &[0x14]).as_array());
Expand Down Expand Up @@ -555,7 +555,7 @@ impl ExtendedFullViewingKey {
depth,
parent_fvk_tag: FvkTag(tag),
child_index,
chain_code: ChainCode(c),
chain_code: ChainCode::new(c),
fvk,
dk: DiversifierKey(dk),
})
Expand All @@ -565,7 +565,7 @@ impl ExtendedFullViewingKey {
writer.write_u8(self.depth)?;
writer.write_all(&self.parent_fvk_tag.0)?;
writer.write_u32::<LittleEndian>(self.child_index.index())?;
writer.write_all(&self.chain_code.0)?;
writer.write_all(self.chain_code.as_bytes())?;
writer.write_all(&self.fvk.to_bytes())?;
writer.write_all(&self.dk.0)?;

Expand Down Expand Up @@ -1612,7 +1612,7 @@ mod tests {

assert_eq!(xsk.expsk.ovk.0, tv.ovk);
assert_eq!(xsk.dk.0, tv.dk);
assert_eq!(xsk.chain_code.0, tv.c);
assert_eq!(xsk.chain_code.as_bytes(), &tv.c);

let mut ser = vec![];
xsk.write(&mut ser).unwrap();
Expand All @@ -1627,7 +1627,7 @@ mod tests {

assert_eq!(internal_xsk.expsk.ovk.0, tv.internal_ovk);
assert_eq!(internal_xsk.dk.0, tv.internal_dk);
assert_eq!(internal_xsk.chain_code.0, tv.c);
assert_eq!(internal_xsk.chain_code.as_bytes(), &tv.c);

let mut ser = vec![];
internal_xsk.write(&mut ser).unwrap();
Expand All @@ -1640,7 +1640,7 @@ mod tests {

assert_eq!(xfvk.fvk.ovk.0, tv.ovk);
assert_eq!(xfvk.dk.0, tv.dk);
assert_eq!(xfvk.chain_code.0, tv.c);
assert_eq!(xfvk.chain_code.as_bytes(), &tv.c);

assert_eq!(xfvk.fvk.vk.ivk().to_repr().as_ref(), tv.ivk);

Expand Down Expand Up @@ -1684,7 +1684,7 @@ mod tests {

assert_eq!(internal_xfvk.fvk.ovk.0, tv.internal_ovk);
assert_eq!(internal_xfvk.dk.0, tv.internal_dk);
assert_eq!(internal_xfvk.chain_code.0, tv.c);
assert_eq!(internal_xfvk.chain_code.as_bytes(), &tv.c);

assert_eq!(
internal_xfvk.fvk.vk.ivk().to_repr().as_ref(),
Expand Down

0 comments on commit 7e07be6

Please sign in to comment.