aboutsummaryrefslogtreecommitdiffstats
path: root/include/mcl/bn.h
blob: b03e5f737864fb624f8263a361f8a1fa3249e682 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#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 BN_MAX_OP_UNIT_SIZE
    #error "define BN_MAX_OP_UNIT_SIZE 4(or 6)"
#endif

#include <stdint.h> // for uint64_t, uint8_t
#include <stdlib.h> // for size_t

#ifdef _MSC_VER
#ifdef BN_DLL_EXPORT
#define BN_DLL_API __declspec(dllexport)
#else
#define BN_DLL_API __declspec(dllimport)
#ifndef MCL_NO_AUTOLINK
    #if BN_MAX_OP_UNIT_SIZE == 4
        #pragma comment(lib, "bn_if256.lib")
    #else
        #pragma comment(lib, "bn_if384.lib")
    #endif
#endif
#endif
#else
#define BN_DLL_API
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef BN_DEFINE_STRUCT

typedef struct {
    uint64_t d[BN_MAX_OP_UNIT_SIZE];
} BN_Fr;

typedef struct {
    uint64_t d[BN_MAX_OP_UNIT_SIZE * 3];
} BN_G1;

typedef struct {
    uint64_t d[BN_MAX_OP_UNIT_SIZE * 2 * 3];
} BN_G2;

typedef struct {
    uint64_t d[BN_MAX_OP_UNIT_SIZE * 12];
} BN_GT;

#else

typedef struct BN_Fr BN_Fr;
typedef struct BN_G1 BN_G1;
typedef struct BN_G2 BN_G2;
typedef struct BN_GT BN_GT;

#endif

/*
    set errlog file name
    use stderr if name == "stderr"
    close if name == ""
    return 0 if success
    @note not threadsafe
*/
BN_DLL_API int BN_setErrFile(const char *name);

enum {
    BN_curveFp254BNb = 0,
    BN_curveFp382_1 = 1,
    BN_curveFp382_2 = 2
};

/*
    init library
    @param curve [in] type of bn curve
    @param maxUnitSize [in] 4 or 6
    curve = BN_CurveFp254BNb is allowed if maxUnitSize = 4
    curve = BN_CurveFp254BNb/BN_CurveFp382_1/BN_CurveFp382_2 are allowed if maxUnitSize = 6
    @note not threadsafe
    @note BN_init is used in libeay32
*/
BN_DLL_API int BN_initLib(int curve, int maxUnitSize);

////////////////////////////////////////////////
// set zero
BN_DLL_API void BN_Fr_clear(BN_Fr *x);

// set x to y
BN_DLL_API void BN_Fr_setInt(BN_Fr *y, int x);

// return 0 if success
BN_DLL_API int BN_Fr_setDecStr(BN_Fr *x, const char *buf, size_t bufSize);
BN_DLL_API int BN_Fr_setHexStr(BN_Fr *x, const char *buf, size_t bufSize);
// mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r
BN_DLL_API int BN_Fr_setLittleEndian(BN_Fr *x, const void *buf, size_t bufSize);

// return 1 if true and 0 otherwise
BN_DLL_API int BN_Fr_isValid(const BN_Fr *x);
BN_DLL_API int BN_Fr_isEqual(const BN_Fr *x, const BN_Fr *y);
BN_DLL_API int BN_Fr_isZero(const BN_Fr *x);
BN_DLL_API int BN_Fr_isOne(const BN_Fr *x);

BN_DLL_API void BN_Fr_setByCSPRNG(BN_Fr *x);

// hash(s) and set x
BN_DLL_API void BN_hashToFr(BN_Fr *x, const void *buf, size_t bufSize);

// return strlen(buf) if sucess else 0
BN_DLL_API size_t BN_Fr_getDecStr(char *buf, size_t maxBufSize, const BN_Fr *x);
BN_DLL_API size_t BN_Fr_getHexStr(char *buf, size_t maxBufSize, const BN_Fr *x);
// return written byte if sucess else 0
BN_DLL_API size_t BN_Fr_getLittleEndian(void *buf, size_t bufSize, const BN_Fr *x);

BN_DLL_API void BN_Fr_neg(BN_Fr *y, const BN_Fr *x);
BN_DLL_API void BN_Fr_inv(BN_Fr *y, const BN_Fr *x);
BN_DLL_API void BN_Fr_add(BN_Fr *z, const BN_Fr *x, const BN_Fr *y);
BN_DLL_API void BN_Fr_sub(BN_Fr *z, const BN_Fr *x, const BN_Fr *y);
BN_DLL_API void BN_Fr_mul(BN_Fr *z, const BN_Fr *x, const BN_Fr *y);
BN_DLL_API void BN_Fr_div(BN_Fr *z, const BN_Fr *x, const BN_Fr *y);

////////////////////////////////////////////////
// set zero
BN_DLL_API void BN_G1_clear(BN_G1 *x);

// return 0 if success
BN_DLL_API int BN_G1_setHexStr(BN_G1 *x, const char *buf, size_t bufSize);
BN_DLL_API int BN_G1_deserialize(BN_G1 *x, const char *buf, size_t bufSize);

// return 1 if true and 0 otherwise
BN_DLL_API int BN_G1_isValid(const BN_G1 *x);
BN_DLL_API int BN_G1_isEqual(const BN_G1 *x, const BN_G1 *y);
BN_DLL_API int BN_G1_isZero(const BN_G1 *x);

