3 Purpose: Keeper of the hordes of testing code.
4 Author: M. J. Fromberger
6 Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37 /* Globals visible from outside this file */
38 mp_result imath_errno
;
41 /* Set imath_errno and return failure from a test. */
42 #define FAIL(E) return (imath_errno = (E), false)
44 /* Check that an expression X yields the expected mp_result value V. */
45 #define VCHECK(X, V) \
48 if ((res_ = (X)) != (V)) { \
52 #define CHECK(X) VCHECK(X, MP_OK)
53 #define ECHECK(X) VCHECK(X, expect)
61 #define OUTPUT_LIMIT 2048
63 #define OTHER_ERROR -1024
65 static char g_output
[OUTPUT_LIMIT
];
66 static mpz_t g_zreg
[NUM_REGS
];
67 static mpq_t g_qreg
[NUM_REGS
];
68 static unsigned char g_bin1
[OUTPUT_LIMIT
];
69 static unsigned char g_bin2
[OUTPUT_LIMIT
];
71 extern void trim_line(char* line
); /* borrowed from imtest.c */
73 /* Read in a string with radix tags */
74 static mp_result
read_int_value(mp_int z
, char* str
);
75 static mp_result
read_rat_value(mp_rat q
, char* str
);
77 /* Read in a string with radix tags, as a long (not an mp_int) */
78 static bool read_long(long* z
, char* str
);
80 /* Parse the input and output values and fill in pointers to the
81 registers containing them. Returns true if all is well, false
82 in case of error. Caller allocates in/out to correct sizes. */
83 static bool parse_int_values(testspec_t
* t
, mp_int
* in
, mp_int
* out
,
85 static bool parse_rat_values(testspec_t
* t
, mp_rat
* in
, mp_rat
* out
,
88 /* Parse a result code name and return the corresponding result code */
89 static bool parse_result_code(char* str
, mp_result
* code
);
91 /* Read in a dot-delimited binary sequence to the given buffer, and return the
92 number of bytes read. Returns < 0 in case of a syntax error. Records no
93 more than limit bytes. */
94 static int parse_binary(char* str
, unsigned char* buf
, int limit
);
96 /* Clean up registers (called from atexit()) */
97 static void done_testing(void);
100 * Utility subroutines for writing tests (explained above)
103 static mp_result
read_int_value(mp_int z
, char* str
) {
131 return mp_int_read_string(z
, radix
, str
);
134 static mp_result
read_rat_value(mp_rat q
, char* str
) {
163 return mp_rat_read_decimal(q
, radix
, str
+ 1);
165 return mp_rat_read_string(q
, radix
, str
);
168 static bool read_long(long* z
, char* str
) {
197 *z
= strtol(str
, &end
, radix
);
198 return (end
!= str
&& *end
== '\0');
201 static bool parse_int_values(testspec_t
* t
, mp_int
* in
, mp_int
* out
,
206 if (rval
!= NULL
) *rval
= MP_OK
; /* default */
209 for (int i
= 0; i
< t
->num_inputs
; ++i
) {
215 int k
= abs(atoi(str
+ 1)) - 1;
217 if (k
< 0 || k
>= i
) {
218 fprintf(stderr
, "Line %d: Invalid input back-reference [%s]\n",
225 mp_int reg
= g_zreg
+ pos
++; /* grab next free register */
227 if (read_int_value(reg
, str
) != MP_OK
) {
228 fprintf(stderr
, "Line %d: Invalid input value [%s]\n", t
->line
, str
);
237 for (int i
= 0; i
< t
->num_outputs
; ++i
) {
238 mp_int reg
= g_zreg
+ pos
++;
244 if (strcmp(str
, "?") == 0)
246 else if (*str
== '$') {
249 if (!parse_result_code(str
, &code
)) {
250 fprintf(stderr
, "Line %d: Invalid result code [%s]\n", t
->line
, str
);
252 } else if (rval
== NULL
) {
253 fprintf(stderr
, "Line %d: Result code not permitted here [%s]\n",
259 /* Provide a dummy value for the corresponding output */
261 } else if (out
!= NULL
&& read_int_value(reg
, str
) != MP_OK
) {
262 fprintf(stderr
, "Line %d: Invalid output value [%s]\n", t
->line
, str
);
266 if (out
!= NULL
) out
[i
] = reg
;
272 static bool parse_rat_values(testspec_t
* t
, mp_rat
* in
, mp_rat
* out
,
277 if (rval
!= NULL
) *rval
= MP_OK
; /* default */
280 for (int i
= 0; i
< t
->num_inputs
; ++i
) {
286 int k
= abs(atoi(str
+ 1)) - 1;
288 if (k
< 0 || k
>= i
) {
289 fprintf(stderr
, "Line %d: Invalid input back-reference [%s]\n",
296 mp_rat reg
= g_qreg
+ pos
++; /* grab next free register */
298 if (read_rat_value(reg
, str
) != MP_OK
) {
299 fprintf(stderr
, "Line %d: Invalid input value [%s]\n", t
->line
, str
);
308 for (int i
= 0; i
< t
->num_outputs
; ++i
) {
309 mp_rat reg
= g_qreg
+ pos
++;
315 if (strcmp(str
, "?") == 0)
317 else if (*str
== '$') {
320 if (!parse_result_code(str
, &code
)) {
321 fprintf(stderr
, "Line %d: Invalid result code [%s]\n", t
->line
, str
);
323 } else if (rval
== NULL
) {
324 fprintf(stderr
, "Line %d: Result code not permitted here [%s]\n",
330 /* Provide a dummy value for the corresponding output */
332 } else if (out
!= NULL
&& read_rat_value(reg
, str
) != MP_OK
) {
333 fprintf(stderr
, "Line %d: Invalid output value [%s]\n", t
->line
, str
);
337 if (out
!= NULL
) out
[i
] = reg
;
343 static bool parse_result_code(char* str
, mp_result
* code
) {
348 if (!read_long(&v
, str
+ 2)) return false;
350 *code
= (mp_result
)v
;
351 } else if (strcmp(str
+ 1, "MP_OK") == 0 ||
352 strcmp(str
+ 1, "MP_FALSE") == 0) {
354 } else if (strcmp(str
+ 1, "MP_TRUE") == 0) {
356 } else if (strcmp(str
+ 1, "MP_MEMORY") == 0) {
358 } else if (strcmp(str
+ 1, "MP_RANGE") == 0) {
360 } else if (strcmp(str
+ 1, "MP_UNDEF") == 0) {
362 } else if (strcmp(str
+ 1, "MP_TRUNC") == 0) {
364 } else if (strcmp(str
+ 1, "MP_ROUND_UP") == 0) {
366 } else if (strcmp(str
+ 1, "MP_ROUND_DOWN") == 0) {
367 *code
= MP_ROUND_DOWN
;
368 } else if (strcmp(str
+ 1, "MP_ROUND_HALF_UP") == 0) {
369 *code
= MP_ROUND_HALF_UP
;
370 } else if (strcmp(str
+ 1, "MP_ROUND_HALF_DOWN") == 0) {
371 *code
= MP_ROUND_HALF_DOWN
;
380 static int parse_binary(char* str
, unsigned char* buf
, int limit
) {
386 for (tok
= strtok(str
, "."); tok
!= NULL
&& pos
< limit
;
387 tok
= strtok(NULL
, ".")) {
390 if (!read_long(&v
, tok
) || v
> UCHAR_MAX
|| v
< 0) return -1;
392 buf
[pos
++] = (unsigned char)v
;
398 static void done_testing(void) {
401 for (i
= 0; i
< NUM_REGS
; ++i
) {
402 mp_int_clear(g_zreg
+ i
);
403 mp_rat_clear(g_qreg
+ i
);
408 * Global functions visible to callers outside this file.
411 void init_testing(void) {
412 static int is_done
= 0;
416 for (int i
= 0; i
< NUM_REGS
; ++i
) {
417 assert(mp_int_init(g_zreg
+ i
) == MP_OK
);
418 assert(mp_rat_init(g_qreg
+ i
) == MP_OK
);
421 imath_errmsg
= g_output
;
423 assert(atexit(done_testing
) == 0);
427 void reset_registers(void) {
428 for (int i
= 0; i
< NUM_REGS
; ++i
) {
429 mp_int_zero(g_zreg
+ i
);
430 mp_rat_zero(g_qreg
+ i
);
434 bool test_init(testspec_t
* t
, FILE* ofp
) {
435 mp_int in
[2], out
[1];
440 ACHECK(parse_int_values(t
, in
, out
, &expect
));
442 if (strcmp(t
->code
, "initu") == 0) {
443 CHECK(mp_int_to_uint(in
[1], &uv
));
444 ECHECK(mp_int_init_uvalue(in
[0], uv
));
446 CHECK(mp_int_to_int(in
[1], &v
));
447 ECHECK(mp_int_init_value(in
[0], v
));
450 if (expect
== MP_OK
&& mp_int_compare(in
[0], out
[0]) != 0) {
451 mp_int_to_string(in
[0], 10, g_output
, OUTPUT_LIMIT
);
458 bool test_set(testspec_t
* t
, FILE* ofp
) {
459 mp_int in
[2], out
[1];
464 ACHECK(parse_int_values(t
, in
, out
, &expect
));
466 if (strcmp(t
->code
, "setu") == 0) {
467 CHECK(mp_int_to_uint(in
[1], &uv
));
468 ECHECK(mp_int_set_uvalue(in
[0], uv
));
470 CHECK(mp_int_to_int(in
[1], &v
));
471 ECHECK(mp_int_set_value(in
[0], v
));
474 if (expect
== MP_OK
&& mp_int_compare(in
[0], out
[0]) != 0) {
475 mp_int_to_string(in
[0], 10, g_output
, OUTPUT_LIMIT
);
482 bool test_neg(testspec_t
* t
, FILE* ofp
) {
483 mp_int in
[2], out
[1];
486 ACHECK(parse_int_values(t
, in
, out
, &expect
));
487 ECHECK(mp_int_neg(in
[0], in
[1]));
489 if (expect
== MP_OK
&& mp_int_compare(in
[1], out
[0]) != 0) {
490 mp_int_to_string(in
[1], 10, g_output
, OUTPUT_LIMIT
);
497 bool test_abs(testspec_t
* t
, FILE* ofp
) {
498 mp_int in
[2], out
[1];
501 ACHECK(parse_int_values(t
, in
, out
, &expect
));
502 ECHECK(mp_int_abs(in
[0], in
[1]));
504 if (expect
== MP_OK
&& mp_int_compare(in
[1], out
[0]) != 0) {
505 mp_int_to_string(in
[1], 10, g_output
, OUTPUT_LIMIT
);
512 bool test_add(testspec_t
* t
, FILE* ofp
) {
513 mp_int in
[3], out
[1];
517 ACHECK(parse_int_values(t
, in
, out
, &expect
));
519 if (strcmp(t
->code
, "addv") == 0) {
520 CHECK(mp_int_to_int(in
[1], &v
));
521 ECHECK(mp_int_add_value(in
[0], v
, in
[2]));
523 ECHECK(mp_int_add(in
[0], in
[1], in
[2]));
526 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
527 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
534 bool test_sub(testspec_t
* t
, FILE* ofp
) {
535 mp_int in
[3], out
[1];
539 ACHECK(parse_int_values(t
, in
, out
, &expect
));
541 if (strcmp(t
->code
, "subv") == 0) {
542 CHECK(mp_int_to_int(in
[1], &v
));
543 ECHECK(mp_int_sub_value(in
[0], v
, in
[2]));
545 ECHECK(mp_int_sub(in
[0], in
[1], in
[2]));
548 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
549 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
555 bool test_mul(testspec_t
* t
, FILE* ofp
) {
556 mp_int in
[3], out
[1];
559 ACHECK(parse_int_values(t
, in
, out
, &expect
));
560 ECHECK(mp_int_mul(in
[0], in
[1], in
[2]));
562 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
563 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
569 bool test_mulp2(testspec_t
* t
, FILE* ofp
) {
570 mp_int in
[3], out
[1];
574 ACHECK(parse_int_values(t
, in
, out
, &expect
));
575 CHECK(mp_int_to_int(in
[1], &p2
));
576 ECHECK(mp_int_mul_pow2(in
[0], p2
, in
[2]));
578 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
579 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
585 bool test_mulv(testspec_t
* t
, FILE* ofp
) {
586 mp_int in
[3], out
[1];
590 ACHECK(parse_int_values(t
, in
, out
, &expect
));
591 CHECK(mp_int_to_int(in
[1], &v
));
592 ECHECK(mp_int_mul_value(in
[0], v
, in
[2]));
594 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
595 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
601 bool test_sqr(testspec_t
* t
, FILE* ofp
) {
602 mp_int in
[2], out
[1];
605 ACHECK(parse_int_values(t
, in
, out
, &expect
));
606 ECHECK(mp_int_sqr(in
[0], in
[1]));
608 if (expect
== MP_OK
&& mp_int_compare(in
[1], out
[0]) != 0) {
609 mp_int_to_string(in
[1], 10, g_output
, OUTPUT_LIMIT
);
615 bool test_div(testspec_t
* t
, FILE* ofp
) {
616 mp_int in
[4], out
[2];
619 ACHECK(parse_int_values(t
, in
, out
, &expect
));
620 ECHECK(mp_int_div(in
[0], in
[1], in
[2], in
[3]));
622 if (expect
== MP_OK
&& ((mp_int_compare(in
[2], out
[0]) != 0) ||
623 (mp_int_compare(in
[3], out
[1]) != 0))) {
627 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
628 str
= g_output
+ (len
= strlen(g_output
));
630 mp_int_to_string(in
[3], 10, str
, OUTPUT_LIMIT
- (len
+ 1));
636 bool test_divp2(testspec_t
* t
, FILE* ofp
) {
637 mp_int in
[4], out
[2];
641 ACHECK(parse_int_values(t
, in
, out
, &expect
));
642 CHECK(mp_int_to_int(in
[1], &p2
));
643 ECHECK(mp_int_div_pow2(in
[0], p2
, in
[2], in
[3]));
645 if (expect
== MP_OK
&& ((mp_int_compare(in
[2], out
[0]) != 0) ||
646 (mp_int_compare(in
[3], out
[1]) != 0))) {
650 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
651 str
= g_output
+ (len
= strlen(g_output
));
653 mp_int_to_string(in
[3], 10, str
, OUTPUT_LIMIT
- (len
+ 1));
659 bool test_divv(testspec_t
* t
, FILE* ofp
) {
660 mp_int in
[3], out
[2];
662 mp_small v
, rem
, orem
;
664 ACHECK(parse_int_values(t
, in
, out
, &expect
));
665 CHECK(mp_int_to_int(in
[1], &v
));
666 CHECK(mp_int_to_int(out
[1], &orem
));
667 ECHECK(mp_int_div_value(in
[0], v
, in
[2], &rem
));
669 if (expect
== MP_OK
&&
670 ((mp_int_compare(in
[2], out
[0]) != 0) || (rem
!= orem
))) {
673 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
674 str
= g_output
+ strlen(g_output
);
676 sprintf(str
, "%ld", rem
);
682 bool test_expt(testspec_t
* t
, FILE* ofp
) {
683 mp_int in
[3], out
[1];
687 ACHECK(parse_int_values(t
, in
, out
, &expect
));
688 CHECK(mp_int_to_int(in
[1], &pow
));
689 ECHECK(mp_int_expt(in
[0], pow
, in
[2]));
691 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
692 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
698 bool test_exptv(testspec_t
* t
, FILE* ofp
) {
699 mp_int in
[3], out
[1];
703 ACHECK(parse_int_values(t
, in
, out
, &expect
));
704 CHECK(mp_int_to_int(in
[0], &a
));
705 CHECK(mp_int_to_int(in
[1], &b
));
706 ECHECK(mp_int_expt_value(a
, b
, in
[2]));
708 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
709 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
715 bool test_exptf(testspec_t
* t
, FILE* ofp
) {
716 mp_int in
[3], out
[1];
719 ACHECK(parse_int_values(t
, in
, out
, &expect
));
720 ECHECK(mp_int_expt_full(in
[0], in
[1], in
[2]));
722 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
723 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
729 bool test_mod(testspec_t
* t
, FILE* ofp
) {
730 mp_int in
[3], out
[1];
733 ACHECK(parse_int_values(t
, in
, out
, &expect
));
734 ECHECK(mp_int_mod(in
[0], in
[1], in
[2]));
736 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
737 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
743 bool test_gcd(testspec_t
* t
, FILE* ofp
) {
744 mp_int in
[3], out
[1];
747 ACHECK(parse_int_values(t
, in
, out
, &expect
));
748 ECHECK(mp_int_gcd(in
[0], in
[1], in
[2]));
750 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
751 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
757 bool test_egcd(testspec_t
* t
, FILE* ofp
) {
758 mp_int in
[5], out
[3], t1
= g_zreg
+ 8, t2
= g_zreg
+ 9;
761 ACHECK(parse_int_values(t
, in
, out
, &expect
));
762 ECHECK(mp_int_egcd(in
[0], in
[1], in
[2], in
[3], in
[4]));
764 /* If we got an error we expected, return success immediately */
765 if (expect
!= MP_OK
) return true;
767 if ((mp_int_compare(in
[2], out
[0]) != 0) ||
768 (mp_int_compare(in
[3], out
[1]) != 0) ||
769 (mp_int_compare(in
[4], out
[2]) != 0)) {
773 /* Failure might occur because the tester computed x and y in a different
774 way than we did. Verify that the results are correct before reporting
776 mp_int_mul(in
[3], in
[0], t1
);
777 mp_int_mul(in
[4], in
[1], t2
);
778 mp_int_add(t1
, t2
, t2
);
779 if (mp_int_compare(t2
, in
[2]) == 0) return true;
781 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
782 str
= g_output
+ (len
= strlen(g_output
));
784 mp_int_to_string(in
[3], 10, str
, OUTPUT_LIMIT
- (len
+ 1));
785 str
= str
+ (len2
= strlen(str
));
787 mp_int_to_string(in
[4], 10, str
, OUTPUT_LIMIT
- (len
+ len2
+ 2));
793 bool test_lcm(testspec_t
* t
, FILE* ofp
) {
794 mp_int in
[3], out
[1];
797 ACHECK(parse_int_values(t
, in
, out
, &expect
));
798 ECHECK(mp_int_lcm(in
[0], in
[1], in
[2]));
800 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
801 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
807 bool test_sqrt(testspec_t
* t
, FILE* ofp
) {
808 mp_int in
[2], out
[1];
811 ACHECK(parse_int_values(t
, in
, out
, &expect
));
812 ECHECK(mp_int_sqrt(in
[0], in
[1]));
814 if (expect
== MP_OK
&& mp_int_compare(in
[1], out
[0]) != 0) {
815 mp_int_to_string(in
[1], 10, g_output
, OUTPUT_LIMIT
);
821 bool test_root(testspec_t
* t
, FILE* ofp
) {
822 mp_int in
[3], out
[1];
826 ACHECK(parse_int_values(t
, in
, out
, &expect
));
827 CHECK(mp_int_to_int(in
[1], &v
));
828 ECHECK(mp_int_root(in
[0], v
, in
[2]));
830 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
831 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
837 bool test_invmod(testspec_t
* t
, FILE* ofp
) {
838 mp_int in
[3], out
[1];
841 ACHECK(parse_int_values(t
, in
, out
, &expect
));
842 ECHECK(mp_int_invmod(in
[0], in
[1], in
[2]));
844 if (expect
== MP_OK
&& mp_int_compare(in
[2], out
[0]) != 0) {
845 mp_int_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
851 bool test_exptmod(testspec_t
* t
, FILE* ofp
) {
852 mp_int in
[4], out
[1];
855 ACHECK(parse_int_values(t
, in
, out
, &expect
));
856 ECHECK(mp_int_exptmod(in
[0], in
[1], in
[2], in
[3]));
858 if (expect
== MP_OK
&& mp_int_compare(in
[3], out
[0]) != 0) {
859 mp_int_to_string(in
[3], 10, g_output
, OUTPUT_LIMIT
);
865 bool test_exptmod_ev(testspec_t
* t
, FILE* ofp
) {
866 mp_int in
[4], out
[1];
870 ACHECK(parse_int_values(t
, in
, out
, &expect
));
871 CHECK(mp_int_to_int(in
[1], &v
));
872 ECHECK(mp_int_exptmod_evalue(in
[0], v
, in
[2], in
[3]));
874 if (expect
== MP_OK
&& mp_int_compare(in
[3], out
[0]) != 0) {
875 mp_int_to_string(in
[3], 10, g_output
, OUTPUT_LIMIT
);
881 bool test_exptmod_bv(testspec_t
* t
, FILE* ofp
) {
882 mp_int in
[4], out
[1];
886 ACHECK(parse_int_values(t
, in
, out
, &expect
));
887 CHECK(mp_int_to_int(in
[0], &v
));
888 ECHECK(mp_int_exptmod_bvalue(v
, in
[1], in
[2], in
[3]));
890 if (expect
== MP_OK
&& mp_int_compare(in
[3], out
[0]) != 0) {
891 mp_int_to_string(in
[3], 10, g_output
, OUTPUT_LIMIT
);
897 bool test_comp(testspec_t
* t
, FILE* ofp
) {
899 mp_result res
, expect
;
901 ACHECK(parse_int_values(t
, in
, NULL
, &expect
));
903 if ((res
= mp_int_compare(in
[0], in
[1])) != expect
) {
904 sprintf(g_output
, "Incorrect comparison result (want %d, got %d)", expect
,
911 bool test_ucomp(testspec_t
* t
, FILE* ofp
) {
913 mp_result res
, expect
;
915 ACHECK(parse_int_values(t
, in
, NULL
, &expect
));
917 if ((res
= mp_int_compare_unsigned(in
[0], in
[1])) != expect
) {
918 sprintf(g_output
, "Incorrect comparison result (want %d, got %d)", expect
,
925 bool test_zcomp(testspec_t
* t
, FILE* ofp
) {
927 mp_result res
, expect
;
929 ACHECK(parse_int_values(t
, in
, NULL
, &expect
));
931 if ((res
= mp_int_compare_zero(in
[0])) != expect
) {
932 sprintf(g_output
, "Incorrect comparison result (want %d, got %d)", expect
,
939 bool test_vcomp(testspec_t
* t
, FILE* ofp
) {
941 mp_result res
, expect
;
944 ACHECK(parse_int_values(t
, in
, NULL
, &expect
));
946 v
= atoi(t
->input
[1]);
947 if ((res
= mp_int_compare_value(in
[0], v
)) != expect
) {
948 sprintf(g_output
, "Incorrect comparison result (want %d, got %d)", expect
,
955 bool test_uvcomp(testspec_t
* t
, FILE* ofp
) {
957 mp_result res
, expect
;
960 ACHECK(parse_int_values(t
, in
, NULL
, &expect
));
962 v
= strtoul(t
->input
[1], NULL
, 0);
963 if ((res
= mp_int_compare_uvalue(in
[0], v
)) != expect
) {
964 sprintf(g_output
, "Incorrect comparison result (want %d, got %d)", expect
,
971 bool test_tostr(testspec_t
* t
, FILE* ofp
) {
976 ACHECK(parse_int_values(t
, in
, NULL
, NULL
));
977 ACHECK(mp_int_to_int(in
[1], &radix
) == MP_OK
);
979 if (radix
< MP_MIN_RADIX
|| radix
> MP_MAX_RADIX
) FAIL(MP_RANGE
);
981 trim_line(t
->output
[0]);
982 len
= mp_int_string_len(in
[0], radix
);
984 CHECK(mp_int_to_string(in
[0], radix
, g_output
, len
));
986 if (strcmp(t
->output
[0], g_output
) != 0) FAIL(OTHER_ERROR
);
991 bool test_tobin(testspec_t
* t
, FILE* ofp
) {
993 int test_len
, out_len
;
995 ACHECK(parse_int_values(t
, in
, NULL
, NULL
));
997 trim_line(t
->output
[0]);
998 if ((out_len
= parse_binary(t
->output
[0], g_bin1
, sizeof(g_bin1
))) < 0)
1001 if ((test_len
= mp_int_binary_len(in
[0])) != out_len
) {
1002 sprintf(g_output
, "Output lengths do not match (want %d, got %d)", test_len
,
1007 CHECK(mp_int_to_binary(in
[0], g_bin2
, sizeof(g_bin2
)));
1009 if (memcmp(g_bin1
, g_bin2
, test_len
) != 0) {
1012 for (i
= 0; i
< test_len
- 1; ++i
)
1013 pos
+= sprintf(g_output
+ pos
, "%d.", g_bin2
[i
]);
1015 sprintf(g_output
+ pos
, "%d", g_bin2
[i
]);
1021 bool test_to_int(testspec_t
* t
, FILE* ofp
) {
1022 mp_int in
[1], out
[1];
1026 ACHECK(parse_int_values(t
, in
, out
, &expect
));
1027 ECHECK(mp_int_to_int(in
[0], &v
));
1029 if (expect
== MP_OK
&& mp_int_compare_value(out
[0], v
) != 0) {
1030 sprintf(g_output
, "Incorrect value (got %ld)", v
);
1036 bool test_to_uint(testspec_t
* t
, FILE* ofp
) {
1037 mp_int in
[1], out
[1];
1041 ACHECK(parse_int_values(t
, in
, out
, &expect
));
1042 ECHECK(mp_int_to_uint(in
[0], &v
));
1044 if (expect
== MP_OK
&& mp_int_compare_uvalue(out
[0], v
) != 0) {
1045 sprintf(g_output
, "Incorrect value (got %lu)", v
);
1051 bool test_read_binary(testspec_t
* t
, FILE* ofp
) {
1052 mp_int out
[1], in
= g_zreg
+ 1;
1056 ACHECK(parse_int_values(t
, NULL
, out
, &expect
));
1058 trim_line(t
->input
[0]);
1059 if ((in_len
= parse_binary(t
->input
[0], g_bin1
, sizeof(g_bin1
))) < 0)
1062 ECHECK(mp_int_read_binary(in
, g_bin1
, in_len
));
1064 if (expect
== MP_OK
&& mp_int_compare(in
, out
[0]) != 0) {
1065 mp_int_to_string(in
, 10, g_output
, OUTPUT_LIMIT
);
1071 bool test_to_uns(testspec_t
* t
, FILE* ofp
) {
1073 int test_len
, out_len
;
1075 ACHECK(parse_int_values(t
, in
, NULL
, NULL
));
1077 trim_line(t
->output
[0]);
1078 if ((out_len
= parse_binary(t
->output
[0], g_bin1
, sizeof(g_bin1
))) < 0)
1081 if ((test_len
= mp_int_unsigned_len(in
[0])) != out_len
) {
1082 sprintf(g_output
, "Output lengths do not match (want %d, got %d)", test_len
,
1087 CHECK(mp_int_to_unsigned(in
[0], g_bin2
, sizeof(g_bin2
)));
1089 if (memcmp(g_bin1
, g_bin2
, test_len
) != 0) {
1092 for (i
= 0; i
< test_len
- 1; ++i
)
1093 pos
+= sprintf(g_output
+ pos
, "%d.", g_bin2
[i
]);
1095 sprintf(g_output
+ pos
, "%d", g_bin2
[i
]);
1101 bool test_read_uns(testspec_t
* t
, FILE* ofp
) {
1102 mp_int out
[1], in
= g_zreg
+ 1;
1106 ACHECK(parse_int_values(t
, NULL
, out
, &expect
));
1108 trim_line(t
->input
[0]);
1109 if ((in_len
= parse_binary(t
->input
[0], g_bin1
, sizeof(g_bin1
))) < 0)
1112 ECHECK(mp_int_read_unsigned(in
, g_bin1
, in_len
));
1114 if (expect
== MP_OK
&& mp_int_compare(in
, out
[0]) != 0) {
1115 mp_int_to_string(in
, 10, g_output
, OUTPUT_LIMIT
);
1121 bool test_meta(testspec_t
* t
, FILE* ofp
) {
1122 mp_int
*in
= NULL
, *out
= NULL
;
1126 if (t
->num_inputs
> 0) {
1127 in
= calloc(t
->num_inputs
, sizeof(mp_int
));
1129 if (t
->num_outputs
> 0) {
1130 out
= calloc(t
->num_outputs
, sizeof(mp_int
));
1133 if (!parse_int_values(t
, in
, out
, &expect
)) {
1134 if (in
!= NULL
) free(in
);
1135 if (out
!= NULL
) free(out
);
1139 fprintf(ofp
, "Test '%s' defined at line %d\n", t
->code
, t
->line
);
1140 fprintf(ofp
, "Expected result: %d\n", expect
);
1141 fprintf(ofp
, "Input values: %d\n", t
->num_inputs
);
1142 for (i
= 0; i
< t
->num_inputs
; ++i
) {
1143 mp_int_to_string(in
[i
], 10, g_output
, OUTPUT_LIMIT
);
1145 fprintf(ofp
, " %2d.) %s", i
+ 1, g_output
);
1147 for (j
= i
- 1; j
>= 0; --j
)
1148 if (in
[j
] == in
[i
]) {
1149 fprintf(ofp
, " (=> %d)", j
+ 1);
1155 fprintf(ofp
, "Output values: %d\n", t
->num_outputs
);
1156 for (i
= 0; i
< t
->num_outputs
; ++i
) {
1157 mp_int_to_string(out
[i
], 10, g_output
, OUTPUT_LIMIT
);
1159 fprintf(ofp
, " %2d.) %s\n", i
+ 1, g_output
);
1161 if (in
!= NULL
) free(in
);
1162 if (out
!= NULL
) free(out
);
1166 bool test_qneg(testspec_t
* t
, FILE* ofp
) {
1167 mp_rat in
[2], out
[1];
1170 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1171 ECHECK(mp_rat_neg(in
[0], in
[1]));
1173 if (expect
== MP_OK
&& mp_rat_compare(in
[1], out
[0]) != 0) {
1174 mp_rat_to_string(in
[1], 10, g_output
, OUTPUT_LIMIT
);
1180 bool test_qrecip(testspec_t
* t
, FILE* ofp
) {
1181 mp_rat in
[2], out
[1];
1184 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1185 ECHECK(mp_rat_recip(in
[0], in
[1]));
1187 if (expect
== MP_OK
&& mp_rat_compare(in
[1], out
[0]) != 0) {
1188 mp_rat_to_string(in
[1], 10, g_output
, OUTPUT_LIMIT
);
1194 bool test_qabs(testspec_t
* t
, FILE* ofp
) {
1195 mp_rat in
[2], out
[1];
1198 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1199 ECHECK(mp_rat_abs(in
[0], in
[1]));
1201 if (expect
== MP_OK
&& mp_rat_compare(in
[1], out
[0]) != 0) {
1202 mp_rat_to_string(in
[1], 10, g_output
, OUTPUT_LIMIT
);
1208 bool test_qadd(testspec_t
* t
, FILE* ofp
) {
1209 mp_rat in
[3], out
[1];
1212 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1213 ECHECK(mp_rat_add(in
[0], in
[1], in
[2]));
1215 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1216 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1222 bool test_qsub(testspec_t
* t
, FILE* ofp
) {
1223 mp_rat in
[3], out
[1];
1226 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1227 ECHECK(mp_rat_sub(in
[0], in
[1], in
[2]));
1229 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1230 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1236 bool test_qmul(testspec_t
* t
, FILE* ofp
) {
1237 mp_rat in
[3], out
[1];
1240 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1241 ECHECK(mp_rat_mul(in
[0], in
[1], in
[2]));
1243 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1244 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1250 bool test_qdiv(testspec_t
* t
, FILE* ofp
) {
1251 mp_rat in
[3], out
[1];
1254 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1255 ECHECK(mp_rat_div(in
[0], in
[1], in
[2]));
1257 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1258 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1264 bool test_qaddz(testspec_t
* t
, FILE* ofp
) {
1265 mp_rat in
[3], out
[1];
1268 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1270 if (!mp_rat_is_integer(in
[1])) {
1272 "Line %d: Second argument must be an integer (test_qaddz)\n",
1277 ECHECK(mp_rat_add_int(in
[0], MP_NUMER_P(in
[1]), in
[2]));
1279 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1280 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1286 bool test_qsubz(testspec_t
* t
, FILE* ofp
) {
1287 mp_rat in
[3], out
[1];
1290 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1292 if (!mp_rat_is_integer(in
[1])) {
1294 "Line %d: Second argument must be an integer (test_qsubz)\n",
1299 ECHECK(mp_rat_sub_int(in
[0], MP_NUMER_P(in
[1]), in
[2]));
1301 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1302 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1308 bool test_qmulz(testspec_t
* t
, FILE* ofp
) {
1309 mp_rat in
[3], out
[1];
1312 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1314 if (!mp_rat_is_integer(in
[1])) {
1316 "Line %d: Second argument must be an integer (test_qmulz)\n",
1321 ECHECK(mp_rat_mul_int(in
[0], MP_NUMER_P(in
[1]), in
[2]));
1323 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1324 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1330 bool test_qdivz(testspec_t
* t
, FILE* ofp
) {
1331 mp_rat in
[3], out
[1];
1334 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1336 if (!mp_rat_is_integer(in
[1])) {
1338 "Line %d: Second argument must be an integer (test_qdivz)\n",
1343 ECHECK(mp_rat_div_int(in
[0], MP_NUMER_P(in
[1]), in
[2]));
1345 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1346 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1352 bool test_qexpt(testspec_t
* t
, FILE* ofp
) {
1353 mp_rat in
[3], out
[1];
1357 ACHECK(parse_rat_values(t
, in
, out
, &expect
));
1359 if (!mp_rat_is_integer(in
[1])) {
1361 "Line %d: Second argument must be an integer (test_qexpt)\n",
1366 CHECK(mp_int_to_int(MP_NUMER_P(in
[1]), &power
));
1367 ECHECK(mp_rat_expt(in
[0], power
, in
[2]));
1369 if (expect
== MP_OK
&& mp_rat_compare(in
[2], out
[0]) != 0) {
1370 mp_rat_to_string(in
[2], 10, g_output
, OUTPUT_LIMIT
);
1376 bool test_qtostr(testspec_t
* t
, FILE* ofp
) {
1381 ACHECK(parse_rat_values(t
, in
, NULL
, NULL
));
1382 trim_line(t
->input
[1]);
1383 ACHECK(read_long(&radix
, t
->input
[1]));
1385 if (radix
< MP_MIN_RADIX
|| radix
> MP_MAX_RADIX
) {
1386 fprintf(stderr
, "Line %d: Radix %ld out of range\n", t
->line
, radix
);
1390 trim_line(t
->output
[0]);
1391 len
= mp_rat_string_len(in
[0], radix
);
1393 CHECK(mp_rat_to_string(in
[0], radix
, g_output
, len
));
1395 if (strcmp(t
->output
[0], g_output
) != 0) FAIL(OTHER_ERROR
);
1400 bool test_qtodec(testspec_t
* t
, FILE* ofp
) {
1402 long radix
, prec
, m
;
1403 mp_round_mode rmode
;
1404 mp_result res
, expect
= MP_OK
, len
;
1406 ACHECK(parse_rat_values(t
, in
, NULL
, NULL
));
1408 if (t
->output
[0][0] == '$' && !parse_result_code(t
->output
[0], &expect
)) {
1409 fprintf(stderr
, "Line %d: Invalid result code [%s]\n", t
->line
,
1414 trim_line(t
->input
[1]);
1415 trim_line(t
->input
[2]);
1416 trim_line(t
->input
[3]);
1417 ACHECK(read_long(&radix
, t
->input
[1]));
1418 ACHECK(read_long(&prec
, t
->input
[2]));
1419 ACHECK(read_long(&m
, t
->input
[3]));
1420 rmode
= (mp_round_mode
)m
;
1423 fprintf(stderr
, "Line %d: Precision %ld out of range\n", t
->line
, prec
);
1427 trim_line(t
->output
[0]);
1428 len
= mp_rat_decimal_len(in
[0], radix
, prec
);
1429 ECHECK((res
= mp_rat_to_decimal(in
[0], radix
, prec
, rmode
, g_output
, len
)));
1431 if (res
== MP_OK
&& strcmp(t
->output
[0], g_output
) != 0) FAIL(OTHER_ERROR
);
1436 bool test_qrdec(testspec_t
* t
, FILE* ofp
) {
1437 mp_rat out
[1] = {NULL
}, reg
= g_qreg
+ 1;
1441 ACHECK(parse_rat_values(t
, NULL
, out
, &expect
));
1442 trim_line(t
->input
[1]);
1443 ACHECK(read_long(&radix
, t
->input
[1]));
1445 ECHECK(mp_rat_read_decimal(reg
, radix
, t
->input
[0]));
1446 if (expect
== MP_OK
&& mp_rat_compare(reg
, out
[0]) != 0) {
1447 mp_rat_to_string(reg
, 10, g_output
, OUTPUT_LIMIT
);
1453 bool test_is_prime(testspec_t
* t
, FILE* OFP
) {
1454 mp_int in
[1] = {NULL
};
1457 ACHECK(parse_int_values(t
, in
, NULL
, &expect
));
1458 ECHECK(mp_int_is_prime(in
[0]));
1462 /* Here there be dragons */