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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/*
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017 J08nY
*/
#define _POSIX_C_SOURCE 200809L
#include "input.h"
#include <parson/parson.h>
#include "output.h"
FILE *in;
int delim;
static GEN input_i(const char *prompt, unsigned long bits) {
if (prompt && in == stdin) {
fprintf(out, "%s ", prompt);
}
char *line = NULL;
size_t n = 0;
ssize_t len = getdelim(&line, &n, delim, in);
if (len <= 0) {
return gen_m1;
}
if (len == 1 && !feof(in)) {
free(line);
return gen_m1;
}
for (size_t i = 0, j = 0; (line[j] = line[i]); j += !isspace(line[i++]))
;
if (len <= 3 || !(line[0] == '0' && (line[1] == 'x' || line[1] == 'X'))) {
char *new_line = realloc(line, (size_t)(len + 2));
if (!new_line) {
perror("Couldn't alloc.");
exit(1);
}
memmove(new_line + 2, new_line, (size_t)len);
new_line[0] = '0';
new_line[1] = 'x';
if (!feof(in)) {
new_line[len + 1] = 0;
} else {
new_line[len + 2] = 0;
}
line = new_line;
}
pari_sp ltop = avma;
GEN in = strtoi(line);
free(line);
// check bitsize here
GEN size = int2n(bits);
if (cmpii(in, size) <= 0) {
return gerepileupto(ltop, in);
} else {
fprintf(stderr, "Number too big(> %ld bits).\n", bits);
return gen_m1;
}
}
GEN input_prime(const char *prompt, unsigned long bits) {
GEN read = input_i(prompt, bits);
if (equalii(read, gen_m1)) {
return read;
} else {
if (isprime(read)) {
return read;
} else {
fprintf(stderr, "Number is not prime. Prime required.\n");
return gen_m1;
}
}
}
GEN input_int(const char *prompt, unsigned long bits) {
return input_i(prompt, bits);
}
GEN input_short(const char *prompt) { return input_i(prompt, 16); }
GEN input_string(const char *prompt) {
if (prompt && in == stdin) {
fprintf(out, "%s ", prompt);
}
char *line = NULL;
size_t n = 0;
ssize_t len = getdelim(&line, &n, delim, in);
if (len == 1) {
free(line);
return strtoGENstr("");
}
line[len - 1] = 0;
GEN result = strtoGENstr(line);
free(line);
return result;
}
GEN input_param(param_t param, const char *prompt, unsigned long bits) {
switch (param) {
case PARAM_PRIME:
return input_prime(prompt, bits);
case PARAM_INT:
return input_int(prompt, bits);
case PARAM_SHORT:
return input_short(prompt);
case PARAM_STRING:
return input_string(prompt);
}
return gen_m1;
}
void input_init(const config_t *cfg) {
json_set_allocation_functions(pari_malloc, pari_free);
if (cfg->input) {
in = fopen(cfg->input, "r");
delim = ',';
if (!in) {
perror("Failed to open input file.");
exit(1);
}
} else {
in = stdin;
delim = '\n';
}
}
void input_quit(void) {
if (in != NULL && in != stdout) {
fclose(in);
}
}
|