Implement zkSNARK compression.
This commit is contained in:
241
src/zcash/Proof.hpp
Normal file
241
src/zcash/Proof.hpp
Normal file
@@ -0,0 +1,241 @@
|
||||
#ifndef _ZCPROOF_H_
|
||||
#define _ZCPROOF_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() { }
|
||||
|
||||
template<typename libsnark_Fq>
|
||||
Fq(libsnark_Fq element);
|
||||
|
||||
template<typename libsnark_Fq>
|
||||
libsnark_Fq to_libsnark_fq() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
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() { }
|
||||
|
||||
template<typename libsnark_Fq2>
|
||||
Fq2(libsnark_Fq2 element);
|
||||
|
||||
template<typename libsnark_Fq2>
|
||||
libsnark_Fq2 to_libsnark_fq2() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
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() { }
|
||||
|
||||
template<typename libsnark_G1>
|
||||
CompressedG1(libsnark_G1 point);
|
||||
|
||||
template<typename libsnark_G1>
|
||||
libsnark_G1 to_libsnark_g1() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
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() { }
|
||||
|
||||
template<typename libsnark_G2>
|
||||
CompressedG2(libsnark_G2 point);
|
||||
|
||||
template<typename libsnark_G2>
|
||||
libsnark_G2 to_libsnark_g2() const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
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 ZCProof {
|
||||
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:
|
||||
ZCProof() : g_A(), g_A_prime(), g_B(), g_B_prime(), g_C(), g_C_prime(), g_K(), g_H() { }
|
||||
|
||||
// Produces a compressed proof using a libsnark zkSNARK proof
|
||||
template<typename libsnark_proof>
|
||||
ZCProof(const libsnark_proof& proof);
|
||||
|
||||
// Produces a libsnark zkSNARK proof out of this proof,
|
||||
// or throws an exception if it is invalid.
|
||||
template<typename libsnark_proof>
|
||||
libsnark_proof to_libsnark_proof() const;
|
||||
|
||||
static ZCProof random_invalid();
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
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 ZCProof& a, const ZCProof& 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 ZCProof& a, const ZCProof& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // _ZCPROOF_H_
|
||||
Reference in New Issue
Block a user