Update ivk derivation to match latest protocol spec draft

This commit is contained in:
Jack Grigg 2021-03-16 09:33:07 +13:00
parent e0b40cb3cb
commit 46bf89c122
3 changed files with 14 additions and 10 deletions

View File

@ -1,4 +1,4 @@
//! Constants used in the Orchard protocol.
/// $\ell^\mathsf{Orchard}_\mathsf{scalar}$
pub(crate) const L_ORCHARD_SCALAR: usize = 255;
/// $\ell^\mathsf{Orchard}_\mathsf{base}$
pub(crate) const L_ORCHARD_BASE: usize = 255;

View File

@ -13,7 +13,8 @@ use crate::{
address::Address,
primitives::redpallas::{self, SpendAuth},
spec::{
commit_ivk, diversify_hash, ka_orchard, prf_expand, prf_expand_vec, to_base, to_scalar,
commit_ivk, diversify_hash, extract_p, ka_orchard, prf_expand, prf_expand_vec, to_base,
to_scalar,
},
};
@ -80,6 +81,8 @@ impl From<&SpendingKey> for SpendAuthorizingKey {
/// A key used to validate spend authorization signatures.
///
/// Defined in [Zcash Protocol Spec § 4.2.3: Orchard Key Components][orchardkeycomponents].
/// Note that this is $\mathsf{ak}^\mathbb{P}$, which by construction is equivalent to
/// $\mathsf{ak}$ but stored here as a RedPallas verification key.
///
/// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
#[derive(Debug)]
@ -262,7 +265,7 @@ pub struct IncomingViewingKey(pallas::Scalar);
impl From<&FullViewingKey> for IncomingViewingKey {
fn from(fvk: &FullViewingKey) -> Self {
let ak = pallas::Point::from_bytes(&(&fvk.ak.0).into()).unwrap();
let ak = extract_p(&pallas::Point::from_bytes(&(&fvk.ak.0).into()).unwrap());
IncomingViewingKey(commit_ivk(&ak, &fvk.nk.0, &fvk.rivk.0))
}
}

View File

@ -2,16 +2,15 @@
use std::iter;
use bitvec::{array::BitArray, order::Lsb0};
use blake2b_simd::Params;
use ff::PrimeField;
use group::{Curve, Group, GroupEncoding};
use group::{Curve, Group};
use halo2::{
arithmetic::{CurveAffine, CurveExt, FieldExt},
pasta::pallas,
};
use crate::{constants::L_ORCHARD_SCALAR, primitives::sinsemilla};
use crate::{constants::L_ORCHARD_BASE, primitives::sinsemilla};
const PRF_EXPAND_PERSONALIZATION: &[u8; 16] = b"Zcash_ExpandSeed";
@ -37,15 +36,17 @@ pub(crate) fn to_scalar(x: [u8; 64]) -> pallas::Scalar {
///
/// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
pub(crate) fn commit_ivk(
ak: &pallas::Point,
ak: &pallas::Base,
nk: &pallas::Base,
rivk: &pallas::Scalar,
) -> pallas::Scalar {
// We rely on the API contract that to_le_bits() returns at least PrimeField::NUM_BITS
// bits, which is equal to L_ORCHARD_BASE.
let ivk = sinsemilla::short_commit(
"z.cash:Orchard-CommitIvk",
iter::empty()
.chain(BitArray::<Lsb0, _>::new(ak.to_bytes()).iter().by_val())
.chain(nk.to_le_bits().iter().by_val().take(L_ORCHARD_SCALAR)),
.chain(ak.to_le_bits().iter().by_val().take(L_ORCHARD_BASE))
.chain(nk.to_le_bits().iter().by_val().take(L_ORCHARD_BASE)),
rivk,
);