Skip to content

Commit

Permalink
feat: benchmarks for primes and biguint operations (#34)
Browse files Browse the repository at this point in the history
* perf: avoid open/close when generating random numbers

* chore: fix some warnings in sha lib

* perf: make random number always odd in random_prime

* feat: primes benchmarks

* feat: biguint operation benchmarks

* feat: rsa key generation benchmarks

* feat: show function args in benchmark

* refactor: add custom name to benchmarks
  • Loading branch information
MarcosNicolau authored Jan 29, 2025
1 parent d9f1790 commit 75fdf7b
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 17 deletions.
21 changes: 21 additions & 0 deletions libs/digital-signature/benchmarks/rsa.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <digital-signature/rsa.h>
#include <math/random.h>
#include <utils/benchmark.h>

#define DEFINE_KEY_GEN_BENCHMARKS(BIT_SIZE) \
void benchmark_rsa_key_generation##BIT_SIZE() { \
RSAKeyPair key_pair = rsa_key_pair_new(BIT_SIZE); \
rsa_gen_key_pair(&key_pair); \
}

DEFINE_KEY_GEN_BENCHMARKS(256)
DEFINE_KEY_GEN_BENCHMARKS(512)
DEFINE_KEY_GEN_BENCHMARKS(1024)

int main() {
BEGIN_BENCHMARK();
benchmark("rsa_key_generation 256 bits", benchmark_rsa_key_generation256, 1);
benchmark("rsa_key_generation 512 bits", benchmark_rsa_key_generation512, 1);
benchmark("rsa_key_generation 1024 bits", benchmark_rsa_key_generation1024, 1);
END_BENCHMARK();
}
2 changes: 1 addition & 1 deletion libs/hashes/src/sha2.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ uint32_t sigma1(uint32_t x) { return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10); };

