github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/mcl/vint.hpp (about)

     1  #pragma once
     2  /**
     3  	emulate mpz_class
     4  */
     5  #ifndef CYBOZU_DONT_USE_EXCEPTION
     6  #include <cybozu/exception.hpp>
     7  #endif
     8  #include <cybozu/bit_operation.hpp>
     9  #include <cybozu/xorshift.hpp>
    10  #include <assert.h>
    11  #ifndef CYBOZU_DONT_USE_STRING
    12  #include <iostream>
    13  #endif
    14  #include <mcl/array.hpp>
    15  #include <mcl/util.hpp>
    16  #include <mcl/randgen.hpp>
    17  #include <mcl/conversion.hpp>
    18  
    19  #if defined(__EMSCRIPTEN__) || defined(__wasm__)
    20  	#define MCL_VINT_64BIT_PORTABLE
    21  	#define MCL_VINT_FIXED_BUFFER
    22  #endif
    23  #ifndef MCL_MAX_BIT_SIZE
    24  	#error "define MCL_MAX_BIT_SZIE"
    25  #endif
    26  
    27  #ifndef MCL_SIZEOF_UNIT
    28  	#if defined(CYBOZU_OS_BIT) && (CYBOZU_OS_BIT == 32)
    29  		#define MCL_SIZEOF_UNIT 4
    30  	#else
    31  		#define MCL_SIZEOF_UNIT 8
    32  	#endif
    33  #endif
    34  
    35  namespace mcl {
    36  
    37  namespace vint {
    38  
    39  #if MCL_SIZEOF_UNIT == 8
    40  typedef uint64_t Unit;
    41  #else
    42  typedef uint32_t Unit;
    43  #endif
    44  
    45  template<size_t x>
    46  struct RoundUp {
    47  	static const size_t UnitBitSize = sizeof(Unit) * 8;
    48  	static const size_t N = (x + UnitBitSize - 1) / UnitBitSize;
    49  	static const size_t bit = N * UnitBitSize;
    50  };
    51  
    52  template<class T>
    53  void dump(const T *x, size_t n, const char *msg = "")
    54  {
    55  	const size_t is4byteUnit = sizeof(*x) == 4;
    56  	if (msg) printf("%s ", msg);
    57  	for (size_t i = 0; i < n; i++) {
    58  		if (is4byteUnit) {
    59  			printf("%08x", (uint32_t)x[n - 1 - i]);
    60  		} else {
    61  			printf("%016llx", (unsigned long long)x[n - 1 - i]);
    62  		}
    63  	}
    64  	printf("\n");
    65  }
    66  
    67  inline uint64_t make64(uint32_t H, uint32_t L)
    68  {
    69  	return ((uint64_t)H << 32) | L;
    70  }
    71  
    72  inline void split64(uint32_t *H, uint32_t *L, uint64_t x)
    73  {
    74  	*H = uint32_t(x >> 32);
    75  	*L = uint32_t(x);
    76  }
    77  
    78  /*
    79  	[H:L] <= x * y
    80  	@return L
    81  */
    82  inline uint32_t mulUnit(uint32_t *pH, uint32_t x, uint32_t y)
    83  {
    84  	uint64_t t = uint64_t(x) * y;
    85  	uint32_t L;
    86  	split64(pH, &L, t);
    87  	return L;
    88  }
    89  #if MCL_SIZEOF_UNIT == 8
    90  inline uint64_t mulUnit(uint64_t *pH, uint64_t x, uint64_t y)
    91  {
    92  #ifdef MCL_VINT_64BIT_PORTABLE
    93  	uint32_t a = uint32_t(x >> 32);
    94  	uint32_t b = uint32_t(x);
    95  	uint32_t c = uint32_t(y >> 32);
    96  	uint32_t d = uint32_t(y);
    97  
    98  	uint64_t ad = uint64_t(d) * a;
    99  	uint64_t bd = uint64_t(d) * b;
   100  	uint64_t L = uint32_t(bd);
   101  	ad += bd >> 32; // [ad:L]
   102  
   103  	uint64_t ac = uint64_t(c) * a;
   104  	uint64_t bc = uint64_t(c) * b;
   105  	uint64_t H = uint32_t(bc);
   106  	ac += bc >> 32; // [ac:H]
   107  	/*
   108  		  adL
   109  		 acH
   110  	*/
   111  	uint64_t t = (ac << 32) | H;
   112  	ac >>= 32;
   113  	H = t + ad;
   114  	if (H < t) {
   115  		ac++;
   116  	}
   117  	/*
   118  		ac:H:L
   119  	*/
   120  	L |= H << 32;
   121  	H = (ac << 32) | uint32_t(H >> 32);
   122  	*pH = H;
   123  	return L;
   124  #elif defined(_WIN64) && !defined(__INTEL_COMPILER)
   125  	return _umul128(x, y, pH);
   126  #else
   127  	typedef __attribute__((mode(TI))) unsigned int uint128;
   128  	uint128 t = uint128(x) * y;
   129  	*pH = uint64_t(t >> 64);
   130  	return uint64_t(t);
   131  #endif
   132  }
   133  #endif
   134  
   135  template<class T>
   136  void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn);
   137  
   138  /*
   139  	q = [H:L] / y
   140  	r = [H:L] % y
   141  	return q
   142  */
   143  inline uint32_t divUnit(uint32_t *pr, uint32_t H, uint32_t L, uint32_t y)
   144  {
   145  	uint64_t t = make64(H, L);
   146  	uint32_t q = uint32_t(t / y);
   147  	*pr = uint32_t(t % y);
   148  	return q;
   149  }
   150  #if MCL_SIZEOF_UNIT == 8
   151  inline uint64_t divUnit(uint64_t *pr, uint64_t H, uint64_t L, uint64_t y)
   152  {
   153  #if defined(MCL_VINT_64BIT_PORTABLE)
   154  	uint32_t px[4] = { uint32_t(L), uint32_t(L >> 32), uint32_t(H), uint32_t(H >> 32) };
   155  	uint32_t py[2] = { uint32_t(y), uint32_t(y >> 32) };
   156  	size_t xn = 4;
   157  	size_t yn = 2;
   158  	uint32_t q[4];
   159  	uint32_t r[2];
   160  	size_t qn = xn - yn + 1;
   161  	divNM(q, qn, r, px, xn, py, yn);
   162  	*pr = make64(r[1], r[0]);
   163  	return make64(q[1], q[0]);
   164  #elif defined(_MSC_VER)
   165  	#error "divUnit for uint64_t is not supported"
   166  #else
   167  	typedef __attribute__((mode(TI))) unsigned int uint128;
   168  	uint128 t = (uint128(H) << 64) | L;
   169  	uint64_t q = uint64_t(t / y);
   170  	*pr = uint64_t(t % y);
   171  	return q;
   172  #endif
   173  }
   174  #endif
   175  
   176  /*
   177  	compare x[] and y[]
   178  	@retval positive  if x > y
   179  	@retval 0         if x == y
   180  	@retval negative  if x < y
   181  */
   182  template<class T>
   183  int compareNM(const T *x, size_t xn, const T *y, size_t yn)
   184  {
   185  	assert(xn > 0 && yn > 0);
   186  	if (xn != yn) return xn > yn ? 1 : -1;
   187  	for (int i = (int)xn - 1; i >= 0; i--) {
   188  		if (x[i] != y[i]) return x[i] > y[i] ? 1 : -1;
   189  	}
   190  	return 0;
   191  }
   192  
   193  template<class T>
   194  void clearN(T *x, size_t n)
   195  {
   196  	for (size_t i = 0; i < n; i++) x[i] = 0;
   197  }
   198  
   199  template<class T>
   200  void copyN(T *y, const T *x, size_t n)
   201  {
   202  	for (size_t i = 0; i < n; i++) y[i] = x[i];
   203  }
   204  
   205  /*
   206  	z[] = x[n] + y[n]
   207  	@note return 1 if having carry
   208  	z may be equal to x or y
   209  */
   210  template<class T>
   211  T addN(T *z, const T *x, const T *y, size_t n)
   212  {
   213  	T c = 0;
   214  	for (size_t i = 0; i < n; i++) {
   215  		T xc = x[i] + c;
   216  		if (xc < c) {
   217  			// x[i] = Unit(-1) and c = 1
   218  			z[i] = y[i];
   219  		} else {
   220  			xc += y[i];
   221  			c = y[i] > xc ? 1 : 0;
   222  			z[i] = xc;
   223  		}
   224  	}
   225  	return c;
   226  }
   227  
   228  /*
   229  	z[] = x[] + y
   230  */
   231  template<class T>
   232  T addu1(T *z, const T *x, size_t n, T y)
   233  {
   234  	assert(n > 0);
   235  	T t = x[0] + y;
   236  	z[0] = t;
   237  	size_t i = 0;
   238  	if (t >= y) goto EXIT_0;
   239  	i = 1;
   240  	for (; i < n; i++) {
   241  		t = x[i] + 1;
   242  		z[i] = t;
   243  		if (t != 0) goto EXIT_0;
   244  	}
   245  	return 1;
   246  EXIT_0:
   247  	i++;
   248  	for (; i < n; i++) {
   249  		z[i] = x[i];
   250  	}
   251  	return 0;
   252  }
   253  
   254  /*
   255  	x[] += y
   256  */
   257  template<class T>
   258  T addu1(T *x, size_t n, T y)
   259  {
   260  	assert(n > 0);
   261  	T t = x[0] + y;
   262  	x[0] = t;
   263  	size_t i = 0;
   264  	if (t >= y) return 0;
   265  	i = 1;
   266  	for (; i < n; i++) {
   267  		t = x[i] + 1;
   268  		x[i] = t;
   269  		if (t != 0) return 0;
   270  	}
   271  	return 1;
   272  }
   273  /*
   274  	z[zn] = x[xn] + y[yn]
   275  	@note zn = max(xn, yn)
   276  */
   277  template<class T>
   278  T addNM(T *z, const T *x, size_t xn, const T *y, size_t yn)
   279  {
   280  	if (yn > xn) {
   281  		fp::swap_(xn, yn);
   282  		fp::swap_(x, y);
   283  	}
   284  	assert(xn >= yn);
   285  	size_t max = xn;
   286  	size_t min = yn;
   287  	T c = vint::addN(z, x, y, min);
   288  	if (max > min) {
   289  		c = vint::addu1(z + min, x + min, max - min, c);
   290  	}
   291  	return c;
   292  }
   293  
   294  /*
   295  	z[] = x[n] - y[n]
   296  	z may be equal to x or y
   297  */
   298  template<class T>
   299  T subN(T *z, const T *x, const T *y, size_t n)
   300  {
   301  	assert(n > 0);
   302  	T c = 0;
   303  	for (size_t i = 0; i < n; i++) {
   304  		T yc = y[i] + c;
   305  		if (yc < c) {
   306  			// y[i] = T(-1) and c = 1
   307  			z[i] = x[i];
   308  		} else {
   309  			c = x[i] < yc ? 1 : 0;
   310  			z[i] = x[i] - yc;
   311  		}
   312  	}
   313  	return c;
   314  }
   315  
   316  /*
   317  	out[] = x[n] - y
   318  */
   319  template<class T>
   320  T subu1(T *z, const T *x, size_t n, T y)
   321  {
   322  	assert(n > 0);
   323  #if 0
   324  	T t = x[0];
   325  	z[0] = t - y;
   326  	size_t i = 0;
   327  	if (t >= y) goto EXIT_0;
   328  	i = 1;
   329  	for (; i < n; i++ ){
   330  		t = x[i];
   331  		z[i] = t - 1;
   332  		if (t != 0) goto EXIT_0;
   333  	}
   334  	return 1;
   335  EXIT_0:
   336  	i++;
   337  	for (; i < n; i++) {
   338  		z[i] = x[i];
   339  	}
   340  	return 0;
   341  #else
   342  	T c = x[0] < y ? 1 : 0;
   343  	z[0] = x[0] - y;
   344  	for (size_t i = 1; i < n; i++) {
   345  		if (x[i] < c) {
   346  			z[i] = T(-1);
   347  		} else {
   348  			z[i] = x[i] - c;
   349  			c = 0;
   350  		}
   351  	}
   352  	return c;
   353  #endif
   354  }
   355  
   356  /*
   357  	z[xn] = x[xn] - y[yn]
   358  	@note xn >= yn
   359  */
   360  template<class T>
   361  T subNM(T *z, const T *x, size_t xn, const T *y, size_t yn)
   362  {
   363  	assert(xn >= yn);
   364  	T c = vint::subN(z, x, y, yn);
   365  	if (xn > yn) {
   366  		c = vint::subu1(z + yn, x + yn, xn - yn, c);
   367  	}
   368  	return c;
   369  }
   370  
   371  /*
   372  	z[0..n) = x[0..n) * y
   373  	return z[n]
   374  	@note accept z == x
   375  */
   376  template<class T>
   377  T mulu1(T *z, const T *x, size_t n, T y)
   378  {
   379  	assert(n > 0);
   380  	T H = 0;
   381  	for (size_t i = 0; i < n; i++) {
   382  		T t = H;
   383  		T L = mulUnit(&H, x[i], y);
   384  		z[i] = t + L;
   385  		if (z[i] < t) {
   386  			H++;
   387  		}
   388  	}
   389  	return H; // z[n]
   390  }
   391  
   392  /*
   393  	z[xn * yn] = x[xn] * y[ym]
   394  */
   395  template<class T>
   396  static inline void mulNM(T *z, const T *x, size_t xn, const T *y, size_t yn)
   397  {
   398  	assert(xn > 0 && yn > 0);
   399  	if (yn > xn) {
   400  		fp::swap_(yn, xn);
   401  		fp::swap_(x, y);
   402  	}
   403  	assert(xn >= yn);
   404  	if (z == x) {
   405  		T *p = (T*)CYBOZU_ALLOCA(sizeof(T) * xn);
   406  		copyN(p, x, xn);
   407  		x = p;
   408  	}
   409  	if (z == y) {
   410  		T *p = (T*)CYBOZU_ALLOCA(sizeof(T) * yn);
   411  		copyN(p, y, yn);
   412  		y = p;
   413  	}
   414  	z[xn] = vint::mulu1(&z[0], x, xn, y[0]);
   415  	clearN(z + xn + 1, yn - 1);
   416  
   417  	T *t2 = (T*)CYBOZU_ALLOCA(sizeof(T) * (xn + 1));
   418  	for (size_t i = 1; i < yn; i++) {
   419  		t2[xn] = vint::mulu1(&t2[0], x, xn, y[i]);
   420  		vint::addN(&z[i], &z[i], &t2[0], xn + 1);
   421  	}
   422  }
   423  /*
   424  	out[xn * 2] = x[xn] * x[xn]
   425  	QQQ : optimize this
   426  */
   427  template<class T>
   428  static inline void sqrN(T *y, const T *x, size_t xn)
   429  {
   430  	mulNM(y, x, xn, x, xn);
   431  }
   432  
   433  /*
   434  	q[] = x[] / y
   435  	@retval r = x[] % y
   436  	accept q == x
   437  */
   438  template<class T>
   439  T divu1(T *q, const T *x, size_t n, T y)
   440  {
   441  	T r = 0;
   442  	for (int i = (int)n - 1; i >= 0; i--) {
   443  		q[i] = divUnit(&r, r, x[i], y);
   444  	}
   445  	return r;
   446  }
   447  /*
   448  	q[] = x[] / y
   449  	@retval r = x[] % y
   450  */
   451  template<class T>
   452  T modu1(const T *x, size_t n, T y)
   453  {
   454  	T r = 0;
   455  	for (int i = (int)n - 1; i >= 0; i--) {
   456  		divUnit(&r, r, x[i], y);
   457  	}
   458  	return r;
   459  }
   460  
   461  /*
   462  	y[] = x[] << bit
   463  	0 < bit < sizeof(T) * 8
   464  	accept y == x
   465  */
   466  template<class T>
   467  T shlBit(T *y, const T *x, size_t xn, size_t bit)
   468  {
   469  	assert(0 < bit && bit < sizeof(T) * 8);
   470  	assert(xn > 0);
   471  	size_t rBit = sizeof(T) * 8 - bit;
   472  	T keep = x[xn - 1];
   473  	T prev = keep;
   474  	for (size_t i = xn - 1; i > 0; i--) {
   475  		T t = x[i - 1];
   476  		y[i] = (prev << bit) | (t >> rBit);
   477  		prev = t;
   478  	}
   479  	y[0] = prev << bit;
   480  	return keep >> rBit;
   481  }
   482  
   483  /*
   484  	y[yn] = x[xn] << bit
   485  	yn = xn + (bit + unitBitBit - 1) / unitBitSize
   486  	accept y == x
   487  */
   488  template<class T>
   489  void shlN(T *y, const T *x, size_t xn, size_t bit)
   490  {
   491  	assert(xn > 0);
   492  	const size_t unitBitSize = sizeof(T) * 8;
   493  	size_t q = bit / unitBitSize;
   494  	size_t r = bit % unitBitSize;
   495  	if (r == 0) {
   496  		// don't use copyN(y + q, x, xn); if overlaped
   497  		for (size_t i = 0; i < xn; i++) {
   498  			y[q + xn - 1 - i] = x[xn - 1 - i];
   499  		}
   500  	} else {
   501  		y[q + xn] = shlBit(y + q, x, xn, r);
   502  	}
   503  	clearN(y, q);
   504  }
   505  
   506  /*
   507  	y[] = x[] >> bit
   508  	0 < bit < sizeof(T) * 8
   509  */
   510  template<class T>
   511  void shrBit(T *y, const T *x, size_t xn, size_t bit)
   512  {
   513  	assert(0 < bit && bit < sizeof(T) * 8);
   514  	assert(xn > 0);
   515  	size_t rBit = sizeof(T) * 8 - bit;
   516  	T prev = x[0];
   517  	for (size_t i = 1; i < xn; i++) {
   518  		T t = x[i];
   519  		y[i - 1] = (prev >> bit) | (t << rBit);
   520  		prev = t;
   521  	}
   522  	y[xn - 1] = prev >> bit;
   523  }
   524  /*
   525  	y[yn] = x[xn] >> bit
   526  	yn = xn - bit / unitBit
   527  */
   528  template<class T>
   529  void shrN(T *y, const T *x, size_t xn, size_t bit)
   530  {
   531  	assert(xn > 0);
   532  	const size_t unitBitSize = sizeof(T) * 8;
   533  	size_t q = bit / unitBitSize;
   534  	size_t r = bit % unitBitSize;
   535  	assert(xn >= q);
   536  	if (r == 0) {
   537  		copyN(y, x + q, xn - q);
   538  	} else {
   539  		shrBit(y, x + q, xn - q, r);
   540  	}
   541  }
   542  
   543  template<class T>
   544  size_t getRealSize(const T *x, size_t xn)
   545  {
   546  	int i = (int)xn - 1;
   547  	for (; i > 0; i--) {
   548  		if (x[i]) {
   549  			return i + 1;
   550  		}
   551  	}
   552  	return 1;
   553  }
   554  
   555  template<class T>
   556  size_t getBitSize(const T *x, size_t n)
   557  {
   558  	if (n == 1 && x[0] == 0) return 1;
   559  	T v = x[n - 1];
   560  	assert(v);
   561  	return (n - 1) * sizeof(T) * 8 + 1 + cybozu::bsr<Unit>(v);
   562  }
   563  
   564  /*
   565  	q[qn] = x[xn] / y[yn] ; qn == xn - yn + 1 if xn >= yn if q
   566  	r[rn] = x[xn] % y[yn] ; rn = yn before getRealSize
   567  	allow q == 0
   568  */
   569  template<class T>
   570  void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn)
   571  {
   572  	assert(xn > 0 && yn > 0);
   573  	assert(xn < yn || (q == 0 || qn == xn - yn + 1));
   574  	assert(q != r);
   575  	const size_t rn = yn;
   576  	xn = getRealSize(x, xn);
   577  	yn = getRealSize(y, yn);
   578  	if (x == y) {
   579  		assert(xn == yn);
   580  	x_is_y:
   581  		clearN(r, rn);
   582  		if (q) {
   583  			q[0] = 1;
   584  			clearN(q + 1, qn - 1);
   585  		}
   586  		return;
   587  	}
   588  	if (yn > xn) {
   589  		/*
   590  			if y > x then q = 0 and r = x
   591  		*/
   592  	q_is_zero:
   593  		copyN(r, x, xn);
   594  		clearN(r + xn, rn - xn);
   595  		if (q) clearN(q, qn);
   596  		return;
   597  	}
   598  	if (yn == 1) {
   599  		T t;
   600  		if (q) {
   601  			if (qn > xn) {
   602  				clearN(q + xn, qn - xn);
   603  			}
   604  			t = divu1(q, x, xn, y[0]);
   605  		} else {
   606  			t = modu1(x, xn, y[0]);
   607  		}
   608  		r[0] = t;
   609  		clearN(r + 1, rn - 1);
   610  		return;
   611  	}
   612  	const size_t yTopBit = cybozu::bsr(y[yn - 1]);
   613  	assert(yn >= 2);
   614  	if (xn == yn) {
   615  		const size_t xTopBit = cybozu::bsr(x[xn - 1]);
   616  		if (xTopBit < yTopBit) goto q_is_zero;
   617  		if (yTopBit == xTopBit) {
   618  			int ret = compareNM(x, xn, y, yn);
   619  			if (ret == 0) goto x_is_y;
   620  			if (ret < 0) goto q_is_zero;
   621  			if (r) {
   622  				subN(r, x, y, yn);
   623  			}
   624  			if (q) {
   625  				q[0] = 1;
   626  				clearN(q + 1, qn - 1);
   627  			}
   628  			return;
   629  		}
   630  		assert(xTopBit > yTopBit);
   631  		// fast reduction for larger than fullbit-3 size p
   632  		if (yTopBit >= sizeof(T) * 8 - 4) {
   633  			T *xx = (T*)CYBOZU_ALLOCA(sizeof(T) * xn);
   634  			T qv = 0;
   635  			if (yTopBit == sizeof(T) * 8 - 2) {
   636  				copyN(xx, x, xn);
   637  			} else {
   638  				qv = x[xn - 1] >> (yTopBit + 1);
   639  				mulu1(xx, y, yn, qv);
   640  				subN(xx, x, xx, xn);
   641  				xn = getRealSize(xx, xn);
   642  			}
   643  			for (;;) {
   644  				T ret = subN(xx, xx, y, yn);
   645  				if (ret) {
   646  					addN(xx, xx, y, yn);
   647  					break;
   648  				}
   649  				qv++;
   650  				xn = getRealSize(xx, xn);
   651  			}
   652  			if (r) {
   653  				copyN(r, xx, xn);
   654  				clearN(r + xn, rn - xn);
   655  			}
   656  			if (q) {
   657  				q[0] = qv;
   658  				clearN(q + 1, qn - 1);
   659  			}
   660  			return;
   661  		}
   662  	}
   663  	/*
   664  		bitwise left shift x and y to adjust MSB of y[yn - 1] = 1
   665  	*/
   666  	const size_t shift = sizeof(T) * 8 - 1 - yTopBit;
   667  	T *xx = (T*)CYBOZU_ALLOCA(sizeof(T) * (xn + 1));
   668  	const T *yy;
   669  	if (shift) {
   670  		T v = shlBit(xx, x, xn, shift);
   671  		if (v) {
   672  			xx[xn] = v;
   673  			xn++;
   674  		}
   675  		T *yBuf = (T*)CYBOZU_ALLOCA(sizeof(T) * yn);
   676  		shlBit(yBuf, y, yn ,shift);
   677  		yy = yBuf;
   678  	} else {
   679  		copyN(xx, x, xn);
   680  		yy = y;
   681  	}
   682  	if (q) {
   683  		clearN(q, qn);
   684  	}
   685  	assert((yy[yn - 1] >> (sizeof(T) * 8 - 1)) != 0);
   686  	T *tt = (T*)CYBOZU_ALLOCA(sizeof(T) * (yn + 1));
   687  	while (xn > yn) {
   688  		size_t d = xn - yn;
   689  		T xTop = xx[xn - 1];
   690  		T yTop = yy[yn - 1];
   691  		if (xTop > yTop || (compareNM(xx + d, xn - d, yy, yn) >= 0)) {
   692  			vint::subN(xx + d, xx + d, yy, yn);
   693  			xn = getRealSize(xx, xn);
   694  			if (q) vint::addu1<T>(q + d, qn - d, 1);
   695  			continue;
   696  		}
   697  		if (xTop == 1) {
   698  			vint::subNM(xx + d - 1, xx + d - 1, xn - d + 1, yy, yn);
   699  			xn = getRealSize(xx, xn);
   700  			if (q) vint::addu1<T>(q + d - 1, qn - d + 1, 1);
   701  			continue;
   702  		}
   703  		tt[yn] = vint::mulu1(tt, yy, yn, xTop);
   704  		vint::subN(xx + d - 1, xx + d - 1, tt, yn + 1);
   705  		xn = getRealSize(xx, xn);
   706  		if (q) vint::addu1<T>(q + d - 1, qn - d + 1, xTop);
   707  	}
   708  	if (xn == yn && compareNM(xx, xn, yy, yn) >= 0) {
   709  		subN(xx, xx, yy, yn);
   710  		xn = getRealSize(xx, xn);
   711  		if (q) vint::addu1<T>(q, qn, 1);
   712  	}
   713  	if (shift) {
   714  		shrBit(r, xx, xn, shift);
   715  	} else {
   716  		copyN(r, xx, xn);
   717  	}
   718  	clearN(r + xn, rn - xn);
   719  }
   720  
   721  #ifndef MCL_VINT_FIXED_BUFFER
   722  template<class T>
   723  class Buffer {
   724  	size_t allocSize_;
   725  	T *ptr_;
   726  public:
   727  	typedef T Unit;
   728  	Buffer() : allocSize_(0), ptr_(0) {}
   729  	~Buffer()
   730  	{
   731  		clear();
   732  	}
   733  	Buffer(const Buffer& rhs)
   734  		: allocSize_(rhs.allocSize_)
   735  		, ptr_(0)
   736  	{
   737  		ptr_ = (T*)malloc(allocSize_ * sizeof(T));
   738  		if (ptr_ == 0) throw cybozu::Exception("Buffer:malloc") << rhs.allocSize_;
   739  		memcpy(ptr_, rhs.ptr_, allocSize_ * sizeof(T));
   740  	}
   741  	Buffer& operator=(const Buffer& rhs)
   742  	{
   743  		Buffer t(rhs);
   744  		swap(t);
   745  		return *this;
   746  	}
   747  	void swap(Buffer& rhs)
   748  #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
   749  		noexcept
   750  #endif
   751  	{
   752  		fp::swap_(allocSize_, rhs.allocSize_);
   753  		fp::swap_(ptr_, rhs.ptr_);
   754  	}
   755  	void clear()
   756  	{
   757  		allocSize_ = 0;
   758  		free(ptr_);
   759  		ptr_ = 0;
   760  	}
   761  
   762  	/*
   763  		@note extended buffer may be not cleared
   764  	*/
   765  	void alloc(bool *pb, size_t n)
   766  	{
   767  		if (n > allocSize_) {
   768  			T *p = (T*)malloc(n * sizeof(T));
   769  			if (p == 0) {
   770  				*pb = false;
   771  				return;
   772  			}
   773  			copyN(p, ptr_, allocSize_);
   774  			free(ptr_);
   775  			ptr_ = p;
   776  			allocSize_ = n;
   777  		}
   778  		*pb = true;
   779  	}
   780  #ifndef CYBOZU_DONT_USE_EXCEPTION
   781  	void alloc(size_t n)
   782  	{
   783  		bool b;
   784  		alloc(&b, n);
   785  		if (!b) throw cybozu::Exception("Buffer:alloc");
   786  	}
   787  #endif
   788  	/*
   789  		*this = rhs
   790  		rhs may be destroyed
   791  	*/
   792  	const T& operator[](size_t n) const { return ptr_[n]; }
   793  	T& operator[](size_t n) { return ptr_[n]; }
   794  };
   795  #endif
   796  
   797  template<class T, size_t BitLen>
   798  class FixedBuffer {
   799  	enum {
   800  		N = (BitLen + sizeof(T) * 8 - 1) / (sizeof(T) * 8)
   801  	};
   802  	size_t size_;
   803  	T v_[N];
   804  public:
   805  	typedef T Unit;
   806  	FixedBuffer()
   807  		: size_(0)
   808  	{
   809  	}
   810  	FixedBuffer(const FixedBuffer& rhs)
   811  	{
   812  		operator=(rhs);
   813  	}
   814  	FixedBuffer& operator=(const FixedBuffer& rhs)
   815  	{
   816  		size_ = rhs.size_;
   817  #if defined(__GNUC__) && !defined(__EMSCRIPTEN__) && !defined(__clang__)
   818  	#pragma GCC diagnostic push
   819  	#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
   820  #endif
   821  		for (size_t i = 0; i < size_; i++) {
   822  			v_[i] = rhs.v_[i];
   823  		}
   824  #if defined(__GNUC__) && !defined(__EMSCRIPTEN__) && !defined(__clang__)
   825  	#pragma GCC diagnostic pop
   826  #endif
   827  		return *this;
   828  	}
   829  	void clear() { size_ = 0; }
   830  	void alloc(bool *pb, size_t n)
   831  	{
   832  		if (n > N) {
   833  			*pb = false;
   834  			return;
   835  		}
   836  		size_ = n;
   837  		*pb = true;
   838  	}
   839  #ifndef CYBOZU_DONT_USE_EXCEPTION
   840  	void alloc(size_t n)
   841  	{
   842  		bool b;
   843  		alloc(&b, n);
   844  		if (!b) throw cybozu::Exception("FixedBuffer:alloc");
   845  	}
   846  #endif
   847  	void swap(FixedBuffer& rhs)
   848  	{
   849  		FixedBuffer *p1 = this;
   850  		FixedBuffer *p2 = &rhs;
   851  		if (p1->size_ < p2->size_) {
   852  			fp::swap_(p1, p2);
   853  		}
   854  		assert(p1->size_ >= p2->size_);
   855  		for (size_t i = 0; i < p2->size_; i++) {
   856  			fp::swap_(p1->v_[i], p2->v_[i]);
   857  		}
   858  		for (size_t i = p2->size_; i < p1->size_; i++) {
   859  			p2->v_[i] = p1->v_[i];
   860  		}
   861  		fp::swap_(p1->size_, p2->size_);
   862  	}
   863  	// to avoid warning of gcc
   864  	void verify(size_t n) const
   865  	{
   866  		assert(n <= N);
   867  		(void)n;
   868  	}
   869  	const T& operator[](size_t n) const { verify(n); return v_[n]; }
   870  	T& operator[](size_t n) { verify(n); return v_[n]; }
   871  };
   872  
   873  #if MCL_SIZEOF_UNIT == 8
   874  /*
   875  	M = 1 << 256
   876  	a = M mod p = (1 << 32) + 0x3d1
   877  	[H:L] mod p = H * a + L
   878  
   879  	if H = L = M - 1, t = H * a + L = aM + (M - a - 1)
   880  	H' = a, L' = M - a - 1
   881  	t' = H' * a + L' = M + (a^2 - a - 1)
   882  	H'' = 1, L'' = a^2 - a - 1
   883  	t'' = H'' * a + L'' = a^2 - 1
   884  */
   885  inline void mcl_fpDbl_mod_SECP256K1(Unit *z, const Unit *x, const Unit *p)
   886  {
   887  	const Unit a = (uint64_t(1) << 32) + 0x3d1;
   888  	Unit buf[5];
   889  	buf[4] = mulu1(buf, x + 4, 4, a); // H * a
   890  	buf[4] += addN(buf, buf, x, 4); // t = H * a + L
   891  	Unit x2[2];
   892  	x2[0] = mulUnit(&x2[1], buf[4], a);
   893  	Unit x3 = addN(buf, buf, x2, 2);
   894  	if (x3) {
   895  		x3 = addu1(buf + 2, buf + 2, 2, Unit(1)); // t' = H' * a + L'
   896  		if (x3) {
   897  			x3 = addu1(buf, buf, 4, a);
   898  			assert(x3 == 0);
   899  		}
   900  	}
   901  	if (fp::isGreaterOrEqualArray(buf, p, 4)) {
   902  		subN(z, buf, p, 4);
   903  	} else {
   904  		fp::copyArray(z, buf, 4);
   905  	}
   906  }
   907  
   908  inline void mcl_fp_mul_SECP256K1(Unit *z, const Unit *x, const Unit *y, const Unit *p)
   909  {
   910  	Unit xy[8];
   911  	mulNM(xy, x, 4, y, 4);
   912  	mcl_fpDbl_mod_SECP256K1(z, xy, p);
   913  }
   914  inline void mcl_fp_sqr_SECP256K1(Unit *y, const Unit *x, const Unit *p)
   915  {
   916  	Unit xx[8];
   917  	sqrN(xx, x, 4);
   918  	mcl_fpDbl_mod_SECP256K1(y, xx, p);
   919  }
   920  #endif
   921  
   922  } // vint
   923  
   924  /**
   925  	signed integer with variable length
   926  */
   927  template<class _Buffer>
   928  class VintT {
   929  public:
   930  	typedef _Buffer Buffer;
   931  	typedef typename Buffer::Unit Unit;
   932  	static const size_t unitBitSize = sizeof(Unit) * 8;
   933  	static const int invalidVar = -2147483647 - 1; // abs(invalidVar) is not defined
   934  private:
   935  	Buffer buf_;
   936  	size_t size_;
   937  	bool isNeg_;
   938  	void trim(size_t n)
   939  	{
   940  		assert(n > 0);
   941  		int i = (int)n - 1;
   942  		for (; i > 0; i--) {
   943  			if (buf_[i]) {
   944  				size_ = i + 1;
   945  				return;
   946  			}
   947  		}
   948  		size_ = 1;
   949  		// zero
   950  		if (buf_[0] == 0) {
   951  			isNeg_ = false;
   952  		}
   953  	}
   954  	static int ucompare(const Buffer& x, size_t xn, const Buffer& y, size_t yn)
   955  	{
   956  		return vint::compareNM(&x[0], xn, &y[0], yn);
   957  	}
   958  	static void uadd(VintT& z, const Buffer& x, size_t xn, const Buffer& y, size_t yn)
   959  	{
   960  		size_t zn = fp::max_(xn, yn) + 1;
   961  		bool b;
   962  		z.buf_.alloc(&b, zn);
   963  		assert(b);
   964  		if (!b) {
   965  			z.clear();
   966  			return;
   967  		}
   968  		z.buf_[zn - 1] = vint::addNM(&z.buf_[0], &x[0], xn, &y[0], yn);
   969  		z.trim(zn);
   970  	}
   971  	static void uadd1(VintT& z, const Buffer& x, size_t xn, Unit y)
   972  	{
   973  		size_t zn = xn + 1;
   974  		bool b;
   975  		z.buf_.alloc(&b, zn);
   976  		assert(b);
   977  		if (!b) {
   978  			z.clear();
   979  			return;
   980  		}
   981  		z.buf_[zn - 1] = vint::addu1(&z.buf_[0], &x[0], xn, y);
   982  		z.trim(zn);
   983  	}
   984  	static void usub1(VintT& z, const Buffer& x, size_t xn, Unit y)
   985  	{
   986  		size_t zn = xn;
   987  		bool b;
   988  		z.buf_.alloc(&b, zn);
   989  		assert(b);
   990  		if (!b) {
   991  			z.clear();
   992  			return;
   993  		}
   994  		Unit c = vint::subu1(&z.buf_[0], &x[0], xn, y);
   995  		(void)c;
   996  		assert(!c);
   997  		z.trim(zn);
   998  	}
   999  	static void usub(VintT& z, const Buffer& x, size_t xn, const Buffer& y, size_t yn)
  1000  	{
  1001  		assert(xn >= yn);
  1002  		bool b;
  1003  		z.buf_.alloc(&b, xn);
  1004  		assert(b);
  1005  		if (!b) {
  1006  			z.clear();
  1007  			return;
  1008  		}
  1009  		Unit c = vint::subN(&z.buf_[0], &x[0], &y[0], yn);
  1010  		if (xn > yn) {
  1011  			c = vint::subu1(&z.buf_[yn], &x[yn], xn - yn, c);
  1012  		}
  1013  		assert(!c);
  1014  		z.trim(xn);
  1015  	}
  1016  	static void _add(VintT& z, const VintT& x, bool xNeg, const VintT& y, bool yNeg)
  1017  	{
  1018  		if ((xNeg ^ yNeg) == 0) {
  1019  			// same sign
  1020  			uadd(z, x.buf_, x.size(), y.buf_, y.size());
  1021  			z.isNeg_ = xNeg;
  1022  			return;
  1023  		}
  1024  		int r = ucompare(x.buf_, x.size(), y.buf_, y.size());
  1025  		if (r >= 0) {
  1026  			usub(z, x.buf_, x.size(), y.buf_, y.size());
  1027  			z.isNeg_ = xNeg;
  1028  		} else {
  1029  			usub(z, y.buf_, y.size(), x.buf_, x.size());
  1030  			z.isNeg_ = yNeg;
  1031  		}
  1032  	}
  1033  	static void _adds1(VintT& z, const VintT& x, int y, bool yNeg)
  1034  	{
  1035  		assert(y >= 0);
  1036  		if ((x.isNeg_ ^ yNeg) == 0) {
  1037  			// same sign
  1038  			uadd1(z, x.buf_, x.size(), y);
  1039  			z.isNeg_ = yNeg;
  1040  			return;
  1041  		}
  1042  		if (x.size() > 1 || x.buf_[0] >= (Unit)y) {
  1043  			usub1(z, x.buf_, x.size(), y);
  1044  			z.isNeg_ = x.isNeg_;
  1045  		} else {
  1046  			z = y - x.buf_[0];
  1047  			z.isNeg_ = yNeg;
  1048  		}
  1049  	}
  1050  	static void _addu1(VintT& z, const VintT& x, Unit y, bool yNeg)
  1051  	{
  1052  		if ((x.isNeg_ ^ yNeg) == 0) {
  1053  			// same sign
  1054  			uadd1(z, x.buf_, x.size(), y);
  1055  			z.isNeg_ = yNeg;
  1056  			return;
  1057  		}
  1058  		if (x.size() > 1 || x.buf_[0] >= y) {
  1059  			usub1(z, x.buf_, x.size(), y);
  1060  			z.isNeg_ = x.isNeg_;
  1061  		} else {
  1062  			z = y - x.buf_[0];
  1063  			z.isNeg_ = yNeg;
  1064  		}
  1065  	}
  1066  	/**
  1067  		@param q [out] x / y if q != 0
  1068  		@param r [out] x % y
  1069  	*/
  1070  	static void udiv(VintT* q, VintT& r, const Buffer& x, size_t xn, const Buffer& y, size_t yn)
  1071  	{
  1072  		assert(q != &r);
  1073  		if (xn < yn) {
  1074  			r.buf_ = x;
  1075  			r.trim(xn);
  1076  			if (q) q->clear();
  1077  			return;
  1078  		}
  1079  		size_t qn = xn - yn + 1;
  1080  		bool b;
  1081  		if (q) {
  1082  			q->buf_.alloc(&b, qn);
  1083  			assert(b);
  1084  			if (!b) {
  1085  				q->clear();
  1086  				r.clear();
  1087  				return;
  1088  			}
  1089  		}
  1090  		r.buf_.alloc(&b, yn);
  1091  		assert(b);
  1092  		if (!b) {
  1093  			r.clear();
  1094  			if (q) q->clear();
  1095  			return;
  1096  		}
  1097  		vint::divNM(q ? &q->buf_[0] : 0, qn, &r.buf_[0], &x[0], xn, &y[0], yn);
  1098  		if (q) {
  1099  			q->trim(qn);
  1100  		}
  1101  		r.trim(yn);
  1102  	}
  1103  	/*
  1104  		@param x [inout] x <- d
  1105  		@retval s for x = 2^s d where d is odd
  1106  	*/
  1107  	static uint32_t countTrailingZero(VintT& x)
  1108  	{
  1109  		uint32_t s = 0;
  1110  		while (x.isEven()) {
  1111  			x >>= 1;
  1112  			s++;
  1113  		}
  1114  		return s;
  1115  	}
  1116  	struct MulMod {
  1117  		const VintT *pm;
  1118  		void operator()(VintT& z, const VintT& x, const VintT& y) const
  1119  		{
  1120  			VintT::mul(z, x, y);
  1121  			z %= *pm;
  1122  		}
  1123  	};
  1124  	struct SqrMod {
  1125  		const VintT *pm;
  1126  		void operator()(VintT& y, const VintT& x) const
  1127  		{
  1128  			VintT::sqr(y, x);
  1129  			y %= *pm;
  1130  		}
  1131  	};
  1132  public:
  1133  	VintT(int x = 0)
  1134  		: size_(0)
  1135  	{
  1136  		*this = x;
  1137  	}
  1138  	VintT(Unit x)
  1139  		: size_(0)
  1140  	{
  1141  		*this = x;
  1142  	}
  1143  	VintT(const VintT& rhs)
  1144  		: buf_(rhs.buf_)
  1145  		, size_(rhs.size_)
  1146  		, isNeg_(rhs.isNeg_)
  1147  	{
  1148  	}
  1149  	VintT& operator=(int x)
  1150  	{
  1151  		assert(x != invalidVar);
  1152  		isNeg_ = x < 0;
  1153  		bool b;
  1154  		buf_.alloc(&b, 1);
  1155  		assert(b); (void)b;
  1156  		buf_[0] = fp::abs_(x);
  1157  		size_ = 1;
  1158  		return *this;
  1159  	}
  1160  	VintT& operator=(Unit x)
  1161  	{
  1162  		isNeg_ = false;
  1163  		bool b;
  1164  		buf_.alloc(&b, 1);
  1165  		assert(b); (void)b;
  1166  		buf_[0] = x;
  1167  		size_ = 1;
  1168  		return *this;
  1169  	}
  1170  	VintT& operator=(const VintT& rhs)
  1171  	{
  1172  		buf_ = rhs.buf_;
  1173  		size_ = rhs.size_;
  1174  		isNeg_ = rhs.isNeg_;
  1175  		return *this;
  1176  	}
  1177  #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
  1178  	VintT(VintT&& rhs)
  1179  		: buf_(rhs.buf_)
  1180  		, size_(rhs.size_)
  1181  		, isNeg_(rhs.isNeg_)
  1182  	{
  1183  	}
  1184  	VintT& operator=(VintT&& rhs)
  1185  	{
  1186  		buf_ = std::move(rhs.buf_);
  1187  		size_ = rhs.size_;
  1188  		isNeg_ = rhs.isNeg_;
  1189  		return *this;
  1190  	}
  1191  #endif
  1192  	void swap(VintT& rhs)
  1193  #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
  1194  		noexcept
  1195  #endif
  1196  	{
  1197  		fp::swap_(buf_, rhs.buf_);
  1198  		fp::swap_(size_, rhs.size_);
  1199  		fp::swap_(isNeg_, rhs.isNeg_);
  1200  	}
  1201  	void dump(const char *msg = "") const
  1202  	{
  1203  		vint::dump(&buf_[0], size_, msg);
  1204  	}
  1205  	/*
  1206  		set positive value
  1207  		@note assume little endian system
  1208  	*/
  1209  	template<class S>
  1210  	void setArray(bool *pb, const S *x, size_t size)
  1211  	{
  1212  		isNeg_ = false;
  1213  		if (size == 0) {
  1214  			clear();
  1215  			*pb = true;
  1216  			return;
  1217  		}
  1218  		size_t unitSize = (sizeof(S) * size + sizeof(Unit) - 1) / sizeof(Unit);
  1219  		buf_.alloc(pb, unitSize);
  1220  		if (!*pb) return;
  1221  		char *dst = (char *)&buf_[0];
  1222  		const char *src = (const char *)x;
  1223  		size_t i = 0;
  1224  		for (; i < sizeof(S) * size; i++) {
  1225  			dst[i] = src[i];
  1226  		}
  1227  		for (; i < sizeof(Unit) * unitSize; i++) {
  1228  			dst[i] = 0;
  1229  		}
  1230  		trim(unitSize);
  1231  	}
  1232  	/*
  1233  		set [0, max) randomly
  1234  	*/
  1235  	void setRand(bool *pb, const VintT& max, fp::RandGen rg = fp::RandGen())
  1236  	{
  1237  		assert(max > 0);
  1238  		if (rg.isZero()) rg = fp::RandGen::get();
  1239  		size_t n = max.size();
  1240  		buf_.alloc(pb, n);
  1241  		if (!*pb) return;
  1242  		rg.read(pb, &buf_[0], n * sizeof(buf_[0]));
  1243  		if (!*pb) return;
  1244  		trim(n);
  1245  		*this %= max;
  1246  	}
  1247  	/*
  1248  		get abs value
  1249  		buf_[0, size) = x
  1250  		buf_[size, maxSize) with zero
  1251  		@note assume little endian system
  1252  	*/
  1253  	void getArray(bool *pb, Unit *x, size_t maxSize) const
  1254  	{
  1255  		size_t n = size();
  1256  		if (n > maxSize) {
  1257  			*pb = false;
  1258  			return;
  1259  		}
  1260  		vint::copyN(x, &buf_[0], n);
  1261  		vint::clearN(x + n, maxSize - n);
  1262  		*pb = true;
  1263  	}
  1264  	void clear() { *this = 0; }
  1265  	template<class OutputStream>
  1266  	void save(bool *pb, OutputStream& os, int base = 10) const
  1267  	{
  1268  		if (isNeg_) cybozu::writeChar(pb, os, '-');
  1269  		char buf[1024];
  1270  		size_t n = mcl::fp::arrayToStr(buf, sizeof(buf), &buf_[0], size_, base, false);
  1271  		if (n == 0) {
  1272  			*pb = false;
  1273  			return;
  1274  		}
  1275  		cybozu::write(pb, os, buf + sizeof(buf) - n, n);
  1276  	}
  1277  	/*
  1278  		set buf with string terminated by '\0'
  1279  		return strlen(buf) if success else 0
  1280  	*/
  1281  	size_t getStr(char *buf, size_t bufSize, int base = 10) const
  1282  	{
  1283  		cybozu::MemoryOutputStream os(buf, bufSize);
  1284  		bool b;
  1285  		save(&b, os, base);
  1286  		const size_t n = os.getPos();
  1287  		if (!b || n == bufSize) return 0;
  1288  		buf[n] = '\0';
  1289  		return n;
  1290  	}
  1291  	/*
  1292  		return bitSize(abs(*this))
  1293  		@note return 1 if zero
  1294  	*/
  1295  	size_t getBitSize() const
  1296  	{
  1297  		if (isZero()) return 1;
  1298  		size_t n = size();
  1299  		Unit v = buf_[n - 1];
  1300  		assert(v);
  1301  		return (n - 1) * sizeof(Unit) * 8 + 1 + cybozu::bsr<Unit>(v);
  1302  	}
  1303  	// ignore sign
  1304  	bool testBit(size_t i) const
  1305  	{
  1306  		size_t q = i / unitBitSize;
  1307  		size_t r = i % unitBitSize;
  1308  		assert(q <= size());
  1309  		Unit mask = Unit(1) << r;
  1310  		return (buf_[q] & mask) != 0;
  1311  	}
  1312  	void setBit(size_t i, bool v = true)
  1313  	{
  1314  		size_t q = i / unitBitSize;
  1315  		size_t r = i % unitBitSize;
  1316  		assert(q <= size());
  1317  		bool b;
  1318  		buf_.alloc(&b, q + 1);
  1319  		assert(b);
  1320  		if (!b) {
  1321  			clear();
  1322  			return;
  1323  		}
  1324  		Unit mask = Unit(1) << r;
  1325  		if (v) {
  1326  			buf_[q] |= mask;
  1327  		} else {
  1328  			buf_[q] &= ~mask;
  1329  			trim(q + 1);
  1330  		}
  1331  	}
  1332  	/*
  1333  		@param str [in] number string
  1334  		@note "0x..."   => base = 16
  1335  		      "0b..."   => base = 2
  1336  		      otherwise => base = 10
  1337  	*/
  1338  	void setStr(bool *pb, const char *str, int base = 0)
  1339  	{
  1340  		// allow twice size of MCL_MAX_BIT_SIZE because of multiplication
  1341  		const size_t maxN = (MCL_MAX_BIT_SIZE * 2 + unitBitSize - 1) / unitBitSize;
  1342  		buf_.alloc(pb, maxN);
  1343  		if (!*pb) return;
  1344  		*pb = false;
  1345  		isNeg_ = false;
  1346  		size_t len = strlen(str);
  1347  		size_t n = fp::strToArray(&isNeg_, &buf_[0], maxN, str, len, base);
  1348  		if (n == 0) return;
  1349  		trim(n);
  1350  		*pb = true;
  1351  	}
  1352  	static int compare(const VintT& x, const VintT& y)
  1353  	{
  1354  		if (x.isNeg_ ^ y.isNeg_) {
  1355  			if (x.isZero() && y.isZero()) return 0;
  1356  			return x.isNeg_ ? -1 : 1;
  1357  		} else {
  1358  			// same sign
  1359  			int c = ucompare(x.buf_, x.size(), y.buf_, y.size());
  1360  			if (x.isNeg_) {
  1361  				return -c;
  1362  			}
  1363  			return c;
  1364  		}
  1365  	}
  1366  	static int compares1(const VintT& x, int y)
  1367  	{
  1368  		assert(y != invalidVar);
  1369  		if (x.isNeg_ ^ (y < 0)) {
  1370  			if (x.isZero() && y == 0) return 0;
  1371  			return x.isNeg_ ? -1 : 1;
  1372  		} else {
  1373  			// same sign
  1374  			Unit y0 = fp::abs_(y);
  1375  			int c = vint::compareNM(&x.buf_[0], x.size(), &y0, 1);
  1376  			if (x.isNeg_) {
  1377  				return -c;
  1378  			}
  1379  			return c;
  1380  		}
  1381  	}
  1382  	static int compareu1(const VintT& x, uint32_t y)
  1383  	{
  1384  		if (x.isNeg_) return -1;
  1385  		if (x.size() > 1) return 1;
  1386  		Unit x0 = x.buf_[0];
  1387  		return x0 > y ? 1 : x0 == y ? 0 : -1;
  1388  	}
  1389  	size_t size() const { return size_; }
  1390  	bool isZero() const { return size() == 1 && buf_[0] == 0; }
  1391  	bool isNegative() const { return !isZero() && isNeg_; }
  1392  	uint32_t getLow32bit() const { return (uint32_t)buf_[0]; }
  1393  	bool isOdd() const { return (buf_[0] & 1) == 1; }
  1394  	bool isEven() const { return !isOdd(); }
  1395  	const Unit *getUnit() const { return &buf_[0]; }
  1396  	size_t getUnitSize() const { return size_; }
  1397  	static void add(VintT& z, const VintT& x, const VintT& y)
  1398  	{
  1399  		_add(z, x, x.isNeg_, y, y.isNeg_);
  1400  	}
  1401  	static void sub(VintT& z, const VintT& x, const VintT& y)
  1402  	{
  1403  		_add(z, x, x.isNeg_, y, !y.isNeg_);
  1404  	}
  1405  	static void mul(VintT& z, const VintT& x, const VintT& y)
  1406  	{
  1407  		const size_t xn = x.size();
  1408  		const size_t yn = y.size();
  1409  		size_t zn = xn + yn;
  1410  		bool b;
  1411  		z.buf_.alloc(&b, zn);
  1412  		assert(b);
  1413  		if (!b) {
  1414  			z.clear();
  1415  			return;
  1416  		}
  1417  		vint::mulNM(&z.buf_[0], &x.buf_[0], xn, &y.buf_[0], yn);
  1418  		z.isNeg_ = x.isNeg_ ^ y.isNeg_;
  1419  		z.trim(zn);
  1420  	}
  1421  	static void sqr(VintT& y, const VintT& x)
  1422  	{
  1423  		mul(y, x, x);
  1424  	}
  1425  	static void addu1(VintT& z, const VintT& x, Unit y)
  1426  	{
  1427  		_addu1(z, x, y, false);
  1428  	}
  1429  	static void subu1(VintT& z, const VintT& x, Unit y)
  1430  	{
  1431  		_addu1(z, x, y, true);
  1432  	}
  1433  	static void mulu1(VintT& z, const VintT& x, Unit y)
  1434  	{
  1435  		size_t xn = x.size();
  1436  		size_t zn = xn + 1;
  1437  		bool b;
  1438  		z.buf_.alloc(&b, zn);
  1439  		assert(b);
  1440  		if (!b) {
  1441  			z.clear();
  1442  			return;
  1443  		}
  1444  		z.buf_[zn - 1] = vint::mulu1(&z.buf_[0], &x.buf_[0], xn, y);
  1445  		z.isNeg_ = x.isNeg_;
  1446  		z.trim(zn);
  1447  	}
  1448  	static void divu1(VintT& q, const VintT& x, Unit y)
  1449  	{
  1450  		udivModu1(&q, x, y);
  1451  	}
  1452  	static void modu1(VintT& r, const VintT& x, Unit y)
  1453  	{
  1454  		bool xNeg = x.isNeg_;
  1455  		r = divModu1(0, x, y);
  1456  		r.isNeg_ = xNeg;
  1457  	}
  1458  	static void adds1(VintT& z, const VintT& x, int y)
  1459  	{
  1460  		assert(y != invalidVar);
  1461  		_adds1(z, x, fp::abs_(y), y < 0);
  1462  	}
  1463  	static void subs1(VintT& z, const VintT& x, int y)
  1464  	{
  1465  		assert(y != invalidVar);
  1466  		_adds1(z, x, fp::abs_(y), !(y < 0));
  1467  	}
  1468  	static void muls1(VintT& z, const VintT& x, int y)
  1469  	{
  1470  		assert(y != invalidVar);
  1471  		mulu1(z, x, fp::abs_(y));
  1472  		z.isNeg_ ^= (y < 0);
  1473  	}
  1474  	/*
  1475  		@param q [out] q = x / y if q is not zero
  1476  		@param x [in]
  1477  		@param y [in] must be not zero
  1478  		return x % y
  1479  	*/
  1480  	static int divMods1(VintT *q, const VintT& x, int y)
  1481  	{
  1482  		assert(y != invalidVar);
  1483  		bool xNeg = x.isNeg_;
  1484  		bool yNeg = y < 0;
  1485  		Unit absY = fp::abs_(y);
  1486  		size_t xn = x.size();
  1487  		int r;
  1488  		if (q) {
  1489  			q->isNeg_ = xNeg ^ yNeg;
  1490  			bool b;
  1491  			q->buf_.alloc(&b, xn);
  1492  			assert(b);
  1493  			if (!b) {
  1494  				q->clear();
  1495  				return 0;
  1496  			}
  1497  			r = (int)vint::divu1(&q->buf_[0], &x.buf_[0], xn, absY);
  1498  			q->trim(xn);
  1499  		} else {
  1500  			r = (int)vint::modu1(&x.buf_[0], xn, absY);
  1501  		}
  1502  		return xNeg ? -r : r;
  1503  	}
  1504  	/*
  1505  		like C
  1506  		  13 /  5 =  2 ...  3
  1507  		  13 / -5 = -2 ...  3
  1508  		 -13 /  5 = -2 ... -3
  1509  		 -13 / -5 =  2 ... -3
  1510  	*/
  1511  	static void divMod(VintT *q, VintT& r, const VintT& x, const VintT& y)
  1512  	{
  1513  		bool qsign = x.isNeg_ ^ y.isNeg_;
  1514  		udiv(q, r, x.buf_, x.size(), y.buf_, y.size());
  1515  		r.isNeg_ = x.isNeg_;
  1516  		if (q) q->isNeg_ = qsign;
  1517  	}
  1518  	static void div(VintT& q, const VintT& x, const VintT& y)
  1519  	{
  1520  		VintT r;
  1521  		divMod(&q, r, x, y);
  1522  	}
  1523  	static void mod(VintT& r, const VintT& x, const VintT& y)
  1524  	{
  1525  		divMod(0, r, x, y);
  1526  	}
  1527  	static void divs1(VintT& q, const VintT& x, int y)
  1528  	{
  1529  		divMods1(&q, x, y);
  1530  	}
  1531  	static void mods1(VintT& r, const VintT& x, int y)
  1532  	{
  1533  		bool xNeg = x.isNeg_;
  1534  		r = divMods1(0, x, y);
  1535  		r.isNeg_ = xNeg;
  1536  	}
  1537  	static Unit udivModu1(VintT *q, const VintT& x, Unit y)
  1538  	{
  1539  		assert(!x.isNeg_);
  1540  		size_t xn = x.size();
  1541  		if (q) {
  1542  			bool b;
  1543  			q->buf_.alloc(&b, xn);
  1544  			assert(b);
  1545  			if (!b) {
  1546  				q->clear();
  1547  				return 0;
  1548  			}
  1549  		}
  1550  		Unit r = vint::divu1(q ? &q->buf_[0] : 0, &x.buf_[0], xn, y);
  1551  		if (q) {
  1552  			q->trim(xn);
  1553  			q->isNeg_ = false;
  1554  		}
  1555  		return r;
  1556  	}
  1557  	/*
  1558  		like Python
  1559  		 13 /  5 =  2 ...  3
  1560  		 13 / -5 = -3 ... -2
  1561  		-13 /  5 = -3 ...  2
  1562  		-13 / -5 =  2 ... -3
  1563  	*/
  1564  	static void quotRem(VintT *q, VintT& r, const VintT& x, const VintT& y)
  1565  	{
  1566  		VintT yy = y;
  1567  		bool qsign = x.isNeg_ ^ y.isNeg_;
  1568  		udiv(q, r, x.buf_, x.size(), y.buf_, y.size());
  1569  		r.isNeg_ = y.isNeg_;
  1570  		if (q) q->isNeg_ = qsign;
  1571  		if (!r.isZero() && qsign) {
  1572  			if (q) {
  1573  				uadd1(*q, q->buf_, q->size(), 1);
  1574  			}
  1575  			usub(r, yy.buf_, yy.size(), r.buf_, r.size());
  1576  		}
  1577  	}
  1578  	template<class InputStream>
  1579  	void load(bool *pb, InputStream& is, int ioMode)
  1580  	{
  1581  		*pb = false;
  1582  		char buf[1024];
  1583  		size_t n = fp::local::loadWord(buf, sizeof(buf), is);
  1584  		if (n == 0) return;
  1585  		const size_t maxN = 384 / (sizeof(MCL_SIZEOF_UNIT) * 8);
  1586  		buf_.alloc(pb, maxN);
  1587  		if (!*pb) return;
  1588  		isNeg_ = false;
  1589  		n = fp::strToArray(&isNeg_, &buf_[0], maxN, buf, n, ioMode);
  1590  		if (n == 0) return;
  1591  		trim(n);
  1592  		*pb = true;
  1593  	}
  1594  	// logical left shift (copy sign)
  1595  	static void shl(VintT& y, const VintT& x, size_t shiftBit)
  1596  	{
  1597  		size_t xn = x.size();
  1598  		size_t yn = xn + (shiftBit + unitBitSize - 1) / unitBitSize;
  1599  		bool b;
  1600  		y.buf_.alloc(&b, yn);
  1601  		assert(b);
  1602  		if (!b) {
  1603  			y.clear();
  1604  			return;
  1605  		}
  1606  		vint::shlN(&y.buf_[0], &x.buf_[0], xn, shiftBit);
  1607  		y.isNeg_ = x.isNeg_;
  1608  		y.trim(yn);
  1609  	}
  1610  	// logical right shift (copy sign)
  1611  	static void shr(VintT& y, const VintT& x, size_t shiftBit)
  1612  	{
  1613  		size_t xn = x.size();
  1614  		if (xn * unitBitSize <= shiftBit) {
  1615  			y.clear();
  1616  			return;
  1617  		}
  1618  		size_t yn = xn - shiftBit / unitBitSize;
  1619  		bool b;
  1620  		y.buf_.alloc(&b, yn);
  1621  		assert(b);
  1622  		if (!b) {
  1623  			y.clear();
  1624  			return;
  1625  		}
  1626  		vint::shrN(&y.buf_[0], &x.buf_[0], xn, shiftBit);
  1627  		y.isNeg_ = x.isNeg_;
  1628  		y.trim(yn);
  1629  	}
  1630  	static void neg(VintT& y, const VintT& x)
  1631  	{
  1632  		if (&y != &x) { y = x; }
  1633  		y.isNeg_ = !x.isNeg_;
  1634  	}
  1635  	static void abs(VintT& y, const VintT& x)
  1636  	{
  1637  		if (&y != &x) { y = x; }
  1638  		y.isNeg_ = false;
  1639  	}
  1640  	static VintT abs(const VintT& x)
  1641  	{
  1642  		VintT y = x;
  1643  		abs(y, x);
  1644  		return y;
  1645  	}
  1646  	// accept only non-negative value
  1647  	static void orBit(VintT& z, const VintT& x, const VintT& y)
  1648  	{
  1649  		assert(!x.isNeg_ && !y.isNeg_);
  1650  		const VintT *px = &x, *py = &y;
  1651  		if (x.size() < y.size()) {
  1652  			fp::swap_(px, py);
  1653  		}
  1654  		size_t xn = px->size();
  1655  		size_t yn = py->size();
  1656  		assert(xn >= yn);
  1657  		bool b;
  1658  		z.buf_.alloc(&b, xn);
  1659  		assert(b);
  1660  		if (!b) {
  1661  			z.clear();
  1662  		}
  1663  		for (size_t i = 0; i < yn; i++) {
  1664  			z.buf_[i] = x.buf_[i] | y.buf_[i];
  1665  		}
  1666  		vint::copyN(&z.buf_[0] + yn, &px->buf_[0] + yn, xn - yn);
  1667  		z.trim(xn);
  1668  	}
  1669  	static void andBit(VintT& z, const VintT& x, const VintT& y)
  1670  	{
  1671  		assert(!x.isNeg_ && !y.isNeg_);
  1672  		const VintT *px = &x, *py = &y;
  1673  		if (x.size() < y.size()) {
  1674  			fp::swap_(px, py);
  1675  		}
  1676  		size_t yn = py->size();
  1677  		assert(px->size() >= yn);
  1678  		bool b;
  1679  		z.buf_.alloc(&b, yn);
  1680  		assert(b);
  1681  		if (!b) {
  1682  			z.clear();
  1683  			return;
  1684  		}
  1685  		for (size_t i = 0; i < yn; i++) {
  1686  			z.buf_[i] = x.buf_[i] & y.buf_[i];
  1687  		}
  1688  		z.trim(yn);
  1689  	}
  1690  	static void orBitu1(VintT& z, const VintT& x, Unit y)
  1691  	{
  1692  		assert(!x.isNeg_);
  1693  		z = x;
  1694  		z.buf_[0] |= y;
  1695  	}
  1696  	static void andBitu1(VintT& z, const VintT& x, Unit y)
  1697  	{
  1698  		assert(!x.isNeg_);
  1699  		bool b;
  1700  		z.buf_.alloc(&b, 1);
  1701  		assert(b); (void)b;
  1702  		z.buf_[0] = x.buf_[0] & y;
  1703  		z.size_ = 1;
  1704  		z.isNeg_ = false;
  1705  	}
  1706  	/*
  1707  		REMARK y >= 0;
  1708  	*/
  1709  	static void pow(VintT& z, const VintT& x, const VintT& y)
  1710  	{
  1711  		assert(!y.isNeg_);
  1712  		const VintT xx = x;
  1713  		z = 1;
  1714  		mcl::fp::powGeneric(z, xx, &y.buf_[0], y.size(), mul, sqr, (void (*)(VintT&, const VintT&))0);
  1715  	}
  1716  	/*
  1717  		REMARK y >= 0;
  1718  	*/
  1719  	static void pow(VintT& z, const VintT& x, int64_t y)
  1720  	{
  1721  		assert(y >= 0);
  1722  		const VintT xx = x;
  1723  		z = 1;
  1724  #if MCL_SIZEOF_UNIT == 8
  1725  		Unit ua = fp::abs_(y);
  1726  		mcl::fp::powGeneric(z, xx, &ua, 1, mul, sqr, (void (*)(VintT&, const VintT&))0);
  1727  #else
  1728  		uint64_t ua = fp::abs_(y);
  1729  		Unit u[2] = { uint32_t(ua), uint32_t(ua >> 32) };
  1730  		size_t un = u[1] ? 2 : 1;
  1731  		mcl::fp::powGeneric(z, xx, u, un, mul, sqr, (void (*)(VintT&, const VintT&))0);
  1732  #endif
  1733  	}
  1734  	/*
  1735  		z = x ^ y mod m
  1736  		REMARK y >= 0;
  1737  	*/
  1738  	static void powMod(VintT& z, const VintT& x, const VintT& y, const VintT& m)
  1739  	{
  1740  		assert(!y.isNeg_);
  1741  		VintT zz;
  1742  		MulMod mulMod;
  1743  		SqrMod sqrMod;
  1744  		mulMod.pm = &m;
  1745  		sqrMod.pm = &m;
  1746  		zz = 1;
  1747  		mcl::fp::powGeneric(zz, x, &y.buf_[0], y.size(), mulMod, sqrMod, (void (*)(VintT&, const VintT&))0);
  1748  		z.swap(zz);
  1749  	}
  1750  	/*
  1751  		inverse mod
  1752  		y = 1/x mod m
  1753  		REMARK x != 0 and m != 0;
  1754  	*/
  1755  	static void invMod(VintT& y, const VintT& x, const VintT& m)
  1756  	{
  1757  		assert(!x.isZero() && !m.isZero());
  1758  		if (x == 1) {
  1759  			y = 1;
  1760  			return;
  1761  		}
  1762  		VintT a = 1;
  1763  		VintT t;
  1764  		VintT q;
  1765  		divMod(&q, t, m, x);
  1766  		VintT s = x;
  1767  		VintT b = -q;
  1768  
  1769  		for (;;) {
  1770  			divMod(&q, s, s, t);
  1771  			if (s.isZero()) {
  1772  				if (b.isNeg_) {
  1773  					b += m;
  1774  				}
  1775  				y = b;
  1776  				return;
  1777  			}
  1778  			a -= b * q;
  1779  
  1780  			divMod(&q, t, t, s);
  1781  			if (t.isZero()) {
  1782  				if (a.isNeg_) {
  1783  					a += m;
  1784  				}
  1785  				y = a;
  1786  				return;
  1787  			}
  1788  			b -= a * q;
  1789  		}
  1790  	}
  1791  	/*
  1792  		Miller-Rabin
  1793  	*/
  1794  	static bool isPrime(bool *pb, const VintT& n, int tryNum = 32)
  1795  	{
  1796  		*pb = true;
  1797  		if (n <= 1) return false;
  1798  		if (n == 2 || n == 3) return true;
  1799  		if (n.isEven()) return false;
  1800  		cybozu::XorShift rg;
  1801  		const VintT nm1 = n - 1;
  1802  		VintT d = nm1;
  1803  		uint32_t r = countTrailingZero(d);
  1804  		// n - 1 = 2^r d
  1805  		VintT a, x;
  1806  		for (int i = 0; i < tryNum; i++) {
  1807  			a.setRand(pb, n - 3, rg);
  1808  			if (!*pb) return false;
  1809  			a += 2; // a in [2, n - 2]
  1810  			powMod(x, a, d, n);
  1811  			if (x == 1 || x == nm1) {
  1812  				continue;
  1813  			}
  1814  			for (uint32_t j = 1; j < r; j++) {
  1815  				sqr(x, x);
  1816  				x %= n;
  1817  				if (x == 1) return false;
  1818  				if (x == nm1) goto NEXT_LOOP;
  1819  			}
  1820  			return false;
  1821  		NEXT_LOOP:;
  1822  		}
  1823  		return true;
  1824  	}
  1825  	bool isPrime(bool *pb, int tryNum = 32) const
  1826  	{
  1827  		return isPrime(pb, *this, tryNum);
  1828  	}
  1829  	static void gcd(VintT& z, VintT x, VintT y)
  1830  	{
  1831  		VintT t;
  1832  		for (;;) {
  1833  			if (y.isZero()) {
  1834  				z = x;
  1835  				return;
  1836  			}
  1837  			t = x;
  1838  			x = y;
  1839  			mod(y, t, y);
  1840  		}
  1841  	}
  1842  	static VintT gcd(const VintT& x, const VintT& y)
  1843  	{
  1844  		VintT z;
  1845  		gcd(z, x, y);
  1846  		return z;
  1847  	}
  1848  	static void lcm(VintT& z, const VintT& x, const VintT& y)
  1849  	{
  1850  		VintT c;
  1851  		gcd(c, x, y);
  1852  		div(c, x, c);
  1853  		mul(z, c, y);
  1854  	}
  1855  	static VintT lcm(const VintT& x, const VintT& y)
  1856  	{
  1857  		VintT z;
  1858  		lcm(z, x, y);
  1859  		return z;
  1860  	}
  1861  	/*
  1862  		 1 if m is quadratic residue modulo n (i.e., there exists an x s.t. x^2 = m mod n)
  1863  		 0 if m = 0 mod n
  1864  		-1 otherwise
  1865  		@note return legendre_symbol(m, p) for m and odd prime p
  1866  	*/
  1867  	static int jacobi(VintT m, VintT n)
  1868  	{
  1869  		assert(n.isOdd());
  1870  		if (n == 1) return 1;
  1871  		if (m < 0 || m > n) {
  1872  			quotRem(0, m, m, n); // m = m mod n
  1873  		}
  1874  		if (m.isZero()) return 0;
  1875  		if (m == 1) return 1;
  1876  		if (gcd(m, n) != 1) return 0;
  1877  
  1878  		int j = 1;
  1879  		VintT t;
  1880  		goto START;
  1881  		while (m != 1) {
  1882  			if ((m.getLow32bit() % 4) == 3 && (n.getLow32bit() % 4) == 3) {
  1883  				j = -j;
  1884  			}
  1885  			mod(t, n, m);
  1886  			n = m;
  1887  			m = t;
  1888  		START:
  1889  			int s = countTrailingZero(m);
  1890  			uint32_t nmod8 = n.getLow32bit() % 8;
  1891  			if ((s % 2) && (nmod8 == 3 || nmod8 == 5)) {
  1892  				j = -j;
  1893  			}
  1894  		}
  1895  		return j;
  1896  	}
  1897  #ifndef CYBOZU_DONT_USE_STRING
  1898  	explicit VintT(const std::string& str)
  1899  		: size_(0)
  1900  	{
  1901  		setStr(str);
  1902  	}
  1903  	void getStr(std::string& s, int base = 10) const
  1904  	{
  1905  		s.clear();
  1906  		cybozu::StringOutputStream os(s);
  1907  		save(os, base);
  1908  	}
  1909  	std::string getStr(int base = 10) const
  1910  	{
  1911  		std::string s;
  1912  		getStr(s, base);
  1913  		return s;
  1914  	}
  1915  	inline friend std::ostream& operator<<(std::ostream& os, const VintT& x)
  1916  	{
  1917  		return os << x.getStr(os.flags() & std::ios_base::hex ? 16 : 10);
  1918  	}
  1919  	inline friend std::istream& operator>>(std::istream& is, VintT& x)
  1920  	{
  1921  		x.load(is);
  1922  		return is;
  1923  	}
  1924  #endif
  1925  #ifndef CYBOZU_DONT_USE_EXCEPTION
  1926  	void setStr(const std::string& str, int base = 0)
  1927  	{
  1928  		bool b;
  1929  		setStr(&b, str.c_str(), base);
  1930  		if (!b) throw cybozu::Exception("Vint:setStr") << str;
  1931  	}
  1932  	void setRand(const VintT& max, fp::RandGen rg = fp::RandGen())
  1933  	{
  1934  		bool b;
  1935  		setRand(&b, max, rg);
  1936  		if (!b) throw cybozu::Exception("Vint:setRand");
  1937  	}
  1938  	void getArray(Unit *x, size_t maxSize) const
  1939  	{
  1940  		bool b;
  1941  		getArray(&b, x, maxSize);
  1942  		if (!b) throw cybozu::Exception("Vint:getArray");
  1943  	}
  1944  	template<class InputStream>
  1945  	void load(InputStream& is, int ioMode = 0)
  1946  	{
  1947  		bool b;
  1948  		load(&b, is, ioMode);
  1949  		if (!b) throw cybozu::Exception("Vint:load");
  1950  	}
  1951  	template<class OutputStream>
  1952  	void save(OutputStream& os, int base = 10) const
  1953  	{
  1954  		bool b;
  1955  		save(&b, os, base);
  1956  		if (!b) throw cybozu::Exception("Vint:save");
  1957  	}
  1958  	static bool isPrime(const VintT& n, int tryNum = 32)
  1959  	{
  1960  		bool b;
  1961  		bool ret = isPrime(&b, n, tryNum);
  1962  		if (!b) throw cybozu::Exception("Vint:isPrime");
  1963  		return ret;
  1964  	}
  1965  	bool isPrime(int tryNum = 32) const
  1966  	{
  1967  		bool b;
  1968  		bool ret = isPrime(&b, *this, tryNum);
  1969  		if (!b) throw cybozu::Exception("Vint:isPrime");
  1970  		return ret;
  1971  	}
  1972  	template<class S>
  1973  	void setArray(const S *x, size_t size)
  1974  	{
  1975  		bool b;
  1976  		setArray(&b, x, size);
  1977  		if (!b) throw cybozu::Exception("Vint:setArray");
  1978  	}
  1979  #endif
  1980  	VintT& operator++() { adds1(*this, *this, 1); return *this; }
  1981  	VintT& operator--() { subs1(*this, *this, 1); return *this; }
  1982  	VintT operator++(int) { VintT c = *this; adds1(*this, *this, 1); return c; }
  1983  	VintT operator--(int) { VintT c = *this; subs1(*this, *this, 1); return c; }
  1984  	friend bool operator<(const VintT& x, const VintT& y) { return compare(x, y) < 0; }
  1985  	friend bool operator>=(const VintT& x, const VintT& y) { return !operator<(x, y); }
  1986  	friend bool operator>(const VintT& x, const VintT& y) { return compare(x, y) > 0; }
  1987  	friend bool operator<=(const VintT& x, const VintT& y) { return !operator>(x, y); }
  1988  	friend bool operator==(const VintT& x, const VintT& y) { return compare(x, y) == 0; }
  1989  	friend bool operator!=(const VintT& x, const VintT& y) { return !operator==(x, y); }
  1990  
  1991  	friend bool operator<(const VintT& x, int y) { return compares1(x, y) < 0; }
  1992  	friend bool operator>=(const VintT& x, int y) { return !operator<(x, y); }
  1993  	friend bool operator>(const VintT& x, int y) { return compares1(x, y) > 0; }
  1994  	friend bool operator<=(const VintT& x, int y) { return !operator>(x, y); }
  1995  	friend bool operator==(const VintT& x, int y) { return compares1(x, y) == 0; }
  1996  	friend bool operator!=(const VintT& x, int y) { return !operator==(x, y); }
  1997  
  1998  	friend bool operator<(const VintT& x, uint32_t y) { return compareu1(x, y) < 0; }
  1999  	friend bool operator>=(const VintT& x, uint32_t y) { return !operator<(x, y); }
  2000  	friend bool operator>(const VintT& x, uint32_t y) { return compareu1(x, y) > 0; }
  2001  	friend bool operator<=(const VintT& x, uint32_t y) { return !operator>(x, y); }
  2002  	friend bool operator==(const VintT& x, uint32_t y) { return compareu1(x, y) == 0; }
  2003  	friend bool operator!=(const VintT& x, uint32_t y) { return !operator==(x, y); }
  2004  
  2005  	VintT& operator+=(const VintT& rhs) { add(*this, *this, rhs); return *this; }
  2006  	VintT& operator-=(const VintT& rhs) { sub(*this, *this, rhs); return *this; }
  2007  	VintT& operator*=(const VintT& rhs) { mul(*this, *this, rhs); return *this; }
  2008  	VintT& operator/=(const VintT& rhs) { div(*this, *this, rhs); return *this; }
  2009  	VintT& operator%=(const VintT& rhs) { mod(*this, *this, rhs); return *this; }
  2010  	VintT& operator&=(const VintT& rhs) { andBit(*this, *this, rhs); return *this; }
  2011  	VintT& operator|=(const VintT& rhs) { orBit(*this, *this, rhs); return *this; }
  2012  
  2013  	VintT& operator+=(int rhs) { adds1(*this, *this, rhs); return *this; }
  2014  	VintT& operator-=(int rhs) { subs1(*this, *this, rhs); return *this; }
  2015  	VintT& operator*=(int rhs) { muls1(*this, *this, rhs); return *this; }
  2016  	VintT& operator/=(int rhs) { divs1(*this, *this, rhs); return *this; }
  2017  	VintT& operator%=(int rhs) { mods1(*this, *this, rhs); return *this; }
  2018  	VintT& operator+=(Unit rhs) { addu1(*this, *this, rhs); return *this; }
  2019  	VintT& operator-=(Unit rhs) { subu1(*this, *this, rhs); return *this; }
  2020  	VintT& operator*=(Unit rhs) { mulu1(*this, *this, rhs); return *this; }
  2021  	VintT& operator/=(Unit rhs) { divu1(*this, *this, rhs); return *this; }
  2022  	VintT& operator%=(Unit rhs) { modu1(*this, *this, rhs); return *this; }
  2023  
  2024  	VintT& operator&=(Unit rhs) { andBitu1(*this, *this, rhs); return *this; }
  2025  	VintT& operator|=(Unit rhs) { orBitu1(*this, *this, rhs); return *this; }
  2026  
  2027  	friend VintT operator+(const VintT& a, const VintT& b) { VintT c; add(c, a, b); return c; }
  2028  	friend VintT operator-(const VintT& a, const VintT& b) { VintT c; sub(c, a, b); return c; }
  2029  	friend VintT operator*(const VintT& a, const VintT& b) { VintT c; mul(c, a, b); return c; }
  2030  	friend VintT operator/(const VintT& a, const VintT& b) { VintT c; div(c, a, b); return c; }
  2031  	friend VintT operator%(const VintT& a, const VintT& b) { VintT c; mod(c, a, b); return c; }
  2032  	friend VintT operator&(const VintT& a, const VintT& b) { VintT c; andBit(c, a, b); return c; }
  2033  	friend VintT operator|(const VintT& a, const VintT& b) { VintT c; orBit(c, a, b); return c; }
  2034  
  2035  	friend VintT operator+(const VintT& a, int b) { VintT c; adds1(c, a, b); return c; }
  2036  	friend VintT operator-(const VintT& a, int b) { VintT c; subs1(c, a, b); return c; }
  2037  	friend VintT operator*(const VintT& a, int b) { VintT c; muls1(c, a, b); return c; }
  2038  	friend VintT operator/(const VintT& a, int b) { VintT c; divs1(c, a, b); return c; }
  2039  	friend VintT operator%(const VintT& a, int b) { VintT c; mods1(c, a, b); return c; }
  2040  	friend VintT operator+(const VintT& a, Unit b) { VintT c; addu1(c, a, b); return c; }
  2041  	friend VintT operator-(const VintT& a, Unit b) { VintT c; subu1(c, a, b); return c; }
  2042  	friend VintT operator*(const VintT& a, Unit b) { VintT c; mulu1(c, a, b); return c; }
  2043  	friend VintT operator/(const VintT& a, Unit b) { VintT c; divu1(c, a, b); return c; }
  2044  	friend VintT operator%(const VintT& a, Unit b) { VintT c; modu1(c, a, b); return c; }
  2045  
  2046  	friend VintT operator&(const VintT& a, Unit b) { VintT c; andBitu1(c, a, b); return c; }
  2047  	friend VintT operator|(const VintT& a, Unit b) { VintT c; orBitu1(c, a, b); return c; }
  2048  
  2049  	VintT operator-() const { VintT c; neg(c, *this); return c; }
  2050  	VintT& operator<<=(size_t n) { shl(*this, *this, n); return *this; }
  2051  	VintT& operator>>=(size_t n) { shr(*this, *this, n); return *this; }
  2052  	VintT operator<<(size_t n) const { VintT c = *this; c <<= n; return c; }
  2053  	VintT operator>>(size_t n) const { VintT c = *this; c >>= n; return c; }
  2054  };
  2055  
  2056  #ifdef MCL_VINT_FIXED_BUFFER
  2057  typedef VintT<vint::FixedBuffer<mcl::vint::Unit, vint::RoundUp<MCL_MAX_BIT_SIZE>::bit * 2> > Vint;
  2058  #else
  2059  typedef VintT<vint::Buffer<mcl::vint::Unit> > Vint;
  2060  #endif
  2061  
  2062  } // mcl
  2063  
  2064  //typedef mcl::Vint mpz_class;