Exemplo n.º 1
0
int main(void) {
    u8         output[64], stream[64];
    ECRYPT_ctx ctx;
    int        i;
    
    // test the permutation first
    for(i=0;i<64;i++) stream[i]=(i+1);
    
    for(i=0;i<2048;i++) {
      salsa20_wordtobyte(output, (u32*)stream);
    }
    bin2hex("permutation result", output, 64);
      
    memset(&ctx, 0, sizeof(ctx));
    
    ECRYPT_keysetup(&ctx, tv_key, 256, 64);
    ECRYPT_ivsetup(&ctx, tv_nonce);
    
    for(i=0;i<2048;i++) {
      ECRYPT_keystream_bytes(&ctx, stream, 64);
    }
    
    bin2hex("stream result", stream, 64);
    return 0;
}
Exemplo n.º 2
0
void perform_iterated_test (u8 *key)
{
    ECRYPT_ctx ctx;
        /* Keystream generator context */
    u8 iv[4];
        /* Array to contain iv derived from keystream */
    u8 keystream[16];
        /* Array to contain generated keystream bytes */
    int i;
        /* Counting variable */

    /* Display the key */
    printf ("Iterated test key =");
    for (i=0; i<10; i++)
        printf (" %02x", key[i]);
    printf ("\n");

    /* Load key */
    ECRYPT_keysetup (&ctx, key, 80, 0);
    ECRYPT_ivsetup (&ctx, iv);

    for (i=0; i<1000; i++)
    {
        /* Generate new key and iv from keystream */
        ECRYPT_keystream_bytes (&ctx, key, 10);
        ECRYPT_keystream_bytes (&ctx, iv, 4);

        /* Load new key */
        ECRYPT_keysetup (&ctx, key, 80, 32);

        /* Load new IV */
        ECRYPT_ivsetup (&ctx, iv);
    }

    /* Generate keystream */
    ECRYPT_keystream_bytes (&ctx, keystream, 16);

    /* Display the derived keytream */
    printf ("Final keystream   =");
    for (i=0; i<16; i++)
        printf (" %02x", keystream[i]);
    printf ("\n");

    printf ("\n");

}
Exemplo n.º 3
0
void perform_test (u8 *key, u8* iv, int iv_length_in_bits)
{
    ECRYPT_ctx ctx;
        /* Keystream generator context */
    u8 keystream[16];
        /* Array to contain generated keystream bytes */
    int i;
        /* Counting variable */

    /* Load key */
    ECRYPT_keysetup (&ctx, key, 80, iv_length_in_bits);
    /* Load IV */
    ECRYPT_ivsetup (&ctx, iv);
    /* Generate keystream */
    ECRYPT_keystream_bytes (&ctx, keystream, 16);

    /* Display the key */
    printf ("Key               =");
    for (i=0; i<10; i++)
        printf (" %02x", key[i]);
    printf ("\n");

    /* Display the IV */
    printf ("IV                =");
    for (i=0; i<(iv_length_in_bits+7)/8; i++)
        printf (" %02x", iv[i]);
    printf ("\n");

    /* Display the derived keytream */
    printf ("Keystream         =");
    for (i=0; i<16; i++)
        printf (" %02x", keystream[i]);
    printf ("\n");

    printf ("\n");

}
Exemplo n.º 4
0
void genOutput_diff_imp(u32 k,u32 *v,u64 N,string curr_DIR){
	//初始化 输入差分为全0 并输出当前组合v的对应的输入状态差分
	u8 *ISD=new u8[LEN]();
	for(int m=0;m<k;m++){
		//cout<<v[m]<<" "<<ends;
		u32 p=posIdx(v[m]-1);
		u32 r=rotateIdx(v[m]-1);
		ISD[p]=ISD[p]^(1<<r);
	}
	
	//for(int i=0;i<k;i++){
	//		if(v[i])
	//			cout<<v[i]<<" "<<ends;
	//}
	//cout<<"对应输入差分:"<<ends;
	//	for(int j=0;j<20;j++){
	//			printf("%x ",ISD[j]);
	//}
	//cout<<endl;
	
	map<string,u32> counter;
	//随机选择N个状态
	for(int i=0;i<N;i++){
		//cout<<"\n------Sample:"<<i+1<<"------"<<endl;
		u8 rnd_state_1[LEN];
		for(int j=0;j<LEN;j++){
			rnd_state_1[j]=rc4();
		}
		//根据差分位置,得到另一个状态rud_state_2
		u8 rnd_state_2[LEN];
		for(int j=0;j<LEN;j++){
			rnd_state_2[j]=rnd_state_1[j]^ISD[j];
		}
		//分别代入Grain中 输出l长的密钥流
		ECRYPT_ctx ctx_1;
		ctx_1.keysize=80;
		ctx_1.ivsize=64;
		u8 keyStream_1[KSLen];
		ECRYPT_ctx ctx_2;
		ctx_2.keysize=80;
		ctx_2.ivsize=64;
		u8 keyStream_2[KSLen];
		//将状态代入grain中,获得对应的长度为KSLen的密钥流,并输出其差分
		ECRYPT_grain_state_load(&ctx_1,rnd_state_1);
		ECRYPT_grain_state_load(&ctx_2,rnd_state_2);
		ECRYPT_keystream_bytes(&ctx_1,keyStream_1,KSLen);
		ECRYPT_keystream_bytes(&ctx_2,keyStream_2,KSLen);	
		//计算输出差分
		u8 Diff_KS[KSLen];
		for(int j=0;j<KSLen;j++){
			Diff_KS[j]=keyStream_1[j]^keyStream_2[j];
		}
		//统计各个差分出现的频率
		string str=char2HexString(Diff_KS,KSLen);
		map<string,u32>::iterator it=counter.find(str);
		if(it!=counter.end()){//已存在这个差分
			it->second+=1;
		}else
			counter.insert(make_pair(str,1));
	}
	//将counter中对应的输出差分存储到一个txt文件中(以输出差分的16进制表示命名),
	//将ISD转化成16进制+输出该差分的比例,存储在txt的一行。
	//最后统计每个txt的行数,求出平均的行数,也即每个table的大小(以输出差分的16进制命名)。
	string inputDiffStr=char2HexString(ISD,LEN);
	//首先遍历counter中的所有输出差分
	map<string,u32>::iterator beg=counter.begin();
	map<string,u32>::iterator end=counter.end();
	for(;beg!=end;beg++){
		string outDiff=beg->first;
		u32 occurs=beg->second;
		double occur_prop=(double)occurs/N;
		//将输入差分和比例 写入到以outDiff命名的txt中。
		string fileName=outDiff+".txt";
		//根据outDiff高1个字节进行索引 将所有输出根据高8比特输出到不同的文件夹中
		string Index_DIR=curr_DIR+outDiff.substr(0,2)+"\\";
		make_DIR(Index_DIR);
		fileName=Index_DIR+fileName;
		ofstream outfile;
		outfile.open(fileName.c_str(),ofstream::app);
		if(outfile){
			//cout<<"file \'"<<fileName<<"\' created."<<endl;
			outfile<<inputDiffStr<<" "<<occur_prop<<"\n";
			//cout<<"Successfully write:"<<inputDiffStr<<" "<<occur_prop<<" to file:" <<fileName<<endl;
		}
		outfile.close();
	}
	counter.clear();
	delete [] ISD;
}
Exemplo n.º 5
0
Arquivo: prng.cpp Projeto: sga001/vex
// generate new random state
void Prng::chacha_refill_randomness() {
  ECRYPT_keystream_bytes(chacha, random_state, RANDOM_STATE_SIZE);
  random_index = 0;
}
double Q_estimate_random_sampling(u32 d,u32 num_ISD,u64 N,u64 sub_N){
	map<string,u32> counter;
	set<string> poss_KSD;
	u64 sum=0;
	//随机选择num_ISD个差分
	for(int D=1;D<=num_ISD;D++){
		if(D % 400 ==0){
			cout<<"proceed "<<setprecision(3)<<(double)D*100/num_ISD<<"%..."<<endl;
		}
			u32* pos=new u32[d]();
		for(int j=0;j<d;j++){
			pos[j]=rc4() % 160;
		}
		//初始化 输入差分为全0
		u8 ISD[LEN];
		for(int j=0;j<LEN;j++){
			ISD[j]=0;
		}
		//引入差分
		for(int j=0;j<d;j++){
			u32 p=posIdx(pos[j]);
			u32 r=rotateIdx(pos[j]);
			ISD[p]=ISD[p]^(1<<r);
		}
		//随机选择N个状态
		for(u64 i=0;i<N;i++){
			//随机选择一个输入状态
			u8 rnd_state_1[LEN];
			for(int j=0;j<LEN;j++){
				rnd_state_1[j]=rc4();
			}
			//根据差分位置,得到另一个状态rud_state_2
			u8 rnd_state_2[LEN];
			for(int j=0;j<LEN;j++){
				rnd_state_2[j]=rnd_state_1[j]^ISD[j];
			}

			//分别代入Grain中
			ECRYPT_ctx ctx_1;
			ctx_1.keysize=80;
			ctx_1.ivsize=64;
			u8 keyStream_1[KSLen];
			ECRYPT_ctx ctx_2;
			ctx_2.keysize=80;
			ctx_2.ivsize=64;
			u8 keyStream_2[KSLen];
			//将状态代入grain中,获得对应的长度为KSLen的密钥流,并输出其差分
			ECRYPT_grain_state_load(&ctx_1,rnd_state_1);
			ECRYPT_grain_state_load(&ctx_2,rnd_state_2);
			ECRYPT_keystream_bytes(&ctx_1,keyStream_1,KSLen);
			ECRYPT_keystream_bytes(&ctx_2,keyStream_2,KSLen);
			//计算输出差分
			u8 Diff_KS[KSLen];
			for(int j=0;j<KSLen;j++){
				Diff_KS[j]=keyStream_1[j]^keyStream_2[j];
			}
			//统计各个差分出现的频率
			string str=char2HexString(Diff_KS,KSLen);
			map<string,u32>::iterator it=counter.find(str);
			if(it!=counter.end()){//已存在这个差分
				it->second+=1;
			}else
				counter.insert(make_pair(str,1));
		}
		delete [] pos;
		//通过最小值堆统计其比例最大的前sub_N个KSD proportion的平均值
		u64 dataSize=counter.size();
		u32 curr_sub_N=dataSize>sub_N?sub_N:dataSize;
		sum+=curr_sub_N;
		u32 heap_size=curr_sub_N; 
		u32 array_size=curr_sub_N+1;//堆的index从1开始计数。
		//首先建立数组
		KSD_Prop* KSD_prop_arr=new KSD_Prop[array_size];
		//将counter的前curr_sub_N个元素填充到堆中
		u64 currIdx=1;
		map<string,u32>::iterator beg=counter.begin();
		map<string,u32>::iterator end=counter.end();
		for(u32 i=0;i<curr_sub_N;i++){
			KSD_prop_arr[currIdx].KSD=beg->first;
			KSD_prop_arr[currIdx++].occurrance=beg->second;
			beg++;
		}
		//建堆操作
		BUILD_MIN_HEAP(KSD_prop_arr,heap_size);
		//从第curr_sub_N+1个元素开始,扫描所有counter中的元素,找到前sub_N个proportion最大的KSD
		for(;beg!=end;beg++){
			//首先和堆顶元素比较,如果比堆顶元素大,那么替换堆顶元素并保持堆的性质
			if(KSD_prop_arr[1].occurrance<beg->second){
				KSD_prop_arr[1].KSD=beg->first;
				KSD_prop_arr[1].occurrance=beg->second;
				HEAP_MIN_HEAPIFY(KSD_prop_arr,1,heap_size);
			}
		}
		//最后堆中的元素即为所求的前sub_N个proportion最大的KSD
		//u64 sum_occur=0;
		for(int i=1;i<array_size;i++){
			poss_KSD.insert(KSD_prop_arr[i].KSD);
		}
		////对KSD及其prop按照prop的大小进行排序
		//u64 dataSize=counter.size();
		//KSD_Prop* KSD_prop_arr=new KSD_Prop[dataSize];
		//u64 currIdx=0;
		//map<string,u32>::iterator beg=counter.begin();
		//map<string,u32>::iterator end=counter.end();
		//for(;beg!=end;beg++){
		//	KSD_prop_arr[currIdx].KSD=beg->first;
		//	KSD_prop_arr[currIdx++].occurrance=beg->second;
		//}
		////进行排序
		//qsort(KSD_prop_arr,dataSize,sizeof(KSD_Prop),comp_struct_KSD_Prop);
		////记录其前sub_N个KSD,当dataSize<sub_N时,就保存全部的dataSize个KSD
		//u64 curr_sub_N=dataSize>sub_N?sub_N:dataSize;
		//sum+=curr_sub_N;
		//for(u64 i=0;i<curr_sub_N;i++){
		//	poss_KSD.insert(KSD_prop_arr[i].KSD);
		//}
		counter.clear();
		delete [] KSD_prop_arr;
	}
	double prop_q=(double)poss_KSD.size()/sum;
	cout<<"对于(d,l)=("<<d<<","<<KSLen*8<<")而言,最终的比例为No. of KSD/No.of Sampling:"
		<<poss_KSD.size()<<"/"<<sum<<",比例为q:"<<prop_q<<endl;
	return prop_q;
}
double cal_all_KSD_with_Random_Sampling(u32 d, u64* N_array, u32 num_ISD){
	set<string> poss_KSD;
	double prop_q=0.0;
	u64 N_sum=0;
	u64 N=N_array[d-1];
	for(int D=1;D<=num_ISD;D++){
		////随机选取汉明重量HW_d <=d
		//u32 HW_d=0;
		//while(HW_d==0)
		//	HW_d= rc4() % (d+1);
		////根据HW_d选择样本量
		//u64 N=N_array[HW_d-1];
		//N_sum+=N;
		//随机选取160bit 状态的差分位置 NFSR从0~79,LFSR从80~159
		u32* pos=new u32[d]();
		for(int j=0;j<d;j++){
			pos[j]=rc4() % 160;
			//pos[j]=(rc4() % 80)+80;			//只给LFSR中引入差分
		}
		//初始化 输入差分为全0
		u8 ISD[LEN];
		for(int j=0;j<LEN;j++){
			ISD[j]=0;
		}
		//引入差分
		for(int j=0;j<d;j++){
			u32 p=posIdx(pos[j]);
			u32 r=rotateIdx(pos[j]);
			ISD[p]=ISD[p]^(1<<r);
		}
		//对每个差分随机选取N个状态
		for(u64 i=0;i<N;i++){
			//随机选择一个输入状态
			u8 rnd_state_1[LEN];
			for(int j=0;j<LEN;j++){
				rnd_state_1[j]=rc4();
			}
			//根据差分位置,得到另一个状态rud_state_2
			u8 rnd_state_2[LEN];
			for(int j=0;j<LEN;j++){
				rnd_state_2[j]=rnd_state_1[j]^ISD[j];
			}
			//分别代入Grain中
			ECRYPT_ctx ctx_1;
			ctx_1.keysize=80;
			ctx_1.ivsize=64;
			u8 keyStream_1[KSLen];
			ECRYPT_ctx ctx_2;
			ctx_2.keysize=80;
			ctx_2.ivsize=64;
			u8 keyStream_2[KSLen];
			//将状态代入grain中,获得对应的长度为KSLen的密钥流,并输出其差分
			ECRYPT_grain_state_load(&ctx_1,rnd_state_1);
			ECRYPT_grain_state_load(&ctx_2,rnd_state_2);
			ECRYPT_keystream_bytes(&ctx_1,keyStream_1,KSLen);
			ECRYPT_keystream_bytes(&ctx_2,keyStream_2,KSLen);
			//计算输出差分
			u8 Diff_KS[KSLen];
			for(int j=0;j<KSLen;j++){
				Diff_KS[j]=keyStream_1[j]^keyStream_2[j];
			}
			string str=char2HexString(Diff_KS,KSLen);
			poss_KSD.insert(str);
		}

		delete [] pos;
	}
	prop_q=(double)poss_KSD.size()/(num_ISD*N);
	cout<<"对于(d,l)=("<<d<<","<<KSLen*8<<")而言,最终的比例为No. of KSD/No.of Sampling:"
		<<poss_KSD.size()<<"/"<<num_ISD*N<<",比例为q:"<<prop_q<<endl;
	return prop_q;
}