Impl From<SpendingKey> for Diversifier
This is the _DefaultDiversifier_ method.
This commit is contained in:
parent
16f1e3061f
commit
ba3ba6d2d9
|
@ -56,13 +56,13 @@ pub const RANDOMNESS_BEACON_URS: &[u8; 64] =
|
|||
/// PRF^expand(sk, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || t)
|
||||
///
|
||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||
fn prf_expand(sk: [u8; 32], t: u8) -> [u8; 64] {
|
||||
fn prf_expand(sk: [u8; 32], t: &[u8]) -> [u8; 64] {
|
||||
let hash = blake2b_simd::Params::new()
|
||||
.hash_length(64)
|
||||
.personal(b"Zcash_ExpandSeed")
|
||||
.to_state()
|
||||
.update(&sk[..])
|
||||
.update(&[t])
|
||||
.update(t)
|
||||
.finalize();
|
||||
|
||||
*hash.as_array()
|
||||
|
@ -278,7 +278,7 @@ impl From<SpendingKey> for SpendAuthorizingKey {
|
|||
/// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
|
||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||
fn from(spending_key: SpendingKey) -> SpendAuthorizingKey {
|
||||
let hash_bytes = prf_expand(spending_key.bytes, 0);
|
||||
let hash_bytes = prf_expand(spending_key.bytes, &[0]);
|
||||
|
||||
Self(Scalar::from_bytes_wide(&hash_bytes))
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ impl From<SpendingKey> for ProofAuthorizingKey {
|
|||
/// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
|
||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||
fn from(spending_key: SpendingKey) -> ProofAuthorizingKey {
|
||||
let hash_bytes = prf_expand(spending_key.bytes, 1);
|
||||
let hash_bytes = prf_expand(spending_key.bytes, &[1]);
|
||||
|
||||
Self(Scalar::from_bytes_wide(&hash_bytes))
|
||||
}
|
||||
|
@ -356,7 +356,7 @@ impl From<SpendingKey> for OutgoingViewingKey {
|
|||
/// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
|
||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||
fn from(spending_key: SpendingKey) -> OutgoingViewingKey {
|
||||
let hash_bytes = prf_expand(spending_key.bytes, 2);
|
||||
let hash_bytes = prf_expand(spending_key.bytes, &[2]);
|
||||
|
||||
let mut bytes = [0u8; 32];
|
||||
bytes[..].copy_from_slice(&hash_bytes[0..32]);
|
||||
|
@ -592,8 +592,6 @@ impl std::str::FromStr for IncomingViewingKey {
|
|||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
pub struct Diversifier(pub [u8; 11]);
|
||||
|
||||
// TODO: _DefaultDiversifier_
|
||||
|
||||
impl fmt::Debug for Diversifier {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_tuple("Diversifier")
|
||||
|
@ -602,6 +600,35 @@ impl fmt::Debug for Diversifier {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<SpendingKey> for Diversifier {
|
||||
/// Derives a [_default diversifier_][4.2.2] from a SpendingKey.
|
||||
///
|
||||
/// 'For each spending key, there is also a default diversified
|
||||
/// payment address with a “random-looking” diversifier. This
|
||||
/// allows an implementation that does not expose diversified
|
||||
/// addresses as a user-visible feature, to use a default address
|
||||
/// that cannot be distinguished (without knowledge of the
|
||||
/// spending key) from one with a random diversifier...'
|
||||
///
|
||||
/// [4.2.2]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
|
||||
fn from(sk: SpendingKey) -> Diversifier {
|
||||
let mut i = 0u8;
|
||||
|
||||
loop {
|
||||
let mut d_bytes = [0u8; 11];
|
||||
d_bytes[..].copy_from_slice(&prf_expand(sk.bytes, &[3, i])[..11]);
|
||||
|
||||
if diversify_hash(d_bytes).is_some() {
|
||||
break Self(d_bytes);
|
||||
}
|
||||
|
||||
assert!(i < 255);
|
||||
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Diversifier {
|
||||
/// Generate a new _Diversifier_ that has already been confirmed
|
||||
/// as a preimage to a valid diversified base point when used to
|
||||
|
@ -613,7 +640,6 @@ impl Diversifier {
|
|||
where
|
||||
T: RngCore + CryptoRng,
|
||||
{
|
||||
// Is this loop overkill?
|
||||
loop {
|
||||
let mut bytes = [0u8; 11];
|
||||
csprng.fill_bytes(&mut bytes);
|
||||
|
|
|
@ -82,9 +82,7 @@ mod tests {
|
|||
IncomingViewingKey::from((authorizing_key, nullifier_deriving_key));
|
||||
assert_eq!(incoming_viewing_key.scalar.to_bytes(), test_vector.ivk);
|
||||
|
||||
// TODO: replace with _DefaultDiversifier_ with spending
|
||||
// key bytes as input.
|
||||
let diversifier = Diversifier(test_vector.default_d);
|
||||
let diversifier = Diversifier::from(spending_key);
|
||||
assert_eq!(diversifier.0, test_vector.default_d);
|
||||
|
||||
let transmission_key = TransmissionKey::from(incoming_viewing_key, diversifier);
|
||||
|
|
Loading…
Reference in New Issue