mirror of https://github.com/zcash/orchard.git
Update ivk derivation to match latest protocol spec draft
This commit is contained in:
parent
e0b40cb3cb
commit
46bf89c122
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
13
src/spec.rs
13
src/spec.rs
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue