Add enum Rseed<E::Fs> to Note struct

This commit is contained in:
therealyingtong 2020-07-30 12:36:12 +08:00
parent b537f0f712
commit 65504d9ca7
No known key found for this signature in database
GPG Key ID: 179F32A1503D607E
6 changed files with 89 additions and 44 deletions

View File

@ -271,7 +271,7 @@ pub fn scan_cached_blocks<P: AsRef<Path>, Q: AsRef<Path>>(
.collect();
for output in tx.shielded_outputs {
let rcm = output.note.r.to_repr();
let rcm = output.note.rcm().to_repr();
let nf = output.note.nf(
&extfvks[output.account].fvk.vk,
output.witness.position() as u64,
@ -459,7 +459,7 @@ pub fn decrypt_and_store_transaction<P: AsRef<Path>>(
])?;
}
} else {
let rcm = output.note.r.to_repr();
let rcm = output.note.rcm().to_repr();
// Try updating an existing received note.
if stmt_update_received_note.execute(&[

View File

@ -13,7 +13,7 @@ use zcash_primitives::{
keys::OutgoingViewingKey,
merkle_tree::{IncrementalWitness, MerklePath},
note_encryption::Memo,
primitives::{Diversifier, Note},
primitives::{Diversifier, Note, Rseed},
prover::TxProver,
sapling::Node,
transaction::{
@ -249,7 +249,9 @@ pub fn create_to_address<P: AsRef<Path>>(
.vk
.to_payment_address(diversifier, &JUBJUB)
.unwrap();
let note = from.create_note(note_value as u64, rcm, &JUBJUB).unwrap();
let note = from
.create_note(note_value as u64, Rseed::BeforeZip212(rcm), &JUBJUB)
.unwrap();
let merkle_path = {
let d: Vec<_> = row.get(3)?;

View File

@ -8,7 +8,7 @@ use crate::{
fs::{Fs, FsRepr},
PrimeOrder, ToUniform, Unknown,
},
primitives::{Diversifier, Note, PaymentAddress},
primitives::{Diversifier, Note, PaymentAddress, Rseed},
};
use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
@ -233,12 +233,12 @@ fn prf_ock(
/// let ovk = OutgoingViewingKey([0; 32]);
///
/// let value = 1000;
/// let rcv = Fs::random(&mut rng);
/// let rcm = Fs::random(&mut rng);
/// let cv = ValueCommitment::<Bls12> {
/// value,
/// randomness: rcv.clone(),
/// };
/// let note = to.create_note(value, rcv, &JUBJUB).unwrap();
/// let note = to.create_note(value, Rseed::BeforeZip212(rcm), &JUBJUB).unwrap();
/// let cmu = note.cm(&JUBJUB);
///
/// let enc = SaplingNoteEncryption::new(ovk, note, to, Memo::default(), &mut rng);
@ -294,12 +294,22 @@ impl SaplingNoteEncryption {
// Note plaintext encoding is defined in section 5.5 of the Zcash Protocol
// Specification.
let mut input = [0; NOTE_PLAINTEXT_SIZE];
input[0] = 1;
input[0] = match self.note.rseed {
Rseed::BeforeZip212(_) => 1,
Rseed::AfterZip212(_) => 2,
};
input[1..12].copy_from_slice(&self.to.diversifier().0);
(&mut input[12..20])
.write_u64::<LittleEndian>(self.note.value)
.unwrap();
input[20..COMPACT_NOTE_SIZE].copy_from_slice(self.note.r.to_repr().as_ref());
match self.note.rseed {
Rseed::BeforeZip212(rcm) => {
input[20..COMPACT_NOTE_SIZE].copy_from_slice(rcm.to_repr().as_ref());
}
Rseed::AfterZip212(rseed) => {
input[20..COMPACT_NOTE_SIZE].copy_from_slice(&rseed);
}
}
input[COMPACT_NOTE_SIZE..NOTE_PLAINTEXT_SIZE].copy_from_slice(&self.memo.0);
let mut output = [0u8; ENC_CIPHERTEXT_SIZE];
@ -355,11 +365,15 @@ fn parse_note_plaintext_without_memo<P: consensus::Parameters>(
let v = (&plaintext[12..20]).read_u64::<LittleEndian>().ok()?;
let rcm = Fs::from_repr(FsRepr(
plaintext[20..COMPACT_NOTE_SIZE]
.try_into()
.expect("slice is the correct length"),
))?;
let mut r = [0u8; 32];
r.copy_from_slice(&plaintext[20..COMPACT_NOTE_SIZE]);
let rseed = if parameters.is_nu_active(NetworkUpgrade::Canopy, height) {
Rseed::AfterZip212(r)
} else {
let rcm = Fs::from_repr(FsRepr(r.try_into().expect("slice is the correct length")))?;
Rseed::BeforeZip212(rcm)
};
let diversifier = Diversifier(d);
let pk_d = diversifier
@ -367,7 +381,7 @@ fn parse_note_plaintext_without_memo<P: consensus::Parameters>(
.mul(ivk.to_repr(), &JUBJUB);
let to = PaymentAddress::from_parts(diversifier, pk_d)?;
let note = to.create_note(v, rcm, &JUBJUB).unwrap();
let note = to.create_note(v, rseed, &JUBJUB).unwrap();
if note.cm(&JUBJUB) != *cmu {
// Published commitment doesn't match calculated commitment
@ -517,11 +531,15 @@ pub fn try_sapling_output_recovery<P: consensus::Parameters>(
let v = (&plaintext[12..20]).read_u64::<LittleEndian>().ok()?;
let rcm = Fs::from_repr(FsRepr(
plaintext[20..COMPACT_NOTE_SIZE]
.try_into()
.expect("slice is the correct length"),
))?;
let mut r = [0u8; 32];
r.copy_from_slice(&plaintext[20..COMPACT_NOTE_SIZE]);
let rseed = if parameters.is_nu_active(NetworkUpgrade::Canopy, height) {
Rseed::AfterZip212(r)
} else {
let rcm = Fs::from_repr(FsRepr(r.try_into().expect("slice is the correct length")))?;
Rseed::BeforeZip212(rcm)
};
let mut memo = [0u8; 512];
memo.copy_from_slice(&plaintext[COMPACT_NOTE_SIZE..NOTE_PLAINTEXT_SIZE]);
@ -537,7 +555,7 @@ pub fn try_sapling_output_recovery<P: consensus::Parameters>(
}
let to = PaymentAddress::from_parts(diversifier, pk_d)?;
let note = to.create_note(v, rcm, &JUBJUB).unwrap();
let note = to.create_note(v, rseed, &JUBJUB).unwrap();
if note.cm(&JUBJUB) != *cmu {
// Published commitment doesn't match calculated commitment
@ -555,7 +573,7 @@ mod tests {
fs::{Fs, FsRepr},
PrimeOrder, Unknown,
},
primitives::{Diversifier, PaymentAddress, ValueCommitment},
primitives::{Diversifier, PaymentAddress, Rseed, ValueCommitment},
};
use crypto_api_chachapoly::ChachaPolyIetf;
use ff::{Field, PrimeField};
@ -752,7 +770,7 @@ mod tests {
let cv = value_commitment.cm(&JUBJUB).into();
let note = pa
.create_note(value, Fs::random(&mut rng), &JUBJUB)
.create_note(value, Rseed::BeforeZip212(Fs::random(&mut rng)), &JUBJUB)
.unwrap();
let cmu = note.cm(&JUBJUB);
@ -1348,7 +1366,9 @@ mod tests {
assert_eq!(ock.as_bytes(), tv.ock);
let to = PaymentAddress::from_parts(Diversifier(tv.default_d), pk_d).unwrap();
let note = to.create_note(tv.v, rcm, &JUBJUB).unwrap();
let note = to
.create_note(tv.v, Rseed::BeforeZip212(rcm), &JUBJUB)
.unwrap();
assert_eq!(note.cm(&JUBJUB), cmu);
//

View File

@ -8,9 +8,11 @@ use crate::group_hash::group_hash;
use crate::pedersen_hash::{pedersen_hash, Personalization};
use byteorder::{LittleEndian, WriteBytesExt};
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
use crate::jubjub::{edwards, FixedGenerators, JubjubEngine, JubjubParams, PrimeOrder};
use crate::jubjub::{edwards, FixedGenerators, JubjubEngine, JubjubParams, PrimeOrder, ToUniform};
use crate::keys::prf_expand;
use blake2s_simd::Params as Blake2sParams;
@ -207,18 +209,24 @@ impl<E: JubjubEngine> PaymentAddress<E> {
pub fn create_note(
&self,
value: u64,
randomness: E::Fs,
randomness: Rseed<E::Fs>,
params: &E::Params,
) -> Option<Note<E>> {
self.g_d(params).map(|g_d| Note {
value,
r: randomness,
rseed: randomness,
g_d,
pk_d: self.pk_d.clone(),
})
}
}
#[derive(Clone, Debug)]
pub enum Rseed<Fs> {
BeforeZip212(Fs),
AfterZip212([u8; 32]),
}
#[derive(Clone, Debug)]
pub struct Note<E: JubjubEngine> {
/// The value of the note
@ -227,8 +235,8 @@ pub struct Note<E: JubjubEngine> {
pub g_d: edwards::Point<E, PrimeOrder>,
/// The public key of the address, g_d^ivk
pub pk_d: edwards::Point<E, PrimeOrder>,
/// The commitment randomness
pub r: E::Fs,
/// rseed
pub rseed: Rseed<E::Fs>,
}
impl<E: JubjubEngine> PartialEq for Note<E> {
@ -236,7 +244,7 @@ impl<E: JubjubEngine> PartialEq for Note<E> {
self.value == other.value
&& self.g_d == other.g_d
&& self.pk_d == other.pk_d
&& self.r == other.r
&& self.rcm() == other.rcm()
}
}
@ -280,7 +288,7 @@ impl<E: JubjubEngine> Note<E> {
// Compute final commitment
params
.generator(FixedGenerators::NoteCommitmentRandomness)
.mul(self.r, params)
.mul(self.rcm(), params)
.add(&hash_of_contents, params)
}
@ -313,4 +321,11 @@ impl<E: JubjubEngine> Note<E> {
// commitment to the x-coordinate is an injective encoding.
self.cm_full_point(params).to_xy().0
}
pub fn rcm(&self) -> E::Fs {
match self.rseed {
Rseed::BeforeZip212(rcm) => rcm,
Rseed::AfterZip212(rseed) => E::Fs::to_uniform(prf_expand(&rseed, &[0x04]).as_bytes()),
}
}
}

View File

@ -3,7 +3,7 @@
use crate::zip32::ExtendedSpendingKey;
use crate::{
jubjub::fs::Fs,
primitives::{Diversifier, Note, PaymentAddress},
primitives::{Diversifier, Note, PaymentAddress, Rseed},
};
use ff::Field;
use pairing::bls12_381::{Bls12, Fr};
@ -110,7 +110,7 @@ impl SaplingOutput {
g_d,
pk_d: to.pk_d().clone(),
value: value.into(),
r: rcm,
rseed: Rseed::BeforeZip212(rcm),
};
Ok(SaplingOutput {
@ -139,7 +139,7 @@ impl SaplingOutput {
ctx,
encryptor.esk().clone(),
self.to,
self.note.r,
self.note.rcm(),
self.note.value,
);
@ -568,7 +568,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
&mut ctx,
proof_generation_key,
spend.diversifier,
spend.note.r,
spend.note.rcm(),
spend.alpha,
spend.note.value,
anchor,
@ -628,7 +628,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
Note {
g_d,
pk_d,
r: Fs::random(&mut self.rng),
rseed: Rseed::BeforeZip212(Fs::random(&mut self.rng)),
value: 0,
},
)
@ -637,8 +637,13 @@ impl<R: RngCore + CryptoRng> Builder<R> {
let esk = generate_esk(&mut self.rng);
let epk = dummy_note.g_d.mul(esk, &JUBJUB);
let (zkproof, cv) =
prover.output_proof(&mut ctx, esk, dummy_to, dummy_note.r, dummy_note.value);
let (zkproof, cv) = prover.output_proof(
&mut ctx,
esk,
dummy_to,
dummy_note.rcm(),
dummy_note.value,
);
let cmu = dummy_note.cm(&JUBJUB);
@ -717,6 +722,7 @@ mod tests {
consensus,
legacy::TransparentAddress,
merkle_tree::{CommitmentTree, IncrementalWitness},
primitives::Rseed,
prover::mock::MockTxProver,
sapling::Node,
transaction::components::Amount,
@ -778,7 +784,7 @@ mod tests {
let mut rng = OsRng;
let note1 = to
.create_note(50000, Fs::random(&mut rng), &JUBJUB)
.create_note(50000, Rseed::BeforeZip212(Fs::random(&mut rng)), &JUBJUB)
.unwrap();
let cm1 = Node::new(note1.cm(&JUBJUB).to_repr());
let mut tree = CommitmentTree::new();
@ -877,7 +883,7 @@ mod tests {
}
let note1 = to
.create_note(59999, Fs::random(&mut rng), &JUBJUB)
.create_note(59999, Rseed::BeforeZip212(Fs::random(&mut rng)), &JUBJUB)
.unwrap();
let cm1 = Node::new(note1.cm(&JUBJUB).to_repr());
let mut tree = CommitmentTree::new();
@ -916,7 +922,9 @@ mod tests {
);
}
let note2 = to.create_note(1, Fs::random(&mut rng), &JUBJUB).unwrap();
let note2 = to
.create_note(1, Rseed::BeforeZip212(Fs::random(&mut rng)), &JUBJUB)
.unwrap();
let cm2 = Node::new(note2.cm(&JUBJUB).to_repr());
tree.append(cm2).unwrap();
witness1.append(cm2).unwrap();

View File

@ -8,7 +8,7 @@ use rand_core::OsRng;
use std::ops::{AddAssign, Neg};
use zcash_primitives::{
jubjub::{edwards, fs::Fs, FixedGenerators, JubjubBls12, Unknown},
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ValueCommitment},
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, Rseed, ValueCommitment},
};
use zcash_primitives::{
merkle_tree::MerklePath,
@ -102,7 +102,7 @@ impl SaplingProvingContext {
.g_d::<Bls12>(params)
.expect("was a valid diversifier before"),
pk_d: payment_address.pk_d().clone(),
r: rcm,
rseed: Rseed::BeforeZip212(rcm),
};
let nullifier = note.nf(&viewing_key, merkle_path.position, params);