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:
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user