docs: document consensus rules from 4.5 Output Descriptions (#3462)
* docs: document consensus rules from 4.4 Spend Descriptions * docs: document consensus rules from 4.5 Output Descriptions * cargo fmt Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
1ffb7a5cd0
commit
495e1ec20f
|
|
@ -1052,6 +1052,8 @@ impl TryFrom<[u8; 32]> for EphemeralPublicKey {
|
||||||
///
|
///
|
||||||
/// Returns an error if the key is non-canonical, or [it is of small order][1].
|
/// Returns an error if the key is non-canonical, or [it is of small order][1].
|
||||||
///
|
///
|
||||||
|
/// # Consensus
|
||||||
|
///
|
||||||
/// > Check that a Output description's cv and epk are not of small order,
|
/// > Check that a Output description's cv and epk are not of small order,
|
||||||
/// > i.e. [h_J]cv MUST NOT be 𝒪_J and [h_J]epk MUST NOT be 𝒪_J.
|
/// > i.e. [h_J]cv MUST NOT be 𝒪_J and [h_J]epk MUST NOT be 𝒪_J.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -134,12 +134,45 @@ impl ZcashSerialize for OutputInTransactionV4 {
|
||||||
|
|
||||||
impl ZcashDeserialize for OutputInTransactionV4 {
|
impl ZcashDeserialize for OutputInTransactionV4 {
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
|
// # Consensus
|
||||||
|
//
|
||||||
|
// > Elements of a Output description MUST be valid encodings of the types given above.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#outputdesc
|
||||||
|
//
|
||||||
|
// > LEOS2IP_{256}(cmu) MUST be less than 𝑞_J.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
|
//
|
||||||
|
// See comments below for each specific type.
|
||||||
Ok(OutputInTransactionV4(Output {
|
Ok(OutputInTransactionV4(Output {
|
||||||
|
// Type is `ValueCommit^{Sapling}.Output`, i.e. J
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#abstractcommit
|
||||||
|
// See [`commitment::NotSmallOrderValueCommitment::zcash_deserialize`].
|
||||||
cv: commitment::NotSmallOrderValueCommitment::zcash_deserialize(&mut reader)?,
|
cv: commitment::NotSmallOrderValueCommitment::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `B^{[ℓ_{Sapling}_{Merkle}]}`, i.e. 32 bytes.
|
||||||
|
// However, the consensus rule above restricts it even more.
|
||||||
|
// See [`jubjub::Fq::zcash_deserialize`].
|
||||||
cm_u: jubjub::Fq::zcash_deserialize(&mut reader)?,
|
cm_u: jubjub::Fq::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `KA^{Sapling}.Public`, i.e. J
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
|
||||||
|
// See [`keys::EphemeralPublicKey::zcash_deserialize`].
|
||||||
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
|
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
|
// See [`note::EncryptedNote::zcash_deserialize`].
|
||||||
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays.
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
|
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
|
// See [`note::WrappedNoteKey::zcash_deserialize`].
|
||||||
out_ciphertext: note::WrappedNoteKey::zcash_deserialize(&mut reader)?,
|
out_ciphertext: note::WrappedNoteKey::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `ZKOutput.Proof`, described in
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#grothencoding
|
||||||
|
// It is not enforced here; this just reads 192 bytes.
|
||||||
|
// The type is validated when validating the proof, see
|
||||||
|
// [`groth16::Item::try_from`]. In #3179 we plan to validate here instead.
|
||||||
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
|
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
@ -164,11 +197,39 @@ impl ZcashSerialize for OutputPrefixInTransactionV5 {
|
||||||
|
|
||||||
impl ZcashDeserialize for OutputPrefixInTransactionV5 {
|
impl ZcashDeserialize for OutputPrefixInTransactionV5 {
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
|
// # Consensus
|
||||||
|
//
|
||||||
|
// > Elements of a Output description MUST be valid encodings of the types given above.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#outputdesc
|
||||||
|
//
|
||||||
|
// > LEOS2IP_{256}(cmu) MUST be less than 𝑞_J.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
|
//
|
||||||
|
// See comments below for each specific type.
|
||||||
Ok(OutputPrefixInTransactionV5 {
|
Ok(OutputPrefixInTransactionV5 {
|
||||||
|
// Type is `ValueCommit^{Sapling}.Output`, i.e. J
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#abstractcommit
|
||||||
|
// See [`commitment::NotSmallOrderValueCommitment::zcash_deserialize`].
|
||||||
cv: commitment::NotSmallOrderValueCommitment::zcash_deserialize(&mut reader)?,
|
cv: commitment::NotSmallOrderValueCommitment::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `B^{[ℓ_{Sapling}_{Merkle}]}`, i.e. 32 bytes.
|
||||||
|
// However, the consensus rule above restricts it even more.
|
||||||
|
// See [`jubjub::Fq::zcash_deserialize`].
|
||||||
cm_u: jubjub::Fq::zcash_deserialize(&mut reader)?,
|
cm_u: jubjub::Fq::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `KA^{Sapling}.Public`, i.e. J
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
|
||||||
|
// See [`keys::EphemeralPublicKey::zcash_deserialize`].
|
||||||
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
|
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
|
// See [`note::EncryptedNote::zcash_deserialize`].
|
||||||
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
|
||||||
|
// Type is `Sym.C`, i.e. `B^Y^{[N]}`, i.e. arbitrary-sized byte arrays.
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
|
||||||
|
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||||
|
// See [`note::WrappedNoteKey::zcash_deserialize`].
|
||||||
out_ciphertext: note::WrappedNoteKey::zcash_deserialize(&mut reader)?,
|
out_ciphertext: note::WrappedNoteKey::zcash_deserialize(&mut reader)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,14 @@ impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> {
|
||||||
// https://zips.z.cash/protocol/protocol.pdf#spenddesc
|
// https://zips.z.cash/protocol/protocol.pdf#spenddesc
|
||||||
//
|
//
|
||||||
// Type is `B^{[ℓ_{Sapling}_{Merkle}]}`, i.e. 32 bytes
|
// Type is `B^{[ℓ_{Sapling}_{Merkle}]}`, i.e. 32 bytes
|
||||||
|
//
|
||||||
|
// # Consensus
|
||||||
|
//
|
||||||
|
// > Elements of a Spend description MUST be valid encodings of the types given above.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#spenddesc
|
||||||
|
//
|
||||||
|
// Type is `B^{[ℓ_{Sapling}_{Merkle}]}`, i.e. 32 bytes
|
||||||
let shared_anchor = if spends_count > 0 {
|
let shared_anchor = if spends_count > 0 {
|
||||||
Some(reader.read_32_bytes()?.into())
|
Some(reader.read_32_bytes()?.into())
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -225,6 +233,18 @@ impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> {
|
||||||
// It is not enforced here; this just reads 192 bytes.
|
// It is not enforced here; this just reads 192 bytes.
|
||||||
// The type is validated when validating the proof, see
|
// The type is validated when validating the proof, see
|
||||||
// [`groth16::Item::try_from`]. In #3179 we plan to validate here instead.
|
// [`groth16::Item::try_from`]. In #3179 we plan to validate here instead.
|
||||||
|
//
|
||||||
|
// # Consensus
|
||||||
|
//
|
||||||
|
// > Elements of a Spend description MUST be valid encodings of the types given above.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#spenddesc
|
||||||
|
//
|
||||||
|
// Type is `ZKSpend.Proof`, described in
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#grothencoding
|
||||||
|
// It is not enforced here; this just reads 192 bytes.
|
||||||
|
// The type is validated when validating the proof, see
|
||||||
|
// [`groth16::Item::try_from`]. In #3179 we plan to validate here instead.
|
||||||
let spend_proofs = zcash_deserialize_external_count(spends_count, &mut reader)?;
|
let spend_proofs = zcash_deserialize_external_count(spends_count, &mut reader)?;
|
||||||
|
|
||||||
// Denoted as `vSpendAuthSigsSapling` in the spec.
|
// Denoted as `vSpendAuthSigsSapling` in the spec.
|
||||||
|
|
@ -242,6 +262,18 @@ impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> {
|
||||||
let spend_sigs = zcash_deserialize_external_count(spends_count, &mut reader)?;
|
let spend_sigs = zcash_deserialize_external_count(spends_count, &mut reader)?;
|
||||||
|
|
||||||
// Denoted as `vOutputProofsSapling` in the spec.
|
// Denoted as `vOutputProofsSapling` in the spec.
|
||||||
|
//
|
||||||
|
// # Consensus
|
||||||
|
//
|
||||||
|
// > Elements of a Output description MUST be valid encodings of the types given above.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#outputdesc
|
||||||
|
//
|
||||||
|
// Type is `ZKOutput.Proof`, described in
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#grothencoding
|
||||||
|
// It is not enforced here; this just reads 192 bytes.
|
||||||
|
// The type is validated when validating the proof, see
|
||||||
|
// [`groth16::Item::try_from`]. In #3179 we plan to validate here instead.
|
||||||
let output_proofs = zcash_deserialize_external_count(outputs_count, &mut reader)?;
|
let output_proofs = zcash_deserialize_external_count(outputs_count, &mut reader)?;
|
||||||
|
|
||||||
// Denoted as `bindingSigSapling` in the spec.
|
// Denoted as `bindingSigSapling` in the spec.
|
||||||
|
|
|
||||||
|
|
@ -834,9 +834,13 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
for output in sapling_shielded_data.outputs() {
|
for output in sapling_shielded_data.outputs() {
|
||||||
// Consensus rule: The proof π_ZKOutput MUST be
|
// # Consensus
|
||||||
// valid given a primary input formed from the other
|
//
|
||||||
// fields except C^enc and C^out.
|
// > The proof π_ZKOutput MUST be
|
||||||
|
// > valid given a primary input formed from the other
|
||||||
|
// > fields except C^enc and C^out.
|
||||||
|
//
|
||||||
|
// https://zips.z.cash/protocol/protocol.pdf#outputdesc
|
||||||
//
|
//
|
||||||
// Queue the verification of the Groth16 output
|
// Queue the verification of the Groth16 output
|
||||||
// proof for each Output description while adding
|
// proof for each Output description while adding
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue