/src/mcl/include/mcl/ec.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | /** |
3 | | @file |
4 | | @brief elliptic curve |
5 | | @author MITSUNARI Shigeo(@herumi) |
6 | | @license modified new BSD license |
7 | | http://opensource.org/licenses/BSD-3-Clause |
8 | | */ |
9 | | #include <stdlib.h> |
10 | | #include <mcl/fp.hpp> |
11 | | #include <mcl/ecparam.hpp> |
12 | | #include <mcl/window_method.hpp> |
13 | | |
14 | | #ifdef _MSC_VER |
15 | | #pragma warning(push) |
16 | | #pragma warning(disable : 4458) |
17 | | #endif |
18 | | #ifdef MCL_USE_OMP |
19 | | #include <omp.h> |
20 | | #endif |
21 | | |
22 | | namespace mcl { |
23 | | |
24 | | template<class _Fp> class Fp2T; |
25 | | |
26 | | namespace ec { |
27 | | |
28 | | enum Mode { |
29 | | Jacobi = 0, |
30 | | Proj = 1, |
31 | | Affine |
32 | | }; |
33 | | |
34 | | namespace local { |
35 | | |
36 | | enum ModeCoeffA { |
37 | | Zero, |
38 | | Minus3, |
39 | | GenericA |
40 | | }; |
41 | | |
42 | | enum ModeCoeffB { |
43 | | Plus1, |
44 | | Plus4, |
45 | | GenericB |
46 | | }; |
47 | | |
48 | | template<class Ec, class Vec> |
49 | | void addTbl(Ec& Q, const Ec *tbl, const Vec& naf, size_t i) |
50 | 1.23M | { |
51 | 1.23M | if (i >= naf.size()) return; |
52 | 1.07M | int n = naf[i]; |
53 | 1.07M | if (n > 0) { |
54 | 90.4k | Q += tbl[(n - 1) >> 1]; |
55 | 988k | } else if (n < 0) { |
56 | 69.6k | Q -= tbl[(-n - 1) >> 1]; |
57 | 69.6k | } |
58 | 1.07M | } void mcl::ec::local::addTbl<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FixedArray<signed char, 130ul> >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, mcl::FixedArray<signed char, 130ul> const&, unsigned long) Line | Count | Source | 50 | 440k | { | 51 | 440k | if (i >= naf.size()) return; | 52 | 351k | int n = naf[i]; | 53 | 351k | if (n > 0) { | 54 | 30.5k | Q += tbl[(n - 1) >> 1]; | 55 | 320k | } else if (n < 0) { | 56 | 25.1k | Q -= tbl[(-n - 1) >> 1]; | 57 | 25.1k | } | 58 | 351k | } |
void mcl::ec::local::addTbl<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FixedArray<signed char, 385ul> >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, mcl::FixedArray<signed char, 385ul> const&, unsigned long) Line | Count | Source | 50 | 525k | { | 51 | 525k | if (i >= naf.size()) return; | 52 | 525k | int n = naf[i]; | 53 | 525k | if (n > 0) { | 54 | 53.0k | Q += tbl[(n - 1) >> 1]; | 55 | 472k | } else if (n < 0) { | 56 | 32.1k | Q -= tbl[(-n - 1) >> 1]; | 57 | 32.1k | } | 58 | 525k | } |
void mcl::ec::local::addTbl<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FixedArray<signed char, 68ul> >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, mcl::FixedArray<signed char, 68ul> const&, unsigned long) Line | Count | Source | 50 | 129k | { | 51 | 129k | if (i >= naf.size()) return; | 52 | 58.1k | int n = naf[i]; | 53 | 58.1k | if (n > 0) { | 54 | 4.58k | Q += tbl[(n - 1) >> 1]; | 55 | 53.5k | } else if (n < 0) { | 56 | 4.69k | Q -= tbl[(-n - 1) >> 1]; | 57 | 4.69k | } | 58 | 58.1k | } |
void mcl::ec::local::addTbl<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FixedArray<signed char, 769ul> >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, mcl::FixedArray<signed char, 769ul> const&, unsigned long) Line | Count | Source | 50 | 144k | { | 51 | 144k | if (i >= naf.size()) return; | 52 | 144k | int n = naf[i]; | 53 | 144k | if (n > 0) { | 54 | 2.33k | Q += tbl[(n - 1) >> 1]; | 55 | 142k | } else if (n < 0) { | 56 | 7.68k | Q -= tbl[(-n - 1) >> 1]; | 57 | 7.68k | } | 58 | 144k | } |
Unexecuted instantiation: void mcl::ec::local::addTbl<mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >, mcl::FixedArray<signed char, 68ul> >(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > const*, mcl::FixedArray<signed char, 68ul> const&, unsigned long) |
59 | | |
60 | | /* |
61 | | elliptic class E must have |
62 | | member variables of type Fp x, y, z |
63 | | static member a_, b_, specialA_ |
64 | | */ |
65 | | // x is negative <=> x < half(:=(p+1)/2) <=> a = 1 |
66 | | template<class F> |
67 | | bool get_a_flag(const F& x) |
68 | 0 | { |
69 | 0 | return x.isNegative(); |
70 | 0 | } |
71 | | |
72 | | // Im(x) is negative <=> Im(x) < half(:=(p+1)/2) <=> a = 1 |
73 | | |
74 | | template<class F> |
75 | | bool get_a_flag(const mcl::Fp2T<F>& x) |
76 | 0 | { |
77 | 0 | return get_a_flag(x.b); // x = a + bi |
78 | 0 | } |
79 | | |
80 | | template<class F> |
81 | | void mul3(F& x) |
82 | | { |
83 | | F t; |
84 | | F::add(t, x, x); |
85 | | F::add(x, t, x); // 3x |
86 | | } |
87 | | |
88 | | template<class F> |
89 | | void mul4(F& x) |
90 | 213 | { |
91 | 213 | F::add(x, x, x); |
92 | 213 | F::add(x, x, x); |
93 | 213 | } void mcl::ec::local::mul4<mcl::FpT<mcl::bn::local::FpTag, 384ul> >(mcl::FpT<mcl::bn::local::FpTag, 384ul>&) Line | Count | Source | 90 | 213 | { | 91 | 213 | F::add(x, x, x); | 92 | 213 | F::add(x, x, x); | 93 | 213 | } |
Unexecuted instantiation: void mcl::ec::local::mul4<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >(mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >&) |
94 | | |
95 | | template<class F> |
96 | | void mul12(F& x) |
97 | | { |
98 | | F t; |
99 | | F::add(t, x, x); |
100 | | F::add(x, t, x); // 3x |
101 | | mul4(x); |
102 | | } |
103 | | |
104 | | /* |
105 | | Q = x P |
106 | | splitN = 2(G1) or 4(G2) |
107 | | w : window size |
108 | | */ |
109 | | template<class GLV, class G> |
110 | | void mulGLV_CT(G& Q, const G& P, const void *yVec) |
111 | 0 | { |
112 | 0 | const size_t w = 4; |
113 | 0 | typedef typename GLV::Fr F; |
114 | 0 | fp::getMpzAtType getMpzAt = fp::getMpzAtT<F>; |
115 | 0 | const int splitN = GLV::splitN; |
116 | 0 | const size_t tblSize = 1 << w; |
117 | 0 | G tbl[splitN][tblSize]; |
118 | 0 | bool negTbl[splitN]; |
119 | 0 | mpz_class u[splitN], y; |
120 | 0 | getMpzAt(y, yVec, 0); |
121 | 0 | GLV::split(u, y); |
122 | 0 | for (int i = 0; i < splitN; i++) { |
123 | 0 | if (u[i] < 0) { |
124 | 0 | gmp::neg(u[i], u[i]); |
125 | 0 | negTbl[i] = true; |
126 | 0 | } else { |
127 | 0 | negTbl[i] = false; |
128 | 0 | } |
129 | 0 | tbl[i][0].clear(); |
130 | 0 | } |
131 | 0 | tbl[0][1] = P; |
132 | 0 | for (size_t j = 2; j < tblSize; j++) { |
133 | 0 | G::add(tbl[0][j], tbl[0][j - 1], P); |
134 | 0 | } |
135 | 0 | for (int i = 1; i < splitN; i++) { |
136 | 0 | for (size_t j = 1; j < tblSize; j++) { |
137 | 0 | GLV::mulLambda(tbl[i][j], tbl[i - 1][j]); |
138 | 0 | } |
139 | 0 | } |
140 | 0 | for (int i = 0; i < splitN; i++) { |
141 | 0 | if (negTbl[i]) { |
142 | 0 | for (size_t j = 0; j < tblSize; j++) { |
143 | 0 | G::neg(tbl[i][j], tbl[i][j]); |
144 | 0 | } |
145 | 0 | } |
146 | 0 | } |
147 | 0 | mcl::FixedArray<uint8_t, sizeof(F) * 8 / w + 1> vTbl[splitN]; |
148 | 0 | size_t loopN = 0; |
149 | 0 | { |
150 | 0 | size_t maxBitSize = 0; |
151 | 0 | fp::BitIterator<Unit> itr[splitN]; |
152 | 0 | for (int i = 0; i < splitN; i++) { |
153 | 0 | itr[i].init(gmp::getUnit(u[i]), gmp::getUnitSize(u[i])); |
154 | 0 | size_t bitSize = itr[i].getBitSize(); |
155 | 0 | if (bitSize > maxBitSize) maxBitSize = bitSize; |
156 | 0 | } |
157 | 0 | loopN = (maxBitSize + w - 1) / w; |
158 | 0 | for (int i = 0; i < splitN; i++) { |
159 | 0 | bool b = vTbl[i].resize(loopN); |
160 | 0 | assert(b); |
161 | 0 | (void)b; |
162 | 0 | for (size_t j = 0; j < loopN; j++) { |
163 | 0 | vTbl[i][loopN - 1 - j] = (uint8_t)itr[i].getNext(w); |
164 | 0 | } |
165 | 0 | } |
166 | 0 | } |
167 | 0 | Q.clear(); |
168 | 0 | for (size_t k = 0; k < loopN; k++) { |
169 | 0 | for (size_t i = 0; i < w; i++) { |
170 | 0 | G::dbl(Q, Q); |
171 | 0 | } |
172 | 0 | for (size_t i = 0; i < splitN; i++) { |
173 | 0 | uint8_t v = vTbl[i][k]; |
174 | 0 | G::add(Q, Q, tbl[i][v]); |
175 | 0 | } |
176 | 0 | } |
177 | 0 | } Unexecuted instantiation: void mcl::ec::local::mulGLV_CT<mcl::bn::local::GLV1, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, void const*) Unexecuted instantiation: void mcl::ec::local::mulGLV_CT<mcl::bn::local::GLV2T<mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, void const*) Unexecuted instantiation: void mcl::ec::local::mulGLV_CT<mcl::bn::local::GLV2T<mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > >(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > const&, void const*) Unexecuted instantiation: void mcl::ec::local::mulGLV_CT<mcl::GLV1T<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, void const*) |
178 | | |
179 | | // AsArrayOfFp[i] gets P[i].z |
180 | | template<class E> |
181 | | struct AsArrayOfFp { |
182 | | typedef typename E::Fp Fp; |
183 | | const E* P; |
184 | 3.98k | AsArrayOfFp(const E* P) : P(P) {}mcl::ec::local::AsArrayOfFp<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >::AsArrayOfFp(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*) Line | Count | Source | 184 | 778 | AsArrayOfFp(const E* P) : P(P) {} |
mcl::ec::local::AsArrayOfFp<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >::AsArrayOfFp(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*) Line | Count | Source | 184 | 3.21k | AsArrayOfFp(const E* P) : P(P) {} |
|
185 | 187k | const Fp& operator[](size_t i) const { return P[i].z; }mcl::ec::local::AsArrayOfFp<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >::operator[](unsigned long) const Line | Count | Source | 185 | 36.7k | const Fp& operator[](size_t i) const { return P[i].z; } |
mcl::ec::local::AsArrayOfFp<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >::operator[](unsigned long) const Line | Count | Source | 185 | 150k | const Fp& operator[](size_t i) const { return P[i].z; } |
|
186 | 0 | void operator+=(size_t n) { P += n; }Unexecuted instantiation: mcl::ec::local::AsArrayOfFp<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >::operator+=(unsigned long) Unexecuted instantiation: mcl::ec::local::AsArrayOfFp<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >::operator+=(unsigned long) |
187 | | }; |
188 | | |
189 | | template<class E> |
190 | | void _normalizeJacobi(E& Q, const E& P, typename E::Fp& inv) |
191 | 33.5k | { |
192 | 33.5k | typedef typename E::Fp F; |
193 | 33.5k | F inv2; |
194 | 33.5k | F::sqr(inv2, inv); |
195 | 33.5k | F::mul(Q.x, P.x, inv2); |
196 | 33.5k | F::mul(Q.y, P.y, inv2); |
197 | 33.5k | Q.y *= inv; |
198 | 33.5k | Q.z = 1; |
199 | 33.5k | } void mcl::ec::local::_normalizeJacobi<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::Fp&) Line | Count | Source | 191 | 6.98k | { | 192 | 6.98k | typedef typename E::Fp F; | 193 | 6.98k | F inv2; | 194 | 6.98k | F::sqr(inv2, inv); | 195 | 6.98k | F::mul(Q.x, P.x, inv2); | 196 | 6.98k | F::mul(Q.y, P.y, inv2); | 197 | 6.98k | Q.y *= inv; | 198 | 6.98k | Q.z = 1; | 199 | 6.98k | } |
void mcl::ec::local::_normalizeJacobi<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::Fp&) Line | Count | Source | 191 | 26.2k | { | 192 | 26.2k | typedef typename E::Fp F; | 193 | 26.2k | F inv2; | 194 | 26.2k | F::sqr(inv2, inv); | 195 | 26.2k | F::mul(Q.x, P.x, inv2); | 196 | 26.2k | F::mul(Q.y, P.y, inv2); | 197 | 26.2k | Q.y *= inv; | 198 | 26.2k | Q.z = 1; | 199 | 26.2k | } |
void mcl::ec::local::_normalizeJacobi<mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >(mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> >&, mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> >::Fp&) Line | Count | Source | 191 | 323 | { | 192 | 323 | typedef typename E::Fp F; | 193 | 323 | F inv2; | 194 | 323 | F::sqr(inv2, inv); | 195 | 323 | F::mul(Q.x, P.x, inv2); | 196 | 323 | F::mul(Q.y, P.y, inv2); | 197 | 323 | Q.y *= inv; | 198 | 323 | Q.z = 1; | 199 | 323 | } |
|
200 | | |
201 | | template<class E> |
202 | | void _normalizeProj(E& Q, const E& P, typename E::Fp& inv) |
203 | 0 | { |
204 | 0 | typedef typename E::Fp F; |
205 | 0 | F::mul(Q.x, P.x, inv); |
206 | 0 | F::mul(Q.y, P.y, inv); |
207 | 0 | Q.z = 1; |
208 | 0 | } Unexecuted instantiation: void mcl::ec::local::_normalizeProj<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::Fp&) Unexecuted instantiation: void mcl::ec::local::_normalizeProj<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::Fp&) |
209 | | |
210 | | template<class E> |
211 | | void _normalize(E& Q, const E& P, typename E::Fp& inv) |
212 | 28.1k | { |
213 | 28.1k | switch (E::mode_) { |
214 | 28.1k | case ec::Jacobi: |
215 | 28.1k | _normalizeJacobi(Q, P, inv); |
216 | 28.1k | break; |
217 | 0 | case ec::Proj: |
218 | 0 | _normalizeProj(Q, P, inv); |
219 | 0 | break; |
220 | 0 | default: |
221 | 0 | assert(0); |
222 | 0 | break; |
223 | 28.1k | } |
224 | 28.1k | } void mcl::ec::local::_normalize<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::Fp&) Line | Count | Source | 212 | 5.67k | { | 213 | 5.67k | switch (E::mode_) { | 214 | 5.67k | case ec::Jacobi: | 215 | 5.67k | _normalizeJacobi(Q, P, inv); | 216 | 5.67k | break; | 217 | 0 | case ec::Proj: | 218 | 0 | _normalizeProj(Q, P, inv); | 219 | 0 | break; | 220 | 0 | default: | 221 | 0 | assert(0); | 222 | 0 | break; | 223 | 5.67k | } | 224 | 5.67k | } |
void mcl::ec::local::_normalize<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::Fp&) Line | Count | Source | 212 | 22.4k | { | 213 | 22.4k | switch (E::mode_) { | 214 | 22.4k | case ec::Jacobi: | 215 | 22.4k | _normalizeJacobi(Q, P, inv); | 216 | 22.4k | break; | 217 | 0 | case ec::Proj: | 218 | 0 | _normalizeProj(Q, P, inv); | 219 | 0 | break; | 220 | 0 | default: | 221 | 0 | assert(0); | 222 | 0 | break; | 223 | 22.4k | } | 224 | 22.4k | } |
|
225 | | |
226 | | /* |
227 | | Q[i] = normalize(P[i]) for i = 0, ..., n-1 |
228 | | AsArray : Pz[i] to access like as F[i] in invVecT |
229 | | N : alloc size |
230 | | */ |
231 | | template<class F, class Eout, class Ein, class AsArrayOfFp> |
232 | | void normalizeVecT(Eout& Q, Ein& P, size_t n, size_t N = 256) |
233 | 3.98k | { |
234 | 3.98k | F *inv = (F*)CYBOZU_ALLOCA(sizeof(F) * N); |
235 | 3.98k | bool PisEqualToQ = &P[0] == &Q[0]; |
236 | 3.98k | for (;;) { |
237 | 3.98k | size_t doneN = (n < N) ? n : N; |
238 | 3.98k | AsArrayOfFp Pz(P); |
239 | 3.98k | invVecT<F>(inv, Pz, doneN, N); |
240 | 35.9k | for (size_t i = 0; i < doneN; i++) { |
241 | 31.9k | if (P[i].z.isZero() || P[i].z.isOne()) { |
242 | 3.75k | if (!PisEqualToQ) Q[i] = P[i]; |
243 | 28.1k | } else { |
244 | 28.1k | local::_normalize(Q[i], P[i], inv[i]); |
245 | 28.1k | } |
246 | 31.9k | } |
247 | 3.98k | n -= doneN; |
248 | 3.98k | if (n == 0) return; |
249 | 0 | Q += doneN; |
250 | 0 | P += doneN; |
251 | 0 | } |
252 | 3.98k | } void mcl::ec::local::normalizeVecT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, mcl::ec::local::AsArrayOfFp<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*&, unsigned long, unsigned long) Line | Count | Source | 233 | 778 | { | 234 | 778 | F *inv = (F*)CYBOZU_ALLOCA(sizeof(F) * N); | 235 | 778 | bool PisEqualToQ = &P[0] == &Q[0]; | 236 | 778 | for (;;) { | 237 | 778 | size_t doneN = (n < N) ? n : N; | 238 | 778 | AsArrayOfFp Pz(P); | 239 | 778 | invVecT<F>(inv, Pz, doneN, N); | 240 | 7.00k | for (size_t i = 0; i < doneN; i++) { | 241 | 6.22k | if (P[i].z.isZero() || P[i].z.isOne()) { | 242 | 548 | if (!PisEqualToQ) Q[i] = P[i]; | 243 | 5.67k | } else { | 244 | 5.67k | local::_normalize(Q[i], P[i], inv[i]); | 245 | 5.67k | } | 246 | 6.22k | } | 247 | 778 | n -= doneN; | 248 | 778 | if (n == 0) return; | 249 | 0 | Q += doneN; | 250 | 0 | P += doneN; | 251 | 0 | } | 252 | 778 | } |
void mcl::ec::local::normalizeVecT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, mcl::ec::local::AsArrayOfFp<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*&, unsigned long, unsigned long) Line | Count | Source | 233 | 3.21k | { | 234 | 3.21k | F *inv = (F*)CYBOZU_ALLOCA(sizeof(F) * N); | 235 | 3.21k | bool PisEqualToQ = &P[0] == &Q[0]; | 236 | 3.21k | for (;;) { | 237 | 3.21k | size_t doneN = (n < N) ? n : N; | 238 | 3.21k | AsArrayOfFp Pz(P); | 239 | 3.21k | invVecT<F>(inv, Pz, doneN, N); | 240 | 28.8k | for (size_t i = 0; i < doneN; i++) { | 241 | 25.6k | if (P[i].z.isZero() || P[i].z.isOne()) { | 242 | 3.21k | if (!PisEqualToQ) Q[i] = P[i]; | 243 | 22.4k | } else { | 244 | 22.4k | local::_normalize(Q[i], P[i], inv[i]); | 245 | 22.4k | } | 246 | 25.6k | } | 247 | 3.21k | n -= doneN; | 248 | 3.21k | if (n == 0) return; | 249 | 0 | Q += doneN; | 250 | 0 | P += doneN; | 251 | 0 | } | 252 | 3.21k | } |
|
253 | | |
254 | | /* |
255 | | split x in [0, r-1] to (a, b) such that x = a + b L, 0 <= a < L, 0 <= b <= L+1 |
256 | | a[] : 128 bit |
257 | | b[] : 128 bit |
258 | | x[] : 256 bit |
259 | | */ |
260 | | inline void optimizedSplitRawForBLS12_381(Unit *a, Unit *b, const Unit *x) |
261 | 3.21k | { |
262 | | /* |
263 | | z = -0xd201000000010000 |
264 | | L = z^2-1 = 0xac45a4010001a40200000000ffffffff |
265 | | s=255 |
266 | | q = (1<<s)//L = 0xbe35f678f00fd56eb1fb72917b67f718 |
267 | | H = 1<<128 |
268 | | */ |
269 | 3.21k | static const Unit L[] = { MCL_U64_TO_UNIT(0x00000000ffffffff), MCL_U64_TO_UNIT(0xac45a4010001a402) }; |
270 | 3.21k | static const Unit q[] = { MCL_U64_TO_UNIT(0xb1fb72917b67f718), MCL_U64_TO_UNIT(0xbe35f678f00fd56e) }; |
271 | 3.21k | static const Unit one[] = { MCL_U64_TO_UNIT(1), MCL_U64_TO_UNIT(0) }; |
272 | 3.21k | static const size_t n = 128 / mcl::UnitBitSize; |
273 | 3.21k | Unit xH[n+1]; // x = xH * (H/2) + xL |
274 | 3.21k | mcl::bint::shrT<n+1>(xH, x+n-1, mcl::UnitBitSize-1); // >>127 |
275 | 3.21k | Unit t[n*2]; |
276 | 3.21k | mcl::bint::mulT<n>(t, xH, q); |
277 | 3.21k | mcl::bint::copyT<n>(b, t+n); // (xH * q)/H |
278 | 3.21k | mcl::bint::mulT<n>(t, b, L); // bL |
279 | 3.21k | mcl::bint::subT<n*2>(t, x, t); // x - bL |
280 | 3.21k | Unit d = mcl::bint::subT<n>(a, t, L); |
281 | 3.21k | if (t[n] - d == 0) { |
282 | 428 | mcl::bint::addT<n>(b, b, one); |
283 | 2.78k | } else { |
284 | 2.78k | mcl::bint::copyT<n>(a, t); |
285 | 2.78k | } |
286 | 3.21k | } |
287 | | |
288 | | inline void optimizedSplitRawForBLS12_377(Unit *a, Unit *b, const Unit *x) |
289 | 0 | { |
290 | | /* |
291 | | z = -0xd201000000010000 |
292 | | L = z^2-1 = 0x452217cc900000010a11800000000000 |
293 | | s=254 |
294 | | q = (1<<s)//L = 0xecfdeaa5a7f4dc581fdcbb4cabe4060b |
295 | | H = 1<<128 |
296 | | */ |
297 | 0 | static const Unit L[] = { MCL_U64_TO_UNIT(0x0a11800000000000), MCL_U64_TO_UNIT(0x452217cc90000001) }; |
298 | 0 | static const Unit q[] = { MCL_U64_TO_UNIT(0x1fdcbb4cabe4060b), MCL_U64_TO_UNIT(0xecfdeaa5a7f4dc58) }; |
299 | 0 | static const Unit one[] = { MCL_U64_TO_UNIT(1), MCL_U64_TO_UNIT(0) }; |
300 | 0 | static const size_t n = 128 / mcl::UnitBitSize; |
301 | 0 | Unit xH[n+1]; // x = xH * (H/4) + xL |
302 | 0 | mcl::bint::shrT<n+1>(xH, x+n-1, mcl::UnitBitSize-2); // >>126 |
303 | 0 | Unit t[n*2]; |
304 | 0 | mcl::bint::mulT<n>(t, xH, q); |
305 | 0 | mcl::bint::copyT<n>(b, t+n); // (xH * q)/H |
306 | 0 | mcl::bint::mulT<n>(t, b, L); // bL |
307 | 0 | mcl::bint::subT<n*2>(t, x, t); // x - bL |
308 | 0 | Unit d = mcl::bint::subT<n>(a, t, L); |
309 | 0 | if (d == 0) { |
310 | 0 | mcl::bint::addT<n>(b, b, one); |
311 | 0 | } else { |
312 | 0 | mcl::bint::copyT<n>(a, t); |
313 | 0 | } |
314 | 0 | } |
315 | | |
316 | | } // mcl::ec::local |
317 | | |
318 | | // [X:Y:Z] as Proj = (X/Z, Y/Z) as Affine = [XZ:YZ^2:Z] as Jacobi |
319 | | // Remark. convert P = [*:*:0] to Q = [0:0:0] |
320 | | template<class E> |
321 | | void ProjToJacobi(E& Q, const E& P) |
322 | | { |
323 | | typedef typename E::Fp F; |
324 | | F::mul(Q.x, P.x, P.z); |
325 | | F::mul(Q.y, P.y, P.z); |
326 | | F::mul(Q.y, Q.y, P.z); |
327 | | Q.z = P.z; |
328 | | } |
329 | | |
330 | | // [X:Y:Z] as Jacobi = (X/Z^2, Y/Z^3) as Affine = [XZ:Y:Z^3] as Proj |
331 | | // Remark. convert P = [*:1:0] to Q = [0:1:0] |
332 | | template<class E> |
333 | | void JacobiToProj(E& Q, const E& P) |
334 | | { |
335 | | typedef typename E::Fp F; |
336 | | F::mul(Q.x, P.x, P.z); |
337 | | Q.y = P.y; |
338 | | F t; |
339 | | F::sqr(t, P.z); |
340 | | F::mul(Q.z, P.z, t); |
341 | | } |
342 | | |
343 | | template<class E> |
344 | | void normalizeJacobi(E& P) |
345 | 10.6k | { |
346 | 10.6k | if (P.z.isZero() || P.z.isOne()) return; |
347 | 5.35k | typedef typename E::Fp F; |
348 | 5.35k | F::inv(P.z, P.z); |
349 | 5.35k | local::_normalizeJacobi(P, P, P.z); |
350 | 5.35k | } void mcl::ec::normalizeJacobi<mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >(mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> >&) Line | Count | Source | 345 | 329 | { | 346 | 329 | if (P.z.isZero() || P.z.isOne()) return; | 347 | 323 | typedef typename E::Fp F; | 348 | 323 | F::inv(P.z, P.z); | 349 | 323 | local::_normalizeJacobi(P, P, P.z); | 350 | 323 | } |
void mcl::ec::normalizeJacobi<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&) Line | Count | Source | 345 | 2.72k | { | 346 | 2.72k | if (P.z.isZero() || P.z.isOne()) return; | 347 | 1.30k | typedef typename E::Fp F; | 348 | 1.30k | F::inv(P.z, P.z); | 349 | 1.30k | local::_normalizeJacobi(P, P, P.z); | 350 | 1.30k | } |
void mcl::ec::normalizeJacobi<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&) Line | Count | Source | 345 | 7.57k | { | 346 | 7.57k | if (P.z.isZero() || P.z.isOne()) return; | 347 | 3.72k | typedef typename E::Fp F; | 348 | 3.72k | F::inv(P.z, P.z); | 349 | 3.72k | local::_normalizeJacobi(P, P, P.z); | 350 | 3.72k | } |
|
351 | | |
352 | | /* |
353 | | Q[i] = normalize(P[i]) for i = 0, ..., n-1 |
354 | | AsArray : Pz[i] to access like as F[i] in invVecT |
355 | | N : alloc size |
356 | | */ |
357 | | template<class E> |
358 | | void normalizeVec(E *Q, const E *P, size_t n) |
359 | 3.98k | { |
360 | 3.98k | local::normalizeVecT<typename E::Fp, E*, const E*, local::AsArrayOfFp<E> >(Q, P, n); |
361 | 3.98k | } void mcl::ec::normalizeVec<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, unsigned long) Line | Count | Source | 359 | 778 | { | 360 | 778 | local::normalizeVecT<typename E::Fp, E*, const E*, local::AsArrayOfFp<E> >(Q, P, n); | 361 | 778 | } |
void mcl::ec::normalizeVec<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, unsigned long) Line | Count | Source | 359 | 3.21k | { | 360 | 3.21k | local::normalizeVecT<typename E::Fp, E*, const E*, local::AsArrayOfFp<E> >(Q, P, n); | 361 | 3.21k | } |
|
362 | | |
363 | | // (x/z^2, y/z^3) |
364 | | template<class E> |
365 | | bool isEqualJacobi(const E& P1, const E& P2) |
366 | 4.93k | { |
367 | 4.93k | typedef typename E::Fp F; |
368 | 4.93k | bool zero1 = P1.isZero(); |
369 | 4.93k | bool zero2 = P2.isZero(); |
370 | 4.93k | if (zero1) { |
371 | 133 | return zero2; |
372 | 133 | } |
373 | 4.80k | if (zero2) return false; |
374 | 4.80k | F s1, s2, t1, t2; |
375 | 4.80k | F::sqr(s1, P1.z); |
376 | 4.80k | F::sqr(s2, P2.z); |
377 | 4.80k | F::mul(t1, P1.x, s2); |
378 | 4.80k | F::mul(t2, P2.x, s1); |
379 | 4.80k | if (t1 != t2) return false; |
380 | 4.71k | F::mul(t1, P1.y, s2); |
381 | 4.71k | F::mul(t2, P2.y, s1); |
382 | 4.71k | t1 *= P2.z; |
383 | 4.71k | t2 *= P1.z; |
384 | 4.71k | return t1 == t2; |
385 | 4.80k | } bool mcl::ec::isEqualJacobi<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 366 | 957 | { | 367 | 957 | typedef typename E::Fp F; | 368 | 957 | bool zero1 = P1.isZero(); | 369 | 957 | bool zero2 = P2.isZero(); | 370 | 957 | if (zero1) { | 371 | 6 | return zero2; | 372 | 6 | } | 373 | 951 | if (zero2) return false; | 374 | 951 | F s1, s2, t1, t2; | 375 | 951 | F::sqr(s1, P1.z); | 376 | 951 | F::sqr(s2, P2.z); | 377 | 951 | F::mul(t1, P1.x, s2); | 378 | 951 | F::mul(t2, P2.x, s1); | 379 | 951 | if (t1 != t2) return false; | 380 | 914 | F::mul(t1, P1.y, s2); | 381 | 914 | F::mul(t2, P2.y, s1); | 382 | 914 | t1 *= P2.z; | 383 | 914 | t2 *= P1.z; | 384 | 914 | return t1 == t2; | 385 | 951 | } |
bool mcl::ec::isEqualJacobi<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 366 | 3.98k | { | 367 | 3.98k | typedef typename E::Fp F; | 368 | 3.98k | bool zero1 = P1.isZero(); | 369 | 3.98k | bool zero2 = P2.isZero(); | 370 | 3.98k | if (zero1) { | 371 | 127 | return zero2; | 372 | 127 | } | 373 | 3.85k | if (zero2) return false; | 374 | 3.85k | F s1, s2, t1, t2; | 375 | 3.85k | F::sqr(s1, P1.z); | 376 | 3.85k | F::sqr(s2, P2.z); | 377 | 3.85k | F::mul(t1, P1.x, s2); | 378 | 3.85k | F::mul(t2, P2.x, s1); | 379 | 3.85k | if (t1 != t2) return false; | 380 | 3.80k | F::mul(t1, P1.y, s2); | 381 | 3.80k | F::mul(t2, P2.y, s1); | 382 | 3.80k | t1 *= P2.z; | 383 | 3.80k | t2 *= P1.z; | 384 | 3.80k | return t1 == t2; | 385 | 3.85k | } |
|
386 | | |
387 | | // return (P1 == P2) ? 1 : (P1 == -P2) ? -1 : 0 |
388 | | template<class E> |
389 | | int isEqualOrMinusJacobi(const E& P1, const E& P2) |
390 | | { |
391 | | typedef typename E::Fp F; |
392 | | bool zero1 = P1.isZero(); |
393 | | bool zero2 = P2.isZero(); |
394 | | if (zero1) { |
395 | | return zero2 ? 1 : 0; |
396 | | } |
397 | | if (zero2) return 0; |
398 | | F s1, s2, t1, t2; |
399 | | F::sqr(s1, P1.z); |
400 | | F::sqr(s2, P2.z); |
401 | | F::mul(t1, P1.x, s2); |
402 | | F::mul(t2, P2.x, s1); |
403 | | if (t1 != t2) return 0; |
404 | | F::mul(t1, P1.y, s2); |
405 | | F::mul(t2, P2.y, s1); |
406 | | t1 *= P2.z; |
407 | | t2 *= P1.z; |
408 | | if (t1 == t2) return 1; |
409 | | F::neg(t1, t1); |
410 | | if (t1 == t2) return -1; |
411 | | return 0; |
412 | | } |
413 | | |
414 | | // Y^2 == X(X^2 + aZ^4) + bZ^6 |
415 | | template<class E> |
416 | | bool isValidJacobi(const E& P) |
417 | 378 | { |
418 | 378 | typedef typename E::Fp F; |
419 | 378 | F y2, x2, z2, z4, t; |
420 | 378 | F::sqr(x2, P.x); |
421 | 378 | F::sqr(y2, P.y); |
422 | 378 | F::sqr(z2, P.z); |
423 | 378 | F::sqr(z4, z2); |
424 | 378 | F::mul(t, z4, E::a_); |
425 | 378 | t += x2; |
426 | 378 | t *= P.x; |
427 | 378 | z4 *= z2; |
428 | 378 | if (E::specialB_ == ec::local::Plus1) { |
429 | | // pass |
430 | 0 | } else |
431 | 378 | if (E::specialB_ == ec::local::Plus4) { |
432 | 213 | local::mul4(z4); |
433 | 213 | } else |
434 | 165 | { |
435 | 165 | z4 *= E::b_; |
436 | 165 | } |
437 | 378 | t += z4; |
438 | 378 | return y2 == t; |
439 | 378 | } bool mcl::ec::isValidJacobi<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 417 | 213 | { | 418 | 213 | typedef typename E::Fp F; | 419 | 213 | F y2, x2, z2, z4, t; | 420 | 213 | F::sqr(x2, P.x); | 421 | 213 | F::sqr(y2, P.y); | 422 | 213 | F::sqr(z2, P.z); | 423 | 213 | F::sqr(z4, z2); | 424 | 213 | F::mul(t, z4, E::a_); | 425 | 213 | t += x2; | 426 | 213 | t *= P.x; | 427 | 213 | z4 *= z2; | 428 | 213 | if (E::specialB_ == ec::local::Plus1) { | 429 | | // pass | 430 | 0 | } else | 431 | 213 | if (E::specialB_ == ec::local::Plus4) { | 432 | 213 | local::mul4(z4); | 433 | 213 | } else | 434 | 0 | { | 435 | 0 | z4 *= E::b_; | 436 | 0 | } | 437 | 213 | t += z4; | 438 | 213 | return y2 == t; | 439 | 213 | } |
bool mcl::ec::isValidJacobi<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 417 | 165 | { | 418 | 165 | typedef typename E::Fp F; | 419 | 165 | F y2, x2, z2, z4, t; | 420 | 165 | F::sqr(x2, P.x); | 421 | 165 | F::sqr(y2, P.y); | 422 | 165 | F::sqr(z2, P.z); | 423 | 165 | F::sqr(z4, z2); | 424 | 165 | F::mul(t, z4, E::a_); | 425 | 165 | t += x2; | 426 | 165 | t *= P.x; | 427 | 165 | z4 *= z2; | 428 | 165 | if (E::specialB_ == ec::local::Plus1) { | 429 | | // pass | 430 | 0 | } else | 431 | 165 | if (E::specialB_ == ec::local::Plus4) { | 432 | 0 | local::mul4(z4); | 433 | 0 | } else | 434 | 165 | { | 435 | 165 | z4 *= E::b_; | 436 | 165 | } | 437 | 165 | t += z4; | 438 | 165 | return y2 == t; | 439 | 165 | } |
|
440 | | |
441 | | /* |
442 | | M > S + A |
443 | | a = 0 2M + 5S + 14A |
444 | | a = -3 2M + 7S + 15A |
445 | | generic 3M + 7S + 15A |
446 | | M == S |
447 | | a = 0 3M + 4S + 13A |
448 | | a = -3 3M + 6S + 14A |
449 | | generic 4M + 6S + 14A |
450 | | */ |
451 | | template<class E> |
452 | | void dblJacobi(E& R, const E& P) |
453 | 938k | { |
454 | 938k | typedef typename E::Fp F; |
455 | 938k | if (P.isZero()) { |
456 | 28.2k | R.clear(); |
457 | 28.2k | return; |
458 | 28.2k | } |
459 | 910k | const bool isPzOne = P.z.isOne(); |
460 | 910k | F x2, y2, xy, t; |
461 | 910k | F::sqr(x2, P.x); |
462 | 910k | F::sqr(y2, P.y); |
463 | 910k | if (sizeof(F) <= 32) { // M == S |
464 | 0 | F::mul(xy, P.x, y2); |
465 | 0 | xy += xy; |
466 | 0 | F::sqr(y2, y2); |
467 | 910k | } else { // M > S + A |
468 | 910k | F::add(xy, P.x, y2); |
469 | 910k | F::sqr(y2, y2); |
470 | 910k | F::sqr(xy, xy); |
471 | 910k | xy -= x2; |
472 | 910k | xy -= y2; |
473 | 910k | } |
474 | 910k | xy += xy; // 4xy^2 |
475 | 910k | switch (E::specialA_) { |
476 | 910k | case local::Zero: |
477 | 910k | F::mul2(t, x2); |
478 | 910k | x2 += t; |
479 | 910k | break; |
480 | 0 | case local::Minus3: |
481 | 0 | if (isPzOne) { |
482 | 0 | x2 -= P.z; |
483 | 0 | } else { |
484 | 0 | F::sqr(t, P.z); |
485 | 0 | F::sqr(t, t); |
486 | 0 | x2 -= t; |
487 | 0 | } |
488 | 0 | F::mul2(t, x2); |
489 | 0 | x2 += t; |
490 | 0 | break; |
491 | 71 | case local::GenericA: |
492 | 71 | default: |
493 | 71 | if (isPzOne) { |
494 | 0 | t = E::a_; |
495 | 71 | } else { |
496 | 71 | F::sqr(t, P.z); |
497 | 71 | F::sqr(t, t); |
498 | 71 | t *= E::a_; |
499 | 71 | } |
500 | 71 | t += x2; |
501 | 71 | F::mul2(x2, x2); |
502 | 71 | x2 += t; |
503 | 71 | break; |
504 | 910k | } |
505 | 910k | F::sqr(R.x, x2); |
506 | 910k | R.x -= xy; |
507 | 910k | R.x -= xy; |
508 | 910k | if (isPzOne) { |
509 | 12.2k | R.z = P.y; |
510 | 898k | } else { |
511 | 898k | F::mul(R.z, P.y, P.z); |
512 | 898k | } |
513 | 910k | F::mul2(R.z, R.z); |
514 | 910k | F::sub(R.y, xy, R.x); |
515 | 910k | R.y *= x2; |
516 | 910k | F::mul2(y2, y2); |
517 | 910k | F::mul2(y2, y2); |
518 | 910k | F::mul2(y2, y2); |
519 | 910k | R.y -= y2; |
520 | 910k | } void mcl::ec::dblJacobi<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 453 | 181k | { | 454 | 181k | typedef typename E::Fp F; | 455 | 181k | if (P.isZero()) { | 456 | 4.23k | R.clear(); | 457 | 4.23k | return; | 458 | 4.23k | } | 459 | 177k | const bool isPzOne = P.z.isOne(); | 460 | 177k | F x2, y2, xy, t; | 461 | 177k | F::sqr(x2, P.x); | 462 | 177k | F::sqr(y2, P.y); | 463 | 177k | if (sizeof(F) <= 32) { // M == S | 464 | 0 | F::mul(xy, P.x, y2); | 465 | 0 | xy += xy; | 466 | 0 | F::sqr(y2, y2); | 467 | 177k | } else { // M > S + A | 468 | 177k | F::add(xy, P.x, y2); | 469 | 177k | F::sqr(y2, y2); | 470 | 177k | F::sqr(xy, xy); | 471 | 177k | xy -= x2; | 472 | 177k | xy -= y2; | 473 | 177k | } | 474 | 177k | xy += xy; // 4xy^2 | 475 | 177k | switch (E::specialA_) { | 476 | 177k | case local::Zero: | 477 | 177k | F::mul2(t, x2); | 478 | 177k | x2 += t; | 479 | 177k | break; | 480 | 0 | case local::Minus3: | 481 | 0 | if (isPzOne) { | 482 | 0 | x2 -= P.z; | 483 | 0 | } else { | 484 | 0 | F::sqr(t, P.z); | 485 | 0 | F::sqr(t, t); | 486 | 0 | x2 -= t; | 487 | 0 | } | 488 | 0 | F::mul2(t, x2); | 489 | 0 | x2 += t; | 490 | 0 | break; | 491 | 0 | case local::GenericA: | 492 | 0 | default: | 493 | 0 | if (isPzOne) { | 494 | 0 | t = E::a_; | 495 | 0 | } else { | 496 | 0 | F::sqr(t, P.z); | 497 | 0 | F::sqr(t, t); | 498 | 0 | t *= E::a_; | 499 | 0 | } | 500 | 0 | t += x2; | 501 | 0 | F::mul2(x2, x2); | 502 | 0 | x2 += t; | 503 | 0 | break; | 504 | 177k | } | 505 | 177k | F::sqr(R.x, x2); | 506 | 177k | R.x -= xy; | 507 | 177k | R.x -= xy; | 508 | 177k | if (isPzOne) { | 509 | 2.15k | R.z = P.y; | 510 | 174k | } else { | 511 | 174k | F::mul(R.z, P.y, P.z); | 512 | 174k | } | 513 | 177k | F::mul2(R.z, R.z); | 514 | 177k | F::sub(R.y, xy, R.x); | 515 | 177k | R.y *= x2; | 516 | 177k | F::mul2(y2, y2); | 517 | 177k | F::mul2(y2, y2); | 518 | 177k | F::mul2(y2, y2); | 519 | 177k | R.y -= y2; | 520 | 177k | } |
void mcl::ec::dblJacobi<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 453 | 757k | { | 454 | 757k | typedef typename E::Fp F; | 455 | 757k | if (P.isZero()) { | 456 | 23.9k | R.clear(); | 457 | 23.9k | return; | 458 | 23.9k | } | 459 | 733k | const bool isPzOne = P.z.isOne(); | 460 | 733k | F x2, y2, xy, t; | 461 | 733k | F::sqr(x2, P.x); | 462 | 733k | F::sqr(y2, P.y); | 463 | 733k | if (sizeof(F) <= 32) { // M == S | 464 | 0 | F::mul(xy, P.x, y2); | 465 | 0 | xy += xy; | 466 | 0 | F::sqr(y2, y2); | 467 | 733k | } else { // M > S + A | 468 | 733k | F::add(xy, P.x, y2); | 469 | 733k | F::sqr(y2, y2); | 470 | 733k | F::sqr(xy, xy); | 471 | 733k | xy -= x2; | 472 | 733k | xy -= y2; | 473 | 733k | } | 474 | 733k | xy += xy; // 4xy^2 | 475 | 733k | switch (E::specialA_) { | 476 | 733k | case local::Zero: | 477 | 733k | F::mul2(t, x2); | 478 | 733k | x2 += t; | 479 | 733k | break; | 480 | 0 | case local::Minus3: | 481 | 0 | if (isPzOne) { | 482 | 0 | x2 -= P.z; | 483 | 0 | } else { | 484 | 0 | F::sqr(t, P.z); | 485 | 0 | F::sqr(t, t); | 486 | 0 | x2 -= t; | 487 | 0 | } | 488 | 0 | F::mul2(t, x2); | 489 | 0 | x2 += t; | 490 | 0 | break; | 491 | 0 | case local::GenericA: | 492 | 0 | default: | 493 | 0 | if (isPzOne) { | 494 | 0 | t = E::a_; | 495 | 0 | } else { | 496 | 0 | F::sqr(t, P.z); | 497 | 0 | F::sqr(t, t); | 498 | 0 | t *= E::a_; | 499 | 0 | } | 500 | 0 | t += x2; | 501 | 0 | F::mul2(x2, x2); | 502 | 0 | x2 += t; | 503 | 0 | break; | 504 | 733k | } | 505 | 733k | F::sqr(R.x, x2); | 506 | 733k | R.x -= xy; | 507 | 733k | R.x -= xy; | 508 | 733k | if (isPzOne) { | 509 | 10.1k | R.z = P.y; | 510 | 723k | } else { | 511 | 723k | F::mul(R.z, P.y, P.z); | 512 | 723k | } | 513 | 733k | F::mul2(R.z, R.z); | 514 | 733k | F::sub(R.y, xy, R.x); | 515 | 733k | R.y *= x2; | 516 | 733k | F::mul2(y2, y2); | 517 | 733k | F::mul2(y2, y2); | 518 | 733k | F::mul2(y2, y2); | 519 | 733k | R.y -= y2; | 520 | 733k | } |
void mcl::ec::dblJacobi<mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >(mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> >&, mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&) Line | Count | Source | 453 | 39 | { | 454 | 39 | typedef typename E::Fp F; | 455 | 39 | if (P.isZero()) { | 456 | 0 | R.clear(); | 457 | 0 | return; | 458 | 0 | } | 459 | 39 | const bool isPzOne = P.z.isOne(); | 460 | 39 | F x2, y2, xy, t; | 461 | 39 | F::sqr(x2, P.x); | 462 | 39 | F::sqr(y2, P.y); | 463 | 39 | if (sizeof(F) <= 32) { // M == S | 464 | 0 | F::mul(xy, P.x, y2); | 465 | 0 | xy += xy; | 466 | 0 | F::sqr(y2, y2); | 467 | 39 | } else { // M > S + A | 468 | 39 | F::add(xy, P.x, y2); | 469 | 39 | F::sqr(y2, y2); | 470 | 39 | F::sqr(xy, xy); | 471 | 39 | xy -= x2; | 472 | 39 | xy -= y2; | 473 | 39 | } | 474 | 39 | xy += xy; // 4xy^2 | 475 | 39 | switch (E::specialA_) { | 476 | 0 | case local::Zero: | 477 | 0 | F::mul2(t, x2); | 478 | 0 | x2 += t; | 479 | 0 | break; | 480 | 0 | case local::Minus3: | 481 | 0 | if (isPzOne) { | 482 | 0 | x2 -= P.z; | 483 | 0 | } else { | 484 | 0 | F::sqr(t, P.z); | 485 | 0 | F::sqr(t, t); | 486 | 0 | x2 -= t; | 487 | 0 | } | 488 | 0 | F::mul2(t, x2); | 489 | 0 | x2 += t; | 490 | 0 | break; | 491 | 39 | case local::GenericA: | 492 | 39 | default: | 493 | 39 | if (isPzOne) { | 494 | 0 | t = E::a_; | 495 | 39 | } else { | 496 | 39 | F::sqr(t, P.z); | 497 | 39 | F::sqr(t, t); | 498 | 39 | t *= E::a_; | 499 | 39 | } | 500 | 39 | t += x2; | 501 | 39 | F::mul2(x2, x2); | 502 | 39 | x2 += t; | 503 | 39 | break; | 504 | 39 | } | 505 | 39 | F::sqr(R.x, x2); | 506 | 39 | R.x -= xy; | 507 | 39 | R.x -= xy; | 508 | 39 | if (isPzOne) { | 509 | 0 | R.z = P.y; | 510 | 39 | } else { | 511 | 39 | F::mul(R.z, P.y, P.z); | 512 | 39 | } | 513 | 39 | F::mul2(R.z, R.z); | 514 | 39 | F::sub(R.y, xy, R.x); | 515 | 39 | R.y *= x2; | 516 | 39 | F::mul2(y2, y2); | 517 | 39 | F::mul2(y2, y2); | 518 | 39 | F::mul2(y2, y2); | 519 | 39 | R.y -= y2; | 520 | 39 | } |
void mcl::ec::dblJacobi<mcl::local::PointT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > > >(mcl::local::PointT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >&, mcl::local::PointT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > > const&) Line | Count | Source | 453 | 32 | { | 454 | 32 | typedef typename E::Fp F; | 455 | 32 | if (P.isZero()) { | 456 | 0 | R.clear(); | 457 | 0 | return; | 458 | 0 | } | 459 | 32 | const bool isPzOne = P.z.isOne(); | 460 | 32 | F x2, y2, xy, t; | 461 | 32 | F::sqr(x2, P.x); | 462 | 32 | F::sqr(y2, P.y); | 463 | 32 | if (sizeof(F) <= 32) { // M == S | 464 | 0 | F::mul(xy, P.x, y2); | 465 | 0 | xy += xy; | 466 | 0 | F::sqr(y2, y2); | 467 | 32 | } else { // M > S + A | 468 | 32 | F::add(xy, P.x, y2); | 469 | 32 | F::sqr(y2, y2); | 470 | 32 | F::sqr(xy, xy); | 471 | 32 | xy -= x2; | 472 | 32 | xy -= y2; | 473 | 32 | } | 474 | 32 | xy += xy; // 4xy^2 | 475 | 32 | switch (E::specialA_) { | 476 | 0 | case local::Zero: | 477 | 0 | F::mul2(t, x2); | 478 | 0 | x2 += t; | 479 | 0 | break; | 480 | 0 | case local::Minus3: | 481 | 0 | if (isPzOne) { | 482 | 0 | x2 -= P.z; | 483 | 0 | } else { | 484 | 0 | F::sqr(t, P.z); | 485 | 0 | F::sqr(t, t); | 486 | 0 | x2 -= t; | 487 | 0 | } | 488 | 0 | F::mul2(t, x2); | 489 | 0 | x2 += t; | 490 | 0 | break; | 491 | 32 | case local::GenericA: | 492 | 32 | default: | 493 | 32 | if (isPzOne) { | 494 | 0 | t = E::a_; | 495 | 32 | } else { | 496 | 32 | F::sqr(t, P.z); | 497 | 32 | F::sqr(t, t); | 498 | 32 | t *= E::a_; | 499 | 32 | } | 500 | 32 | t += x2; | 501 | 32 | F::mul2(x2, x2); | 502 | 32 | x2 += t; | 503 | 32 | break; | 504 | 32 | } | 505 | 32 | F::sqr(R.x, x2); | 506 | 32 | R.x -= xy; | 507 | 32 | R.x -= xy; | 508 | 32 | if (isPzOne) { | 509 | 0 | R.z = P.y; | 510 | 32 | } else { | 511 | 32 | F::mul(R.z, P.y, P.z); | 512 | 32 | } | 513 | 32 | F::mul2(R.z, R.z); | 514 | 32 | F::sub(R.y, xy, R.x); | 515 | 32 | R.y *= x2; | 516 | 32 | F::mul2(y2, y2); | 517 | 32 | F::mul2(y2, y2); | 518 | 32 | F::mul2(y2, y2); | 519 | 32 | R.y -= y2; | 520 | 32 | } |
|
521 | | |
522 | | /* |
523 | | J + J : 12mul + 4sqr + 7add |
524 | | J + A : 8mul + 3sqr + 7add |
525 | | A + A : 4mul + 2sqr + 7add |
526 | | */ |
527 | | template<class E> |
528 | | void addJacobi(E& R, const E& P, const E& Q) |
529 | 220k | { |
530 | 220k | typedef typename E::Fp F; |
531 | 220k | if (P.isZero()) { R = Q; return; } |
532 | 206k | if (Q.isZero()) { R = P; return; } |
533 | 206k | bool isPzOne = P.z.isOne(); |
534 | 206k | bool isQzOne = Q.z.isOne(); |
535 | 206k | F r, U1, S1, H, H3; |
536 | 206k | if (isPzOne) { |
537 | | // r = 1; |
538 | 200k | } else { |
539 | 200k | F::sqr(r, P.z); |
540 | 200k | } |
541 | 206k | if (isQzOne) { |
542 | 70.3k | U1 = P.x; |
543 | 70.3k | if (isPzOne) { |
544 | 364 | H = Q.x; |
545 | 69.9k | } else { |
546 | 69.9k | F::mul(H, Q.x, r); |
547 | 69.9k | } |
548 | 70.3k | H -= U1; |
549 | 70.3k | S1 = P.y; |
550 | 136k | } else { |
551 | 136k | F::sqr(S1, Q.z); |
552 | 136k | F::mul(U1, P.x, S1); |
553 | 136k | if (isPzOne) { |
554 | 5.36k | H = Q.x; |
555 | 130k | } else { |
556 | 130k | F::mul(H, Q.x, r); |
557 | 130k | } |
558 | 136k | H -= U1; |
559 | 136k | S1 *= Q.z; |
560 | 136k | S1 *= P.y; |
561 | 136k | } |
562 | 206k | if (isPzOne) { |
563 | 5.73k | r = Q.y; |
564 | 200k | } else { |
565 | 200k | r *= P.z; |
566 | 200k | r *= Q.y; |
567 | 200k | } |
568 | 206k | r -= S1; |
569 | 206k | if (H.isZero()) { |
570 | 351 | if (r.isZero()) { |
571 | 205 | ec::dblJacobi(R, P); |
572 | 205 | } else { |
573 | 146 | R.clear(); |
574 | 146 | } |
575 | 351 | return; |
576 | 351 | } |
577 | 206k | if (isPzOne) { |
578 | 5.71k | if (isQzOne) { |
579 | 350 | R.z = H; |
580 | 5.36k | } else { |
581 | 5.36k | F::mul(R.z, H, Q.z); |
582 | 5.36k | } |
583 | 200k | } else { |
584 | 200k | if (isQzOne) { |
585 | 69.7k | F::mul(R.z, P.z, H); |
586 | 130k | } else { |
587 | 130k | F::mul(R.z, P.z, Q.z); |
588 | 130k | R.z *= H; |
589 | 130k | } |
590 | 200k | } |
591 | 206k | F::sqr(H3, H); // H^2 |
592 | 206k | F::sqr(R.y, r); // r^2 |
593 | 206k | U1 *= H3; // U1 H^2 |
594 | 206k | H3 *= H; // H^3 |
595 | 206k | R.y -= U1; |
596 | 206k | R.y -= U1; |
597 | 206k | F::sub(R.x, R.y, H3); |
598 | 206k | U1 -= R.x; |
599 | 206k | U1 *= r; |
600 | 206k | H3 *= S1; |
601 | 206k | F::sub(R.y, U1, H3); |
602 | 206k | } void mcl::ec::addJacobi<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 529 | 34.9k | { | 530 | 34.9k | typedef typename E::Fp F; | 531 | 34.9k | if (P.isZero()) { R = Q; return; } | 532 | 31.6k | if (Q.isZero()) { R = P; return; } | 533 | 31.6k | bool isPzOne = P.z.isOne(); | 534 | 31.6k | bool isQzOne = Q.z.isOne(); | 535 | 31.6k | F r, U1, S1, H, H3; | 536 | 31.6k | if (isPzOne) { | 537 | | // r = 1; | 538 | 29.4k | } else { | 539 | 29.4k | F::sqr(r, P.z); | 540 | 29.4k | } | 541 | 31.6k | if (isQzOne) { | 542 | 10.1k | U1 = P.x; | 543 | 10.1k | if (isPzOne) { | 544 | 59 | H = Q.x; | 545 | 10.1k | } else { | 546 | 10.1k | F::mul(H, Q.x, r); | 547 | 10.1k | } | 548 | 10.1k | H -= U1; | 549 | 10.1k | S1 = P.y; | 550 | 21.4k | } else { | 551 | 21.4k | F::sqr(S1, Q.z); | 552 | 21.4k | F::mul(U1, P.x, S1); | 553 | 21.4k | if (isPzOne) { | 554 | 2.15k | H = Q.x; | 555 | 19.3k | } else { | 556 | 19.3k | F::mul(H, Q.x, r); | 557 | 19.3k | } | 558 | 21.4k | H -= U1; | 559 | 21.4k | S1 *= Q.z; | 560 | 21.4k | S1 *= P.y; | 561 | 21.4k | } | 562 | 31.6k | if (isPzOne) { | 563 | 2.21k | r = Q.y; | 564 | 29.4k | } else { | 565 | 29.4k | r *= P.z; | 566 | 29.4k | r *= Q.y; | 567 | 29.4k | } | 568 | 31.6k | r -= S1; | 569 | 31.6k | if (H.isZero()) { | 570 | 7 | if (r.isZero()) { | 571 | 5 | ec::dblJacobi(R, P); | 572 | 5 | } else { | 573 | 2 | R.clear(); | 574 | 2 | } | 575 | 7 | return; | 576 | 7 | } | 577 | 31.6k | if (isPzOne) { | 578 | 2.21k | if (isQzOne) { | 579 | 52 | R.z = H; | 580 | 2.15k | } else { | 581 | 2.15k | F::mul(R.z, H, Q.z); | 582 | 2.15k | } | 583 | 29.4k | } else { | 584 | 29.4k | if (isQzOne) { | 585 | 10.1k | F::mul(R.z, P.z, H); | 586 | 19.3k | } else { | 587 | 19.3k | F::mul(R.z, P.z, Q.z); | 588 | 19.3k | R.z *= H; | 589 | 19.3k | } | 590 | 29.4k | } | 591 | 31.6k | F::sqr(H3, H); // H^2 | 592 | 31.6k | F::sqr(R.y, r); // r^2 | 593 | 31.6k | U1 *= H3; // U1 H^2 | 594 | 31.6k | H3 *= H; // H^3 | 595 | 31.6k | R.y -= U1; | 596 | 31.6k | R.y -= U1; | 597 | 31.6k | F::sub(R.x, R.y, H3); | 598 | 31.6k | U1 -= R.x; | 599 | 31.6k | U1 *= r; | 600 | 31.6k | H3 *= S1; | 601 | 31.6k | F::sub(R.y, U1, H3); | 602 | 31.6k | } |
void mcl::ec::addJacobi<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 529 | 184k | { | 530 | 184k | typedef typename E::Fp F; | 531 | 184k | if (P.isZero()) { R = Q; return; } | 532 | 173k | if (Q.isZero()) { R = P; return; } | 533 | 173k | bool isPzOne = P.z.isOne(); | 534 | 173k | bool isQzOne = Q.z.isOne(); | 535 | 173k | F r, U1, S1, H, H3; | 536 | 173k | if (isPzOne) { | 537 | | // r = 1; | 538 | 170k | } else { | 539 | 170k | F::sqr(r, P.z); | 540 | 170k | } | 541 | 173k | if (isQzOne) { | 542 | 60.1k | U1 = P.x; | 543 | 60.1k | if (isPzOne) { | 544 | 305 | H = Q.x; | 545 | 59.8k | } else { | 546 | 59.8k | F::mul(H, Q.x, r); | 547 | 59.8k | } | 548 | 60.1k | H -= U1; | 549 | 60.1k | S1 = P.y; | 550 | 113k | } else { | 551 | 113k | F::sqr(S1, Q.z); | 552 | 113k | F::mul(U1, P.x, S1); | 553 | 113k | if (isPzOne) { | 554 | 3.21k | H = Q.x; | 555 | 110k | } else { | 556 | 110k | F::mul(H, Q.x, r); | 557 | 110k | } | 558 | 113k | H -= U1; | 559 | 113k | S1 *= Q.z; | 560 | 113k | S1 *= P.y; | 561 | 113k | } | 562 | 173k | if (isPzOne) { | 563 | 3.51k | r = Q.y; | 564 | 170k | } else { | 565 | 170k | r *= P.z; | 566 | 170k | r *= Q.y; | 567 | 170k | } | 568 | 173k | r -= S1; | 569 | 173k | if (H.isZero()) { | 570 | 261 | if (r.isZero()) { | 571 | 129 | ec::dblJacobi(R, P); | 572 | 132 | } else { | 573 | 132 | R.clear(); | 574 | 132 | } | 575 | 261 | return; | 576 | 261 | } | 577 | 173k | if (isPzOne) { | 578 | 3.50k | if (isQzOne) { | 579 | 298 | R.z = H; | 580 | 3.21k | } else { | 581 | 3.21k | F::mul(R.z, H, Q.z); | 582 | 3.21k | } | 583 | 170k | } else { | 584 | 170k | if (isQzOne) { | 585 | 59.6k | F::mul(R.z, P.z, H); | 586 | 110k | } else { | 587 | 110k | F::mul(R.z, P.z, Q.z); | 588 | 110k | R.z *= H; | 589 | 110k | } | 590 | 170k | } | 591 | 173k | F::sqr(H3, H); // H^2 | 592 | 173k | F::sqr(R.y, r); // r^2 | 593 | 173k | U1 *= H3; // U1 H^2 | 594 | 173k | H3 *= H; // H^3 | 595 | 173k | R.y -= U1; | 596 | 173k | R.y -= U1; | 597 | 173k | F::sub(R.x, R.y, H3); | 598 | 173k | U1 -= R.x; | 599 | 173k | U1 *= r; | 600 | 173k | H3 *= S1; | 601 | 173k | F::sub(R.y, U1, H3); | 602 | 173k | } |
void mcl::ec::addJacobi<mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >(mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> >&, mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, mcl::local::PointT<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&) Line | Count | Source | 529 | 329 | { | 530 | 329 | typedef typename E::Fp F; | 531 | 329 | if (P.isZero()) { R = Q; return; } | 532 | 329 | if (Q.isZero()) { R = P; return; } | 533 | 329 | bool isPzOne = P.z.isOne(); | 534 | 329 | bool isQzOne = Q.z.isOne(); | 535 | 329 | F r, U1, S1, H, H3; | 536 | 329 | if (isPzOne) { | 537 | | // r = 1; | 538 | 329 | } else { | 539 | 329 | F::sqr(r, P.z); | 540 | 329 | } | 541 | 329 | if (isQzOne) { | 542 | 0 | U1 = P.x; | 543 | 0 | if (isPzOne) { | 544 | 0 | H = Q.x; | 545 | 0 | } else { | 546 | 0 | F::mul(H, Q.x, r); | 547 | 0 | } | 548 | 0 | H -= U1; | 549 | 0 | S1 = P.y; | 550 | 329 | } else { | 551 | 329 | F::sqr(S1, Q.z); | 552 | 329 | F::mul(U1, P.x, S1); | 553 | 329 | if (isPzOne) { | 554 | 0 | H = Q.x; | 555 | 329 | } else { | 556 | 329 | F::mul(H, Q.x, r); | 557 | 329 | } | 558 | 329 | H -= U1; | 559 | 329 | S1 *= Q.z; | 560 | 329 | S1 *= P.y; | 561 | 329 | } | 562 | 329 | if (isPzOne) { | 563 | 0 | r = Q.y; | 564 | 329 | } else { | 565 | 329 | r *= P.z; | 566 | 329 | r *= Q.y; | 567 | 329 | } | 568 | 329 | r -= S1; | 569 | 329 | if (H.isZero()) { | 570 | 45 | if (r.isZero()) { | 571 | 39 | ec::dblJacobi(R, P); | 572 | 39 | } else { | 573 | 6 | R.clear(); | 574 | 6 | } | 575 | 45 | return; | 576 | 45 | } | 577 | 284 | if (isPzOne) { | 578 | 0 | if (isQzOne) { | 579 | 0 | R.z = H; | 580 | 0 | } else { | 581 | 0 | F::mul(R.z, H, Q.z); | 582 | 0 | } | 583 | 284 | } else { | 584 | 284 | if (isQzOne) { | 585 | 0 | F::mul(R.z, P.z, H); | 586 | 284 | } else { | 587 | 284 | F::mul(R.z, P.z, Q.z); | 588 | 284 | R.z *= H; | 589 | 284 | } | 590 | 284 | } | 591 | 284 | F::sqr(H3, H); // H^2 | 592 | 284 | F::sqr(R.y, r); // r^2 | 593 | 284 | U1 *= H3; // U1 H^2 | 594 | 284 | H3 *= H; // H^3 | 595 | 284 | R.y -= U1; | 596 | 284 | R.y -= U1; | 597 | 284 | F::sub(R.x, R.y, H3); | 598 | 284 | U1 -= R.x; | 599 | 284 | U1 *= r; | 600 | 284 | H3 *= S1; | 601 | 284 | F::sub(R.y, U1, H3); | 602 | 284 | } |
void mcl::ec::addJacobi<mcl::local::PointT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > > >(mcl::local::PointT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >&, mcl::local::PointT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > > const&, mcl::local::PointT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > > const&) Line | Count | Source | 529 | 688 | { | 530 | 688 | typedef typename E::Fp F; | 531 | 688 | if (P.isZero()) { R = Q; return; } | 532 | 688 | if (Q.isZero()) { R = P; return; } | 533 | 688 | bool isPzOne = P.z.isOne(); | 534 | 688 | bool isQzOne = Q.z.isOne(); | 535 | 688 | F r, U1, S1, H, H3; | 536 | 688 | if (isPzOne) { | 537 | | // r = 1; | 538 | 688 | } else { | 539 | 688 | F::sqr(r, P.z); | 540 | 688 | } | 541 | 688 | if (isQzOne) { | 542 | 0 | U1 = P.x; | 543 | 0 | if (isPzOne) { | 544 | 0 | H = Q.x; | 545 | 0 | } else { | 546 | 0 | F::mul(H, Q.x, r); | 547 | 0 | } | 548 | 0 | H -= U1; | 549 | 0 | S1 = P.y; | 550 | 688 | } else { | 551 | 688 | F::sqr(S1, Q.z); | 552 | 688 | F::mul(U1, P.x, S1); | 553 | 688 | if (isPzOne) { | 554 | 0 | H = Q.x; | 555 | 688 | } else { | 556 | 688 | F::mul(H, Q.x, r); | 557 | 688 | } | 558 | 688 | H -= U1; | 559 | 688 | S1 *= Q.z; | 560 | 688 | S1 *= P.y; | 561 | 688 | } | 562 | 688 | if (isPzOne) { | 563 | 0 | r = Q.y; | 564 | 688 | } else { | 565 | 688 | r *= P.z; | 566 | 688 | r *= Q.y; | 567 | 688 | } | 568 | 688 | r -= S1; | 569 | 688 | if (H.isZero()) { | 570 | 38 | if (r.isZero()) { | 571 | 32 | ec::dblJacobi(R, P); | 572 | 32 | } else { | 573 | 6 | R.clear(); | 574 | 6 | } | 575 | 38 | return; | 576 | 38 | } | 577 | 650 | if (isPzOne) { | 578 | 0 | if (isQzOne) { | 579 | 0 | R.z = H; | 580 | 0 | } else { | 581 | 0 | F::mul(R.z, H, Q.z); | 582 | 0 | } | 583 | 650 | } else { | 584 | 650 | if (isQzOne) { | 585 | 0 | F::mul(R.z, P.z, H); | 586 | 650 | } else { | 587 | 650 | F::mul(R.z, P.z, Q.z); | 588 | 650 | R.z *= H; | 589 | 650 | } | 590 | 650 | } | 591 | 650 | F::sqr(H3, H); // H^2 | 592 | 650 | F::sqr(R.y, r); // r^2 | 593 | 650 | U1 *= H3; // U1 H^2 | 594 | 650 | H3 *= H; // H^3 | 595 | 650 | R.y -= U1; | 596 | 650 | R.y -= U1; | 597 | 650 | F::sub(R.x, R.y, H3); | 598 | 650 | U1 -= R.x; | 599 | 650 | U1 *= r; | 600 | 650 | H3 *= S1; | 601 | 650 | F::sub(R.y, U1, H3); | 602 | 650 | } |
|
603 | | |
604 | | /* |
605 | | accept P == Q |
606 | | https://eprint.iacr.org/2015/1060 |
607 | | (x, y, z) is zero <=> x = 0, y = 1, z = 0 |
608 | | */ |
609 | | |
610 | | // (b=4) 12M+27A |
611 | | // (generic) 14M+19A |
612 | | // Q.z = 1 if mixed |
613 | | template<class E> |
614 | | void addCTProj(E& R, const E& P, const E& Q, bool mixed = false) |
615 | | { |
616 | | typedef typename E::Fp F; |
617 | | assert(E::a_ == 0); |
618 | | F t0, t1, t2, t3, t4, x3, y3; |
619 | | F::mul(t0, P.x, Q.x); |
620 | | F::mul(t1, P.y, Q.y); |
621 | | if (mixed) { |
622 | | t2 = P.z; |
623 | | } else { |
624 | | F::mul(t2, P.z, Q.z); |
625 | | } |
626 | | F::add(t3, P.x, P.y); |
627 | | F::add(t4, Q.x, Q.y); |
628 | | F::mul(t3, t3, t4); |
629 | | F::add(t4, t0, t1); |
630 | | F::sub(t3, t3, t4); |
631 | | F::add(t4, P.y, P.z); |
632 | | F::add(x3, Q.y, Q.z); |
633 | | F::mul(t4, t4, x3); |
634 | | F::add(x3, t1, t2); |
635 | | F::sub(t4, t4, x3); |
636 | | F::add(x3, P.x, P.z); |
637 | | F::add(y3, Q.x, Q.z); |
638 | | F::mul(x3, x3, y3); |
639 | | F::add(y3, t0, t2); |
640 | | F::sub(y3, x3, y3); |
641 | | F::add(x3, t0, t0); |
642 | | F::add(t0, t0, x3); |
643 | | if (E::specialB_ == ec::local::Plus1) { |
644 | | local::mul3(t2); |
645 | | } else |
646 | | if (E::specialB_ == ec::local::Plus4) { |
647 | | local::mul12(t2); |
648 | | } else |
649 | | { |
650 | | F::mul(t2, t2, E::b3_); |
651 | | } |
652 | | F::add(R.z, t1, t2); |
653 | | F::sub(t1, t1, t2); |
654 | | if (E::specialB_ == ec::local::Plus1) { |
655 | | local::mul3(y3); |
656 | | } else |
657 | | if (E::specialB_ == ec::local::Plus4) { |
658 | | local::mul12(y3); |
659 | | } else |
660 | | { |
661 | | F::mul(y3, y3, E::b3_); |
662 | | } |
663 | | F::mul(x3, y3, t4); |
664 | | F::mul(t2, t3, t1); |
665 | | F::sub(R.x, t2, x3); |
666 | | F::mul(y3, y3, t0); |
667 | | F::mul(t1, t1, R.z); |
668 | | F::add(R.y, y3, t1); |
669 | | F::mul(t0, t0, t3); |
670 | | F::mul(R.z, R.z, t4); |
671 | | F::add(R.z, R.z, t0); |
672 | | } |
673 | | // (b = 4) 6M+2S+13A |
674 | | // (generic) 7M+2S+9A |
675 | | template<class E> |
676 | | void dblCTProj(E& R, const E& P) |
677 | | { |
678 | | typedef typename E::Fp F; |
679 | | assert(E::a_ == 0); |
680 | | F t0, t1, t2, x3, y3; |
681 | | F::sqr(t0, P.y); |
682 | | F::mul(t1, P.y, P.z); |
683 | | F::sqr(t2, P.z); |
684 | | F::add(R.z, t0, t0); |
685 | | F::add(R.z, R.z, R.z); |
686 | | F::add(R.z, R.z, R.z); |
687 | | if (E::specialB_ == ec::local::Plus1) { |
688 | | local::mul3(t2); |
689 | | } else |
690 | | if (E::specialB_ == ec::local::Plus4) { |
691 | | local::mul12(t2); |
692 | | } else |
693 | | { |
694 | | F::mul(t2, t2, E::b3_); |
695 | | } |
696 | | F::mul(x3, t2, R.z); |
697 | | F::add(y3, t0, t2); |
698 | | F::mul(R.z, R.z, t1); |
699 | | F::add(t1, t2, t2); |
700 | | F::add(t2, t2, t1); |
701 | | F::mul(t1, P.x, P.y); |
702 | | F::sub(t0, t0, t2); |
703 | | F::mul(R.y, y3, t0); |
704 | | F::add(R.y, R.y, x3); |
705 | | F::mul(R.x, t0, t1); |
706 | | F::add(R.x, R.x, R.x); |
707 | | } |
708 | | |
709 | | template<class E> |
710 | | void normalizeProj(E& P) |
711 | 0 | { |
712 | 0 | if (P.z.isZero() || P.z.isOne()) return; |
713 | 0 | typedef typename E::Fp F; |
714 | 0 | F::inv(P.z, P.z); |
715 | 0 | local::_normalizeProj(P, P, P.z); |
716 | 0 | } Unexecuted instantiation: void mcl::ec::normalizeProj<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&) Unexecuted instantiation: void mcl::ec::normalizeProj<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&) |
717 | | |
718 | | // (Y^2 - bZ^2)Z = X(X^2 + aZ^2) |
719 | | template<class E> |
720 | | bool isValidProj(const E& P) |
721 | 0 | { |
722 | 0 | typedef typename E::Fp F; |
723 | 0 | F y2, x2, z2, t; |
724 | 0 | F::sqr(x2, P.x); |
725 | 0 | F::sqr(y2, P.y); |
726 | 0 | F::sqr(z2, P.z); |
727 | 0 | F::mul(t, E::a_, z2); |
728 | 0 | t += x2; |
729 | 0 | t *= P.x; |
730 | 0 | z2 *= E::b_; |
731 | 0 | y2 -= z2; |
732 | 0 | y2 *= P.z; |
733 | 0 | return y2 == t; |
734 | 0 | } Unexecuted instantiation: bool mcl::ec::isValidProj<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Unexecuted instantiation: bool mcl::ec::isValidProj<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) |
735 | | |
736 | | // (x/z, y/z) |
737 | | template<class E> |
738 | | bool isEqualProj(const E& P1, const E& P2) |
739 | 0 | { |
740 | 0 | typedef typename E::Fp F; |
741 | 0 | bool zero1 = P1.isZero(); |
742 | 0 | bool zero2 = P2.isZero(); |
743 | 0 | if (zero1) { |
744 | 0 | return zero2; |
745 | 0 | } |
746 | 0 | if (zero2) return false; |
747 | 0 | F t1, t2; |
748 | 0 | F::mul(t1, P1.x, P2.z); |
749 | 0 | F::mul(t2, P2.x, P1.z); |
750 | 0 | if (t1 != t2) return false; |
751 | 0 | F::mul(t1, P1.y, P2.z); |
752 | 0 | F::mul(t2, P2.y, P1.z); |
753 | 0 | return t1 == t2; |
754 | 0 | } Unexecuted instantiation: bool mcl::ec::isEqualProj<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Unexecuted instantiation: bool mcl::ec::isEqualProj<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) |
755 | | |
756 | | // return (P1 == P2) ? 1 : (P1 == -P2) ? -1 : 0 |
757 | | template<class E> |
758 | | int isEqualOrMinusProj(const E& P1, const E& P2) |
759 | | { |
760 | | typedef typename E::Fp F; |
761 | | bool zero1 = P1.isZero(); |
762 | | bool zero2 = P2.isZero(); |
763 | | if (zero1) { |
764 | | return zero2 ? 1 : 0; |
765 | | } |
766 | | if (zero2) return 0; |
767 | | F t1, t2; |
768 | | F::mul(t1, P1.x, P2.z); |
769 | | F::mul(t2, P2.x, P1.z); |
770 | | if (t1 != t2) return 0; |
771 | | F::mul(t1, P1.y, P2.z); |
772 | | F::mul(t2, P2.y, P1.z); |
773 | | if (t1 == t2) return 1; |
774 | | F::neg(t1, t1); |
775 | | if (t1 == t2) return -1; |
776 | | return 0; |
777 | | } |
778 | | |
779 | | /* |
780 | | |a=0|-3| generic |
781 | | mul| 8| 8| 9 |
782 | | sqr| 4| 5| 5 |
783 | | add| 11|12|12 |
784 | | */ |
785 | | template<class E> |
786 | | void dblProj(E& R, const E& P) |
787 | 0 | { |
788 | 0 | typedef typename E::Fp F; |
789 | 0 | if (P.isZero()) { |
790 | 0 | R.clear(); |
791 | 0 | return; |
792 | 0 | } |
793 | 0 | const bool isPzOne = P.z.isOne(); |
794 | 0 | F w, t, h; |
795 | 0 | switch (E::specialA_) { |
796 | 0 | case local::Zero: |
797 | 0 | F::sqr(w, P.x); |
798 | 0 | F::add(t, w, w); |
799 | 0 | w += t; |
800 | 0 | break; |
801 | 0 | case local::Minus3: |
802 | 0 | F::sqr(w, P.x); |
803 | 0 | if (isPzOne) { |
804 | 0 | w -= P.z; |
805 | 0 | } else { |
806 | 0 | F::sqr(t, P.z); |
807 | 0 | w -= t; |
808 | 0 | } |
809 | 0 | F::add(t, w, w); |
810 | 0 | w += t; |
811 | 0 | break; |
812 | 0 | case local::GenericA: |
813 | 0 | default: |
814 | 0 | if (isPzOne) { |
815 | 0 | w = E::a_; |
816 | 0 | } else { |
817 | 0 | F::sqr(w, P.z); |
818 | 0 | w *= E::a_; |
819 | 0 | } |
820 | 0 | F::sqr(t, P.x); |
821 | 0 | w += t; |
822 | 0 | w += t; |
823 | 0 | w += t; // w = a z^2 + 3x^2 |
824 | 0 | break; |
825 | 0 | } |
826 | 0 | if (isPzOne) { |
827 | 0 | R.z = P.y; |
828 | 0 | } else { |
829 | 0 | F::mul(R.z, P.y, P.z); // s = yz |
830 | 0 | } |
831 | 0 | F::mul(t, R.z, P.x); |
832 | 0 | t *= P.y; // xys |
833 | 0 | t += t; |
834 | 0 | t += t; // 4(xys) ; 4B |
835 | 0 | F::sqr(h, w); |
836 | 0 | h -= t; |
837 | 0 | h -= t; // w^2 - 8B |
838 | 0 | F::mul(R.x, h, R.z); |
839 | 0 | t -= h; // h is free |
840 | 0 | t *= w; |
841 | 0 | F::sqr(w, P.y); |
842 | 0 | R.x += R.x; |
843 | 0 | R.z += R.z; |
844 | 0 | F::sqr(h, R.z); |
845 | 0 | w *= h; |
846 | 0 | R.z *= h; |
847 | 0 | F::sub(R.y, t, w); |
848 | 0 | R.y -= w; |
849 | 0 | } Unexecuted instantiation: void mcl::ec::dblProj<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Unexecuted instantiation: void mcl::ec::dblProj<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) |
850 | | |
851 | | /* |
852 | | mul| 12 |
853 | | sqr| 2 |
854 | | add| 7 |
855 | | */ |
856 | | template<class E> |
857 | | void addProj(E& R, const E& P, const E& Q) |
858 | 0 | { |
859 | 0 | typedef typename E::Fp F; |
860 | 0 | if (P.isZero()) { R = Q; return; } |
861 | 0 | if (Q.isZero()) { R = P; return; } |
862 | 0 | bool isPzOne = P.z.isOne(); |
863 | 0 | bool isQzOne = Q.z.isOne(); |
864 | 0 | F r, PyQz, v, A, vv; |
865 | 0 | if (isQzOne) { |
866 | 0 | r = P.x; |
867 | 0 | PyQz = P.y; |
868 | 0 | } else { |
869 | 0 | F::mul(r, P.x, Q.z); |
870 | 0 | F::mul(PyQz, P.y, Q.z); |
871 | 0 | } |
872 | 0 | if (isPzOne) { |
873 | 0 | A = Q.y; |
874 | 0 | v = Q.x; |
875 | 0 | } else { |
876 | 0 | F::mul(A, Q.y, P.z); |
877 | 0 | F::mul(v, Q.x, P.z); |
878 | 0 | } |
879 | 0 | v -= r; |
880 | 0 | if (v.isZero()) { |
881 | 0 | if (A == PyQz) { |
882 | 0 | dblProj(R, P); |
883 | 0 | } else { |
884 | 0 | R.clear(); |
885 | 0 | } |
886 | 0 | return; |
887 | 0 | } |
888 | 0 | F::sub(R.y, A, PyQz); |
889 | 0 | F::sqr(A, R.y); |
890 | 0 | F::sqr(vv, v); |
891 | 0 | r *= vv; |
892 | 0 | vv *= v; |
893 | 0 | if (isQzOne) { |
894 | 0 | R.z = P.z; |
895 | 0 | } else { |
896 | 0 | if (isPzOne) { |
897 | 0 | R.z = Q.z; |
898 | 0 | } else { |
899 | 0 | F::mul(R.z, P.z, Q.z); |
900 | 0 | } |
901 | 0 | } |
902 | | // R.z = 1 if isPzOne && isQzOne |
903 | 0 | if (isPzOne && isQzOne) { |
904 | 0 | R.z = vv; |
905 | 0 | } else { |
906 | 0 | A *= R.z; |
907 | 0 | R.z *= vv; |
908 | 0 | } |
909 | 0 | A -= vv; |
910 | 0 | vv *= PyQz; |
911 | 0 | A -= r; |
912 | 0 | A -= r; |
913 | 0 | F::mul(R.x, v, A); |
914 | 0 | r -= A; |
915 | 0 | R.y *= r; |
916 | 0 | R.y -= vv; |
917 | 0 | } Unexecuted instantiation: void mcl::ec::addProj<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Unexecuted instantiation: void mcl::ec::addProj<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) |
918 | | |
919 | | // y^2 == (x^2 + a)x + b |
920 | | template<class E> |
921 | | bool isValidAffine(const E& P) |
922 | 27.7k | { |
923 | 27.7k | typedef typename E::Fp F; |
924 | 27.7k | assert(!P.z.isZero()); |
925 | 27.7k | F y2, t; |
926 | 27.7k | F::sqr(y2, P.y); |
927 | 27.7k | F::sqr(t, P.x); |
928 | 27.7k | t += E::a_; |
929 | 27.7k | t *= P.x; |
930 | 27.7k | t += E::b_; |
931 | 27.7k | return y2 == t; |
932 | 27.7k | } bool mcl::ec::isValidAffine<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 922 | 13.2k | { | 923 | 13.2k | typedef typename E::Fp F; | 924 | 13.2k | assert(!P.z.isZero()); | 925 | 13.2k | F y2, t; | 926 | 13.2k | F::sqr(y2, P.y); | 927 | 13.2k | F::sqr(t, P.x); | 928 | 13.2k | t += E::a_; | 929 | 13.2k | t *= P.x; | 930 | 13.2k | t += E::b_; | 931 | 13.2k | return y2 == t; | 932 | 13.2k | } |
bool mcl::ec::isValidAffine<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 922 | 14.4k | { | 923 | 14.4k | typedef typename E::Fp F; | 924 | 14.4k | assert(!P.z.isZero()); | 925 | 14.4k | F y2, t; | 926 | 14.4k | F::sqr(y2, P.y); | 927 | 14.4k | F::sqr(t, P.x); | 928 | 14.4k | t += E::a_; | 929 | 14.4k | t *= P.x; | 930 | 14.4k | t += E::b_; | 931 | 14.4k | return y2 == t; | 932 | 14.4k | } |
|
933 | | |
934 | | // y^2 = x^3 + ax + b |
935 | | template<class E> |
936 | | static inline void dblAffine(E& R, const E& P) |
937 | 0 | { |
938 | 0 | typedef typename E::Fp F; |
939 | 0 | if (P.isZero()) { |
940 | 0 | R.clear(); |
941 | 0 | return; |
942 | 0 | } |
943 | 0 | if (P.y.isZero()) { |
944 | 0 | R.clear(); |
945 | 0 | return; |
946 | 0 | } |
947 | 0 | F t, s; |
948 | 0 | F::sqr(t, P.x); |
949 | 0 | F::add(s, t, t); |
950 | 0 | t += s; |
951 | 0 | t += E::a_; |
952 | 0 | F::add(s, P.y, P.y); |
953 | 0 | t /= s; |
954 | 0 | F::sqr(s, t); |
955 | 0 | s -= P.x; |
956 | 0 | F x3; |
957 | 0 | F::sub(x3, s, P.x); |
958 | 0 | F::sub(s, P.x, x3); |
959 | 0 | s *= t; |
960 | 0 | F::sub(R.y, s, P.y); |
961 | 0 | R.x = x3; |
962 | 0 | R.z = 1; |
963 | 0 | } Unexecuted instantiation: module.cpp:void mcl::ec::dblAffine<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Unexecuted instantiation: module.cpp:void mcl::ec::dblAffine<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) |
964 | | |
965 | | template<class E> |
966 | | void addAffine(E& R, const E& P, const E& Q) |
967 | 0 | { |
968 | 0 | typedef typename E::Fp F; |
969 | 0 | if (P.isZero()) { R = Q; return; } |
970 | 0 | if (Q.isZero()) { R = P; return; } |
971 | 0 | F t; |
972 | 0 | F::sub(t, Q.x, P.x); |
973 | 0 | if (t.isZero()) { |
974 | 0 | if (P.y == Q.y) { |
975 | 0 | dblAffine(R, P); |
976 | 0 | } else { |
977 | 0 | R.clear(); |
978 | 0 | } |
979 | 0 | return; |
980 | 0 | } |
981 | 0 | F s; |
982 | 0 | F::sub(s, Q.y, P.y); |
983 | 0 | F::div(t, s, t); |
984 | 0 | R.z = 1; |
985 | 0 | F x3; |
986 | 0 | F::sqr(x3, t); |
987 | 0 | x3 -= P.x; |
988 | 0 | x3 -= Q.x; |
989 | 0 | F::sub(s, P.x, x3); |
990 | 0 | s *= t; |
991 | 0 | F::sub(R.y, s, P.y); |
992 | 0 | R.x = x3; |
993 | 0 | } Unexecuted instantiation: void mcl::ec::addAffine<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Unexecuted instantiation: void mcl::ec::addAffine<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) |
994 | | |
995 | | template<class E> |
996 | | void tryAndIncMapTo(E& P, const typename E::Fp& t) |
997 | 0 | { |
998 | 0 | typedef typename E::Fp F; |
999 | 0 | F x = t; |
1000 | 0 | for (;;) { |
1001 | 0 | F y; |
1002 | 0 | E::getWeierstrass(y, x); |
1003 | 0 | if (F::squareRoot(y, y)) { |
1004 | 0 | bool b; |
1005 | 0 | P.set(&b, x, y, false); |
1006 | 0 | assert(b); |
1007 | 0 | return; |
1008 | 0 | } |
1009 | 0 | *x.getFp0() += F::BaseFp::one(); |
1010 | 0 | } |
1011 | 0 | } Unexecuted instantiation: void mcl::ec::tryAndIncMapTo<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::Fp const&) Unexecuted instantiation: void mcl::ec::tryAndIncMapTo<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::Fp const&) |
1012 | | |
1013 | | inline size_t ilog2(size_t n) |
1014 | 0 | { |
1015 | 0 | if (n == 0) return 0; |
1016 | 0 | return cybozu::bsr(n) + 1; |
1017 | 0 | } |
1018 | | |
1019 | | // The number of ADD for n-elements with bucket size b |
1020 | | inline size_t glvCost(size_t n, size_t b) |
1021 | 0 | { |
1022 | 0 | return (n + (size_t(1)<<(b+1))-1)/b; |
1023 | 0 | } |
1024 | | // approximate value such that argmin { b : glvCost(n, b) } |
1025 | | inline size_t estimateBucketSize(size_t n) |
1026 | 0 | { |
1027 | 0 | if (n <= 16) return 2; |
1028 | 0 | size_t log2n = ilog2(n); |
1029 | 0 | return log2n - ilog2(log2n); |
1030 | 0 | } |
1031 | | |
1032 | | /* |
1033 | | First, get approximate value x and compute glvCost of x-1 and x+1, |
1034 | | and return the minimum value. |
1035 | | */ |
1036 | | inline size_t glvGetTheoreticBucketSize(size_t n) |
1037 | 0 | { |
1038 | 0 | size_t x = estimateBucketSize(n); |
1039 | 0 | size_t vm1 = x > 1 ? glvCost(n, x-1) : n; |
1040 | 0 | size_t v0 = glvCost(n, x); |
1041 | 0 | size_t vp1 = glvCost(n, x+1); |
1042 | 0 | if (vm1 <= v0) return x-1; |
1043 | 0 | if (vp1 < v0) return x+1; |
1044 | 0 | return x; |
1045 | 0 | } |
1046 | | |
1047 | | // return heuristic backet size which is faster than glvGetTheoreticBucketSize |
1048 | | inline size_t glvGetBucketSize(size_t n) |
1049 | 0 | { |
1050 | 0 | if (n <= 2) return 2; |
1051 | 0 | size_t log2n = mcl::ec::ilog2(n); |
1052 | 0 | const size_t tblMin = 8; |
1053 | 0 | if (log2n < tblMin) return 3; |
1054 | | // n >= 2^tblMin |
1055 | 0 | static const size_t tbl[] = { |
1056 | 0 | 3, 4, 5, 5, 8, 8, 9, 10, 11, 12, 13, 13, 13, 16, 16, 16, 18, 19, 19, 19, 19, 19 |
1057 | 0 | }; |
1058 | 0 | if (log2n >= CYBOZU_NUM_OF_ARRAY(tbl)) return 19; |
1059 | 0 | size_t ret = tbl[log2n - tblMin]; |
1060 | 0 | return ret; |
1061 | 0 | } |
1062 | | |
1063 | | #ifndef MCL_MAX_N_TO_USE_STACK_FOR_MUL_VEC |
1064 | | // use (1 << glvGetBucketSize(n)) * sizeof(G) bytes stack + alpha |
1065 | | // about 18KiB (G1) or 36KiB (G2) for n = 1024 |
1066 | | // you can decrease this value but this algorithm is slow if n < 256 |
1067 | 0 | #define MCL_MAX_N_TO_USE_STACK_FOR_MUL_VEC 1024 |
1068 | | #endif |
1069 | | |
1070 | | /* |
1071 | | Extract w bits from yVec[i] starting at the pos-th bit, assign this value to v. |
1072 | | tbl[v-1] += xVec[i] |
1073 | | win = xVec[0] + 2 xVec[1] + 3 xVec[2] + ... + tblN xVec[tblN-1] |
1074 | | */ |
1075 | | template<class G> |
1076 | | void mulVecUpdateTable(G& win, G *tbl, size_t tblN, const G *xVec, const Unit *yVec, size_t yUnitSize, size_t next, size_t pos, size_t n, bool first) |
1077 | 0 | { |
1078 | 0 | for (size_t i = 0; i < tblN; i++) { |
1079 | 0 | tbl[i].clear(); |
1080 | 0 | } |
1081 | 0 | for (size_t i = 0; i < n; i++) { |
1082 | 0 | Unit v = fp::getUnitAt(yVec + next * i, yUnitSize, pos) & tblN; |
1083 | 0 | if (v) { |
1084 | 0 | tbl[v - 1] += xVec[i]; |
1085 | 0 | } |
1086 | 0 | } |
1087 | 0 | G sum = tbl[tblN - 1]; |
1088 | 0 | if (first) { |
1089 | 0 | win = sum; |
1090 | 0 | } else { |
1091 | 0 | win += sum; |
1092 | 0 | } |
1093 | 0 | for (size_t i = 1; i < tblN; i++) { |
1094 | 0 | sum += tbl[tblN - 1 - i]; |
1095 | 0 | win += sum; |
1096 | 0 | } |
1097 | 0 | } Unexecuted instantiation: void mcl::ec::mulVecUpdateTable<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, unsigned long, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) Unexecuted instantiation: void mcl::ec::mulVecUpdateTable<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, unsigned long, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) Unexecuted instantiation: void mcl::ec::mulVecUpdateTable<mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > >(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >*, unsigned long, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > const*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) |
1098 | | /* |
1099 | | z = sum_{i=0}^{n-1} xVec[i] * yVec[i] |
1100 | | yVec[i] means yVec[i*next:(i+1)*next+yUnitSize] |
1101 | | return numbers of done, which may be smaller than n if malloc fails |
1102 | | @note xVec may be normlized |
1103 | | fast for n >= 256 |
1104 | | */ |
1105 | | template<class G> |
1106 | | size_t mulVecCore(G& z, G *xVec, const Unit *yVec, size_t yUnitSize, size_t next, size_t n, size_t b, bool doNormalize) |
1107 | 0 | { |
1108 | 0 | if (n == 0) { |
1109 | 0 | z.clear(); |
1110 | 0 | return 0; |
1111 | 0 | } |
1112 | 0 | if (n == 1) { |
1113 | 0 | G::mulArray(z, xVec[0], yVec, yUnitSize); |
1114 | 0 | return 1; |
1115 | 0 | } |
1116 | | |
1117 | 0 | size_t tblN; |
1118 | 0 | G *tbl = 0; |
1119 | |
|
1120 | 0 | #ifndef MCL_DONT_USE_MALLOC |
1121 | 0 | G *tbl_ = 0; // malloc is used if tbl_ != 0 |
1122 | | // if n is large then try to use malloc |
1123 | 0 | if (n > MCL_MAX_N_TO_USE_STACK_FOR_MUL_VEC) { |
1124 | 0 | if (b == 0) b = glvGetBucketSize(n); |
1125 | 0 | tblN = (1 << b) - 1; |
1126 | 0 | tbl_ = (G*)malloc(sizeof(G) * tblN); |
1127 | 0 | if (tbl_) { |
1128 | 0 | tbl = tbl_; |
1129 | 0 | goto main; |
1130 | 0 | } |
1131 | 0 | } |
1132 | 0 | #endif |
1133 | | // n is small or malloc fails so use stack |
1134 | 0 | if (n > MCL_MAX_N_TO_USE_STACK_FOR_MUL_VEC) n = MCL_MAX_N_TO_USE_STACK_FOR_MUL_VEC; |
1135 | 0 | if (b == 0) b = glvGetBucketSize(n); |
1136 | 0 | tblN = (1 << b) - 1; |
1137 | 0 | tbl = (G*)CYBOZU_ALLOCA(sizeof(G) * tblN); |
1138 | | // keep tbl_ = 0 |
1139 | 0 | #ifndef MCL_DONT_USE_MALLOC |
1140 | 0 | main: |
1141 | 0 | #endif |
1142 | 0 | const size_t maxBitSize = sizeof(Unit) * yUnitSize * 8; |
1143 | 0 | const size_t winN = (maxBitSize + b-1) / b; |
1144 | | |
1145 | | // about 10% faster |
1146 | 0 | if (doNormalize) G::normalizeVec(xVec, xVec, n); |
1147 | |
|
1148 | 0 | mulVecUpdateTable(z, tbl, tblN, xVec, yVec, yUnitSize, next, b * (winN-1), n, true); |
1149 | 0 | for (size_t w = 1; w < winN; w++) { |
1150 | 0 | for (size_t i = 0; i < b; i++) { |
1151 | 0 | G::dbl(z, z); |
1152 | 0 | } |
1153 | 0 | mulVecUpdateTable(z, tbl, tblN, xVec, yVec, yUnitSize, next, b * (winN-1-w), n, false); |
1154 | 0 | } |
1155 | 0 | #ifndef MCL_DONT_USE_MALLOC |
1156 | 0 | if (tbl_) free(tbl_); |
1157 | 0 | #endif |
1158 | 0 | return n; |
1159 | 0 | } Unexecuted instantiation: unsigned long mcl::ec::mulVecCore<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) Unexecuted instantiation: unsigned long mcl::ec::mulVecCore<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) Unexecuted instantiation: unsigned long mcl::ec::mulVecCore<mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > >(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) |
1160 | | template<class G> |
1161 | | void mulVecLong(G& z, G *xVec, const Unit *yVec, size_t yUnitSize, size_t next, size_t n, size_t b, bool doNormalize) |
1162 | 0 | { |
1163 | 0 | size_t done = mulVecCore(z, xVec, yVec, yUnitSize, next, n, b, doNormalize); |
1164 | 0 | if (done == n) return; |
1165 | 0 | do { |
1166 | 0 | xVec += done; |
1167 | 0 | yVec += next * done; |
1168 | 0 | n -= done; |
1169 | 0 | G t; |
1170 | 0 | done = mulVecCore(t, xVec, yVec, yUnitSize, next, n, b, doNormalize); |
1171 | 0 | z += t; |
1172 | 0 | } while (done < n); |
1173 | 0 | } Unexecuted instantiation: void mcl::ec::mulVecLong<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) Unexecuted instantiation: void mcl::ec::mulVecLong<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) Unexecuted instantiation: void mcl::ec::mulVecLong<mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > >(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, bool) |
1174 | | |
1175 | | // for n >= 128 |
1176 | | template<class GLV, class G> |
1177 | | bool mulVecGLVlarge(G& z, const G *xVec, const void *yVec, size_t n, size_t bucket) |
1178 | 0 | { |
1179 | 0 | const int splitN = GLV::splitN; |
1180 | 0 | assert(n > 0); |
1181 | 0 | typedef typename GLV::Fr F; |
1182 | 0 | fp::getMpzAtType getMpzAt = fp::getMpzAtT<F>; |
1183 | 0 | typedef mcl::Unit Unit; |
1184 | 0 | const size_t next = F::getUnitSize(); |
1185 | 0 | mpz_class u[splitN], y; |
1186 | |
|
1187 | 0 | const size_t tblByteSize = sizeof(G) * splitN * n; |
1188 | 0 | const size_t ypByteSize = sizeof(Unit) * next * splitN * n; |
1189 | 0 | G *tbl = (G*)malloc(tblByteSize + ypByteSize); |
1190 | 0 | if (tbl == 0) return false; |
1191 | | |
1192 | 0 | Unit *yp = (Unit *)(tbl + splitN * n); |
1193 | |
|
1194 | 0 | G::normalizeVec(tbl, xVec, n); |
1195 | 0 | for (int i = 1; i < splitN; i++) { |
1196 | 0 | for (size_t j = 0; j < n; j++) { |
1197 | 0 | GLV::mulLambda(tbl[i * n + j], tbl[(i - 1) * n + j]); |
1198 | 0 | } |
1199 | 0 | } |
1200 | 0 | for (size_t i = 0; i < n; i++) { |
1201 | 0 | getMpzAt(y, yVec, i); |
1202 | 0 | GLV::split(u, y); |
1203 | 0 | for (size_t j = 0; j < splitN; j++) { |
1204 | 0 | size_t idx = j * n + i; |
1205 | 0 | if (u[j] < 0) { |
1206 | 0 | u[j] = -u[j]; |
1207 | 0 | G::neg(tbl[idx], tbl[idx]); |
1208 | 0 | } |
1209 | 0 | bool b; |
1210 | 0 | mcl::gmp::getArray(&b, &yp[idx * next], next, u[j]); |
1211 | 0 | assert(b); (void)b; |
1212 | 0 | } |
1213 | 0 | } |
1214 | 0 | mulVecLong(z, tbl, yp, next, next, n * splitN, false, bucket); |
1215 | 0 | free(tbl); |
1216 | 0 | return true; |
1217 | 0 | } Unexecuted instantiation: bool mcl::ec::mulVecGLVlarge<mcl::bn::local::GLV1, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long, unsigned long) Unexecuted instantiation: bool mcl::ec::mulVecGLVlarge<mcl::bn::local::GLV2T<mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long, unsigned long) Unexecuted instantiation: bool mcl::ec::mulVecGLVlarge<mcl::bn::local::GLV2T<mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > >(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > const*, void const*, unsigned long, unsigned long) Unexecuted instantiation: bool mcl::ec::mulVecGLVlarge<mcl::GLV1T<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long, unsigned long) |
1218 | | |
1219 | | template<class G> |
1220 | | bool mulSmallInt(G& z, const G& x, Unit y, bool isNegative) |
1221 | 5.34k | { |
1222 | 5.34k | switch (y) { |
1223 | 19 | case 0: z.clear(); return true; |
1224 | 51 | case 1: z = x; break; |
1225 | 26 | case 2: G::dbl(z, x); break; |
1226 | 12 | case 3: { |
1227 | 12 | G t; |
1228 | 12 | G::dbl(t, x); |
1229 | 12 | G::add(z, t, x); |
1230 | 12 | break; |
1231 | 0 | } |
1232 | 55 | case 4: { |
1233 | 55 | G::dbl(z, x); |
1234 | 55 | G::dbl(z, z); |
1235 | 55 | break; |
1236 | 0 | } |
1237 | 37 | case 5: { |
1238 | 37 | G t; |
1239 | 37 | G::dbl(t, x); |
1240 | 37 | G::dbl(t, t); |
1241 | 37 | G::add(z, t, x); |
1242 | 37 | break; |
1243 | 0 | } |
1244 | 107 | case 6: { |
1245 | 107 | G t; |
1246 | 107 | G::dbl(t, x); |
1247 | 107 | G::add(z, t, x); |
1248 | 107 | G::dbl(z, z); |
1249 | 107 | break; |
1250 | 0 | } |
1251 | 46 | case 7: { |
1252 | 46 | G t; |
1253 | 46 | G::dbl(t, x); |
1254 | 46 | G::dbl(t, t); |
1255 | 46 | G::dbl(t, t); |
1256 | 46 | G::sub(z, t, x); |
1257 | 46 | break; |
1258 | 0 | } |
1259 | 27 | case 8: { |
1260 | 27 | G::dbl(z, x); |
1261 | 27 | G::dbl(z, z); |
1262 | 27 | G::dbl(z, z); |
1263 | 27 | break; |
1264 | 0 | } |
1265 | 15 | case 9: { |
1266 | 15 | G t; |
1267 | 15 | G::dbl(t, x); |
1268 | 15 | G::dbl(t, t); |
1269 | 15 | G::dbl(t, t); |
1270 | 15 | G::add(z, t, x); |
1271 | 15 | break; |
1272 | 0 | } |
1273 | 6 | case 10: { |
1274 | 6 | G t; |
1275 | 6 | G::dbl(t, x); |
1276 | 6 | G::dbl(t, t); |
1277 | 6 | G::add(z, t, x); |
1278 | 6 | G::dbl(z, z); |
1279 | 6 | break; |
1280 | 0 | } |
1281 | 7 | case 11: { |
1282 | 7 | G t1, t2; |
1283 | 7 | G::dbl(t1, x); // 2x |
1284 | 7 | G::dbl(t2, t1); |
1285 | 7 | G::dbl(t2, t2); // 8x |
1286 | 7 | G::add(t2, t2, t1); |
1287 | 7 | G::add(z, t2, x); |
1288 | 7 | break; |
1289 | 0 | } |
1290 | 5 | case 12: { |
1291 | 5 | G t1, t2; |
1292 | 5 | G::dbl(t1, x); |
1293 | 5 | G::dbl(t1, t1); // 4x |
1294 | 5 | G::dbl(t2, t1); // 8x |
1295 | 5 | G::add(z, t1, t2); |
1296 | 5 | break; |
1297 | 0 | } |
1298 | 6 | case 13: { |
1299 | 6 | G t1, t2; |
1300 | 6 | G::dbl(t1, x); |
1301 | 6 | G::dbl(t1, t1); // 4x |
1302 | 6 | G::dbl(t2, t1); // 8x |
1303 | 6 | G::add(t1, t1, t2); // 12x |
1304 | 6 | G::add(z, t1, x); |
1305 | 6 | break; |
1306 | 0 | } |
1307 | 10 | case 14: { |
1308 | 10 | G t; |
1309 | | // (8 - 1) * 2 |
1310 | 10 | G::dbl(t, x); |
1311 | 10 | G::dbl(t, t); |
1312 | 10 | G::dbl(t, t); |
1313 | 10 | G::sub(t, t, x); |
1314 | 10 | G::dbl(z, t); |
1315 | 10 | break; |
1316 | 0 | } |
1317 | 13 | case 15: { |
1318 | 13 | G t; |
1319 | 13 | G::dbl(t, x); |
1320 | 13 | G::dbl(t, t); |
1321 | 13 | G::dbl(t, t); |
1322 | 13 | G::dbl(t, t); |
1323 | 13 | G::sub(z, t, x); |
1324 | 13 | break; |
1325 | 0 | } |
1326 | 6 | case 16: { |
1327 | 6 | G::dbl(z, x); |
1328 | 6 | G::dbl(z, z); |
1329 | 6 | G::dbl(z, z); |
1330 | 6 | G::dbl(z, z); |
1331 | 6 | break; |
1332 | 0 | } |
1333 | 4.89k | default: |
1334 | 4.89k | return false; |
1335 | 5.34k | } |
1336 | 429 | if (isNegative) { |
1337 | 0 | G::neg(z, z); |
1338 | 0 | } |
1339 | 429 | return true; |
1340 | 5.34k | } bool mcl::ec::mulSmallInt<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, unsigned long, bool) Line | Count | Source | 1221 | 2.22k | { | 1222 | 2.22k | switch (y) { | 1223 | 10 | case 0: z.clear(); return true; | 1224 | 25 | case 1: z = x; break; | 1225 | 13 | case 2: G::dbl(z, x); break; | 1226 | 6 | case 3: { | 1227 | 6 | G t; | 1228 | 6 | G::dbl(t, x); | 1229 | 6 | G::add(z, t, x); | 1230 | 6 | break; | 1231 | 0 | } | 1232 | 28 | case 4: { | 1233 | 28 | G::dbl(z, x); | 1234 | 28 | G::dbl(z, z); | 1235 | 28 | break; | 1236 | 0 | } | 1237 | 17 | case 5: { | 1238 | 17 | G t; | 1239 | 17 | G::dbl(t, x); | 1240 | 17 | G::dbl(t, t); | 1241 | 17 | G::add(z, t, x); | 1242 | 17 | break; | 1243 | 0 | } | 1244 | 51 | case 6: { | 1245 | 51 | G t; | 1246 | 51 | G::dbl(t, x); | 1247 | 51 | G::add(z, t, x); | 1248 | 51 | G::dbl(z, z); | 1249 | 51 | break; | 1250 | 0 | } | 1251 | 23 | case 7: { | 1252 | 23 | G t; | 1253 | 23 | G::dbl(t, x); | 1254 | 23 | G::dbl(t, t); | 1255 | 23 | G::dbl(t, t); | 1256 | 23 | G::sub(z, t, x); | 1257 | 23 | break; | 1258 | 0 | } | 1259 | 13 | case 8: { | 1260 | 13 | G::dbl(z, x); | 1261 | 13 | G::dbl(z, z); | 1262 | 13 | G::dbl(z, z); | 1263 | 13 | break; | 1264 | 0 | } | 1265 | 8 | case 9: { | 1266 | 8 | G t; | 1267 | 8 | G::dbl(t, x); | 1268 | 8 | G::dbl(t, t); | 1269 | 8 | G::dbl(t, t); | 1270 | 8 | G::add(z, t, x); | 1271 | 8 | break; | 1272 | 0 | } | 1273 | 3 | case 10: { | 1274 | 3 | G t; | 1275 | 3 | G::dbl(t, x); | 1276 | 3 | G::dbl(t, t); | 1277 | 3 | G::add(z, t, x); | 1278 | 3 | G::dbl(z, z); | 1279 | 3 | break; | 1280 | 0 | } | 1281 | 3 | case 11: { | 1282 | 3 | G t1, t2; | 1283 | 3 | G::dbl(t1, x); // 2x | 1284 | 3 | G::dbl(t2, t1); | 1285 | 3 | G::dbl(t2, t2); // 8x | 1286 | 3 | G::add(t2, t2, t1); | 1287 | 3 | G::add(z, t2, x); | 1288 | 3 | break; | 1289 | 0 | } | 1290 | 2 | case 12: { | 1291 | 2 | G t1, t2; | 1292 | 2 | G::dbl(t1, x); | 1293 | 2 | G::dbl(t1, t1); // 4x | 1294 | 2 | G::dbl(t2, t1); // 8x | 1295 | 2 | G::add(z, t1, t2); | 1296 | 2 | break; | 1297 | 0 | } | 1298 | 3 | case 13: { | 1299 | 3 | G t1, t2; | 1300 | 3 | G::dbl(t1, x); | 1301 | 3 | G::dbl(t1, t1); // 4x | 1302 | 3 | G::dbl(t2, t1); // 8x | 1303 | 3 | G::add(t1, t1, t2); // 12x | 1304 | 3 | G::add(z, t1, x); | 1305 | 3 | break; | 1306 | 0 | } | 1307 | 3 | case 14: { | 1308 | 3 | G t; | 1309 | | // (8 - 1) * 2 | 1310 | 3 | G::dbl(t, x); | 1311 | 3 | G::dbl(t, t); | 1312 | 3 | G::dbl(t, t); | 1313 | 3 | G::sub(t, t, x); | 1314 | 3 | G::dbl(z, t); | 1315 | 3 | break; | 1316 | 0 | } | 1317 | 7 | case 15: { | 1318 | 7 | G t; | 1319 | 7 | G::dbl(t, x); | 1320 | 7 | G::dbl(t, t); | 1321 | 7 | G::dbl(t, t); | 1322 | 7 | G::dbl(t, t); | 1323 | 7 | G::sub(z, t, x); | 1324 | 7 | break; | 1325 | 0 | } | 1326 | 2 | case 16: { | 1327 | 2 | G::dbl(z, x); | 1328 | 2 | G::dbl(z, z); | 1329 | 2 | G::dbl(z, z); | 1330 | 2 | G::dbl(z, z); | 1331 | 2 | break; | 1332 | 0 | } | 1333 | 2.01k | default: | 1334 | 2.01k | return false; | 1335 | 2.22k | } | 1336 | 207 | if (isNegative) { | 1337 | 0 | G::neg(z, z); | 1338 | 0 | } | 1339 | 207 | return true; | 1340 | 2.22k | } |
bool mcl::ec::mulSmallInt<mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, unsigned long, bool) Line | Count | Source | 1221 | 3.11k | { | 1222 | 3.11k | switch (y) { | 1223 | 9 | case 0: z.clear(); return true; | 1224 | 26 | case 1: z = x; break; | 1225 | 13 | case 2: G::dbl(z, x); break; | 1226 | 6 | case 3: { | 1227 | 6 | G t; | 1228 | 6 | G::dbl(t, x); | 1229 | 6 | G::add(z, t, x); | 1230 | 6 | break; | 1231 | 0 | } | 1232 | 27 | case 4: { | 1233 | 27 | G::dbl(z, x); | 1234 | 27 | G::dbl(z, z); | 1235 | 27 | break; | 1236 | 0 | } | 1237 | 20 | case 5: { | 1238 | 20 | G t; | 1239 | 20 | G::dbl(t, x); | 1240 | 20 | G::dbl(t, t); | 1241 | 20 | G::add(z, t, x); | 1242 | 20 | break; | 1243 | 0 | } | 1244 | 56 | case 6: { | 1245 | 56 | G t; | 1246 | 56 | G::dbl(t, x); | 1247 | 56 | G::add(z, t, x); | 1248 | 56 | G::dbl(z, z); | 1249 | 56 | break; | 1250 | 0 | } | 1251 | 23 | case 7: { | 1252 | 23 | G t; | 1253 | 23 | G::dbl(t, x); | 1254 | 23 | G::dbl(t, t); | 1255 | 23 | G::dbl(t, t); | 1256 | 23 | G::sub(z, t, x); | 1257 | 23 | break; | 1258 | 0 | } | 1259 | 14 | case 8: { | 1260 | 14 | G::dbl(z, x); | 1261 | 14 | G::dbl(z, z); | 1262 | 14 | G::dbl(z, z); | 1263 | 14 | break; | 1264 | 0 | } | 1265 | 7 | case 9: { | 1266 | 7 | G t; | 1267 | 7 | G::dbl(t, x); | 1268 | 7 | G::dbl(t, t); | 1269 | 7 | G::dbl(t, t); | 1270 | 7 | G::add(z, t, x); | 1271 | 7 | break; | 1272 | 0 | } | 1273 | 3 | case 10: { | 1274 | 3 | G t; | 1275 | 3 | G::dbl(t, x); | 1276 | 3 | G::dbl(t, t); | 1277 | 3 | G::add(z, t, x); | 1278 | 3 | G::dbl(z, z); | 1279 | 3 | break; | 1280 | 0 | } | 1281 | 4 | case 11: { | 1282 | 4 | G t1, t2; | 1283 | 4 | G::dbl(t1, x); // 2x | 1284 | 4 | G::dbl(t2, t1); | 1285 | 4 | G::dbl(t2, t2); // 8x | 1286 | 4 | G::add(t2, t2, t1); | 1287 | 4 | G::add(z, t2, x); | 1288 | 4 | break; | 1289 | 0 | } | 1290 | 3 | case 12: { | 1291 | 3 | G t1, t2; | 1292 | 3 | G::dbl(t1, x); | 1293 | 3 | G::dbl(t1, t1); // 4x | 1294 | 3 | G::dbl(t2, t1); // 8x | 1295 | 3 | G::add(z, t1, t2); | 1296 | 3 | break; | 1297 | 0 | } | 1298 | 3 | case 13: { | 1299 | 3 | G t1, t2; | 1300 | 3 | G::dbl(t1, x); | 1301 | 3 | G::dbl(t1, t1); // 4x | 1302 | 3 | G::dbl(t2, t1); // 8x | 1303 | 3 | G::add(t1, t1, t2); // 12x | 1304 | 3 | G::add(z, t1, x); | 1305 | 3 | break; | 1306 | 0 | } | 1307 | 7 | case 14: { | 1308 | 7 | G t; | 1309 | | // (8 - 1) * 2 | 1310 | 7 | G::dbl(t, x); | 1311 | 7 | G::dbl(t, t); | 1312 | 7 | G::dbl(t, t); | 1313 | 7 | G::sub(t, t, x); | 1314 | 7 | G::dbl(z, t); | 1315 | 7 | break; | 1316 | 0 | } | 1317 | 6 | case 15: { | 1318 | 6 | G t; | 1319 | 6 | G::dbl(t, x); | 1320 | 6 | G::dbl(t, t); | 1321 | 6 | G::dbl(t, t); | 1322 | 6 | G::dbl(t, t); | 1323 | 6 | G::sub(z, t, x); | 1324 | 6 | break; | 1325 | 0 | } | 1326 | 4 | case 16: { | 1327 | 4 | G::dbl(z, x); | 1328 | 4 | G::dbl(z, z); | 1329 | 4 | G::dbl(z, z); | 1330 | 4 | G::dbl(z, z); | 1331 | 4 | break; | 1332 | 0 | } | 1333 | 2.88k | default: | 1334 | 2.88k | return false; | 1335 | 3.11k | } | 1336 | 222 | if (isNegative) { | 1337 | 0 | G::neg(z, z); | 1338 | 0 | } | 1339 | 222 | return true; | 1340 | 3.11k | } |
Unexecuted instantiation: bool mcl::ec::mulSmallInt<mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > >(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > const&, unsigned long, bool) |
1341 | | |
1342 | | /* |
1343 | | z += xVec[i] * yVec[i] for i = 0, ..., min(N, n) |
1344 | | splitN = 2(G1) or 4(G2) |
1345 | | w : window size |
1346 | | for n <= 16 |
1347 | | */ |
1348 | | template<class GLV, class G, int w> |
1349 | | static void mulVecGLVsmall(G& z, const G *xVec, const void* yVec, size_t n) |
1350 | 4.43k | { |
1351 | 4.43k | assert(n <= mcl::fp::maxMulVecNGLV); |
1352 | 4.43k | const int splitN = GLV::splitN; |
1353 | 4.43k | const size_t tblSize = 1 << (w - 2); |
1354 | 4.43k | typedef typename GLV::Fr F; |
1355 | 4.43k | fp::getMpzAtType getMpzAt = fp::getMpzAtT<F>; |
1356 | 4.43k | typedef mcl::FixedArray<int8_t, sizeof(typename GLV::Fr) * 8 / splitN + splitN> NafArray; |
1357 | 4.43k | NafArray (*naf)[splitN] = (NafArray (*)[splitN])CYBOZU_ALLOCA(sizeof(NafArray) * n * splitN); |
1358 | | // layout tbl[splitN][n][tblSize]; |
1359 | 4.43k | G (*tbl)[tblSize] = (G (*)[tblSize])CYBOZU_ALLOCA(sizeof(G) * splitN * n * tblSize); |
1360 | 4.43k | mpz_class u[splitN], y; |
1361 | 4.43k | size_t maxBit = 0; |
1362 | | |
1363 | 8.42k | for (size_t i = 0; i < n; i++) { |
1364 | 4.43k | getMpzAt(y, yVec, i); |
1365 | 4.43k | if (n == 1) { |
1366 | 4.43k | const Unit *y0 = mcl::gmp::getUnit(y); |
1367 | 4.43k | size_t yn = mcl::gmp::getUnitSize(y); |
1368 | 4.43k | yn = bint::getRealSize(y0, yn); |
1369 | 4.43k | if (yn <= 1 && mulSmallInt(z, xVec[0], *y0, false)) return; |
1370 | 4.43k | } |
1371 | 3.98k | GLV::split(u, y); |
1372 | | |
1373 | 13.5k | for (int j = 0; j < splitN; j++) { |
1374 | 9.53k | bool b; |
1375 | 9.53k | gmp::getNAFwidth(&b, naf[i][j], u[j], w); |
1376 | 9.53k | assert(b); (void)b; |
1377 | 9.53k | if (naf[i][j].size() > maxBit) maxBit = naf[i][j].size(); |
1378 | 9.53k | } |
1379 | | |
1380 | 3.98k | G P2; |
1381 | 3.98k | G::dbl(P2, xVec[i]); |
1382 | 3.98k | tbl[0 * n + i][0] = xVec[i]; |
1383 | 31.9k | for (size_t j = 1; j < tblSize; j++) { |
1384 | 27.9k | G::add(tbl[0 * n + i][j], tbl[0 * n + i][j - 1], P2); |
1385 | 27.9k | } |
1386 | 3.98k | } |
1387 | 3.98k | G::normalizeVec(&tbl[0][0], &tbl[0][0], n * tblSize); |
1388 | 7.97k | for (size_t i = 0; i < n; i++) { |
1389 | 9.53k | for (int k = 1; k < splitN; k++) { |
1390 | 5.54k | GLV::mulLambda(tbl[k * n + i][0], tbl[(k - 1) * n + i][0]); |
1391 | 5.54k | } |
1392 | 31.9k | for (size_t j = 1; j < tblSize; j++) { |
1393 | 66.7k | for (int k = 1; k < splitN; k++) { |
1394 | 38.8k | GLV::mulLambda(tbl[k * n + i][j], tbl[(k - 1) * n + i][j]); |
1395 | 38.8k | } |
1396 | 27.9k | } |
1397 | 3.98k | } |
1398 | 3.98k | z.clear(); |
1399 | 256k | for (size_t i = 0; i < maxBit; i++) { |
1400 | 252k | const size_t bit = maxBit - 1 - i; |
1401 | 252k | G::dbl(z, z); |
1402 | 504k | for (size_t j = 0; j < n; j++) { |
1403 | 822k | for (int k = 0; k < splitN; k++) { |
1404 | 569k | local::addTbl(z, tbl[k * n + j], naf[j][k], bit); |
1405 | 569k | } |
1406 | 252k | } |
1407 | 252k | } |
1408 | 3.98k | } module.cpp:void mcl::ec::mulVecGLVsmall<mcl::bn::local::GLV1, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, 5>(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long) Line | Count | Source | 1350 | 3.42k | { | 1351 | 3.42k | assert(n <= mcl::fp::maxMulVecNGLV); | 1352 | 3.42k | const int splitN = GLV::splitN; | 1353 | 3.42k | const size_t tblSize = 1 << (w - 2); | 1354 | 3.42k | typedef typename GLV::Fr F; | 1355 | 3.42k | fp::getMpzAtType getMpzAt = fp::getMpzAtT<F>; | 1356 | 3.42k | typedef mcl::FixedArray<int8_t, sizeof(typename GLV::Fr) * 8 / splitN + splitN> NafArray; | 1357 | 3.42k | NafArray (*naf)[splitN] = (NafArray (*)[splitN])CYBOZU_ALLOCA(sizeof(NafArray) * n * splitN); | 1358 | | // layout tbl[splitN][n][tblSize]; | 1359 | 3.42k | G (*tbl)[tblSize] = (G (*)[tblSize])CYBOZU_ALLOCA(sizeof(G) * splitN * n * tblSize); | 1360 | 3.42k | mpz_class u[splitN], y; | 1361 | 3.42k | size_t maxBit = 0; | 1362 | | | 1363 | 6.63k | for (size_t i = 0; i < n; i++) { | 1364 | 3.42k | getMpzAt(y, yVec, i); | 1365 | 3.42k | if (n == 1) { | 1366 | 3.42k | const Unit *y0 = mcl::gmp::getUnit(y); | 1367 | 3.42k | size_t yn = mcl::gmp::getUnitSize(y); | 1368 | 3.42k | yn = bint::getRealSize(y0, yn); | 1369 | 3.42k | if (yn <= 1 && mulSmallInt(z, xVec[0], *y0, false)) return; | 1370 | 3.42k | } | 1371 | 3.21k | GLV::split(u, y); | 1372 | | | 1373 | 9.63k | for (int j = 0; j < splitN; j++) { | 1374 | 6.42k | bool b; | 1375 | 6.42k | gmp::getNAFwidth(&b, naf[i][j], u[j], w); | 1376 | 6.42k | assert(b); (void)b; | 1377 | 6.42k | if (naf[i][j].size() > maxBit) maxBit = naf[i][j].size(); | 1378 | 6.42k | } | 1379 | | | 1380 | 3.21k | G P2; | 1381 | 3.21k | G::dbl(P2, xVec[i]); | 1382 | 3.21k | tbl[0 * n + i][0] = xVec[i]; | 1383 | 25.6k | for (size_t j = 1; j < tblSize; j++) { | 1384 | 22.4k | G::add(tbl[0 * n + i][j], tbl[0 * n + i][j - 1], P2); | 1385 | 22.4k | } | 1386 | 3.21k | } | 1387 | 3.21k | G::normalizeVec(&tbl[0][0], &tbl[0][0], n * tblSize); | 1388 | 6.42k | for (size_t i = 0; i < n; i++) { | 1389 | 6.42k | for (int k = 1; k < splitN; k++) { | 1390 | 3.21k | GLV::mulLambda(tbl[k * n + i][0], tbl[(k - 1) * n + i][0]); | 1391 | 3.21k | } | 1392 | 25.6k | for (size_t j = 1; j < tblSize; j++) { | 1393 | 44.9k | for (int k = 1; k < splitN; k++) { | 1394 | 22.4k | GLV::mulLambda(tbl[k * n + i][j], tbl[(k - 1) * n + i][j]); | 1395 | 22.4k | } | 1396 | 22.4k | } | 1397 | 3.21k | } | 1398 | 3.21k | z.clear(); | 1399 | 223k | for (size_t i = 0; i < maxBit; i++) { | 1400 | 220k | const size_t bit = maxBit - 1 - i; | 1401 | 220k | G::dbl(z, z); | 1402 | 440k | for (size_t j = 0; j < n; j++) { | 1403 | 660k | for (int k = 0; k < splitN; k++) { | 1404 | 440k | local::addTbl(z, tbl[k * n + j], naf[j][k], bit); | 1405 | 440k | } | 1406 | 220k | } | 1407 | 220k | } | 1408 | 3.21k | } |
module.cpp:void mcl::ec::mulVecGLVsmall<mcl::bn::local::GLV2T<mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, 5>(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long) Line | Count | Source | 1350 | 1.00k | { | 1351 | 1.00k | assert(n <= mcl::fp::maxMulVecNGLV); | 1352 | 1.00k | const int splitN = GLV::splitN; | 1353 | 1.00k | const size_t tblSize = 1 << (w - 2); | 1354 | 1.00k | typedef typename GLV::Fr F; | 1355 | 1.00k | fp::getMpzAtType getMpzAt = fp::getMpzAtT<F>; | 1356 | 1.00k | typedef mcl::FixedArray<int8_t, sizeof(typename GLV::Fr) * 8 / splitN + splitN> NafArray; | 1357 | 1.00k | NafArray (*naf)[splitN] = (NafArray (*)[splitN])CYBOZU_ALLOCA(sizeof(NafArray) * n * splitN); | 1358 | | // layout tbl[splitN][n][tblSize]; | 1359 | 1.00k | G (*tbl)[tblSize] = (G (*)[tblSize])CYBOZU_ALLOCA(sizeof(G) * splitN * n * tblSize); | 1360 | 1.00k | mpz_class u[splitN], y; | 1361 | 1.00k | size_t maxBit = 0; | 1362 | | | 1363 | 1.78k | for (size_t i = 0; i < n; i++) { | 1364 | 1.00k | getMpzAt(y, yVec, i); | 1365 | 1.00k | if (n == 1) { | 1366 | 1.00k | const Unit *y0 = mcl::gmp::getUnit(y); | 1367 | 1.00k | size_t yn = mcl::gmp::getUnitSize(y); | 1368 | 1.00k | yn = bint::getRealSize(y0, yn); | 1369 | 1.00k | if (yn <= 1 && mulSmallInt(z, xVec[0], *y0, false)) return; | 1370 | 1.00k | } | 1371 | 778 | GLV::split(u, y); | 1372 | | | 1373 | 3.89k | for (int j = 0; j < splitN; j++) { | 1374 | 3.11k | bool b; | 1375 | 3.11k | gmp::getNAFwidth(&b, naf[i][j], u[j], w); | 1376 | 3.11k | assert(b); (void)b; | 1377 | 3.11k | if (naf[i][j].size() > maxBit) maxBit = naf[i][j].size(); | 1378 | 3.11k | } | 1379 | | | 1380 | 778 | G P2; | 1381 | 778 | G::dbl(P2, xVec[i]); | 1382 | 778 | tbl[0 * n + i][0] = xVec[i]; | 1383 | 6.22k | for (size_t j = 1; j < tblSize; j++) { | 1384 | 5.44k | G::add(tbl[0 * n + i][j], tbl[0 * n + i][j - 1], P2); | 1385 | 5.44k | } | 1386 | 778 | } | 1387 | 778 | G::normalizeVec(&tbl[0][0], &tbl[0][0], n * tblSize); | 1388 | 1.55k | for (size_t i = 0; i < n; i++) { | 1389 | 3.11k | for (int k = 1; k < splitN; k++) { | 1390 | 2.33k | GLV::mulLambda(tbl[k * n + i][0], tbl[(k - 1) * n + i][0]); | 1391 | 2.33k | } | 1392 | 6.22k | for (size_t j = 1; j < tblSize; j++) { | 1393 | 21.7k | for (int k = 1; k < splitN; k++) { | 1394 | 16.3k | GLV::mulLambda(tbl[k * n + i][j], tbl[(k - 1) * n + i][j]); | 1395 | 16.3k | } | 1396 | 5.44k | } | 1397 | 778 | } | 1398 | 778 | z.clear(); | 1399 | 33.1k | for (size_t i = 0; i < maxBit; i++) { | 1400 | 32.3k | const size_t bit = maxBit - 1 - i; | 1401 | 32.3k | G::dbl(z, z); | 1402 | 64.7k | for (size_t j = 0; j < n; j++) { | 1403 | 161k | for (int k = 0; k < splitN; k++) { | 1404 | 129k | local::addTbl(z, tbl[k * n + j], naf[j][k], bit); | 1405 | 129k | } | 1406 | 32.3k | } | 1407 | 32.3k | } | 1408 | 778 | } |
Unexecuted instantiation: module.cpp:void mcl::ec::mulVecGLVsmall<mcl::bn::local::GLV2T<mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >, 5>(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > const*, void const*, unsigned long) Unexecuted instantiation: module.cpp:void mcl::ec::mulVecGLVsmall<mcl::GLV1T<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, 5>(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long) |
1409 | | |
1410 | | // return false if malloc fails or n is not in a target range |
1411 | | template<class GLV, class G, class F> |
1412 | | bool mulVecGLVT(G& z, const G *xVec, const void *yVec, size_t n, bool constTime = false, size_t b = 0) |
1413 | 4.43k | { |
1414 | 4.43k | if (n == 1 && constTime) { |
1415 | 0 | local::mulGLV_CT<GLV, G>(z, xVec[0], yVec); |
1416 | 0 | return true; |
1417 | 0 | } |
1418 | 4.43k | if (n <= mcl::fp::maxMulVecNGLV) { |
1419 | 4.43k | mulVecGLVsmall<GLV, G, 5>(z, xVec, yVec, n); |
1420 | 4.43k | return true; |
1421 | 4.43k | } |
1422 | 0 | if (n >= 128) { |
1423 | 0 | return mulVecGLVlarge<GLV, G>(z, xVec, yVec, n, b); |
1424 | 0 | } |
1425 | 0 | return false; |
1426 | 0 | } bool mcl::ec::mulVecGLVT<mcl::bn::local::GLV1, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long, bool, unsigned long) Line | Count | Source | 1413 | 3.42k | { | 1414 | 3.42k | if (n == 1 && constTime) { | 1415 | 0 | local::mulGLV_CT<GLV, G>(z, xVec[0], yVec); | 1416 | 0 | return true; | 1417 | 0 | } | 1418 | 3.42k | if (n <= mcl::fp::maxMulVecNGLV) { | 1419 | 3.42k | mulVecGLVsmall<GLV, G, 5>(z, xVec, yVec, n); | 1420 | 3.42k | return true; | 1421 | 3.42k | } | 1422 | 0 | if (n >= 128) { | 1423 | 0 | return mulVecGLVlarge<GLV, G>(z, xVec, yVec, n, b); | 1424 | 0 | } | 1425 | 0 | return false; | 1426 | 0 | } |
bool mcl::ec::mulVecGLVT<mcl::bn::local::GLV2T<mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long, bool, unsigned long) Line | Count | Source | 1413 | 1.00k | { | 1414 | 1.00k | if (n == 1 && constTime) { | 1415 | 0 | local::mulGLV_CT<GLV, G>(z, xVec[0], yVec); | 1416 | 0 | return true; | 1417 | 0 | } | 1418 | 1.00k | if (n <= mcl::fp::maxMulVecNGLV) { | 1419 | 1.00k | mulVecGLVsmall<GLV, G, 5>(z, xVec, yVec, n); | 1420 | 1.00k | return true; | 1421 | 1.00k | } | 1422 | 0 | if (n >= 128) { | 1423 | 0 | return mulVecGLVlarge<GLV, G>(z, xVec, yVec, n, b); | 1424 | 0 | } | 1425 | 0 | return false; | 1426 | 0 | } |
Unexecuted instantiation: bool mcl::ec::mulVecGLVT<mcl::bn::local::GLV2T<mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >(mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > >&, mcl::GroupMtoA<mcl::Fp12T<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > > const*, void const*, unsigned long, bool, unsigned long) Unexecuted instantiation: bool mcl::ec::mulVecGLVT<mcl::GLV1T<mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long, bool, unsigned long) |
1427 | | |
1428 | | } // mcl::ec |
1429 | | |
1430 | | /* |
1431 | | elliptic curve |
1432 | | y^2 = x^3 + ax + b (affine) |
1433 | | y^2 = x^3 + az^4 + bz^6 (Jacobi) x = X/Z^2, y = Y/Z^3 |
1434 | | */ |
1435 | | template<class _Fp, class _Fr> |
1436 | | class EcT : public fp::Serializable<EcT<_Fp, _Fr> > { |
1437 | | public: |
1438 | | typedef _Fp Fp; // definition field |
1439 | | typedef _Fr Fr; // group order |
1440 | | typedef _Fp BaseFp; |
1441 | | Fp x, y, z; |
1442 | | static int mode_; |
1443 | | static Fp a_; |
1444 | | static Fp b_; |
1445 | | static Fp b3_; |
1446 | | static int specialA_; |
1447 | | static int specialB_; |
1448 | | static int ioMode_; |
1449 | | /* |
1450 | | order_ is the order of G2 which is the subgroup of EcT<Fp2, Fr>. |
1451 | | check the order of the elements if verifyOrder_ is true |
1452 | | */ |
1453 | | static bool verifyOrder_; |
1454 | | static mpz_class order_; |
1455 | | static bool (*mulVecGLV)(EcT& z, const EcT *xVec, const void *yVec, size_t n, bool constTime, size_t b); |
1456 | | static void (*mulVecOpti)(Unit *z, Unit *xVec, const Unit *yVec, size_t n, size_t b); |
1457 | | static void (*mulEachOpti)(Unit *xVec, const Unit *yVec, size_t n); |
1458 | | static bool (*isValidOrderFast)(const EcT& x); |
1459 | | /* default constructor is undefined value */ |
1460 | 160k | EcT() {}mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::EcT() Line | Count | Source | 1460 | 41.1k | EcT() {} |
mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::EcT() Line | Count | Source | 1460 | 119k | EcT() {} |
|
1461 | | EcT(const Fp& _x, const Fp& _y) |
1462 | 27.7k | { |
1463 | 27.7k | set(_x, _y); |
1464 | 27.7k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::EcT(mcl::FpT<mcl::bn::local::FpTag, 384ul> const&, mcl::FpT<mcl::bn::local::FpTag, 384ul> const&) Line | Count | Source | 1462 | 13.2k | { | 1463 | 13.2k | set(_x, _y); | 1464 | 13.2k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::EcT(mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&) Line | Count | Source | 1462 | 14.4k | { | 1463 | 14.4k | set(_x, _y); | 1464 | 14.4k | } |
|
1465 | | bool isNormalized() const |
1466 | | { |
1467 | | return isZero() || z.isOne(); |
1468 | | } |
1469 | | private: |
1470 | | bool isValidAffine() const |
1471 | 27.7k | { |
1472 | 27.7k | return ec::isValidAffine(*this); |
1473 | 27.7k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isValidAffine() const Line | Count | Source | 1471 | 13.2k | { | 1472 | 13.2k | return ec::isValidAffine(*this); | 1473 | 13.2k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isValidAffine() const Line | Count | Source | 1471 | 14.4k | { | 1472 | 14.4k | return ec::isValidAffine(*this); | 1473 | 14.4k | } |
|
1474 | | public: |
1475 | | void normalize() |
1476 | 10.3k | { |
1477 | 10.3k | switch (mode_) { |
1478 | 10.3k | case ec::Jacobi: |
1479 | 10.3k | ec::normalizeJacobi(*this); |
1480 | 10.3k | break; |
1481 | 0 | case ec::Proj: |
1482 | 0 | ec::normalizeProj(*this); |
1483 | 0 | break; |
1484 | 10.3k | } |
1485 | 10.3k | } mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::normalize() Line | Count | Source | 1476 | 2.72k | { | 1477 | 2.72k | switch (mode_) { | 1478 | 2.72k | case ec::Jacobi: | 1479 | 2.72k | ec::normalizeJacobi(*this); | 1480 | 2.72k | break; | 1481 | 0 | case ec::Proj: | 1482 | 0 | ec::normalizeProj(*this); | 1483 | 0 | break; | 1484 | 2.72k | } | 1485 | 2.72k | } |
mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::normalize() Line | Count | Source | 1476 | 7.57k | { | 1477 | 7.57k | switch (mode_) { | 1478 | 7.57k | case ec::Jacobi: | 1479 | 7.57k | ec::normalizeJacobi(*this); | 1480 | 7.57k | break; | 1481 | 0 | case ec::Proj: | 1482 | 0 | ec::normalizeProj(*this); | 1483 | 0 | break; | 1484 | 7.57k | } | 1485 | 7.57k | } |
|
1486 | | static void normalize(EcT& y, const EcT& x) |
1487 | 33 | { |
1488 | 33 | y = x; |
1489 | 33 | y.normalize(); |
1490 | 33 | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::normalize(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1487 | 21 | { | 1488 | 21 | y = x; | 1489 | 21 | y.normalize(); | 1490 | 21 | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::normalize(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1487 | 12 | { | 1488 | 12 | y = x; | 1489 | 12 | y.normalize(); | 1490 | 12 | } |
|
1491 | | static void normalizeVec(EcT *y, const EcT *x, size_t n) |
1492 | 3.98k | { |
1493 | 3.98k | if (mode_ == ec::Affine) { |
1494 | 0 | if (y == x) return; |
1495 | 0 | for (size_t i = 0; i < n; i++) { |
1496 | 0 | y[i] = x[i]; |
1497 | 0 | } |
1498 | 0 | return; |
1499 | 0 | } |
1500 | 3.98k | ec::normalizeVec(y, x, n); |
1501 | 3.98k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::normalizeVec(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, unsigned long) Line | Count | Source | 1492 | 3.21k | { | 1493 | 3.21k | if (mode_ == ec::Affine) { | 1494 | 0 | if (y == x) return; | 1495 | 0 | for (size_t i = 0; i < n; i++) { | 1496 | 0 | y[i] = x[i]; | 1497 | 0 | } | 1498 | 0 | return; | 1499 | 0 | } | 1500 | 3.21k | ec::normalizeVec(y, x, n); | 1501 | 3.21k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::normalizeVec(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >*, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, unsigned long) Line | Count | Source | 1492 | 778 | { | 1493 | 778 | if (mode_ == ec::Affine) { | 1494 | 0 | if (y == x) return; | 1495 | 0 | for (size_t i = 0; i < n; i++) { | 1496 | 0 | y[i] = x[i]; | 1497 | 0 | } | 1498 | 0 | return; | 1499 | 0 | } | 1500 | 778 | ec::normalizeVec(y, x, n); | 1501 | 778 | } |
|
1502 | | static inline void init(const Fp& a, const Fp& b, int mode = ec::Jacobi) |
1503 | 8 | { |
1504 | 8 | a_ = a; |
1505 | 8 | b_ = b; |
1506 | 8 | b3_ = b * 3; |
1507 | 8 | if (a_.isZero()) { |
1508 | 8 | specialA_ = ec::local::Zero; |
1509 | 8 | } else if (a_ == -3) { |
1510 | 0 | specialA_ = ec::local::Minus3; |
1511 | 0 | } else { |
1512 | 0 | specialA_ = ec::local::GenericA; |
1513 | 0 | } |
1514 | 8 | if (b_ == 1) { |
1515 | 0 | specialB_ = ec::local::Plus1; |
1516 | 0 | } else |
1517 | 8 | if (b_ == 4) { |
1518 | 4 | specialB_ = ec::local::Plus4; |
1519 | 4 | } else |
1520 | 4 | { |
1521 | 4 | specialB_ = ec::local::GenericB; |
1522 | 4 | } |
1523 | 8 | ioMode_ = 0; |
1524 | 8 | verifyOrder_ = false; |
1525 | 8 | order_ = 0; |
1526 | 8 | mulVecGLV = 0; |
1527 | 8 | mulVecOpti = 0; |
1528 | 8 | mulEachOpti = 0; |
1529 | 8 | isValidOrderFast = 0; |
1530 | 8 | mode_ = mode; |
1531 | 8 | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::init(mcl::FpT<mcl::bn::local::FpTag, 384ul> const&, mcl::FpT<mcl::bn::local::FpTag, 384ul> const&, int) Line | Count | Source | 1503 | 4 | { | 1504 | 4 | a_ = a; | 1505 | 4 | b_ = b; | 1506 | 4 | b3_ = b * 3; | 1507 | 4 | if (a_.isZero()) { | 1508 | 4 | specialA_ = ec::local::Zero; | 1509 | 4 | } else if (a_ == -3) { | 1510 | 0 | specialA_ = ec::local::Minus3; | 1511 | 0 | } else { | 1512 | 0 | specialA_ = ec::local::GenericA; | 1513 | 0 | } | 1514 | 4 | if (b_ == 1) { | 1515 | 0 | specialB_ = ec::local::Plus1; | 1516 | 0 | } else | 1517 | 4 | if (b_ == 4) { | 1518 | 4 | specialB_ = ec::local::Plus4; | 1519 | 4 | } else | 1520 | 0 | { | 1521 | 0 | specialB_ = ec::local::GenericB; | 1522 | 0 | } | 1523 | 4 | ioMode_ = 0; | 1524 | 4 | verifyOrder_ = false; | 1525 | 4 | order_ = 0; | 1526 | 4 | mulVecGLV = 0; | 1527 | 4 | mulVecOpti = 0; | 1528 | 4 | mulEachOpti = 0; | 1529 | 4 | isValidOrderFast = 0; | 1530 | 4 | mode_ = mode; | 1531 | 4 | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::init(mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, int) Line | Count | Source | 1503 | 4 | { | 1504 | 4 | a_ = a; | 1505 | 4 | b_ = b; | 1506 | 4 | b3_ = b * 3; | 1507 | 4 | if (a_.isZero()) { | 1508 | 4 | specialA_ = ec::local::Zero; | 1509 | 4 | } else if (a_ == -3) { | 1510 | 0 | specialA_ = ec::local::Minus3; | 1511 | 0 | } else { | 1512 | 0 | specialA_ = ec::local::GenericA; | 1513 | 0 | } | 1514 | 4 | if (b_ == 1) { | 1515 | 0 | specialB_ = ec::local::Plus1; | 1516 | 0 | } else | 1517 | 4 | if (b_ == 4) { | 1518 | 0 | specialB_ = ec::local::Plus4; | 1519 | 0 | } else | 1520 | 4 | { | 1521 | 4 | specialB_ = ec::local::GenericB; | 1522 | 4 | } | 1523 | 4 | ioMode_ = 0; | 1524 | 4 | verifyOrder_ = false; | 1525 | 4 | order_ = 0; | 1526 | 4 | mulVecGLV = 0; | 1527 | 4 | mulVecOpti = 0; | 1528 | 4 | mulEachOpti = 0; | 1529 | 4 | isValidOrderFast = 0; | 1530 | 4 | mode_ = mode; | 1531 | 4 | } |
|
1532 | | static inline int getMode() { return mode_; } |
1533 | | /* |
1534 | | verify the order of *this is equal to order if order != 0 |
1535 | | in constructor, set, setStr, operator<<(). |
1536 | | */ |
1537 | | static void setOrder(const mpz_class& order) |
1538 | 24 | { |
1539 | 24 | if (order != 0) { |
1540 | 16 | verifyOrder_ = true; |
1541 | 16 | order_ = order; |
1542 | 16 | } else { |
1543 | 8 | verifyOrder_ = false; |
1544 | | // don't clear order_ because it is used for isValidOrder() |
1545 | 8 | } |
1546 | 24 | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::setOrder(mcl::Vint const&) Line | Count | Source | 1538 | 12 | { | 1539 | 12 | if (order != 0) { | 1540 | 8 | verifyOrder_ = true; | 1541 | 8 | order_ = order; | 1542 | 8 | } else { | 1543 | 4 | verifyOrder_ = false; | 1544 | | // don't clear order_ because it is used for isValidOrder() | 1545 | 4 | } | 1546 | 12 | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::setOrder(mcl::Vint const&) Line | Count | Source | 1538 | 12 | { | 1539 | 12 | if (order != 0) { | 1540 | 8 | verifyOrder_ = true; | 1541 | 8 | order_ = order; | 1542 | 8 | } else { | 1543 | 4 | verifyOrder_ = false; | 1544 | | // don't clear order_ because it is used for isValidOrder() | 1545 | 4 | } | 1546 | 12 | } |
|
1547 | | static void setVerifyOrderFunc(bool f(const EcT&)) |
1548 | 8 | { |
1549 | 8 | isValidOrderFast = f; |
1550 | 8 | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::setVerifyOrderFunc(bool (*)(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&)) Line | Count | Source | 1548 | 4 | { | 1549 | 4 | isValidOrderFast = f; | 1550 | 4 | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::setVerifyOrderFunc(bool (*)(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&)) Line | Count | Source | 1548 | 4 | { | 1549 | 4 | isValidOrderFast = f; | 1550 | 4 | } |
|
1551 | | static void setMulVecGLV(bool f(EcT& z, const EcT *xVec, const void *yVec, size_t yn, bool constTime, size_t b)) |
1552 | 8 | { |
1553 | 8 | mulVecGLV = f; |
1554 | 8 | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::setMulVecGLV(bool (*)(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long, bool, unsigned long)) Line | Count | Source | 1552 | 4 | { | 1553 | 4 | mulVecGLV = f; | 1554 | 4 | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::setMulVecGLV(bool (*)(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const*, void const*, unsigned long, bool, unsigned long)) Line | Count | Source | 1552 | 4 | { | 1553 | 4 | mulVecGLV = f; | 1554 | 4 | } |
|
1555 | | static void setMulVecOpti(void f(Unit* _z, Unit *_xVec, const Unit *_yVec, size_t yn, size_t b)) |
1556 | 0 | { |
1557 | 0 | mulVecOpti = f; |
1558 | 0 | } |
1559 | | static void setMulEachOpti(void f(Unit *_xVec, const Unit *_yVec, size_t yn)) |
1560 | 0 | { |
1561 | 0 | mulEachOpti = f; |
1562 | 0 | } |
1563 | | static inline void init(bool *pb, const char *astr, const char *bstr, int mode = ec::Jacobi) |
1564 | 0 | { |
1565 | 0 | Fp a, b; |
1566 | 0 | a.setStr(pb, astr); |
1567 | 0 | if (!*pb) return; |
1568 | 0 | b.setStr(pb, bstr); |
1569 | 0 | if (!*pb) return; |
1570 | 0 | init(a, b, mode); |
1571 | 0 | } |
1572 | | // verify the order |
1573 | | bool isValidOrder() const |
1574 | 4.92k | { |
1575 | 4.92k | if (isValidOrderFast) { |
1576 | 4.92k | return isValidOrderFast(*this); |
1577 | 4.92k | } |
1578 | 0 | EcT Q; |
1579 | 0 | EcT::mulGeneric(Q, *this, order_); |
1580 | 0 | return Q.isZero(); |
1581 | 4.92k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isValidOrder() const Line | Count | Source | 1574 | 3.97k | { | 1575 | 3.97k | if (isValidOrderFast) { | 1576 | 3.97k | return isValidOrderFast(*this); | 1577 | 3.97k | } | 1578 | 0 | EcT Q; | 1579 | 0 | EcT::mulGeneric(Q, *this, order_); | 1580 | 0 | return Q.isZero(); | 1581 | 3.97k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isValidOrder() const Line | Count | Source | 1574 | 952 | { | 1575 | 952 | if (isValidOrderFast) { | 1576 | 952 | return isValidOrderFast(*this); | 1577 | 952 | } | 1578 | 0 | EcT Q; | 1579 | 0 | EcT::mulGeneric(Q, *this, order_); | 1580 | 0 | return Q.isZero(); | 1581 | 952 | } |
|
1582 | | bool isValid() const |
1583 | 378 | { |
1584 | 378 | switch (mode_) { |
1585 | 378 | case ec::Jacobi: |
1586 | 378 | if (!ec::isValidJacobi(*this)) return false; |
1587 | 372 | break; |
1588 | 372 | case ec::Proj: |
1589 | 0 | if (!ec::isValidProj(*this)) return false; |
1590 | 0 | break; |
1591 | 0 | case ec::Affine: |
1592 | 0 | if (z.isZero()) return true; |
1593 | 0 | if (!isValidAffine()) return false; |
1594 | 0 | break; |
1595 | 378 | } |
1596 | 372 | if (verifyOrder_) return isValidOrder(); |
1597 | 0 | return true; |
1598 | 372 | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isValid() const Line | Count | Source | 1583 | 213 | { | 1584 | 213 | switch (mode_) { | 1585 | 213 | case ec::Jacobi: | 1586 | 213 | if (!ec::isValidJacobi(*this)) return false; | 1587 | 207 | break; | 1588 | 207 | case ec::Proj: | 1589 | 0 | if (!ec::isValidProj(*this)) return false; | 1590 | 0 | break; | 1591 | 0 | case ec::Affine: | 1592 | 0 | if (z.isZero()) return true; | 1593 | 0 | if (!isValidAffine()) return false; | 1594 | 0 | break; | 1595 | 213 | } | 1596 | 207 | if (verifyOrder_) return isValidOrder(); | 1597 | 0 | return true; | 1598 | 207 | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isValid() const Line | Count | Source | 1583 | 165 | { | 1584 | 165 | switch (mode_) { | 1585 | 165 | case ec::Jacobi: | 1586 | 165 | if (!ec::isValidJacobi(*this)) return false; | 1587 | 165 | break; | 1588 | 165 | case ec::Proj: | 1589 | 0 | if (!ec::isValidProj(*this)) return false; | 1590 | 0 | break; | 1591 | 0 | case ec::Affine: | 1592 | 0 | if (z.isZero()) return true; | 1593 | 0 | if (!isValidAffine()) return false; | 1594 | 0 | break; | 1595 | 165 | } | 1596 | 165 | if (verifyOrder_) return isValidOrder(); | 1597 | 0 | return true; | 1598 | 165 | } |
|
1599 | | void set(bool *pb, const Fp& x, const Fp& y, bool verify = true) |
1600 | 27.7k | { |
1601 | 27.7k | this->x = x; |
1602 | 27.7k | this->y = y; |
1603 | 27.7k | z = 1; |
1604 | 27.7k | if (!verify || (isValidAffine() && (!verifyOrder_ || isValidOrder()))) { |
1605 | 4.34k | *pb = true; |
1606 | 4.34k | return; |
1607 | 4.34k | } |
1608 | 23.3k | *pb = false; |
1609 | 23.3k | clear(); |
1610 | 23.3k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::set(bool*, mcl::FpT<mcl::bn::local::FpTag, 384ul> const&, mcl::FpT<mcl::bn::local::FpTag, 384ul> const&, bool) Line | Count | Source | 1600 | 13.2k | { | 1601 | 13.2k | this->x = x; | 1602 | 13.2k | this->y = y; | 1603 | 13.2k | z = 1; | 1604 | 13.2k | if (!verify || (isValidAffine() && (!verifyOrder_ || isValidOrder()))) { | 1605 | 3.59k | *pb = true; | 1606 | 3.59k | return; | 1607 | 3.59k | } | 1608 | 9.70k | *pb = false; | 1609 | 9.70k | clear(); | 1610 | 9.70k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::set(bool*, mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, bool) Line | Count | Source | 1600 | 14.4k | { | 1601 | 14.4k | this->x = x; | 1602 | 14.4k | this->y = y; | 1603 | 14.4k | z = 1; | 1604 | 14.4k | if (!verify || (isValidAffine() && (!verifyOrder_ || isValidOrder()))) { | 1605 | 751 | *pb = true; | 1606 | 751 | return; | 1607 | 751 | } | 1608 | 13.6k | *pb = false; | 1609 | 13.6k | clear(); | 1610 | 13.6k | } |
|
1611 | | void clear() |
1612 | 63.4k | { |
1613 | 63.4k | if (mode_ == ec::Jacobi) { |
1614 | 63.4k | x = 0; |
1615 | 63.4k | y = 0; |
1616 | 63.4k | z.clear(); |
1617 | 63.4k | } else { // ec::Proj |
1618 | 0 | x.clear(); |
1619 | 0 | y = 1; |
1620 | 0 | z.clear(); |
1621 | 0 | } |
1622 | 63.4k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::clear() Line | Count | Source | 1612 | 42.3k | { | 1613 | 42.3k | if (mode_ == ec::Jacobi) { | 1614 | 42.3k | x = 0; | 1615 | 42.3k | y = 0; | 1616 | 42.3k | z.clear(); | 1617 | 42.3k | } else { // ec::Proj | 1618 | 0 | x.clear(); | 1619 | 0 | y = 1; | 1620 | 0 | z.clear(); | 1621 | 0 | } | 1622 | 42.3k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::clear() Line | Count | Source | 1612 | 21.0k | { | 1613 | 21.0k | if (mode_ == ec::Jacobi) { | 1614 | 21.0k | x = 0; | 1615 | 21.0k | y = 0; | 1616 | 21.0k | z.clear(); | 1617 | 21.0k | } else { // ec::Proj | 1618 | 0 | x.clear(); | 1619 | 0 | y = 1; | 1620 | 0 | z.clear(); | 1621 | 0 | } | 1622 | 21.0k | } |
|
1623 | | static inline void clear(EcT& P) |
1624 | 0 | { |
1625 | 0 | P.clear(); |
1626 | 0 | } |
1627 | | static inline void dbl(EcT& R, const EcT& P) |
1628 | 938k | { |
1629 | 938k | switch (mode_) { |
1630 | 938k | case ec::Jacobi: |
1631 | 938k | ec::dblJacobi(R, P); |
1632 | 938k | break; |
1633 | 0 | case ec::Proj: |
1634 | 0 | ec::dblProj(R, P); |
1635 | 0 | break; |
1636 | 0 | case ec::Affine: |
1637 | 0 | ec::dblAffine(R, P); |
1638 | 0 | break; |
1639 | 938k | } |
1640 | 938k | } mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::dbl(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1628 | 181k | { | 1629 | 181k | switch (mode_) { | 1630 | 181k | case ec::Jacobi: | 1631 | 181k | ec::dblJacobi(R, P); | 1632 | 181k | break; | 1633 | 0 | case ec::Proj: | 1634 | 0 | ec::dblProj(R, P); | 1635 | 0 | break; | 1636 | 0 | case ec::Affine: | 1637 | 0 | ec::dblAffine(R, P); | 1638 | 0 | break; | 1639 | 181k | } | 1640 | 181k | } |
mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::dbl(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1628 | 757k | { | 1629 | 757k | switch (mode_) { | 1630 | 757k | case ec::Jacobi: | 1631 | 757k | ec::dblJacobi(R, P); | 1632 | 757k | break; | 1633 | 0 | case ec::Proj: | 1634 | 0 | ec::dblProj(R, P); | 1635 | 0 | break; | 1636 | 0 | case ec::Affine: | 1637 | 0 | ec::dblAffine(R, P); | 1638 | 0 | break; | 1639 | 757k | } | 1640 | 757k | } |
|
1641 | | static inline void add(EcT& R, const EcT& P, const EcT& Q) |
1642 | 219k | { |
1643 | 219k | switch (mode_) { |
1644 | 219k | case ec::Jacobi: |
1645 | 219k | ec::addJacobi(R, P, Q); |
1646 | 219k | break; |
1647 | 0 | case ec::Proj: |
1648 | 0 | ec::addProj(R, P, Q); |
1649 | 0 | break; |
1650 | 0 | case ec::Affine: |
1651 | 0 | ec::addAffine(R, P, Q); |
1652 | 0 | break; |
1653 | 219k | } |
1654 | 219k | } mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::add(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1642 | 34.9k | { | 1643 | 34.9k | switch (mode_) { | 1644 | 34.9k | case ec::Jacobi: | 1645 | 34.9k | ec::addJacobi(R, P, Q); | 1646 | 34.9k | break; | 1647 | 0 | case ec::Proj: | 1648 | 0 | ec::addProj(R, P, Q); | 1649 | 0 | break; | 1650 | 0 | case ec::Affine: | 1651 | 0 | ec::addAffine(R, P, Q); | 1652 | 0 | break; | 1653 | 34.9k | } | 1654 | 34.9k | } |
mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::add(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1642 | 184k | { | 1643 | 184k | switch (mode_) { | 1644 | 184k | case ec::Jacobi: | 1645 | 184k | ec::addJacobi(R, P, Q); | 1646 | 184k | break; | 1647 | 0 | case ec::Proj: | 1648 | 0 | ec::addProj(R, P, Q); | 1649 | 0 | break; | 1650 | 0 | case ec::Affine: | 1651 | 0 | ec::addAffine(R, P, Q); | 1652 | 0 | break; | 1653 | 184k | } | 1654 | 184k | } |
|
1655 | | static inline void sub(EcT& R, const EcT& P, const EcT& Q) |
1656 | 79.3k | { |
1657 | 79.3k | EcT nQ; |
1658 | 79.3k | neg(nQ, Q); |
1659 | 79.3k | add(R, P, nQ); |
1660 | 79.3k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::sub(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1656 | 65.2k | { | 1657 | 65.2k | EcT nQ; | 1658 | 65.2k | neg(nQ, Q); | 1659 | 65.2k | add(R, P, nQ); | 1660 | 65.2k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::sub(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1656 | 14.0k | { | 1657 | 14.0k | EcT nQ; | 1658 | 14.0k | neg(nQ, Q); | 1659 | 14.0k | add(R, P, nQ); | 1660 | 14.0k | } |
|
1661 | | static inline void neg(EcT& R, const EcT& P) |
1662 | 79.3k | { |
1663 | 79.3k | if (P.isZero()) { |
1664 | 1.08k | R.clear(); |
1665 | 1.08k | return; |
1666 | 1.08k | } |
1667 | 78.2k | R.x = P.x; |
1668 | 78.2k | Fp::neg(R.y, P.y); |
1669 | 78.2k | R.z = P.z; |
1670 | 78.2k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::neg(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1662 | 65.2k | { | 1663 | 65.2k | if (P.isZero()) { | 1664 | 1.01k | R.clear(); | 1665 | 1.01k | return; | 1666 | 1.01k | } | 1667 | 64.2k | R.x = P.x; | 1668 | 64.2k | Fp::neg(R.y, P.y); | 1669 | 64.2k | R.z = P.z; | 1670 | 64.2k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::neg(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 1662 | 14.0k | { | 1663 | 14.0k | if (P.isZero()) { | 1664 | 72 | R.clear(); | 1665 | 72 | return; | 1666 | 72 | } | 1667 | 14.0k | R.x = P.x; | 1668 | 14.0k | Fp::neg(R.y, P.y); | 1669 | 14.0k | R.z = P.z; | 1670 | 14.0k | } |
|
1671 | | static inline void mul(EcT& z, const EcT& x, const EcT::Fr& y, bool constTime = false) |
1672 | 4.43k | { |
1673 | 4.43k | if (mulVecGLV) { |
1674 | 4.43k | mulVecGLV(z, &x, &y, 1, constTime, 0); |
1675 | 4.43k | return; |
1676 | 4.43k | } |
1677 | 0 | fp::Block b; |
1678 | 0 | y.getBlock(b); |
1679 | 0 | mulArray(z, x, b.p, b.n, false, constTime); |
1680 | 0 | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::mul(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::FpT<mcl::bn::local::FrTag, 256ul> const&, bool) Line | Count | Source | 1672 | 3.42k | { | 1673 | 3.42k | if (mulVecGLV) { | 1674 | 3.42k | mulVecGLV(z, &x, &y, 1, constTime, 0); | 1675 | 3.42k | return; | 1676 | 3.42k | } | 1677 | 0 | fp::Block b; | 1678 | 0 | y.getBlock(b); | 1679 | 0 | mulArray(z, x, b.p, b.n, false, constTime); | 1680 | 0 | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::mul(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::FpT<mcl::bn::local::FrTag, 256ul> const&, bool) Line | Count | Source | 1672 | 1.00k | { | 1673 | 1.00k | if (mulVecGLV) { | 1674 | 1.00k | mulVecGLV(z, &x, &y, 1, constTime, 0); | 1675 | 1.00k | return; | 1676 | 1.00k | } | 1677 | 0 | fp::Block b; | 1678 | 0 | y.getBlock(b); | 1679 | 0 | mulArray(z, x, b.p, b.n, false, constTime); | 1680 | 0 | } |
|
1681 | | static inline void mul(EcT& z, const EcT& x, int64_t y) |
1682 | | { |
1683 | | const uint64_t u = fp::abs_(y); |
1684 | | #if MCL_SIZEOF_UNIT == 8 |
1685 | | const uint64_t *ua = &u; |
1686 | | const size_t un = 1; |
1687 | | #else |
1688 | | uint32_t ua[2] = { uint32_t(u), uint32_t(u >> 32) }; |
1689 | | const size_t un = ua[1] ? 2 : 1; |
1690 | | #endif |
1691 | | mulArray(z, x, ua, un, y < 0); |
1692 | | } |
1693 | | static inline void mul(EcT& z, const EcT& x, const mpz_class& y) |
1694 | | { |
1695 | | mulArray(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0); |
1696 | | } |
1697 | | // not const time |
1698 | | static inline void mulCT(EcT& z, const EcT& x, const EcT::Fr& y) |
1699 | | { |
1700 | | mul(z, x, y, true); |
1701 | | } |
1702 | | static inline void mulCT(EcT& z, const EcT& x, const mpz_class& y) |
1703 | | { |
1704 | | mulArray(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0, true); |
1705 | | } |
1706 | | /* |
1707 | | 0 <= P for any P |
1708 | | (Px, Py) <= (P'x, P'y) iff Px < P'x or Px == P'x and Py <= P'y |
1709 | | @note compare function calls normalize() |
1710 | | */ |
1711 | | template<class F> |
1712 | | static inline int compareFunc(const EcT& P_, const EcT& Q_, F comp) |
1713 | | { |
1714 | | const bool QisZero = Q_.isZero(); |
1715 | | if (P_.isZero()) { |
1716 | | if (QisZero) return 0; |
1717 | | return -1; |
1718 | | } |
1719 | | if (QisZero) return 1; |
1720 | | EcT P(P_), Q(Q_); |
1721 | | P.normalize(); |
1722 | | Q.normalize(); |
1723 | | int c = comp(P.x, Q.x); |
1724 | | if (c > 0) return 1; |
1725 | | if (c < 0) return -1; |
1726 | | return comp(P.y, Q.y); |
1727 | | } |
1728 | | static inline int compare(const EcT& P, const EcT& Q) |
1729 | | { |
1730 | | return compareFunc(P, Q, Fp::compare); |
1731 | | } |
1732 | | static inline int compareRaw(const EcT& P, const EcT& Q) |
1733 | | { |
1734 | | return compareFunc(P, Q, Fp::compareRaw); |
1735 | | } |
1736 | | bool isZero() const |
1737 | 1.45M | { |
1738 | 1.45M | return z.isZero(); |
1739 | 1.45M | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isZero() const Line | Count | Source | 1737 | 1.19M | { | 1738 | 1.19M | return z.isZero(); | 1739 | 1.19M | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isZero() const Line | Count | Source | 1737 | 265k | { | 1738 | 265k | return z.isZero(); | 1739 | 265k | } |
|
1740 | | static inline bool isMSBserialize() |
1741 | 0 | { |
1742 | 0 | return !b_.isZero() && (Fp::BaseFp::getBitSize() & 7) != 0; |
1743 | 0 | } Unexecuted instantiation: mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isMSBserialize() Unexecuted instantiation: mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::isMSBserialize() |
1744 | | // return serialized byte size |
1745 | | static inline size_t getSerializedByteSize() |
1746 | | { |
1747 | | const size_t n = Fp::getByteSize(); |
1748 | | const size_t adj = isMSBserialize() ? 0 : 1; |
1749 | | return n + adj; |
1750 | | } |
1751 | | template<class OutputStream> |
1752 | | void save(bool *pb, OutputStream& os, int ioMode) const |
1753 | 5.12k | { |
1754 | 5.12k | const char sep = *fp::getIoSeparator(ioMode); |
1755 | 5.12k | if (ioMode & IoEcProj) { |
1756 | 0 | cybozu::writeChar(pb, os, '4'); if (!*pb) return; |
1757 | 0 | if (sep) { |
1758 | 0 | cybozu::writeChar(pb, os, sep); |
1759 | 0 | if (!*pb) return; |
1760 | 0 | } |
1761 | 0 | x.save(pb, os, ioMode); if (!*pb) return; |
1762 | 0 | if (sep) { |
1763 | 0 | cybozu::writeChar(pb, os, sep); |
1764 | 0 | if (!*pb) return; |
1765 | 0 | } |
1766 | 0 | y.save(pb, os, ioMode); if (!*pb) return; |
1767 | 0 | if (sep) { |
1768 | 0 | cybozu::writeChar(pb, os, sep); |
1769 | 0 | if (!*pb) return; |
1770 | 0 | } |
1771 | 0 | z.save(pb, os, ioMode); |
1772 | 0 | return; |
1773 | 0 | } |
1774 | 5.12k | EcT P(*this); |
1775 | 5.12k | P.normalize(); |
1776 | 5.12k | if (ioMode & IoEcAffineSerialize) { |
1777 | 0 | if (b_ == 0) { // assume Zero if x = y = 0 |
1778 | 0 | *pb = false; |
1779 | 0 | return; |
1780 | 0 | } |
1781 | 0 | if (isZero()) { |
1782 | | // all zero |
1783 | 0 | P.z.save(pb, os, IoSerialize); |
1784 | 0 | if (!*pb) return; |
1785 | 0 | P.z.save(pb, os, IoSerialize); |
1786 | 0 | return; |
1787 | 0 | } |
1788 | 0 | P.x.save(pb, os, IoSerialize); |
1789 | 0 | if (!*pb) return; |
1790 | 0 | P.y.save(pb, os, IoSerialize); |
1791 | 0 | return; |
1792 | 0 | } |
1793 | 5.12k | if (ioMode & (IoSerialize | IoSerializeHexStr)) { |
1794 | 0 | const size_t n = Fp::getByteSize(); |
1795 | 0 | const size_t adj = isMSBserialize() ? 0 : 1; |
1796 | 0 | uint8_t buf[sizeof(Fp) + 1]; |
1797 | 0 | if (Fp::BaseFp::getETHserialization()) { |
1798 | 0 | const uint8_t c_flag = 0x80; |
1799 | 0 | const uint8_t b_flag = 0x40; |
1800 | 0 | const uint8_t a_flag = 0x20; |
1801 | 0 | if (P.isZero()) { |
1802 | 0 | buf[0] = c_flag | b_flag; |
1803 | 0 | memset(buf + 1, 0, n - 1); |
1804 | 0 | } else { |
1805 | 0 | cybozu::MemoryOutputStream mos(buf, n); |
1806 | 0 | P.x.save(pb, mos, IoSerialize); if (!*pb) return; |
1807 | 0 | uint8_t cba = c_flag; |
1808 | 0 | if (ec::local::get_a_flag(P.y)) cba |= a_flag; |
1809 | 0 | buf[0] |= cba; |
1810 | 0 | } |
1811 | 0 | } else { |
1812 | | /* |
1813 | | if (isMSBserialize()) { |
1814 | | // n bytes |
1815 | | x | (y.isOdd ? 0x80 : 0) |
1816 | | } else { |
1817 | | // n + 1 bytes |
1818 | | (y.isOdd ? 3 : 2), x |
1819 | | } |
1820 | | */ |
1821 | 0 | if (isZero()) { |
1822 | 0 | memset(buf, 0, n + adj); |
1823 | 0 | } else { |
1824 | 0 | cybozu::MemoryOutputStream mos(buf + adj, n); |
1825 | 0 | P.x.save(pb, mos, IoSerialize); if (!*pb) return; |
1826 | 0 | if (adj) { |
1827 | 0 | buf[0] = P.y.isOdd() ? 3 : 2; |
1828 | 0 | } else { |
1829 | 0 | if (P.y.isOdd()) { |
1830 | 0 | buf[n - 1] |= 0x80; |
1831 | 0 | } |
1832 | 0 | } |
1833 | 0 | } |
1834 | 0 | } |
1835 | 0 | if (ioMode & IoSerializeHexStr) { |
1836 | 0 | mcl::fp::writeHexStr(pb, os, buf, n + adj); |
1837 | 0 | } else { |
1838 | 0 | cybozu::write(pb, os, buf, n + adj); |
1839 | 0 | } |
1840 | 0 | return; |
1841 | 0 | } |
1842 | 5.12k | if (isZero()) { |
1843 | 32 | cybozu::writeChar(pb, os, '0'); |
1844 | 32 | return; |
1845 | 32 | } |
1846 | 5.09k | if (ioMode & IoEcCompY) { |
1847 | 0 | cybozu::writeChar(pb, os, P.y.isOdd() ? '3' : '2'); |
1848 | 0 | if (!*pb) return; |
1849 | 0 | if (sep) { |
1850 | 0 | cybozu::writeChar(pb, os, sep); |
1851 | 0 | if (!*pb) return; |
1852 | 0 | } |
1853 | 0 | P.x.save(pb, os, ioMode); |
1854 | 5.09k | } else { |
1855 | 5.09k | cybozu::writeChar(pb, os, '1'); if (!*pb) return; |
1856 | 5.09k | if (sep) { |
1857 | 5.09k | cybozu::writeChar(pb, os, sep); |
1858 | 5.09k | if (!*pb) return; |
1859 | 5.09k | } |
1860 | 5.09k | P.x.save(pb, os, ioMode); if (!*pb) return; |
1861 | 5.09k | if (sep) { |
1862 | 5.09k | cybozu::writeChar(pb, os, sep); |
1863 | 5.09k | if (!*pb) return; |
1864 | 5.09k | } |
1865 | 5.09k | P.y.save(pb, os, ioMode); |
1866 | 5.09k | } |
1867 | 5.09k | } void mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::save<cybozu::StringOutputStream>(bool*, cybozu::StringOutputStream&, int) const Line | Count | Source | 1753 | 3.77k | { | 1754 | 3.77k | const char sep = *fp::getIoSeparator(ioMode); | 1755 | 3.77k | if (ioMode & IoEcProj) { | 1756 | 0 | cybozu::writeChar(pb, os, '4'); if (!*pb) return; | 1757 | 0 | if (sep) { | 1758 | 0 | cybozu::writeChar(pb, os, sep); | 1759 | 0 | if (!*pb) return; | 1760 | 0 | } | 1761 | 0 | x.save(pb, os, ioMode); if (!*pb) return; | 1762 | 0 | if (sep) { | 1763 | 0 | cybozu::writeChar(pb, os, sep); | 1764 | 0 | if (!*pb) return; | 1765 | 0 | } | 1766 | 0 | y.save(pb, os, ioMode); if (!*pb) return; | 1767 | 0 | if (sep) { | 1768 | 0 | cybozu::writeChar(pb, os, sep); | 1769 | 0 | if (!*pb) return; | 1770 | 0 | } | 1771 | 0 | z.save(pb, os, ioMode); | 1772 | 0 | return; | 1773 | 0 | } | 1774 | 3.77k | EcT P(*this); | 1775 | 3.77k | P.normalize(); | 1776 | 3.77k | if (ioMode & IoEcAffineSerialize) { | 1777 | 0 | if (b_ == 0) { // assume Zero if x = y = 0 | 1778 | 0 | *pb = false; | 1779 | 0 | return; | 1780 | 0 | } | 1781 | 0 | if (isZero()) { | 1782 | | // all zero | 1783 | 0 | P.z.save(pb, os, IoSerialize); | 1784 | 0 | if (!*pb) return; | 1785 | 0 | P.z.save(pb, os, IoSerialize); | 1786 | 0 | return; | 1787 | 0 | } | 1788 | 0 | P.x.save(pb, os, IoSerialize); | 1789 | 0 | if (!*pb) return; | 1790 | 0 | P.y.save(pb, os, IoSerialize); | 1791 | 0 | return; | 1792 | 0 | } | 1793 | 3.77k | if (ioMode & (IoSerialize | IoSerializeHexStr)) { | 1794 | 0 | const size_t n = Fp::getByteSize(); | 1795 | 0 | const size_t adj = isMSBserialize() ? 0 : 1; | 1796 | 0 | uint8_t buf[sizeof(Fp) + 1]; | 1797 | 0 | if (Fp::BaseFp::getETHserialization()) { | 1798 | 0 | const uint8_t c_flag = 0x80; | 1799 | 0 | const uint8_t b_flag = 0x40; | 1800 | 0 | const uint8_t a_flag = 0x20; | 1801 | 0 | if (P.isZero()) { | 1802 | 0 | buf[0] = c_flag | b_flag; | 1803 | 0 | memset(buf + 1, 0, n - 1); | 1804 | 0 | } else { | 1805 | 0 | cybozu::MemoryOutputStream mos(buf, n); | 1806 | 0 | P.x.save(pb, mos, IoSerialize); if (!*pb) return; | 1807 | 0 | uint8_t cba = c_flag; | 1808 | 0 | if (ec::local::get_a_flag(P.y)) cba |= a_flag; | 1809 | 0 | buf[0] |= cba; | 1810 | 0 | } | 1811 | 0 | } else { | 1812 | | /* | 1813 | | if (isMSBserialize()) { | 1814 | | // n bytes | 1815 | | x | (y.isOdd ? 0x80 : 0) | 1816 | | } else { | 1817 | | // n + 1 bytes | 1818 | | (y.isOdd ? 3 : 2), x | 1819 | | } | 1820 | | */ | 1821 | 0 | if (isZero()) { | 1822 | 0 | memset(buf, 0, n + adj); | 1823 | 0 | } else { | 1824 | 0 | cybozu::MemoryOutputStream mos(buf + adj, n); | 1825 | 0 | P.x.save(pb, mos, IoSerialize); if (!*pb) return; | 1826 | 0 | if (adj) { | 1827 | 0 | buf[0] = P.y.isOdd() ? 3 : 2; | 1828 | 0 | } else { | 1829 | 0 | if (P.y.isOdd()) { | 1830 | 0 | buf[n - 1] |= 0x80; | 1831 | 0 | } | 1832 | 0 | } | 1833 | 0 | } | 1834 | 0 | } | 1835 | 0 | if (ioMode & IoSerializeHexStr) { | 1836 | 0 | mcl::fp::writeHexStr(pb, os, buf, n + adj); | 1837 | 0 | } else { | 1838 | 0 | cybozu::write(pb, os, buf, n + adj); | 1839 | 0 | } | 1840 | 0 | return; | 1841 | 0 | } | 1842 | 3.77k | if (isZero()) { | 1843 | 15 | cybozu::writeChar(pb, os, '0'); | 1844 | 15 | return; | 1845 | 15 | } | 1846 | 3.76k | if (ioMode & IoEcCompY) { | 1847 | 0 | cybozu::writeChar(pb, os, P.y.isOdd() ? '3' : '2'); | 1848 | 0 | if (!*pb) return; | 1849 | 0 | if (sep) { | 1850 | 0 | cybozu::writeChar(pb, os, sep); | 1851 | 0 | if (!*pb) return; | 1852 | 0 | } | 1853 | 0 | P.x.save(pb, os, ioMode); | 1854 | 3.76k | } else { | 1855 | 3.76k | cybozu::writeChar(pb, os, '1'); if (!*pb) return; | 1856 | 3.76k | if (sep) { | 1857 | 3.76k | cybozu::writeChar(pb, os, sep); | 1858 | 3.76k | if (!*pb) return; | 1859 | 3.76k | } | 1860 | 3.76k | P.x.save(pb, os, ioMode); if (!*pb) return; | 1861 | 3.76k | if (sep) { | 1862 | 3.76k | cybozu::writeChar(pb, os, sep); | 1863 | 3.76k | if (!*pb) return; | 1864 | 3.76k | } | 1865 | 3.76k | P.y.save(pb, os, ioMode); | 1866 | 3.76k | } | 1867 | 3.76k | } |
void mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::save<cybozu::StringOutputStream>(bool*, cybozu::StringOutputStream&, int) const Line | Count | Source | 1753 | 1.35k | { | 1754 | 1.35k | const char sep = *fp::getIoSeparator(ioMode); | 1755 | 1.35k | if (ioMode & IoEcProj) { | 1756 | 0 | cybozu::writeChar(pb, os, '4'); if (!*pb) return; | 1757 | 0 | if (sep) { | 1758 | 0 | cybozu::writeChar(pb, os, sep); | 1759 | 0 | if (!*pb) return; | 1760 | 0 | } | 1761 | 0 | x.save(pb, os, ioMode); if (!*pb) return; | 1762 | 0 | if (sep) { | 1763 | 0 | cybozu::writeChar(pb, os, sep); | 1764 | 0 | if (!*pb) return; | 1765 | 0 | } | 1766 | 0 | y.save(pb, os, ioMode); if (!*pb) return; | 1767 | 0 | if (sep) { | 1768 | 0 | cybozu::writeChar(pb, os, sep); | 1769 | 0 | if (!*pb) return; | 1770 | 0 | } | 1771 | 0 | z.save(pb, os, ioMode); | 1772 | 0 | return; | 1773 | 0 | } | 1774 | 1.35k | EcT P(*this); | 1775 | 1.35k | P.normalize(); | 1776 | 1.35k | if (ioMode & IoEcAffineSerialize) { | 1777 | 0 | if (b_ == 0) { // assume Zero if x = y = 0 | 1778 | 0 | *pb = false; | 1779 | 0 | return; | 1780 | 0 | } | 1781 | 0 | if (isZero()) { | 1782 | | // all zero | 1783 | 0 | P.z.save(pb, os, IoSerialize); | 1784 | 0 | if (!*pb) return; | 1785 | 0 | P.z.save(pb, os, IoSerialize); | 1786 | 0 | return; | 1787 | 0 | } | 1788 | 0 | P.x.save(pb, os, IoSerialize); | 1789 | 0 | if (!*pb) return; | 1790 | 0 | P.y.save(pb, os, IoSerialize); | 1791 | 0 | return; | 1792 | 0 | } | 1793 | 1.35k | if (ioMode & (IoSerialize | IoSerializeHexStr)) { | 1794 | 0 | const size_t n = Fp::getByteSize(); | 1795 | 0 | const size_t adj = isMSBserialize() ? 0 : 1; | 1796 | 0 | uint8_t buf[sizeof(Fp) + 1]; | 1797 | 0 | if (Fp::BaseFp::getETHserialization()) { | 1798 | 0 | const uint8_t c_flag = 0x80; | 1799 | 0 | const uint8_t b_flag = 0x40; | 1800 | 0 | const uint8_t a_flag = 0x20; | 1801 | 0 | if (P.isZero()) { | 1802 | 0 | buf[0] = c_flag | b_flag; | 1803 | 0 | memset(buf + 1, 0, n - 1); | 1804 | 0 | } else { | 1805 | 0 | cybozu::MemoryOutputStream mos(buf, n); | 1806 | 0 | P.x.save(pb, mos, IoSerialize); if (!*pb) return; | 1807 | 0 | uint8_t cba = c_flag; | 1808 | 0 | if (ec::local::get_a_flag(P.y)) cba |= a_flag; | 1809 | 0 | buf[0] |= cba; | 1810 | 0 | } | 1811 | 0 | } else { | 1812 | | /* | 1813 | | if (isMSBserialize()) { | 1814 | | // n bytes | 1815 | | x | (y.isOdd ? 0x80 : 0) | 1816 | | } else { | 1817 | | // n + 1 bytes | 1818 | | (y.isOdd ? 3 : 2), x | 1819 | | } | 1820 | | */ | 1821 | 0 | if (isZero()) { | 1822 | 0 | memset(buf, 0, n + adj); | 1823 | 0 | } else { | 1824 | 0 | cybozu::MemoryOutputStream mos(buf + adj, n); | 1825 | 0 | P.x.save(pb, mos, IoSerialize); if (!*pb) return; | 1826 | 0 | if (adj) { | 1827 | 0 | buf[0] = P.y.isOdd() ? 3 : 2; | 1828 | 0 | } else { | 1829 | 0 | if (P.y.isOdd()) { | 1830 | 0 | buf[n - 1] |= 0x80; | 1831 | 0 | } | 1832 | 0 | } | 1833 | 0 | } | 1834 | 0 | } | 1835 | 0 | if (ioMode & IoSerializeHexStr) { | 1836 | 0 | mcl::fp::writeHexStr(pb, os, buf, n + adj); | 1837 | 0 | } else { | 1838 | 0 | cybozu::write(pb, os, buf, n + adj); | 1839 | 0 | } | 1840 | 0 | return; | 1841 | 0 | } | 1842 | 1.35k | if (isZero()) { | 1843 | 17 | cybozu::writeChar(pb, os, '0'); | 1844 | 17 | return; | 1845 | 17 | } | 1846 | 1.33k | if (ioMode & IoEcCompY) { | 1847 | 0 | cybozu::writeChar(pb, os, P.y.isOdd() ? '3' : '2'); | 1848 | 0 | if (!*pb) return; | 1849 | 0 | if (sep) { | 1850 | 0 | cybozu::writeChar(pb, os, sep); | 1851 | 0 | if (!*pb) return; | 1852 | 0 | } | 1853 | 0 | P.x.save(pb, os, ioMode); | 1854 | 1.33k | } else { | 1855 | 1.33k | cybozu::writeChar(pb, os, '1'); if (!*pb) return; | 1856 | 1.33k | if (sep) { | 1857 | 1.33k | cybozu::writeChar(pb, os, sep); | 1858 | 1.33k | if (!*pb) return; | 1859 | 1.33k | } | 1860 | 1.33k | P.x.save(pb, os, ioMode); if (!*pb) return; | 1861 | 1.33k | if (sep) { | 1862 | 1.33k | cybozu::writeChar(pb, os, sep); | 1863 | 1.33k | if (!*pb) return; | 1864 | 1.33k | } | 1865 | 1.33k | P.y.save(pb, os, ioMode); | 1866 | 1.33k | } | 1867 | 1.33k | } |
|
1868 | | template<class InputStream> |
1869 | | void load(bool *pb, InputStream& is, int ioMode) |
1870 | | { |
1871 | | z = 1; |
1872 | | if (ioMode & IoEcAffineSerialize) { |
1873 | | if (b_ == 0) { // assume Zero if x = y = 0 |
1874 | | *pb = false; |
1875 | | return; |
1876 | | } |
1877 | | x.load(pb, is, IoSerialize); |
1878 | | if (!*pb) return; |
1879 | | y.load(pb, is, IoSerialize); |
1880 | | if (!*pb) return; |
1881 | | if (x.isZero() && y.isZero()) { |
1882 | | z.clear(); |
1883 | | return; |
1884 | | } |
1885 | | goto verifyValidAffine; |
1886 | | } |
1887 | | if (ioMode & (IoSerialize | IoSerializeHexStr)) { |
1888 | | const size_t n = Fp::getByteSize(); |
1889 | | const size_t adj = isMSBserialize() ? 0 : 1; |
1890 | | const size_t n1 = n + adj; |
1891 | | uint8_t buf[sizeof(Fp) + 1]; |
1892 | | size_t readSize; |
1893 | | if (ioMode & IoSerializeHexStr) { |
1894 | | readSize = mcl::fp::readHexStr(buf, n1, is); |
1895 | | } else { |
1896 | | readSize = cybozu::readSome(buf, n1, is); |
1897 | | } |
1898 | | if (readSize != n1) { |
1899 | | *pb = false; |
1900 | | return; |
1901 | | } |
1902 | | if (Fp::BaseFp::getETHserialization()) { |
1903 | | const uint8_t c_flag = 0x80; |
1904 | | const uint8_t b_flag = 0x40; |
1905 | | const uint8_t a_flag = 0x20; |
1906 | | *pb = false; |
1907 | | if ((buf[0] & c_flag) == 0) { // assume compressed |
1908 | | return; |
1909 | | } |
1910 | | if (buf[0] & b_flag) { // infinity |
1911 | | if (buf[0] != (c_flag | b_flag)) return; |
1912 | | for (size_t i = 1; i < n - 1; i++) { |
1913 | | if (buf[i]) return; |
1914 | | } |
1915 | | clear(); |
1916 | | *pb = true; |
1917 | | return; |
1918 | | } |
1919 | | bool a = (buf[0] & a_flag) != 0; |
1920 | | buf[0] &= ~(c_flag | b_flag | a_flag); |
1921 | | mcl::fp::local::byteSwap(buf, n); |
1922 | | x.setArray(pb, buf, n); |
1923 | | if (!*pb) return; |
1924 | | getWeierstrass(y, x); |
1925 | | if (!Fp::squareRoot(y, y)) { |
1926 | | *pb = false; |
1927 | | return; |
1928 | | } |
1929 | | if (ec::local::get_a_flag(y) ^ a) { |
1930 | | Fp::neg(y, y); |
1931 | | } |
1932 | | goto verifyOrder; |
1933 | | } |
1934 | | if (bint::isZeroN(buf, n1)) { |
1935 | | clear(); |
1936 | | *pb = true; |
1937 | | return; |
1938 | | } |
1939 | | bool isYodd; |
1940 | | if (adj) { |
1941 | | char c = buf[0]; |
1942 | | if (c != 2 && c != 3) { |
1943 | | *pb = false; |
1944 | | return; |
1945 | | } |
1946 | | isYodd = c == 3; |
1947 | | } else { |
1948 | | isYodd = (buf[n - 1] >> 7) != 0; |
1949 | | buf[n - 1] &= 0x7f; |
1950 | | } |
1951 | | x.setArray(pb, buf + adj, n); |
1952 | | if (!*pb) return; |
1953 | | *pb = getYfromX(y, x, isYodd); |
1954 | | if (!*pb) return; |
1955 | | } else { |
1956 | | char c = 0; |
1957 | | if (!fp::local::skipSpace(&c, is)) { |
1958 | | *pb = false; |
1959 | | return; |
1960 | | } |
1961 | | if (c == '0') { |
1962 | | clear(); |
1963 | | *pb = true; |
1964 | | return; |
1965 | | } |
1966 | | x.load(pb, is, ioMode); if (!*pb) return; |
1967 | | if (c == '1') { |
1968 | | y.load(pb, is, ioMode); if (!*pb) return; |
1969 | | goto verifyValidAffine; |
1970 | | } else if (c == '2' || c == '3') { |
1971 | | bool isYodd = c == '3'; |
1972 | | *pb = getYfromX(y, x, isYodd); |
1973 | | if (!*pb) return; |
1974 | | } else if (c == '4') { |
1975 | | y.load(pb, is, ioMode); if (!*pb) return; |
1976 | | z.load(pb, is, ioMode); if (!*pb) return; |
1977 | | if (mode_ == ec::Affine) { |
1978 | | if (!z.isZero() && !z.isOne()) { |
1979 | | *pb = false; |
1980 | | return; |
1981 | | } |
1982 | | } |
1983 | | *pb = isValid(); |
1984 | | return; |
1985 | | } else { |
1986 | | *pb = false; |
1987 | | return; |
1988 | | } |
1989 | | } |
1990 | | verifyOrder: |
1991 | | if (verifyOrder_ && !isValidOrder()) { |
1992 | | *pb = false; |
1993 | | } else { |
1994 | | *pb = true; |
1995 | | } |
1996 | | return; |
1997 | | verifyValidAffine: |
1998 | | if (!isValidAffine()) { |
1999 | | *pb = false; |
2000 | | return; |
2001 | | } |
2002 | | goto verifyOrder; |
2003 | | } |
2004 | | // deplicated |
2005 | | static void setCompressedExpression(bool compressedExpression = true) |
2006 | 8 | { |
2007 | 8 | if (compressedExpression) { |
2008 | 8 | ioMode_ |= IoEcCompY; |
2009 | 8 | } else { |
2010 | 0 | ioMode_ &= ~IoEcCompY; |
2011 | 0 | } |
2012 | 8 | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::setCompressedExpression(bool) Line | Count | Source | 2006 | 4 | { | 2007 | 4 | if (compressedExpression) { | 2008 | 4 | ioMode_ |= IoEcCompY; | 2009 | 4 | } else { | 2010 | 0 | ioMode_ &= ~IoEcCompY; | 2011 | 0 | } | 2012 | 4 | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::setCompressedExpression(bool) Line | Count | Source | 2006 | 4 | { | 2007 | 4 | if (compressedExpression) { | 2008 | 4 | ioMode_ |= IoEcCompY; | 2009 | 4 | } else { | 2010 | 0 | ioMode_ &= ~IoEcCompY; | 2011 | 0 | } | 2012 | 4 | } |
|
2013 | | /* |
2014 | | set IoMode for operator<<(), or operator>>() |
2015 | | */ |
2016 | | static void setIoMode(int ioMode) |
2017 | | { |
2018 | | assert(!(ioMode & 0xff)); |
2019 | | ioMode_ = ioMode; |
2020 | | } |
2021 | | static inline int getIoMode() { return Fp::BaseFp::getIoMode() | ioMode_; } |
2022 | | static inline void getWeierstrass(Fp& yy, const Fp& x) |
2023 | 0 | { |
2024 | 0 | Fp t; |
2025 | 0 | Fp::sqr(t, x); |
2026 | 0 | t += a_; |
2027 | 0 | t *= x; |
2028 | 0 | Fp::add(yy, t, b_); |
2029 | 0 | } Unexecuted instantiation: mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::getWeierstrass(mcl::FpT<mcl::bn::local::FpTag, 384ul>&, mcl::FpT<mcl::bn::local::FpTag, 384ul> const&) Unexecuted instantiation: mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::getWeierstrass(mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >&, mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&) |
2030 | | static inline bool getYfromX(Fp& y, const Fp& x, bool isYodd) |
2031 | | { |
2032 | | getWeierstrass(y, x); |
2033 | | if (!Fp::squareRoot(y, y)) { |
2034 | | return false; |
2035 | | } |
2036 | | if (y.isOdd() ^ isYodd) { |
2037 | | Fp::neg(y, y); |
2038 | | } |
2039 | | return true; |
2040 | | } |
2041 | 26 | inline friend EcT operator+(const EcT& x, const EcT& y) { EcT z; add(z, x, y); return z; }mcl::operator+(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 2041 | 15 | inline friend EcT operator+(const EcT& x, const EcT& y) { EcT z; add(z, x, y); return z; } |
mcl::operator+(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 2041 | 11 | inline friend EcT operator+(const EcT& x, const EcT& y) { EcT z; add(z, x, y); return z; } |
|
2042 | | inline friend EcT operator-(const EcT& x, const EcT& y) { EcT z; sub(z, x, y); return z; } |
2043 | | template<class INT> |
2044 | 88 | inline friend EcT operator*(const EcT& x, const INT& y) { EcT z; mul(z, x, y); return z; }mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > mcl::operator*<mcl::FpT<mcl::bn::local::FrTag, 256ul> >(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::FpT<mcl::bn::local::FrTag, 256ul> const&) Line | Count | Source | 2044 | 68 | inline friend EcT operator*(const EcT& x, const INT& y) { EcT z; mul(z, x, y); return z; } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > mcl::operator*<mcl::FpT<mcl::bn::local::FrTag, 256ul> >(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::FpT<mcl::bn::local::FrTag, 256ul> const&) Line | Count | Source | 2044 | 20 | inline friend EcT operator*(const EcT& x, const INT& y) { EcT z; mul(z, x, y); return z; } |
|
2045 | 91.1k | EcT& operator+=(const EcT& x) { add(*this, *this, x); return *this; }mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::operator+=(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 2045 | 83.5k | EcT& operator+=(const EcT& x) { add(*this, *this, x); return *this; } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::operator+=(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 2045 | 7.60k | EcT& operator+=(const EcT& x) { add(*this, *this, x); return *this; } |
|
2046 | 79.2k | EcT& operator-=(const EcT& x) { sub(*this, *this, x); return *this; }mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::operator-=(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 2046 | 65.2k | EcT& operator-=(const EcT& x) { sub(*this, *this, x); return *this; } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::operator-=(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) Line | Count | Source | 2046 | 14.0k | EcT& operator-=(const EcT& x) { sub(*this, *this, x); return *this; } |
|
2047 | | template<class INT> |
2048 | 0 | EcT& operator*=(const INT& x) { mul(*this, *this, x); return *this; } |
2049 | 25 | EcT operator-() const { EcT x; neg(x, *this); return x; }mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::operator-() const Line | Count | Source | 2049 | 12 | EcT operator-() const { EcT x; neg(x, *this); return x; } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::operator-() const Line | Count | Source | 2049 | 13 | EcT operator-() const { EcT x; neg(x, *this); return x; } |
|
2050 | | bool operator==(const EcT& rhs) const |
2051 | 4.93k | { |
2052 | 4.93k | switch (mode_) { |
2053 | 4.93k | case ec::Jacobi: |
2054 | 4.93k | return ec::isEqualJacobi(*this, rhs); |
2055 | 0 | case ec::Proj: |
2056 | 0 | return ec::isEqualProj(*this, rhs); |
2057 | 0 | case ec::Affine: |
2058 | 0 | default: |
2059 | 0 | return x == rhs.x && y == rhs.y && z == rhs.z; |
2060 | 4.93k | } |
2061 | 4.93k | } mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::operator==(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) const Line | Count | Source | 2051 | 957 | { | 2052 | 957 | switch (mode_) { | 2053 | 957 | case ec::Jacobi: | 2054 | 957 | return ec::isEqualJacobi(*this, rhs); | 2055 | 0 | case ec::Proj: | 2056 | 0 | return ec::isEqualProj(*this, rhs); | 2057 | 0 | case ec::Affine: | 2058 | 0 | default: | 2059 | 0 | return x == rhs.x && y == rhs.y && z == rhs.z; | 2060 | 957 | } | 2061 | 957 | } |
mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::operator==(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&) const Line | Count | Source | 2051 | 3.98k | { | 2052 | 3.98k | switch (mode_) { | 2053 | 3.98k | case ec::Jacobi: | 2054 | 3.98k | return ec::isEqualJacobi(*this, rhs); | 2055 | 0 | case ec::Proj: | 2056 | 0 | return ec::isEqualProj(*this, rhs); | 2057 | 0 | case ec::Affine: | 2058 | 0 | default: | 2059 | 0 | return x == rhs.x && y == rhs.y && z == rhs.z; | 2060 | 3.98k | } | 2061 | 3.98k | } |
|
2062 | | // return (==rhs) ? 1 : (==-rhs) ? -1 : 0 |
2063 | | int isEqualOrMinus(const EcT& rhs) const |
2064 | | { |
2065 | | switch (mode_) { |
2066 | | case ec::Jacobi: |
2067 | | return ec::isEqualOrMinusJacobi(*this, rhs); |
2068 | | case ec::Proj: |
2069 | | return ec::isEqualOrMinusProj(*this, rhs); |
2070 | | case ec::Affine: |
2071 | | default: |
2072 | | if (x == rhs.x && z == rhs.z) { |
2073 | | if (y == rhs.y) return 1; |
2074 | | if (y == -rhs.y) return -1; |
2075 | | } |
2076 | | return 0; |
2077 | | } |
2078 | | } |
2079 | | bool operator!=(const EcT& rhs) const { return !operator==(rhs); } |
2080 | | bool operator<(const EcT& rhs) const |
2081 | | { |
2082 | | return compare(*this, rhs) < 0; |
2083 | | } |
2084 | | bool operator>=(const EcT& rhs) const { return !operator<(rhs); } |
2085 | | bool operator>(const EcT& rhs) const { return rhs < *this; } |
2086 | | bool operator<=(const EcT& rhs) const { return !operator>(rhs); } |
2087 | | static inline void mulArrayCT(EcT& z, const EcT& x, const Unit *y, size_t yn, bool isNegative) |
2088 | 0 | { |
2089 | 0 | const int w = 4; // don't change |
2090 | 0 | const size_t tblSize = 1u << w; |
2091 | 0 | const size_t mask = tblSize - 1; |
2092 | 0 | const size_t m = sizeof(Unit) * 8 / w; |
2093 | 0 | EcT tbl[tblSize]; |
2094 | 0 | tbl[0].clear(); |
2095 | 0 | tbl[1] = x; |
2096 | 0 | for (size_t i = 2; i < tblSize; i++) { |
2097 | 0 | add(tbl[i], tbl[i - 1], x); |
2098 | 0 | } |
2099 | 0 | z.clear(); |
2100 | 0 | for (size_t i = 0; i < yn; i++) { |
2101 | 0 | Unit v = y[yn - 1 - i]; |
2102 | 0 | for (size_t j = 0; j < m; j++) { |
2103 | 0 | for (size_t k = 0; k < w; k++) { |
2104 | 0 | EcT::dbl(z, z); |
2105 | 0 | } |
2106 | 0 | z += tbl[(v >> ((m - 1 - j) * w)) & mask]; |
2107 | 0 | } |
2108 | 0 | } |
2109 | 0 | if (isNegative) { |
2110 | 0 | EcT::neg(z, z); |
2111 | 0 | } |
2112 | 0 | } Unexecuted instantiation: mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::mulArrayCT(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, unsigned long const*, unsigned long, bool) Unexecuted instantiation: mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::mulArrayCT(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, unsigned long const*, unsigned long, bool) |
2113 | | |
2114 | | static inline void mulArray(EcT& z, const EcT& x, const Unit *y, size_t yn, bool isNegative = false, bool constTime = false) |
2115 | 6.63k | { |
2116 | 6.63k | if (constTime) { |
2117 | 0 | mulArrayCT(z, x, y, yn, isNegative); |
2118 | 0 | return; |
2119 | 0 | } |
2120 | 6.63k | if (yn == 0) { |
2121 | 0 | z.clear(); |
2122 | 0 | return; |
2123 | 0 | } |
2124 | 6.63k | yn = bint::getRealSize(y, yn); |
2125 | 6.63k | if (yn <= 1 && mcl::ec::mulSmallInt(z, x, *y, isNegative)) return; |
2126 | 6.63k | mpz_class v; |
2127 | 6.63k | bool b; |
2128 | 6.63k | gmp::setArray(&b, v, y, yn); |
2129 | 6.63k | assert(b); (void)b; |
2130 | 6.63k | if (isNegative) v = -v; |
2131 | 6.63k | const int maxW = 5; |
2132 | 6.63k | const int maxTblSize = 1 << (maxW - 2); |
2133 | | /* |
2134 | | L = log2(y), w = (L <= 32) ? 3 : (L <= 128) ? 4 : 5; |
2135 | | */ |
2136 | 6.63k | const int w = (yn == 1 && *y <= (1ull << 32)) ? 3 : (yn * sizeof(Unit) > 16) ? 5 : 4; |
2137 | 6.63k | const size_t tblSize = size_t(1) << (w - 2); |
2138 | 6.63k | typedef mcl::FixedArray<int8_t, sizeof(EcT::Fp) * 8 + 1> NafArray; |
2139 | 6.63k | NafArray naf; |
2140 | 6.63k | EcT tbl[maxTblSize]; |
2141 | 6.63k | gmp::getNAFwidth(&b, naf, v, w); |
2142 | 6.63k | assert(b); (void)b; |
2143 | 6.63k | EcT P2; |
2144 | 6.63k | dbl(P2, x); |
2145 | 6.63k | tbl[0] = x; |
2146 | 26.5k | for (size_t i = 1; i < tblSize; i++) { |
2147 | 19.9k | add(tbl[i], tbl[i - 1], P2); |
2148 | 19.9k | } |
2149 | 6.63k | z.clear(); |
2150 | 676k | for (size_t i = 0; i < naf.size(); i++) { |
2151 | 669k | EcT::dbl(z, z); |
2152 | 669k | ec::local::addTbl(z, tbl, naf, naf.size() - 1 - i); |
2153 | 669k | } |
2154 | 6.63k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::mulArray(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, unsigned long const*, unsigned long, bool, bool) Line | Count | Source | 2115 | 4.30k | { | 2116 | 4.30k | if (constTime) { | 2117 | 0 | mulArrayCT(z, x, y, yn, isNegative); | 2118 | 0 | return; | 2119 | 0 | } | 2120 | 4.30k | if (yn == 0) { | 2121 | 0 | z.clear(); | 2122 | 0 | return; | 2123 | 0 | } | 2124 | 4.30k | yn = bint::getRealSize(y, yn); | 2125 | 4.30k | if (yn <= 1 && mcl::ec::mulSmallInt(z, x, *y, isNegative)) return; | 2126 | 4.30k | mpz_class v; | 2127 | 4.30k | bool b; | 2128 | 4.30k | gmp::setArray(&b, v, y, yn); | 2129 | 4.30k | assert(b); (void)b; | 2130 | 4.30k | if (isNegative) v = -v; | 2131 | 4.30k | const int maxW = 5; | 2132 | 4.30k | const int maxTblSize = 1 << (maxW - 2); | 2133 | | /* | 2134 | | L = log2(y), w = (L <= 32) ? 3 : (L <= 128) ? 4 : 5; | 2135 | | */ | 2136 | 4.30k | const int w = (yn == 1 && *y <= (1ull << 32)) ? 3 : (yn * sizeof(Unit) > 16) ? 5 : 4; | 2137 | 4.30k | const size_t tblSize = size_t(1) << (w - 2); | 2138 | 4.30k | typedef mcl::FixedArray<int8_t, sizeof(EcT::Fp) * 8 + 1> NafArray; | 2139 | 4.30k | NafArray naf; | 2140 | 4.30k | EcT tbl[maxTblSize]; | 2141 | 4.30k | gmp::getNAFwidth(&b, naf, v, w); | 2142 | 4.30k | assert(b); (void)b; | 2143 | 4.30k | EcT P2; | 2144 | 4.30k | dbl(P2, x); | 2145 | 4.30k | tbl[0] = x; | 2146 | 17.2k | for (size_t i = 1; i < tblSize; i++) { | 2147 | 12.9k | add(tbl[i], tbl[i - 1], P2); | 2148 | 12.9k | } | 2149 | 4.30k | z.clear(); | 2150 | 529k | for (size_t i = 0; i < naf.size(); i++) { | 2151 | 525k | EcT::dbl(z, z); | 2152 | 525k | ec::local::addTbl(z, tbl, naf, naf.size() - 1 - i); | 2153 | 525k | } | 2154 | 4.30k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::mulArray(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, unsigned long const*, unsigned long, bool, bool) Line | Count | Source | 2115 | 2.33k | { | 2116 | 2.33k | if (constTime) { | 2117 | 0 | mulArrayCT(z, x, y, yn, isNegative); | 2118 | 0 | return; | 2119 | 0 | } | 2120 | 2.33k | if (yn == 0) { | 2121 | 0 | z.clear(); | 2122 | 0 | return; | 2123 | 0 | } | 2124 | 2.33k | yn = bint::getRealSize(y, yn); | 2125 | 2.33k | if (yn <= 1 && mcl::ec::mulSmallInt(z, x, *y, isNegative)) return; | 2126 | 2.33k | mpz_class v; | 2127 | 2.33k | bool b; | 2128 | 2.33k | gmp::setArray(&b, v, y, yn); | 2129 | 2.33k | assert(b); (void)b; | 2130 | 2.33k | if (isNegative) v = -v; | 2131 | 2.33k | const int maxW = 5; | 2132 | 2.33k | const int maxTblSize = 1 << (maxW - 2); | 2133 | | /* | 2134 | | L = log2(y), w = (L <= 32) ? 3 : (L <= 128) ? 4 : 5; | 2135 | | */ | 2136 | 2.33k | const int w = (yn == 1 && *y <= (1ull << 32)) ? 3 : (yn * sizeof(Unit) > 16) ? 5 : 4; | 2137 | 2.33k | const size_t tblSize = size_t(1) << (w - 2); | 2138 | 2.33k | typedef mcl::FixedArray<int8_t, sizeof(EcT::Fp) * 8 + 1> NafArray; | 2139 | 2.33k | NafArray naf; | 2140 | 2.33k | EcT tbl[maxTblSize]; | 2141 | 2.33k | gmp::getNAFwidth(&b, naf, v, w); | 2142 | 2.33k | assert(b); (void)b; | 2143 | 2.33k | EcT P2; | 2144 | 2.33k | dbl(P2, x); | 2145 | 2.33k | tbl[0] = x; | 2146 | 9.32k | for (size_t i = 1; i < tblSize; i++) { | 2147 | 6.99k | add(tbl[i], tbl[i - 1], P2); | 2148 | 6.99k | } | 2149 | 2.33k | z.clear(); | 2150 | 146k | for (size_t i = 0; i < naf.size(); i++) { | 2151 | 144k | EcT::dbl(z, z); | 2152 | 144k | ec::local::addTbl(z, tbl, naf, naf.size() - 1 - i); | 2153 | 144k | } | 2154 | 2.33k | } |
|
2155 | | static inline bool mulSmallInt(EcT& z, const EcT& x, Unit y, bool isNegative) |
2156 | | { |
2157 | | return mcl::ec::mulSmallInt(z, x, y, isNegative); |
2158 | | } |
2159 | | /* |
2160 | | generic mul |
2161 | | GLV can't be applied in Fp12 - GT |
2162 | | */ |
2163 | | static inline void mulGeneric(EcT& z, const EcT& x, const mpz_class& y) |
2164 | 6.63k | { |
2165 | 6.63k | mulArray(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0); |
2166 | 6.63k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::mulGeneric(mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::Vint const&) Line | Count | Source | 2164 | 4.30k | { | 2165 | 4.30k | mulArray(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0); | 2166 | 4.30k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::mulGeneric(mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >&, mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> > const&, mcl::Vint const&) Line | Count | Source | 2164 | 2.33k | { | 2165 | 2.33k | mulArray(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0); | 2166 | 2.33k | } |
|
2167 | | /* |
2168 | | z = sum_{i=0}^{n-1} xVec[i] * yVec[i] |
2169 | | return min(N, n) |
2170 | | @note &z != xVec[i] |
2171 | | */ |
2172 | | private: |
2173 | | static inline size_t mulVecN(EcT& z, const EcT *xVec, const EcT::Fr *yVec, size_t n) |
2174 | | { |
2175 | | const size_t N = mcl::fp::maxMulVecN; |
2176 | | if (n > N) n = N; |
2177 | | const int w = 5; |
2178 | | const size_t tblSize = 1 << (w - 2); |
2179 | | typedef mcl::FixedArray<int8_t, sizeof(EcT::Fp) * 8 + 1> NafArray; |
2180 | | NafArray naf[N]; |
2181 | | EcT tbl[N][tblSize]; |
2182 | | size_t maxBit = 0; |
2183 | | mpz_class y; |
2184 | | for (size_t i = 0; i < n; i++) { |
2185 | | bool b; |
2186 | | yVec[i].getMpz(&b, y); |
2187 | | assert(b); (void)b; |
2188 | | gmp::getNAFwidth(&b, naf[i], y, w); |
2189 | | assert(b); (void)b; |
2190 | | if (naf[i].size() > maxBit) maxBit = naf[i].size(); |
2191 | | EcT P2; |
2192 | | EcT::dbl(P2, xVec[i]); |
2193 | | tbl[i][0] = xVec[i]; |
2194 | | for (size_t j = 1; j < tblSize; j++) { |
2195 | | EcT::add(tbl[i][j], tbl[i][j - 1], P2); |
2196 | | } |
2197 | | } |
2198 | | z.clear(); |
2199 | | EcT::normalizeVec(&tbl[0][0], &tbl[0][0], n * tblSize); |
2200 | | for (size_t i = 0; i < maxBit; i++) { |
2201 | | EcT::dbl(z, z); |
2202 | | for (size_t j = 0; j < n; j++) { |
2203 | | ec::local::addTbl(z, tbl[j], naf[j], maxBit - 1 - i); |
2204 | | } |
2205 | | } |
2206 | | return n; |
2207 | | } |
2208 | | |
2209 | | public: |
2210 | | /* |
2211 | | estimation for n multVec |
2212 | | GLV method x n-times |
2213 | | L : bitsize (=256 for Fr) |
2214 | | w : withdow size (=5 for L=256) |
2215 | | S : splitSize (=2 for G1, =4 for G2) |
2216 | | #DBL = L/S, #ADD = ((2^(w-2) + (L/(Sw)S)) * n |
2217 | | mulVecLong |
2218 | | c = 5 (for n <= 256), c = 6 for n = 512 |
2219 | | #DBL = L, #ADD = (n + 2^(c+1)-1)*(L/c) |
2220 | | |
2221 | | #ADD |
2222 | | n = 128, 256, 512 |
2223 | | GLV : 7680, 15360, 30720 |
2224 | | Long: 9779, 16322, 24533 |
2225 | | */ |
2226 | | static inline void mulVec(EcT& z, EcT *xVec, const EcT::Fr *yVec, size_t n, size_t b = 0) |
2227 | | { |
2228 | | if (n == 0) { |
2229 | | z.clear(); |
2230 | | return; |
2231 | | } |
2232 | | if (mulVecOpti && n >= 128) { |
2233 | | mulVecOpti((Unit*)&z, (Unit*)xVec, yVec[0].getUnit(), n, b); |
2234 | | return; |
2235 | | } |
2236 | | if (mulVecGLV && mulVecGLV(z, xVec, yVec, n, false, b)) { |
2237 | | return; |
2238 | | } |
2239 | | EcT r; |
2240 | | r.clear(); |
2241 | | while (n > 0) { |
2242 | | EcT t; |
2243 | | size_t done = mulVecN(t, xVec, yVec, n); |
2244 | | r += t; |
2245 | | xVec += done; |
2246 | | yVec += done; |
2247 | | n -= done; |
2248 | | } |
2249 | | z = r; |
2250 | | } |
2251 | | // multi thread version of mulVec |
2252 | | // the num of thread is automatically detected if cpuN = 0 |
2253 | | static inline void mulVecMT(EcT& z, EcT *xVec, const EcT::Fr *yVec, size_t n, size_t cpuN = 0) |
2254 | | { |
2255 | | #ifdef MCL_USE_OMP |
2256 | | const size_t minN = mcl::fp::maxMulVecN; |
2257 | | if (cpuN == 0) { |
2258 | | cpuN = omp_get_num_procs(); |
2259 | | if (n < minN * cpuN) { |
2260 | | cpuN = (n + minN - 1) / minN; |
2261 | | } |
2262 | | } |
2263 | | if (cpuN <= 1 || n <= cpuN) { |
2264 | | mulVec(z, xVec, yVec, n); |
2265 | | return; |
2266 | | } |
2267 | | EcT *zs = (EcT*)CYBOZU_ALLOCA(sizeof(EcT) * cpuN); |
2268 | | size_t q = n / cpuN; |
2269 | | size_t r = n % cpuN; |
2270 | | #pragma omp parallel for |
2271 | | for (size_t i = 0; i < cpuN; i++) { |
2272 | | size_t adj = q * i + fp::min_(i, r); |
2273 | | mulVec(zs[i], xVec + adj, yVec + adj, q + (i < r)); |
2274 | | } |
2275 | | z.clear(); |
2276 | | // #pragma omp declare reduction(red:EcT:omp_out *= omp_in) initializer(omp_priv = omp_orig) |
2277 | | // #pragma omp parallel for reduction(red:z) |
2278 | | for (size_t i = 0; i < cpuN; i++) { |
2279 | | z += zs[i]; |
2280 | | } |
2281 | | #else |
2282 | | (void)cpuN; |
2283 | | mulVec(z, xVec, yVec, n); |
2284 | | #endif |
2285 | | } |
2286 | | // xVec[i] *= yVec[i] |
2287 | | static void mulEach(EcT *xVec, const EcT::Fr *yVec, size_t n) |
2288 | | { |
2289 | | if (mulEachOpti && n >= 16) { |
2290 | | size_t n16 = n & ~size_t(16-1); |
2291 | | mulEachOpti((Unit*)xVec, yVec[0].getUnit(), n16); |
2292 | | xVec += n16; |
2293 | | yVec += n16; |
2294 | | n -= n16; |
2295 | | } |
2296 | | for (size_t i = 0; i < n; i++) { |
2297 | | xVec[i] *= yVec[i]; |
2298 | | } |
2299 | | } |
2300 | | #ifndef CYBOZU_DONT_USE_EXCEPTION |
2301 | | static inline void init(const std::string& astr, const std::string& bstr, int mode = ec::Jacobi) |
2302 | | { |
2303 | | bool b; |
2304 | | init(&b, astr.c_str(), bstr.c_str(), mode); |
2305 | | if (!b) throw cybozu::Exception("mcl:EcT:init"); |
2306 | | } |
2307 | | void set(const Fp& _x, const Fp& _y, bool verify = true) |
2308 | 27.7k | { |
2309 | 27.7k | bool b; |
2310 | 27.7k | set(&b, _x, _y, verify); |
2311 | 27.7k | if (!b) throw cybozu::Exception("ec:EcT:set") << _x << _y; |
2312 | 27.7k | } mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::set(mcl::FpT<mcl::bn::local::FpTag, 384ul> const&, mcl::FpT<mcl::bn::local::FpTag, 384ul> const&, bool) Line | Count | Source | 2308 | 13.2k | { | 2309 | 13.2k | bool b; | 2310 | 13.2k | set(&b, _x, _y, verify); | 2311 | 13.2k | if (!b) throw cybozu::Exception("ec:EcT:set") << _x << _y; | 2312 | 13.2k | } |
mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::set(mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&, bool) Line | Count | Source | 2308 | 14.4k | { | 2309 | 14.4k | bool b; | 2310 | 14.4k | set(&b, _x, _y, verify); | 2311 | 14.4k | if (!b) throw cybozu::Exception("ec:EcT:set") << _x << _y; | 2312 | 14.4k | } |
|
2313 | | template<class OutputStream> |
2314 | | void save(OutputStream& os, int ioMode = IoSerialize) const |
2315 | 5.12k | { |
2316 | 5.12k | bool b; |
2317 | 5.12k | save(&b, os, ioMode); |
2318 | 5.12k | if (!b) throw cybozu::Exception("EcT:save"); |
2319 | 5.12k | } void mcl::EcT<mcl::FpT<mcl::bn::local::FpTag, 384ul>, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::save<cybozu::StringOutputStream>(cybozu::StringOutputStream&, int) const Line | Count | Source | 2315 | 3.77k | { | 2316 | 3.77k | bool b; | 2317 | 3.77k | save(&b, os, ioMode); | 2318 | 3.77k | if (!b) throw cybozu::Exception("EcT:save"); | 2319 | 3.77k | } |
void mcl::EcT<mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> >, mcl::FpT<mcl::bn::local::FrTag, 256ul> >::save<cybozu::StringOutputStream>(cybozu::StringOutputStream&, int) const Line | Count | Source | 2315 | 1.35k | { | 2316 | 1.35k | bool b; | 2317 | 1.35k | save(&b, os, ioMode); | 2318 | 1.35k | if (!b) throw cybozu::Exception("EcT:save"); | 2319 | 1.35k | } |
|
2320 | | template<class InputStream> |
2321 | | void load(InputStream& is, int ioMode = IoSerialize) |
2322 | | { |
2323 | | bool b; |
2324 | | load(&b, is, ioMode); |
2325 | | if (!b) throw cybozu::Exception("EcT:load"); |
2326 | | } |
2327 | | #endif |
2328 | | #ifndef CYBOZU_DONT_USE_STRING |
2329 | | // backward compatilibity |
2330 | | static inline void setParam(const std::string& astr, const std::string& bstr, int mode = ec::Jacobi) |
2331 | | { |
2332 | | init(astr, bstr, mode); |
2333 | | } |
2334 | | friend inline std::istream& operator>>(std::istream& is, EcT& self) |
2335 | | { |
2336 | | self.load(is, fp::detectIoMode(getIoMode(), is)); |
2337 | | return is; |
2338 | | } |
2339 | | friend inline std::ostream& operator<<(std::ostream& os, const EcT& self) |
2340 | | { |
2341 | | self.save(os, fp::detectIoMode(getIoMode(), os)); |
2342 | | return os; |
2343 | | } |
2344 | | #endif |
2345 | | }; |
2346 | | |
2347 | | template<class Fp, class Fr> Fp EcT<Fp, Fr>::a_; |
2348 | | template<class Fp, class Fr> Fp EcT<Fp, Fr>::b_; |
2349 | | template<class Fp, class Fr> Fp EcT<Fp, Fr>::b3_; |
2350 | | template<class Fp, class Fr> int EcT<Fp, Fr>::specialA_; |
2351 | | template<class Fp, class Fr> int EcT<Fp, Fr>::specialB_; |
2352 | | template<class Fp, class Fr> int EcT<Fp, Fr>::ioMode_; |
2353 | | template<class Fp, class Fr> bool EcT<Fp, Fr>::verifyOrder_; |
2354 | | template<class Fp, class Fr> mpz_class EcT<Fp, Fr>::order_; |
2355 | | template<class Fp, class Fr> bool (*EcT<Fp, Fr>::mulVecGLV)(EcT& z, const EcT *xVec, const void *yVec, size_t n, bool constTime, size_t b); |
2356 | | template<class Fp, class Fr> void (*EcT<Fp, Fr>::mulVecOpti)(Unit *z, Unit *xVec, const Unit *yVec, size_t n, size_t b); |
2357 | | template<class Fp, class Fr> bool (*EcT<Fp, Fr>::isValidOrderFast)(const EcT& x); |
2358 | | template<class Fp, class Fr> int EcT<Fp, Fr>::mode_; |
2359 | | template<class Fp, class Fr> void (*EcT<Fp, Fr>::mulEachOpti)(Unit *xVec, const Unit *yVec, size_t n); |
2360 | | |
2361 | | // r = the order of Ec |
2362 | | template<class Ec, class _Fr> |
2363 | | struct GLV1T { |
2364 | | typedef GLV1T<Ec, _Fr> GLV1; |
2365 | | typedef typename Ec::Fp Fp; |
2366 | | typedef _Fr Fr; |
2367 | | static const int splitN = 2; |
2368 | | static Fp rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 |
2369 | | static size_t rBitSize; |
2370 | | static mpz_class v0, v1; |
2371 | | static mpz_class B[2][2]; |
2372 | | static void (*optimizedSplit)(mpz_class u[2], const mpz_class& x); |
2373 | | public: |
2374 | | #ifndef CYBOZU_DONT_USE_STRING |
2375 | | static void dump(const mpz_class& x) |
2376 | | { |
2377 | | printf("\"%s\",\n", mcl::gmp::getStr(x, 16).c_str()); |
2378 | | } |
2379 | | static void dump() |
2380 | | { |
2381 | | printf("\"%s\",\n", rw.getStr(16).c_str()); |
2382 | | printf("%d,\n", (int)rBitSize); |
2383 | | dump(v0); |
2384 | | dump(v1); |
2385 | | dump(B[0][0]); dump(B[0][1]); dump(B[1][0]); dump(B[1][1]); |
2386 | | } |
2387 | | #endif |
2388 | | /* |
2389 | | L (x, y) = (rw x, y) |
2390 | | */ |
2391 | | static void mulLambda(Ec& Q, const Ec& P) |
2392 | 25.6k | { |
2393 | 25.6k | Fp::mul(Q.x, P.x, rw); |
2394 | 25.6k | Q.y = P.y; |
2395 | 25.6k | Q.z = P.z; |
2396 | 25.6k | } |
2397 | | /* |
2398 | | x = u[0] + u[1] * lambda mod r |
2399 | | */ |
2400 | | static void split(mpz_class u[2], mpz_class& x) |
2401 | 3.21k | { |
2402 | 3.21k | Fr::getOp().modp.modp(x, x); |
2403 | 3.21k | if (optimizedSplit) { |
2404 | 3.21k | optimizedSplit(u, x); |
2405 | 3.21k | return; |
2406 | 3.21k | } |
2407 | 0 | mpz_class& a = u[0]; |
2408 | 0 | mpz_class& b = u[1]; |
2409 | 0 | mpz_class t; |
2410 | 0 | t = (x * v0) >> rBitSize; |
2411 | 0 | b = (x * v1) >> rBitSize; |
2412 | 0 | a = x - (t * B[0][0] + b * B[1][0]); |
2413 | 0 | b = - (t * B[0][1] + b * B[1][1]); |
2414 | 0 | } |
2415 | | /* |
2416 | | init() is defined in bn.hpp |
2417 | | */ |
2418 | | static void initForSecp256k1() |
2419 | 0 | { |
2420 | 0 | bool b = Fp::squareRoot(rw, -3); |
2421 | 0 | assert(b); |
2422 | 0 | (void)b; |
2423 | 0 | rw = -(rw + 1) / 2; |
2424 | 0 | rBitSize = Fr::getOp().bitSize; |
2425 | 0 | rBitSize = (rBitSize + UnitBitSize - 1) & ~(UnitBitSize - 1); |
2426 | 0 | gmp::setStr(&b, B[0][0], "0x3086d221a7d46bcde86c90e49284eb15"); |
2427 | 0 | assert(b); (void)b; |
2428 | 0 | gmp::setStr(&b, B[0][1], "-0xe4437ed6010e88286f547fa90abfe4c3"); |
2429 | 0 | assert(b); (void)b; |
2430 | 0 | gmp::setStr(&b, B[1][0], "0x114ca50f7a8e2f3f657c1108d9d44cfd8"); |
2431 | 0 | assert(b); (void)b; |
2432 | 0 | B[1][1] = B[0][0]; |
2433 | 0 | const mpz_class& r = Fr::getOp().mp; |
2434 | 0 | v0 = ((B[1][1]) << rBitSize) / r; |
2435 | 0 | v1 = ((-B[0][1]) << rBitSize) / r; |
2436 | 0 | optimizedSplit = 0; |
2437 | 0 | } |
2438 | | }; |
2439 | | |
2440 | | // rw = 1 / w = (-1 - sqrt(-3)) / 2 |
2441 | | template<class Ec, class Fr> typename Ec::Fp GLV1T<Ec, Fr>::rw; |
2442 | | template<class Ec, class Fr> size_t GLV1T<Ec, Fr>::rBitSize; |
2443 | | template<class Ec, class Fr> mpz_class GLV1T<Ec, Fr>::v0; |
2444 | | template<class Ec, class Fr> mpz_class GLV1T<Ec, Fr>::v1; |
2445 | | template<class Ec, class Fr> mpz_class GLV1T<Ec, Fr>::B[2][2]; |
2446 | | template<class Ec, class Fr> void (*GLV1T<Ec, Fr>::optimizedSplit)(mpz_class u[2], const mpz_class& x); |
2447 | | |
2448 | | /* |
2449 | | Ec : elliptic curve |
2450 | | Zn : cyclic group of the order |Ec| |
2451 | | set P the generator of Ec if P != 0 |
2452 | | */ |
2453 | | template<class Ec> |
2454 | | void initCurve(bool *pb, int curveType, Ec *P = 0, mcl::fp::Mode mode = fp::FP_AUTO, mcl::ec::Mode ecMode = ec::Jacobi) |
2455 | 0 | { |
2456 | 0 | typedef typename Ec::Fp Fp; |
2457 | 0 | typedef typename Ec::Fr Zn; |
2458 | 0 | *pb = false; |
2459 | 0 | const EcParam *ecParam = getEcParam(curveType); |
2460 | 0 | if (ecParam == 0) return; |
2461 | 0 |
|
2462 | 0 | Zn::init(pb, ecParam->n, mode); |
2463 | 0 | if (!*pb) return; |
2464 | 0 | Fp::init(pb, ecParam->p, mode); |
2465 | 0 | if (!*pb) return; |
2466 | 0 | Ec::init(pb, ecParam->a, ecParam->b, ecMode); |
2467 | 0 | if (!*pb) return; |
2468 | 0 | if (P) { |
2469 | 0 | Fp x, y; |
2470 | 0 | x.setStr(pb, ecParam->gx); |
2471 | 0 | if (!*pb) return; |
2472 | 0 | y.setStr(pb, ecParam->gy); |
2473 | 0 | if (!*pb) return; |
2474 | 0 | P->set(pb, x, y); |
2475 | 0 | if (!*pb) return; |
2476 | 0 | } |
2477 | 0 | if (curveType == MCL_SECP256K1) { |
2478 | 0 | typedef GLV1T<Ec, Zn> GLV1; |
2479 | 0 | GLV1::initForSecp256k1(); |
2480 | 0 | Ec::setMulVecGLV(mcl::ec::mulVecGLVT<GLV1, Ec, Zn>); |
2481 | 0 | } else { |
2482 | 0 | Ec::setMulVecGLV(0); |
2483 | 0 | } |
2484 | 0 | } |
2485 | | |
2486 | | #ifndef CYBOZU_DONT_USE_EXCEPTION |
2487 | | template<class Ec> |
2488 | | void initCurve(int curveType, Ec *P = 0, mcl::fp::Mode mode = fp::FP_AUTO, mcl::ec::Mode ecMode = ec::Jacobi) |
2489 | | { |
2490 | | bool b; |
2491 | | initCurve<Ec>(&b, curveType, P, mode, ecMode); |
2492 | | if (!b) throw cybozu::Exception("mcl:initCurve") << curveType << mode << ecMode; |
2493 | | } |
2494 | | #endif |
2495 | | |
2496 | | } // mcl |
2497 | | |
2498 | | #ifndef CYBOZU_DONT_USE_EXCEPTION |
2499 | | #ifdef CYBOZU_USE_BOOST |
2500 | | namespace mcl { |
2501 | | template<class Fp, class Fr> |
2502 | | size_t hash_value(const mcl::EcT<Fp, Fr>& P_) |
2503 | | { |
2504 | | if (P_.isZero()) return 0; |
2505 | | mcl::EcT<Fp, Fr> P(P_); P.normalize(); |
2506 | | return mcl::hash_value(P.y, mcl::hash_value(P.x)); |
2507 | | } |
2508 | | |
2509 | | } |
2510 | | #else |
2511 | | namespace std { CYBOZU_NAMESPACE_TR1_BEGIN |
2512 | | |
2513 | | template<class Fp, class Fr> |
2514 | | struct hash<mcl::EcT<Fp, Fr> > { |
2515 | | size_t operator()(const mcl::EcT<Fp, Fr>& P_) const |
2516 | | { |
2517 | | if (P_.isZero()) return 0; |
2518 | | mcl::EcT<Fp, Fr> P(P_); P.normalize(); |
2519 | | return hash<Fp>()(P.y, hash<Fp>()(P.x)); |
2520 | | } |
2521 | | }; |
2522 | | |
2523 | | CYBOZU_NAMESPACE_TR1_END } // std |
2524 | | #endif |
2525 | | #endif |
2526 | | |
2527 | | #ifdef _MSC_VER |
2528 | | #pragma warning(pop) |
2529 | | #endif |