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
136
137
138
139
140
141
142
143
144
145
|
/*
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017 J08nY
*/
#include "curve.h"
#include "exhaustive/seed.h"
#include "field.h"
#include "point.h"
curve_t *curve_new(void) {
curve_t *curve = pari_malloc(sizeof(curve_t));
if (!curve) {
perror("Couldn't malloc.");
exit(1);
}
memset(curve, 0, sizeof(curve_t));
return curve;
}
curve_t *curve_copy(curve_t *src, curve_t *dest) {
if (src->seed) dest->seed = seed_copy(src->seed, dest->seed);
if (src->field) dest->field = gcopy(src->field);
if (src->a) dest->a = gcopy(src->a);
if (src->b) dest->b = gcopy(src->b);
if (src->curve) dest->curve = gcopy(src->curve);
if (src->order) dest->order = gcopy(src->order);
if (src->generators) {
dest->generators = points_new(src->ngens);
dest->generators =
points_copy(src->generators, dest->generators, src->ngens);
dest->ngens = src->ngens;
}
if (src->points) {
dest->points = points_new(src->npoints);
dest->points = points_copy(src->points, dest->points, src->npoints);
dest->npoints = src->npoints;
}
return dest;
}
void curve_free(curve_t **curve) {
if (*curve) {
seed_free(&(*curve)->seed);
points_free_deep(&(*curve)->points, (*curve)->npoints);
pari_free(*curve);
*curve = NULL;
}
}
int curve_any(curve_t *curve, config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
GEN v = gen_0;
switch (typ(curve->field)) {
case t_INT:
v = gtovec0(gen_0, 2);
gel(v, 1) = curve->a;
gel(v, 2) = curve->b;
break;
case t_FFELT:
v = gtovec0(gen_0, 5);
gel(v, 1) = gen_1;
gel(v, 4) = curve->a;
gel(v, 5) = curve->b;
break;
default:
pari_err_TYPE("curve_any", curve->field);
}
curve->curve = gerepilecopy(ltop, ellinit(v, curve->field, -1));
return 1;
}
int curve_nonzero(curve_t *curve, config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
curve_any(curve, cfg, args);
if (gequal0(ell_get_disc(curve->curve))) {
avma = ltop;
return -3;
} else {
return 1;
}
}
static int curve_seed_fp(curve_t *curve, config_t *cfg, arg_t *args) {
// TODO implement
return INT_MIN;
}
static int curve_seed_f2m(curve_t *curve, config_t *cfg, arg_t *args) {
// TODO implement
return INT_MIN;
}
int curve_seed(curve_t *curve, config_t *cfg, arg_t *args) {
switch (typ(curve->field)) {
case t_INT:
return curve_seed_fp(curve, cfg, args);
case t_FFELT:
return curve_seed_f2m(curve, cfg, args);
default:
pari_err_TYPE("curve_seed", curve->field);
return INT_MIN; /* NOT REACHABLE */
}
}
GEN curve_params(curve_t *curve) {
pari_sp ltop = avma;
GEN result = field_params(curve->field);
if (curve->a) result = gconcat(result, field_elementi(curve->a));
if (curve->b) result = gconcat(result, field_elementi(curve->b));
if (curve->generators) {
for (size_t i = 0; i < curve->ngens; ++i) {
GEN point =
gconcat(field_elementi(gel(curve->generators[i]->point, 1)),
field_elementi(gel(curve->generators[i]->point, 2)));
GEN x = field_elementi(gel(point, 1));
GEN y = field_elementi(gel(point, 2));
result = gconcat(result, x);
result = gconcat(result, y);
result = gconcat(result, curve->generators[i]->order);
if (curve->generators[i]->cofactor) {
result = gconcat(result, curve->generators[i]->cofactor);
}
}
}
if (curve->order) result = gconcat(result, gtovec(curve->order));
if (curve->points) {
for (size_t i = 0; i < curve->npoints; ++i) {
GEN point =
gconcat(field_elementi(gel(curve->points[i]->point, 1)),
field_elementi(gel(curve->points[i]->point, 2)));
GEN x = field_elementi(gel(point, 1));
GEN y = field_elementi(gel(point, 2));
result = gconcat(result, x);
result = gconcat(result, y);
result = gconcat(result, curve->points[i]->order);
if (curve->points[i]->cofactor) {
result = gconcat(result, curve->points[i]->cofactor);
}
}
}
return gerepilecopy(ltop, result);
}
|