Implementation and Experiment of Multilinear Maps

一,Reference:

(1)  https://github.com/tlepoint/multimap: this is  an implementation of multilinear maps over the integers. used to perform a one-round n-party (unauthenticated) Diffie-Hellman key exchange.

(2)http://gas.dia.unisa.it/projects/jpbc/index.htmlThe Java Pairing-Based Cryptography Library (JPBC) also provides  An implementation of Multilinear Maps based on the paper Practical Multilinear Maps over the Integers by Coron, Lepoint, and Tibouchi. The implementation supports multithreading and uses memory mapped files to save in primary memory requirements.

(3)相关paper支持请参见前几篇博文。


二,Experiments based on (1):


In cryptography, a multilinear map is a mapping between useful cryptographic groups, which allows the construction of new cryptographic schemes based on the reduction of one problem in one group to a different problem in the target group.

Install GMP:download it and configure it accordingly:  ./configure --enable-cxx, sudo make install, make check

modify the makefile as: 

IFLAGS  = -I/usr/local/include
 LFLAGS  = -L/usr/local/lib -lgmpxx -lgmp
 
 all: Multimap.cpp Multimap.h main.cpp Makefile
     $(CC) $(CCFLAGS) $(IFLAGS) -c -o Multimap.o Multimap.cpp $(LFLAGS)
     $(CC) $(CCFLAGS) $(IFLAGS) main.cpp Multimap.o -o multimap $(LFLAGS)

Then there will be no more complication errors

g++ -Wall -O3 -fopenmp  -I/usr/local/include  -c -o Multimap.o Multimap.cpp -L/usr/local/lib -lgmpxx -lgmp
g++ -Wall -O3 -fopenmp  -I/usr/local/include  main.cpp Multimap.o -o multimap -L/usr/local/lib -lgmpxx -lgmp



Session keys of 160 bits
User #0: 386998600064854454291301789805079065417790031671
User #1: 386998600064854454291301789805079065417790031671
User #2: 386998600064854454291301789805079065417790031671
User #3: 386998600064854454291301789805079065417790031671
User #4: 386998600064854454291301789805079065417790031671
User #5: 386998600064854454291301789805079065417790031671
User #6: 386998600064854454291301789805079065417790031671
(Product+Extract): 0.887151s


下面我们具体看一下这个代码的内部实现:

