Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241818 views
1
#ifndef _HECURVE_INCLUDE_
2
#define _HECURVE_INCLUDE_
3
4
#include "gmp.h"
5
#include "smalljac.h"
6
#include "ff.h"
7
8
/*
9
Copyright 2007 Andrew V. Sutherland
10
11
This file is part of smalljac.
12
13
smalljac is free software: you can redistribute it and/or modify
14
it under the terms of the GNU General Public License as published by
15
the Free Software Foundation, either version 2 of the License, or
16
(at your option) any later version.
17
18
smalljac is distributed in the hope that it will be useful,
19
but WITHOUT ANY WARRANTY; without even the implied warranty of
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
GNU General Public License for more details.
22
23
You should have received a copy of the GNU General Public License
24
along with smalljac. If not, see <http://www.gnu.org/licenses/>.
25
*/
26
27
// some counters used for performance diagnostics
28
extern unsigned long hecurve_fastorders;
29
extern unsigned long hecurve_steps;
30
extern unsigned long hecurve_fastorder_expbits;
31
extern unsigned long hecurve_expbits;
32
extern unsigned long hecurve_retries;
33
extern unsigned long hecurve_g1_tor3_counter[10];
34
extern unsigned long hecurve_g1_tor4_counter[17];
35
extern unsigned long hecurve_g1_a_counter;
36
extern unsigned long hecurve_g1_s2known_counter;
37
38
39
/*
40
Implementation of Jacobian group operation for genus 1, 2 and 3 hyperelliptic curves over prime fields
41
Currently the genus is fixed at compile time. This is planned to change. This module is the common
42
entry point for all genera and calls the appropriate genus specific code in hecurve1.c, hecurve2.c, hecurve3.c
43
*/
44
45
#define HECURVE_GENUS SMALLJAC_GENUS
46
#define HECURVE_DEGREE (2*HECURVE_GENUS+1)
47
48
#define HECURVE_RANDOM 0 // generate truly random divisors
49
#define HECURVE_VERIFY 0 // verifies that all inputs and outputs are valid elements of the Jacobian - ONLY USE FOR DEBUGGING THIS IS VERY SLOW
50
#define HECURVE_FAST 1 // define to turn off certain error checking. see also FF_FAST (only marginally effects performance)
51
#define HECURVE_SPARSE 0 // assumes f2 through f_2g are zero (makes only about 1-2 % difference)
52
53
#define HECURVE_RANDOM_POINT_RETRIES 100 // this fails with probability 1/2, and we really need it to succeed
54
#define HECURVE_G1_ORDER_RETRIES 20
55
#define HECURVE_G1_SHORT_INTERVAL 5 // don't bother with full BSGS search for very short intervals
56
#define HECURVE_G1_4TOR_MINP (1<<23) // don't compute 4-torsion for p smaller than this, its not worth the effort
57
#define HECURVE_G1_8TOR_MINP (1<<26) // don't check any 8-torsion for p smaller than this, its not worth the effort
58
59
#if HECURVE_GENUS == 1
60
// note that rep in genus 1 accomodates projective coords, so we use u[1]=z and have (x,y,z) => u[0]=-x, u[1]=z, v[0]=y (note the sign difference of u[0] and x)
61
#define _hecurve_init_uv(u,v) { _ff_init(u[0]); _ff_init(v[0]); }
62
#define _hecurve_set(u1,v1,u2,v2) {_ff_set(u1[1],u2[1]);_ff_set(u1[0],u2[0]);_ff_set(v1[0],v2[0]);}
63
#define _hecurve_is_identity(u,v) _ff_zero((u)[1])
64
#define _hecurve_set_identity(u,v) {_ff_set_zero((u)[1]); _ff_set_zero((u)[0]); _ff_set_zero((v)[0]); }
65
#define _hecurve_2tor(u,v) (_ff_zero((v)[0]))
66
#endif
67
#if HECURVE_GENUS == 2
68
#define _hecurve_init_uv(u,v) { _ff_init(u[0]); _ff_init(u[1]); _ff_init(u[2]); _ff_init(v[0]); _ff_init(v[1]); }
69
#define _hecurve_set(u1,v1,u2,v2) {_ff_set(u1[2],u2[2]);_ff_set(u1[1],u2[1]);_ff_set(u1[0],u2[0]);_ff_set(v1[1],v2[1]);_ff_set(v1[0],v2[0]);}
70
#define _hecurve_is_identity(u,v) (_ff_zero((u)[1]) && _ff_zero((u)[2])) // ignores v
71
#define _hecurve_set_identity(u,v) {_ff_set_one((u)[0]); _ff_set_zero((u)[1]); _ff_set_zero((u)[2]); \
72
_ff_set_zero((v)[0]); _ff_set_zero((v)[1]);}
73
#define _hecurve_2tor(u,v) (_ff_zero((v)[1]) && _ff_zero((v)[0]))
74
#endif
75
#if HECURVE_GENUS == 3
76
#define _hecurve_init_uv(u,v) { _ff_init(u[0]); _ff_init(u[1]); _ff_init(u[2]); _ff_init(u[3]); _ff_init(v[0]); _ff_init(v[1]); _ff_init(v[2]); }
77
#define _hecurve_set(u1,v1,u2,v2) {_ff_set(u1[3],u2[3]);_ff_set(u1[2],u2[2]);_ff_set(u1[1],u2[1]);_ff_set(u1[0],u2[0]);_ff_set(v1[2],v2[2]);_ff_set(v1[1],v2[1]);_ff_set(v1[0],v2[0]);}
78
#define _hecurve_is_identity(u,v) (_ff_zero((u)[1]) && _ff_zero((u)[2]) && _ff_zero((u)[3])) // ignores v
79
#define _hecurve_set_identity(u,v) {_ff_set_one((u)[0]); _ff_set_zero((u)[1]); _ff_set_zero((u)[2]); _ff_set_zero((u)[3]); \
80
_ff_set_zero((v)[0]); _ff_set_zero((v)[1]); _ff_set_zero((v)[2]);}
81
#define _hecurve_2tor(u,v) (_ff_zero((v)[2]) && _ff_zero((v)[1]) && _ff_zero((v)[0]))
82
#endif
83
84
struct _hecurve_ctx_struct {
85
ff_t invert;
86
ff_t s0;
87
ff_t s1;
88
ff_t s2;
89
ff_t r;
90
ff_t inv1;
91
int state; // must be 0 on first call, 1 on second call
92
};
93
typedef struct _hecurve_ctx_struct hecurve_ctx_t;
94
95
// Jacobian coordinate rep for genus 1, represents the affine point s(x/z,y/z), in Mumford rep: u(t)=t-x, v(t)=y.
96
struct _hec_j_struct {
97
ff_t x, y, z;
98
};
99
typedef struct _hec_j_struct hec_j_t;
100
101
// reduced Chudnovsky Jacobian coordinate representation for genus 1
102
// Represents the affine point (x/z2,y/z3), or in Mumford rep: u(t)=t-x, v(t)=y.
103
struct _hec_rc_struct {
104
ff_t x, y, z2, z3; // note that we don't maintain z, this saves a field multiplication when composing elements
105
};
106
typedef struct _hec_rc_struct hec_jc_t;
107
108
#define _hecurve_init_ctx(ctx) {_ff_init(ctx.invert);_ff_init(ctx.s0);_ff_init(ctx.s1);_ff_init(ctx.r);_ff_init(ctx.inv1);ctx.state=0;}
109
#define _hecurve_clear_ctx(ctx) {_ff_clear(ctx.invert);_ff_clear(ctx.s0);_ff_clear(ctx.s1);_ff_clear(ctx.r);_ff_clear(ctx.inv1);ctx.state=0;}
110
111
// return 1 if equal, -1 if unequal inverses, 0 otherwise
112
#if HECURVE_GENUS == 1
113
// IMPORTANT - point comparison is only supported for points in affice coordinates!
114
// we could compare projective points by cross multiplying, but currently comparisons are only used during table lookup, in which case
115
// we expect to use a unique (affine) representation anyway.
116
static inline int hecurve_cmp (ff_t u1[3], ff_t v1[2], ff_t u2[3], ff_t v2[2])
117
{
118
if ( _ff_zero(u1[1]) ) return ( _ff_zero(u2[1]) ? 1 : 0 );
119
if ( _ff_zero(u2[1]) ) return 0;
120
#if ! HECURVE_FAST
121
if ( ! _ff_one(u1[1]) || ! _ff_one(u2[1]) ) { puts ("Attempt to compare genus 1 points in non-affine coordinates!"); exit (0); }
122
#endif
123
if ( _ff_equal(u1[0],u2[0]) ) {
124
if ( _ff_equal (v1[0], v2[0]) ) return 1;
125
if ( ff_is_negation(v1[0],v2[0]) ) return -1;
126
}
127
return 0;
128
}
129
#endif
130
#if HECURVE_GENUS == 2
131
static inline int hecurve_cmp (ff_t u1[3], ff_t v1[2], ff_t u2[3], ff_t v2[2])
132
{
133
if ( _ff_equal(u1[0],u2[0]) && _ff_equal(u1[1],u2[1]) && _ff_equal(u1[2],u2[2]) ) {
134
if ( _ff_equal (v1[0], v2[0]) && _ff_equal(v1[1], v2[1]) ) return 1;
135
if ( ff_is_negation(v1[0],v2[0]) && ff_is_negation (v1[1],v2[1]) ) return -1;
136
}
137
return 0;
138
}
139
#endif
140
#if HECURVE_GENUS == 3
141
static inline int hecurve_cmp (ff_t u1[4], ff_t v1[3], ff_t u2[4], ff_t v2[3])
142
{
143
if ( _ff_equal(u1[0],u2[0]) && _ff_equal(u1[1],u2[1]) && _ff_equal(u1[2],u2[2]) && _ff_equal(u1[3],u2[3]) ) {
144
if ( _ff_equal (v1[0], v2[0]) && _ff_equal(v1[1], v2[1]) && _ff_equal(v1[2], v2[2]) ) return 1;
145
if ( ff_is_negation(v1[0],v2[0]) && ff_is_negation (v1[1],v2[1]) && ff_is_negation (v1[2],v2[2]) ) return -1;
146
}
147
return 0;
148
}
149
#endif
150
static inline void hecurve_invert (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS])
151
{
152
#if HECURVE_GENUS == 3
153
ff_negate(v[2]);
154
#endif
155
#if HECURVE_GENUS >= 2
156
ff_negate(v[1]);
157
#endif
158
ff_negate(v[0]);
159
}
160
161
162
#if HECURVE_GENUS == 1
163
#define hecurve_compose hecurve_g1_compose
164
#define hecurve_square hecurve_g1_square
165
#endif
166
#if HECURVE_GENUS == 2
167
#define hecurve_compose hecurve_g2_compose
168
#define hecurve_square hecurve_g2_square
169
#endif
170
#if HECURVE_GENUS == 3
171
#define hecurve_compose hecurve_g3_compose
172
#define hecurve_square hecurve_g3_square
173
#endif
174
175
void hecurve_setup (mpz_t p);
176
int hecurve_init_ctx (hecurve_ctx_t *ctx, ff_t f[HECURVE_DEGREE+1]);
177
void hecurve_clear_ctx (hecurve_ctx_t *ctx);
178
179
void hecurve_compose_cantor (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS],
180
ff_t u1[HECURVE_GENUS+1], ff_t v1[HECURVE_GENUS],
181
ff_t u2[HECURVE_GENUS+1], ff_t v2[HECURVE_GENUS], ff_t f[HECURVE_DEGREE+1]);
182
183
// ctx->state should be set by the caller to compose and square
184
// 0=inital call, return to invert 1=2nd call with inverted element -1=initial call, don't return to invert
185
// note that inputs and outputs may overlap
186
187
int hecurve_g1_compose (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t u1[HECURVE_GENUS+1],
188
ff_t v1[HECURVE_GENUS], ff_t u2[HECURVE_GENUS+1],
189
ff_t v2[HECURVE_GENUS+1], ff_t f[HECURVE_DEGREE+1], hecurve_ctx_t *ctx);
190
int hecurve_g1_square (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS],
191
ff_t u1[HECURVE_GENUS+1], ff_t v1[HECURVE_GENUS], ff_t f[HECURVE_DEGREE+1], hecurve_ctx_t *ctx);
192
193
int hecurve_g2_compose (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t u1[HECURVE_GENUS+1],
194
ff_t v1[HECURVE_GENUS], ff_t u2[HECURVE_GENUS+1],
195
ff_t v2[HECURVE_GENUS+1], ff_t f[HECURVE_DEGREE+1], hecurve_ctx_t *ctx);
196
int hecurve_g2_square (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS],
197
ff_t u1[HECURVE_GENUS+1], ff_t v1[HECURVE_GENUS], ff_t f[HECURVE_DEGREE+1], hecurve_ctx_t *ctx);
198
199
int hecurve_g3_compose (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t u1[HECURVE_GENUS+1],
200
ff_t v1[HECURVE_GENUS], ff_t u2[HECURVE_GENUS+1],
201
ff_t v2[HECURVE_GENUS+1], ff_t f[HECURVE_DEGREE+1], hecurve_ctx_t *ctx);
202
int hecurve_g3_square(ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS],
203
ff_t u1[HECURVE_GENUS+1], ff_t v1[HECURVE_GENUS], ff_t f[HECURVE_DEGREE+1], hecurve_ctx_t *ctx);
204
205
void hecurve_g1_exp_ui (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t u1[HECURVE_GENUS+1], ff_t v1[HECURVE_GENUS], unsigned long e, ff_t f[HECURVE_DEGREE+1]);
206
void hecurve_g1_AJ_powers (hec_j_t p[], ff_t x0, ff_t y0, int k, ff_t f1);
207
int hecurve_g1_AJC_steps_1 (hec_jc_t s[], ff_t x0, ff_t y0, int n, ff_t f1);
208
int hecurve_g1_AJC_steps_2 (hec_jc_t s[], ff_t x0, ff_t y0, ff_t x1, ff_t y1, int n, ff_t f1);
209
long hecurve_g1_order (long *pd, ff_t f[4]);
210
int hecurve_g1_group_structure (long n[2], long N, long d, ff_t f[4]);
211
int hecurve_g1_test_exponent (long e, ff_t f[4]);
212
213
214
// The function below should are used in both genus 2 and 3 although the compression support functions (bits/unbits)
215
// are currently only supported in genus 2
216
217
int hecurve_verify (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t f[HECURVE_DEGREE+1]);
218
void hecurve_random (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t f[HECURVE_DEGREE+1]);
219
int hecurve_random_point (ff_t *px, ff_t *py, ff_t f[HECURVE_DEGREE+1]);
220
void hecurve_invert (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS]);
221
unsigned hecurve_bits (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t f[HECURVE_DEGREE+1]);
222
int hecurve_unbits (ff_t v[HECURVE_GENUS], ff_t u[HECURVE_GENUS+1], unsigned bits, ff_t f[HECURVE_DEGREE+1]);
223
224
void hecurve_copy (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t u1[HECURVE_GENUS+1], ff_t v1[HECURVE_GENUS]);
225
void hecurve_print (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS]);
226
int hecurve_sprint (char *s, ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS]);
227
228
#endif
229
230