Make pk_d validity an invariant of PaymentAddress

Introduces a PaymentAddress::from_parts constructor, and getters for
the diversifier and pk_d fields (which are now private).
This commit is contained in:
Jack Grigg
2019-08-23 23:08:09 +01:00
parent 86142d044c
commit abbd43ff57
9 changed files with 85 additions and 62 deletions

View File

@@ -94,10 +94,10 @@ impl<E: JubjubEngine> ViewingKey<E> {
diversifier: Diversifier,
params: &E::Params,
) -> Option<PaymentAddress<E>> {
diversifier.g_d(params).map(|g_d| {
diversifier.g_d(params).and_then(|g_d| {
let pk_d = g_d.mul(self.ivk(), params);
PaymentAddress { pk_d, diversifier }
PaymentAddress::from_parts(diversifier, pk_d)
})
}
}
@@ -118,10 +118,16 @@ impl Diversifier {
}
}
/// A Sapling payment address.
///
/// # Invariants
///
/// `pk_d` is guaranteed to be prime-order (i.e. in the prime-order subgroup of Jubjub,
/// and not the identity).
#[derive(Clone, Debug)]
pub struct PaymentAddress<E: JubjubEngine> {
pub pk_d: edwards::Point<E, PrimeOrder>,
pub diversifier: Diversifier,
pk_d: edwards::Point<E, PrimeOrder>,
diversifier: Diversifier,
}
impl<E: JubjubEngine> PartialEq for PaymentAddress<E> {
@@ -131,6 +137,20 @@ impl<E: JubjubEngine> PartialEq for PaymentAddress<E> {
}
impl<E: JubjubEngine> PaymentAddress<E> {
/// Constructs a PaymentAddress from a diversifier and a Jubjub point.
///
/// Returns None if `pk_d` is the identity.
pub fn from_parts(
diversifier: Diversifier,
pk_d: edwards::Point<E, PrimeOrder>,
) -> Option<Self> {
if pk_d == edwards::Point::zero() {
None
} else {
Some(PaymentAddress { pk_d, diversifier })
}
}
/// Parses a PaymentAddress from bytes.
pub fn from_bytes(bytes: &[u8; 43], params: &E::Params) -> Option<Self> {
let diversifier = {
@@ -146,13 +166,7 @@ impl<E: JubjubEngine> PaymentAddress<E> {
edwards::Point::<E, _>::read(&bytes[11..43], params)
.ok()?
.as_prime_order(params)
.and_then(|pk_d| {
if pk_d == edwards::Point::zero() {
None
} else {
Some(PaymentAddress { pk_d, diversifier })
}
})
.and_then(|pk_d| PaymentAddress::from_parts(diversifier, pk_d))
}
/// Returns the byte encoding of this `PaymentAddress`.
@@ -163,6 +177,16 @@ impl<E: JubjubEngine> PaymentAddress<E> {
bytes
}
/// Returns the [`Diversifier`] for this `PaymentAddress`.
pub fn diversifier(&self) -> &Diversifier {
&self.diversifier
}
/// Returns `pk_d` for this `PaymentAddress`.
pub fn pk_d(&self) -> &edwards::Point<E, PrimeOrder> {
&self.pk_d
}
pub fn g_d(&self, params: &E::Params) -> Option<edwards::Point<E, PrimeOrder>> {
self.diversifier.g_d(params)
}