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
7 #include <g2hec_nsfieldtype.h>
9 #include <g2hec_Genus2_ops.h>
10 #include <g2hec_nsdebug.h>
13 #define MAX_STRING_LEN 300
17 static void compare(const divisor& div, const divisor& divc, string ops);
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;
29 cin.getline(p, MAX_STRING_LEN);
31 ZZ n; // For scalar multiplication
33 field_t::init(to_ZZ(p)); // define GF(p)
39 divisor div, divc, div1, div2;
42 SetCoeff(f, 5, 1); // Make monic of degree 5
48 /*****************************************\
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;
64 assert(curve.is_valid_curve());
65 cout << "Checking valid curve...OK" << endl;
69 cout << curve << endl;
71 /* Test g2hcurve::operator<< */
72 cout << curve << endl;
75 /* Another valid curve with h(x) = 0. Assume char is not 2 */
76 cout << "- Valid curve 2 - " << endl;
79 random(f, 6); // deg(f) < 6
80 SetCoeff(f, 5, 1); // f5 = 1;
81 } while (!DetIrredTest(f));
89 assert(curve.is_valid_curve());
90 cout << "Checking valid curve (h = 0)...OK" << endl;
93 cout << curve << endl;
96 /* Test invalid curve: not genus 2 */
97 cout << "- Invalid curve 1: not genus 2 -" << endl;
99 NTL_NNS random(f, 5); // degree < 5
104 assert(!curve.is_valid_curve());
105 cout << "Checking invalid curve: not genus 2...OK" << endl;
108 cout << curve << endl;
111 /* Test invalid curve: singular */
112 cout << "- Invalid curve 2: singular -" << endl;
116 SetCoeff(f, 1, 2); // f = x^2 + 2x + 1 = (x + 1)^2
123 assert(!curve.is_valid_curve());
124 cout << "Checking invalid curve: singular...OK" << endl;
127 cout << curve << endl;
130 /* Test invalid curve: f(x) not monic */
131 cout << "- Invalid curve 3: f(x) not monic -" << endl;
138 assert(!curve.is_valid_curve());
139 cout << "Checking invalid curve: non-monic f(x)...OK" << endl;
142 cout << curve << endl;
145 /*****************************************\
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
162 assert(div.is_valid_divisor());
163 cout << "Checking random divisor...OK" << endl;
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 */
175 "Invalid curve is a checked runtime error for all divisor arithmetic ops"
178 /* Invalid divisor: invalid upoly */
180 cout << "- Invalid divisor 2: invalid upoly -" << endl;
182 SetCoeff(u, genus + 1, 1); // deg(u) = 3
186 assert(!div.is_valid_divisor());
187 cout << "Checking invalid divisor: invalid u(x)...OK" << endl;
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;
203 assert(div.is_unit());
204 cout << "Checking unit divisor...OK" << endl;
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
220 assert(!div.is_valid_divisor());
221 cout << "Checking invalid divisor: invalid v(x)...OK" << endl;
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;
244 assert(div2.is_valid_divisor());
245 cout << "Checking divisor negation...OK" << endl;
248 cout << "div1: " << endl;
249 cout << div1 << endl;
251 cout << "div2 = -div1:" << endl;
252 cout << div2 << endl;
257 assert(div.is_unit());
258 cout << "This test should return a unit divisor...OK" << endl;
261 cout << "div1 + div2: " << endl;
265 /* Test divisor addition */
266 cout << "\t*** Test addition ***" << endl;
269 cout << "- Addition: deg 2 + deg 2 -" << endl;
275 } while (div1 == div2); // Choose diffrent div2
278 cout << "Random div1: " << endl;
279 cout << div1 << endl;
280 cout << "Random div2: " << endl;
281 cout << div2 << endl;
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;
292 if (add(div, div1, div2))
293 cout << "div = div1 + div2: add()" << endl;
295 compare(div, divc, "Addtion(2+2)");
298 cout << "- Addition: deg 2 + deg 1 -" << endl;
300 div1.random(); // degree 2
301 div2.random(DEGREE_1);// degree 1
304 cout << "Random div1: " << endl;
305 cout << div1 << endl;
306 cout << "Random div2: " << endl;
307 cout << div2 << endl;
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;
318 compare(div, divc, "Addition(2+1)");
321 cout << "- Addition: deg 1 + deg 1 -" << endl;
323 div1.random(DEGREE_1);
325 div2.random(DEGREE_1);
326 } while (div1 == div2);
329 cout << "Random div1: " << endl;
330 cout << div1 << endl;
331 cout << "Random div2: " << endl;
332 cout << div2 << endl;
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)");
343 cout << "- Addition: deg 2 + unit divisor -" << endl;
349 cout << "Random div1: " << endl;
350 cout << div1 << endl;
351 cout << "Unit div2: " << endl;
352 cout << div2 << endl;
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)");
364 cout << "Checking adding unit divisor...OK" << endl;
367 cout << "- Addition: unit divisor + unit divisor -" << endl;
373 cout << "Unit div1 & div2: " << endl;
374 cout << div1 << endl;
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)");
386 cout << "Result should be unit...OK" << endl;
388 /* Test commutativity */
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;
407 cout << "- Doubling: deg 2 -" << endl;
412 cout << "Random div1: " << endl;
413 cout << div1 << endl;
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)");
425 cout << "- Doubling: deg 1 -" << endl;
427 div1.random(DEGREE_1);
430 cout << "Random div1: " << endl;
431 cout << div1 << endl;
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;
451 cout << "Random div1: " << endl;
452 cout << div1 << endl;
454 cout << "Random div2: " << endl;
455 cout << div2 << endl;
457 cout << "div1 - div2: " << endl;
461 assert(div.is_valid_divisor());
462 cout << "Checking subtraction...OK" << endl;
464 /* Test scalar multiplication */
465 cout << "\t*** Test scalar multiplication ***" << endl;
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;
482 cout << "Exponent n = " << n << endl;
485 cout << "div: " << endl;
491 scalar_mul(div1, div, n, NULL);
493 assert(div1.is_valid_divisor());
494 cout << "Checking scalar multiplication: square and multiply...OK" << endl;
497 cout << "[" << n << "]*div: SAM " << endl;
498 cout << div1 << endl;
501 scalar_mul(div2, div, n, NAF);
502 assert(div2.is_valid_divisor());
503 cout << "Checking scalar multiplication: non-adjacent form...OK" << endl;
506 cout << "[" << n << "]*div: NAF " << endl;
507 cout << div2 << endl;
510 scalar_mul(divc, div, n, ML);
511 assert(divc.is_valid_divisor());
512 cout << "Checking scalar multiplication: Montgomery's ladder...OK" << endl;
515 cout << "[" << n << "]*div: ML " << endl;
516 cout << divc << endl;
519 assert(div1 == div2 && div2 == divc);
520 cout << "Outcomes of three method should agree...OK" << endl;
523 cout << "- Test operator* -" << endl;
524 assert( (divc == n*div) && (divc == div*n));
525 cout << "Checking operator*...OK" << endl;
529 cout << "**************************************" << endl;
530 cout << " Test completed. Everything seems OK" << endl;
531 cout << "**************************************" << endl;
537 static void compare(const divisor& div, const divisor& divc, string ops)
540 cout << ops << " results agree: div equals divc" << endl;
542 cout << div << endl << endl;
545 cout << ops << " arithemetic wrong" << endl;