Files
csprng_test/test_bbs.c
T
2026-06-15 10:31:58 +02:00

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;
}