github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/mcl/op.hpp (about) 1 #pragma once 2 /** 3 @file 4 @brief definition of Op 5 @author MITSUNARI Shigeo(@herumi) 6 @license modified new BSD license 7 http://opensource.org/licenses/BSD-3-Clause 8 */ 9 #include <mcl/gmp_util.hpp> 10 #include <memory.h> 11 #include <mcl/array.hpp> 12 13 #if defined(__EMSCRIPTEN__) || defined(__wasm__) 14 #define MCL_DONT_USE_XBYAK 15 #define MCL_DONT_USE_OPENSSL 16 #endif 17 #if !defined(MCL_DONT_USE_XBYAK) && (defined(_WIN64) || defined(__x86_64__)) && (MCL_SIZEOF_UNIT == 8) 18 #define MCL_USE_XBYAK 19 #define MCL_XBYAK_DIRECT_CALL 20 #endif 21 22 #define MCL_MAX_HASH_BIT_SIZE 512 23 24 namespace mcl { 25 26 static const int version = 0x095; /* 0xABC = A.BC */ 27 28 /* 29 specifies available string format mode for X::setIoMode() 30 // for Fp, Fp2, Fp6, Fp12 31 default(0) : IoDec 32 printable string(zero terminated, variable size) 33 IoBin(2) | IoDec(10) | IoHex(16) | IoBinPrefix | IoHexPrefix 34 35 byte string(not zero terminated, fixed size) 36 IoArray | IoArrayRaw 37 IoArray = IoSerialize 38 39 // for Ec 40 affine(0) | IoEcCompY | IoComp 41 default : affine 42 43 affine and IoEcCompY are available with ioMode for Fp 44 IoSerialize ignores ioMode for Fp 45 46 IoAuto 47 dec or hex according to ios_base::fmtflags 48 IoBin 49 binary number([01]+) 50 IoDec 51 decimal number 52 IoHex 53 hexadecimal number([0-9a-fA-F]+) 54 IoBinPrefix 55 0b + <binary number> 56 IoHexPrefix 57 0x + <hexadecimal number> 58 IoArray 59 array of Unit(fixed size = Fp::getByteSize()) 60 IoArrayRaw 61 array of Unit(fixed size = Fp::getByteSize()) without Montgomery conversion 62 63 // for Ec::setIoMode() 64 IoEcAffine(default) 65 "0" ; infinity 66 "1 <x> <y>" ; affine coordinate 67 68 IoEcProj 69 "4" <x> <y> <z> ; projective or jacobi coordinate 70 71 IoEcCompY 72 1-bit y prepresentation of elliptic curve 73 "2 <x>" ; compressed for even y 74 "3 <x>" ; compressed for odd y 75 76 IoSerialize 77 if isMSBserialize(): // p is not full bit 78 size = Fp::getByteSize() 79 use MSB of array of x for 1-bit y for prime p where (p % 8 != 0) 80 [0] ; infinity 81 <x> ; for even y 82 <x>|1 ; for odd y ; |1 means set MSB of x 83 else: 84 size = Fp::getByteSize() + 1 85 [0] ; infinity 86 2 <x> ; for even y 87 3 <x> ; for odd y 88 */ 89 enum IoMode { 90 IoAuto = 0, // dec or hex according to ios_base::fmtflags 91 IoBin = 2, // binary number without prefix 92 IoDec = 10, // decimal number without prefix 93 IoHex = 16, // hexadecimal number without prefix 94 IoArray = 32, // array of Unit(fixed size) 95 IoArrayRaw = 64, // raw array of Unit without Montgomery conversion 96 IoPrefix = 128, // append '0b'(bin) or '0x'(hex) 97 IoBinPrefix = IoBin | IoPrefix, 98 IoHexPrefix = IoHex | IoPrefix, 99 IoEcAffine = 0, // affine coordinate 100 IoEcCompY = 256, // 1-bit y representation of elliptic curve 101 IoSerialize = 512, // use MBS for 1-bit y 102 IoFixedSizeByteSeq = IoSerialize, // obsolete 103 IoEcProj = 1024, // projective or jacobi coordinate 104 IoSerializeHexStr = 2048 // printable hex string 105 }; 106 107 namespace fp { 108 109 const size_t UnitBitSize = sizeof(Unit) * 8; 110 111 const size_t maxUnitSize = (MCL_MAX_BIT_SIZE + UnitBitSize - 1) / UnitBitSize; 112 #define MCL_MAX_UNIT_SIZE ((MCL_MAX_BIT_SIZE + MCL_UNIT_BIT_SIZE - 1) / MCL_UNIT_BIT_SIZE) 113 114 struct FpGenerator; 115 struct Op; 116 117 typedef void (*void1u)(Unit*); 118 typedef void (*void2u)(Unit*, const Unit*); 119 typedef void (*void2uI)(Unit*, const Unit*, Unit); 120 typedef void (*void2uIu)(Unit*, const Unit*, Unit, const Unit*); 121 typedef void (*void2uOp)(Unit*, const Unit*, const Op&); 122 typedef void (*void3u)(Unit*, const Unit*, const Unit*); 123 typedef void (*void4u)(Unit*, const Unit*, const Unit*, const Unit*); 124 typedef int (*int2u)(Unit*, const Unit*); 125 126 typedef Unit (*u1uII)(Unit*, Unit, Unit); 127 typedef Unit (*u3u)(Unit*, const Unit*, const Unit*); 128 129 /* 130 disable -Wcast-function-type 131 the number of arguments of some JIT functions is smaller than that of T 132 */ 133 template<class T, class S> 134 T func_ptr_cast(S func) 135 { 136 return reinterpret_cast<T>(reinterpret_cast<void*>(func)); 137 } 138 struct Block { 139 const Unit *p; // pointer to original FpT.v_ 140 size_t n; 141 Unit v_[maxUnitSize]; 142 }; 143 144 enum Mode { 145 FP_AUTO, 146 FP_GMP, 147 FP_GMP_MONT, 148 FP_LLVM, 149 FP_LLVM_MONT, 150 FP_XBYAK 151 }; 152 153 enum PrimeMode { 154 PM_GENERIC = 0, 155 PM_NIST_P192, 156 PM_SECP256K1, 157 PM_NIST_P521 158 }; 159 160 enum MaskMode { 161 NoMask = 0, // throw if greater or equal 162 SmallMask = 1, // 1-bit smaller mask if greater or equal 163 MaskAndMod = 2, // mask and substract if greater or equal 164 Mod = 3 // mod p 165 }; 166 167 struct Op { 168 /* 169 don't change the layout of rp and p 170 asm code assumes &rp + 1 == p 171 */ 172 Unit rp; 173 Unit p[maxUnitSize]; 174 mpz_class mp; 175 uint32_t pmod4; 176 mcl::SquareRoot sq; 177 mcl::Modp modp; 178 Unit half[maxUnitSize]; // (p + 1) / 2 179 Unit oneRep[maxUnitSize]; // 1(=inv R if Montgomery) 180 /* 181 for Montgomery 182 one = 1 183 R = (1 << (N * sizeof(Unit) * 8)) % p 184 R2 = (R * R) % p 185 R3 = RR^3 186 */ 187 Unit one[maxUnitSize]; 188 Unit R2[maxUnitSize]; 189 Unit R3[maxUnitSize]; 190 #ifdef MCL_USE_XBYAK 191 FpGenerator *fg; 192 mcl::Array<Unit> invTbl; 193 #endif 194 void3u fp_addA_; 195 void3u fp_subA_; 196 void2u fp_negA_; 197 void3u fp_mulA_; 198 void2u fp_sqrA_; 199 void3u fp2_addA_; 200 void3u fp2_subA_; 201 void2u fp2_negA_; 202 void3u fp2_mulA_; 203 void2u fp2_sqrA_; 204 void3u fpDbl_addA_; 205 void3u fpDbl_subA_; 206 void3u fpDbl_mulPreA_; 207 void2u fpDbl_sqrPreA_; 208 void2u fpDbl_modA_; 209 void3u fp2Dbl_mulPreA_; 210 void2u fp2Dbl_sqrPreA_; 211 size_t maxN; 212 size_t N; 213 size_t bitSize; 214 bool (*fp_isZero)(const Unit*); 215 void1u fp_clear; 216 void2u fp_copy; 217 void2u fp_shr1; 218 void3u fp_neg; 219 void4u fp_add; 220 void4u fp_sub; 221 void4u fp_mul; 222 void3u fp_sqr; 223 void2uOp fp_invOp; 224 void2uIu fp_mulUnit; // fpN1_mod + fp_mulUnitPre 225 226 void3u fpDbl_mulPre; 227 void2u fpDbl_sqrPre; 228 int2u fp_preInv; 229 void2uI fp_mulUnitPre; // z[N + 1] = x[N] * y 230 void3u fpN1_mod; // y[N] = x[N + 1] % p[N] 231 232 void4u fpDbl_add; 233 void4u fpDbl_sub; 234 void3u fpDbl_mod; 235 236 u3u fp_addPre; // without modulo p 237 u3u fp_subPre; // without modulo p 238 u3u fpDbl_addPre; 239 u3u fpDbl_subPre; 240 /* 241 for Fp2 = F[u] / (u^2 + 1) 242 x = a + bu 243 */ 244 int xi_a; // xi = xi_a + u 245 void4u fp2_mulNF; 246 void2u fp2_inv; 247 void2u fp2_mul_xiA_; 248 uint32_t (*hash)(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize); 249 250 PrimeMode primeMode; 251 bool isFullBit; // true if bitSize % uniSize == 0 252 bool isMont; // true if use Montgomery 253 bool isFastMod; // true if modulo is fast 254 255 Op() 256 { 257 clear(); 258 } 259 ~Op() 260 { 261 #ifdef MCL_USE_XBYAK 262 destroyFpGenerator(fg); 263 #endif 264 } 265 void clear() 266 { 267 rp = 0; 268 memset(p, 0, sizeof(p)); 269 mp = 0; 270 pmod4 = 0; 271 sq.clear(); 272 // fg is not set 273 memset(half, 0, sizeof(half)); 274 memset(oneRep, 0, sizeof(oneRep)); 275 memset(one, 0, sizeof(one)); 276 memset(R2, 0, sizeof(R2)); 277 memset(R3, 0, sizeof(R3)); 278 #ifdef MCL_USE_XBYAK 279 invTbl.clear(); 280 #endif 281 fp_addA_ = 0; 282 fp_subA_ = 0; 283 fp_negA_ = 0; 284 fp_mulA_ = 0; 285 fp_sqrA_ = 0; 286 fp2_addA_ = 0; 287 fp2_subA_ = 0; 288 fp2_negA_ = 0; 289 fp2_mulA_ = 0; 290 fp2_sqrA_ = 0; 291 fpDbl_addA_ = 0; 292 fpDbl_subA_ = 0; 293 fpDbl_mulPreA_ = 0; 294 fpDbl_sqrPreA_ = 0; 295 fpDbl_modA_ = 0; 296 fp2Dbl_mulPreA_ = 0; 297 fp2Dbl_sqrPreA_ = 0; 298 maxN = 0; 299 N = 0; 300 bitSize = 0; 301 fp_isZero = 0; 302 fp_clear = 0; 303 fp_copy = 0; 304 fp_shr1 = 0; 305 fp_neg = 0; 306 fp_add = 0; 307 fp_sub = 0; 308 fp_mul = 0; 309 fp_sqr = 0; 310 fp_invOp = 0; 311 fp_mulUnit = 0; 312 313 fpDbl_mulPre = 0; 314 fpDbl_sqrPre = 0; 315 fp_preInv = 0; 316 fp_mulUnitPre = 0; 317 fpN1_mod = 0; 318 319 fpDbl_add = 0; 320 fpDbl_sub = 0; 321 fpDbl_mod = 0; 322 323 fp_addPre = 0; 324 fp_subPre = 0; 325 fpDbl_addPre = 0; 326 fpDbl_subPre = 0; 327 328 xi_a = 0; 329 fp2_mulNF = 0; 330 fp2_inv = 0; 331 fp2_mul_xiA_ = 0; 332 hash = 0; 333 334 primeMode = PM_GENERIC; 335 isFullBit = false; 336 isMont = false; 337 isFastMod = false; 338 } 339 void fromMont(Unit* y, const Unit *x) const 340 { 341 /* 342 M(x, y) = xyR^-1 343 y = M(x, 1) = xR^-1 344 */ 345 fp_mul(y, x, one, p); 346 } 347 void toMont(Unit* y, const Unit *x) const 348 { 349 /* 350 y = M(x, R2) = xR^2 R^-1 = xR 351 */ 352 fp_mul(y, x, R2, p); 353 } 354 bool init(const mpz_class& p, size_t maxBitSize, int xi_a, Mode mode, size_t mclMaxBitSize = MCL_MAX_BIT_SIZE); 355 #ifdef MCL_USE_XBYAK 356 static FpGenerator* createFpGenerator(); 357 static void destroyFpGenerator(FpGenerator *fg); 358 #endif 359 private: 360 Op(const Op&); 361 void operator=(const Op&); 362 }; 363 364 inline const char* getIoSeparator(int ioMode) 365 { 366 return (ioMode & (IoArray | IoArrayRaw | IoSerialize | IoSerializeHexStr)) ? "" : " "; 367 } 368 369 inline void dump(const char *s, size_t n) 370 { 371 for (size_t i = 0; i < n; i++) { 372 printf("%02x ", (uint8_t)s[i]); 373 } 374 printf("\n"); 375 } 376 377 #ifndef CYBOZU_DONT_USE_STRING 378 int detectIoMode(int ioMode, const std::ios_base& ios); 379 380 inline void dump(const std::string& s) 381 { 382 dump(s.c_str(), s.size()); 383 } 384 #endif 385 386 } } // mcl::fp