a portable and fast pairing-based cryptography library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
mcl/include/mcl/op.hpp

203 lines
4.3 KiB

#pragma once
/**
@file
@brief definition of Op
@author MITSUNARI Shigeo(@herumi)
@license modified new BSD license
http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/gmp_util.hpp>
#ifndef MCL_MAX_OP_BIT_SIZE
#define MCL_MAX_OP_BIT_SIZE 521
#endif
#if !defined(MCL_DONT_USE_XBYAK) && (defined(_WIN64) || defined(__x86_64__))
#define MCL_USE_XBYAK
#endif
namespace mcl { namespace fp {
#if defined(CYBOZU_OS_BIT) && (CYBOZU_OS_BIT == 32)
typedef uint32_t Unit;
#else
typedef uint64_t Unit;
#endif
const size_t UnitBitSize = sizeof(Unit) * 8;
const size_t maxOpUnitSize = (MCL_MAX_OP_BIT_SIZE + UnitBitSize - 1) / UnitBitSize;
struct FpGenerator;
struct Op;
typedef void (*void1u)(Unit*);
typedef void (*void2u)(Unit*, const Unit*);
typedef void (*void2uI)(Unit*, const Unit*, Unit);
typedef void (*void2uOp)(Unit*, const Unit*, const Op&);
typedef void (*void3u)(Unit*, const Unit*, const Unit*);
typedef void (*void4u)(Unit*, const Unit*, const Unit*, const Unit*);
typedef int (*int2u)(Unit*, const Unit*);
struct Block {
const Unit *p; // pointer to original FpT.v_
size_t n;
Unit v_[maxOpUnitSize];
};
enum Mode {
FP_AUTO,
FP_GMP,
FP_GMP_MONT,
FP_LLVM,
FP_LLVM_MONT,
FP_XBYAK
};
enum PrimeMode {
PM_GENERIC = 0,
PM_NICT_P192,
PM_NICT_P521,
};
struct Op {
mpz_class mp;
mcl::SquareRoot sq;
Unit p[maxOpUnitSize];
Unit half[maxOpUnitSize]; // (p - 1) / 2
Unit oneRep[maxOpUnitSize]; // 1(=inv R if Montgomery)
/*
for Montgomery
one = 1
R = (1 << (N * sizeof(Unit) * 8)) % p
R2 = (R * R) % p
R3 = RR^3
*/
Unit one[maxOpUnitSize];
Unit R2[maxOpUnitSize];
Unit R3[maxOpUnitSize];
std::vector<Unit> invTbl;
size_t N;
size_t bitSize;
// independent from p
bool (*fp_isZero)(const Unit*);
void1u fp_clear;
void2u fp_copy;
// not require p(function having p)
void2u fp_neg;
void2u fp_sqr;
void3u fp_add;
void3u fp_sub;
void3u fp_mul;
void2uI fp_mul_UnitPre; // z[N + 1] = x[N] * y
void3u fpN1_modP; // y[N] = x[N + 1] % p[N]
void2uI fp_mul_Unit; // fpN1_modP + fp_mul_UnitPre
bool isFullBit; // true if bitSize % uniSize == 0
bool isMont; // true if use Montgomery
PrimeMode primeMode;
bool isFastMod; // true if modulo is fast
/*
same fp_add, fp_sub if isFullBit
*/
void3u fp_addNC; // assume no carry if !isFullBit
void3u fp_subNC; // assume x > y
// for Montgomery
int2u fp_preInv;
// these two members are for mcl_fp_mont
Unit rp;
// z = montRed(xy)
void (*montRedPU)(Unit *z, const Unit *xy, const Unit *p, Unit rp);
// z = mont(x, y) = montRed(fpDbl_mulPre(x, y))
void (*montPU)(Unit *z, const Unit *x, const Unit *y, const Unit *p, Unit rp);
// require p
void3u fp_negP;
void2uOp fp_invOp;
void4u fp_addP;
void4u fp_subP;
void3u fpDbl_modP;
FpGenerator *fg;
/*
for FpDbl
*/
void3u fpDbl_add;
void3u fpDbl_sub;
void4u fpDbl_addP;
void4u fpDbl_subP;
void3u fpDbl_addNC;
void3u fpDbl_subNC;
/*
FpDbl <=> Fp
*/
void2u fpDbl_sqrPre;
void3u fpDbl_mulPre;
void2u fpDbl_mod;
/*
for Fp2 = F[u] / (u^2 + 1)
x = a + bu
*/
int xi_a; // xi = xi_a + u
void3u fp2_add;
void3u fp2_sub;
void3u fp2_mul;
void2u fp2_neg;
void2u fp2_inv;
void2u fp2_sqr;
void2u fp2_mul_xi;
Op()
: N(0), bitSize(0)
, fp_isZero(0), fp_clear(0), fp_copy(0)
, fp_neg(0), fp_sqr(0), fp_add(0), fp_sub(0), fp_mul(0)
, fp_mul_UnitPre(0)
, fpN1_modP(0)
, fp_mul_Unit(0)
, isFullBit(false)
, isMont(false)
, primeMode(PM_GENERIC)
, isFastMod(false)
, fp_addNC(0), fp_subNC(0)
, fp_preInv(0)
, rp(0), montRedPU(0), montPU(0)
, fp_negP(0), fp_invOp(0), fp_addP(0), fp_subP(0), fpDbl_modP(0)
, fg(createFpGenerator())
, fpDbl_add(0), fpDbl_sub(0)
, fpDbl_addP(0), fpDbl_subP(0)
, fpDbl_addNC(0), fpDbl_subNC(0)
, fpDbl_sqrPre(0), fpDbl_mulPre(0), fpDbl_mod(0)
, xi_a(0)
, fp2_add(0), fp2_sub(0), fp2_mul(0), fp2_neg(0)
, fp2_sqr(0), fp2_mul_xi(0)
{
}
~Op()
{
destroyFpGenerator(fg);
}
void fromMont(Unit* y, const Unit *x) const
{
/*
M(x, y) = xyR^-1
y = M(x, 1) = xR^-1
*/
fp_mul(y, x, one);
}
void toMont(Unit* y, const Unit *x) const
{
/*
y = M(x, R2) = xR^2 R^-1 = xR
*/
fp_mul(y, x, R2);
}
void init(const std::string& mstr, int base, size_t maxBitSize, Mode mode);
void initFp2(int xi_a);
static FpGenerator* createFpGenerator();
static void destroyFpGenerator(FpGenerator *fg);
private:
Op(const Op&);
void operator=(const Op&);
};
} } // mcl::fp