3 * Testing group operations
5 * (c) 2004 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Catacomb.
12 * Catacomb is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
17 * Catacomb is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
28 /*----- Header files ------------------------------------------------------*/
32 #include <mLib/macros.h>
33 #include <mLib/testrig.h>
40 /*----- Main code ---------------------------------------------------------*/
42 static group
*getgroup(const char *p
) {
43 group
*g
; qd_parse qd
;
44 qd
.p
= p
; qd
.e
= 0; g
= group_parse(&qd
);
45 if (g
&& !qd_eofp(&qd
)) { G_DESTROYGROUP(g
); g
= 0; qd
.e
= "junk at eof"; }
47 fprintf(stderr
, "bad group string `%.*s|%s': %s\n",
48 (int)(qd
.p
- p
), p
, qd
.p
, qd
.e
);
54 static ge
*getge(group
*g
, const char *p
) {
56 if (group_readstring(g
, x
, p
, 0)) {
57 fprintf(stderr
, "bad group element `%s'\n", p
);
63 static void show(group
*g
, const char *p
, ge
*x
) {
64 fprintf(stderr
, "*** %s = ", p
); group_writefile(g
, x
, stderr
);
68 static void showec(const char *p
, ec
*q
) {
69 fprintf(stderr
, "*** %s = ", p
);
70 if (EC_ATINF(q
)) fprintf(stderr
, "inf\n");
72 mp_writefile(q
->x
, stderr
, 16); fputs(", ", stderr
);
73 mp_writefile(q
->x
, stderr
, 16); putchar('\n');
77 static void showmp(const char *p
, mp
*x
, int r
) {
78 fprintf(stderr
, "*** %s = ", p
); mp_writefile(x
, stderr
, r
);
82 static int EXECL_LIKE(0)
83 check(const char *op
, const char *gd
, group
*g
, ge
*r
, ge
*c
, ...)
87 if (G_EQ(g
, r
, c
)) return (1);
88 fprintf(stderr
, "\n*** %s failed\n", op
);
89 fprintf(stderr
, "*** group: %s\n", gd
);
93 p
= va_arg(ap
, const char *); if (!p
) break;
94 x
= va_arg(ap
, ge
*); show(g
, p
, x
);
96 show(g
, "expected", r
);
97 show(g
, "computed", c
);
101 /*----- Actual tests ------------------------------------------------------*/
103 static int vcheck(dstr
*v
)
105 group
*g
= getgroup(v
[0].buf
);
106 grand
*gr
= fibrand_create(0);
107 const char *e
= G_CHECK(g
, gr
);
109 gr
->ops
->destroy(gr
);
112 if (STRCMP(e
, !=, v
[1].buf
)) {
114 fprintf(stderr
, "*** check failed\n");
115 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
116 fprintf(stderr
, "*** expected: %s\n", v
[1].buf
);
117 fprintf(stderr
, "*** returned: %s\n", e
);
119 assert(mparena_count(MPARENA_GLOBAL
) == 0);
123 static int vcheckelt(dstr
*v
)
125 group
*g
= getgroup(v
[0].buf
);
126 ge
*x
= getge(g
, v
[1].buf
);
127 int ir
= *(int *)v
[2].buf
;
128 int ic
= group_check(g
, x
);
132 fprintf(stderr
, "*** check failed\n");
133 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
135 fprintf(stderr
, "*** expected %s\n", ir ?
"failure" : "success");
139 assert(mparena_count(MPARENA_GLOBAL
) == 0);
143 static int vmul(dstr
*v
)
145 group
*g
= getgroup(v
[0].buf
);
146 ge
*x
= getge(g
, v
[1].buf
);
147 ge
*y
= getge(g
, v
[2].buf
);
148 ge
*r
= getge(g
, v
[3].buf
);
152 ok
&= check("mul", v
[0].buf
, g
, r
, c
, "x", x
, "y", y
, (char *)0);
153 G_DESTROY(g
, x
); G_DESTROY(g
, y
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
155 assert(mparena_count(MPARENA_GLOBAL
) == 0);
159 static int vsqr(dstr
*v
)
161 group
*g
= getgroup(v
[0].buf
);
162 ge
*x
= getge(g
, v
[1].buf
);
163 ge
*r
= getge(g
, v
[2].buf
);
167 ok
&= check("sqr", v
[0].buf
, g
, r
, c
, "x", x
, (char *)0);
168 G_DESTROY(g
, x
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
170 assert(mparena_count(MPARENA_GLOBAL
) == 0);
174 static int vinv(dstr
*v
)
176 group
*g
= getgroup(v
[0].buf
);
177 ge
*x
= getge(g
, v
[1].buf
);
178 ge
*r
= getge(g
, v
[2].buf
);
182 ok
&= check("inv", v
[0].buf
, g
, r
, c
, "x", x
, (char *)0);
183 G_DESTROY(g
, x
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
185 assert(mparena_count(MPARENA_GLOBAL
) == 0);
189 static int vdiv(dstr
*v
)
191 group
*g
= getgroup(v
[0].buf
);
192 ge
*x
= getge(g
, v
[1].buf
);
193 ge
*y
= getge(g
, v
[2].buf
);
194 ge
*r
= getge(g
, v
[3].buf
);
198 ok
&= check("div", v
[0].buf
, g
, r
, c
, "x", x
, "y", y
, (char *)0);
199 group_stddiv(g
, c
, x
, y
);
200 ok
&= check("stddiv", v
[0].buf
, g
, r
, c
, "x", x
, "y", y
, (char *)0);
201 G_DESTROY(g
, x
); G_DESTROY(g
, y
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
203 assert(mparena_count(MPARENA_GLOBAL
) == 0);
207 static int vexp(dstr
*v
)
209 group
*g
= getgroup(v
[0].buf
);
210 ge
*x
= getge(g
, v
[1].buf
);
211 mp
*n
= *(mp
**)v
[2].buf
;
212 ge
*r
= getge(g
, v
[3].buf
);
216 if (!G_EQ(g
, r
, c
)) {
218 fprintf(stderr
, "\n*** exp failed\n");
219 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
220 show(g
, "x", x
); showmp("n", n
, 10);
221 show(g
, "expected", r
); show(g
, "computed", c
);
223 group_stdexp(g
, c
, x
, n
);
224 if (!G_EQ(g
, r
, c
)) {
226 fprintf(stderr
, "\n*** stdexp failed\n");
227 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
228 show(g
, "x", x
); showmp("n", n
, 10);
229 show(g
, "expected", r
); show(g
, "computed", c
);
231 G_DESTROY(g
, x
); MP_DROP(n
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
233 assert(mparena_count(MPARENA_GLOBAL
) == 0);
237 static int vmexp(size_t n
, dstr
*v
)
239 group
*g
= getgroup(v
[0].buf
);
241 group_expfactor
*f
= xmalloc(n
* sizeof(group_expfactor
));
244 for (i
= 0; i
< n
; i
++) {
245 f
[i
].base
= getge(g
, v
[1 + 2 * i
].buf
);
246 f
[i
].exp
= *(mp
**)v
[2 + 2 * i
].buf
;
248 r
= getge(g
, v
[1 + 2 * n
].buf
);
251 if (!G_EQ(g
, r
, c
)) {
253 fprintf(stderr
, "\n*** mexp failed\n");
254 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
255 for (i
= 0; i
< n
; i
++) {
256 show(g
, "base", f
[i
].base
);
257 showmp("exp", f
[i
].exp
, 10);
259 show(g
, "expected", r
); show(g
, "computed", c
);
261 group_stdmexp(g
, c
, f
, n
);
262 if (!G_EQ(g
, r
, c
)) {
264 fprintf(stderr
, "\n*** stdmexp failed\n");
265 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
266 for (i
= 0; i
< n
; i
++) {
267 show(g
, "base", f
[i
].base
);
268 showmp("exp", f
[i
].exp
, 10);
270 show(g
, "expected", r
); show(g
, "computed", c
);
272 for (i
= 0; i
< n
; i
++) { G_DESTROY(g
, f
[i
].base
); MP_DROP(f
[i
].exp
); }
273 G_DESTROY(g
, r
); G_DESTROY(g
, c
);
275 assert(mparena_count(MPARENA_GLOBAL
) == 0);
279 static int vmexp1(dstr
*v
) { return vmexp(1, v
); }
280 static int vmexp2(dstr
*v
) { return vmexp(2, v
); }
281 static int vmexp3(dstr
*v
) { return vmexp(3, v
); }
282 static int vmexp4(dstr
*v
) { return vmexp(4, v
); }
284 static int vtoint(dstr
*v
)
286 group
*g
= getgroup(v
[0].buf
);
287 ge
*x
= getge(g
, v
[1].buf
);
288 int ir
= *(int *)v
[2].buf
;
289 mp
*r
= *(mp
**)v
[3].buf
;
293 c
= G_TOINT(g
, MP_NEW
, x
);
295 if (ir
!= ic
|| (!ic
&& !MP_EQ(r
, c
))) {
297 fprintf(stderr
, "\n*** toint failed\n");
298 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
299 if (ir
) fprintf(stderr
, "*** expected failure\n");
300 else { show(g
, "x", x
); showmp("expected", r
, 16);
301 showmp("computed", c
, 16); }
303 G_DESTROY(g
, x
); mp_drop(r
); mp_drop(c
);
305 assert(mparena_count(MPARENA_GLOBAL
) == 0);
309 static int vfromint(dstr
*v
)
311 group
*g
= getgroup(v
[0].buf
);
312 mp
*x
= *(mp
**)v
[1].buf
;
313 int ir
= *(int *)v
[2].buf
;
314 ge
*r
= getge(g
, v
[3].buf
);
318 ic
= G_FROMINT(g
, c
, x
);
319 if (ir
!= ic
|| (!ic
&& !G_EQ(g
, r
, c
))) {
321 fprintf(stderr
, "\n*** fromint failed\n");
322 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
323 showmp("x", x
, 16); if (ir
) fprintf(stderr
, "*** should have failed\n");
324 else { show(g
, "expected", r
); show(g
, "computed", c
); }
326 MP_DROP(x
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
328 assert(mparena_count(MPARENA_GLOBAL
) == 0);
332 static int vtoec(dstr
*v
)
334 group
*g
= getgroup(v
[0].buf
);
335 ge
*x
= getge(g
, v
[1].buf
);
336 int ir
= *(int *)v
[2].buf
;
337 ec
*r
= (ec
*)v
[3].buf
;
341 ic
= G_TOEC(g
, &c
, x
);
342 if (ir
!= ic
|| (!ic
&& !EC_EQ(r
, &c
))) {
344 fprintf(stderr
, "\n*** toec failed\n");
345 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
347 if (ir
) fprintf(stderr
, "*** should have failed\n");
348 else { showec("expected", r
); showec("computed", &c
); }
350 G_DESTROY(g
, x
); EC_DESTROY(&c
); EC_DESTROY(r
);
352 assert(mparena_count(MPARENA_GLOBAL
) == 0);
356 static int vfromec(dstr
*v
)
358 group
*g
= getgroup(v
[0].buf
);
359 ec
*p
= (ec
*)v
[1].buf
;
360 int ir
= *(int *)v
[2].buf
;
361 ge
*r
= getge(g
, v
[3].buf
);
365 ic
= G_FROMEC(g
, c
, p
);
366 if (ir
!= ic
|| (!ic
&& !G_EQ(g
, r
, c
))) {
368 fprintf(stderr
, "\n*** fromec failed\n");
369 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
370 showec("p", p
); if (ir
) fprintf(stderr
, "*** should have failed\n");
371 else { show(g
, "expected", r
); show(g
, "computed", c
); }
373 EC_DESTROY(p
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
375 assert(mparena_count(MPARENA_GLOBAL
) == 0);
379 static int vtobuf(dstr
*v
)
381 group
*g
= getgroup(v
[0].buf
);
382 ge
*x
= getge(g
, v
[1].buf
);
383 int ir
= *(int *)v
[2].buf
;
389 dstr_ensure(&c
, v
[3].len
);
390 buf_init(&b
, c
.buf
, v
[3].len
);
391 ic
= G_TOBUF(g
, &b
, x
);
393 if (ic
!= ir
|| (!ic
&& (c
.len
!= v
[3].len
||
394 MEMCMP(c
.buf
, !=, v
[3].buf
, c
.len
)))) {
396 fprintf(stderr
, "*** tobuf failed\n");
397 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
399 if (ir
) fprintf(stderr
, "*** expected failure\n");
401 fprintf(stderr
, "*** expected: "); type_hex
.dump(&v
[3], stderr
);
402 fprintf(stderr
, "\n*** computed: "); type_hex
.dump(&c
, stderr
);
406 G_DESTROY(g
, x
); dstr_destroy(&c
);
408 assert(mparena_count(MPARENA_GLOBAL
) == 0);
412 static int vfrombuf(dstr
*v
)
414 group
*g
= getgroup(v
[0].buf
);
415 int ir
= *(int *)v
[2].buf
;
416 ge
*r
= getge(g
, v
[3].buf
);
422 buf_init(&b
, v
[1].buf
, v
[1].len
);
423 ic
= G_FROMBUF(g
, &b
, c
);
424 if ((ic
< 0) != (ir
< 0) || (ir
>= 0 &&
425 (ir
!= BLEN(&b
) || !G_EQ(g
, r
, c
)))) {
427 fprintf(stderr
, "*** frombuf failed\n");
428 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
429 fprintf(stderr
, "*** input string: "); type_hex
.dump(&v
[1], stderr
);
431 if (ir
< 0) fprintf(stderr
, "*** expected failure\n");
433 show(g
, "expected", r
); show(g
, "computed", c
);
434 fprintf(stderr
, "*** expected used = %d\n", ir
);
435 fprintf(stderr
, "*** computed used = %lu\n", (unsigned long)BLEN(&b
));
438 G_DESTROY(g
, r
); G_DESTROY(g
, c
);
440 assert(mparena_count(MPARENA_GLOBAL
) == 0);
444 static int vtoraw(dstr
*v
)
446 group
*g
= getgroup(v
[0].buf
);
447 ge
*x
= getge(g
, v
[1].buf
);
448 int ir
= *(int *)v
[2].buf
;
454 dstr_ensure(&c
, v
[3].len
);
455 buf_init(&b
, c
.buf
, v
[3].len
);
456 ic
= G_TORAW(g
, &b
, x
);
458 if (ic
!= ir
|| (!ic
&& (c
.len
!= v
[3].len
||
459 MEMCMP(c
.buf
, !=, v
[3].buf
, c
.len
)))) {
461 fprintf(stderr
, "*** toraw failed\n");
462 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
464 if (ir
) fprintf(stderr
, "*** expected failure\n");
466 fprintf(stderr
, "*** expected: "); type_hex
.dump(&v
[3], stderr
);
467 fprintf(stderr
, "\n*** computed: "); type_hex
.dump(&c
, stderr
);
471 G_DESTROY(g
, x
); dstr_destroy(&c
);
473 assert(mparena_count(MPARENA_GLOBAL
) == 0);
477 static int vfromraw(dstr
*v
)
479 group
*g
= getgroup(v
[0].buf
);
480 int ir
= *(int *)v
[2].buf
;
481 ge
*r
= getge(g
, v
[3].buf
);
487 buf_init(&b
, v
[1].buf
, v
[1].len
);
488 ic
= G_FROMRAW(g
, &b
, c
);
489 if ((ic
< 0) != (ir
< 0) || (ir
>= 0 &&
490 (ir
!= BLEN(&b
) || !G_EQ(g
, r
, c
)))) {
492 fprintf(stderr
, "*** fromraw failed\n");
493 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
494 fprintf(stderr
, "*** input string: "); type_hex
.dump(&v
[1], stderr
);
496 if (ir
< 0) fprintf(stderr
, "*** expected failure\n");
498 show(g
, "expected", r
); show(g
, "computed", c
);
499 fprintf(stderr
, "*** expected used = %d\n", ir
);
500 fprintf(stderr
, "*** computed used = %lu\n", (unsigned long)BLEN(&b
));
503 G_DESTROY(g
, r
); G_DESTROY(g
, c
);
505 assert(mparena_count(MPARENA_GLOBAL
) == 0);
509 static const test_chunk tests
[] = {
510 { "check", vcheck
, { &type_string
, &type_string
} },
511 { "checkelt", vcheckelt
, { &type_string
, &type_string
, &type_int
} },
512 { "mul", vmul
, { &type_string
, &type_string
,
513 &type_string
, &type_string
} },
514 { "sqr", vsqr
, { &type_string
, &type_string
,
516 { "inv", vinv
, { &type_string
, &type_string
,
518 { "div", vdiv
, { &type_string
, &type_string
,
519 &type_string
, &type_string
} },
520 { "exp", vexp
, { &type_string
, &type_string
,
521 &type_mp
, &type_string
} },
522 { "mexp-1", vmexp1
, { &type_string
,
523 &type_string
, &type_mp
,
525 { "mexp-2", vmexp2
, { &type_string
,
526 &type_string
, &type_mp
,
527 &type_string
, &type_mp
,
529 { "mexp-3", vmexp3
, { &type_string
,
530 &type_string
, &type_mp
,
531 &type_string
, &type_mp
,
532 &type_string
, &type_mp
,
534 { "mexp-4", vmexp4
, { &type_string
,
535 &type_string
, &type_mp
,
536 &type_string
, &type_mp
,
537 &type_string
, &type_mp
,
538 &type_string
, &type_mp
,
540 { "toint", vtoint
, { &type_string
, &type_string
,
541 &type_int
, &type_mp
} },
542 { "fromint", vfromint
, { &type_string
, &type_mp
,
543 &type_int
, &type_string
} },
544 { "toec", vtoec
, { &type_string
, &type_string
,
545 &type_int
, &type_ec
} },
546 { "fromec", vfromec
, { &type_string
, &type_ec
,
547 &type_int
, &type_string
} },
548 { "tobuf", vtobuf
, { &type_string
, &type_string
,
549 &type_int
, &type_hex
} },
550 { "frombuf", vfrombuf
, { &type_string
, &type_hex
,
551 &type_int
, &type_string
} },
552 { "toraw", vtoraw
, { &type_string
, &type_string
,
553 &type_int
, &type_hex
} },
554 { "fromraw", vfromraw
, { &type_string
, &type_hex
,
555 &type_int
, &type_string
} },
559 int main(int argc
, char *argv
[])
562 test_run(argc
, argv
, tests
, SRCDIR
"/t/group");
566 /*----- That's all, folks -------------------------------------------------*/