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