#ifndef _SMALLJAC_INCLUDE_1#define _SMALLJAC_INCLUDE_23/*4Copyright 2007-2008 Andrew V. Sutherland56This file is part of smalljac.78smalljac is free software: you can redistribute it and/or modify9it under the terms of the GNU General Public License as published by10the Free Software Foundation, either version 2 of the License, or11(at your option) any later version.1213smalljac is distributed in the hope that it will be useful,14but WITHOUT ANY WARRANTY; without even the implied warranty of15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16GNU General Public License for more details.1718You should have received a copy of the GNU General Public License19along with smalljac. If not, see <http://www.gnu.org/licenses/>.20*/2122/*23IMPORTANT NOTES2425The genus 1 algorithms now reside in hecurve1x.c - the general Jacobian algorithms are not used -26but the same calling interface through smalljac_Lpolys is retained. In addition to being more than27twice as fast, version 3 corrects a bug in version 2 which could have resulted in some incorrect a_p28values (this typically only impacted CM curves).2930Currently in genus > 1 computation of L-poly coefficients and group structure is31limited to hyperelliptic curves of the form y^2=f(x) with f of odd degree (and also x^6+a), however32pointcounting support (to compute a_1=-a_p) is provided for even degree f in genus 2 and 333(use the SMALLJAC_A1_ONLY flag for this purpose).3435The genus 3 code is still incomplete. It will handle the typical case (minimal endomorphism ring)36reliably, but for exceptional curves it may often fail for small values of p due to unresolved ambiguities.37(when successful, the output is (barring a bug) provably correct). Pointcounting is supported38(within memory constraints - see SMALLJAC_INIT_COUNT_P) for all genus 3 curves.39*/4041#define SMALLJAC_VERSION_STRING "smalljac version 3.0"4243//#define SMALLJAC_GENUS 1 // currently genus is hardwired at compile time - this will change4445#define SMALLJAC_FF_64BITS 1 // set to 1 to use 64-bit finite field elements, default is 32 (this forces p < 2^31)4647#define SMALLJAC_MAX_END \48(SMALLJAC_FF_64BITS ? (1UL<<63) : (1UL<<31))4950#define SMALLJAC_MAX_GENUS 4 // genus 4 curves only supported for pointcounting51#define SMALLJAC_MAX_DEGREE 952#define SMALLJAC_RETRIES 40 // number of random elements to use to test group exponents53#define SMALLJAC_FULL_P (1UL<<33) // determines when to do a full search of the Weil interval in genus 1(only)54#define SMALLJAC_MAX_COUNT_P (1<<25) // genus independent55#define SMALLJAC_BIG_COUNT_P 3600000 // experimentally determined on an AMD Athlon-64 4800+, YMMV5657#if SMALLJAC_GENUS == 158#define SMALLJAC_MAX_P (1UL<<40) // this can easily be increased to 2^63 by increasing BSGS_STEPS (to approx 2^16) in hecurve1x.c59#define SMALLJAC_TINY_P 3 // must be at least 360#define SMALLJAC_COUNT_P (1UL<<10) // no minimum requirement61#define SMALLJAC_PADIC_P SMALLJAC_MAX_P // never use p-adic62#define SMALLJAC_TABBITS 16 // no longer used in genus 163#endif64#if SMALLJAC_GENUS == 265#define SMALLJAC_MAX_P (1UL<<31) // group size needs to fit in a long66#define SMALLJAC_TINY_P 61 // should be >= 61. p > 61 ensures a1 < p/2, only need p > 23 to ensures unique group order in Weil interval given a1.67#define SMALLJAC_COUNT_P 1500000 // crossover point determined on an AMD Athonl 2.5GHz - YMMV, should be at least 147 (p > 147 ensures unique group order in Weil interval)68#define SMALLJAC_PADIC_P SMALLJAC_MAX_P // p-adic is slower within the feasible range (crossover is >2^32)69#define SMALLJAC_TABBITS 2370#endif71#if SMALLJAC_GENUS == 372#define SMALLJAC_MAX_P (1UL<<31) // p^2+1 needs to fit in a long, its ok for the group size to be larger than 64 bits73#define SMALLJAC_TINY_P 47 // must be at least 47, needs to be 143 to ensure a1 < p/2.74#define SMALLJAC_COUNT_P SMALLJAC_MAX_P // always pointcount75#define SMALLJAC_PADIC_P (1<<14) // Should not be greater than 2^21 - group computation code assumes order < 2^6376#define SMALLJAC_TABBITS 1977#endif7879#define SMALLJAC_INIT_COUNT_P (1<<26) // allocate extra space8081// bit-masks for flags parameter82#define SMALLJAC_A1_ONLY 0x1 // only compute a1 coefficient83#define SMALLJAC_GOOD_ONLY 0x2 // only callback for good primes84#define SMALLJAC_SPLIT4 0x4 // only process half the primes mod 4, SMALLJAC_HIGH4 set => p mod 4 > 2, else p mod 4 <= 285#define SMALLJAC_SPLIT8 0x8 // similarly for 8, 16, and 32 - allows primes to be conveniently partitioned among up to 16 jobs86#define SMALLJAC_SPLIT16 0x1087#define SMALLJAC_SPLIT32 0x2088#define SMALLJAC_HIGH4 0x4089#define SMALLJAC_HIGH8 0x8090#define SMALLJAC_HIGH16 0x10091#define SMALLJAC_HIGH32 0x20092#define SMALLJAC_FILTER 0x400 // flag to permit more general prime filtering - calls callback function with good=-1 to test whether p should be processed93#define SMALLJAC_GROUP 0x1000 // indicates group structure computation rather than L-poly coefficients94#define SMALLJAC_SGROUP 0x2000 // compute only the group structure actually generated by the black box, may be a subgroup.95// only relevant when SMALLJAC_GROUP is set9697#define SMALLJAC_SPLIT 0x3c // all 2^k split flags98#define SMALLJAC_SPLIT_SHIFT 199#define SMALLJAC_HIGH 0x3c0 // all 2^k high flags100#define SMALLJAC_HIGH_SHIFT 5101102// error codes103#define SMALLJAC_INTERNAL_ERROR -1 // general unspecified internal error - probably indicates a bug104#define SMALLJAC_INVALID_INTERVAL -2 // end < start or end > SMALLJAC_MAX_END105#define SMALLJAC_PARSE_ERROR -3 // couldn't parse curve string106#define SMALLJAC_UNSUPPORTED_CURVE -4 // currently curve must have odd degree in [3,SMALLJAC_MAX_DEGREE]107#define SMALLJAC_SINGULAR_CURVE -5 // curve is singular over Q108#define SMALLJAC_INVALID_PP -6 // prime power (or prime) required109#define SMALLJAC_WRONG_GENUS -7 // curve may be valid, but it doesn't have the compiled genus (this will go away eventually)110#define SMALLJAC_INVALID_FLAGS -8 // invalid combination of flag bits set111112// public interface for SAGE113typedef void *smalljac_Qcurve_t; // private type - we don't want to spell out the details here - see smalljac_internal.h114115smalljac_Qcurve_t smalljac_Qcurve_init (char *str, int *err); // creates a curve over Q from a null-terminated curve specification, either [a1,a2,a3,a4,a6] (integers a1,a2,...,a6)116// or a monic poly f(x) of odd degree with rational coefficients to define y^2 = f(x), err is an optional pointer to an error code117118char *smalljac_Qcurve_str (smalljac_Qcurve_t c); // returns a (readonly) pointer to curve specification used to create the curve119int smalljac_Qcurve_genus (smalljac_Qcurve_t c); // returns the genus of the curve120void smalljac_Qcurve_clear (smalljac_Qcurve_t c); // frees memory allocated for curve121122long smalljac_Lpolys (smalljac_Qcurve_t c, // curve over Q created via smalljac_Qcurve_init123unsigned long start, // start and end specify closed search interval [start,end]. Set start=end=p to compute L_p(T)124unsigned long end,125unsigned long flags, // bitmask of options defined above126int (*callback)(smalljac_Qcurve_t c, // pointer to callback function127unsigned long p, // prime in [start,end]128int good, // 1 if good reduction, 0 if bad129long a[], // n coefficients of L_p(T) with a[0] = a_1130int n, // either 1 or g for good p, 0 for bad p131void *arg), // forwarded arg from caller132void *arg); // pass-through arg uninterpreted by smalljac133134// smalljac_groups has the same interface as smalljac_Lpolys, except instead of an array a[] of L-poly coefficients,135// the array m[] contains the orders of the cyclic factors of J(C/F_p) ~ Z_m[0] x Z_m[1] x ... x Z_m[n-1]136// with m[0] | m[1] | ... | m[n-1] and 1 <= n <= 2g137static inline long smalljac_groups (smalljac_Qcurve_t curve, unsigned long start, unsigned long end, unsigned long flags,138int (*callback)(smalljac_Qcurve_t curve, unsigned long p, int good, long m[], int n, void *arg), void *arg)139{ return smalljac_Lpolys(curve, start, end, flags|SMALLJAC_GROUP, callback, arg); }140141// One shot version for computing a single L-poly. flags may be set to SMALLJAC_A1_ONLY142// Returns the number of coefficients computed (1 or g), 0 for bad reduction, or a negative error code143// Supports prime powers (but curve must still have rational coefficients)144int smalljac_Lpoly (long a[], char *curve, unsigned long q, unsigned long flags);145146// One shot version for computing a single group structure. Computes m[0],...,m[n-1] s.t.147// J(C/F_q) is isomorphic to Z_m[0] x ... x Z_m[r] with m[0] | m[1] | ... | m[n-1], where 1 <= n <= 2g.148// Returns n, the number of cyclic factors, 0 for bad reduction, or a negative error code149// Currently q must be prime and no flag values are used.150static inline int smalljac_group (long m[], char *curve, unsigned long q, unsigned long flags)151{ return smalljac_Lpoly (m, curve, q, flags|SMALLJAC_GROUP); }152153154#endif155156157