void sha256_process(sha256 *hash) {
uint32_t w[64];
memset(w, 0, 64);
memset(w, 0, 64 * sizeof(uint32_t));

// we need to fit the 64 entries bytes into 16 entries
// so each entry needs to have a size of 4 bytes
Expand Down
4 changes: 0 additions & 4 deletions libs/hashes/tests/sha2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
#include <string.h>
#include <utils/test.h>

#include <hashes/sha256.h>
#include <string.h>
#include <utils/test.h>

void test_sha256_empty() {
sha256 hash = sha256_new();
sha256_update(&hash, (uint8_t *)"", 0);
Expand Down
50 changes: 50 additions & 0 deletions libs/math/benchmarks/primes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <math/primes.h>
#include <math/random.h>
#include <utils/benchmark.h>

void benchmark_random_prime(int size) {
BigUint a = biguint_new_heap(size);
biguint_random_prime(&a);
biguint_free(&a);
}

void benchmark_is_prime_solovay_strassen(int size, char *prime) {
BigUint a = biguint_new_heap(size);
biguint_from_dec_string(prime, &a);
biguint_is_prime_solovay_strassen(a);
biguint_free(&a);
}

void benchmark_jacobi(int size, char *prime) {
BigUint p = biguint_new_heap(size);
BigUint a = biguint_new_heap(size);
biguint_from_dec_string(prime, &p);
biguint_random(&a);
jacobi(a, p);
biguint_free(&a, &p);
}

int main() {
BEGIN_BENCHMARK()
benchmark("random_prime 256 bits", benchmark_random_prime, 1, 4);
benchmark("random_prime 512 bits", benchmark_random_prime, 1, 8);
benchmark("random_prime 1024 bits", benchmark_random_prime, 1, 16);
benchmark("is_prime_solovay_strassen 512 bits prime", benchmark_is_prime_solovay_strassen, 1, 8,
"34335733933145862804940350952130198968391666739716830607881089259566479256360992225995345130785490553890"
"25695338868874287109369850868158680127720763571503");
benchmark("is_prime_solovay_strassen 1024 bits prime", benchmark_is_prime_solovay_strassen, 1, 16,
"24655650060360753080142862709006690867636082763996432687872619014553026794142593984738962973795417850400"
"85414073637172246986341398241070222037495540411160258675361723321157569314242853171336423647307914642357"
"9483846036052104816190148409971239514167619589698929804939809242854000598245576619523371634111874143");
benchmark("jacobi 512 bits prime", benchmark_jacobi, 1, 8,
"34335733933145862804940350952130198968391666739716830607881089259566479256360992225995345130785490553890"
"25695338868874287109369850868158680127720763571503");
benchmark("jacobi 1024 bits prime", benchmark_jacobi, 1, 16,
"24655650060360753080142862709006690867636082763996432687872619014553026794142593984738962973795417850400"
"85414073637172246986341398241070222037495540411160258675361723321157569314242853171336423647307914642357"
"9483846036052104816190148409971239514167619589698929804939809242854000598245576619523371634111874143");

END_BENCHMARK()

return 0;
}
4 changes: 3 additions & 1 deletion libs/math/include/primes.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ const unsigned int PRIMES[PRIMES_LENGTH] = {
7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817,
7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919};

#define SOLOVAY_STRASSEN_TEST_SAMPLES 100
#define SOLOVAY_STRASSEN_TEST_SAMPLES 20

void biguint_random_prime(BigUint *a);
int biguint_is_prime(BigUint a);
int biguint_is_prime_solovay_strassen(BigUint p);
int jacobi(BigUint a, BigUint n);

#endif
2 changes: 2 additions & 0 deletions libs/math/src/primes.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ void biguint_random_prime(BigUint *a) {
biguint_random(a);
while (!biguint_is_prime(*a)) {
biguint_random(a);
// make it odd
a->limbs[0] |= 1;
}
}

Expand Down
12 changes: 7 additions & 5 deletions libs/math/src/random.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#include <random.h>

static FILE *urandom_file = NULL;

uint64_t u64_random() {
uint64_t randval;
FILE *f;

// use urandom https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
f = fopen("/dev/urandom", "r");
fread(&randval, sizeof(randval), 1, f);
fclose(f);
if (urandom_file == NULL) {
// use urandom https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
urandom_file = fopen("/dev/urandom", "r");
}
fread(&randval, sizeof(randval), 1, urandom_file);

return randval;
}
Expand Down
57 changes: 53 additions & 4 deletions libs/primitive-types/benchmarks/biguint.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,65 @@
#include <primitive-types/biguint.h>
#include <utils/benchmark.h>

void benchmark_add() {
BigUint a = biguint_new(16);
BigUint b = biguint_new(16);
biguint_random(&a);
biguint_random(&b);
biguint_add(&a, b);
}

void benchmark_sub() {
BigUint a = biguint_new(16);
BigUint b = biguint_new(16);
biguint_random(&a);
biguint_random(&b);
biguint_sub(&a, b);
}

void benchmark_divmod() {
BigUint a = biguint_new(4);
BigUint b = biguint_new(4);
BigUint a = biguint_new(16);
BigUint b = biguint_new(16);
BigUint c = biguint_new(16);
BigUint d = biguint_new(16);
biguint_random(&a);
biguint_random(&b);
biguint_divmod(a, b, &c, &d);
}

void benchmark_mul() {
BigUint a = biguint_new(16);
BigUint b = biguint_new(16);
biguint_random(&a);
biguint_random(&b);
biguint_mul(&a, b);
}

void benchmark_pow() {
BigUint a = biguint_new(16);
BigUint b = biguint_new(16);
biguint_random(&a);
biguint_random(&b);
biguint_pow(&a, b);
}

void benchmark_pow_mod() {
BigUint a = biguint_new(16);
BigUint b = biguint_new(16);
BigUint m = biguint_new(16);
biguint_random(&a);
biguint_random(&b);
biguint_divmod(a, b, &a, &b);
biguint_random(&m);
biguint_pow_mod(&a, b, m);
}

int main() {
BEGIN_BENCHMARK();
benchmark(benchmark_divmod, 1000000);
benchmark("biguint_add random 1024 bits", benchmark_add, 1000000);
benchmark("biguint_sub random 1024 bits", benchmark_sub, 1000000);
benchmark("biguint_divmod random 1024 bits", benchmark_divmod, 1000000);
benchmark("biguint_mul random 1024 bits", benchmark_mul, 1000000);
benchmark("biguint_pow random 1024 bits", benchmark_pow, 1000);
benchmark("biguint_pow_mod random 1024 bits", benchmark_pow_mod, 10);
END_BENCHMARK();
}
4 changes: 2 additions & 2 deletions libs/utils/include/benchmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#include <time.h>
#include <utils/macros.h>

#define benchmark(benchmark_fn, iterations, ...) \
#define benchmark(name, benchmark_fn, iterations, ...) \
do { \
printf("\n=============== %s (%d iterations) ===============\n", #benchmark_fn, iterations); \
printf("\n=============== %s (%d iterations) ===============\n", name, iterations); \
int ANONYMOUS_VARIABLE(benchmark_fn) = 0; \
double measures[iterations]; \
for (; ANONYMOUS_VARIABLE(benchmark_fn) < iterations; ANONYMOUS_VARIABLE(benchmark_fn)++) { \
Expand Down

0 comments on commit 75fdf7b

Please sign in to comment.