-
Notifications
You must be signed in to change notification settings - Fork 0
/
elgamal.c
43 lines (35 loc) · 1.22 KB
/
elgamal.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "elgamal.h"
#include "prime.h"
void elgamal_keygen(elgamal_keys_t *keys, int higher, uint64_t (*random64)(void)) {
if (higher) {
// generate new prime number & primitive root
do {
// large prime number p
keys->p = random_prime_u64(higher, random64);
#ifdef ELGAMAL_G_2
keys->g = 2;
#else
// primitive root g modulo p
// using other than minimal primitive root
keys->g = prime_find_primitive_root_u64(keys->p, random64() & 0xFFF0, 0xFFFF);
#endif
} while (!keys->g);
}
// random private key x, 1 < x < p-1
keys->x = random64() % (keys->p - 1) + 1;
// calculate the public key y = g^x mod p
keys->y = power_mod_u64(keys->g, keys->x, keys->p);
}
void elgamal_encrypt(uint64_t p, uint32_t g, uint64_t y, uint64_t message, uint64_t *out, uint64_t (*random64)(void)) {
// choose a random number k, 1 < k < p-1
uint64_t k = random64() % (p - 1) + 1;
// compute a = g^k mod p
out[0] = power_mod_u64(g, k, p);
// compute b = (message * y^k) mod p
out[1] = mul_mod_u64(message, power_mod_u64(y, k, p), p);
}
uint64_t elgamal_decrypt(uint64_t p, uint64_t x, uint64_t *in) {
// compute m = b * (a^(p-1-x)) mod p
uint64_t t = power_mod_u64(in[0], p - 1 - x, p);
return mul_mod_u64(in[1],t, p);
}