1 /* Implementation of genus 2 divisor arithmetic over V. Shoup's
10 #include <g2hec_Genus2_ops.h>
14 /*****************************************************\
15 Initialize static member s_hcurve of class divisor
16 \*****************************************************/
18 g2hcurve divisor::s_hcurve = my_curve;
20 void divisor::update() {
23 // Check curve's validity
24 OK = OK && s_hcurve.is_valid_curve();
26 /* Check if [u, v] belongs to Jacobian of genus 2 curve
29 (2) deg(v) < deg(u) <= genus = 2
33 OK = OK && IsOne( LeadCoeff(upoly) ); // (1)
35 OK = OK && ( deg(upoly) <= genus ) && ( deg(vpoly) < deg(upoly) ); // (2)
37 OK = OK && IsZero(( vpoly*(vpoly + s_hcurve.get_h())
38 - s_hcurve.get_f() ) % upoly ); // (3)
46 bool_t divisor::is_valid_divisor() const {
50 bool_t divisor::is_unit(){
51 assert(is_valid); // Invalid divisor is checked runtime error
53 return ( IsOne(upoly) && IsZero(vpoly) );
56 void divisor::set_unit() {
57 assert(s_hcurve.is_valid_curve()); // Invalid curve is checked runtime error
59 clear(vpoly); // vpoly = 0
60 set(upoly); // upoly = 1
64 divisor& divisor::random(divdeg_t dgr){ // Underlying curve is not touched
65 assert(s_hcurve.is_valid_curve());
67 // A random valid divisor is generated by the following algorithm:
68 // generate a degree 1 divisor [x - a1, b1] by choosing a1 by random
69 // then trying to solve quadratic equation
70 // x^2 + h(a1)*x - f(a1) for b1.
71 // Note that finding a root of an equation by calling routine
72 // FindRoot(root, poly) may go into an infinite loop if poly does
73 // not split completely. We avoid this by calling irreducibility
74 // test routine DetIrredTest(poly). After a degree 1 divisor is
75 // found, this divisor is doubled by calling add_cantor() to return
76 // a degree 2 polynomial.
78 field_t a1, b1, f_of_a1, h_of_a1;
80 poly_t poly; // polynomial x^2 + h(a1)*x - f(a1)
82 SetCoeff(poly, 2); // set degree 2 leading term to 1
88 eval(f_of_a1, s_hcurve.get_f(), a1);
90 eval(h_of_a1, s_hcurve.get_h(), a1);
92 SetCoeff(poly, 1, h_of_a1);
93 SetCoeff(poly, 0, - f_of_a1);
95 } while ( DetIrredTest(poly) );
101 SetCoeff(upoly, 0, -a1);
107 } while (*this == -*this); // Avoid getting unit after doubling
109 // return a degree one divisor if dgr = 1
113 // Double the degree 1 divisor to get a degree 2 divisor, otherwise
114 add_cantor(*this, *this, *this);
116 if (is_valid_divisor())
119 cerr << "Random divisor failed to generate" << endl;
124 divisor& divisor::random() {
125 return random(DEGREE_2);
129 std::ostream& operator<<(std::ostream& s, const divisor& a)
133 s << "Divisor [u(x), v(x)] for Jacobian group of curve y^2 + h(x)*y = f(x)."
140 s << "[u(x), v(x)]:" << endl;
144 print_poly(a.get_upoly(), &s);
147 print_poly(a.get_vpoly(), &s);
150 if (a.is_valid_divisor())
151 s << " Divisor is valid" << endl;
153 s << " Divisor is invalid" << endl;