3 * $Id: group-test.c,v 1.3 2004/04/08 01:36:15 mdw Exp $
5 * Testing group operations
7 * (c) 2004 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30 /*----- Header files ------------------------------------------------------*/
34 #include <mLib/testrig.h>
41 /*----- Main code ---------------------------------------------------------*/
43 static group
*getgroup(const char *p
) {
44 group
*g
; qd_parse qd
;
45 qd
.p
= p
; qd
.e
= 0; g
= group_parse(&qd
);
46 if (g
&& !qd_eofp(&qd
)) { G_DESTROYGROUP(g
); g
= 0; qd
.e
= "junk at eof"; }
47 if (!g
) { fprintf(stderr
, "bad group string `%.*s|%s': %s\n", qd
.p
- p
,
48 p
, qd
.p
, qd
.e
); exit(1); }
52 static ge
*getge(group
*g
, const char *p
) {
54 if (group_readstring(g
, x
, p
, 0)) {
55 fprintf(stderr
, "bad group element `%s'\n", p
);
61 static void show(group
*g
, const char *p
, ge
*x
) {
62 fprintf(stderr
, "*** %s = ", p
); group_writefile(g
, x
, stderr
);
66 static void showec(const char *p
, ec
*q
) {
67 fprintf(stderr
, "*** %s = ", p
);
68 if (EC_ATINF(q
)) fprintf(stderr
, "inf\n");
70 mp_writefile(q
->x
, stderr
, 16); fputs(", ", stderr
);
71 mp_writefile(q
->x
, stderr
, 16); putchar('\n');
75 static void showmp(const char *p
, mp
*x
, int r
) {
76 fprintf(stderr
, "*** %s = ", p
); mp_writefile(x
, stderr
, r
);
80 static int check(const char *op
, const char *gd
, group
*g
,
84 if (G_EQ(g
, r
, c
)) return (1);
85 fprintf(stderr
, "\n*** %s failed\n", op
);
86 fprintf(stderr
, "*** group: %s\n", gd
);
90 p
= va_arg(ap
, const char *); if (!p
) break;
91 x
= va_arg(ap
, ge
*); show(g
, p
, x
);
93 show(g
, "expected", r
);
94 show(g
, "computed", c
);
98 /*----- Actual tests ------------------------------------------------------*/
100 static int vcheck(dstr
*v
)
102 group
*g
= getgroup(v
[0].buf
);
103 grand
*gr
= fibrand_create(0);
104 const char *e
= G_CHECK(g
, gr
);
106 gr
->ops
->destroy(gr
);
109 if (strcmp(e
, v
[1].buf
)) {
111 fprintf(stderr
, "*** check failed\n");
112 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
113 fprintf(stderr
, "*** expected: %s\n", v
[1].buf
);
114 fprintf(stderr
, "*** returned: %s\n", e
);
116 assert(mparena_count(MPARENA_GLOBAL
) == 0);
120 static int vcheckelt(dstr
*v
)
122 group
*g
= getgroup(v
[0].buf
);
123 ge
*x
= getge(g
, v
[1].buf
);
124 int ir
= *(int *)v
[2].buf
;
125 int ic
= group_check(g
, x
);
129 fprintf(stderr
, "*** check failed\n");
130 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
132 fprintf(stderr
, "*** expected %s\n", ir ?
"failure" : "success");
136 assert(mparena_count(MPARENA_GLOBAL
) == 0);
140 static int vmul(dstr
*v
)
142 group
*g
= getgroup(v
[0].buf
);
143 ge
*x
= getge(g
, v
[1].buf
);
144 ge
*y
= getge(g
, v
[2].buf
);
145 ge
*r
= getge(g
, v
[3].buf
);
149 ok
&= check("mul", v
[0].buf
, g
, r
, c
, "x", x
, "y", y
, (char *)0);
150 G_DESTROY(g
, x
); G_DESTROY(g
, y
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
152 assert(mparena_count(MPARENA_GLOBAL
) == 0);
156 static int vsqr(dstr
*v
)
158 group
*g
= getgroup(v
[0].buf
);
159 ge
*x
= getge(g
, v
[1].buf
);
160 ge
*r
= getge(g
, v
[2].buf
);
164 ok
&= check("sqr", v
[0].buf
, g
, r
, c
, "x", x
, (char *)0);
165 G_DESTROY(g
, x
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
167 assert(mparena_count(MPARENA_GLOBAL
) == 0);
171 static int vinv(dstr
*v
)
173 group
*g
= getgroup(v
[0].buf
);
174 ge
*x
= getge(g
, v
[1].buf
);
175 ge
*r
= getge(g
, v
[2].buf
);
179 ok
&= check("inv", v
[0].buf
, g
, r
, c
, "x", x
, (char *)0);
180 G_DESTROY(g
, x
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
182 assert(mparena_count(MPARENA_GLOBAL
) == 0);
186 static int vdiv(dstr
*v
)
188 group
*g
= getgroup(v
[0].buf
);
189 ge
*x
= getge(g
, v
[1].buf
);
190 ge
*y
= getge(g
, v
[2].buf
);
191 ge
*r
= getge(g
, v
[3].buf
);
195 ok
&= check("div", v
[0].buf
, g
, r
, c
, "x", x
, "y", y
, (char *)0);
196 group_stddiv(g
, c
, x
, y
);
197 ok
&= check("stddiv", v
[0].buf
, g
, r
, c
, "x", x
, "y", y
, (char *)0);
198 G_DESTROY(g
, x
); G_DESTROY(g
, y
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
200 assert(mparena_count(MPARENA_GLOBAL
) == 0);
204 static int vexp(dstr
*v
)
206 group
*g
= getgroup(v
[0].buf
);
207 ge
*x
= getge(g
, v
[1].buf
);
208 mp
*n
= *(mp
**)v
[2].buf
;
209 ge
*r
= getge(g
, v
[3].buf
);
213 if (!G_EQ(g
, r
, c
)) {
215 fprintf(stderr
, "\n*** exp failed\n");
216 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
217 show(g
, "x", x
); showmp("n", n
, 10);
218 show(g
, "expected", r
); show(g
, "computed", c
);
220 group_stdexp(g
, c
, x
, n
);
221 if (!G_EQ(g
, r
, c
)) {
223 fprintf(stderr
, "\n*** stdexp failed\n");
224 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
225 show(g
, "x", x
); showmp("n", n
, 10);
226 show(g
, "expected", r
); show(g
, "computed", c
);
228 G_DESTROY(g
, x
); MP_DROP(n
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
230 assert(mparena_count(MPARENA_GLOBAL
) == 0);
234 static int vmexp(size_t n
, dstr
*v
)
236 group
*g
= getgroup(v
[0].buf
);
238 group_expfactor
*f
= xmalloc(n
* sizeof(group_expfactor
));
241 for (i
= 0; i
< n
; i
++) {
242 f
[i
].base
= getge(g
, v
[1 + 2 * i
].buf
);
243 f
[i
].exp
= *(mp
**)v
[2 + 2 * i
].buf
;
245 r
= getge(g
, v
[1 + 2 * n
].buf
);
248 if (!G_EQ(g
, r
, c
)) {
250 fprintf(stderr
, "\n*** mexp failed\n");
251 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
252 for (i
= 0; i
< n
; i
++) {
253 show(g
, "base", f
[i
].base
);
254 showmp("exp", f
[i
].exp
, 10);
256 show(g
, "expected", r
); show(g
, "computed", c
);
258 group_stdmexp(g
, c
, f
, n
);
259 if (!G_EQ(g
, r
, c
)) {
261 fprintf(stderr
, "\n*** stdmexp failed\n");
262 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
263 for (i
= 0; i
< n
; i
++) {
264 show(g
, "base", f
[i
].base
);
265 showmp("exp", f
[i
].exp
, 10);
267 show(g
, "expected", r
); show(g
, "computed", c
);
269 for (i
= 0; i
< n
; i
++) { G_DESTROY(g
, f
[i
].base
); MP_DROP(f
[i
].exp
); }
270 G_DESTROY(g
, r
); G_DESTROY(g
, c
);
272 assert(mparena_count(MPARENA_GLOBAL
) == 0);
276 static int vmexp1(dstr
*v
) { return vmexp(1, v
); }
277 static int vmexp2(dstr
*v
) { return vmexp(2, v
); }
278 static int vmexp3(dstr
*v
) { return vmexp(3, v
); }
279 static int vmexp4(dstr
*v
) { return vmexp(4, v
); }
281 static int vtoint(dstr
*v
)
283 group
*g
= getgroup(v
[0].buf
);
284 ge
*x
= getge(g
, v
[1].buf
);
285 int ir
= *(int *)v
[2].buf
;
286 mp
*r
= *(mp
**)v
[3].buf
;
290 c
= G_TOINT(g
, MP_NEW
, x
);
292 if (ir
!= ic
|| (!ic
&& !MP_EQ(r
, c
))) {
294 fprintf(stderr
, "\n*** toint failed\n");
295 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
296 if (ir
) fprintf(stderr
, "*** expected failure\n");
297 else { show(g
, "x", x
); showmp("expected", r
, 16);
298 showmp("computed", c
, 16); }
300 G_DESTROY(g
, x
); mp_drop(r
); mp_drop(c
);
302 assert(mparena_count(MPARENA_GLOBAL
) == 0);
306 static int vfromint(dstr
*v
)
308 group
*g
= getgroup(v
[0].buf
);
309 mp
*x
= *(mp
**)v
[1].buf
;
310 int ir
= *(int *)v
[2].buf
;
311 ge
*r
= getge(g
, v
[3].buf
);
315 ic
= G_FROMINT(g
, c
, x
);
316 if (ir
!= ic
|| (!ic
&& !G_EQ(g
, r
, c
))) {
318 fprintf(stderr
, "\n*** fromint failed\n");
319 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
320 showmp("x", x
, 16); if (ir
) fprintf(stderr
, "*** should have failed\n");
321 else { show(g
, "expected", r
); show(g
, "computed", c
); }
323 MP_DROP(x
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
325 assert(mparena_count(MPARENA_GLOBAL
) == 0);
329 static int vtoec(dstr
*v
)
331 group
*g
= getgroup(v
[0].buf
);
332 ge
*x
= getge(g
, v
[1].buf
);
333 int ir
= *(int *)v
[2].buf
;
334 ec
*r
= (ec
*)v
[3].buf
;
338 ic
= G_TOEC(g
, &c
, x
);
339 if (ir
!= ic
|| (!ic
&& !EC_EQ(r
, &c
))) {
341 fprintf(stderr
, "\n*** toec failed\n");
342 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
344 if (ir
) fprintf(stderr
, "*** should have failed\n");
345 else { showec("expected", r
); showec("computed", &c
); }
347 G_DESTROY(g
, x
); EC_DESTROY(&c
); EC_DESTROY(r
);
349 assert(mparena_count(MPARENA_GLOBAL
) == 0);
353 static int vfromec(dstr
*v
)
355 group
*g
= getgroup(v
[0].buf
);
356 ec
*p
= (ec
*)v
[1].buf
;
357 int ir
= *(int *)v
[2].buf
;
358 ge
*r
= getge(g
, v
[3].buf
);
362 ic
= G_FROMEC(g
, c
, p
);
363 if (ir
!= ic
|| (!ic
&& !G_EQ(g
, r
, c
))) {
365 fprintf(stderr
, "\n*** fromec failed\n");
366 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
367 showec("p", p
); if (ir
) fprintf(stderr
, "*** should have failed\n");
368 else { show(g
, "expected", r
); show(g
, "computed", c
); }
370 EC_DESTROY(p
); G_DESTROY(g
, r
); G_DESTROY(g
, c
);
372 assert(mparena_count(MPARENA_GLOBAL
) == 0);
376 static int vtobuf(dstr
*v
)
378 group
*g
= getgroup(v
[0].buf
);
379 ge
*x
= getge(g
, v
[1].buf
);
380 int ir
= *(int *)v
[2].buf
;
386 dstr_ensure(&c
, v
[3].len
);
387 buf_init(&b
, c
.buf
, v
[3].len
);
388 ic
= G_TOBUF(g
, &b
, x
);
390 if (ic
!= ir
|| (!ic
&& (c
.len
!= v
[3].len
||
391 memcmp(c
.buf
, v
[3].buf
, c
.len
)))) {
393 fprintf(stderr
, "*** tobuf failed\n");
394 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
396 if (ir
) fprintf(stderr
, "*** expected failure\n");
398 fprintf(stderr
, "*** expected: "); type_hex
.dump(&v
[3], stderr
);
399 fprintf(stderr
, "\n*** computed: "); type_hex
.dump(&c
, stderr
);
403 G_DESTROY(g
, x
); dstr_destroy(&c
);
405 assert(mparena_count(MPARENA_GLOBAL
) == 0);
409 static int vfrombuf(dstr
*v
)
411 group
*g
= getgroup(v
[0].buf
);
412 int ir
= *(int *)v
[2].buf
;
413 ge
*r
= getge(g
, v
[3].buf
);
419 buf_init(&b
, v
[1].buf
, v
[1].len
);
420 ic
= G_FROMBUF(g
, &b
, c
);
421 if ((ic
< 0) != (ir
< 0) || (ir
>= 0 &&
422 (ir
!= BLEN(&b
) || !G_EQ(g
, r
, c
)))) {
424 fprintf(stderr
, "*** frombuf failed\n");
425 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
426 fprintf(stderr
, "*** input string: "); type_hex
.dump(&v
[1], stderr
);
428 if (ir
< 0) fprintf(stderr
, "*** expected failure\n");
430 show(g
, "expected", r
); show(g
, "computed", c
);
431 fprintf(stderr
, "*** expected used = %d\n", ir
);
432 fprintf(stderr
, "*** computed used = %lu\n", (unsigned long)BLEN(&b
));
435 G_DESTROY(g
, r
); G_DESTROY(g
, c
);
437 assert(mparena_count(MPARENA_GLOBAL
) == 0);
441 static int vtoraw(dstr
*v
)
443 group
*g
= getgroup(v
[0].buf
);
444 ge
*x
= getge(g
, v
[1].buf
);
445 int ir
= *(int *)v
[2].buf
;
451 dstr_ensure(&c
, v
[3].len
);
452 buf_init(&b
, c
.buf
, v
[3].len
);
453 ic
= G_TORAW(g
, &b
, x
);
455 if (ic
!= ir
|| (!ic
&& (c
.len
!= v
[3].len
||
456 memcmp(c
.buf
, v
[3].buf
, c
.len
)))) {
458 fprintf(stderr
, "*** toraw failed\n");
459 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
461 if (ir
) fprintf(stderr
, "*** expected failure\n");
463 fprintf(stderr
, "*** expected: "); type_hex
.dump(&v
[3], stderr
);
464 fprintf(stderr
, "\n*** computed: "); type_hex
.dump(&c
, stderr
);
468 G_DESTROY(g
, x
); dstr_destroy(&c
);
470 assert(mparena_count(MPARENA_GLOBAL
) == 0);
474 static int vfromraw(dstr
*v
)
476 group
*g
= getgroup(v
[0].buf
);
477 int ir
= *(int *)v
[2].buf
;
478 ge
*r
= getge(g
, v
[3].buf
);
484 buf_init(&b
, v
[1].buf
, v
[1].len
);
485 ic
= G_FROMRAW(g
, &b
, c
);
486 if ((ic
< 0) != (ir
< 0) || (ir
>= 0 &&
487 (ir
!= BLEN(&b
) || !G_EQ(g
, r
, c
)))) {
489 fprintf(stderr
, "*** fromraw failed\n");
490 fprintf(stderr
, "*** group: %s\n", v
[0].buf
);
491 fprintf(stderr
, "*** input string: "); type_hex
.dump(&v
[1], stderr
);
493 if (ir
< 0) fprintf(stderr
, "*** expected failure\n");
495 show(g
, "expected", r
); show(g
, "computed", c
);
496 fprintf(stderr
, "*** expected used = %d\n", ir
);
497 fprintf(stderr
, "*** computed used = %lu\n", (unsigned long)BLEN(&b
));
500 G_DESTROY(g
, r
); G_DESTROY(g
, c
);
502 assert(mparena_count(MPARENA_GLOBAL
) == 0);
506 static const test_chunk tests
[] = {
507 { "check", vcheck
, { &type_string
, &type_string
} },
508 { "checkelt", vcheckelt
, { &type_string
, &type_string
, &type_int
} },
509 { "mul", vmul
, { &type_string
, &type_string
,
510 &type_string
, &type_string
} },
511 { "sqr", vsqr
, { &type_string
, &type_string
,
513 { "inv", vinv
, { &type_string
, &type_string
,
515 { "div", vdiv
, { &type_string
, &type_string
,
516 &type_string
, &type_string
} },
517 { "exp", vexp
, { &type_string
, &type_string
,
518 &type_mp
, &type_string
} },
519 { "mexp-1", vmexp1
, { &type_string
,
520 &type_string
, &type_mp
,
522 { "mexp-2", vmexp2
, { &type_string
,
523 &type_string
, &type_mp
,
524 &type_string
, &type_mp
,
526 { "mexp-3", vmexp3
, { &type_string
,
527 &type_string
, &type_mp
,
528 &type_string
, &type_mp
,
529 &type_string
, &type_mp
,
531 { "mexp-4", vmexp4
, { &type_string
,
532 &type_string
, &type_mp
,
533 &type_string
, &type_mp
,
534 &type_string
, &type_mp
,
535 &type_string
, &type_mp
,
537 { "toint", vtoint
, { &type_string
, &type_string
,
538 &type_int
, &type_mp
} },
539 { "fromint", vfromint
, { &type_string
, &type_mp
,
540 &type_int
, &type_string
} },
541 { "toec", vtoec
, { &type_string
, &type_string
,
542 &type_int
, &type_ec
} },
543 { "fromec", vfromec
, { &type_string
, &type_ec
,
544 &type_int
, &type_string
} },
545 { "tobuf", vtobuf
, { &type_string
, &type_string
,
546 &type_int
, &type_hex
} },
547 { "frombuf", vfrombuf
, { &type_string
, &type_hex
,
548 &type_int
, &type_string
} },
549 { "toraw", vtoraw
, { &type_string
, &type_string
,
550 &type_int
, &type_hex
} },
551 { "fromraw", vfromraw
, { &type_string
, &type_hex
,
552 &type_int
, &type_string
} },
556 int main(int argc
, char *argv
[])
559 test_run(argc
, argv
, tests
, SRCDIR
"/tests/group");
563 /*----- That's all, folks -------------------------------------------------*/