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)
|
/// PRF^expand(sk, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || t)
|
||||||
///
|
///
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
/// 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()
|
let hash = blake2b_simd::Params::new()
|
||||||
.hash_length(64)
|
.hash_length(64)
|
||||||
.personal(b"Zcash_ExpandSeed")
|
.personal(b"Zcash_ExpandSeed")
|
||||||
.to_state()
|
.to_state()
|
||||||
.update(&sk[..])
|
.update(&sk[..])
|
||||||
.update(&[t])
|
.update(t)
|
||||||
.finalize();
|
.finalize();
|
||||||
|
|
||||||
*hash.as_array()
|
*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#saplingkeycomponents
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||||
fn from(spending_key: SpendingKey) -> SpendAuthorizingKey {
|
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))
|
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#saplingkeycomponents
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||||
fn from(spending_key: SpendingKey) -> ProofAuthorizingKey {
|
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))
|
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#saplingkeycomponents
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||||
fn from(spending_key: SpendingKey) -> OutgoingViewingKey {
|
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];
|
let mut bytes = [0u8; 32];
|
||||||
bytes[..].copy_from_slice(&hash_bytes[0..32]);
|
bytes[..].copy_from_slice(&hash_bytes[0..32]);
|
||||||
|
|
@ -592,8 +592,6 @@ impl std::str::FromStr for IncomingViewingKey {
|
||||||
#[cfg_attr(test, derive(Arbitrary))]
|
#[cfg_attr(test, derive(Arbitrary))]
|
||||||
pub struct Diversifier(pub [u8; 11]);
|
pub struct Diversifier(pub [u8; 11]);
|
||||||
|
|
||||||
// TODO: _DefaultDiversifier_
|
|
||||||
|
|
||||||
impl fmt::Debug for Diversifier {
|
impl fmt::Debug for Diversifier {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_tuple("Diversifier")
|
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 {
|
impl Diversifier {
|
||||||
/// Generate a new _Diversifier_ that has already been confirmed
|
/// Generate a new _Diversifier_ that has already been confirmed
|
||||||
/// as a preimage to a valid diversified base point when used to
|
/// as a preimage to a valid diversified base point when used to
|
||||||
|
|
@ -613,7 +640,6 @@ impl Diversifier {
|
||||||
where
|
where
|
||||||
T: RngCore + CryptoRng,
|
T: RngCore + CryptoRng,
|
||||||
{
|
{
|
||||||
// Is this loop overkill?
|
|
||||||
loop {
|
loop {
|
||||||
let mut bytes = [0u8; 11];
|
let mut bytes = [0u8; 11];
|
||||||
csprng.fill_bytes(&mut bytes);
|
csprng.fill_bytes(&mut bytes);
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,7 @@ mod tests {
|
||||||
IncomingViewingKey::from((authorizing_key, nullifier_deriving_key));
|
IncomingViewingKey::from((authorizing_key, nullifier_deriving_key));
|
||||||
assert_eq!(incoming_viewing_key.scalar.to_bytes(), test_vector.ivk);
|
assert_eq!(incoming_viewing_key.scalar.to_bytes(), test_vector.ivk);
|
||||||
|
|
||||||
// TODO: replace with _DefaultDiversifier_ with spending
|
let diversifier = Diversifier::from(spending_key);
|
||||||
// key bytes as input.
|
|
||||||
let diversifier = Diversifier(test_vector.default_d);
|
|
||||||
assert_eq!(diversifier.0, test_vector.default_d);
|
assert_eq!(diversifier.0, test_vector.default_d);
|
||||||
|
|
||||||
let transmission_key = TransmissionKey::from(incoming_viewing_key, diversifier);
|
let transmission_key = TransmissionKey::from(incoming_viewing_key, diversifier);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue