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