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/operator.hpp

77 lines
2.7 KiB

#pragma once
/**
@file
@brief operator class
@author MITSUNARI Shigeo(@herumi)
@license modified new BSD license
http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/op.hpp>
#include <mcl/util.hpp>
#ifdef _MSC_VER
#ifndef MCL_FORCE_INLINE
#define MCL_FORCE_INLINE __forceinline
#endif
#pragma warning(push)
#pragma warning(disable : 4714)
#else
#ifndef MCL_FORCE_INLINE
#define MCL_FORCE_INLINE __attribute__((always_inline))
#endif
#endif
namespace mcl { namespace fp {
template<class T>
struct Empty {};
/*
T must have add, sub, mul, inv, neg
*/
template<class T, class E = Empty<T> >
struct Operator : E {
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); }
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); }
template<class S> friend MCL_FORCE_INLINE T operator+(const T& a, const S& b) { T c; T::add(c, a, b); return c; }
template<class S> friend MCL_FORCE_INLINE T operator-(const T& a, const S& b) { T c; T::sub(c, a, b); return c; }
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); }
template<class S> friend MCL_FORCE_INLINE T operator*(const T& a, const S& b) { T c; T::mul(c, a, b); return c; }
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); }
friend MCL_FORCE_INLINE void div(T& c, const T& a, const T& b) { T t; T::inv(t, b); T::mul(c, a, t); }
friend MCL_FORCE_INLINE T operator/(const T& a, const T& b) { T c; T::inv(c, b); c *= a; return c; }
MCL_FORCE_INLINE T operator-() const { T c; T::neg(c, static_cast<const T&>(*this)); return c; }
template<class tag2, size_t maxBitSize2, template<class _tag, size_t _maxBitSize> class FpT>
static void pow(T& z, const T& x, const FpT<tag2, maxBitSize2>& y)
{
fp::Block b;
y.getBlock(b);
powArray(z, x, b.p, b.n, false);
}
static void pow(T& z, const T& x, int y)
{
const Unit u = abs(y);
powArray(z, x, &u, 1, y < 0);
}
static void pow(T& z, const T& x, const mpz_class& y)
{
powArray(z, x, gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0);
}
private:
static void powArray(T& z, const T& x, const Unit *y, size_t yn, bool isNegative)
{
T tmp;
const T *px = &x;
if (&z == &x) {
tmp = x;
px = &tmp;
}
z = 1;
fp::powGeneric(z, *px, y, yn, T::mul, T::sqr);
if (isNegative) {
T::inv(z, z);
}
}
};
} } // mcl::fp