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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
/*
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017 J08nY
*/
#define _POSIX_C_SOURCE 200809L
#include "random.h"
#include <time.h>
bool random_init(void) {
pari_ulong seed = 0;
// Try urandom first
FILE *rand = fopen("/dev/urandom", "rb");
if (rand) {
size_t read = 0;
while (read < sizeof(pari_ulong)) {
read += fread(&seed + read, 1, sizeof(pari_ulong) - read, rand);
}
fclose(rand);
}
// Try worse methods later
if (seed == 0) {
struct timespec t;
if (!clock_gettime(CLOCK_REALTIME, &t)) {
seed = (pari_ulong)t.tv_nsec;
} else {
seed = (pari_ulong)time(NULL);
}
}
pari_sp ltop = avma;
setrand(utoi(seed));
avma = ltop;
return true;
}
GEN random_prime(unsigned long bits) {
pari_sp ltop = avma;
GEN range = gtovec0(gen_0, 2);
gel(range, 1) = powis(gen_2, bits - 1);
gel(range, 2) = powis(gen_2, bits);
GEN p;
pari_sp btop = avma;
do {
p = randomprime(range);
p = gerepileupto(btop, p);
} while (!isprime(p));
return gerepilecopy(ltop, p);
}
GEN random_int(unsigned long bits) {
pari_sp ltop = avma;
GEN range = gtovec0(gen_0, 2);
gel(range, 1) = powis(gen_2, bits - 1);
gel(range, 2) = powis(gen_2, bits);
return gerepilecopy(ltop, genrand(range));
}
|