#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "poly.h"
#include "params.h"
#include "byte.h"
#include "sig.h"
#include "fips202.h"
#include "ntt.h"
#include "rand.h"

#define NTESTS 10000

//验证测试向量函数
int verify_vector() {
	int i, j;
	unsigned char rdlen[4], sklen[4], pklen[4], mlen[4], smlen[4], result[1];
	unsigned char rd[48], sk[2944], pk[2432], m[256], sm[2135];
	unsigned char sk1[2944], pk1[2432], sm1[2135];
	unsigned long long pk_size[1] = { 0 }, sk_size[1] = { 0 }, sm_size[1] = { 0 };
	FILE *fp;
	fopen_s(&fp, "SIG_VEC_INFO(10).dat", "rb+");
	//for (i = 0; i < 10; i++) {
	//fseek(fp, 0, SEEK_SET);
	//读取随机种子长度
	fread(rdlen, 1, 4, fp);
	printf("%d\t", (rdlen[2] << 8) + rdlen[3]);
	//读取随机数
	fread(rd, 1, 48, fp);
	//读取私钥长度
	fread(sklen, 1, 4, fp);
	printf("%d\t", (sklen[2] << 8) + sklen[3]);
	//读取私钥
	fread(sk, 1, 2944, fp);
	//读取公钥长度
	fread(pklen, 1, 4, fp);
	printf("%d\t", (pklen[2] << 8) + pklen[3]);
	//读取公钥
	fread(pk, 1, 2432, fp);
	//读取明文长度
	fread(mlen, 1, 4, fp);
	printf("%d\t", (mlen[2] << 8) + mlen[3]);
	//读取明文
	fread(m, 1, 256, fp);
	//读取签名长度
	fread(smlen, 1, 4, fp);
	printf("%d\t", (smlen[2] << 8) + smlen[3]);
	//读取签名
	fread(sm, 1, 2135, fp);
	//读取验证结果
	fread(result, 1, 1, fp);
	printf("%d\n", result[0]);

	fclose(fp);

	rand_init(rd, 48);
	sig_keygen(pk1, pk_size, sk1, sk_size);
	sig_sign(sk1, sk_size[0], m, MLEN, sm1, sm_size);
	j = sig_verf(pk1, pk_size[0], sm1, sm_size[0], m, MLEN);
	for (i = 0; i < 2944; i++) {
		if (sk[i] != sk1[i]) {
			printf("sk diff\n");
			return 0;
		}
	}
	for (i = 0; i < 2432; i++) {
		if (pk[i] != pk1[i]) {
			printf("pk dif\n");
			return 0;
		}
	}
	for (i = 0; i < 2135; i++) {
		if (sm[i] != sm1[i]) {
			printf("sm dif\n");
			printf("%d\n", i);
			return 0;
		}
	}
	return j;
}

int main()
{
	clock_t start,finish;
	double t1=0,t2=0,t3=0;
	unsigned long long pk_size[1] = { 0 }, sk_size[1] = { 0 };
	int32_t arr[5] = { 805306368,2148204544,2148073472,65536,1460142080 };//{48,2944,2432,256,2135}
	int32_t a[N]={0},b[N]={0},c[N]={0},d[N]={1}, i,j=0;
	unsigned long long smlen[1];
	unsigned char  m[256], pk[N_BYTES],sk[N2+N_BYTES],temp[256],sm[ULEN + RLEN + L_BYTES],j1,rb[N];
	//unsigned char rd[48] = { 0 };
	//rand_init(rd, 256);
	//for (i = 0; i < NTESTS; i++) {
	//	randombytes(temp, 256);
	//	start = clock();
	//	sig_keygen(pk, pk_size, sk, sk_size);
	//	finish = clock();
	//	t1 = t1+(double)(finish - start) / CLOCKS_PER_SEC;
	//	
	//	start = clock();
	//	sig_sign(sk, sk_size, temp, MLEN, sm, smlen);
	//	finish = clock();
	//	t2 = t2+(double)(finish - start) / CLOCKS_PER_SEC;
	//	
	//	start = clock();
	//	j = sig_verf(pk, pk_size, sm, smlen[0], temp, MLEN);
	//	finish = clock();
	//	t3 = t3+(double)(finish - start) / CLOCKS_PER_SEC;

	//	if (j == 1) printf("success\n");
	//	if (j != 1) printf("wrong\n");
	//}
	//printf("keygen time  :%f us\n", (t1 * 1000000 / NTESTS));
	//printf("sign time  :%f us\n", (t2 * 1000000 / NTESTS));
	//printf("verify time  :%f us\n", (t3 * 1000000 / NTESTS));
 //   printf("\n");


	FILE *fpt;
	unsigned char rd[48] = { 0 }, bg[48] = { 1,2,3,4,5,6,7,8,9,10 };

	rand_init(bg, 48);
	randombytes(temp, 256);
	randombytes(rd, 48);
	rand_init(rd, 48);
	fopen_s(&fpt, "SIG_VEC_INFO(10).dat", "wb+");
	fwrite(arr, 4, 1, fpt);
	fwrite(rd, sizeof(rd), 1, fpt);
	
	sig_keygen(pk, pk_size, sk, sk_size);

	fwrite(arr + 1, 4, 1, fpt);
	fwrite(sk, sizeof(sk), 1, fpt);
	fwrite(arr + 2, 4, 1, fpt);
	fwrite(pk, sizeof(pk), 1, fpt);

	sig_sign(sk, sk_size[0], temp, MLEN, sm, smlen);

	fwrite(arr + 3, 4, 1, fpt);
	fwrite(temp, sizeof(temp), 1, fpt);
	fwrite(arr + 4, 4, 1, fpt);
	fwrite(sm, sizeof(sm), 1, fpt);

	j = sig_verf(pk, pk_size[0], sm, smlen[0], temp, MLEN);
	if (j != 1) printf("wrong\n");
	j1 = j & 0xff;
	fwrite(&j1, sizeof(j1), 1, fpt);

	fclose(fpt);


	if (verify_vector()) printf("测试向量验证正确");


	return 0;
}