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::{
|
||||
note::{ExtractedNoteCommitment, Nullifier},
|
||||
note::{ExtractedNoteCommitment, Nullifier, RandomSeed},
|
||||
value::NoteValue,
|
||||
Note,
|
||||
};
|
||||
|
@ -625,7 +625,7 @@ mod tests {
|
|||
addr,
|
||||
NoteValue::from_raw(tv.note_v),
|
||||
rho,
|
||||
tv.note_rseed.into(),
|
||||
RandomSeed::from_bytes(tv.note_rseed, &rho).unwrap(),
|
||||
);
|
||||
|
||||
let cmx: ExtractedNoteCommitment = note.commitment().into();
|
||||
|
|
43
src/note.rs
43
src/note.rs
|
@ -6,7 +6,7 @@ use subtle::CtOption;
|
|||
|
||||
use crate::{
|
||||
keys::{FullViewingKey, SpendingKey},
|
||||
spec::{to_base, to_scalar, PrfExpand},
|
||||
spec::{to_base, to_scalar, NonZeroPallasScalar, PrfExpand},
|
||||
value::NoteValue,
|
||||
Address,
|
||||
};
|
||||
|
@ -21,17 +21,22 @@ pub use self::nullifier::Nullifier;
|
|||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct RandomSeed([u8; 32]);
|
||||
|
||||
impl From<[u8; 32]> for RandomSeed {
|
||||
fn from(rseed: [u8; 32]) -> Self {
|
||||
RandomSeed(rseed)
|
||||
}
|
||||
}
|
||||
|
||||
impl RandomSeed {
|
||||
pub(crate) fn random(rng: &mut impl RngCore) -> Self {
|
||||
let mut bytes = [0; 32];
|
||||
rng.fill_bytes(&mut bytes);
|
||||
RandomSeed(bytes)
|
||||
pub(crate) fn random(rng: &mut impl RngCore, rho: &Nullifier) -> Self {
|
||||
loop {
|
||||
let mut bytes = [0; 32];
|
||||
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].
|
||||
|
@ -44,8 +49,18 @@ impl RandomSeed {
|
|||
/// 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) -> pallas::Scalar {
|
||||
to_scalar(PrfExpand::Esk.with_ad(&self.0, &rho.to_bytes()[..]))
|
||||
fn esk_inner(&self, rho: &Nullifier) -> CtOption<NonZeroPallasScalar> {
|
||||
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].
|
||||
|
@ -108,7 +123,7 @@ impl Note {
|
|||
recipient,
|
||||
value,
|
||||
rho,
|
||||
rseed: RandomSeed::random(&mut rng),
|
||||
rseed: RandomSeed::random(&mut rng, &rho),
|
||||
};
|
||||
if note.commitment_inner().is_some().into() {
|
||||
break note;
|
||||
|
|
Loading…
Reference in New Issue