//
//  main.c
//  c
//


#include "parameter.h"
#include  "pke.h"
#include  "kem.h"
#include "rng.h"
#include  <time.h>
#include <stdint.h>
#include <stdio.h>
#include "rand.h"
#include"poly.h"
#include "fips202.h"
#include <openssl/rand.h>

#define ROUND 10000


//test the correctness and the speed of KEM
void test_kem()
{


	clock_t start, finish;
	double total_time1 = 0;
	double total_time2 = 0;
	double total_time3 = 0;
	int i, result;
	unsigned char kem_pk[KEM_PUBLICKEYBYTES], kem_sk[KEM_SECRETKEYBYTES], ct[KEM_CIP_BYTES], ss[KEM_KEYBYTES];
	unsigned long long ct_byts, pk_byts, ss_byts, sk_byts;

	for (i = 0; i < ROUND; i++)
	{
		start = clock();
		kem_keygen(kem_pk, &pk_byts, kem_sk, &sk_byts);
		finish = clock();
		total_time1 += (double)(finish - start) / CLOCKS_PER_SEC;

		
		start = clock();
		kem_enc(kem_pk, pk_byts, ss, &ss_byts, ct, &ct_byts);
		finish = clock();
		total_time2 += (double)(finish - start) / CLOCKS_PER_SEC;

		start = clock();
		result = kem_dec(kem_sk, sk_byts, ct, ct_byts, ss, &ss_byts);
		finish = clock();
		total_time3 += (double)(finish - start) / CLOCKS_PER_SEC;

		if (result == -1)
			printf("Incorrect!\n");

	}
	printf("\n");
	printf("kem keygen time:%f ms\n", (total_time1 * 1000 / ROUND));
	printf("kem enc time:%f ms\n", (total_time2 * 1000/ ROUND));
	printf("kem dec time:%f ms\n", (total_time3 * 1000 / ROUND));

}

int main() {

    
  
   //测试正确性和性能
   test_kem();

   //测试向量
   unsigned char kem_pk[KEM_PUBLICKEYBYTES], kem_sk[KEM_SECRETKEYBYTES], ct[KEM_CIP_BYTES], ss[KEM_KEYBYTES];
   unsigned long long ct_byts, pk_byts, ss_byts, sk_byts;
   FILE *fpt;

   unsigned char seed[48];
   uint32_t BYTES[5] = {805306368,3222011904,537264128,458752,2147483648};//48,3264,1568,1792,128
   
   //memset(seed, 0, 48);
   //seed[0] = 1;
   RAND_bytes(seed,48);//生成随机种子

   fopen_s(&fpt, "KEM_VEC_INFO.dat", "wb+");
   fwrite(BYTES, 4, 1, fpt);//随机种子长度
   fwrite(seed, 48, 1, fpt);//私钥

   rand_init(seed, 48);
   kem_keygen(kem_pk, &pk_byts, kem_sk, &sk_byts);

   fwrite(BYTES + 1, 4, 1, fpt);//私钥长度
   fwrite(kem_sk, sk_byts, 1, fpt);//私钥
   fwrite(BYTES + 2, 4, 1, fpt);//公钥长度
   fwrite(kem_pk, pk_byts, 1, fpt);//公钥

   kem_enc(kem_pk, pk_byts, ss, &ss_byts, ct, &ct_byts);

   fwrite(BYTES + 3, 4, 1, fpt);//密文长度
   fwrite(ct, ct_byts, 1, fpt);//密文

   kem_dec(kem_sk, sk_byts, ct, ct_byts, ss, &ss_byts);

   fwrite(BYTES + 4, 4, 1, fpt);//共享密钥长度
   fwrite(ss, ss_byts, 1, fpt);//共享密钥
   fclose(fpt);
	
  

  
   system("pause");

   
    return 0;
    
    
    
}
