brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.8 KiB · 40860d6 Raw
1463 lines · c
1/*2  Name:     imdrover.c3  Purpose:  Keeper of the hordes of testing code.4  Author:   M. J. Fromberger5 6  Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.7 8  Permission is hereby granted, free of charge, to any person obtaining a copy9  of this software and associated documentation files (the "Software"), to deal10  in the Software without restriction, including without limitation the rights11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell12  copies of the Software, and to permit persons to whom the Software is13  furnished to do so, subject to the following conditions:14 15  The above copyright notice and this permission notice shall be included in16  all copies or substantial portions of the Software.17 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER22  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 THE24  SOFTWARE.25 */26 27#include <assert.h>28#include <limits.h>29#include <stdlib.h>30#include <string.h>31 32#include "imath.h"33#include "imdrover.h"34#include "imrat.h"35#include "iprime.h"36 37/* Globals visible from outside this file */38mp_result imath_errno;39char* imath_errmsg;40 41/* Set imath_errno and return failure from a test. */42#define FAIL(E) return (imath_errno = (E), false)43 44/* Check that an expression X yields the expected mp_result value V. */45#define VCHECK(X, V)           \46  do {                         \47    mp_result res_;            \48    if ((res_ = (X)) != (V)) { \49      FAIL(res_);              \50    }                          \51  } while (0)52#define CHECK(X) VCHECK(X, MP_OK)53#define ECHECK(X) VCHECK(X, expect)54#define ACHECK(X)      \55  do {                 \56    if (!(X)) {        \57      FAIL(MP_BADARG); \58    }                  \59  } while (0)60 61#define OUTPUT_LIMIT 204862#define NUM_REGS 1663#define OTHER_ERROR -102464 65static char g_output[OUTPUT_LIMIT];66static mpz_t g_zreg[NUM_REGS];67static mpq_t g_qreg[NUM_REGS];68static unsigned char g_bin1[OUTPUT_LIMIT];69static unsigned char g_bin2[OUTPUT_LIMIT];70 71extern void trim_line(char* line); /* borrowed from imtest.c */72 73/* Read in a string with radix tags */74static mp_result read_int_value(mp_int z, char* str);75static mp_result read_rat_value(mp_rat q, char* str);76 77/* Read in a string with radix tags, as a long (not an mp_int) */78static bool read_long(long* z, char* str);79 80/* Parse the input and output values and fill in pointers to the81   registers containing them.  Returns true if all is well, false82   in case of error.  Caller allocates in/out to correct sizes. */83static bool parse_int_values(testspec_t* t, mp_int* in, mp_int* out,84                             mp_result* rval);85static bool parse_rat_values(testspec_t* t, mp_rat* in, mp_rat* out,86                             mp_result* rval);87 88/* Parse a result code name and return the corresponding result code */89static bool parse_result_code(char* str, mp_result* code);90 91/* Read in a dot-delimited binary sequence to the given buffer, and return the92   number of bytes read.  Returns < 0 in case of a syntax error.  Records no93   more than limit bytes. */94static int parse_binary(char* str, unsigned char* buf, int limit);95 96/* Clean up registers (called from atexit()) */97static void done_testing(void);98 99/*100 * Utility subroutines for writing tests (explained above)101 */102 103static mp_result read_int_value(mp_int z, char* str) {104  int radix = 10;105 106  if (*str == '#') {107    ++str;108    switch (*str) {109      case 'x':110      case 'X':111        radix = 16;112        break;113      case 'd':114      case 'D':115        radix = 10;116        break;117      case 'o':118      case 'O':119        radix = 8;120        break;121      case 'b':122      case 'B':123        radix = 2;124        break;125      default:126        return MP_RANGE;127    }128    ++str;129  }130 131  return mp_int_read_string(z, radix, str);132}133 134static mp_result read_rat_value(mp_rat q, char* str) {135  int radix = 10;136 137  if (*str == '#') {138    ++str;139    switch (*str) {140      case 'x':141      case 'X':142        radix = 16;143        break;144      case 'd':145      case 'D':146        radix = 10;147        break;148      case 'o':149      case 'O':150        radix = 8;151        break;152      case 'b':153      case 'B':154        radix = 2;155        break;156      default:157        return MP_RANGE;158    }159    ++str;160  }161 162  if (*str == '@')163    return mp_rat_read_decimal(q, radix, str + 1);164  else165    return mp_rat_read_string(q, radix, str);166}167 168static bool read_long(long* z, char* str) {169  char* end;170  int radix = 10;171 172  if (*str == '#') {173    ++str;174    switch (*str) {175      case 'x':176      case 'X':177        radix = 16;178        break;179      case 'd':180      case 'D':181        radix = 10;182        break;183      case 'o':184      case 'O':185        radix = 8;186        break;187      case 'b':188      case 'B':189        radix = 2;190        break;191      default:192        return false;193    }194    ++str;195  }196 197  *z = strtol(str, &end, radix);198  return (end != str && *end == '\0');199}200 201static bool parse_int_values(testspec_t* t, mp_int* in, mp_int* out,202                             mp_result* rval) {203  int pos = 0;204  char* str;205 206  if (rval != NULL) *rval = MP_OK; /* default */207 208  if (in != NULL) {209    for (int i = 0; i < t->num_inputs; ++i) {210      str = t->input[i];211 212      trim_line(str);213 214      if (*str == '=') {215        int k = abs(atoi(str + 1)) - 1;216 217        if (k < 0 || k >= i) {218          fprintf(stderr, "Line %d: Invalid input back-reference [%s]\n",219                  t->line, str);220          return false;221        }222 223        in[i] = in[k];224      } else {225        mp_int reg = g_zreg + pos++; /* grab next free register */226 227        if (read_int_value(reg, str) != MP_OK) {228          fprintf(stderr, "Line %d: Invalid input value [%s]\n", t->line, str);229          return false;230        }231 232        in[i] = reg;233      }234    }235  }236 237  for (int i = 0; i < t->num_outputs; ++i) {238    mp_int reg = g_zreg + pos++;239 240    str = t->output[i];241 242    trim_line(str);243 244    if (strcmp(str, "?") == 0)245      mp_int_zero(reg);246    else if (*str == '$') {247      mp_result code;248 249      if (!parse_result_code(str, &code)) {250        fprintf(stderr, "Line %d: Invalid result code [%s]\n", t->line, str);251        return false;252      } else if (rval == NULL) {253        fprintf(stderr, "Line %d: Result code not permitted here [%s]\n",254                t->line, str);255        return false;256      } else257        *rval = code;258 259      /* Provide a dummy value for the corresponding output */260      mp_int_zero(reg);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);263      return false;264    }265 266    if (out != NULL) out[i] = reg;267  }268 269  return true;270}271 272static bool parse_rat_values(testspec_t* t, mp_rat* in, mp_rat* out,273                             mp_result* rval) {274  int pos = 0;275  char* str;276 277  if (rval != NULL) *rval = MP_OK; /* default */278 279  if (in != NULL) {280    for (int i = 0; i < t->num_inputs; ++i) {281      str = t->input[i];282 283      trim_line(str);284 285      if (*str == '=') {286        int k = abs(atoi(str + 1)) - 1;287 288        if (k < 0 || k >= i) {289          fprintf(stderr, "Line %d: Invalid input back-reference [%s]\n",290                  t->line, str);291          return false;292        }293 294        in[i] = in[k];295      } else {296        mp_rat reg = g_qreg + pos++; /* grab next free register */297 298        if (read_rat_value(reg, str) != MP_OK) {299          fprintf(stderr, "Line %d: Invalid input value [%s]\n", t->line, str);300          return false;301        }302 303        in[i] = reg;304      }305    }306  }307 308  for (int i = 0; i < t->num_outputs; ++i) {309    mp_rat reg = g_qreg + pos++;310 311    str = t->output[i];312 313    trim_line(str);314 315    if (strcmp(str, "?") == 0)316      mp_rat_zero(reg);317    else if (*str == '$') {318      mp_result code;319 320      if (!parse_result_code(str, &code)) {321        fprintf(stderr, "Line %d: Invalid result code [%s]\n", t->line, str);322        return false;323      } else if (rval == NULL) {324        fprintf(stderr, "Line %d: Result code not permitted here [%s]\n",325                t->line, str);326        return false;327      } else328        *rval = code;329 330      /* Provide a dummy value for the corresponding output */331      mp_rat_zero(reg);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);334      return false;335    }336 337    if (out != NULL) out[i] = reg;338  }339 340  return true;341}342 343static bool parse_result_code(char* str, mp_result* code) {344  if (str[0] == '$') {345    if (str[1] == '#') {346      long v;347 348      if (!read_long(&v, str + 2)) return false;349 350      *code = (mp_result)v;351    } else if (strcmp(str + 1, "MP_OK") == 0 ||352               strcmp(str + 1, "MP_FALSE") == 0) {353      *code = MP_OK;354    } else if (strcmp(str + 1, "MP_TRUE") == 0) {355      *code = MP_TRUE;356    } else if (strcmp(str + 1, "MP_MEMORY") == 0) {357      *code = MP_MEMORY;358    } else if (strcmp(str + 1, "MP_RANGE") == 0) {359      *code = MP_RANGE;360    } else if (strcmp(str + 1, "MP_UNDEF") == 0) {361      *code = MP_UNDEF;362    } else if (strcmp(str + 1, "MP_TRUNC") == 0) {363      *code = MP_TRUNC;364    } else if (strcmp(str + 1, "MP_ROUND_UP") == 0) {365      *code = MP_ROUND_UP;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;372    } else {373      return false;374    }375  }376 377  return true;378}379 380static int parse_binary(char* str, unsigned char* buf, int limit) {381  int pos = 0;382  char* tok;383 384  trim_line(str);385 386  for (tok = strtok(str, "."); tok != NULL && pos < limit;387       tok = strtok(NULL, ".")) {388    long v;389 390    if (!read_long(&v, tok) || v > UCHAR_MAX || v < 0) return -1;391 392    buf[pos++] = (unsigned char)v;393  }394 395  return pos;396}397 398static void done_testing(void) {399  int i;400 401  for (i = 0; i < NUM_REGS; ++i) {402    mp_int_clear(g_zreg + i);403    mp_rat_clear(g_qreg + i);404  }405}406 407/*408 * Global functions visible to callers outside this file.409 */410 411void init_testing(void) {412  static int is_done = 0;413 414  if (is_done) return;415 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);419  }420 421  imath_errmsg = g_output;422 423  assert(atexit(done_testing) == 0);424  is_done = 1;425}426 427void 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);431  }432}433 434bool test_init(testspec_t* t, FILE* ofp) {435  mp_int in[2], out[1];436  mp_small v;437  mp_usmall uv;438  mp_result expect;439 440  ACHECK(parse_int_values(t, in, out, &expect));441 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));445  } else { /* initv */446    CHECK(mp_int_to_int(in[1], &v));447    ECHECK(mp_int_init_value(in[0], v));448  }449 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);452    FAIL(OTHER_ERROR);453  }454 455  return true;456}457 458bool test_set(testspec_t* t, FILE* ofp) {459  mp_int in[2], out[1];460  mp_small v;461  mp_usmall uv;462  mp_result expect;463 464  ACHECK(parse_int_values(t, in, out, &expect));465 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));469  } else { /* setv */470    CHECK(mp_int_to_int(in[1], &v));471    ECHECK(mp_int_set_value(in[0], v));472  }473 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);476    FAIL(OTHER_ERROR);477  }478 479  return true;480}481 482bool test_neg(testspec_t* t, FILE* ofp) {483  mp_int in[2], out[1];484  mp_result expect;485 486  ACHECK(parse_int_values(t, in, out, &expect));487  ECHECK(mp_int_neg(in[0], in[1]));488 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);491    FAIL(OTHER_ERROR);492  }493 494  return true;495}496 497bool test_abs(testspec_t* t, FILE* ofp) {498  mp_int in[2], out[1];499  mp_result expect;500 501  ACHECK(parse_int_values(t, in, out, &expect));502  ECHECK(mp_int_abs(in[0], in[1]));503 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);506    FAIL(OTHER_ERROR);507  }508 509  return true;510}511 512bool test_add(testspec_t* t, FILE* ofp) {513  mp_int in[3], out[1];514  mp_small v;515  mp_result expect;516 517  ACHECK(parse_int_values(t, in, out, &expect));518 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]));522  } else {523    ECHECK(mp_int_add(in[0], in[1], in[2]));524  }525 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);528    FAIL(OTHER_ERROR);529  }530 531  return true;532}533 534bool test_sub(testspec_t* t, FILE* ofp) {535  mp_int in[3], out[1];536  mp_small v;537  mp_result expect;538 539  ACHECK(parse_int_values(t, in, out, &expect));540 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]));544  } else {545    ECHECK(mp_int_sub(in[0], in[1], in[2]));546  }547 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);550    FAIL(OTHER_ERROR);551  }552  return true;553}554 555bool test_mul(testspec_t* t, FILE* ofp) {556  mp_int in[3], out[1];557  mp_result expect;558 559  ACHECK(parse_int_values(t, in, out, &expect));560  ECHECK(mp_int_mul(in[0], in[1], in[2]));561 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);564    FAIL(OTHER_ERROR);565  }566  return true;567}568 569bool test_mulp2(testspec_t* t, FILE* ofp) {570  mp_int in[3], out[1];571  mp_result expect;572  mp_small p2;573 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]));577 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);580    FAIL(OTHER_ERROR);581  }582  return true;583}584 585bool test_mulv(testspec_t* t, FILE* ofp) {586  mp_int in[3], out[1];587  mp_result expect;588  mp_small v;589 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]));593 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);596    FAIL(OTHER_ERROR);597  }598  return true;599}600 601bool test_sqr(testspec_t* t, FILE* ofp) {602  mp_int in[2], out[1];603  mp_result expect;604 605  ACHECK(parse_int_values(t, in, out, &expect));606  ECHECK(mp_int_sqr(in[0], in[1]));607 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);610    FAIL(OTHER_ERROR);611  }612  return true;613}614 615bool test_div(testspec_t* t, FILE* ofp) {616  mp_int in[4], out[2];617  mp_result expect;618 619  ACHECK(parse_int_values(t, in, out, &expect));620  ECHECK(mp_int_div(in[0], in[1], in[2], in[3]));621 622  if (expect == MP_OK && ((mp_int_compare(in[2], out[0]) != 0) ||623                          (mp_int_compare(in[3], out[1]) != 0))) {624    int len;625    char* str;626 627    mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);628    str = g_output + (len = strlen(g_output));629    *str++ = ',';630    mp_int_to_string(in[3], 10, str, OUTPUT_LIMIT - (len + 1));631    FAIL(OTHER_ERROR);632  }633  return true;634}635 636bool test_divp2(testspec_t* t, FILE* ofp) {637  mp_int in[4], out[2];638  mp_result expect;639  mp_small p2;640 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]));644 645  if (expect == MP_OK && ((mp_int_compare(in[2], out[0]) != 0) ||646                          (mp_int_compare(in[3], out[1]) != 0))) {647    int len;648    char* str;649 650    mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);651    str = g_output + (len = strlen(g_output));652    *str++ = ',';653    mp_int_to_string(in[3], 10, str, OUTPUT_LIMIT - (len + 1));654    FAIL(OTHER_ERROR);655  }656  return true;657}658 659bool test_divv(testspec_t* t, FILE* ofp) {660  mp_int in[3], out[2];661  mp_result expect;662  mp_small v, rem, orem;663 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));668 669  if (expect == MP_OK &&670      ((mp_int_compare(in[2], out[0]) != 0) || (rem != orem))) {671    char* str;672 673    mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);674    str = g_output + strlen(g_output);675    *str++ = ',';676    sprintf(str, "%ld", rem);677    FAIL(OTHER_ERROR);678  }679  return true;680}681 682bool test_expt(testspec_t* t, FILE* ofp) {683  mp_int in[3], out[1];684  mp_result expect;685  mp_small pow;686 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]));690 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);693    FAIL(OTHER_ERROR);694  }695  return true;696}697 698bool test_exptv(testspec_t* t, FILE* ofp) {699  mp_int in[3], out[1];700  mp_result expect;701  mp_small a, b;702 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]));707 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);710    FAIL(OTHER_ERROR);711  }712  return true;713}714 715bool test_exptf(testspec_t* t, FILE* ofp) {716  mp_int in[3], out[1];717  mp_result expect;718 719  ACHECK(parse_int_values(t, in, out, &expect));720  ECHECK(mp_int_expt_full(in[0], in[1], in[2]));721 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);724    FAIL(OTHER_ERROR);725  }726  return true;727}728 729bool test_mod(testspec_t* t, FILE* ofp) {730  mp_int in[3], out[1];731  mp_result expect;732 733  ACHECK(parse_int_values(t, in, out, &expect));734  ECHECK(mp_int_mod(in[0], in[1], in[2]));735 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);738    FAIL(OTHER_ERROR);739  }740  return true;741}742 743bool test_gcd(testspec_t* t, FILE* ofp) {744  mp_int in[3], out[1];745  mp_result expect;746 747  ACHECK(parse_int_values(t, in, out, &expect));748  ECHECK(mp_int_gcd(in[0], in[1], in[2]));749 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);752    FAIL(OTHER_ERROR);753  }754  return true;755}756 757bool test_egcd(testspec_t* t, FILE* ofp) {758  mp_int in[5], out[3], t1 = g_zreg + 8, t2 = g_zreg + 9;759  mp_result expect;760 761  ACHECK(parse_int_values(t, in, out, &expect));762  ECHECK(mp_int_egcd(in[0], in[1], in[2], in[3], in[4]));763 764  /* If we got an error we expected, return success immediately */765  if (expect != MP_OK) return true;766 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)) {770    int len, len2;771    char* str;772 773    /* Failure might occur because the tester computed x and y in a different774       way than we did.  Verify that the results are correct before reporting775       an error. */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;780 781    mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);782    str = g_output + (len = strlen(g_output));783    *str++ = ',';784    mp_int_to_string(in[3], 10, str, OUTPUT_LIMIT - (len + 1));785    str = str + (len2 = strlen(str));786    *str++ = ',';787    mp_int_to_string(in[4], 10, str, OUTPUT_LIMIT - (len + len2 + 2));788    FAIL(OTHER_ERROR);789  }790  return true;791}792 793bool test_lcm(testspec_t* t, FILE* ofp) {794  mp_int in[3], out[1];795  mp_result expect;796 797  ACHECK(parse_int_values(t, in, out, &expect));798  ECHECK(mp_int_lcm(in[0], in[1], in[2]));799 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);802    FAIL(OTHER_ERROR);803  }804  return true;805}806 807bool test_sqrt(testspec_t* t, FILE* ofp) {808  mp_int in[2], out[1];809  mp_result expect;810 811  ACHECK(parse_int_values(t, in, out, &expect));812  ECHECK(mp_int_sqrt(in[0], in[1]));813 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);816    FAIL(OTHER_ERROR);817  }818  return true;819}820 821bool test_root(testspec_t* t, FILE* ofp) {822  mp_int in[3], out[1];823  mp_small v;824  mp_result expect;825 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]));829 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);832    FAIL(OTHER_ERROR);833  }834  return true;835}836 837bool test_invmod(testspec_t* t, FILE* ofp) {838  mp_int in[3], out[1];839  mp_result expect;840 841  ACHECK(parse_int_values(t, in, out, &expect));842  ECHECK(mp_int_invmod(in[0], in[1], in[2]));843 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);846    FAIL(OTHER_ERROR);847  }848  return true;849}850 851bool test_exptmod(testspec_t* t, FILE* ofp) {852  mp_int in[4], out[1];853  mp_result expect;854 855  ACHECK(parse_int_values(t, in, out, &expect));856  ECHECK(mp_int_exptmod(in[0], in[1], in[2], in[3]));857 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);860    FAIL(OTHER_ERROR);861  }862  return true;863}864 865bool test_exptmod_ev(testspec_t* t, FILE* ofp) {866  mp_int in[4], out[1];867  mp_result expect;868  mp_small v;869 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]));873 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);876    FAIL(OTHER_ERROR);877  }878  return true;879}880 881bool test_exptmod_bv(testspec_t* t, FILE* ofp) {882  mp_int in[4], out[1];883  mp_result expect;884  mp_small v;885 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]));889 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);892    FAIL(OTHER_ERROR);893  }894  return true;895}896 897bool test_comp(testspec_t* t, FILE* ofp) {898  mp_int in[2];899  mp_result res, expect;900 901  ACHECK(parse_int_values(t, in, NULL, &expect));902 903  if ((res = mp_int_compare(in[0], in[1])) != expect) {904    sprintf(g_output, "Incorrect comparison result (want %d, got %d)", expect,905            res);906    FAIL(OTHER_ERROR);907  }908  return true;909}910 911bool test_ucomp(testspec_t* t, FILE* ofp) {912  mp_int in[2];913  mp_result res, expect;914 915  ACHECK(parse_int_values(t, in, NULL, &expect));916 917  if ((res = mp_int_compare_unsigned(in[0], in[1])) != expect) {918    sprintf(g_output, "Incorrect comparison result (want %d, got %d)", expect,919            res);920    FAIL(OTHER_ERROR);921  }922  return true;923}924 925bool test_zcomp(testspec_t* t, FILE* ofp) {926  mp_int in[1];927  mp_result res, expect;928 929  ACHECK(parse_int_values(t, in, NULL, &expect));930 931  if ((res = mp_int_compare_zero(in[0])) != expect) {932    sprintf(g_output, "Incorrect comparison result (want %d, got %d)", expect,933            res);934    FAIL(OTHER_ERROR);935  }936  return true;937}938 939bool test_vcomp(testspec_t* t, FILE* ofp) {940  mp_int in[2];941  mp_result res, expect;942  mp_small v;943 944  ACHECK(parse_int_values(t, in, NULL, &expect));945 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,949            res);950    FAIL(OTHER_ERROR);951  }952  return true;953}954 955bool test_uvcomp(testspec_t* t, FILE* ofp) {956  mp_int in[2];957  mp_result res, expect;958  mp_usmall v;959 960  ACHECK(parse_int_values(t, in, NULL, &expect));961 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,965            res);966    FAIL(OTHER_ERROR);967  }968  return true;969}970 971bool test_tostr(testspec_t* t, FILE* ofp) {972  mp_int in[2];973  mp_small radix;974  mp_result len;975 976  ACHECK(parse_int_values(t, in, NULL, NULL));977  ACHECK(mp_int_to_int(in[1], &radix) == MP_OK);978 979  if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) FAIL(MP_RANGE);980 981  trim_line(t->output[0]);982  len = mp_int_string_len(in[0], radix);983 984  CHECK(mp_int_to_string(in[0], radix, g_output, len));985 986  if (strcmp(t->output[0], g_output) != 0) FAIL(OTHER_ERROR);987 988  return true;989}990 991bool test_tobin(testspec_t* t, FILE* ofp) {992  mp_int in[1];993  int test_len, out_len;994 995  ACHECK(parse_int_values(t, in, NULL, NULL));996 997  trim_line(t->output[0]);998  if ((out_len = parse_binary(t->output[0], g_bin1, sizeof(g_bin1))) < 0)999    FAIL(MP_BADARG);1000 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,1003            out_len);1004    FAIL(OTHER_ERROR);1005  }1006 1007  CHECK(mp_int_to_binary(in[0], g_bin2, sizeof(g_bin2)));1008 1009  if (memcmp(g_bin1, g_bin2, test_len) != 0) {1010    int pos = 0, i;1011 1012    for (i = 0; i < test_len - 1; ++i)1013      pos += sprintf(g_output + pos, "%d.", g_bin2[i]);1014 1015    sprintf(g_output + pos, "%d", g_bin2[i]);1016    FAIL(OTHER_ERROR);1017  }1018  return true;1019}1020 1021bool test_to_int(testspec_t* t, FILE* ofp) {1022  mp_int in[1], out[1];1023  mp_small v;1024  mp_result expect;1025 1026  ACHECK(parse_int_values(t, in, out, &expect));1027  ECHECK(mp_int_to_int(in[0], &v));1028 1029  if (expect == MP_OK && mp_int_compare_value(out[0], v) != 0) {1030    sprintf(g_output, "Incorrect value (got %ld)", v);1031    FAIL(OTHER_ERROR);1032  }1033  return true;1034}1035 1036bool test_to_uint(testspec_t* t, FILE* ofp) {1037  mp_int in[1], out[1];1038  mp_usmall v;1039  mp_result expect;1040 1041  ACHECK(parse_int_values(t, in, out, &expect));1042  ECHECK(mp_int_to_uint(in[0], &v));1043 1044  if (expect == MP_OK && mp_int_compare_uvalue(out[0], v) != 0) {1045    sprintf(g_output, "Incorrect value (got %lu)", v);1046    FAIL(OTHER_ERROR);1047  }1048  return true;1049}1050 1051bool test_read_binary(testspec_t* t, FILE* ofp) {1052  mp_int out[1], in = g_zreg + 1;1053  int in_len;1054  mp_result expect;1055 1056  ACHECK(parse_int_values(t, NULL, out, &expect));1057 1058  trim_line(t->input[0]);1059  if ((in_len = parse_binary(t->input[0], g_bin1, sizeof(g_bin1))) < 0)1060    FAIL(MP_BADARG);1061 1062  ECHECK(mp_int_read_binary(in, g_bin1, in_len));1063 1064  if (expect == MP_OK && mp_int_compare(in, out[0]) != 0) {1065    mp_int_to_string(in, 10, g_output, OUTPUT_LIMIT);1066    FAIL(OTHER_ERROR);1067  }1068  return true;1069}1070 1071bool test_to_uns(testspec_t* t, FILE* ofp) {1072  mp_int in[1];1073  int test_len, out_len;1074 1075  ACHECK(parse_int_values(t, in, NULL, NULL));1076 1077  trim_line(t->output[0]);1078  if ((out_len = parse_binary(t->output[0], g_bin1, sizeof(g_bin1))) < 0)1079    FAIL(MP_BADARG);1080 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,1083            out_len);1084    FAIL(OTHER_ERROR);1085  }1086 1087  CHECK(mp_int_to_unsigned(in[0], g_bin2, sizeof(g_bin2)));1088 1089  if (memcmp(g_bin1, g_bin2, test_len) != 0) {1090    int pos = 0, i;1091 1092    for (i = 0; i < test_len - 1; ++i)1093      pos += sprintf(g_output + pos, "%d.", g_bin2[i]);1094 1095    sprintf(g_output + pos, "%d", g_bin2[i]);1096    FAIL(OTHER_ERROR);1097  }1098  return true;1099}1100 1101bool test_read_uns(testspec_t* t, FILE* ofp) {1102  mp_int out[1], in = g_zreg + 1;1103  int in_len;1104  mp_result expect;1105 1106  ACHECK(parse_int_values(t, NULL, out, &expect));1107 1108  trim_line(t->input[0]);1109  if ((in_len = parse_binary(t->input[0], g_bin1, sizeof(g_bin1))) < 0)1110    FAIL(MP_BADARG);1111 1112  ECHECK(mp_int_read_unsigned(in, g_bin1, in_len));1113 1114  if (expect == MP_OK && mp_int_compare(in, out[0]) != 0) {1115    mp_int_to_string(in, 10, g_output, OUTPUT_LIMIT);1116    FAIL(OTHER_ERROR);1117  }1118  return true;1119}1120 1121bool test_meta(testspec_t* t, FILE* ofp) {1122  mp_int *in = NULL, *out = NULL;1123  int i, j;1124  mp_result expect;1125 1126  if (t->num_inputs > 0) {1127    in = calloc(t->num_inputs, sizeof(mp_int));1128  }1129  if (t->num_outputs > 0) {1130    out = calloc(t->num_outputs, sizeof(mp_int));1131  }1132 1133  if (!parse_int_values(t, in, out, &expect)) {1134    if (in != NULL) free(in);1135    if (out != NULL) free(out);1136    FAIL(MP_BADARG);1137  }1138 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);1144 1145    fprintf(ofp, " %2d.) %s", i + 1, g_output);1146 1147    for (j = i - 1; j >= 0; --j)1148      if (in[j] == in[i]) {1149        fprintf(ofp, " (=> %d)", j + 1);1150        break;1151      }1152 1153    fputc('\n', ofp);1154  }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);1158 1159    fprintf(ofp, " %2d.) %s\n", i + 1, g_output);1160  }1161  if (in != NULL) free(in);1162  if (out != NULL) free(out);1163  return true;1164}1165 1166bool test_qneg(testspec_t* t, FILE* ofp) {1167  mp_rat in[2], out[1];1168  mp_result expect;1169 1170  ACHECK(parse_rat_values(t, in, out, &expect));1171  ECHECK(mp_rat_neg(in[0], in[1]));1172 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);1175    FAIL(OTHER_ERROR);1176  }1177  return true;1178}1179 1180bool test_qrecip(testspec_t* t, FILE* ofp) {1181  mp_rat in[2], out[1];1182  mp_result expect;1183 1184  ACHECK(parse_rat_values(t, in, out, &expect));1185  ECHECK(mp_rat_recip(in[0], in[1]));1186 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);1189    FAIL(OTHER_ERROR);1190  }1191  return true;1192}1193 1194bool test_qabs(testspec_t* t, FILE* ofp) {1195  mp_rat in[2], out[1];1196  mp_result expect;1197 1198  ACHECK(parse_rat_values(t, in, out, &expect));1199  ECHECK(mp_rat_abs(in[0], in[1]));1200 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);1203    FAIL(OTHER_ERROR);1204  }1205  return true;1206}1207 1208bool test_qadd(testspec_t* t, FILE* ofp) {1209  mp_rat in[3], out[1];1210  mp_result expect;1211 1212  ACHECK(parse_rat_values(t, in, out, &expect));1213  ECHECK(mp_rat_add(in[0], in[1], in[2]));1214 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);1217    FAIL(OTHER_ERROR);1218  }1219  return true;1220}1221 1222bool test_qsub(testspec_t* t, FILE* ofp) {1223  mp_rat in[3], out[1];1224  mp_result expect;1225 1226  ACHECK(parse_rat_values(t, in, out, &expect));1227  ECHECK(mp_rat_sub(in[0], in[1], in[2]));1228 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);1231    FAIL(OTHER_ERROR);1232  }1233  return true;1234}1235 1236bool test_qmul(testspec_t* t, FILE* ofp) {1237  mp_rat in[3], out[1];1238  mp_result expect;1239 1240  ACHECK(parse_rat_values(t, in, out, &expect));1241  ECHECK(mp_rat_mul(in[0], in[1], in[2]));1242 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);1245    FAIL(OTHER_ERROR);1246  }1247  return true;1248}1249 1250bool test_qdiv(testspec_t* t, FILE* ofp) {1251  mp_rat in[3], out[1];1252  mp_result expect;1253 1254  ACHECK(parse_rat_values(t, in, out, &expect));1255  ECHECK(mp_rat_div(in[0], in[1], in[2]));1256 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);1259    FAIL(OTHER_ERROR);1260  }1261  return true;1262}1263 1264bool test_qaddz(testspec_t* t, FILE* ofp) {1265  mp_rat in[3], out[1];1266  mp_result expect;1267 1268  ACHECK(parse_rat_values(t, in, out, &expect));1269 1270  if (!mp_rat_is_integer(in[1])) {1271    fprintf(stderr,1272            "Line %d: Second argument must be an integer (test_qaddz)\n",1273            t->line);1274    FAIL(MP_BADARG);1275  }1276 1277  ECHECK(mp_rat_add_int(in[0], MP_NUMER_P(in[1]), in[2]));1278 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);1281    FAIL(OTHER_ERROR);1282  }1283  return true;1284}1285 1286bool test_qsubz(testspec_t* t, FILE* ofp) {1287  mp_rat in[3], out[1];1288  mp_result expect;1289 1290  ACHECK(parse_rat_values(t, in, out, &expect));1291 1292  if (!mp_rat_is_integer(in[1])) {1293    fprintf(stderr,1294            "Line %d: Second argument must be an integer (test_qsubz)\n",1295            t->line);1296    FAIL(MP_BADARG);1297  }1298 1299  ECHECK(mp_rat_sub_int(in[0], MP_NUMER_P(in[1]), in[2]));1300 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);1303    FAIL(OTHER_ERROR);1304  }1305  return true;1306}1307 1308bool test_qmulz(testspec_t* t, FILE* ofp) {1309  mp_rat in[3], out[1];1310  mp_result expect;1311 1312  ACHECK(parse_rat_values(t, in, out, &expect));1313 1314  if (!mp_rat_is_integer(in[1])) {1315    fprintf(stderr,1316            "Line %d: Second argument must be an integer (test_qmulz)\n",1317            t->line);1318    FAIL(MP_BADARG);1319  }1320 1321  ECHECK(mp_rat_mul_int(in[0], MP_NUMER_P(in[1]), in[2]));1322 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);1325    FAIL(OTHER_ERROR);1326  }1327  return true;1328}1329 1330bool test_qdivz(testspec_t* t, FILE* ofp) {1331  mp_rat in[3], out[1];1332  mp_result expect;1333 1334  ACHECK(parse_rat_values(t, in, out, &expect));1335 1336  if (!mp_rat_is_integer(in[1])) {1337    fprintf(stderr,1338            "Line %d: Second argument must be an integer (test_qdivz)\n",1339            t->line);1340    FAIL(MP_BADARG);1341  }1342 1343  ECHECK(mp_rat_div_int(in[0], MP_NUMER_P(in[1]), in[2]));1344 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);1347    FAIL(OTHER_ERROR);1348  }1349  return true;1350}1351 1352bool test_qexpt(testspec_t* t, FILE* ofp) {1353  mp_rat in[3], out[1];1354  mp_result expect;1355  mp_small power;1356 1357  ACHECK(parse_rat_values(t, in, out, &expect));1358 1359  if (!mp_rat_is_integer(in[1])) {1360    fprintf(stderr,1361            "Line %d: Second argument must be an integer (test_qexpt)\n",1362            t->line);1363    FAIL(MP_BADARG);1364  }1365 1366  CHECK(mp_int_to_int(MP_NUMER_P(in[1]), &power));1367  ECHECK(mp_rat_expt(in[0], power, in[2]));1368 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);1371    FAIL(OTHER_ERROR);1372  }1373  return true;1374}1375 1376bool test_qtostr(testspec_t* t, FILE* ofp) {1377  mp_rat in[2];1378  long radix;1379  mp_result len;1380 1381  ACHECK(parse_rat_values(t, in, NULL, NULL));1382  trim_line(t->input[1]);1383  ACHECK(read_long(&radix, t->input[1]));1384 1385  if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) {1386    fprintf(stderr, "Line %d: Radix %ld out of range\n", t->line, radix);1387    FAIL(MP_RANGE);1388  }1389 1390  trim_line(t->output[0]);1391  len = mp_rat_string_len(in[0], radix);1392 1393  CHECK(mp_rat_to_string(in[0], radix, g_output, len));1394 1395  if (strcmp(t->output[0], g_output) != 0) FAIL(OTHER_ERROR);1396 1397  return true;1398}1399 1400bool test_qtodec(testspec_t* t, FILE* ofp) {1401  mp_rat in[4];1402  long radix, prec, m;1403  mp_round_mode rmode;1404  mp_result res, expect = MP_OK, len;1405 1406  ACHECK(parse_rat_values(t, in, NULL, NULL));1407 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,1410            t->output[0]);1411    FAIL(OTHER_ERROR);1412  }1413 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;1421 1422  if (prec < 0) {1423    fprintf(stderr, "Line %d: Precision %ld out of range\n", t->line, prec);1424    FAIL(MP_RANGE);1425  }1426 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)));1430 1431  if (res == MP_OK && strcmp(t->output[0], g_output) != 0) FAIL(OTHER_ERROR);1432 1433  return true;1434}1435 1436bool test_qrdec(testspec_t* t, FILE* ofp) {1437  mp_rat out[1] = {NULL}, reg = g_qreg + 1;1438  long radix;1439  mp_result expect;1440 1441  ACHECK(parse_rat_values(t, NULL, out, &expect));1442  trim_line(t->input[1]);1443  ACHECK(read_long(&radix, t->input[1]));1444 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);1448    FAIL(OTHER_ERROR);1449  }1450  return true;1451}1452 1453bool test_is_prime(testspec_t* t, FILE* OFP) {1454  mp_int in[1] = {NULL};1455  mp_result expect;1456 1457  ACHECK(parse_int_values(t, in, NULL, &expect));1458  ECHECK(mp_int_is_prime(in[0]));1459  return true;1460}1461 1462/* Here there be dragons */1463