243 lines
5.3 KiB
C++
243 lines
5.3 KiB
C++
#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 <typename Stream, typename Operation>
|
|
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 <typename Stream, typename Operation>
|
|
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 <typename Stream, typename Operation>
|
|
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 <typename Stream, typename Operation>
|
|
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 <typename Stream, typename Operation>
|
|
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 <typename VerificationKey,
|
|
typename ProcessedVerificationKey,
|
|
typename PrimaryInput,
|
|
typename Proof
|
|
>
|
|
bool check(
|
|
const VerificationKey& vk,
|
|
const ProcessedVerificationKey& pvk,
|
|
const PrimaryInput& pi,
|
|
const Proof& p
|
|
);
|
|
};
|
|
|
|
}
|
|
|
|
#endif // ZC_PROOF_H_
|