diff options
author | MITSUNARI Shigeo <herumi@nifty.com> | 2018-06-02 16:49:08 +0800 |
---|---|---|
committer | MITSUNARI Shigeo <herumi@nifty.com> | 2018-06-02 16:49:08 +0800 |
commit | c3886e5b65236bc9c64e43787037ddcf3c35765a (patch) | |
tree | 599aa561e883e6fea5e28c61d9fd19e7bcd6bf05 | |
parent | c0bdae8ea7d47f5456b8000f3621d3c8f2d0f21a (diff) | |
download | dexon-mcl-c3886e5b65236bc9c64e43787037ddcf3c35765a.tar.gz dexon-mcl-c3886e5b65236bc9c64e43787037ddcf3c35765a.tar.zst dexon-mcl-c3886e5b65236bc9c64e43787037ddcf3c35765a.zip |
add api for she
-rw-r--r-- | misc/she/she-api.md | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/misc/she/she-api.md b/misc/she/she-api.md new file mode 100644 index 0000000..32a85ae --- /dev/null +++ b/misc/she/she-api.md @@ -0,0 +1,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) |