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/bn.h

359 lines
12 KiB

#pragma once
/**
@file
@brief C interface of 256/384-bit optimal ate pairing over BN curves
@author MITSUNARI Shigeo(@herumi)
@license modified new BSD license
http://opensource.org/licenses/BSD-3-Clause
*/
#ifndef MCLBN_FP_UNIT_SIZE
#error "define MCLBN_FP_UNIT_SIZE 4(, 6 or 8)"
#endif
#include <stdint.h> // for uint64_t, uint8_t
#include <stdlib.h> // for size_t
#if defined(_MSC_VER)
#ifdef MCLBN_DONT_EXPORT
#define MCLBN_DLL_API
#else
#ifdef MCLBN_DLL_EXPORT
#define MCLBN_DLL_API __declspec(dllexport)
#else
#define MCLBN_DLL_API __declspec(dllimport)
#endif
#endif
#ifndef MCLBN_NO_AUTOLINK
#if MCLBN_FP_UNIT_SIZE == 4
#pragma comment(lib, "mclbn256.lib")
#elif MCLBN_FP_UNIT_SIZE == 6
#pragma comment(lib, "mclbn384.lib")
#else
#pragma comment(lib, "mclbn512.lib")
#endif
#endif
#elif defined(__EMSCRIPTEN__) && !defined(MCLBN_DONT_EXPORT)
#define MCLBN_DLL_API __attribute__((used))
#elif defined(__wasm__) && !defined(MCLBN_DONT_EXPORT)
#define MCLBN_DLL_API __attribute__((visibility("default")))
#else
#define MCLBN_DLL_API
#endif
#ifdef __EMSCRIPTEN__
// avoid 64-bit integer
#define mclSize unsigned int
#define mclInt int
#else
// use #define for cgo
#define mclSize size_t
#define mclInt int64_t
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef MCLBN_NOT_DEFINE_STRUCT
typedef struct mclBnFr mclBnFr;
typedef struct mclBnG1 mclBnG1;
typedef struct mclBnG2 mclBnG2;
typedef struct mclBnGT mclBnGT;
#else
typedef struct {
uint64_t d[MCLBN_FP_UNIT_SIZE];
} mclBnFr;
typedef struct {
uint64_t d[MCLBN_FP_UNIT_SIZE * 3];
} mclBnG1;
typedef struct {
uint64_t d[MCLBN_FP_UNIT_SIZE * 2 * 3];
} mclBnG2;
typedef struct {
uint64_t d[MCLBN_FP_UNIT_SIZE * 12];
} mclBnGT;
#endif
#include <mcl/curve_type.h>
#define MCLBN_IO_SERIALIZE_HEX_STR 2048
// for backword compatibility
enum {
mclBn_CurveFp254BNb = 0,
mclBn_CurveFp382_1 = 1,
mclBn_CurveFp382_2 = 2,
mclBn_CurveFp462 = 3,
mclBn_CurveSNARK1 = 4,
mclBls12_CurveFp381 = 5
};
/*
init library
@param curve [in] type of bn curve
@param maxUnitSize [in] MCLBN_FP_UNIT_SIZE
return 0 if success else -1
curve = BN254/BN_SNARK1 is allowed if maxUnitSize = 4
curve = BN381_1/BN381_2/BLS12_381 are allowed if maxUnitSize = 6
This parameter is used to detect a library compiled with different MCLBN_FP_UNIT_SIZE for safety.
@note not threadsafe
@note BN_init is used in libeay32
*/
MCLBN_DLL_API int mclBn_init(int curve, int maxUnitSize);
/*
pairing : G1 x G2 -> GT
#G1 = #G2 = r
G1 is a curve defined on Fp
serialized size of elements
|Fr| |Fp|
BN254 32 32
BN381 48 48
BLS12_381 32 48
BN462 58 58
|G1| = |Fp|
|G2| = |G1| * 2
|GT| = |G1| * 12
*/
/*
return the num of Unit(=uint64_t) to store Fr
*/
MCLBN_DLL_API int mclBn_getOpUnitSize(void);
/*
return bytes for serialized G1(=Fp)
*/
MCLBN_DLL_API int mclBn_getG1ByteSize(void);
/*
return bytes for serialized Fr
*/
MCLBN_DLL_API int mclBn_getFrByteSize(void);
/*
return decimal string of the order of the curve(=the characteristic of Fr)
return str(buf) if success
*/
MCLBN_DLL_API mclSize mclBn_getCurveOrder(char *buf, mclSize maxBufSize);
/*
return decimal string of the characteristic of Fp
return str(buf) if success
*/
MCLBN_DLL_API mclSize mclBn_getFieldOrder(char *buf, mclSize maxBufSize);
////////////////////////////////////////////////
/*
deserialize
return read size if success else 0
*/
MCLBN_DLL_API mclSize mclBnFr_deserialize(mclBnFr *x, const void *buf, mclSize bufSize);
MCLBN_DLL_API mclSize mclBnG1_deserialize(mclBnG1 *x, const void *buf, mclSize bufSize);
MCLBN_DLL_API mclSize mclBnG2_deserialize(mclBnG2 *x, const void *buf, mclSize bufSize);
MCLBN_DLL_API mclSize mclBnGT_deserialize(mclBnGT *x, const void *buf, mclSize bufSize);
/*
serialize
return written byte if sucess else 0
*/
MCLBN_DLL_API mclSize mclBnFr_serialize(void *buf, mclSize maxBufSize, const mclBnFr *x);
MCLBN_DLL_API mclSize mclBnG1_serialize(void *buf, mclSize maxBufSize, const mclBnG1 *x);
MCLBN_DLL_API mclSize mclBnG2_serialize(void *buf, mclSize maxBufSize, const mclBnG2 *x);
MCLBN_DLL_API mclSize mclBnGT_serialize(void *buf, mclSize maxBufSize, const mclBnGT *x);
/*
set string
ioMode
10 : decimal number
16 : hexadecimal number
MCLBN_IO_SERIALIZE_HEX_STR : hex string of serialized data
return 0 if success else -1
*/
MCLBN_DLL_API int mclBnFr_setStr(mclBnFr *x, const char *buf, mclSize bufSize, int ioMode);
MCLBN_DLL_API int mclBnG1_setStr(mclBnG1 *x, const char *buf, mclSize bufSize, int ioMode);
MCLBN_DLL_API int mclBnG2_setStr(mclBnG2 *x, const char *buf, mclSize bufSize, int ioMode);
MCLBN_DLL_API int mclBnGT_setStr(mclBnGT *x, const char *buf, mclSize bufSize, int ioMode);
/*
buf is terminated by '\0'
return strlen(buf) if sucess else 0
*/
MCLBN_DLL_API mclSize mclBnFr_getStr(char *buf, mclSize maxBufSize, const mclBnFr *x, int ioMode);
MCLBN_DLL_API mclSize mclBnG1_getStr(char *buf, mclSize maxBufSize, const mclBnG1 *x, int ioMode);
MCLBN_DLL_API mclSize mclBnG2_getStr(char *buf, mclSize maxBufSize, const mclBnG2 *x, int ioMode);
MCLBN_DLL_API mclSize mclBnGT_getStr(char *buf, mclSize maxBufSize, const mclBnGT *x, int ioMode);
// set zero
MCLBN_DLL_API void mclBnFr_clear(mclBnFr *x);
// set x to y
MCLBN_DLL_API void mclBnFr_setInt(mclBnFr *y, mclInt x);
MCLBN_DLL_API void mclBnFr_setInt32(mclBnFr *y, int x);
// mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r
MCLBN_DLL_API int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize);
// return 1 if true and 0 otherwise
MCLBN_DLL_API int mclBnFr_isValid(const mclBnFr *x);
MCLBN_DLL_API int mclBnFr_isEqual(const mclBnFr *x, const mclBnFr *y);
MCLBN_DLL_API int mclBnFr_isZero(const mclBnFr *x);
MCLBN_DLL_API int mclBnFr_isOne(const mclBnFr *x);
#ifndef MCL_DONT_USE_CSRPNG
// return 0 if success
MCLBN_DLL_API int mclBnFr_setByCSPRNG(mclBnFr *x);
#endif
// hash(s) and set x
// return 0 if success
MCLBN_DLL_API int mclBnFr_setHashOf(mclBnFr *x, const void *buf, mclSize bufSize);
MCLBN_DLL_API void mclBnFr_neg(mclBnFr *y, const mclBnFr *x);
MCLBN_DLL_API void mclBnFr_inv(mclBnFr *y, const mclBnFr *x);
MCLBN_DLL_API void mclBnFr_sqr(mclBnFr *y, const mclBnFr *x);
MCLBN_DLL_API void mclBnFr_add(mclBnFr *z, const mclBnFr *x, const mclBnFr *y);
MCLBN_DLL_API void mclBnFr_sub(mclBnFr *z, const mclBnFr *x, const mclBnFr *y);
MCLBN_DLL_API void mclBnFr_mul(mclBnFr *z, const mclBnFr *x, const mclBnFr *y);
MCLBN_DLL_API void mclBnFr_div(mclBnFr *z, const mclBnFr *x, const mclBnFr *y);
////////////////////////////////////////////////
// set zero
MCLBN_DLL_API void mclBnG1_clear(mclBnG1 *x);
// return 1 if true and 0 otherwise
MCLBN_DLL_API int mclBnG1_isValid(const mclBnG1 *x);
MCLBN_DLL_API int mclBnG1_isEqual(const mclBnG1 *x, const mclBnG1 *y);
MCLBN_DLL_API int mclBnG1_isZero(const mclBnG1 *x);
/*
return 1 if x has a correct order
x is valid point of G1 if and only if
mclBnG1_isValid() is true, which contains mclBnG1_isValidOrder() if mclBn_verifyOrderG1(true)
mclBnG1_isValid() && mclBnG1_isValidOrder() is true if mclBn_verifyOrderG1(false)
*/
MCLBN_DLL_API int mclBnG1_isValidOrder(const mclBnG1 *x);
MCLBN_DLL_API int mclBnG1_hashAndMapTo(mclBnG1 *x, const void *buf, mclSize bufSize);
MCLBN_DLL_API void mclBnG1_neg(mclBnG1 *y, const mclBnG1 *x);
MCLBN_DLL_API void mclBnG1_dbl(mclBnG1 *y, const mclBnG1 *x);
MCLBN_DLL_API void mclBnG1_normalize(mclBnG1 *y, const mclBnG1 *x);
MCLBN_DLL_API void mclBnG1_add(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y);
MCLBN_DLL_API void mclBnG1_sub(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y);
MCLBN_DLL_API void mclBnG1_mul(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y);
/*
constant time mul
*/
MCLBN_DLL_API void mclBnG1_mulCT(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y);
////////////////////////////////////////////////
// set zero
MCLBN_DLL_API void mclBnG2_clear(mclBnG2 *x);
// return 1 if true and 0 otherwise
MCLBN_DLL_API int mclBnG2_isValid(const mclBnG2 *x);
MCLBN_DLL_API int mclBnG2_isEqual(const mclBnG2 *x, const mclBnG2 *y);
MCLBN_DLL_API int mclBnG2_isZero(const mclBnG2 *x);
// return 1 if x has a correct order
MCLBN_DLL_API int mclBnG2_isValidOrder(const mclBnG2 *x);
MCLBN_DLL_API int mclBnG2_hashAndMapTo(mclBnG2 *x, const void *buf, mclSize bufSize);
// return written size if sucess else 0
MCLBN_DLL_API void mclBnG2_neg(mclBnG2 *y, const mclBnG2 *x);
MCLBN_DLL_API void mclBnG2_dbl(mclBnG2 *y, const mclBnG2 *x);
MCLBN_DLL_API void mclBnG2_normalize(mclBnG2 *y, const mclBnG2 *x);
MCLBN_DLL_API void mclBnG2_add(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y);
MCLBN_DLL_API void mclBnG2_sub(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y);
MCLBN_DLL_API void mclBnG2_mul(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y);
/*
constant time mul
*/
MCLBN_DLL_API void mclBnG2_mulCT(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y);
////////////////////////////////////////////////
// set zero
MCLBN_DLL_API void mclBnGT_clear(mclBnGT *x);
// set x to y
MCLBN_DLL_API void mclBnGT_setInt(mclBnGT *y, mclInt x);
MCLBN_DLL_API void mclBnGT_setInt32(mclBnGT *y, int x);
// return 1 if true and 0 otherwise
MCLBN_DLL_API int mclBnGT_isEqual(const mclBnGT *x, const mclBnGT *y);
MCLBN_DLL_API int mclBnGT_isZero(const mclBnGT *x);
MCLBN_DLL_API int mclBnGT_isOne(const mclBnGT *x);
MCLBN_DLL_API void mclBnGT_neg(mclBnGT *y, const mclBnGT *x);
MCLBN_DLL_API void mclBnGT_inv(mclBnGT *y, const mclBnGT *x);
MCLBN_DLL_API void mclBnGT_sqr(mclBnGT *y, const mclBnGT *x);
MCLBN_DLL_API void mclBnGT_add(mclBnGT *z, const mclBnGT *x, const mclBnGT *y);
MCLBN_DLL_API void mclBnGT_sub(mclBnGT *z, const mclBnGT *x, const mclBnGT *y);
MCLBN_DLL_API void mclBnGT_mul(mclBnGT *z, const mclBnGT *x, const mclBnGT *y);
MCLBN_DLL_API void mclBnGT_div(mclBnGT *z, const mclBnGT *x, const mclBnGT *y);
/*
pow for all elements of Fp12
*/
MCLBN_DLL_API void mclBnGT_powGeneric(mclBnGT *z, const mclBnGT *x, const mclBnFr *y);
/*
pow for only {x|x^r = 1} in Fp12 by GLV method
the value generated by pairing satisfies the condition
*/
MCLBN_DLL_API void mclBnGT_pow(mclBnGT *z, const mclBnGT *x, const mclBnFr *y);
MCLBN_DLL_API void mclBn_pairing(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y);
MCLBN_DLL_API void mclBn_finalExp(mclBnGT *y, const mclBnGT *x);
MCLBN_DLL_API void mclBn_millerLoop(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y);
// return precomputedQcoeffSize * sizeof(Fp6) / sizeof(uint64_t)
MCLBN_DLL_API int mclBn_getUint64NumToPrecompute(void);
// allocate Qbuf[MCLBN_getUint64NumToPrecompute()] before calling this
MCLBN_DLL_API void mclBn_precomputeG2(uint64_t *Qbuf, const mclBnG2 *Q);
MCLBN_DLL_API void mclBn_precomputedMillerLoop(mclBnGT *f, const mclBnG1 *P, const uint64_t *Qbuf);
MCLBN_DLL_API void mclBn_precomputedMillerLoop2(mclBnGT *f, const mclBnG1 *P1, const uint64_t *Q1buf, const mclBnG1 *P2, const uint64_t *Q2buf);
MCLBN_DLL_API void mclBn_precomputedMillerLoop2mixed(mclBnGT *f, const mclBnG1 *P1, const mclBnG2 *Q1, const mclBnG1 *P2, const uint64_t *Q2buf);
/*
Lagrange interpolation
recover out = y(0) by { (xVec[i], yVec[i]) }
return 0 if success else -1
@note k >= 2, xVec[i] != 0, xVec[i] != xVec[j] for i != j
*/
MCLBN_DLL_API int mclBn_FrLagrangeInterpolation(mclBnFr *out, const mclBnFr *xVec, const mclBnFr *yVec, mclSize k);
MCLBN_DLL_API int mclBn_G1LagrangeInterpolation(mclBnG1 *out, const mclBnFr *xVec, const mclBnG1 *yVec, mclSize k);
MCLBN_DLL_API int mclBn_G2LagrangeInterpolation(mclBnG2 *out, const mclBnFr *xVec, const mclBnG2 *yVec, mclSize k);
/*
evaluate polynomial
out = f(x) = c[0] + c[1] * x + c[2] * x^2 + ... + c[cSize - 1] * x^(cSize - 1)
@note cSize >= 2
*/
MCLBN_DLL_API int mclBn_FrEvaluatePolynomial(mclBnFr *out, const mclBnFr *cVec, mclSize cSize, const mclBnFr *x);
MCLBN_DLL_API int mclBn_G1EvaluatePolynomial(mclBnG1 *out, const mclBnG1 *cVec, mclSize cSize, const mclBnFr *x);
MCLBN_DLL_API int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, mclSize cSize, const mclBnFr *x);
/*
verify whether a point of an elliptic curve has order r
This api affetcs setStr(), deserialize() for G2 on BN or G1/G2 on BLS12
@param doVerify [in] does not verify if zero(default 1)
*/
MCLBN_DLL_API void mclBn_verifyOrderG1(int doVerify);
MCLBN_DLL_API void mclBn_verifyOrderG2(int doVerify);
#ifdef __cplusplus
}
#endif