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