163 lines
4.3 KiB
C
163 lines
4.3 KiB
C
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include "test_bbs.h"
|
|
|
|
|
|
static int gcd(unsigned long a, unsigned long b){
|
|
if (b == 0)
|
|
return a;
|
|
return gcd(b, a % b);
|
|
}
|
|
|
|
static int isPrimeNumber(unsigned int x){
|
|
for (int i = 0; i < SIEVES_LEN; i++){
|
|
if (x % sieves[i] == 0)
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/*
|
|
* This function check if the prime number x is congruent 3 modulo 4
|
|
*/
|
|
static int isCongruent(unsigned int x){
|
|
int res = x % 4;
|
|
if (res != 3)
|
|
return res;
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
* This function convert a bit sequences store in the char * to unsigned long long
|
|
*/
|
|
static unsigned long long bitToUl(char *bits){
|
|
unsigned long long o = 0;
|
|
for (int i = 0; i < strlen(bits); i++)
|
|
o = (o << 1) + bits[i] - '0';
|
|
return o;
|
|
}
|
|
/*
|
|
* This function write to the report file
|
|
*/
|
|
static void writeToReport(int fd, const char *buf, ...){
|
|
char str[BUF_FILE];
|
|
va_list va;
|
|
va_start(va, buf);
|
|
//snprintf(str, BUF_FILE, buf, va);
|
|
vsnprintf(str, BUF_FILE, buf, va);
|
|
|
|
write(fd, str, strlen(str));
|
|
|
|
va_end(va);
|
|
}
|
|
/*
|
|
* This function test the BBS algorithm received from the STM32 board
|
|
* Return 0 if succeed otherwise return -1
|
|
*/
|
|
int test_bbs(int fd, unsigned int p, unsigned int q, unsigned long long seed, unsigned long long g){
|
|
int res = 0;
|
|
/*
|
|
* Check if p and q are prime numbers
|
|
*/
|
|
writeToReport(fd, "Testing p (%d)\n", p);
|
|
|
|
res = isPrimeNumber(p);
|
|
|
|
if (!res){
|
|
writeToReport(fd, "p is not a prime number. The has failed.\n");
|
|
return -1;
|
|
}
|
|
writeToReport(fd, "p is a prime number. The test has succeeded.\n\n", q);
|
|
|
|
writeToReport(fd, "Testing q (%d)\n", q);
|
|
res = isPrimeNumber(q);
|
|
|
|
if (!res){
|
|
writeToReport(fd, "q is not a prime number. The has failed.\n");
|
|
return -1;
|
|
}
|
|
writeToReport(fd, "q is a prime number. The test has succeeded.\n\n", q);
|
|
|
|
// Check if is congruent 3 modulo 4
|
|
writeToReport(fd, "Testing p congruent 3 modulo 4:\n");
|
|
res = isCongruent(p);
|
|
if (res >= 0){
|
|
writeToReport(
|
|
fd,
|
|
"p is not congruent 3 modulo 4, but congruent %d. The test has failed.\n",
|
|
res
|
|
);
|
|
return -1;
|
|
}
|
|
writeToReport(
|
|
fd,
|
|
"p is congruent 3 modulo 4. The test has succeeded.\n\n"
|
|
);
|
|
|
|
writeToReport(fd, "Testing q congruent 3 modulo 4:\n");
|
|
res = isCongruent(q);
|
|
if (res >= 0){
|
|
writeToReport(fd,
|
|
"q is not congruent 3 modulo 4, but congruent %d. The test has failed.\n",
|
|
res
|
|
);
|
|
return -1;
|
|
}
|
|
writeToReport(fd, "q is congruent 3 modulo 4. The test has succeeded.\n\n");
|
|
|
|
// Check if n is correct
|
|
unsigned long long n = (unsigned long long)p * (unsigned long long)q;
|
|
writeToReport(fd, "n: %llu\n", n);
|
|
|
|
// Check if seed is in the range 1 < seed < n - 1
|
|
writeToReport(fd, "Testing seed:\n");
|
|
if (seed < 1 || seed > n - 1){
|
|
writeToReport(
|
|
fd,
|
|
"Seed (%llu) is not in the range 1 < seed < n - 1. "
|
|
"The test has failed\n",
|
|
seed
|
|
);
|
|
return -1;
|
|
}
|
|
writeToReport(fd, "The seed test has passed.\n\n");
|
|
|
|
// Check if seed satisfy the equation: gcd(seed, n) = 1
|
|
writeToReport(fd, "Testing gcd(seed, n) = 1:\n");
|
|
int res_gcd = gcd(seed, n);
|
|
if (res_gcd != 1){
|
|
writeToReport(
|
|
fd,
|
|
"the result of the gcd(seed, n) = %d. "
|
|
"The test has failed.\n",
|
|
res_gcd
|
|
);
|
|
return -1;
|
|
}
|
|
writeToReport(fd, "gcd (seed, n) = %d. The has passed.\n\n", res_gcd);
|
|
|
|
// Check least bit significant
|
|
unsigned long long tmp = (seed * seed) % n;
|
|
|
|
char bits[ITER_BBS];
|
|
memset(bits, 0, ITER_BBS);
|
|
int pos = 0;
|
|
for (size_t i = 1; i < ITER_BBS; i++){
|
|
unsigned long long x = (tmp * tmp) % n;
|
|
bits[pos++] = (x & 1) + '0';
|
|
tmp = x;
|
|
}
|
|
|
|
/* We convert the bit sequence to unsigned long long */
|
|
unsigned long long output = bitToUl(bits);
|
|
if (output != g){
|
|
writeToReport(fd, "The random generated has failed.\n");
|
|
return -1;
|
|
}
|
|
writeToReport(fd, "Random number: %llu\n", g);
|
|
writeToReport(fd, "All tests has passed with success, the BBS algorithm works.\n\n");
|
|
return 0;
|
|
}
|