Initial GIT commit
[libg2hec.git] / src / .svn / text-base / testcurve.C.svn-base
blob182ae00fbbc18a774e79529d7ffaac3947d97f4d
1 /* Test */
2 /* Note that because we have a static g2hcurve member s_hcurve in the
3 divisor class and this memeber may result in chaos when we swith moduli, 
4 we require that there is only one modulus per process
5 */
7 #include <g2hec_nsfieldtype.h>
8 #include <assert.h>
9 #include <g2hec_Genus2_ops.h>
10 #include <g2hec_nsdebug.h>
12 #undef MAX_STRING_LEN 
13 #define MAX_STRING_LEN 300
15 NS_G2_CLIENT
17 static void compare(const divisor& div, const divisor& divc, string ops);
19 int main() 
21   /* Set PRNG seed */
22   SetSeed(to_ZZ(19800729));
24   char p[MAX_STRING_LEN], exp[MAX_STRING_LEN];
26   cout << "Please choose your modulus p (up to " 
27 << MAX_STRING_LEN << " decimal digits):" << endl;
28   cout << "p = ";
29   cin.getline(p, MAX_STRING_LEN);
31   ZZ n; // For scalar multiplication
33    field_t::init(to_ZZ(p)); // define GF(p)
35    poly_t f, h, u, v;
37    g2hcurve curve;
39    divisor div, divc, div1, div2;
41    random(f, 6);
42    SetCoeff(f, 5, 1); // Make monic of degree 5
44    random(h, 3);
46    cout << endl; 
48    /*****************************************\
49       Test curve 
50    \*****************************************/
51    cout << "The underlying finite field is GF(" << p << ")." << endl;
53    cout << "\t*** Test g2hcurve ***" << endl;
55    /* Valid curve 1 generated by g2hcurve::random() */
56    cout << "- Valid curve 1 -" << endl;
58    /* Test g2hcurve::random */
60    cout << "\t*** Test random curve ***" << endl; 
62    curve.random();
64    assert(curve.is_valid_curve());
65    cout << "Checking valid curve...OK" << endl;
67 #if DEBUG_LEVEL > 1
68    /* Valid curve */
69    cout << curve << endl;
71    /* Test g2hcurve::operator<< */
72    cout << curve << endl;
73 #endif
75    /* Another valid curve with h(x) = 0. Assume char is not 2 */
76    cout << "- Valid curve 2 - " << endl;
78    do {
79      random(f, 6); // deg(f) < 6
80      SetCoeff(f, 5, 1); // f5 = 1;
81    } while (!DetIrredTest(f));
83    curve.set_f(f);
85    clear(h); // h = 0
86    curve.set_h(h);
87    curve.update();
89    assert(curve.is_valid_curve());
90    cout << "Checking valid curve (h = 0)...OK" << endl;
92 #if DEBUG_LEVEL > 1
93    cout << curve << endl;
94 #endif
96    /* Test invalid curve: not genus 2 */
97    cout << "- Invalid curve 1: not genus 2 -" << endl;
99    NTL_NNS random(f, 5); // degree < 5
100    MakeMonic(f);
101    curve.set_f(f); 
102    curve.update();
104    assert(!curve.is_valid_curve());
105    cout << "Checking invalid curve: not genus 2...OK" << endl;
107 #if DEBUG_LEVEL > 1
108    cout << curve << endl;
109 #endif
111    /* Test invalid curve: singular */
112    cout << "- Invalid curve 2: singular -" << endl;
114    set(f); 
115    SetCoeff(f, 2, 1);
116    SetCoeff(f, 1, 2); // f = x^2 + 2x + 1 = (x + 1)^2
117    clear(h); // h = 0
119    curve.set_f(f);
120    curve.set_h(h);
121    curve.update();
123    assert(!curve.is_valid_curve());
124    cout << "Checking invalid curve: singular...OK" << endl;
126 #if DEBUG_LEVEL > 1
127    cout << curve << endl;
128 #endif
130    /* Test invalid curve: f(x) not monic */
131    cout << "- Invalid curve 3: f(x) not monic -" << endl;
133    SetCoeff(f, 5, 2);
135    curve.set_f(f);
136    curve.update();
138    assert(!curve.is_valid_curve());
139    cout << "Checking invalid curve: non-monic f(x)...OK" << endl;
141 #if DEBUG_LEVEL > 1
142    cout << curve << endl;
143 #endif
145    /*****************************************\
146       Test divisor basics 
147    \*****************************************/
149    cout << "\t*** Test divisor routines ***" << endl;
151    curve.random(); // Set curve valid
153    /* Valid divisor generated by divisor::random() */
154    cout << "\t*** Test random divisor ***" << endl;
156    div.set_curve(curve); // Set to valid curve
158    div.update();
160    div.random();
162    assert(div.is_valid_divisor());
163    cout << "Checking random divisor...OK" << endl;
165 #if DEBUG_LEVEL > 1
166    cout << div << endl;
167 #endif
169    cout << "\t*** Test invalid divisor ***" << endl;
171    cout << "- Invalid divisor 1: invalid curve -" << endl;
173    /* Invalid divisor: invalid curve is a checked runtime error */
174    cout << 
175 "Invalid curve is a checked runtime error for all divisor arithmetic ops"
176         << endl << endl;
178    /* Invalid divisor: invalid upoly */
180    cout << "- Invalid divisor 2: invalid upoly -" << endl;
182    SetCoeff(u, genus + 1, 1);  // deg(u) = 3 
183    div.set_upoly(u);
184    div.update();
186    assert(!div.is_valid_divisor());
187    cout << "Checking invalid divisor: invalid u(x)...OK" << endl;
189 #if DEBUG_LEVEL > 1
190    cout << div << endl;
191 #endif
194    /* Invliad divisor: invalid vpoly */
195    cout << "- Invalid divisor 3: invalid vpoly -" << endl;
198    // Test divisor::set_unit, divisor::is_unit()
199    cout << "    - Unit divisor -" << endl;
201    div.set_unit();
203    assert(div.is_unit());
204    cout << "Checking unit divisor...OK" << endl;
206 #if DEBUG_LEVEL > 1
207    cout << div << endl;
208 #endif
210    /* Invalid vpoly */
211    div.random();  // Valid divisor
213    cout << "    - vpoly is set to invalid -" << endl;
215    random(v, genus + 1);
216    SetCoeff(v, 2, 1); // deg(v) = 1
217    div.set_vpoly(v);
218    div.update();
220    assert(!div.is_valid_divisor());
221    cout << "Checking invalid divisor: invalid v(x)...OK" << endl;
223 #if DEBUG_LEVEL > 1 
224    cout << div << endl;
225 #endif
227    /*****************************************\
228       Test divisor arithmetic 
229    \*****************************************/
231    /* Test divisor arithmeitc:
232       divisor addition, doubling and scalar multiplication are tested.
233       Results return from add() and add_cantor() are compared to test
234       correctness. Some results can also be compared to the results
235       generated by the CAS MAGMA */
237    cout << "\t*** Test divisor arithmetic operations ***" << endl;
239    /* Test Divisor negation */
240    cout << "\t*** Test negation ***" << endl;
241    div1.random();
242    dnegate(div2, div1);
244    assert(div2.is_valid_divisor());
245    cout << "Checking divisor negation...OK" << endl;
247 #if DEBUG_LEVEL > 1
248    cout << "div1: " << endl;
249    cout << div1 << endl;
251    cout << "div2 = -div1:" << endl;
252    cout << div2 << endl;
253 #endif
255    div = div1 + div2;
257    assert(div.is_unit());
258    cout << "This test should return a unit divisor...OK" << endl;
260 #if DEBUG_LEVEL > 1
261    cout << "div1 + div2: " << endl; 
262    cout << div << endl;
263 #endif
265    /* Test divisor addition */
266    cout << "\t*** Test addition ***" << endl;
268    /* deg 2 + deg 2 */
269    cout << "- Addition: deg 2 + deg 2 -" << endl;
271    div1.random();
273    do {
274      div2.random();
275    } while (div1 == div2); // Choose diffrent div2
277 #if DEBUG_LEVEL > 1
278    cout << "Random div1: " << endl;
279    cout << div1 << endl;
280    cout << "Random div2: " << endl;
281    cout << div2 << endl;
282 #endif
284    if (add_cantor(divc, div1, div2)) 
285      cout << "divc = div1 + div2: add_cantor()" << endl;
287 #if (DEBUG_LEVEL > 1)
288    cout << "divc : " << endl;
289    cout << divc << endl;
290 #endif
292    if (add(div, div1, div2))
293      cout << "div = div1 + div2: add()" << endl;
295    compare(div, divc, "Addtion(2+2)");
297    /* deg 2 + deg 1 */
298    cout << "- Addition: deg 2 + deg 1 -" << endl;
300    div1.random(); // degree 2
301    div2.random(DEGREE_1);// degree 1
303 #if DEBUG_LEVEL > 1
304    cout << "Random div1: " << endl;
305    cout << div1 << endl;
306    cout << "Random div2: " << endl;
307    cout << div2 << endl;
308 #endif
310    if (add_cantor(divc, div1, div2)) 
311      cout << "divc = div1 + div2: add_cantor()" << endl;
313    if (add(div, div1, div2))
314      cout << "div = div1 + div2: add()" << endl;
316    cout << endl;
318    compare(div, divc, "Addition(2+1)");
320    /* deg 1 + deg 1 */
321    cout << "- Addition: deg 1 + deg 1 -" << endl;
323    div1.random(DEGREE_1);
324    do {
325      div2.random(DEGREE_1);
326    } while (div1 == div2);
328 #if DEBUG_LEVEL > 1
329    cout << "Random div1: " << endl;
330    cout << div1 << endl;
331    cout << "Random div2: " << endl;
332    cout << div2 << endl;
333 #endif
335    if (add_cantor(divc, div1, div2)) 
336      cout << "divc = div1 + div2: add_cantor()" << endl;
338    if (add(div, div1, div2))
339      cout << "div = div1 + div2: add()" << endl;
340    compare(div, divc, "Addition(1+1)");
342    /* deg 2 + unit */
343    cout << "- Addition: deg 2 + unit divisor -" << endl;
345    div1.random();
346    div2.set_unit();
348 #if DEBUG_LEVEL > 1
349    cout << "Random div1: " << endl;
350    cout << div1 << endl;
351    cout << "Unit div2: " << endl;
352    cout << div2 << endl;
353 #endif
355    if (add_cantor(divc, div1, div2))
356      cout << "divc = div1 + div2: add_cantor()" << endl;
358    if (add(div, div1, div2))
359      cout << "div = div1 + div2: add()" << endl;
361    compare(div, divc, "Addtion(2+0)");
363    assert(div==div1);
364    cout << "Checking adding unit divisor...OK" << endl;
366    /* unit + unit */
367    cout << "- Addition: unit divisor + unit divisor -" << endl;
369    div1.set_unit();
370    div2.set_unit();
372 #if DEBUG_LEVEL > 1
373    cout << "Unit div1 & div2: " << endl;
374    cout << div1 << endl;
375 #endif
377    if (add_cantor(divc, div1, div2))
378      cout << "divc = div1 + div2: add_cantor()" << endl;
380    if (add(div, div1, div2))
381      cout << "div = div1 + div2: add()" << endl;
383    compare(div, divc, "Addition(0+0)");
385    assert(div==div1);
386    cout << "Result should be unit...OK" << endl;
388    /* Test commutativity */
389    div.random();
390    div1.random();
391    div2.random();
392   
393    cout << "\t*** Test commutativity and associativity ***" << endl;
394    assert( (div + div1) == (div1 + div));
396    cout << "...Commutativity holds" << endl;
398    cout << "\t*** Test associativity ***" << endl;
399    assert( ((div + div1) + div2) == (div + (div1 + div2)) );
401    cout << "...Associativity holds" << endl;
403    /* Test divisor doubling */
404    cout << "\t*** Test doubling ***" << endl;
406    /* [2]* deg_2 */
407    cout << "- Doubling: deg 2 -" << endl;
409    div1.random();
411 #if DEBUG_LEVEL > 1
412    cout << "Random div1: " << endl;
413    cout << div1 << endl;
414 #endif 
416    if (add_cantor(divc, div1, div1))
417      cout << "divc = [2]*div1: add_cantor()" << endl;
419    if (add(div, div1, div1))
420      cout << "div =[2]*div1: add()" << endl;
422    compare(div, divc, "Doubling([2]*2)");
424    /* [2]* deg_1 */
425    cout << "- Doubling: deg 1 -" << endl;
427    div1.random(DEGREE_1);
429 #if DEBUG_LEVEL > 1
430    cout << "Random div1: " << endl;
431    cout << div1 << endl;
432 #endif
434    if (add_cantor(divc, div1, div1))
435      cout << "divc = [2]*div1: add_cantor()" << endl;
437    if (add(div, div1, div1))
438      cout << "div =[2]*div1: add()" << endl;
440    compare(div, divc, "Doubling([2]*1)");
442    /* Test divisor subtraction */
443    cout << "\t*** Test subtraction ***" << endl;
445    div1.random();
446    div2.random();
448    div = div1 - div2;
450 #if DEBUG_LEVEL > 1
451    cout << "Random div1: " << endl;
452    cout << div1 << endl;
454    cout << "Random div2: " << endl;
455    cout << div2 << endl;
457    cout << "div1 - div2: " << endl;
458    cout << div << endl;
459 #endif
461    assert(div.is_valid_divisor());
462    cout << "Checking subtraction...OK" << endl;
464    /* Test scalar multiplication */
465    cout << "\t*** Test scalar multiplication ***" << endl;
467   do {
468    div.random();
470    assert(div.is_valid_divisor());
471    cout << "Random base divisor generated" << endl;
473    cout << "Please choose exponent n (up to " << MAX_STRING_LEN 
474 << " decimal digits.  Input '.' to break): " << endl;
476    cin.getline(exp, MAX_STRING_LEN);
478    if (exp[0] == '.') break;
480    n = to_ZZ(exp);
482    cout << "Exponent n = " << n << endl;
484 #if DEBUG_LEVEL > 2
485    cout << "div: " << endl;
486    cout << div << endl;
487 #endif
489    /* Operator* */
491    scalar_mul(div1, div, n, NULL);
493    assert(div1.is_valid_divisor());
494    cout << "Checking scalar multiplication: square and multiply...OK" << endl;
496 #if DEBUG_LEVEL > 1
497    cout << "[" << n << "]*div: SAM " << endl;
498    cout << div1 << endl;
499 #endif
501    scalar_mul(div2, div, n, NAF);
502    assert(div2.is_valid_divisor());
503    cout << "Checking scalar multiplication: non-adjacent form...OK" << endl;
505 #if DEBUG_LEVEL > 1
506    cout << "[" << n << "]*div: NAF " << endl;
507    cout << div2 << endl;
508 #endif
510    scalar_mul(divc, div, n,  ML);
511    assert(divc.is_valid_divisor());
512    cout << "Checking scalar multiplication: Montgomery's ladder...OK" << endl;
514 #if DEBUG_LEVEL > 1
515    cout << "[" << n << "]*div: ML " << endl;
516    cout << divc << endl;
517 #endif
519    assert(div1 == div2 && div2 == divc);
520    cout << "Outcomes of three method should agree...OK" << endl;
522    /* Test operator* */
523    cout << "- Test operator* -" << endl;
524    assert( (divc == n*div) && (divc == div*n));
525    cout << "Checking operator*...OK" << endl;
527   } while (1);
529    cout << "**************************************" << endl;
530    cout << "  Test completed. Everything seems OK" << endl;
531    cout << "**************************************" << endl;
533    return 0;
537 static void compare(const divisor& div, const divisor& divc, string ops)
539    if (divc == div ) {
540      cout << ops << " results agree: div equals divc" << endl;
541 #if DEBUG_LEVEL > 1
542      cout << div << endl << endl;
543 #endif
544    } else {
545      cout << ops << " arithemetic wrong" << endl;
546      assert(0);
547    }