orchard: derive IncomingViewingKey from FullViewingKey

Includes sinsemilla commit and short commit
This commit is contained in:
Deirdre Connolly 2021-03-08 15:45:18 -05:00 committed by Deirdre Connolly
parent 6e1d2f1fb1
commit fd29708ecc
2 changed files with 33 additions and 7 deletions

View File

@ -389,7 +389,7 @@ mod ivk_hrp {
pub const TESTNET: &str = "zivktestorchard";
}
/// An _Incoming Viewing Key_, as described in [protocol specification
/// An incoming viewing key, as described in [protocol specification
/// §4.2.3][ps].
///
/// Used to decrypt incoming notes without spending them.
@ -433,18 +433,23 @@ impl From<[u8; 32]> for IncomingViewingKey {
}
}
impl From<(SpendValidatingKey, NullifierDerivingKey)> for IncomingViewingKey {
/// For this invocation of Blake2s-256 as _CRH^ivk_.
impl From<FullViewingKey> for IncomingViewingKey {
/// Commit^ivk_rivk(ak, nk) :=
/// SinsemillaShortCommit_rcm ("z.cash:Orchard-CommitIvk", I2LEBSP_l(ak) || I2LEBSP_l(nk)) mod r_P
///
/// https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
fn from((ask, nk): (SpendValidatingKey, NullifierDerivingKey)) -> Self {
unimplemented!();
fn from(fvk: FullViewingKey) -> Self {
let M = fvk.ak.into().join(fvk.nk.into());
let hash_bytes = commit_ivk(ask.into(), nk.into());
// Commit^ivk_rivk
let scalar = sinsemilla_short_commit(fvk.ivk.into(), "z.cash:Orchard-CommitIvk", M);
IncomingViewingKey::from(hash_bytes)
Self {
network: Network::default(),
scalar,
}
}
}

View File

@ -105,3 +105,24 @@ pub fn extract_p(point: pallas::Point) -> pallas::Base {
pub fn sinsemilla_hash(D: &[u8], M: &BitVec<Lsb0, u8>) -> pallas::Base {
extract_p(sinsemilla_hash_to_point(D, M))
}
/// Sinsemilla commit
///
/// We construct Sinsemilla commitments by hashing to a point with Sinsemilla
/// hash, and adding a randomized point on the Pallas curve.
///
/// SinsemillaCommit_r(D, M) := SinsemillaHashToPoint(D || "-M", M) + [r]GroupHash^P(D ||“-r”,"")
///
/// https://zips.z.cash/protocol/nu5.pdf#concretesinsemillacommit
#[allow(non_snake_case)]
pub fn sinsemilla_commit(r: pallas::Scalar, D: &[u8], M: &BitVec<Lsb0, u8>) -> pallas::Point {
sinsemilla_hash_to_point(D.join(b"-M"), M) + r * pallas_group_hash(D.join(b"r"), b"")
}
/// SinsemillaShortCommit_r(D, M) := Extract_P(SinsemillaCommit_r(D, M))
///
/// https://zips.z.cash/protocol/nu5.pdf#concretesinsemillacommit
#[allow(non_snake_case)]
pub fn sinsemilla_short_commit(r: pallas::Scalar, D: &[u8], M: &BitVec<Lsb0, u8>) -> pallas::Base {
extract_p(sinsemilla_commit(r, D, M))
}