aboutsummaryrefslogtreecommitdiff
path: root/src/curve.c
blob: 812f6883f1817aeabb835434655f1024f64f8d4e (plain)
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
/*
 * ecgen, tool for generating Elliptic curve domain parameters
 * Copyright (C) 2017 J08nY
 */
#include "curve.h"
#include "field.h"
#include "seed.h"

curve_t *curve_new() {
	curve_t *curve = pari_malloc(sizeof(curve_t));
	if (!curve) {
		perror("Couldn't malloc.");
		exit(1);
	}
	memset(curve, 0, sizeof(curve_t));
	return curve;
}

void curve_free(curve_t **curve) {
	if (*curve) {
		seed_free(&(*curve)->seed);
		pari_free((*curve)->points);
		pari_free(*curve);
		*curve = NULL;
	}
}

int curve_init(curve_t *curve, config_t *config) {
	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_init", curve->field);
	}

	curve->curve = gerepilecopy(ltop, ellinit(v, curve->field, -1));
	return 1;
}

int curve_nonzero(curve_t *curve, config_t *config) {
	pari_sp ltop = avma;
	curve_init(curve, config);
	if (gequal0(ell_get_disc(curve->curve))) {
		avma = ltop;
		return -3;
	} else {
		return 1;
	}
}

int curve_prime(curve_t *curve, config_t *config) {
	pari_sp ltop = avma;
	int nonzero = curve_nonzero(curve, config);
	if (nonzero == 1) {
		curve->order = ellsea(curve->curve, 1);
		if (gequal0(curve->order) || !(isprime(curve->order))) {
			avma = ltop;
			return -3;
		} else {
			return 1;
		}
	} else {
		avma = ltop;
		return nonzero;
	}
}

int curve_seed_fp(curve_t *curve, config_t *config) {}

int curve_seed_f2m(curve_t *curve, config_t *config) {}

int curve_seed(curve_t *curve, config_t *config) {
	switch (typ(curve->field)) {
		case t_INT:
			return curve_seed_fp(curve, config);
		case t_FFELT:
			return curve_seed_f2m(curve, config);
		default:
			pari_err_TYPE("curve_seed", curve->field);
			return 0; /* NOT REACHABLE */
	}
}

int curve_g(curve_t *curve, config_t *config) {
	if (config->from_seed) {
		return curve_seed(curve, config);
	} else if (config->prime) {
		return curve_prime(curve, config);
	} else {
		return curve_nonzero(curve, config);
	}
}

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->order) result = gconcat(result, gtovec(curve->order));

	return gerepilecopy(ltop, result);
}