Replace manual address decoding with PaymentAddress::from_bytes

This commit is contained in:
Jack Grigg 2019-08-03 10:40:09 +01:00
parent b19b40ccf0
commit 73ee19239c
No known key found for this signature in database
GPG Key ID: 9E8255172BBF9898
4 changed files with 37 additions and 36 deletions

View File

@ -112,8 +112,7 @@ extern "C" {
bool librustzcash_sapling_output_proof( bool librustzcash_sapling_output_proof(
void *ctx, void *ctx,
const unsigned char *esk, const unsigned char *esk,
const unsigned char *diversifier, const unsigned char *payment_address,
const unsigned char *pk_d,
const unsigned char *rcm, const unsigned char *rcm,
const uint64_t value, const uint64_t value,
unsigned char *cv, unsigned char *cv,

View File

@ -927,8 +927,7 @@ pub extern "system" fn librustzcash_sprout_verify(
pub extern "system" fn librustzcash_sapling_output_proof( pub extern "system" fn librustzcash_sapling_output_proof(
ctx: *mut SaplingProvingContext, ctx: *mut SaplingProvingContext,
esk: *const [c_uchar; 32], esk: *const [c_uchar; 32],
diversifier: *const [c_uchar; 11], payment_address: *const [c_uchar; 43],
pk_d: *const [c_uchar; 32],
rcm: *const [c_uchar; 32], rcm: *const [c_uchar; 32],
value: u64, value: u64,
cv: *mut [c_uchar; 32], cv: *mut [c_uchar; 32],
@ -940,26 +939,12 @@ pub extern "system" fn librustzcash_sapling_output_proof(
Err(_) => return false, Err(_) => return false,
}; };
// Grab the diversifier from the caller. // Grab the payment address from the caller
let diversifier = Diversifier(unsafe { *diversifier }); let payment_address =
match PaymentAddress::<Bls12>::from_bytes(unsafe { &*payment_address }, &JUBJUB) {
// Grab pk_d from the caller. Some(pa) => pa,
let pk_d = match edwards::Point::<Bls12, Unknown>::read(&(unsafe { &*pk_d })[..], &JUBJUB) { None => return false,
Ok(p) => p, };
Err(_) => return false,
};
// pk_d should be prime order.
let pk_d = match pk_d.as_prime_order(&JUBJUB) {
Some(p) => p,
None => return false,
};
// Construct a payment address
let payment_address = PaymentAddress {
pk_d: pk_d,
diversifier: diversifier,
};
// The caller provides the commitment randomness for the output note // The caller provides the commitment randomness for the output note
let rcm = match Fs::from_repr(read_fs(&(unsafe { &*rcm })[..])) { let rcm = match Fs::from_repr(read_fs(&(unsafe { &*rcm })[..])) {

View File

@ -7,10 +7,7 @@ use bech32::{self, Error, FromBase32, ToBase32};
use pairing::bls12_381::Bls12; use pairing::bls12_381::Bls12;
use std::io::{self, Write}; use std::io::{self, Write};
use zcash_primitives::{ use zcash_primitives::{
jubjub::edwards, primitives::PaymentAddress,
primitives::{Diversifier, PaymentAddress},
};
use zcash_primitives::{
zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}, zip32::{ExtendedFullViewingKey, ExtendedSpendingKey},
JUBJUB, JUBJUB,
}; };
@ -168,17 +165,13 @@ pub fn encode_payment_address(hrp: &str, addr: &PaymentAddress<Bls12>) -> String
/// ``` /// ```
pub fn decode_payment_address(hrp: &str, s: &str) -> Result<Option<PaymentAddress<Bls12>>, Error> { pub fn decode_payment_address(hrp: &str, s: &str) -> Result<Option<PaymentAddress<Bls12>>, Error> {
bech32_decode(hrp, s, |data| { bech32_decode(hrp, s, |data| {
let mut diversifier = Diversifier([0; 11]); if data.len() != 43 {
diversifier.0.copy_from_slice(&data[0..11]);
// Check that the diversifier is valid
if diversifier.g_d::<Bls12>(&JUBJUB).is_none() {
return None; return None;
} }
edwards::Point::<Bls12, _>::read(&data[11..], &JUBJUB) let mut bytes = [0; 43];
.ok()? bytes.copy_from_slice(&data);
.as_prime_order(&JUBJUB) PaymentAddress::<Bls12>::from_bytes(&bytes, &JUBJUB)
.map(|pk_d| PaymentAddress { pk_d, diversifier })
}) })
} }

View File

@ -131,6 +131,30 @@ impl<E: JubjubEngine> PartialEq for PaymentAddress<E> {
} }
impl<E: JubjubEngine> PaymentAddress<E> { impl<E: JubjubEngine> PaymentAddress<E> {
/// Parses a PaymentAddress from bytes.
pub fn from_bytes(bytes: &[u8; 43], params: &E::Params) -> Option<Self> {
let diversifier = {
let mut tmp = [0; 11];
tmp.copy_from_slice(&bytes[0..11]);
Diversifier(tmp)
};
// Check that the diversifier is valid
if diversifier.g_d::<E>(params).is_none() {
return None;
}
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 })
}
})
}
pub fn g_d(&self, params: &E::Params) -> Option<edwards::Point<E, PrimeOrder>> { pub fn g_d(&self, params: &E::Params) -> Option<edwards::Point<E, PrimeOrder>> {
self.diversifier.g_d(params) self.diversifier.g_d(params)
} }