(1) Multimap.h (https://github.com/vingstar/multimap/blob/master/Multimap.h) :

#define INSTANTIATION 1 		// 1- Small, 2- Medium, 3- Large, 4- Extra

#define kappa 6					// Maximal level
#define hBits 80 				// size of h_i's in v = BETA
#define ell 160 				// number of elements during encoding
#define theta  15 				// number of non-zero elements in subset sum during rerand 

#define sessionKeyBits 160 		// Bitsize of session key to derive
#define bound sessionKeyBits 	// bound to decide if it is zero or not
								// bound must be >= sessionKeyBits
#define alpha 80				// size of g_i's and elements of A

#if INSTANTIATION == 1 		// Small

	#define N  540  			// number of p_i's
	#define delta 23 			// sqrt(N)
	#define eta 1838			// size of p_i's
	#define etp 460				// Size of primes in p_i's; it is better to have eta%etp=0
	#define rho 41				// size of r_i's in xp_i's and y

#elif INSTANTIATION == 2 		// Medium

	#define N  2085  			// number of p_i's
	#define delta 45 			// sqrt(N)
	#define eta 2043			// size of p_i's
	#define etp 409				// Size of primes in p_i's; it is better to have eta%etp=0
	#define rho 56				// size of r_i's in xp_i's and y

#elif INSTANTIATION == 3 		// Large

	#define N  8250  			// number of p_i's
	#define delta 90 			// sqrt(N)
	#define eta 2261			// size of p_i's
	#define etp 453				// Size of primes in p_i's; it is better to have eta%etp=0
	#define rho 72				// size of r_i's in xp_i's and y

#elif INSTANTIATION == 4 		// Extra

	#define N  26115  			// number of p_i's
	#define delta 161 			// sqrt(N)
	#define eta 2438			// size of p_i's
	#define etp 407				// Size of primes in p_i's; it is better to have eta%etp=0
	#define rho 85				// size of r_i's in xp_i's and y

#endif



double currentTime();

class MMKey;

/* 
Class Ciphertext

Contain: 
- ciphertext value (large integer) `cval'
- ciphertext degree `degree'
- pointer to the key associated with the ciphertext `key'
*/
class Ciphertext {
private:
	mpz_class cval;
	long degree;
	MMKey* key;

public:
	Ciphertext();
	Ciphertext(const Ciphertext& c);
	Ciphertext(MMKey* mmkey, mpz_class c, long deg);

	void Decrypt_with_sk(mpz_class* m);
	long get_noise(); 

	long get_degree() const {return degree;};
	mpz_class get_cval() const {return cval;};  

	mpz_class deriveSessionKey();         //相当于Extract

         //以下都是进行运算符重载
	Ciphertext& operator=(const Ciphertext&);
	Ciphertext& operator+=(const Ciphertext&);
	Ciphertext& operator+=(const mpz_class&);
	Ciphertext& operator*=(const Ciphertext&);
	Ciphertext& operator-=(const Ciphertext&);
	Ciphertext& operator-=(const mpz_class&);

	Ciphertext operator+(const Ciphertext& c) const {
	    Ciphertext c2(*this);
	    return (c2 += c);
	}
	Ciphertext operator+(const mpz_class a) const {
	    Ciphertext c2(*this);
	    return (c2 += a);
	}
	friend Ciphertext operator+(const mpz_class, const Ciphertext&);

	Ciphertext operator-(const Ciphertext& c) const {
	    Ciphertext c2(*this);
	    return (c2 -= c);
	}
	Ciphertext operator-(const mpz_class a) const {
	    Ciphertext c2(*this);
	    return (c2 -= a);
	}
	friend Ciphertext operator-(const mpz_class, const Ciphertext&);

	Ciphertext operator*(Ciphertext& c) const {
	    Ciphertext c2(*this);
	    return (c2 *= c);
	}
};

/* 
Class MMKey (Multilinear-Map Key)

Contain: 
- pointer to the gmp pseudorandom generator `rng'
- pointer to secret primes `p'
- public key value `x0' (=prod(p))
- private value `z' and `zkappa'=z^kappa
- private value `zinv' = z^(-1) mod x0
- pointer to private elements `g'
- pointer to secret matrix `A'
- pointer to public values `xp'
- public value `y'
- public zero-tester `v'
- pointer to rerandomization values `varpi' (= x in the article)
*/
class MMKey {
private:
	gmp_randclass* 	rng;
	mpz_class* 		p; 				//	[N];
	mpz_class 		x0, z, zkappa;
	mpz_class 		zinv; 			//	[N];
	mpz_class* 		crtCoeff; 		//	[N];
	mpz_class* 		g; 				//	[N];
	mpz_class* 		A; 				//	[ell*N];
	mpz_class* 		xp; 			//	[ell];
	mpz_class 		y;
	mpz_class 		v;
	mpz_class* 		varpi; 			//	[2*delta];注意,这个就是论文中用来进行rerand的一系列x(level 1的encoding 0)

public:
	MMKey(gmp_randclass* random);
	~MMKey();
	Ciphertext Encrypt(bool b[ell]);
	mpz_class Encrypt_with_sk(mpz_class* m, long nbBits, long degree);
	mpz_class Encrypt_with_sk(unsigned long m, long nbBits, long degree);
	void Decrypt_with_sk(mpz_class* m, const Ciphertext& c);
	mpz_class reduce(const mpz_class &c);
	Ciphertext get_y();
	long get_noise(const mpz_class& c, long degree);
	mpz_class zero_test(const mpz_class &c, long degree);
	long nbBits(const mpz_class &v);
	bool is_zero(const Ciphertext &c);
	Ciphertext Rerand(const Ciphertext & c);
	mpz_class& get_x0() { return x0; };
};

#endif 
// #ifndef __MULTIMAP_H


这里定义了基本的参数以及基本的数据结构类

不同的instantiation标志着不同的security level。其内分别制定了各个基本的参数,主要是各种size的值。

MMkey类制定了一个具体的MMAP instance的相关系统key。


Ciphertext封装了密文信息。


mpz_class 是GMP中的 C++ Interface Integers

为了能较好的理解这里的源代码,我们有必要了解基本的GMP最基本的一些知识,这些知识可以简要的从GMP的手册中学习掌握。

比如:

12.1 C++ Interface General

All the C++ classes and functions are available with

     #include <gmpxx.h>

Programs should be linked with the libgmpxx and libgmp libraries. For example,

     g++ mycxxprog.cc -lgmpxx -lgmp

The classes defined are

— Class:  mpz_class
— Class:  mpq_class
— Class:  mpf_class

12.2 C++ Interface Integers

— Function:  mpz_class::mpz_class ( type n)

Construct an mpz_class. All the standard C++ types may be used, except long long and long double, and all the GMP C++ classes can be used, although conversions from mpq_class and mpf_class are explicit. Any necessary conversion follows the corresponding C function, for exampledouble follows mpz_set_d (see Assigning Integers).

— Function: explicit  mpz_class::mpz_class ( const mpz_t z)

Construct an mpz_class from an mpz_t. The value in z is copied into the new mpz_class, there won't be any permanent association between it andz.


12.5 C++ Interface Random Numbers

— Class:  gmp_randclass

The C++ class interface to the GMP random number functions uses gmp_randclass to hold an algorithm selection and current state, as pergmp_randstate_t.

— Function:  gmp_randclass::gmp_randclass ( void ( *randinit) ( gmp_randstate_t, ...) ...)

Construct a gmp_randclass, using a call to the given randinit function (see Random State Initialization). The arguments expected are the same as randinit, but with mpz_class instead of mpz_t. For example,

          gmp_randclass r1 (gmp_randinit_default);
          gmp_randclass r2 (gmp_randinit_lc_2exp_size, 32);
          gmp_randclass r3 (gmp_randinit_lc_2exp, a, c, m2exp);
          gmp_randclass r4 (gmp_randinit_mt);

Also there are no automatic conversions from the classes to the corresponding GMP C types, instead a reference to the underlying C object can be obtained with the following functions,

— Function: mpz_t  mpz_class::get_mpz_t ()
— Function: mpq_t  mpq_class::get_mpq_t ()
— Function: mpf_t  mpf_class::get_mpf_t ()

These can be used to call a C function which doesn't have a C++ class interface. For example to set a to the GCD of b and c,

     mpz_class a, b, c;
     ...
     mpz_gcd (a.get_mpz_t(), b.get_mpz_t(), c.get_mpz_t());






三, 基于JPBC的初步实验




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值