Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241852 views
1
#ifndef _SMALLJAC_INTERNAL_
2
#define _SMALLJAC_INTERNAL_
3
4
#include "gmp.h"
5
#include "smalljac.h"
6
#include "ffpoly.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
// Internal smalljac functions not part of the public interface
28
29
#define SMALLJAC_MAX_BAD_PRIMES 32
30
#define SMALLJAC_MAX_FACTOR_BITS 64 // don't waste time trying to factor anything hard
31
#define SMALLJAC_SMALL_INTERVAL 1000 // don't bother factoring for small intervals
32
33
#define SMALLJAC_SPECIAL_X6PA 1 // special curve type 1: y^2=x^6+a
34
35
#define SMALLJAC_QCURVE_DELTA 0x1 // indicates Delta values have been precomputed
36
#define SMALLJAC_QCURVE_WS 0x2 // indicates genus 1 curve specified in Weierstrass form
37
#define SMALLJAC_QCURVE_2G 0x4 // indicates the 2g coefficient was non-zero - modified curve not defined for primes dividing 2g
38
// however the original curve may have had good reduction at these primes and should be checked
39
40
#define SMALLJAC_GROUP_FLAG 0x1000
41
42
43
typedef struct smalljac_Qcurve_struct {
44
mpz_t f[SMALLJAC_MAX_DEGREE+1]; // Integer poly f(x) representing numerator of rational poly over common denominator
45
mpz_t Deltas[SMALLJAC_MAX_DEGREE+1]; // Deltas[k] = (\Delta^k f)(0), the k-th difference poly of f evaluated at 0
46
mpz_t denom; // common denominator - applys to both f and Deltaf0
47
mpz_t disc; // mostly D is used, but its handy to keep this around
48
mpz_t D; // discriminant * denom - the divisors of D are bad primes (curve undefined or singular)
49
int f_inits; //# of f elements initiailized
50
int Delta_inits; // # of Deltaf0 elements initialized
51
int degree; // degree of the curve - currently always 2*genus + 1
52
int genus; // genus of the curve
53
unsigned flags; // mask of boolean flags indicating the state of initialization of other parameters
54
unsigned ws2; // for Weierstrass specified curves, holds the coefficients mod 2 in bottom 5 bits
55
unsigned ws3; // for Weierstrass specified curves, holds the coefficients mod 3 in bottom 10 bits (2 bits per)
56
long a[SMALLJAC_MAX_GENUS]; // L_p(T) coefficients (or group structure coefficients) most recently computed
57
int n; // number of coefficients
58
int special; // flag for special curves, e.g. x^6+a
59
unsigned long pts; // pointcount over F_p, if performed, zero o.w.
60
unsigned long p; // prime for which a[] are the coefficients of L_p(T)
61
char str[1024]; // pointer to original curve specification - null terminated
62
} smalljac_Qcurve;
63
64
int padic_charpoly(long a[], long f[], int n, unsigned long p); // c -> c++ interface function for David Harvey's frobenius() code - used in genus 3
65
66
int smalljac_internal_Lpoly (long a[], smalljac_Qcurve *qc, unsigned long p, unsigned long flags); // doesn't handle small primes, assumes good reduction
67
unsigned long smalljac_pointcount (smalljac_Qcurve *qc, unsigned long p);
68
int smalljac_padic_Lpoly (long a[], smalljac_Qcurve *qc, unsigned long p, unsigned long flags);
69
int smalljac_generic_Lpoly (long a[], smalljac_Qcurve *qc, unsigned long p, unsigned long pts, unsigned long flags);
70
int smalljac_tiny_Lpoly (long a[], smalljac_Qcurve *qc, int p, unsigned long flags);
71
int smalljac_x6pa_Lpoly (long a[], smalljac_Qcurve *qc, long p, unsigned long flags);
72
int smalljac_Lpoly_extend (long a[], int n, unsigned long p, int h); // extend coefficients for prime field p to extension field of size q = p^h
73
74
// the following functions update an existing Qcurve structure to reflect new curve parameters without reallocating.
75
int smalljac_Qcurve_set_str (smalljac_Qcurve *qc, char *str, int *err);
76
int smalljac_Qcurve_set_mpz (smalljac_Qcurve *qc, mpz_t f[], int degree, mpz_t denom, mpz_t disc, char *str); // note str is not validated
77
int smalljac_Qcurve_set_i (smalljac_Qcurve *qc, long f[], int degree, char *str); // ditto
78
79
smalljac_Qcurve *smalljac_Qcurve_alloc (); // simply allocates an unitialized Qcurve structure to be used above
80
81
static inline void smalljac_Qcurve_init_f (smalljac_Qcurve *qc, int degree)
82
{ qc->degree = degree; qc->genus = (degree-1)>>1; while ( qc->f_inits <= qc->degree ) mpz_init (qc->f[qc->f_inits++]); }
83
84
static inline void smalljac_Qcurve_init_Deltas(smalljac_Qcurve *qc)
85
{ while ( qc->Delta_inits <= qc->degree ) mpz_init (qc->Deltas[qc->Delta_inits++]); }
86
87
static inline int smalljac_Qcurve_reduce (ff_t f[], smalljac_Qcurve *qc)
88
{ return ff_poly_set_rational_mpz (f, qc->f, qc->degree, qc->denom); }
89
90
static inline int smalljac_Qcurve_degree (smalljac_Qcurve *qc)
91
{ return qc->degree; }
92
93
static inline int smalljac_Qcurve_special (smalljac_Qcurve *qc)
94
{ return qc->special; }
95
96
97
void smalljac_init (void);
98
99
// computes L_p(1) - does not check for overflow
100
static inline unsigned long smalljac_Lp1_ui (long a[], int genus, unsigned long p)
101
{
102
switch (genus) {
103
case 1: return (unsigned long)((long)(p+1)+a[0]);
104
case 2: return (unsigned long)((long)(p*p+1)+(long)(p+1)*a[0]+a[1]);
105
case 3: return (unsigned long)((long)(p*p*p+1)+(long)(p*p+1)*a[0]+(long)(p+1)*a[1]+a[2]);
106
default: printf ("unhandled genus %d\n", genus); exit (0);
107
}
108
}
109
110
static inline int smalljac_last_Lpoly (long a[], smalljac_Qcurve *qc)
111
{ register int i; for ( i = 0 ; i < qc->n ; i++ ) a[i] = qc->a[i]; return qc->n; }
112
static inline unsigned long smalljac_last_p (smalljac_Qcurve *qc)
113
{ return qc->p; }
114
static inline unsigned long smalljac_last_pts (smalljac_Qcurve *qc)
115
{ return qc->pts; }
116
117
#endif
118
119