github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/mcl/operator.hpp (about) 1 #pragma once 2 /** 3 @file 4 @brief operator class 5 @author MITSUNARI Shigeo(@herumi) 6 @license modified new BSD license 7 http://opensource.org/licenses/BSD-3-Clause 8 */ 9 #include <mcl/op.hpp> 10 #include <mcl/util.hpp> 11 #ifdef _MSC_VER 12 #ifndef MCL_FORCE_INLINE 13 #define MCL_FORCE_INLINE __forceinline 14 #endif 15 #pragma warning(push) 16 #pragma warning(disable : 4714) 17 #else 18 #ifndef MCL_FORCE_INLINE 19 #define MCL_FORCE_INLINE __attribute__((always_inline)) 20 #endif 21 #endif 22 23 namespace mcl { namespace fp { 24 25 template<class T> 26 struct Empty {}; 27 28 /* 29 T must have add, sub, mul, inv, neg 30 */ 31 template<class T, class E = Empty<T> > 32 struct Operator : public E { 33 template<class S> MCL_FORCE_INLINE T& operator+=(const S& rhs) { T::add(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); } 34 template<class S> MCL_FORCE_INLINE T& operator-=(const S& rhs) { T::sub(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); } 35 template<class S> friend MCL_FORCE_INLINE T operator+(const T& a, const S& b) { T c; T::add(c, a, b); return c; } 36 template<class S> friend MCL_FORCE_INLINE T operator-(const T& a, const S& b) { T c; T::sub(c, a, b); return c; } 37 template<class S> MCL_FORCE_INLINE T& operator*=(const S& rhs) { T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); } 38 template<class S> friend MCL_FORCE_INLINE T operator*(const T& a, const S& b) { T c; T::mul(c, a, b); return c; } 39 MCL_FORCE_INLINE T& operator/=(const T& rhs) { T c; T::inv(c, rhs); T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), c); return static_cast<T&>(*this); } 40 static MCL_FORCE_INLINE void div(T& c, const T& a, const T& b) { T t; T::inv(t, b); T::mul(c, a, t); } 41 friend MCL_FORCE_INLINE T operator/(const T& a, const T& b) { T c; T::inv(c, b); c *= a; return c; } 42 MCL_FORCE_INLINE T operator-() const { T c; T::neg(c, static_cast<const T&>(*this)); return c; } 43 template<class tag2, size_t maxBitSize2, template<class _tag, size_t _maxBitSize> class FpT> 44 static void pow(T& z, const T& x, const FpT<tag2, maxBitSize2>& y) 45 { 46 fp::Block b; 47 y.getBlock(b); 48 powArray(z, x, b.p, b.n, false, false); 49 } 50 template<class tag2, size_t maxBitSize2, template<class _tag, size_t _maxBitSize> class FpT> 51 static void powGeneric(T& z, const T& x, const FpT<tag2, maxBitSize2>& y) 52 { 53 fp::Block b; 54 y.getBlock(b); 55 powArrayBase(z, x, b.p, b.n, false, false); 56 } 57 template<class tag2, size_t maxBitSize2, template<class _tag, size_t _maxBitSize> class FpT> 58 static void powCT(T& z, const T& x, const FpT<tag2, maxBitSize2>& y) 59 { 60 fp::Block b; 61 y.getBlock(b); 62 powArray(z, x, b.p, b.n, false, true); 63 } 64 static void pow(T& z, const T& x, int64_t y) 65 { 66 const uint64_t u = fp::abs_(y); 67 #if MCL_SIZEOF_UNIT == 8 68 powArray(z, x, &u, 1, y < 0, false); 69 #else 70 uint32_t ua[2] = { uint32_t(u), uint32_t(u >> 32) }; 71 size_t un = ua[1] ? 2 : 1; 72 powArray(z, x, ua, un, y < 0, false); 73 #endif 74 } 75 static void pow(T& z, const T& x, const mpz_class& y) 76 { 77 powArray(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0, false); 78 } 79 static void powGeneric(T& z, const T& x, const mpz_class& y) 80 { 81 powArrayBase(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0, false); 82 } 83 static void powCT(T& z, const T& x, const mpz_class& y) 84 { 85 powArray(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0, true); 86 } 87 static void setPowArrayGLV(void f(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime)) 88 { 89 powArrayGLV = f; 90 } 91 private: 92 static void (*powArrayGLV)(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime); 93 static void powArray(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime) 94 { 95 if (powArrayGLV && (constTime || yn > 1)) { 96 powArrayGLV(z, x, y, yn, isNegative, constTime); 97 return; 98 } 99 powArrayBase(z, x, y, yn, isNegative, constTime); 100 } 101 static void powArrayBase(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime) 102 { 103 T tmp; 104 const T *px = &x; 105 if (&z == &x) { 106 tmp = x; 107 px = &tmp; 108 } 109 z = 1; 110 fp::powGeneric(z, *px, y, yn, T::mul, T::sqr, (void (*)(T&, const T&))0, constTime ? T::BaseFp::getBitSize() : 0); 111 if (isNegative) { 112 T::inv(z, z); 113 } 114 } 115 }; 116 117 template<class T, class E> 118 void (*Operator<T, E>::powArrayGLV)(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime); 119 120 /* 121 T must have save and load 122 */ 123 template<class T, class E = Empty<T> > 124 struct Serializable : public E { 125 void setStr(bool *pb, const char *str, int ioMode = 0) 126 { 127 size_t len = strlen(str); 128 size_t n = deserialize(str, len, ioMode); 129 *pb = n > 0 && n == len; 130 } 131 // return strlen(buf) if success else 0 132 size_t getStr(char *buf, size_t maxBufSize, int ioMode = 0) const 133 { 134 size_t n = serialize(buf, maxBufSize, ioMode); 135 if (n == 0 || n == maxBufSize - 1) return 0; 136 buf[n] = '\0'; 137 return n; 138 } 139 #ifndef CYBOZU_DONT_USE_STRING 140 void setStr(const std::string& str, int ioMode = 0) 141 { 142 cybozu::StringInputStream is(str); 143 static_cast<T&>(*this).load(is, ioMode); 144 } 145 void getStr(std::string& str, int ioMode = 0) const 146 { 147 str.clear(); 148 cybozu::StringOutputStream os(str); 149 static_cast<const T&>(*this).save(os, ioMode); 150 } 151 std::string getStr(int ioMode = 0) const 152 { 153 std::string str; 154 getStr(str, ioMode); 155 return str; 156 } 157 #endif 158 // return written bytes 159 size_t serialize(void *buf, size_t maxBufSize, int ioMode = IoSerialize) const 160 { 161 cybozu::MemoryOutputStream os(buf, maxBufSize); 162 bool b; 163 static_cast<const T&>(*this).save(&b, os, ioMode); 164 return b ? os.getPos() : 0; 165 } 166 // return read bytes 167 size_t deserialize(const void *buf, size_t bufSize, int ioMode = IoSerialize) 168 { 169 cybozu::MemoryInputStream is(buf, bufSize); 170 bool b; 171 static_cast<T&>(*this).load(&b, is, ioMode); 172 return b ? is.getPos() : 0; 173 } 174 }; 175 176 } } // mcl::fp 177