BN_DLL_API int BN_hashAndMapToG1(BN_G1 *x, const void *buf, size_t bufSize);

// return 0 if success
BN_DLL_API size_t BN_G1_getHexStr(char *buf, size_t maxBufSize, const BN_G1 *x);
// return written size if sucess else 0
BN_DLL_API size_t BN_G1_serialize(void *buf, size_t maxBufSize, const BN_G1 *x);

BN_DLL_API void BN_G1_neg(BN_G1 *y, const BN_G1 *x);
BN_DLL_API void BN_G1_dbl(BN_G1 *y, const BN_G1 *x);
BN_DLL_API void BN_G1_add(BN_G1 *z, const BN_G1 *x, const BN_G1 *y);
BN_DLL_API void BN_G1_sub(BN_G1 *z, const BN_G1 *x, const BN_G1 *y);
BN_DLL_API void BN_G1_mul(BN_G1 *z, const BN_G1 *x, const BN_Fr *y);

////////////////////////////////////////////////
// set zero
BN_DLL_API void BN_G2_clear(BN_G2 *x);

// return 0 if success
BN_DLL_API int BN_G2_setHexStr(BN_G2 *x, const char *buf, size_t bufSize);
BN_DLL_API int BN_G2_deserialize(BN_G2 *x, const char *buf, size_t bufSize);

// return 1 if true and 0 otherwise
BN_DLL_API int BN_G2_isValid(const BN_G2 *x);
BN_DLL_API int BN_G2_isEqual(const BN_G2 *x, const BN_G2 *y);
BN_DLL_API int BN_G2_isZero(const BN_G2 *x);

BN_DLL_API int BN_hashAndMapToG2(BN_G2 *x, const void *buf, size_t bufSize);

// return 0 if success
BN_DLL_API size_t BN_G2_getHexStr(char *buf, size_t maxBufSize, const BN_G2 *x);
// return written size if sucess else 0
BN_DLL_API size_t BN_G2_serialize(void *buf, size_t maxBufSize, const BN_G2 *x);

BN_DLL_API void BN_G2_neg(BN_G2 *y, const BN_G2 *x);
BN_DLL_API void BN_G2_dbl(BN_G2 *y, const BN_G2 *x);
BN_DLL_API void BN_G2_add(BN_G2 *z, const BN_G2 *x, const BN_G2 *y);
BN_DLL_API void BN_G2_sub(BN_G2 *z, const BN_G2 *x, const BN_G2 *y);
BN_DLL_API void BN_G2_mul(BN_G2 *z, const BN_G2 *x, const BN_Fr *y);

////////////////////////////////////////////////
// set zero
BN_DLL_API void BN_GT_clear(BN_GT *x);

// return 0 if success
BN_DLL_API int BN_GT_setDecStr(BN_GT *x, const char *buf, size_t bufSize);
BN_DLL_API int BN_GT_setHexStr(BN_GT *x, const char *buf, size_t bufSize);
BN_DLL_API int BN_GT_deserialize(BN_GT *x, const char *buf, size_t bufSize);

// return 1 if true and 0 otherwise
BN_DLL_API int BN_GT_isEqual(const BN_GT *x, const BN_GT *y);
BN_DLL_API int BN_GT_isZero(const BN_GT *x);
BN_DLL_API int BN_GT_isOne(const BN_GT *x);

// return 0 if success
BN_DLL_API size_t BN_GT_getDecStr(char *buf, size_t maxBufSize, const BN_GT *x);
BN_DLL_API size_t BN_GT_getHexStr(char *buf, size_t maxBufSize, const BN_GT *x);
// return written size if sucess else 0
BN_DLL_API size_t BN_GT_serialize(void *buf, size_t maxBufSize, const BN_GT *x);

BN_DLL_API void BN_GT_neg(BN_GT *y, const BN_GT *x);
BN_DLL_API void BN_GT_inv(BN_GT *y, const BN_GT *x);
BN_DLL_API void BN_GT_add(BN_GT *z, const BN_GT *x, const BN_GT *y);
BN_DLL_API void BN_GT_sub(BN_GT *z, const BN_GT *x, const BN_GT *y);
BN_DLL_API void BN_GT_mul(BN_GT *z, const BN_GT *x, const BN_GT *y);
BN_DLL_API void BN_GT_div(BN_GT *z, const BN_GT *x, const BN_GT *y);

BN_DLL_API void BN_GT_pow(BN_GT *z, const BN_GT *x, const BN_Fr *y);

BN_DLL_API void BN_pairing(BN_GT *z, const BN_G1 *x, const BN_G2 *y);
BN_DLL_API void BN_finalExp(BN_GT *y, const BN_GT *x);
BN_DLL_API void BN_millerLoop(BN_GT *z, const BN_G1 *x, const BN_G2 *y);

// return precomputedQcoeffSize * sizeof(Fp6) / sizeof(uint64_t)
BN_DLL_API int BN_getUint64NumToPrecompute(void);

// allocate Qbuf[BN_getUint64NumToPrecompute()] before calling this
BN_DLL_API void BN_precomputeG2(uint64_t *Qbuf, const BN_G2 *Q);

BN_DLL_API void BN_precomputedMillerLoop(BN_GT *f, const BN_G1 *P, const uint64_t *Qbuf);
BN_DLL_API void BN_precomputedMillerLoop2(BN_GT *f, const BN_G1 *P1, const uint64_t *Q1buf, const BN_G1 *P2, const uint64_t *Q2buf);

#ifdef __cplusplus
}
#endif