Exemple #1
0
int find_d(int u, int f, int s) {
	sz[u] = 1;
	int mx = 0;
	for (int i = head[i]; i != -1; i = next[i]) {
		int v = to[i];
		if (v != f && !ban[v]) {
			find_d(v, u, s);
			sz[u] += sz[v];
			mx = max(mx, sz[v]);
		}
	}
	mx = max(mx, s - mx);
	if (mx < rmx) rmx = mx, d = u;
}
Exemple #2
0
int main(int argc, char ** argv)
{
	long long max_n, max_d;
	long long d;
	
	if(argc < 3)
		printf("Usage: %s max_n=%Ld max_d=%Ld\n", 
			argv[0], max_n = 15499, max_d = 94744);
	else
		max_n = atoi(argv[1]), max_d = atoi(argv[2]);
	
	printf("%Ld\n", find_d(max_n, max_d));
	
	return 0;
}
Exemple #3
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;
}