diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index fb15ffeeb..584a5b7e5 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -33,26 +33,118 @@ static constexpr size_t GROTH_PROOF_SIZE = ( 48 + // π_A 96 + // π_B 48); // π_C -static constexpr size_t SPEND_DESCRIPTION_SIZE = ( - 32 + // cv - 32 + // anchor - 32 + // nullifier - 32 + // rk - GROTH_PROOF_SIZE + - 64); // spendAuthSig -static constexpr size_t OUTPUT_DESCRIPTION_SIZE = ( - 32 + // cv - 32 + // cm - 32 + // ephemeralKey - 580 + // encCiphertext - 80 + // outCiphertext - GROTH_PROOF_SIZE); namespace libzcash { typedef boost::array GrothProof; } -typedef boost::array SpendDescription; -typedef boost::array OutputDescription; + +/** + * A shielded input to a transaction. It contains data that describes a Spend transfer. + */ +class SpendDescription +{ +public: + typedef boost::array spend_auth_sig_t; + + uint256 cv; //!< A value commitment to the value of the input note. + uint256 anchor; //!< A Merkle root of the Sapling note commitment tree at some block height in the past. + uint256 nullifier; //!< The nullifier of the input note. + uint256 rk; //!< The randomized public key for spendAuthSig. + libzcash::GrothProof zkproof; //!< A zero-knowledge proof using the spend circuit. + spend_auth_sig_t spendAuthSig; //!< A signature authorizing this spend. + + SpendDescription() { } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(cv); + READWRITE(anchor); + READWRITE(nullifier); + READWRITE(rk); + READWRITE(zkproof); + READWRITE(spendAuthSig); + } + + friend bool operator==(const SpendDescription& a, const SpendDescription& b) + { + return ( + a.cv == b.cv && + a.anchor == b.anchor && + a.nullifier == b.nullifier && + a.rk == b.rk && + a.zkproof == b.zkproof && + a.spendAuthSig == b.spendAuthSig + ); + } + + friend bool operator!=(const SpendDescription& a, const SpendDescription& b) + { + return !(a == b); + } +}; + +static constexpr size_t SAPLING_ENC_CIPHERTEXT_SIZE = ( + 1 + // leading byte + 11 + // d + 8 + // value + 32 + // rcm + ZC_MEMO_SIZE + // memo + NOTEENCRYPTION_AUTH_BYTES); + +static constexpr size_t SAPLING_OUT_CIPHERTEXT_SIZE = ( + 32 + // pkd_new + 32 + // esk + NOTEENCRYPTION_AUTH_BYTES); + +/** + * A shielded output to a transaction. It contains data that describes an Output transfer. + */ +class OutputDescription +{ +public: + typedef boost::array sapling_enc_ct_t; // TODO: Replace with actual type + typedef boost::array sapling_out_ct_t; // TODO: Replace with actual type + + uint256 cv; //!< A value commitment to the value of the output note. + uint256 cm; //!< The note commitment for the output note. + uint256 ephemeralKey; //!< A Jubjub public key. + sapling_enc_ct_t encCiphertext; //!< A ciphertext component for the encrypted output note. + sapling_out_ct_t outCiphertext; //!< A ciphertext component for the encrypted output note. + libzcash::GrothProof zkproof; //!< A zero-knowledge proof using the output circuit. + + OutputDescription() { } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(cv); + READWRITE(cm); + READWRITE(ephemeralKey); + READWRITE(encCiphertext); + READWRITE(outCiphertext); + READWRITE(zkproof); + } + + friend bool operator==(const OutputDescription& a, const OutputDescription& b) + { + return ( + a.cv == b.cv && + a.cm == b.cm && + a.ephemeralKey == b.ephemeralKey && + a.encCiphertext == b.encCiphertext && + a.outCiphertext == b.outCiphertext && + a.zkproof == b.zkproof + ); + } + + friend bool operator!=(const OutputDescription& a, const OutputDescription& b) + { + return !(a == b); + } +}; template class SproutProofSerializer : public boost::static_visitor<>