Example #1
0
/*
 * gen_priv_key()
 */
void gen_priv_key(const unsigned int seed) {
  uint1024 a,one;
  int i;

  if (verbose>1)  puts("  Generating items");
  srandom(seed);

  uint_to_1024(priv_sum,0);
  
  for (i=0; i<ITEMS; i++) {
    uint_to_1024(private_key[i],0);
    while (cmp1024(private_key[i],priv_sum)<=0) {
      shl1024(private_key[i],4);
      uint_to_1024(a,(uint) (16.0*random()/RAND_MAX));
      add1024(private_key[i],a);
    }
    add1024(priv_sum,private_key[i]);

  }
  
  if (verbose>1) puts("  Counting 'm'"); 
  find_m();
  
  if (verbose>1) puts("  Counting 'v'");
  find_v();
  
  if (verbose>1) puts("  Counting 'u'");
  find_u();

  if (verbose>1) puts("  Checking u*v=1 (mod m)");
  cpy1024(a, u);
  mul1024modN(a,v,m);
  uint_to_1024(one,1);
  if (cmp1024(one,a)) {
	  puts("!! WARNING !! u*v != 1 (mod m) !! WARNING !!");
	  puts("This key will provide only one-way trip !");
	  if (verbose>1) 
		  puts("E.g. it's usable only for encryption, not decryption !");
  }
}
Example #2
0
int main()
{
	PFC pfc(AES_SECURITY);  // initialise pairing-friendly curve
	miracl *mip=get_mip();  // get handle on mip (Miracl Instance Pointer)
	time_t seed;
	int i,j,k,l,n,m,d,nS;
	Big **LSSS;
	int *attr;
	Big det,order=pfc.order();  // get pairing-friendly group order

	Big alpha,a,M,CT,s,t;
	G2 g2,g2a,*h,CD;
	G1 g1,g1a,K,L,MSK;
	GT eg2g1a,mask;

	time(&seed);       // initialise (insecure!) random numbers
    irand((long)seed);

// Setup

	pfc.random(alpha);
	pfc.random(a);
	pfc.random(g1);
	pfc.random(g2);
	pfc.precomp_for_mult(g1);  // g1 is fixed, so precompute on it
	pfc.precomp_for_mult(g2);  // g2 is fixed, so precompute on it

	eg2g1a=pfc.power(pfc.pairing(g2,g1),alpha);
	pfc.precomp_for_power(eg2g1a);

	g1a=pfc.mult(g1,a);
	g2a=pfc.mult(g2,a);
	pfc.precomp_for_mult(g2a);  // g2a is fixed, so precompute on it

	h=new G2[U]; 
	for (i=0;i<U;i++)
	{
		pfc.random(h[i]);
		pfc.precomp_for_mult(h[i]);  // precompute on h[.]
	}
	MSK=pfc.mult(g1,alpha);

// Encrypt

	m=find_m(Access);
	d=find_d(Access);

	LSSS=new Big *[m];
	for (i=0;i<m;i++)
		LSSS[i]=new Big[d+1]; // get memory for each row
	attr=new int [m];

	make_LSSS(Access,m,d,LSSS,attr); // create LSSS matrix from Access structure
	
	cout << "LSSS matrix " << m << "x" << d << endl;
	for (i=0;i<m;i++)
	{
		for (j=0;j<d;j++)
			cout << LSSS[i][j] << " ";
		cout << "    " << (char)attr[i] << endl;
	}
	cout << endl;

	mip->IOBASE=256;
	M=(char *)"test message"; 
	cout << "Message to be encrypted=   " << M << endl;
	mip->IOBASE=16;

	Big *v=new Big [d];
	Big *lambda=new Big [m];
	Big *r=new Big [m];
	for (i=0;i<d;i++)
		pfc.random(v[i]);
	s=v[0];
	for (i=0;i<m;i++)
		pfc.random(r[i]);
	
	G2 *C=new G2 [m];
	G1 *D=new G1 [m];

	for (i=0;i<m;i++)
	{
		lambda[i]=0;
		for (j=0;j<d;j++)
			lambda[i]+=modmult(LSSS[i][j],v[j],order);
		lambda[i]%=order;
	}

	CT=lxor(M,pfc.hash_to_aes_key(pfc.power(eg2g1a,s)));
	CD=pfc.mult(g2,s);

	for (i=0;i<m;i++)
	{
		C[i]=pfc.mult(g2a,lambda[i])+pfc.mult(h[attr[i]-'A'],-r[i]);
		D[i]=pfc.mult(g1,r[i]);
	}

// keygen
	cout << "Generating keys" << endl;
	pfc.random(t);
	K=MSK+pfc.mult(g1a,t);
	L=pfc.mult(g1,t);

	G2 *KX=new G2[U];
	nS=0;
	while (auth[nS]!=0)
	{
		j=auth[nS++]-'A';
		KX[j]=pfc.mult(h[j],t);
		pfc.precomp_for_pairing(KX[j]);
	}

// decrypt - and apply some optimisations e.g. e(A,B)*e(A,C) = e(A,B+C)
	cout << "Decrypting" << endl;
    int *rows=new int [m];
	Big *w=new Big [m];

	if (!reduce_LSSS(order,m,d,LSSS,attr,auth,rows,w)) 
	{
		cout << "Unable to decrypt - insufficient attributes" << endl;
		exit(0);
	}
	cout << "reduced matrix= " << m << "x" << d << endl;

// Note that w[i] are usually very small, so this is fast
	
	G2 TC;
	for (i=0;i<m;i++)
	{
		cout << "w[i]=  " << w[i] << endl;
		TC=TC+pfc.mult(C[rows[i]],w[i]);
		D[rows[i]]=pfc.mult(D[rows[i]],-w[i]);
	}
	TC=-TC;

// combine rows which share same attribute

	for (i=0;i<m;i++)
	{
		k=rows[i];
		for (j=i+1;j<m;j++)
		{
			if (attr[j]==attr[i])
			{
				D[k]=D[k]+D[rows[j]];  // combine them
				for (n=j;n<m;n++)
				{
					rows[n]=rows[n+1];
					attr[n]=attr[n+1];
				}
				m--;  // delete row
			}
		}
	}

	G2 **t2=new G2* [m+2];
	G1 **t1=new G1* [m+2];

	t2[0]=&CD; t1[0]=&K;  // e(CD,K)
	t2[1]=&TC; t1[1]=&L;  // e(TC,L)
	for (i=0;i<m;i++)
	{
		t2[i+2]=&KX[attr[i]-'A'];
		t1[i+2]=&D[rows[i]];
	}

	mask=pfc.multi_pairing(m+2,t2,t1);  // most pairings benefit from precomputation

	M=lxor(CT,pfc.hash_to_aes_key(mask));

	mip->IOBASE=256;
	cout << "Decrypted message=         " << M << endl;

	return 0;
}