diff --git a/api.md b/api.md
new file mode 100644
index 0000000..1c0f4ea
--- /dev/null
+++ b/api.md
@@ -0,0 +1,538 @@
+# C API
+
+## Minimum sample
+
+[sample/pairing_c.c](sample/pairing_c.c) is a sample of how to use BLS12-381 pairing.
+
+```
+cd mcl
+make -j4
+make bin/pairing_c.exe && bin/pairing_c.exe
+```
+
+## Header and libraries
+
+To use BLS12-381, include `mcl/bn_c384_256.h` and link
+- libmclbn384_256.{a,so}
+- libmcl.{a,so} ; core library
+
+`384_256` means the max bit size of `Fp` is 384 and that size of `Fr` is 256.
+
+## Notation
+
+The elliptic equation of a curve E is `E: y^2 = x^3 + b`.
+
+- `Fp` ; a finite field of a prime order `p`, where curves is defined over.
+- `Fr` ; a finite field of a prime order `r`.
+- `Fp2` ; the field extension over Fp with degree 2. Fp[i] / (i^2 + 1).
+- `Fp6` ; the field extension over Fp2 with degree 3. Fp2[v] / (v^3 - Xi) where Xi = i + 1.
+- `Fp12` ; the field extension over Fp6 with degree 2. Fp6[w] / (w^2 - v).
+- `G1` ; the cyclic subgroup of E(Fp).
+- `G2` ; the cyclic subgroup of the inverse image of E'(Fp^2) under a twisting isomorphism from E' to E.
+- `GT` ; the cyclie subgroup of Fp12.
+ - `G1`, `G2` and `GT` have the order `r`.
+
+The pairing e: G1 x G2 -> GT is the optimal ate pairing.
+
+mcl treats `G1` and `G2` as an additive group and `GT` as a multiplicative group.
+
+- `mclSize` ; `unsigned int` if WebAssembly else `size_t`
+
+### Curve Parameter
+r = |G1| = |G2| = |GT|
+
+curveType | b| r and p |
+------------|--|------------------|
+BN254 | 2|r = 0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d
p = 0x2523648240000001ba344d80000000086121000000000013a700000000000013 |
+BLS12-381 | 4|r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab |
+BN381 | 2|r = 0x240026400f3d82b2e42de125b00158405b710818ac000007e0042f008e3e00000000001080046200000000000000000d
p = 0x240026400f3d82b2e42de125b00158405b710818ac00000840046200950400000000001380052e000000000000000013 |
+
+## Structures
+
+### `mclBnFp`
+This is a struct of `Fp`. The value is stored as Montgomery representation.
+
+### `mclBnFr`
+This is a struct of `Fr`. The value is stored as Montgomery representation.
+
+### `mclBnFp2`
+This is a struct of `Fp2` which has a member `mclBnFp d[2]`.
+
+An element `x` of `Fp2` is represented as `x = d[0] + d[1] i` where `i^2 = -1`.
+
+### `mclBnG1`
+This is a struct of `G1` which has three members `x`, `y`, `z` of type `mclBnFp`.
+
+An element `P` of `G1` is represented as `P = [x:y:z]` of a Jacobi coordinate.
+
+### `mclBnG2`
+This is a struct of `G2` which has three members `x`, `y`, `z` of type `mclBnFp2`.
+
+An element `Q` of `G2` is represented as `Q = [x:y:z]` of a Jacobi coordinate.
+
+### `mclBnGT`
+
+This is a struct of `GT` which has a member `mclBnFp d[12]`.
+
+### sizeof
+
+library |MCLBN_FR_UNIT_SIZE|MCLBN_FP_UNIT_SIZE|sizeof Fr|sizeof Fp|
+------------------|------------------|------------------|---------|---------|
+libmclbn256.a | 4 | 4 | 32 | 32 |
+libmclbn384_256.a | 4 | 6 | 32 | 48 |
+libmclbn384.a | 6 | 6 | 48 | 48 |
+
+## Thread safety
+All functions except for initialization and changing global setting are thread-safe.
+
+## Initialization
+
+Initialize mcl library. Call this function at first before calling the other functions.
+
+```
+int mclBn_init(int curve, int compiledTimeVar);
+```
+
+- `curve` ; specify the curve type
+ - MCL_BN254 ; BN254 (a little faster if including `mcl/bn_c256.h` and linking `libmclbn256.{a,so}`)
+ - MCL_BN_SNARK1 ; the same parameter used in libsnark
+ - MCL_BLS12_381 ; BLS12-381
+ - MCL_BN381_1 ; BN381 (include `mcl/bn_c384.h` and link `libmclbn384.{a,so}`)
+- `compiledTimeVar` ; set `MCLBN_COMPILED_TIME_VAR`, which macro is used to make sure that
+the values are the same when the library is built and used.
+- return 0 if success.
+- This is not thread safe.
+
+## Global setting
+
+### Control to verify that a point of the elliptic curve has the order `r`.
+
+This function affects `setStr()` and `deserialize()` for G1/G2.
+```
+void mclBn_verifyOrderG1(int doVerify);
+void mclBn_verifyOrderG2(int doVerify);
+```
+- verify if `doVerify` is 1 or does not. The default parameter is 1.
+- The cost of verification is not small, so set `doVerify = 0` carefully if necessary.
+- This is not thread safe.
+
+## Setter / Getter
+
+### Clear
+Set `x` is zero.
+```
+void mclBnFr_clear(mclBnFr *x);
+void mclBnFp_clear(mclBnFp *x);
+void mclBnFp2_clear(mclBnFp2 *x);
+void mclBnG1_clear(mclBnG1 *x);
+void mclBnG2_clear(mclBnG2 *x);
+void mclBnGT_clear(mclBnGT *x);
+```
+
+### Set `x` to `y`.
+```
+void mclBnFp_setInt(mclBnFp *y, mclInt x);
+void mclBnFr_setInt(mclBnFr *y, mclInt x);
+void mclBnGT_setInt(mclBnGT *y, mclInt x);
+```
+
+### Set `buf[0..bufSize-1]` to `x` with masking according to the following way.
+```
+int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize);
+int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize);
+```
+1. set x = buf[0..bufSize-1] as little endian
+2. x &= (1 << bitLen(r)) - 1
+3. if (x >= r) x &= (1 << (bitLen(r) - 1)) - 1
+
+- always return 0
+
+### Set (`buf[0..bufSize-1]` mod `p` or `r`) to `x`.
+```
+int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize);
+int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize);
+```
+- return 0 if bufSize <= (sizeof(*x) * 8 * 2) else -1
+
+### Get little endian byte sequence corresponding `buf[0..maxBufSize-1]` to `x`
+```
+mclSize mclBnFr_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFr *x);
+mclSize mclBnFp_getLittleEndian(void *buf, mclSize maxBufSize, const mclBnFp *x);
+```
+- write `x` to `buf` as little endian
+- return the written size if sucess else 0
+- NOTE: `buf[0] = 0` and return 1 if `x` is zero.
+
+### Serialization
+### Serialize
+```
+mclSize mclBnFr_serialize(void *buf, mclSize maxBufSize, const mclBnFr *x);
+mclSize mclBnG1_serialize(void *buf, mclSize maxBufSize, const mclBnG1 *x);
+mclSize mclBnG2_serialize(void *buf, mclSize maxBufSize, const mclBnG2 *x);
+mclSize mclBnGT_serialize(void *buf, mclSize maxBufSize, const mclBnGT *x);
+mclSize mclBnFp_serialize(void *buf, mclSize maxBufSize, const mclBnFp *x);
+mclSize mclBnFp2_serialize(void *buf, mclSize maxBufSize, const mclBnFp2 *x);
+```
+- serialize `x` into `buf[0..maxBufSize-1]`
+- return written byte size if success else 0
+
+### Serialization format
+- `Fp`(resp. `Fr`) ; a little endian byte sequence with a fixed size
+ - the size is the return value of `mclBn_getFpByteSize()` (resp. `mclBn_getFpByteSize()`).
+- `G1` ; a compressed fixed size
+ - the size is equal to `mclBn_getG1ByteSize()` (=`mclBn_getFpByteSize()`).
+- `G2` ; a compressed fixed size
+ - the size is equal to `mclBn_getG1ByteSize() * 2`.
+
+pseudo-code to serialize of `P` of `G1` (resp. `G2`)
+```
+size = mclBn_getG1ByteSize() # resp. mclBn_getG1ByteSize() * 2
+if P is zero:
+ return [0] * size
+else:
+ P = P.normalize()
+ s = P.x.serialize()
+ # x in Fp2 is odd <=> x.a is odd
+ if P.y is odd: # resp. P.y.d[0] is odd
+ s[byte-length(s) - 1] |= 0x80
+ return s
+```
+
+### Ethereum serialization mode for BLS12-381 (experimental)
+```
+void mclBn_setETHserialization(int ETHserialization);
+```
+- serialize according to [ETH2.0 serialization of BLS12-381](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/bls_signature.md#point-representations) if BLS12-381 is used and `ETHserialization = 1` (default 0).
+
+### Deserialize
+```
+mclSize mclBnFr_deserialize(mclBnFr *x, const void *buf, mclSize bufSize);
+mclSize mclBnG1_deserialize(mclBnG1 *x, const void *buf, mclSize bufSize);
+mclSize mclBnG2_deserialize(mclBnG2 *x, const void *buf, mclSize bufSize);
+mclSize mclBnGT_deserialize(mclBnGT *x, const void *buf, mclSize bufSize);
+mclSize mclBnFp_deserialize(mclBnFp *x, const void *buf, mclSize bufSize);
+mclSize mclBnFp2_deserialize(mclBnFp2 *x, const void *buf, mclSize bufSize);
+```
+- deserialize `x` from `buf[0..bufSize-1]`
+- return read size if success else 0
+
+## String conversion
+### Get string
+```
+mclSize mclBnFr_getStr(char *buf, mclSize maxBufSize, const mclBnFr *x, int ioMode);
+mclSize mclBnG1_getStr(char *buf, mclSize maxBufSize, const mclBnG1 *x, int ioMode);
+mclSize mclBnG2_getStr(char *buf, mclSize maxBufSize, const mclBnG2 *x, int ioMode);
+mclSize mclBnGT_getStr(char *buf, mclSize maxBufSize, const mclBnGT *x, int ioMode);
+mclSize mclBnFp_getStr(char *buf, mclSize maxBufSize, const mclBnFp *x, int ioMode);
+```
+- write `x` to `buf` according to `ioMode`
+- `ioMode`
+ - 10 ; decimal number
+ - 16 ; hexadecimal number
+ - `MCLBN_IO_EC_PROJ` ; output as Jacobi coordinate
+- return `strlen(buf)` if success else 0.
+
+The meaning of the output of `G1`.
+- `0` ; infinity
+- `1 ` ; affine coordinate
+- `4 ` ; Jacobi coordinate
+- the element `` of `G2` outputs `d[0] d[1]`.
+
+### Set string
+```
+int mclBnFr_setStr(mclBnFr *x, const char *buf, mclSize bufSize, int ioMode);
+int mclBnG1_setStr(mclBnG1 *x, const char *buf, mclSize bufSize, int ioMode);
+int mclBnG2_setStr(mclBnG2 *x, const char *buf, mclSize bufSize, int ioMode);
+int mclBnGT_setStr(mclBnGT *x, const char *buf, mclSize bufSize, int ioMode);
+int mclBnFp_setStr(mclBnFp *x, const char *buf, mclSize bufSize, int ioMode);
+```
+- set `buf[0..bufSize-1]` to `x` accoring to `ioMode`
+- return 0 if success else -1
+
+If you want to use the same generators of BLS12-381 with [zkcrypto](https://github.com/zkcrypto/pairing/tree/master/src/bls12_381#g2) then,
+
+```
+mclBnG1 P;
+mclBnG1_setStr(&P, "1 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569", 10);
+
+mclBnG2 Q;
+mclBnG2_setStr(&Q, "1 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582");
+```
+
+
+## Set random value
+Set `x` by cryptographically secure pseudo random number generator.
+```
+int mclBnFr_setByCSPRNG(mclBnFr *x);
+int mclBnFp_setByCSPRNG(mclBnFp *x);
+```
+
+### Change random generator function
+```
+void mclBn_setRandFunc(
+ void *self,
+ unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)
+);
+```
+- `self` ; user-defined pointer
+- `readFunc` ; user-defined function, which writes random `bufSize` bytes to `buf` and returns `bufSize` if success else returns 0.
+ - `readFunc` must be thread-safe.
+- Set the default random function if `self == 0` and `readFunc == 0`.
+- This is not thread safe.
+
+## Arithmetic operations
+### neg / inv / sqr / add / sub / mul / div of `Fr`, `Fp`, `Fp2`, `GT`.
+```
+void mclBnFr_neg(mclBnFr *y, const mclBnFr *x);
+void mclBnFr_inv(mclBnFr *y, const mclBnFr *x);
+void mclBnFr_sqr(mclBnFr *y, const mclBnFr *x);
+void mclBnFr_add(mclBnFr *z, const mclBnFr *x, const mclBnFr *y);
+void mclBnFr_sub(mclBnFr *z, const mclBnFr *x, const mclBnFr *y);
+void mclBnFr_mul(mclBnFr *z, const mclBnFr *x, const mclBnFr *y);
+void mclBnFr_div(mclBnFr *z, const mclBnFr *x, const mclBnFr *y);
+
+void mclBnFp_neg(mclBnFp *y, const mclBnFp *x);
+void mclBnFp_inv(mclBnFp *y, const mclBnFp *x);
+void mclBnFp_sqr(mclBnFp *y, const mclBnFp *x);
+void mclBnFp_add(mclBnFp *z, const mclBnFp *x, const mclBnFp *y);
+void mclBnFp_sub(mclBnFp *z, const mclBnFp *x, const mclBnFp *y);
+void mclBnFp_mul(mclBnFp *z, const mclBnFp *x, const mclBnFp *y);
+void mclBnFp_div(mclBnFp *z, const mclBnFp *x, const mclBnFp *y);
+
+void mclBnFp2_neg(mclBnFp2 *y, const mclBnFp2 *x);
+void mclBnFp2_inv(mclBnFp2 *y, const mclBnFp2 *x);
+void mclBnFp2_sqr(mclBnFp2 *y, const mclBnFp2 *x);
+void mclBnFp2_add(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y);
+void mclBnFp2_sub(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y);
+void mclBnFp2_mul(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y);
+void mclBnFp2_div(mclBnFp2 *z, const mclBnFp2 *x, const mclBnFp2 *y);
+
+void mclBnGT_inv(mclBnGT *y, const mclBnGT *x); // y = a - bw for x = a + bw where Fp12 = Fp6[w]
+void mclBnGT_sqr(mclBnGT *y, const mclBnGT *x);
+void mclBnGT_mul(mclBnGT *z, const mclBnGT *x, const mclBnGT *y);
+void mclBnGT_div(mclBnGT *z, const mclBnGT *x, const mclBnGT *y);
+```
+- use `mclBnGT_invGeneric` for an element in Fp12 - GT.
+
+- NOTE: The following functions does NOT return a GT element because GT is multiplicative group.
+
+```
+void mclBnGT_neg(mclBnGT *y, const mclBnGT *x);
+void mclBnGT_add(mclBnGT *z, const mclBnGT *x, const mclBnGT *y);
+void mclBnGT_sub(mclBnGT *z, const mclBnGT *x, const mclBnGT *y);
+```
+
+### Square root of `x`.
+```
+int mclBnFr_squareRoot(mclBnFr *y, const mclBnFr *x);
+int mclBnFp_squareRoot(mclBnFp *y, const mclBnFp *x);
+int mclBnFp2_squareRoot(mclBnFp2 *y, const mclBnFp2 *x);
+```
+- `y` is one of square root of `x` if `y` exists.
+- return 0 if success else -1
+
+### add / sub / dbl / neg for `G1` and `G2`.
+```
+void mclBnG1_neg(mclBnG1 *y, const mclBnG1 *x);
+void mclBnG1_dbl(mclBnG1 *y, const mclBnG1 *x);
+void mclBnG1_add(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y);
+void mclBnG1_sub(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y);
+
+void mclBnG2_neg(mclBnG2 *y, const mclBnG2 *x);
+void mclBnG2_dbl(mclBnG2 *y, const mclBnG2 *x);
+void mclBnG2_add(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y);
+void mclBnG2_sub(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y);
+```
+
+### Convert a point from Jacobi coordinate to affine.
+```
+void mclBnG1_normalize(mclBnG1 *y, const mclBnG1 *x);
+void mclBnG2_normalize(mclBnG2 *y, const mclBnG2 *x);
+```
+- convert `[x:y:z]` to `[x:y:1]` if `z != 0` else `[*:*:0]`
+
+### scalar multiplication
+```
+void mclBnG1_mul(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y);
+void mclBnG2_mul(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y);
+void mclBnGT_pow(mclBnGT *z, const mclBnGT *x, const mclBnFr *y);
+```
+- z = x * y for G1 / G2
+- z = pow(x, y) for GT
+
+- use `mclBnGT_powGeneric` for an element in Fp12 - GT.
+
+### multi scalar multiplication
+```
+void mclBnG1_mulVec(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y, mclSize n);
+void mclBnG2_mulVec(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y, mclSize n);
+void mclBnGT_powVec(mclBnGT *z, const mclBnGT *x, const mclBnFr *y, mclSize n);
+```
+- z = sum_{i=0}^{n-1} mul(x[i], y[i]) for G1 / G2.
+- z = prod_{i=0}^{n-1} pow(x[i], y[i]) for GT.
+
+## hash and mapTo functions
+### Set hash of `buf[0..bufSize-1]` to `x`
+```
+int mclBnFr_setHashOf(mclBnFr *x, const void *buf, mclSize bufSize);
+int mclBnFp_setHashOf(mclBnFp *x, const void *buf, mclSize bufSize);
+```
+- always return 0
+- use SHA-256 if sizeof(*x) <= 256 else SHA-512
+- set accoring to the same way as `setLittleEndian`
+ - support the other wasy if you want in the future
+
+### map `x` to G1 / G2.
+```
+int mclBnFp_mapToG1(mclBnG1 *y, const mclBnFp *x);
+int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x);
+```
+- See `struct MapTo` in `mcl/bn.hpp` for the detail of the algorithm.
+- return 0 if success else -1
+
+### hash and map to G1 / G2.
+```
+int mclBnG1_hashAndMapTo(mclBnG1 *x, const void *buf, mclSize bufSize);
+int mclBnG2_hashAndMapTo(mclBnG2 *x, const void *buf, mclSize bufSize);
+```
+- Combine `setHashOf` and `mapTo` functions
+
+## Pairing operations
+The pairing function `e(P, Q)` is consist of two parts:
+ - `MillerLoop(P, Q)`
+ - `finalExp(x)`
+
+`finalExp` satisfies the following properties:
+ - `e(P, Q) = finalExp(MillerLoop(P, Q))`
+ - `e(P1, Q1) e(P2, Q2) = finalExp(MillerLoop(P1, Q1) MillerLoop(P2, Q2))`
+
+### pairing
+```
+void mclBn_pairing(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y);
+```
+### millerLoop
+```
+void mclBn_millerLoop(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y);
+```
+### finalExp
+```
+void mclBn_finalExp(mclBnGT *y, const mclBnGT *x);
+```
+
+## Variants of MillerLoop
+### multi pairing
+```
+void mclBn_millerLoopVec(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y, mclSize n);
+```
+- This function is for multi-pairing
+ - computes prod_{i=0}^{n-1} MillerLoop(x[i], y[i])
+ - prod_{i=0}^{n-1} e(x[i], y[i]) = finalExp(prod_{i=0}^{n-1} MillerLoop(x[i], y[i]))
+
+### pairing for a fixed point of G2
+```
+int mclBn_getUint64NumToPrecompute(void);
+void mclBn_precomputeG2(uint64_t *Qbuf, const mclBnG2 *Q);
+void mclBn_precomputedMillerLoop(mclBnGT *f, const mclBnG1 *P, const uint64_t *Qbuf);
+```
+These functions is the same computation of `pairing(P, Q);` as the followings:
+```
+uint64_t *Qbuf = (uint64_t*)malloc(mclBn_getUint64NumToPrecompute() * sizeof(uint64_t));
+mclBn_precomputeG2(Qbuf, Q); // precomputing of Q
+mclBn_precomputedMillerLoop(f, P, Qbuf); // pairing of any P of G1 and the fixed Q
+free(p);
+```
+
+```
+void mclBn_precomputedMillerLoop2(
+ mclBnGT *f,
+ const mclBnG1 *P1, const uint64_t *Q1buf,
+ const mclBnG1 *P2, const uint64_t *Q2buf
+);
+```
+- compute `MillerLoop(P1, Q1buf) * MillerLoop(P2, Q2buf)`
+
+
+```
+void mclBn_precomputedMillerLoop2mixed(
+ mclBnGT *f,
+ const mclBnG1 *P1, const mclBnG2 *Q1,
+ const mclBnG1 *P2, const uint64_t *Q2buf
+);
+```
+- compute `MillerLoop(P1, Q2) * MillerLoop(P2, Q2buf)`
+
+## Check value
+### Check validness
+```
+int mclBnFr_isValid(const mclBnFr *x);
+int mclBnFp_isValid(const mclBnFp *x);
+int mclBnG1_isValid(const mclBnG1 *x);
+int mclBnG2_isValid(const mclBnG2 *x);
+```
+- return 1 if true else 0
+
+### Check the order of a point
+```
+int mclBnG1_isValidOrder(const mclBnG1 *x);
+int mclBnG2_isValidOrder(const mclBnG2 *x);
+```
+- Check whether the order of `x` is valid or not
+- return 1 if true else 0
+- This function always cheks according to `mclBn_verifyOrderG1` and `mclBn_verifyOrderG2`.
+
+### Is equal / zero / one / isOdd
+```
+int mclBnFr_isEqual(const mclBnFr *x, const mclBnFr *y);
+int mclBnFr_isZero(const mclBnFr *x);
+int mclBnFr_isOne(const mclBnFr *x);
+int mclBnFr_isOdd(const mclBnFr *x);
+
+int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y);
+int mclBnFp_isZero(const mclBnFp *x);
+int mclBnFp_isOne(const mclBnFp *x);
+int mclBnFp_isOdd(const mclBnFp *x);
+
+int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y);
+int mclBnFp2_isZero(const mclBnFp2 *x);
+int mclBnFp2_isOne(const mclBnFp2 *x);
+
+int mclBnG1_isEqual(const mclBnG1 *x, const mclBnG1 *y);
+int mclBnG1_isZero(const mclBnG1 *x);
+
+int mclBnG2_isEqual(const mclBnG2 *x, const mclBnG2 *y);
+int mclBnG2_isZero(const mclBnG2 *x);
+
+int mclBnGT_isEqual(const mclBnGT *x, const mclBnGT *y);
+int mclBnGT_isZero(const mclBnGT *x);
+int mclBnGT_isOne(const mclBnGT *x);
+```
+- return 1 if true else 0
+
+### isNegative
+```
+int mclBnFr_isNegative(const mclBnFr *x);
+int mclBnFp_isNegative(const mclBnFr *x);
+```
+return 1 if x >= half where half = (r + 1) / 2 (resp. (p + 1) / 2).
+
+## Lagrange interpolation
+
+```
+int mclBn_FrLagrangeInterpolation(mclBnFr *out, const mclBnFr *xVec, const mclBnFr *yVec, mclSize k);
+int mclBn_G1LagrangeInterpolation(mclBnG1 *out, const mclBnFr *xVec, const mclBnG1 *yVec, mclSize k);
+int mclBn_G2LagrangeInterpolation(mclBnG2 *out, const mclBnFr *xVec, const mclBnG2 *yVec, mclSize k);
+```
+- Lagrange interpolation
+- recover out = y(0) from {(xVec[i], yVec[i])} for {i=0..k-1}
+- return 0 if success else -1
+ - satisfy that xVec[i] != 0, xVec[i] != xVec[j] for i != j
+
+```
+int mclBn_FrEvaluatePolynomial(mclBnFr *out, const mclBnFr *cVec, mclSize cSize, const mclBnFr *x);
+int mclBn_G1EvaluatePolynomial(mclBnG1 *out, const mclBnG1 *cVec, mclSize cSize, const mclBnFr *x);
+int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, mclSize cSize, const mclBnFr *x);
+```
+- Evaluate polynomial
+- out = f(x) = c[0] + c[1] * x + ... + c[cSize - 1] * x^{cSize - 1}
+- return 0 if success else -1
+ - satisfy cSize >= 1
diff --git a/readme.md b/readme.md
index 1879184..3b43772 100644
--- a/readme.md
+++ b/readme.md
@@ -9,7 +9,6 @@ A portable and fast pairing-based cryptography library.
mcl is a library for pairing-based cryptography,
which supports the optimal Ate pairing over BN curves and BLS12-381 curves.
-
# Support architecture
- x86-64 Windows + Visual Studio
@@ -30,6 +29,9 @@ which supports the optimal Ate pairing over BN curves and BLS12-381 curves.
- BN462 ; a BN curve over the 462-bit prime p(z) where z = 2^114 + 2^101 - 2^14 - 1.
- BLS12\_381 ; [a BLS12-381 curve](https://blog.z.cash/new-snark-curve/)
+# C-API
+see [api.md](api.md)
+
# How to build on Linux and macOS
x86-64/ARM/ARM64 Linux, macOS and mingw64 are supported.
@@ -232,193 +234,6 @@ pairing 1.394Mclk
finalExp 546.259Kclk
```
-# Libraries
-
-* G1 and G2 is defined over Fp
-* The order of G1 and G2 is r.
-* Use `bn256.hpp` if only BN254 is used.
-
-## C++ library
-
-* libmcl.a ; static C++ library of mcl
-* libmcl.so ; shared C++ library of mcl
-* the default parameter of curveType is BN254
-
-header |support curveType |sizeof Fr|sizeof Fp|
---------------|-------------------------|---------|---------|
-bn256.hpp |BN254, BN_SNARK1 | 32 | 32 |
-bls12_381.hpp |the above + BLS12_381 | 32 | 48 |
-bn384.hpp |the above + BN381_1 | 48 | 48 |
-
-## C library
-
-* Define `MCLBN_FR_UNIT_SIZE` and `MCLBN_FP_UNIT_SIZE` and include bn.h
-* set `MCLBN_FR_UNIT_SIZE = MCLBN_FP_UNIT_SIZE` unless `MCLBN_FR_UNIT_SIZE` is defined
-
-
-library |MCLBN_FR_UNIT_SIZE|MCLBN_FP_UNIT_SIZE|
-------------------|------------------|------------------|
-sizeof | Fr | Fp |
-libmclbn256.a | 4 | 4 |
-libmclbn384_256.a | 4 | 6 |
-libmclbn384.a | 6 | 6 |
-
-
-* libmclbn*.a ; static C library
-* libmclbn*.so ; shared C library
-
-### 2nd argument of `mclBn_init`
-Specify `MCLBN_COMPILED_TIME_VAR` to 2nd argument of `mclBn_init`, which
-is defined as `MCLBN_FR_UNIT_SIZE * 10 + MCLBN_FP_UNIT_SIZE`.
-This parameter is used to make sure that the values are the same when the library is built and used.
-
-# How to initialize pairing library
-Call `mcl::bn256::initPairing` before calling any operations.
-```
-#include
-mcl::bn::CurveParam cp = mcl::BN254; // or mcl::BN_SNARK1
-mcl::bn256::initPairing(cp);
-mcl::bn256::G1 P(...);
-mcl::bn256::G2 Q(...);
-mcl::bn256::Fp12 e;
-mcl::bn256::pairing(e, P, Q);
-```
-1. (BN254) a BN curve over the 254-bit prime p = p(z) where z = -(2^62 + 2^55 + 1).
-2. (BN_SNARK1) a BN curve over a 254-bit prime p such that n := p + 1 - t has high 2-adicity.
-3. BN381_1 with `mcl/bn384.hpp`.
-4. BN462 with `mcl/bn512.hpp`.
-
-See [test/bn_test.cpp](https://github.com/herumi/mcl/blob/master/test/bn_test.cpp).
-
-## Default constructor of Fp, Ec, etc.
-A default constructor does not initialize the instance.
-Set a valid value before reffering it.
-
-## Definition of groups
-
-The curve equation for a BN curve is:
-
- E/Fp: y^2 = x^3 + b .
-
-* the cyclic group G1 is instantiated as E(Fp)[n] where n := p + 1 - t;
-* the cyclic group G2 is instantiated as the inverse image of E'(Fp^2)[n] under a twisting isomorphism phi from E' to E; and
-* the pairing e: G1 x G2 -> Fp12 is the optimal ate pairing.
-
-The field Fp12 is constructed via the following tower:
-
-* Fp2 = Fp[u] / (u^2 + 1)
-* Fp6 = Fp2[v] / (v^3 - Xi) where Xi = u + 1
-* Fp12 = Fp6[w] / (w^2 - v)
-* GT = { x in Fp12 | x^r = 1 }
-
-## Curve Parameter
-r = |G1| = |G2| = |GT|
-
-curveType | hexadecimal number|
-------------|-------------------|
-BN254 r | 2523648240000001ba344d8000000007ff9f800000000010a10000000000000d |
-BN254 p | 2523648240000001ba344d80000000086121000000000013a700000000000013 |
-BN381 r | 240026400f3d82b2e42de125b00158405b710818ac000007e0042f008e3e00000000001080046200000000000000000d |
-BN381 p | 240026400f3d82b2e42de125b00158405b710818ac00000840046200950400000000001380052e000000000000000013 |
-BN462 r | 240480360120023ffffffffff6ff0cf6b7d9bfca0000000000d812908ee1c201f7fffffffff6ff66fc7bf717f7c0000000002401b007e010800d |
-BN462 r | 240480360120023ffffffffff6ff0cf6b7d9bfca0000000000d812908f41c8020ffffffffff6ff66fc6ff687f640000000002401b00840138013 |
-BLS12-381 r | 73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 |
-BLS12-381 r | 1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab |
-
-## Arithmetic operations
-
-G1 and G2 is additive group and has the following operations:
-
-* T::add(T& z, const T& x, const T& y); // z = x + y
-* T::sub(T& z, const T& x, const T& y); // z = x - y
-* T::neg(T& y, const T& x); // y = -x
-* T::mul(T& z, const T& x, const INT& y); // z = y times scalar multiplication of x
-
-Remark: &z == &x or &y are allowed. INT means integer type such as Fr, int and mpz_class.
-
-`T::mul` uses GLV method then `G2::mul` returns wrong value if x is not in G2.
-Use `T::mulGeneric(T& z, const T& x, const INT& y)` for x in phi^-1(E'(Fp^2)) - G2.
-
-Fp, Fp2, Fp6 and Fp12 have the following operations:
-
-* T::add(T& z, const T& x, const T& y); // z = x + y
-* T::sub(T& z, const T& x, const T& y); // z = x - y
-* T::mul(T& z, const T& x, const T& y); // z = x * y
-* T::div(T& z, const T& x, const T& y); // z = x / y
-* T::neg(T& y, const T& x); // y = -x
-* T::inv(T& y, const T& x); // y = 1/x
-* T::pow(T& z, const T& x, const INT& y); // z = x^y
-* Fp12::unitaryInv(T& y, const T& x); // y = conjugate of x
-
-Remark: `Fp12::mul` uses GLV method then returns wrong value if x is not in GT.
-Use `Fp12::mulGeneric` for x in Fp12 - GT.
-
-## Map To points
-
-Use these functions to make a point of G1 and G2.
-
-* mapToG1(G1& P, const Fp& x); // assume x != 0
-* mapToG2(G2& P, const Fp2& x);
-* hashAndMapToG1(G1& P, const void *buf, size_t bufSize); // set P by the hash value of [buf, bufSize)
-* hashAndMapToG2(G2& P, const void *buf, size_t bufSize);
-
-These functions maps x into Gi according to [\[_Faster hashing to G2_\]].
-
-## String format of G1 and G2
-G1 and G2 have three elements of Fp (x, y, z) for Jacobi coordinate.
-`normalize()` method normalizes it to affine coordinate (x, y, 1) or (0, 0, 0).
-
-getStr(mode = 0) method gets
-
-* `0` ; infinity
-* `1 ` ; Affine coordinate with mode = `mcl:IoEcAffine`
-* `4 ` ; jacobi/Proj coordinate with mode = `mcl::IoEcProj`
-* `2 ` ; compressed format for even y with mode = `mcl::IoEcCompY`
-* `3 ` ; compressed format for odd y with mode = `mcl::IoEcCompY`
-
-## Generator of G1 and G2
-
-If you want to use the same generators of BLS12-381 with [zkcrypto](https://github.com/zkcrypto/pairing/tree/master/src/bls12_381#g2) then,
-
-```
-// G1 P
-P.setStr('1 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569')
-
-// G2 Q
-Q.setStr('1 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582')
-```
-
-## Serialization format of G1 and G2
-
-pseudo-code to serialize of p
-```
-if bit-length(p) % 8 != 0:
- size = Fp::getByteSize()
- if p is zero:
- return [0] * size
- else:
- s = x.serialize()
- # x in Fp2 is odd <=> x.a is odd
- if y is odd:
- s[byte-length(s) - 1] |= 0x80
- return s
-else:
- size = Fp::getByteSize() + 1
- if p is zero:
- return [0] * size
- else:
- s = x.serialize()
- if y is odd:
- return 2:s
- else:
- return 3:s
-```
-
-## Verify an element in G2
-`G2::isValid()` checks that the element is in the curve of G2 and the order of it is r for subgroup attack.
-`G2::set()`, `G2::setStr` and `operator<<` also check the order.
-If you check it out of the library, then you can stop the verification by calling `G2::verifyOrderG2(false)`.
-
# How to make asm files (optional)
The asm files generated by this way are already put in `src/asm`, then it is not necessary to do this.
@@ -478,6 +293,7 @@ If `MCL_USE_OLD_MAPTO_FOR_BLS12` is defined, then the old function is used, but
# History
+- 2019/Sep/30 v1.00 add some functions to bn.h ; [api.md](api.md).
- 2019/Sep/22 v0.99 add mclBnG1_mulVec, etc.
- 2019/Sep/08 v0.98 bugfix Ec::add(P, Q, R) when P == R
- 2019/Aug/14 v0.97 add some C api functions