Impl Display/FromStr for Sapling IncomingViewingKey, including network field
This commit is contained in:
parent
cdfcdc4751
commit
68c281c590
|
@ -394,6 +394,14 @@ impl From<ProofAuthorizingKey> for NullifierDerivingKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Magic human-readable strings used to identify what networks
|
||||||
|
/// Sapling IncomingViewingKeys are associated with when
|
||||||
|
/// encoded/decoded with bech32.
|
||||||
|
mod ivk_hrp {
|
||||||
|
pub const MAINNET: &str = "zivks";
|
||||||
|
pub const TESTNET: &str = "zivktestsapling";
|
||||||
|
}
|
||||||
|
|
||||||
/// An _Incoming Viewing Key_, as described in [protocol specification
|
/// An _Incoming Viewing Key_, as described in [protocol specification
|
||||||
/// §4.2.2][ps].
|
/// §4.2.2][ps].
|
||||||
///
|
///
|
||||||
|
@ -401,13 +409,18 @@ impl From<ProofAuthorizingKey> for NullifierDerivingKey {
|
||||||
///
|
///
|
||||||
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
|
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
pub struct IncomingViewingKey(pub Scalar);
|
pub struct IncomingViewingKey {
|
||||||
|
network: Network,
|
||||||
|
scalar: Scalar,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: impl a From that accepts a Network?
|
||||||
|
|
||||||
impl Deref for IncomingViewingKey {
|
impl Deref for IncomingViewingKey {
|
||||||
type Target = Scalar;
|
type Target = Scalar;
|
||||||
|
|
||||||
fn deref(&self) -> &Scalar {
|
fn deref(&self) -> &Scalar {
|
||||||
&self.0
|
&self.scalar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,6 +432,41 @@ impl fmt::Debug for IncomingViewingKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for IncomingViewingKey {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let hrp = match self.network {
|
||||||
|
Network::Mainnet => ivk_hrp::MAINNET,
|
||||||
|
_ => ivk_hrp::TESTNET,
|
||||||
|
};
|
||||||
|
|
||||||
|
bech32::encode_to_fmt(f, hrp, &self.scalar.to_bytes().to_base32()).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for IncomingViewingKey {
|
||||||
|
type Err = SerializationError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match bech32::decode(s) {
|
||||||
|
Ok((hrp, bytes)) => {
|
||||||
|
let decoded = Vec::<u8>::from_base32(&bytes).unwrap();
|
||||||
|
|
||||||
|
let mut scalar_bytes = [0u8; 32];
|
||||||
|
scalar_bytes[..].copy_from_slice(&decoded[0..32]);
|
||||||
|
|
||||||
|
Ok(IncomingViewingKey {
|
||||||
|
network: match hrp.as_str() {
|
||||||
|
ivk_hrp::MAINNET => Network::Mainnet,
|
||||||
|
_ => Network::Testnet,
|
||||||
|
},
|
||||||
|
scalar: Scalar::from_bytes(&scalar_bytes).unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(_) => Err(SerializationError::Parse("bech32 decoding error")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl IncomingViewingKey {
|
impl IncomingViewingKey {
|
||||||
/// For this invocation of Blake2s-256 as _CRH^ivk_.
|
/// For this invocation of Blake2s-256 as _CRH^ivk_.
|
||||||
///
|
///
|
||||||
|
@ -447,7 +495,10 @@ impl IncomingViewingKey {
|
||||||
// https://github.com/zcash/librustzcash/blob/master/zcash_primitives/src/primitives.rs#L86
|
// https://github.com/zcash/librustzcash/blob/master/zcash_primitives/src/primitives.rs#L86
|
||||||
hash_bytes[31] &= 0b0000_0111;
|
hash_bytes[31] &= 0b0000_0111;
|
||||||
|
|
||||||
Self(Scalar::from_bytes(&hash_bytes).unwrap())
|
Self {
|
||||||
|
network: Network::default(),
|
||||||
|
scalar: Scalar::from_bytes(&hash_bytes).unwrap(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,7 +585,7 @@ impl TransmissionKey {
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
|
/// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
|
||||||
pub fn from(ivk: IncomingViewingKey, d: Diversifier) -> Self {
|
pub fn from(ivk: IncomingViewingKey, d: Diversifier) -> Self {
|
||||||
Self(jubjub::AffinePoint::from(
|
Self(jubjub::AffinePoint::from(
|
||||||
diversify_hash(d.0).unwrap() * ivk.0,
|
diversify_hash(d.0).unwrap() * ivk.scalar,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,13 +709,6 @@ mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn check_deref() {
|
|
||||||
let ivk = IncomingViewingKey(jubjub::Fr::zero());
|
|
||||||
|
|
||||||
ivk.to_bytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn derive() {
|
fn derive() {
|
||||||
let spending_key = SpendingKey::new(&mut OsRng);
|
let spending_key = SpendingKey::new(&mut OsRng);
|
||||||
|
|
Loading…
Reference in New Issue