github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/mcl/util.hpp (about) 1 #pragma once 2 /** 3 @file 4 @brief functions for T[] 5 @author MITSUNARI Shigeo(@herumi) 6 @license modified new BSD license 7 http://opensource.org/licenses/BSD-3-Clause 8 */ 9 #include <cybozu/bit_operation.hpp> 10 11 #ifdef _MSC_VER 12 #pragma warning(push) 13 #pragma warning(disable : 4456) 14 #pragma warning(disable : 4459) 15 #endif 16 17 namespace mcl { namespace fp { 18 19 // some environments do not have utility 20 template<class T> 21 T abs_(T x) { return x < 0 ? -x : x; } 22 23 template<class T> 24 T min_(T x, T y) { return x < y ? x : y; } 25 26 template<class T> 27 T max_(T x, T y) { return x < y ? y : x; } 28 29 template<class T> 30 void swap_(T& x, T& y) 31 { 32 T t; 33 t = x; 34 x = y; 35 y = t; 36 } 37 38 /* 39 get pp such that p * pp = -1 mod M, 40 where p is prime and M = 1 << 64(or 32). 41 @param pLow [in] p mod M 42 */ 43 template<class T> 44 T getMontgomeryCoeff(T pLow) 45 { 46 T ret = 0; 47 T t = 0; 48 T x = 1; 49 for (size_t i = 0; i < sizeof(T) * 8; i++) { 50 if ((t & 1) == 0) { 51 t += pLow; 52 ret += x; 53 } 54 t >>= 1; 55 x <<= 1; 56 } 57 return ret; 58 } 59 60 template<class T> 61 int compareArray(const T* x, const T* y, size_t n) 62 { 63 for (size_t i = n - 1; i != size_t(-1); i--) { 64 T a = x[i]; 65 T b = y[i]; 66 if (a != b) return a < b ? -1 : 1; 67 } 68 return 0; 69 } 70 71 template<class T> 72 bool isLessArray(const T *x, const T* y, size_t n) 73 { 74 for (size_t i = n - 1; i != size_t(-1); i--) { 75 T a = x[i]; 76 T b = y[i]; 77 if (a != b) return a < b; 78 } 79 return false; 80 } 81 82 template<class T> 83 bool isGreaterOrEqualArray(const T *x, const T* y, size_t n) 84 { 85 return !isLessArray(x, y, n); 86 } 87 88 template<class T> 89 bool isLessOrEqualArray(const T *x, const T* y, size_t n) 90 { 91 for (size_t i = n - 1; i != size_t(-1); i--) { 92 T a = x[i]; 93 T b = y[i]; 94 if (a != b) return a < b; 95 } 96 return true; 97 } 98 99 template<class T> 100 bool isGreaterArray(const T *x, const T* y, size_t n) 101 { 102 return !isLessOrEqualArray(x, y, n); 103 } 104 105 template<class T> 106 bool isEqualArray(const T* x, const T* y, size_t n) 107 { 108 for (size_t i = 0; i < n; i++) { 109 if (x[i] != y[i]) return false; 110 } 111 return true; 112 } 113 114 template<class T> 115 bool isZeroArray(const T *x, size_t n) 116 { 117 for (size_t i = 0; i < n; i++) { 118 if (x[i]) return false; 119 } 120 return true; 121 } 122 123 template<class T> 124 void clearArray(T *x, size_t begin, size_t end) 125 { 126 for (size_t i = begin; i < end; i++) x[i] = 0; 127 } 128 129 template<class T> 130 void copyArray(T *y, const T *x, size_t n) 131 { 132 for (size_t i = 0; i < n; i++) y[i] = x[i]; 133 } 134 135 /* 136 x &= (1 << bitSize) - 1 137 */ 138 template<class T> 139 void maskArray(T *x, size_t n, size_t bitSize) 140 { 141 const size_t TbitSize = sizeof(T) * 8; 142 assert(bitSize <= TbitSize * n); 143 const size_t q = bitSize / TbitSize; 144 const size_t r = bitSize % TbitSize; 145 if (r) { 146 x[q] &= (T(1) << r) - 1; 147 clearArray(x, q + 1, n); 148 } else { 149 clearArray(x, q, n); 150 } 151 } 152 153 /* 154 return non zero size of x[] 155 return 1 if x[] == 0 156 */ 157 template<class T> 158 size_t getNonZeroArraySize(const T *x, size_t n) 159 { 160 assert(n > 0); 161 while (n > 0) { 162 if (x[n - 1]) return n; 163 n--; 164 } 165 return 1; 166 } 167 168 /* 169 @param out [inout] : set element of G ; out = x^y[] 170 @param x [in] 171 @param y [in] 172 @param n [in] size of y[] 173 @param limitBit [in] const time version if the value is positive 174 @note &out != x and out = the unit element of G 175 */ 176 template<class G, class Mul, class Sqr, class T> 177 void powGeneric(G& out, const G& x, const T *y, size_t n, const Mul& mul, const Sqr& sqr, void normalize(G&, const G&), size_t limitBit = 0) 178 { 179 assert(&out != &x); 180 G tbl[4]; // tbl = { discard, x, x^2, x^3 } 181 T v; 182 bool constTime = limitBit > 0; 183 int maxBit = 0; 184 int m = 0; 185 while (n > 0) { 186 if (y[n - 1]) break; 187 n--; 188 } 189 if (n == 0) { 190 if (constTime) goto DummyLoop; 191 return; 192 } 193 if (!constTime && n == 1) { 194 switch (y[0]) { 195 case 1: 196 out = x; 197 return; 198 case 2: 199 sqr(out, x); 200 return; 201 case 3: 202 sqr(out, x); 203 mul(out, out, x); 204 return; 205 case 4: 206 sqr(out, x); 207 sqr(out, out); 208 return; 209 } 210 } 211 if (normalize != 0) { 212 normalize(tbl[0], x); 213 } else { 214 tbl[0] = x; 215 } 216 tbl[1] = tbl[0]; 217 sqr(tbl[2], tbl[1]); 218 if (normalize != 0) { normalize(tbl[2], tbl[2]); } 219 mul(tbl[3], tbl[2], x); 220 if (normalize != 0) { normalize(tbl[3], tbl[3]); } 221 v = y[n - 1]; 222 assert(v); 223 m = cybozu::bsr<T>(v); 224 maxBit = int(m + (n - 1) * sizeof(T) * 8); 225 if (m & 1) { 226 m--; 227 T idx = (v >> m) & 3; 228 assert(idx > 0); 229 out = tbl[idx]; 230 } else { 231 out = x; 232 } 233 for (int i = (int)n - 1; i >= 0; i--) { 234 T v = y[i]; 235 for (int j = m - 2; j >= 0; j -= 2) { 236 sqr(out, out); 237 sqr(out, out); 238 T idx = (v >> j) & 3; 239 if (idx == 0) { 240 if (constTime) mul(tbl[0], tbl[0], tbl[1]); 241 } else { 242 mul(out, out, tbl[idx]); 243 } 244 } 245 m = (int)sizeof(T) * 8; 246 } 247 DummyLoop: 248 if (!constTime) return; 249 G D = out; 250 for (size_t i = maxBit + 1; i < limitBit; i += 2) { 251 sqr(D, D); 252 sqr(D, D); 253 mul(D, D, tbl[1]); 254 } 255 } 256 257 /* 258 shortcut of multiplication by Unit 259 */ 260 template<class T, class U> 261 bool mulSmallUnit(T& z, const T& x, U y) 262 { 263 switch (y) { 264 case 0: z.clear(); break; 265 case 1: z = x; break; 266 case 2: T::add(z, x, x); break; 267 case 3: { T t; T::add(t, x, x); T::add(z, t, x); break; } 268 case 4: T::add(z, x, x); T::add(z, z, z); break; 269 case 5: { T t; T::add(t, x, x); T::add(t, t, t); T::add(z, t, x); break; } 270 case 6: { T t; T::add(t, x, x); T::add(t, t, x); T::add(z, t, t); break; } 271 case 7: { T t; T::add(t, x, x); T::add(t, t, t); T::add(t, t, t); T::sub(z, t, x); break; } 272 case 8: T::add(z, x, x); T::add(z, z, z); T::add(z, z, z); break; 273 case 9: { T t; T::add(t, x, x); T::add(t, t, t); T::add(t, t, t); T::add(z, t, x); break; } 274 case 10: { T t; T::add(t, x, x); T::add(t, t, t); T::add(t, t, x); T::add(z, t, t); break; } 275 default: 276 return false; 277 } 278 return true; 279 } 280 281 } } // mcl::fp 282 283 #ifdef _MSC_VER 284 #pragma warning(pop) 285 #endif