mirror of https://github.com/zcash/halo2.git
Ensure that derived esk is non-zero
There's a (negligble) chance that we could generate (or be sent adversarially) a RandomSeed which derives esk == 0. It's not hard to detect and reject, in order to satisfy the type system.
This commit is contained in:
parent
8a7ff1b28a
commit
11350339f5
|
@ -558,7 +558,7 @@ mod tests {
|
||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
note::{ExtractedNoteCommitment, Nullifier},
|
note::{ExtractedNoteCommitment, Nullifier, RandomSeed},
|
||||||
value::NoteValue,
|
value::NoteValue,
|
||||||
Note,
|
Note,
|
||||||
};
|
};
|
||||||
|
@ -625,7 +625,7 @@ mod tests {
|
||||||
addr,
|
addr,
|
||||||
NoteValue::from_raw(tv.note_v),
|
NoteValue::from_raw(tv.note_v),
|
||||||
rho,
|
rho,
|
||||||
tv.note_rseed.into(),
|
RandomSeed::from_bytes(tv.note_rseed, &rho).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let cmx: ExtractedNoteCommitment = note.commitment().into();
|
let cmx: ExtractedNoteCommitment = note.commitment().into();
|
||||||
|
|
43
src/note.rs
43
src/note.rs
|
@ -6,7 +6,7 @@ use subtle::CtOption;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
keys::{FullViewingKey, SpendingKey},
|
keys::{FullViewingKey, SpendingKey},
|
||||||
spec::{to_base, to_scalar, PrfExpand},
|
spec::{to_base, to_scalar, NonZeroPallasScalar, PrfExpand},
|
||||||
value::NoteValue,
|
value::NoteValue,
|
||||||
Address,
|
Address,
|
||||||
};
|
};
|
||||||
|
@ -21,17 +21,22 @@ pub use self::nullifier::Nullifier;
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct RandomSeed([u8; 32]);
|
pub(crate) struct RandomSeed([u8; 32]);
|
||||||
|
|
||||||
impl From<[u8; 32]> for RandomSeed {
|
|
||||||
fn from(rseed: [u8; 32]) -> Self {
|
|
||||||
RandomSeed(rseed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RandomSeed {
|
impl RandomSeed {
|
||||||
pub(crate) fn random(rng: &mut impl RngCore) -> Self {
|
pub(crate) fn random(rng: &mut impl RngCore, rho: &Nullifier) -> Self {
|
||||||
let mut bytes = [0; 32];
|
loop {
|
||||||
rng.fill_bytes(&mut bytes);
|
let mut bytes = [0; 32];
|
||||||
RandomSeed(bytes)
|
rng.fill_bytes(&mut bytes);
|
||||||
|
let rseed = RandomSeed::from_bytes(bytes, rho);
|
||||||
|
if rseed.is_some().into() {
|
||||||
|
break rseed.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_bytes(rseed: [u8; 32], rho: &Nullifier) -> CtOption<Self> {
|
||||||
|
let rseed = RandomSeed(rseed);
|
||||||
|
let esk = rseed.esk_inner(rho);
|
||||||
|
CtOption::new(rseed, esk.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
||||||
|
@ -44,8 +49,18 @@ impl RandomSeed {
|
||||||
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
||||||
///
|
///
|
||||||
/// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend
|
/// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend
|
||||||
fn esk(&self, rho: &Nullifier) -> pallas::Scalar {
|
fn esk_inner(&self, rho: &Nullifier) -> CtOption<NonZeroPallasScalar> {
|
||||||
to_scalar(PrfExpand::Esk.with_ad(&self.0, &rho.to_bytes()[..]))
|
NonZeroPallasScalar::from_scalar(to_scalar(
|
||||||
|
PrfExpand::Esk.with_ad(&self.0, &rho.to_bytes()[..]),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
||||||
|
///
|
||||||
|
/// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend
|
||||||
|
fn esk(&self, rho: &Nullifier) -> NonZeroPallasScalar {
|
||||||
|
// We can't construct a RandomSeed for which this unwrap fails.
|
||||||
|
self.esk_inner(rho).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
||||||
|
@ -108,7 +123,7 @@ impl Note {
|
||||||
recipient,
|
recipient,
|
||||||
value,
|
value,
|
||||||
rho,
|
rho,
|
||||||
rseed: RandomSeed::random(&mut rng),
|
rseed: RandomSeed::random(&mut rng, &rho),
|
||||||
};
|
};
|
||||||
if note.commitment_inner().is_some().into() {
|
if note.commitment_inner().is_some().into() {
|
||||||
break note;
|
break note;
|
||||||
|
|
Loading…
Reference in New Issue