forked from jancarlsson/snarklib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPPZK_verify.hpp
171 lines (133 loc) · 5.21 KB
/
PPZK_verify.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#ifndef _SNARKLIB_PPZK_VERIFY_HPP_
#define _SNARKLIB_PPZK_VERIFY_HPP_
#include <memory>
#include "ProgressCallback.hpp"
#include "PPZK_keystruct.hpp"
#include "PPZK_proof.hpp"
#include "Rank1DSL.hpp"
namespace snarklib {
////////////////////////////////////////////////////////////////////////////////
// Verification functions
//
template <typename PAIRING>
bool weakVerify(const PPZK_PrecompVerificationKey<PAIRING>& pvk,
const R1Witness<typename PAIRING::Fr>& input,
const PPZK_Proof<PAIRING>& proof,
ProgressCallback* callback = nullptr)
{
ProgressCallback_NOP<PAIRING> dummyNOP;
ProgressCallback* dummy = callback ? callback : std::addressof(dummyNOP);
dummy->majorSteps(6);
typedef typename PAIRING::GT GT;
typedef typename PAIRING::G1_precomp G1_precomp;
typedef typename PAIRING::G2_precomp G2_precomp;
const auto ONE = GT::one();
// step 6 (starting) - accumulate input consistency
dummy->major();
const auto accum_IC = pvk.encoded_IC_query().accumWitness(input);
if (0 != accum_IC.input_size() || ! proof.wellFormed()) return false;
// step 5 - knowledge commitment for A
dummy->major();
const G1_precomp proof_g_A_g_precomp(proof.A().G());
const G1_precomp proof_g_A_h_precomp(proof.A().H());
const auto kc_A_1 = PAIRING::ate_miller_loop(
proof_g_A_g_precomp,
pvk.vk_alphaA_g2_precomp());
const auto kc_A_2 = PAIRING::ate_miller_loop(
proof_g_A_h_precomp,
pvk.pp_G2_one_precomp());
const auto kc_A = PAIRING::final_exponentiation(
kc_A_1 * unitary_inverse(kc_A_2));
if (ONE != kc_A) return false;
// step 4 - knowledge commitment for B
dummy->major();
const G2_precomp proof_g_B_g_precomp(proof.B().G());
const G1_precomp proof_g_B_h_precomp(proof.B().H());
const auto kc_B_1 = PAIRING::ate_miller_loop(
pvk.vk_alphaB_g1_precomp(),
proof_g_B_g_precomp);
const auto kc_B_2 = PAIRING::ate_miller_loop(
proof_g_B_h_precomp,
pvk.pp_G2_one_precomp());
const auto kc_B = PAIRING::final_exponentiation(
kc_B_1 * unitary_inverse(kc_B_2));
if (ONE != kc_B) return false;
// step 3 - knowledge commitment for C
dummy->major();
const G1_precomp proof_g_C_g_precomp(proof.C().G());
const G1_precomp proof_g_C_h_precomp(proof.C().H());
const auto kc_C_1 = PAIRING::ate_miller_loop(
proof_g_C_g_precomp,
pvk.vk_alphaC_g2_precomp());
const auto kc_C_2 = PAIRING::ate_miller_loop(
proof_g_C_h_precomp,
pvk.pp_G2_one_precomp());
const auto kc_C = PAIRING::final_exponentiation(
kc_C_1 * unitary_inverse(kc_C_2));
if (ONE != kc_C) return false;
// step 2 - quadratic arithmetic program divisibility
dummy->major();
const G1_precomp proof_g_A_g_acc_precomp(proof.A().G() + accum_IC.base());
const G1_precomp proof_g_H_precomp(proof.H());
const auto QAP_1 = PAIRING::ate_miller_loop(
proof_g_A_g_acc_precomp,
proof_g_B_g_precomp);
const auto QAP_23 = PAIRING::ate_double_miller_loop(
proof_g_H_precomp,
pvk.vk_rC_Z_g2_precomp(),
proof_g_C_g_precomp,
pvk.pp_G2_one_precomp());
const auto QAP = PAIRING::final_exponentiation(
QAP_1 * unitary_inverse(QAP_23));
if (ONE != QAP) return false;
// step 1 - same coefficients
dummy->major();
const G1_precomp proof_g_K_precomp(proof.K());
const G1_precomp proof_g_A_g_acc_C_precomp(proof.A().G() + accum_IC.base() + proof.C().G());
const auto K_1 = PAIRING::ate_miller_loop(
proof_g_K_precomp,
pvk.vk_gamma_g2_precomp());
const auto K_23 = PAIRING::ate_double_miller_loop(
proof_g_A_g_acc_C_precomp,
pvk.vk_gamma_beta_g2_precomp(),
pvk.vk_gamma_beta_g1_precomp(),
proof_g_B_g_precomp);
const auto K = PAIRING::final_exponentiation(
K_1 * unitary_inverse(K_23));
if (ONE != K) return false;
return true;
}
template <typename PAIRING>
bool weakVerify(const PPZK_VerificationKey<PAIRING>& vk,
const R1Witness<typename PAIRING::Fr>& input,
const PPZK_Proof<PAIRING>& proof,
ProgressCallback* callback = nullptr)
{
return weakVerify(PPZK_PrecompVerificationKey<PAIRING>(vk),
input,
proof,
callback);
}
template <typename PAIRING>
bool strongVerify(const PPZK_PrecompVerificationKey<PAIRING>& pvk,
const R1Witness<typename PAIRING::Fr>& input,
const PPZK_Proof<PAIRING>& proof,
ProgressCallback* callback = nullptr)
{
return (pvk.encoded_IC_query().input_size() == input.size())
? weakVerify(pvk, input, proof, callback)
: false;
}
template <typename PAIRING>
bool strongVerify(const PPZK_VerificationKey<PAIRING>& vk,
const R1Witness<typename PAIRING::Fr>& input,
const PPZK_Proof<PAIRING>& proof,
ProgressCallback* callback = nullptr)
{
return strongVerify(PPZK_PrecompVerificationKey<PAIRING>(vk),
input,
proof,
callback);
}
} // namespace snarklib
#endif