// Copyright (c) 2019-2020 The Hush developers // Distributed under the GPLv3 software license, see the accompanying // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html #ifndef ZC_PROOF_H_ #define ZC_PROOF_H_ #include "serialize.h" #include "uint256.h" namespace libzcash { const unsigned char G1_PREFIX_MASK = 0x02; const unsigned char G2_PREFIX_MASK = 0x0a; // Element in the base field class Fq { private: base_blob<256> data; public: Fq() : data() { } ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(data); } friend bool operator==(const Fq& a, const Fq& b) { return ( a.data == b.data ); } friend bool operator!=(const Fq& a, const Fq& b) { return !(a == b); } }; // Element in the extension field class Fq2 { private: base_blob<512> data; public: Fq2() : data() { } ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(data); } friend bool operator==(const Fq2& a, const Fq2& b) { return ( a.data == b.data ); } friend bool operator!=(const Fq2& a, const Fq2& b) { return !(a == b); } }; // Compressed point in G1 class CompressedG1 { private: bool y_lsb; Fq x; public: CompressedG1() : y_lsb(false), x() { } ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { unsigned char leadingByte = G1_PREFIX_MASK; if (y_lsb) { leadingByte |= 1; } READWRITE(leadingByte); if ((leadingByte & (~1)) != G1_PREFIX_MASK) { throw std::ios_base::failure("lead byte of G1 point not recognized"); } y_lsb = leadingByte & 1; READWRITE(x); } friend bool operator==(const CompressedG1& a, const CompressedG1& b) { return ( a.y_lsb == b.y_lsb && a.x == b.x ); } friend bool operator!=(const CompressedG1& a, const CompressedG1& b) { return !(a == b); } }; // Compressed point in G2 class CompressedG2 { private: bool y_gt; Fq2 x; public: CompressedG2() : y_gt(false), x() { } ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { unsigned char leadingByte = G2_PREFIX_MASK; if (y_gt) { leadingByte |= 1; } READWRITE(leadingByte); if ((leadingByte & (~1)) != G2_PREFIX_MASK) { throw std::ios_base::failure("lead byte of G2 point not recognized"); } y_gt = leadingByte & 1; READWRITE(x); } friend bool operator==(const CompressedG2& a, const CompressedG2& b) { return ( a.y_gt == b.y_gt && a.x == b.x ); } friend bool operator!=(const CompressedG2& a, const CompressedG2& b) { return !(a == b); } }; // Compressed zkSNARK proof class PHGRProof { private: CompressedG1 g_A; CompressedG1 g_A_prime; CompressedG2 g_B; CompressedG1 g_B_prime; CompressedG1 g_C; CompressedG1 g_C_prime; CompressedG1 g_K; CompressedG1 g_H; public: PHGRProof() : g_A(), g_A_prime(), g_B(), g_B_prime(), g_C(), g_C_prime(), g_K(), g_H() { } ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(g_A); READWRITE(g_A_prime); READWRITE(g_B); READWRITE(g_B_prime); READWRITE(g_C); READWRITE(g_C_prime); READWRITE(g_K); READWRITE(g_H); } friend bool operator==(const PHGRProof& a, const PHGRProof& b) { return ( a.g_A == b.g_A && a.g_A_prime == b.g_A_prime && a.g_B == b.g_B && a.g_B_prime == b.g_B_prime && a.g_C == b.g_C && a.g_C_prime == b.g_C_prime && a.g_K == b.g_K && a.g_H == b.g_H ); } friend bool operator!=(const PHGRProof& a, const PHGRProof& b) { return !(a == b); } }; void initialize_curve_params(); class ProofVerifier { private: bool perform_verification; ProofVerifier(bool perform_verification) : perform_verification(perform_verification) { } public: // ProofVerifier should never be copied ProofVerifier(const ProofVerifier&) = delete; ProofVerifier& operator=(const ProofVerifier&) = delete; ProofVerifier(ProofVerifier&&); ProofVerifier& operator=(ProofVerifier&&); // Creates a verification context that strictly verifies // all proofs using libsnark's API. static ProofVerifier Strict(); // Creates a verification context that performs no // verification, used when avoiding duplicate effort // such as during reindexing. static ProofVerifier Disabled(); template bool check( const VerificationKey& vk, const ProcessedVerificationKey& pvk, const PrimaryInput& pi, const Proof& p ); }; } #endif // ZC_PROOF_H_