github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/mcl/paillier.hpp (about)

     1  #pragma once
     2  /**
     3  	@file
     4  	@brief paillier encryption
     5  	@author MITSUNARI Shigeo(@herumi)
     6  	@license modified new BSD license
     7  	http://opensource.org/licenses/BSD-3-Clause
     8  */
     9  #include <mcl/gmp_util.hpp>
    10  
    11  namespace mcl { namespace paillier {
    12  
    13  class PublicKey {
    14  	size_t primeBitSize;
    15  	mpz_class g;
    16  	mpz_class n;
    17  	mpz_class n2;
    18  public:
    19  	PublicKey() : primeBitSize(0) {}
    20  	void init(size_t _primeBitSize, const mpz_class& _n)
    21  	{
    22  		primeBitSize = _primeBitSize;
    23  		n = _n;
    24  		g = 1 + _n;
    25  		n2 = _n * _n;
    26  	}
    27  	void enc(mpz_class& c, const mpz_class& m, mcl::fp::RandGen rg = mcl::fp::RandGen()) const
    28  	{
    29  		if (rg.isZero()) rg = mcl::fp::RandGen::get();
    30  		if (primeBitSize == 0) throw cybozu::Exception("paillier:PublicKey:not init");
    31  		mpz_class r;
    32  		mcl::gmp::getRand(r, primeBitSize, rg);
    33  		mpz_class a, b;
    34  		mcl::gmp::powMod(a, g, m, n2);
    35  		mcl::gmp::powMod(b, r, n, n2);
    36  		c = (a * b) % n2;
    37  	}
    38  	/*
    39  		additive homomorphic encryption
    40  		cz = cx + cy
    41  	*/
    42  	void add(mpz_class& cz, mpz_class& cx, mpz_class& cy) const
    43  	{
    44  		cz = (cx * cy) % n2;
    45  	}
    46  };
    47  
    48  class SecretKey {
    49  	size_t primeBitSize;
    50  	mpz_class n;
    51  	mpz_class n2;
    52  	mpz_class lambda;
    53  	mpz_class invLambda;
    54  public:
    55  	SecretKey() : primeBitSize(0) {}
    56  	/*
    57  		the size of prime is half of bitSize
    58  	*/
    59  	void init(size_t bitSize, mcl::fp::RandGen rg = mcl::fp::RandGen())
    60  	{
    61  		if (rg.isZero()) rg = mcl::fp::RandGen::get();
    62  		primeBitSize = bitSize / 2;
    63  		mpz_class p, q;
    64  		mcl::gmp::getRandPrime(p, primeBitSize, rg);
    65  		mcl::gmp::getRandPrime(q, primeBitSize, rg);
    66  		lambda = (p - 1) * (q - 1);
    67  		n = p * q;
    68  		n2 = n * n;
    69  		mcl::gmp::invMod(invLambda, lambda, n);
    70  	}
    71  	void getPublicKey(PublicKey& pub) const
    72  	{
    73  		pub.init(primeBitSize, n);
    74  	}
    75  	void dec(mpz_class& m, const mpz_class& c) const
    76  	{
    77  		mpz_class L;
    78  		mcl::gmp::powMod(L, c, lambda, n2);
    79  		L = ((L - 1) / n) % n;
    80  		m = (L * invLambda) % n;
    81  	}
    82  };
    83  
    84  } } // mcl::paillier