2 *****************************************************************************
4 Implementation of interfaces for:
5 - a knowledge commitment, and
6 - a knowledge commitment vector.
8 See knowledge_commitment.hpp .
10 *****************************************************************************
11 * @author This file is part of libsnark, developed by SCIPR Lab
12 * and contributors (see AUTHORS).
13 * @copyright MIT license (see LICENSE file)
14 *****************************************************************************/
16 #ifndef KNOWLEDGE_COMMITMENT_TCC_
17 #define KNOWLEDGE_COMMITMENT_TCC_
22 template<typename T1, typename T2>
23 knowledge_commitment<T1, T2>::knowledge_commitment(const T1 &g, const T2 &h)
28 template<typename T1, typename T2>
29 knowledge_commitment<T1, T2> knowledge_commitment<T1, T2>::add(
30 const knowledge_commitment<T1, T2> &other) const
32 return knowledge_commitment<T1, T2>(
33 this->g.add(other.g), this->h.add(other.h));
36 template<typename T1, typename T2>
37 knowledge_commitment<T1, T2> knowledge_commitment<T1, T2>::mixed_add(
38 const knowledge_commitment<T1, T2> &other) const
40 return knowledge_commitment<T1, T2>(
41 this->g.mixed_add(other.g), this->h.mixed_add(other.h));
44 template<typename T1, typename T2>
45 knowledge_commitment<T1, T2> knowledge_commitment<T1, T2>::dbl() const
47 return knowledge_commitment<T1, T2>(this->g.dbl(), this->h.dbl());
50 template<typename T1, typename T2>
51 knowledge_commitment<T1, T2> knowledge_commitment<T1, T2>::operator+(
52 const knowledge_commitment<T1, T2> &other) const
57 template<typename T1, typename T2>
58 knowledge_commitment<T1, T2> knowledge_commitment<T1, T2>::operator-() const
60 return knowledge_commitment<T1, T2>(-(this->g), -(this->h));
63 template<typename T1, typename T2>
64 void knowledge_commitment<T1, T2>::to_special()
70 template<typename T1, typename T2>
71 bool knowledge_commitment<T1, T2>::is_special() const
73 return this->g->is_special() && this->h->is_special();
76 template<typename T1, typename T2>
77 bool knowledge_commitment<T1, T2>::is_zero() const
79 return (g.is_zero() && h.is_zero());
82 template<typename T1, typename T2>
83 bool knowledge_commitment<T1, T2>::operator==(
84 const knowledge_commitment<T1, T2> &other) const
86 return (this->g == other.g && this->h == other.h);
89 template<typename T1, typename T2>
90 bool knowledge_commitment<T1, T2>::operator!=(
91 const knowledge_commitment<T1, T2> &other) const
93 return !((*this) == other);
96 template<typename T1, typename T2>
97 knowledge_commitment<T1, T2> knowledge_commitment<T1, T2>::zero()
99 return knowledge_commitment<T1, T2>(T1::zero(), T2::zero());
102 template<typename T1, typename T2>
103 knowledge_commitment<T1, T2> knowledge_commitment<T1, T2>::one()
105 return knowledge_commitment<T1, T2>(T1::one(), T2::one());
108 template<typename T1, typename T2, mp_size_t m>
109 knowledge_commitment<T1, T2> operator*(
110 const libff::bigint<m> &lhs, const knowledge_commitment<T1, T2> &rhs)
112 return knowledge_commitment<T1, T2>(lhs * rhs.g, lhs * rhs.h);
119 const libff::bigint<m> &modulus_p>
120 knowledge_commitment<T1, T2> operator*(
121 const libff::Fp_model<m, modulus_p> &lhs,
122 const knowledge_commitment<T1, T2> &rhs)
124 return (lhs.as_bigint()) * rhs;
127 template<typename T1, typename T2>
128 void knowledge_commitment<T1, T2>::print() const
130 printf("knowledge_commitment.g:\n");
132 printf("knowledge_commitment.h:\n");
136 template<typename T1, typename T2>
137 size_t knowledge_commitment<T1, T2>::size_in_bits()
139 return T1::size_in_bits() + T2::size_in_bits();
142 template<typename T1, typename T2>
143 std::ostream &operator<<(
144 std::ostream &out, const knowledge_commitment<T1, T2> &kc)
146 out << kc.g << OUTPUT_SEPARATOR << kc.h;
150 template<typename T1, typename T2>
151 std::istream &operator>>(std::istream &in, knowledge_commitment<T1, T2> &kc)
154 libff::consume_OUTPUT_SEPARATOR(in);
159 template<typename T1, typename T2>
160 void knowledge_commitment<T1, T2>::batch_to_special_all_non_zeros(
161 std::vector<knowledge_commitment<T1, T2>> &vec)
163 // it is guaranteed that every vec[i] is non-zero,
164 // but, for any i, *one* of vec[i].g and vec[i].h might still be zero,
165 // so we still have to handle zeros separately
167 // we separately process g's first, then h's
168 // to lower memory consumption
169 std::vector<T1> g_vec;
170 g_vec.reserve(vec.size());
172 for (size_t i = 0; i < vec.size(); ++i) {
173 if (!vec[i].g.is_zero()) {
174 g_vec.emplace_back(vec[i].g);
178 T1::batch_to_special_all_non_zeros(g_vec);
179 auto g_it = g_vec.begin();
180 T1 T1_zero_special = T1::zero();
181 T1_zero_special.to_special();
183 for (size_t i = 0; i < vec.size(); ++i) {
184 if (!vec[i].g.is_zero()) {
188 vec[i].g = T1_zero_special;
194 // exactly the same thing, but for h:
195 std::vector<T2> h_vec;
196 h_vec.reserve(vec.size());
198 for (size_t i = 0; i < vec.size(); ++i) {
199 if (!vec[i].h.is_zero()) {
200 h_vec.emplace_back(vec[i].h);
204 T2::batch_to_special_all_non_zeros(h_vec);
205 auto h_it = h_vec.begin();
206 T2 T2_zero_special = T2::zero();
207 T2_zero_special.to_special();
209 for (size_t i = 0; i < vec.size(); ++i) {
210 if (!vec[i].h.is_zero()) {
214 vec[i].h = T2_zero_special;
221 } // namespace libsnark
223 #endif // KNOWLEDGE_COMMITMENT_TCC_