aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/byzantine-lab/mcl/misc/she/she-api.md
blob: af54311e9beb6da4670653dc0be9d368e7450e93 (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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# she ; Two-level homomorphic encryption library for browser/Node.js by WebAssembly

# Abstruct
she is a somewhat(two-level) homomorphic encryption library,
which is based on pairings.
This library supports polynomially many homomorphic additions and
one multiplication over encrypted data.

Especially, the inner products of two encrypted integer vectors such as Enc(x) = (Enc(x_i)), Enc(y) = (Enc(y_i))
can be computed.

Sum_i Enc(x_i) Enc(y_i) = Enc(Sum_i x_i y_i).

# Features
* supports the latest pairing based algorithm
    * [Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and A Fast Implementation in WebAssembly : ASIA CCS2018](http://asiaccs2018.org/?page_id=632)
* supports Windows(x64), Linux(x64, ARM64), OSX(x64)
* supports JavaScript(WebAssembly), Chrome, Firefox, Safari(contains Android, iPhone), Node.js

# Classes

## Main classes
* secret key class ; SecretKey
* public key class ; PublicKey
* ciphertext class ; CipherTextG1, CipherTextG2, CipherTextGT
* zero-knowledge proof class ; ZkpBin, ZkpEq, ZkpBinEq

## Encryption and decryption
* create the corresponding public key from a secret key
* encrypt an integer(plaintext) with a public key
* decrypt a ciphertext with a secret key

## Homomorphic operations
* homomorphic addtion/substraction over ciphertexts of the same ciphertext class
* homomprphic multiplication over ciphertext of CipherTextG1 and CipherTextG2
    * The class of the result is CipherTextGT.

## Important notation of decryption
* This library requires to solve a small DLP to decrypt a ciphertext.
* The decryption timing is O(m/s), where s is the size of table to solve DLP, and m is the size fo a plaintext.
* call `setRangeForDLP(s)` to set the table size.
    * The maximun `m/s` is set by `setTryNum(tryNum)`.

## Zero-knowledge proof class
* A zero-knowledge proof is simultaneously created when encrypting a plaintext `m`.
* The restriction according to `m` can be verified with a created zero-knowledge proof and a public key.

# Setup for JavaScript(JS)

## for Node.js

```
>npm install she-wasm
>node
>const she = require('she-wasm')
```

## for a browser

Copy `she.js`, `she\_c.js`, `she\_c.wasm` to your directory from [she-wasm](https://github.com/herumi/she-wasm/),
and read `she.js`.
```
// HTML
<script src="she.js"></script>
```

## A sample for JS

```
// initialize a library
she.init().then(() => {
  const sec = new she.SecretKey()
  // initialize a secret key by CSPRNG(cryptographically secure pseudo random number generator)
  sec.setByCSPRNG()

  // create a public key from a secret key
  const pub = sec.getPublicKey()

  const m1 = 1
  const m2 = 2
  const m3 = 3
  const m4 = -1

  // encrypt m1 and m2 as CipherTextG1 class
  const c11 = pub.encG1(m1)
  const c12 = pub.encG1(m2)

  // encrypt m3 and m4 as CipherTextG2 class
  const c21 = pub.encG2(m3)
  const c22 = pub.encG2(m4)

  // add c11 and c12, c21 and c22 respectively
  const c1 = she.add(c11, c12)
  const c2 = she.add(c21, c22)

  // get ct as a CipherTextGT class by multiplying c1 with c2
  const ct = she.mul(c1, c2)

  // decrypt ct
  console.log(`(${m1} + ${m2}) * (${m3} + ${m4}) = ${sec.dec(ct)}`)
})
```

# A sample for C++
How to build the library, see [mcl](https://github.com/herumi/mcl/#installation-requirements).
```
#include <mcl/she.hpp>
int main()
    try
{
    using namespace mcl::she;
    // initialize a library
    init();

    SecretKey sec;

    // initialize a secret key by CSPRNG
    sec.setByCSPRNG();

    // create a public key from a secret key
    PublicKey pub;
    sec.getPublicKey(pub);

    int m1 = 1;
    int m2 = 2;
    int m3 = 3;
    int m4 = -1;

    // encrypt m1 and m2 as CipherTextG1 class
    CipherTextG1 c11, c12;
    pub.enc(c11, m1);
    pub.enc(c12, m2);

    // encrypt m3 and m4 as CipherTextG2 class
    CipherTextG2 c21, c22;
    pub.enc(c21, m3);
    pub.enc(c22, m4);

    // add c11 and c12, c21 and c22 respectively
    CipherTextG1 c1;
    CipherTextG2 c2;
    CipherTextG1::add(c1, c11, c12);
    CipherTextG2::add(c2, c21, c22);

    // get ct as a CipherTextGT class by multiplying c1 with c2
    CipherTextGT ct;
    CipherTextGT::mul(ct, c1, c2);

    // decrypt ct
    printf("(%d + %d) * (%d + %d) = %d\n", m1, m2, m3, m4, (int)sec.dec(ct));
} catch (std::exception& e) {
    printf("ERR %s\n", e.what());
    return 1;
}

```
# Class method

## Serialization(C++)

* `setStr(const std::string& str, int ioMode = 0)`
    * set a value by `str` according to `ioMode`

* `getStr(std::string& str, int ioMode = 0) const`
* `std::string getStr(int ioMode = 0) const`
    * get a string `str` according to `ioMode`
* `size_t serialize(void *buf, size_t maxBufSize) const`
    * serialize a value to buf which has maxBufSize byte size
    * return the byte size to be written in `buf`
    * return zero if error
* `size_t deserialize(const void *buf, size_t bufSize)`
    * deserialize a value from buf which has bufSize byte size
    * return the byte size to be read from `buf`
    * return zero if error

## Serialization(JS)

* `deserialize(s)`
    * deserialize from `s` as Uint8Array type
* `serialize()`
    * serialize a value and return Uint8Array value
* `deserializeHexStr(s)`
    * deserialize as a hexadecimal string
* `serializeToHexStr()`
    * serialize as a hexadecimal string

## ioMode

* 2 ; binary number
* 10 ; decimal number
* 16 ; hexadecimal number
* IoPrefix ; append a prefix 0b(resp. 2) or 0x(resp. 16)
* IoEcAffine ; affine coordinate (for only G1, G2)
* IoEcProj ; projective coordinate (for only G1, G2)
* IoSerialize ; same as serialize()/deserialize()

## Notation
* the namespace of C++ is `mcl::she`
* CT means one of CipherTextG1, CipherTextG2, CipherTextGT
* The range of plaintext is rectricted as a 32-bit integer for JS

## SecretKey class

* `void setByCSPRNG()`(C++)
* `void setByCSPRNG()`(JS)
    * set a secret key by CSPRNG(cryptographically secure pseudo random number generator)

* `int64_t dec(const CT& c) const`(C++)
* `int dec(CT c)`(JS)
    * decrypt `c`
* `int64_t decViaGT(const CipherTextG1& c) const`(C++)
* `int64_t decViaGT(const CipherTextG2& c) const`(C++)
* `int decViaGT(CT c)`(JS)
    * decrypt `c` through CipherTextGT
* `bool isZero(const CT& c) const`(C++)
* `bool isZero(CT c)`(JS)
    * return true if decryption of `c` is zero
    * it is faster than the timing of comparision with zero after decrypting `c`

## PublicKey, PrecomputedPublicKey class
`PrecomputedPublicKey` is a faster version of `PublicKey`

* `void PrecomputedPublicKey::init(const PublicKey& pub)`(C++)
* `void PrecomputedPublicKey::init(pub)`(JS)
    * initialize `PrecomputedPublicKey` by a public key `pub`

* `PrecomputedPublicKey::destroy()`(JS)
    * It is necessary to call this method if this instance becomes unnecessary
    * otherwise a memory leak will be caused

PK means PublicKey or PrecomputedPublicKey

* `void PK::enc(CT& c, int64_t m) const`(C++)
* `CipherTextG1 PK::encG1(m)`(JS)
* `CipherTextG2 PK::encG2(m)`(JS)
* `CipherTextGT PK::encGT(m)`(JS)
    * encrypt `m` and set `c`(or return the value)

* `void PK::reRand(CT& c) const`(C++)
* `CT PK::reRand(CT c)`(JS)
    * rerandomize `c`
    * For `c = Enc(m)`, the rerandomized ciphertext is hard to detect if it is generated by the rerandomization
    or an encrypted `m` freshly again.

* `void convert(CipherTextGT& cm, const CT& ca) const`
* `CipherTextGT convert(CT ca)`
   * convert `ca`(CipherTextG1 or CipherTextG2) to `CipherTextGT` class

## CipherText class

* `void CT::add(CT& z, const CT& x const CT& y)`(C++)
* `CT she.add(CT x, CT y)`(JS)
    * add `x` and `y` and set the value to `z`(or return the value)
* `void CT::sub(CT& z, const CT& x const CT& y)`(C++)
* `CT she.sub(CT x, CT y)`(JS)
    * subtract `x` and `y` and set the value to `z`(or return the value)
* `void CT::neg(CT& y, const CT& x)`(C++)
* `void she.neg(CT x)`(JS)
    * negate `x` and set the value to `y`(or return the value)
* `void CT::mul(CT& z, const CT& x, int y)`(C++)
* `CT she.mulInt(CT x, int y)`(JS)
    * multiple `x` and `y` and set the value `y`(or return the value)

* `void CipherTextGT::mul(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++)
* `CipherTextGT she.mul(CipherTextG1 x, CipherTextG2 y)`(JS)
    * multiple `x` and `y` and set the value `y`(or return the value)

* `void CipherTextGT::mulML(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++)
    * multiple(only Miller Loop) `x` and `y` and set the value `y`(or return the value)

* `CipherTextGT::finalExp(CipherText& , const CipherTextG1& x, const CipherTextG2& y)`(C++)
    * mul(a, b) = finalExp(mulML(a, b))
    * add(mul(a, b), mul(c, d)) = finalExp(add(mulML(a, b), mulML(c, d)))
    * i.e., innor product can be computed as once calling `finalExp` after computing `mulML` for each elements of two vectors and adding all

## Zero knowledge proof class

### Abstract
* ZkpBin ; verify whether `m = 0` or `1` for ciphertexts `encGi(m)(i = 1, 2, T)`
* ZkpEq ; verify whether `m1 = m2` for ciphertexts `encG1(m1)` and `encG2(m2)`
* ZkpBinEq ; verify whether `m1 = m2 = 0` or `1` for ciphertexts `encG1(m1)` and `encG2(m2)`

### API
PK = PublicKey or PrecomputedPublicKey

* `void PK::encWithZkpBin(CipherTextG1& c, Zkp& zkp, int m) const`(C++)
* `void PK::encWithZkpBin(CipherTextG2& c, Zkp& zkp, int m) const`(C++)
* `[CipherTextG1, ZkpBin] PK::encWithZkpBinG1(m)`(JS)
* `[CipherTextG2, ZkpBin] PK::encWithZkpBinG2(m)`(JS)
    * encrypt `m`(=0 or 1) and set the ciphertext `c` and zero-knowledge proof `zkp`(or returns [c, zkp])
    * throw exception if m != 0 and m != 1
* `void PK::encWithZkpEq(CipherTextG1& c1, CipherTextG2& c2, ZkpEq& zkp, const INT& m) const`(C++)
* `[CipherTextG1, CipherTextG2, ZkpEq] PK::encWithZkpEq(m)`(JS)
    * encrypt `m` and set the ciphertext `c1`, `c2` and zero-knowledge proof `zk`(or returns [c1, c2, zkp])
* `void PK::encWithZkpBinEq(CipherTextG1& c1, CipherTextG2& c2, ZkpBinEq& zkp, int m) const`(C++)
* `[CipherTextG1, CipherTextG2, ZkpEqBin] PK::encWithZkpBinEq(m)`(JS)
    * encrypt `m`(=0 or 1) and set ciphertexts `c1`, `c2` and zero-knowledge proof `zkp`(or returns [c1, c2, zkp])
    * throw exception if m != 0 and m != 1

## Global functions

* `void init(const CurveParam& cp, size_t hashSize = 1024, size_t tryNum = 2048)`(C++)
* `void init(curveType = she.BN254, hashSize = 1024, tryNum = 2048)`(JS)
    * initialize a table to solve a DLP with `hashSize` size and set maximum trying count `tryNum`.
    * the range `m` to be solvable is |m| <= hashSize * tryNum
* `getHashTableGT().load(InputStream& is)`(C++)
* `she.loadTableForGTDLP(Uint8Array a)`(JS)
    * load a DLP table for CipherTextGT
    * reset the value of `hashSize` used in `init()`
    * `https://herumi.github.io/she-dlp-table/she-dlp-0-20-gt.bin` is a precomputed table
* `void useDecG1ViaGT(bool use)`(C++/JS)
* `void useDecG2ViaGT(bool use)`(C++/JS)
    * decrypt a ciphertext of CipherTextG1 and CipherTextG2 through CipherTextGT
    * it is better when decrypt a big value

# License

[modified new BSD License](https://github.com/herumi/mcl/blob/master/COPYRIGHT)

# Author

光成滋生 MITSUNARI Shigeo(herumi@nifty.com)