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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
/*
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017-2018 J08nY
*/
#define _POSIX_C_SOURCE 200809L
#include "random.h"
#include <time.h>
void random_reseed(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;
}
bool random_init(void) {
random_reseed();
return true;
}
GEN random_prime(unsigned long bits) {
pari_sp ltop = avma;
GEN range = mkvec2(int2n(bits - 1), int2n(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 = mkvec2(int2n(bits - 1), int2n(bits));
return gerepilecopy(ltop, genrand(range));
}
GEN random_range(GEN lower, GEN upper) {
pari_sp ltop = avma;
if (gequal(lower, upper)) {
return gcopy(lower);
}
GEN range = mkvec2(lower, subis(upper, 1));
return gerepilecopy(ltop, genrand(range));
}
GEN random_field_element(GEN field) {
switch (typ(field)) {
case t_INT:
return mkintmod(genrand(field), field);
case t_FFELT:
return genrand(field);
default:
pari_err_TYPE("", field);
return NULL;
}
}
|