1*f0865ec9SKyle Evans /* 2*f0865ec9SKyle Evans * Copyright (C) 2017 - This file is part of libecc project 3*f0865ec9SKyle Evans * 4*f0865ec9SKyle Evans * Authors: 5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com> 6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7*f0865ec9SKyle Evans * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr> 8*f0865ec9SKyle Evans * 9*f0865ec9SKyle Evans * Contributors: 10*f0865ec9SKyle Evans * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr> 11*f0865ec9SKyle Evans * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr> 12*f0865ec9SKyle Evans * 13*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license. 14*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project. 15*f0865ec9SKyle Evans */ 16*f0865ec9SKyle Evans #include <libecc/libarith.h> 17*f0865ec9SKyle Evans /* Include internal API as it is used in our tests */ 18*f0865ec9SKyle Evans #include "../nn/nn_div.h" 19*f0865ec9SKyle Evans #include <sys/types.h> 20*f0865ec9SKyle Evans #include <sys/stat.h> 21*f0865ec9SKyle Evans #include <fcntl.h> 22*f0865ec9SKyle Evans #include <unistd.h> 23*f0865ec9SKyle Evans #include <string.h> 24*f0865ec9SKyle Evans #include <stdio.h> 25*f0865ec9SKyle Evans #include <stdlib.h> 26*f0865ec9SKyle Evans #include <assert.h> 27*f0865ec9SKyle Evans 28*f0865ec9SKyle Evans #ifdef WITH_ASSERT_BACKTRACE 29*f0865ec9SKyle Evans #include <signal.h> 30*f0865ec9SKyle Evans #include <execinfo.h> 31*f0865ec9SKyle Evans 32*f0865ec9SKyle Evans #define BACKTRACE_SIZE 4096 33*f0865ec9SKyle Evans static unsigned int backtrace_buffer_ptr = 0; 34*f0865ec9SKyle Evans static char backtrace_buffer[BACKTRACE_SIZE]; 35*f0865ec9SKyle Evans 36*f0865ec9SKyle Evans /* assert trapping and backtracing */ 37*f0865ec9SKyle Evans static void assert_signal_handler(int sig) 38*f0865ec9SKyle Evans { 39*f0865ec9SKyle Evans if (sig != SIGINT) { 40*f0865ec9SKyle Evans raise(sig); 41*f0865ec9SKyle Evans } 42*f0865ec9SKyle Evans /* Print the recorded backtrace */ 43*f0865ec9SKyle Evans printf("**** BACKTRACE *****\n"); 44*f0865ec9SKyle Evans printf("(from old to most recent calls)\n"); 45*f0865ec9SKyle Evans printf("%s", backtrace_buffer); 46*f0865ec9SKyle Evans exit(-1); 47*f0865ec9SKyle Evans } 48*f0865ec9SKyle Evans 49*f0865ec9SKyle Evans #define ADD_TO_BACKTRACE(...) do {\ 50*f0865ec9SKyle Evans int written_size;\ 51*f0865ec9SKyle Evans written_size = snprintf(backtrace_buffer + backtrace_buffer_ptr, BACKTRACE_SIZE - 1 - backtrace_buffer_ptr, __VA_ARGS__);\ 52*f0865ec9SKyle Evans backtrace_buffer_ptr += written_size;\ 53*f0865ec9SKyle Evans if(backtrace_buffer_ptr >= BACKTRACE_SIZE - 1){\ 54*f0865ec9SKyle Evans memset(backtrace_buffer, 0, sizeof(backtrace_buffer)-1);\ 55*f0865ec9SKyle Evans backtrace_buffer_ptr = 0;\ 56*f0865ec9SKyle Evans }\ 57*f0865ec9SKyle Evans } while(0) 58*f0865ec9SKyle Evans #else 59*f0865ec9SKyle Evans 60*f0865ec9SKyle Evans #define ADD_TO_BACKTRACE(...) do {\ 61*f0865ec9SKyle Evans } while(0) 62*f0865ec9SKyle Evans 63*f0865ec9SKyle Evans #endif 64*f0865ec9SKyle Evans 65*f0865ec9SKyle Evans /* 66*f0865ec9SKyle Evans * Import integer number (found in hexadecimal form in hbuf buffer 67*f0865ec9SKyle Evans * of length hbuflen) into already allocated out_nn. hbuflen is 68*f0865ec9SKyle Evans * expected to be of even size. out_nn parameter is expected to 69*f0865ec9SKyle Evans * have a large enough storage space (i.e. hbuflen / 2) to hold 70*f0865ec9SKyle Evans * imported number. 71*f0865ec9SKyle Evans */ 72*f0865ec9SKyle Evans static int nn_import_from_hexbuf(nn_t out_nn, const char *hbuf, u32 hbuflen) 73*f0865ec9SKyle Evans { 74*f0865ec9SKyle Evans char buf[WORD_BYTES * 2 + 1]; 75*f0865ec9SKyle Evans const char *start; 76*f0865ec9SKyle Evans u32 wlen; 77*f0865ec9SKyle Evans u32 k; 78*f0865ec9SKyle Evans int ret; 79*f0865ec9SKyle Evans 80*f0865ec9SKyle Evans ret = nn_check_initialized(out_nn); EG(ret, err); 81*f0865ec9SKyle Evans MUST_HAVE((hbuf != NULL), ret, err); 82*f0865ec9SKyle Evans MUST_HAVE(((hbuflen / 2) / WORD_BYTES) == out_nn->wlen, ret, err); 83*f0865ec9SKyle Evans 84*f0865ec9SKyle Evans wlen = (hbuflen + WORD_BYTES - 1) / (2 * WORD_BYTES); 85*f0865ec9SKyle Evans for (k = wlen; k > 0; k--) { 86*f0865ec9SKyle Evans /* 87*f0865ec9SKyle Evans * Copy current hex encoded word into null terminated 88*f0865ec9SKyle Evans * scratch buffer 89*f0865ec9SKyle Evans */ 90*f0865ec9SKyle Evans memset(buf, 0, WORD_BYTES * 2 + 1); 91*f0865ec9SKyle Evans start = hbuf + ((k - 1) * WORD_BYTES * 2); 92*f0865ec9SKyle Evans memcpy(buf, start, WORD_BYTES * 2); 93*f0865ec9SKyle Evans 94*f0865ec9SKyle Evans /* Let strtoull() convert the value for us */ 95*f0865ec9SKyle Evans out_nn->val[wlen - k] = strtoull(buf, NULL, 16); 96*f0865ec9SKyle Evans } 97*f0865ec9SKyle Evans 98*f0865ec9SKyle Evans for (k = NN_MAX_WORD_LEN; k > wlen; k--) { 99*f0865ec9SKyle Evans out_nn->val[k - 1] = 0; 100*f0865ec9SKyle Evans } 101*f0865ec9SKyle Evans 102*f0865ec9SKyle Evans err: 103*f0865ec9SKyle Evans return ret; 104*f0865ec9SKyle Evans } 105*f0865ec9SKyle Evans 106*f0865ec9SKyle Evans #define DISPATCH_TABLE_MAGIC "FEEDBABE" 107*f0865ec9SKyle Evans struct dispatch_table { 108*f0865ec9SKyle Evans const char magic[sizeof(DISPATCH_TABLE_MAGIC)]; 109*f0865ec9SKyle Evans const char *op_string; 110*f0865ec9SKyle Evans const char *op_string_helper; 111*f0865ec9SKyle Evans int (*fun) (const char *op, void **, int); 112*f0865ec9SKyle Evans }; 113*f0865ec9SKyle Evans 114*f0865ec9SKyle Evans #define ADD_TO_DISPATCH_TABLE(fun, op_string, op_string_helper) \ 115*f0865ec9SKyle Evans static const struct dispatch_table entry_##fun \ 116*f0865ec9SKyle Evans ATTRIBUTE_SECTION("tests_dispatch_table_section") ATTRIBUTE_USED = \ 117*f0865ec9SKyle Evans { DISPATCH_TABLE_MAGIC, op_string, op_string_helper, fun }; 118*f0865ec9SKyle Evans 119*f0865ec9SKyle Evans #define FIND_IN_DISPATCH_TABLE(op, to_find, type) do {\ 120*f0865ec9SKyle Evans extern struct dispatch_table __start_tests_dispatch_table_section;\ 121*f0865ec9SKyle Evans extern struct dispatch_table __stop_tests_dispatch_table_section;\ 122*f0865ec9SKyle Evans struct dispatch_table *dt, *begin, *end;\ 123*f0865ec9SKyle Evans char *ptr;\ 124*f0865ec9SKyle Evans \ 125*f0865ec9SKyle Evans begin = &__start_tests_dispatch_table_section;\ 126*f0865ec9SKyle Evans end = &__stop_tests_dispatch_table_section;\ 127*f0865ec9SKyle Evans ptr = (char*)begin;\ 128*f0865ec9SKyle Evans \ 129*f0865ec9SKyle Evans to_find = NULL;\ 130*f0865ec9SKyle Evans \ 131*f0865ec9SKyle Evans while(ptr < (char*)end){\ 132*f0865ec9SKyle Evans dt = (struct dispatch_table*)ptr;\ 133*f0865ec9SKyle Evans /* Find the magic */\ 134*f0865ec9SKyle Evans while(memcmp(dt->magic, DISPATCH_TABLE_MAGIC, sizeof(DISPATCH_TABLE_MAGIC)) != 0){\ 135*f0865ec9SKyle Evans ptr++;\ 136*f0865ec9SKyle Evans dt = (struct dispatch_table*)ptr;\ 137*f0865ec9SKyle Evans }\ 138*f0865ec9SKyle Evans if(strcmp(dt->op_string, op) == 0){ \ 139*f0865ec9SKyle Evans to_find = dt->type;\ 140*f0865ec9SKyle Evans break;\ 141*f0865ec9SKyle Evans }\ 142*f0865ec9SKyle Evans ptr += sizeof(struct dispatch_table);\ 143*f0865ec9SKyle Evans }\ 144*f0865ec9SKyle Evans } while(0) 145*f0865ec9SKyle Evans 146*f0865ec9SKyle Evans #define FIND_FUN_IN_DISPATCH_TABLE(op, function) FIND_IN_DISPATCH_TABLE(op, function, fun) 147*f0865ec9SKyle Evans 148*f0865ec9SKyle Evans #define FIND_HELPER_IN_DISPATCH_TABLE(op, string_helper) FIND_IN_DISPATCH_TABLE(op, string_helper, op_string_helper) 149*f0865ec9SKyle Evans 150*f0865ec9SKyle Evans /*****************/ 151*f0865ec9SKyle Evans 152*f0865ec9SKyle Evans #define GENERIC_TEST_FP_DECL_INIT0(name, ctx) \ 153*f0865ec9SKyle Evans fp_t name##_ptr[] = {NULL}; 154*f0865ec9SKyle Evans 155*f0865ec9SKyle Evans #define GENERIC_TEST_FP_DECL_INIT1(name, ctx) \ 156*f0865ec9SKyle Evans fp name##0; \ 157*f0865ec9SKyle Evans fp_t name##_ptr[] = { &name##0 };\ 158*f0865ec9SKyle Evans ret |= fp_init(&name##0, ctx);\ 159*f0865ec9SKyle Evans 160*f0865ec9SKyle Evans #define GENERIC_TEST_FP_DECL_INIT2(name, ctx) \ 161*f0865ec9SKyle Evans fp name##0, name##1;\ 162*f0865ec9SKyle Evans fp_t name##_ptr[] = { &name##0, &name##1 };\ 163*f0865ec9SKyle Evans ret |= fp_init(&name##0, ctx);\ 164*f0865ec9SKyle Evans ret |= fp_init(&name##1, ctx);\ 165*f0865ec9SKyle Evans 166*f0865ec9SKyle Evans #define GENERIC_TEST_FP_DECL_INIT3(name, ctx) \ 167*f0865ec9SKyle Evans fp name##0, name##1, name##2;\ 168*f0865ec9SKyle Evans fp_t name##_ptr[] = { &name##0, &name##1, &name##2 };\ 169*f0865ec9SKyle Evans ret |= fp_init(&name##0, ctx);\ 170*f0865ec9SKyle Evans ret |= fp_init(&name##1, ctx);\ 171*f0865ec9SKyle Evans ret |= fp_init(&name##2, ctx);\ 172*f0865ec9SKyle Evans 173*f0865ec9SKyle Evans #define GENERIC_TEST_FP_DECL_INIT4(name, ctx) \ 174*f0865ec9SKyle Evans fp name##0, name##1, name##2, name##3;\ 175*f0865ec9SKyle Evans fp_t name##_ptr[] = { &name##0, &name##1, &name##2, &name##3 };\ 176*f0865ec9SKyle Evans ret |= fp_init(&name##0, ctx);\ 177*f0865ec9SKyle Evans ret |= fp_init(&name##1, ctx);\ 178*f0865ec9SKyle Evans ret |= fp_init(&name##2, ctx);\ 179*f0865ec9SKyle Evans ret |= fp_init(&name##3, ctx);\ 180*f0865ec9SKyle Evans 181*f0865ec9SKyle Evans #define GENERIC_TEST_FP_DECL_INIT5(name, ctx) \ 182*f0865ec9SKyle Evans fp name##0, name##1, name##2, name##3, name##4;\ 183*f0865ec9SKyle Evans fp_t name##_ptr[] = { &name##0, &name##1, &name##2, &name##3, &name##4 };\ 184*f0865ec9SKyle Evans ret |= fp_init(&name##0, ctx);\ 185*f0865ec9SKyle Evans ret |= fp_init(&name##1, ctx);\ 186*f0865ec9SKyle Evans ret |= fp_init(&name##2, ctx);\ 187*f0865ec9SKyle Evans ret |= fp_init(&name##3, ctx);\ 188*f0865ec9SKyle Evans ret |= fp_init(&name##4, ctx);\ 189*f0865ec9SKyle Evans 190*f0865ec9SKyle Evans #define GENERIC_TEST_FP_DECL_INIT6(name, ctx) \ 191*f0865ec9SKyle Evans fp name##0, name##1, name##2, name##3, name##4, name##5;\ 192*f0865ec9SKyle Evans fp_t name##_ptr[] = { &name##0, &name##1, &name##2, &name##3, &name##4, &name##5 };\ 193*f0865ec9SKyle Evans ret |= fp_init(&name##0, ctx);\ 194*f0865ec9SKyle Evans ret |= fp_init(&name##1, ctx);\ 195*f0865ec9SKyle Evans ret |= fp_init(&name##2, ctx);\ 196*f0865ec9SKyle Evans ret |= fp_init(&name##3, ctx);\ 197*f0865ec9SKyle Evans ret |= fp_init(&name##4, ctx);\ 198*f0865ec9SKyle Evans ret |= fp_init(&name##5, ctx);\ 199*f0865ec9SKyle Evans 200*f0865ec9SKyle Evans #define GENERIC_TEST_NN_DECL_INIT0(name, size) \ 201*f0865ec9SKyle Evans nn_t name##_ptr[] = {NULL}; 202*f0865ec9SKyle Evans 203*f0865ec9SKyle Evans #define GENERIC_TEST_NN_DECL_INIT1(name, size) \ 204*f0865ec9SKyle Evans nn name##0; \ 205*f0865ec9SKyle Evans nn_t name##_ptr[] = { &name##0 }; \ 206*f0865ec9SKyle Evans ret |= nn_init(&name##0, size); \ 207*f0865ec9SKyle Evans 208*f0865ec9SKyle Evans #define GENERIC_TEST_NN_DECL_INIT2(name, size) \ 209*f0865ec9SKyle Evans nn name##0, name##1; \ 210*f0865ec9SKyle Evans nn_t name##_ptr[] = { &name##0, &name##1 }; \ 211*f0865ec9SKyle Evans ret |= nn_init(&name##0, size); \ 212*f0865ec9SKyle Evans ret |= nn_init(&name##1, size); \ 213*f0865ec9SKyle Evans 214*f0865ec9SKyle Evans #define GENERIC_TEST_NN_DECL_INIT3(name, size) \ 215*f0865ec9SKyle Evans nn name##0, name##1, name##2; \ 216*f0865ec9SKyle Evans nn_t name##_ptr[] = { &name##0, &name##1, &name##2 }; \ 217*f0865ec9SKyle Evans ret |= nn_init(&name##0, size); \ 218*f0865ec9SKyle Evans ret |= nn_init(&name##1, size); \ 219*f0865ec9SKyle Evans ret |= nn_init(&name##2, size); \ 220*f0865ec9SKyle Evans 221*f0865ec9SKyle Evans #define GENERIC_TEST_NN_DECL_INIT4(name, size) \ 222*f0865ec9SKyle Evans nn name##0, name##1, name##2, name##3; \ 223*f0865ec9SKyle Evans nn_t name##_ptr[] = { &name##0, &name##1, &name##2, &name##3 }; \ 224*f0865ec9SKyle Evans ret |= nn_init(&name##0, size); \ 225*f0865ec9SKyle Evans ret |= nn_init(&name##1, size); \ 226*f0865ec9SKyle Evans ret |= nn_init(&name##2, size); \ 227*f0865ec9SKyle Evans ret |= nn_init(&name##3, size); \ 228*f0865ec9SKyle Evans 229*f0865ec9SKyle Evans #define GENERIC_TEST_NN_DECL_INIT5(name, size) \ 230*f0865ec9SKyle Evans nn name##0, name##1, name##2, name##3, name##4; \ 231*f0865ec9SKyle Evans nn_t name##_ptr[] = { &name##0, &name##1, &name##2, &name##3, &name##4 };\ 232*f0865ec9SKyle Evans ret |= nn_init(&name##0, size); \ 233*f0865ec9SKyle Evans ret |= nn_init(&name##1, size); \ 234*f0865ec9SKyle Evans ret |= nn_init(&name##2, size); \ 235*f0865ec9SKyle Evans ret |= nn_init(&name##3, size); \ 236*f0865ec9SKyle Evans ret |= nn_init(&name##4, size); \ 237*f0865ec9SKyle Evans 238*f0865ec9SKyle Evans #define GENERIC_TEST_NN_DECL_INIT6(name, size) \ 239*f0865ec9SKyle Evans nn name##0, name##1, name##2, name##3, name##4, name##5; \ 240*f0865ec9SKyle Evans nn_t name##_ptr[] = { &name##0, &name##1, &name##2, &name##3, &name##4, &name##5 };\ 241*f0865ec9SKyle Evans ret |= nn_init(&name##0, size); \ 242*f0865ec9SKyle Evans ret |= nn_init(&name##1, size); \ 243*f0865ec9SKyle Evans ret |= nn_init(&name##2, size); \ 244*f0865ec9SKyle Evans ret |= nn_init(&name##3, size); \ 245*f0865ec9SKyle Evans ret |= nn_init(&name##4, size); \ 246*f0865ec9SKyle Evans ret |= nn_init(&name##5, size); \ 247*f0865ec9SKyle Evans 248*f0865ec9SKyle Evans #define GENERIC_TEST_FP_CLEAR0(name) 249*f0865ec9SKyle Evans 250*f0865ec9SKyle Evans #define GENERIC_TEST_FP_CLEAR1(name) \ 251*f0865ec9SKyle Evans fp_uninit(&name##0);\ 252*f0865ec9SKyle Evans 253*f0865ec9SKyle Evans #define GENERIC_TEST_FP_CLEAR2(name) \ 254*f0865ec9SKyle Evans fp_uninit(&name##0);\ 255*f0865ec9SKyle Evans fp_uninit(&name##1);\ 256*f0865ec9SKyle Evans 257*f0865ec9SKyle Evans #define GENERIC_TEST_FP_CLEAR3(name) \ 258*f0865ec9SKyle Evans fp_uninit(&name##0);\ 259*f0865ec9SKyle Evans fp_uninit(&name##1);\ 260*f0865ec9SKyle Evans fp_uninit(&name##2);\ 261*f0865ec9SKyle Evans 262*f0865ec9SKyle Evans #define GENERIC_TEST_FP_CLEAR4(name) \ 263*f0865ec9SKyle Evans fp_uninit(&name##0);\ 264*f0865ec9SKyle Evans fp_uninit(&name##1);\ 265*f0865ec9SKyle Evans fp_uninit(&name##2);\ 266*f0865ec9SKyle Evans fp_uninit(&name##3);\ 267*f0865ec9SKyle Evans 268*f0865ec9SKyle Evans #define GENERIC_TEST_FP_CLEAR5(name) \ 269*f0865ec9SKyle Evans fp_uninit(&name##0);\ 270*f0865ec9SKyle Evans fp_uninit(&name##1);\ 271*f0865ec9SKyle Evans fp_uninit(&name##2);\ 272*f0865ec9SKyle Evans fp_uninit(&name##3);\ 273*f0865ec9SKyle Evans fp_uninit(&name##4);\ 274*f0865ec9SKyle Evans 275*f0865ec9SKyle Evans #define GENERIC_TEST_FP_CLEAR6(name) \ 276*f0865ec9SKyle Evans fp_uninit(&name##0);\ 277*f0865ec9SKyle Evans fp_uninit(&name##1);\ 278*f0865ec9SKyle Evans fp_uninit(&name##2);\ 279*f0865ec9SKyle Evans fp_uninit(&name##3);\ 280*f0865ec9SKyle Evans fp_uninit(&name##4);\ 281*f0865ec9SKyle Evans fp_uninit(&name##5);\ 282*f0865ec9SKyle Evans 283*f0865ec9SKyle Evans #define GENERIC_TEST_nn_uninit0(name) 284*f0865ec9SKyle Evans 285*f0865ec9SKyle Evans #define GENERIC_TEST_nn_uninit1(name) \ 286*f0865ec9SKyle Evans nn_uninit(&name##0);\ 287*f0865ec9SKyle Evans 288*f0865ec9SKyle Evans #define GENERIC_TEST_nn_uninit2(name) \ 289*f0865ec9SKyle Evans nn_uninit(&name##0);\ 290*f0865ec9SKyle Evans nn_uninit(&name##1);\ 291*f0865ec9SKyle Evans 292*f0865ec9SKyle Evans #define GENERIC_TEST_nn_uninit3(name) \ 293*f0865ec9SKyle Evans nn_uninit(&name##0);\ 294*f0865ec9SKyle Evans nn_uninit(&name##1);\ 295*f0865ec9SKyle Evans nn_uninit(&name##2);\ 296*f0865ec9SKyle Evans 297*f0865ec9SKyle Evans #define GENERIC_TEST_nn_uninit4(name) \ 298*f0865ec9SKyle Evans nn_uninit(&name##0);\ 299*f0865ec9SKyle Evans nn_uninit(&name##1);\ 300*f0865ec9SKyle Evans nn_uninit(&name##2);\ 301*f0865ec9SKyle Evans nn_uninit(&name##3);\ 302*f0865ec9SKyle Evans 303*f0865ec9SKyle Evans #define GENERIC_TEST_nn_uninit5(name) \ 304*f0865ec9SKyle Evans nn_uninit(&name##0);\ 305*f0865ec9SKyle Evans nn_uninit(&name##1);\ 306*f0865ec9SKyle Evans nn_uninit(&name##2);\ 307*f0865ec9SKyle Evans nn_uninit(&name##3);\ 308*f0865ec9SKyle Evans nn_uninit(&name##4);\ 309*f0865ec9SKyle Evans 310*f0865ec9SKyle Evans #define GENERIC_TEST_nn_uninit6(name) \ 311*f0865ec9SKyle Evans nn_uninit(&name##0);\ 312*f0865ec9SKyle Evans nn_uninit(&name##1);\ 313*f0865ec9SKyle Evans nn_uninit(&name##2);\ 314*f0865ec9SKyle Evans nn_uninit(&name##3);\ 315*f0865ec9SKyle Evans nn_uninit(&name##4);\ 316*f0865ec9SKyle Evans nn_uninit(&name##5);\ 317*f0865ec9SKyle Evans 318*f0865ec9SKyle Evans #define FP_CTX_T_GENERIC_IN(num) ((fp_ctx_t)params[num]) 319*f0865ec9SKyle Evans #define FP_T_GENERIC_IN(num) ((fp_t)params[num]) 320*f0865ec9SKyle Evans #define NN_T_GENERIC_IN(num) ((nn_t)params[num]) 321*f0865ec9SKyle Evans #define UINT_GENERIC_IN(num) ((u64)*((u64*)params[num])) 322*f0865ec9SKyle Evans #define WORD_T_GENERIC_IN(num) ((word_t)*((word_t*)params[num])) 323*f0865ec9SKyle Evans #define INT_GENERIC_IN(num) ((int)*((int*)params[num])) 324*f0865ec9SKyle Evans 325*f0865ec9SKyle Evans #define FP_T_GENERIC_OUT(num) (&fp_out##num) 326*f0865ec9SKyle Evans #define NN_T_GENERIC_OUT(num) (&nn_out##num) 327*f0865ec9SKyle Evans #define WORD_T_GENERIC_OUT(num) (&(word_out[num])) 328*f0865ec9SKyle Evans #define INT_GENERIC_OUT(num) (&(int_out[num])) 329*f0865ec9SKyle Evans 330*f0865ec9SKyle Evans #define CHECK_FUN_RET there_is_output = 1; fun_out_value = (int) 331*f0865ec9SKyle Evans 332*f0865ec9SKyle Evans #define CHECK_FUN_NO_RET there_is_output = 0; fun_out_value = (int) 333*f0865ec9SKyle Evans 334*f0865ec9SKyle Evans /* Number of pre-allocated */ 335*f0865ec9SKyle Evans #define NUM_PRE_ALLOCATED_NN 6 336*f0865ec9SKyle Evans #define NUM_PRE_ALLOCATED_FP 6 337*f0865ec9SKyle Evans #define MAX_PARAMS 6 338*f0865ec9SKyle Evans 339*f0865ec9SKyle Evans #define GENERIC_TEST_NN_DECL_INIT_MAX(name, n) GENERIC_TEST_NN_DECL_INIT6(name, n) 340*f0865ec9SKyle Evans #define GENERIC_TEST_FP_DECL_INIT_MAX(name, ctx) GENERIC_TEST_FP_DECL_INIT6(name, ctx) 341*f0865ec9SKyle Evans 342*f0865ec9SKyle Evans /* Check that the string of parameters types only containes 'c', 'f', 'n' and 'u' 343*f0865ec9SKyle Evans * Check that the string of parameters I/O only contains 'i', 'o' and 'O' 344*f0865ec9SKyle Evans * 345*f0865ec9SKyle Evans */ 346*f0865ec9SKyle Evans #define PARAMETERS_SANITY_CHECK(test_num, param_types, param_io) do {\ 347*f0865ec9SKyle Evans unsigned int i, real_output = 0;\ 348*f0865ec9SKyle Evans assert(sizeof(param_types) == sizeof(param_io));\ 349*f0865ec9SKyle Evans for(i = 0; i < sizeof(param_types)-1; i++){\ 350*f0865ec9SKyle Evans if((param_types[i] != 'c') && (param_types[i] != 'f') && (param_types[i] != 'n') && (param_types[i] != 'u') && (param_types[i] != 's')){ \ 351*f0865ec9SKyle Evans printf("Error: types parameters of test %d mismatch!\n", test_num);\ 352*f0865ec9SKyle Evans return 0;\ 353*f0865ec9SKyle Evans }\ 354*f0865ec9SKyle Evans if((param_io[i] != 'i') && (param_io[i] != 'o') && (param_io[i] != 'O')){\ 355*f0865ec9SKyle Evans printf("Error: I/O parameters of test %d mismatch!\n", test_num);\ 356*f0865ec9SKyle Evans return 0;\ 357*f0865ec9SKyle Evans }\ 358*f0865ec9SKyle Evans if((param_io[i] == 'O') && (param_types[i] != 'u') && (param_types[i] != 's')){\ 359*f0865ec9SKyle Evans printf("Error: types and I/O parameters of test %d mismatch!\n", test_num);\ 360*f0865ec9SKyle Evans return 0;\ 361*f0865ec9SKyle Evans }\ 362*f0865ec9SKyle Evans if(param_io[i] == 'O'){\ 363*f0865ec9SKyle Evans real_output++;\ 364*f0865ec9SKyle Evans }\ 365*f0865ec9SKyle Evans }\ 366*f0865ec9SKyle Evans /* Check that we only have one function output */\ 367*f0865ec9SKyle Evans if(real_output > 1){\ 368*f0865ec9SKyle Evans printf("Error: multiple function output defined in I/O parameters of test %d!\n", test_num);\ 369*f0865ec9SKyle Evans return 0;\ 370*f0865ec9SKyle Evans }\ 371*f0865ec9SKyle Evans } while(0); 372*f0865ec9SKyle Evans 373*f0865ec9SKyle Evans #define SET_PARAMETER_PRETTY_NAME1(a) a 374*f0865ec9SKyle Evans #define SET_PARAMETER_PRETTY_NAME2(a, b) SET_PARAMETER_PRETTY_NAME1(a) "\0" b 375*f0865ec9SKyle Evans #define SET_PARAMETER_PRETTY_NAME3(a, b, c) SET_PARAMETER_PRETTY_NAME2(a, b) "\0" c 376*f0865ec9SKyle Evans #define SET_PARAMETER_PRETTY_NAME4(a, b, c, d) SET_PARAMETER_PRETTY_NAME3(a, b, c) "\0" d 377*f0865ec9SKyle Evans #define SET_PARAMETER_PRETTY_NAME5(a, b, c, d, e) SET_PARAMETER_PRETTY_NAME4(a, b, c, d) "\0" e 378*f0865ec9SKyle Evans #define SET_PARAMETER_PRETTY_NAME6(a, b, c, d, e, f) SET_PARAMETER_PRETTY_NAME5(a, b, c, d, e) "\0" f 379*f0865ec9SKyle Evans 380*f0865ec9SKyle Evans #define SET_PARAMETER_PRETTY_NAME(num, ...) SET_PARAMETER_PRETTY_NAME##num(__VA_ARGS__) 381*f0865ec9SKyle Evans 382*f0865ec9SKyle Evans /* Parse the helper string to get the pretty print names */ 383*f0865ec9SKyle Evans #define GET_PARAMETER_PRETTY_NAME(parameters_string_names_, parameters_string_names, num, out) do {\ 384*f0865ec9SKyle Evans unsigned int cnt = 0;\ 385*f0865ec9SKyle Evans out = 0;\ 386*f0865ec9SKyle Evans \ 387*f0865ec9SKyle Evans /* Find the proper position */\ 388*f0865ec9SKyle Evans while(out < sizeof(parameters_string_names_)-1){\ 389*f0865ec9SKyle Evans if(cnt == num){\ 390*f0865ec9SKyle Evans break;\ 391*f0865ec9SKyle Evans }\ 392*f0865ec9SKyle Evans if(parameters_string_names[out] == '\0'){\ 393*f0865ec9SKyle Evans cnt++;\ 394*f0865ec9SKyle Evans }\ 395*f0865ec9SKyle Evans out++;\ 396*f0865ec9SKyle Evans }\ 397*f0865ec9SKyle Evans } while(0); 398*f0865ec9SKyle Evans 399*f0865ec9SKyle Evans /* Print for a given test all the inputs, outpus and expected outputs */ 400*f0865ec9SKyle Evans #define PRINT_ALL(parameters_types, parameters_io, params, nn_out_ptr, fp_out_ptr, fun_output, there_is_output, parameters_string_names_, bad_num) do { \ 401*f0865ec9SKyle Evans unsigned int j;\ 402*f0865ec9SKyle Evans unsigned int nn_out_local_cnt = 0, fp_out_local_cnt = 0;\ 403*f0865ec9SKyle Evans unsigned int str_pos;\ 404*f0865ec9SKyle Evans const char parameters_string_names[] = parameters_string_names_;\ 405*f0865ec9SKyle Evans const char real[] = "Real ";\ 406*f0865ec9SKyle Evans const char expected[] = "Expected ";\ 407*f0865ec9SKyle Evans char expected_modified_string_names[sizeof(expected)+sizeof(parameters_string_names_)];\ 408*f0865ec9SKyle Evans char real_modified_string_names[sizeof(real)+sizeof(parameters_string_names_)];\ 409*f0865ec9SKyle Evans /* First print the inputs */\ 410*f0865ec9SKyle Evans for(j=0; j<sizeof(parameters_types)-1; j++){\ 411*f0865ec9SKyle Evans GET_PARAMETER_PRETTY_NAME(parameters_string_names_, parameters_string_names, j, str_pos);\ 412*f0865ec9SKyle Evans if(parameters_io[j] == 'i'){\ 413*f0865ec9SKyle Evans /* This is an input */\ 414*f0865ec9SKyle Evans if(parameters_types[j] == 'c'){\ 415*f0865ec9SKyle Evans nn_print(&(parameters_string_names[str_pos]), &(FP_CTX_T_GENERIC_IN(j)->p)); \ 416*f0865ec9SKyle Evans }\ 417*f0865ec9SKyle Evans if(parameters_types[j] == 'f'){\ 418*f0865ec9SKyle Evans nn_print(&(parameters_string_names[str_pos]), &(FP_T_GENERIC_IN(j)->fp_val)); \ 419*f0865ec9SKyle Evans }\ 420*f0865ec9SKyle Evans if(parameters_types[j] == 'n'){\ 421*f0865ec9SKyle Evans nn_print(&(parameters_string_names[str_pos]), NN_T_GENERIC_IN(j));\ 422*f0865ec9SKyle Evans }\ 423*f0865ec9SKyle Evans if(parameters_types[j] == 'u'){\ 424*f0865ec9SKyle Evans printf("%16s: 0x", &(parameters_string_names[str_pos])); \ 425*f0865ec9SKyle Evans printf(PRINTF_WORD_HEX_FMT, WORD_T_GENERIC_IN(j)); \ 426*f0865ec9SKyle Evans printf("\n"); \ 427*f0865ec9SKyle Evans }\ 428*f0865ec9SKyle Evans if(parameters_types[j] == 's'){\ 429*f0865ec9SKyle Evans printf("%16s:", &(parameters_string_names[str_pos])); \ 430*f0865ec9SKyle Evans printf("%d", INT_GENERIC_IN(j)); \ 431*f0865ec9SKyle Evans printf("\n"); \ 432*f0865ec9SKyle Evans }\ 433*f0865ec9SKyle Evans }\ 434*f0865ec9SKyle Evans }\ 435*f0865ec9SKyle Evans /* Then print the outputs */\ 436*f0865ec9SKyle Evans for(j=0; j<sizeof(parameters_types)-1; j++){\ 437*f0865ec9SKyle Evans GET_PARAMETER_PRETTY_NAME(parameters_string_names_, parameters_string_names, j, str_pos);\ 438*f0865ec9SKyle Evans memset(expected_modified_string_names, 0, sizeof(expected_modified_string_names));\ 439*f0865ec9SKyle Evans strcat(expected_modified_string_names, expected);\ 440*f0865ec9SKyle Evans strcat(expected_modified_string_names, &(parameters_string_names[str_pos]));\ 441*f0865ec9SKyle Evans memset(real_modified_string_names, 0, sizeof(real_modified_string_names));\ 442*f0865ec9SKyle Evans strcat(real_modified_string_names, real);\ 443*f0865ec9SKyle Evans strcat(real_modified_string_names, &(parameters_string_names[str_pos]));\ 444*f0865ec9SKyle Evans if(parameters_io[j] == 'o'){\ 445*f0865ec9SKyle Evans /* This is an input that is an output */\ 446*f0865ec9SKyle Evans if(parameters_types[j] == 'f'){\ 447*f0865ec9SKyle Evans nn_print(real_modified_string_names, &(fp_out_ptr[j]->fp_val)); \ 448*f0865ec9SKyle Evans nn_print(expected_modified_string_names, &(FP_T_GENERIC_IN(j)->fp_val)); \ 449*f0865ec9SKyle Evans fp_out_local_cnt++;\ 450*f0865ec9SKyle Evans }\ 451*f0865ec9SKyle Evans if(parameters_types[j] == 'n'){\ 452*f0865ec9SKyle Evans nn_print(real_modified_string_names, nn_out_ptr[j]);\ 453*f0865ec9SKyle Evans nn_print(expected_modified_string_names, NN_T_GENERIC_IN(j));\ 454*f0865ec9SKyle Evans nn_out_local_cnt++;\ 455*f0865ec9SKyle Evans }\ 456*f0865ec9SKyle Evans if(parameters_types[j] == 'u'){\ 457*f0865ec9SKyle Evans printf("%16s: 0x", real_modified_string_names); \ 458*f0865ec9SKyle Evans printf(PRINTF_WORD_HEX_FMT, *(WORD_T_GENERIC_OUT(j))); \ 459*f0865ec9SKyle Evans printf("\n"); \ 460*f0865ec9SKyle Evans printf("%16s: 0x", expected_modified_string_names); \ 461*f0865ec9SKyle Evans printf(PRINTF_WORD_HEX_FMT, WORD_T_GENERIC_IN(j)); \ 462*f0865ec9SKyle Evans printf("\n"); \ 463*f0865ec9SKyle Evans }\ 464*f0865ec9SKyle Evans if(parameters_types[j] == 's'){\ 465*f0865ec9SKyle Evans printf("%16s: ", real_modified_string_names); \ 466*f0865ec9SKyle Evans printf("%d", *(INT_GENERIC_OUT(j))); \ 467*f0865ec9SKyle Evans printf("\n"); \ 468*f0865ec9SKyle Evans printf("%16s: ", expected_modified_string_names); \ 469*f0865ec9SKyle Evans printf("%d", INT_GENERIC_IN(j)); \ 470*f0865ec9SKyle Evans printf("\n"); \ 471*f0865ec9SKyle Evans }\ 472*f0865ec9SKyle Evans }\ 473*f0865ec9SKyle Evans if((parameters_io[j] == 'O') && (there_is_output == 1)){\ 474*f0865ec9SKyle Evans /* This is a real function output */\ 475*f0865ec9SKyle Evans if(parameters_types[j] == 'u'){\ 476*f0865ec9SKyle Evans printf("%16s: 0x", real_modified_string_names); \ 477*f0865ec9SKyle Evans printf(PRINTF_WORD_HEX_FMT, (word_t)fun_output); \ 478*f0865ec9SKyle Evans printf("\n"); \ 479*f0865ec9SKyle Evans printf("%16s: 0x", expected_modified_string_names); \ 480*f0865ec9SKyle Evans printf(PRINTF_WORD_HEX_FMT, WORD_T_GENERIC_IN(j)); \ 481*f0865ec9SKyle Evans printf("\n"); \ 482*f0865ec9SKyle Evans }\ 483*f0865ec9SKyle Evans if(parameters_types[j] == 's'){\ 484*f0865ec9SKyle Evans printf("%16s: ", real_modified_string_names); \ 485*f0865ec9SKyle Evans printf("%d", (int)fun_output); \ 486*f0865ec9SKyle Evans printf("\n"); \ 487*f0865ec9SKyle Evans printf("%16s: ", expected_modified_string_names); \ 488*f0865ec9SKyle Evans printf("%d", INT_GENERIC_IN(j)); \ 489*f0865ec9SKyle Evans printf("\n"); \ 490*f0865ec9SKyle Evans }\ 491*f0865ec9SKyle Evans }\ 492*f0865ec9SKyle Evans }\ 493*f0865ec9SKyle Evans } while(0) 494*f0865ec9SKyle Evans 495*f0865ec9SKyle Evans /* Generic testing framework. Seems ugly but does the job! */ 496*f0865ec9SKyle Evans #define GENERIC_TEST(test_name, operation_, given_string_helper, fun_name, parameters_types_, parameters_io_, parameters_string_names, fun_output, nn_out_num, fp_out_num, ...) \ 497*f0865ec9SKyle Evans int test_##test_name(const char ATTRIBUTE_UNUSED *op, void **params, int test_num);\ 498*f0865ec9SKyle Evans int test_##test_name(const char ATTRIBUTE_UNUSED *op, void **params, int test_num){\ 499*f0865ec9SKyle Evans unsigned int i;\ 500*f0865ec9SKyle Evans int ret = 0, cmp, mismatch = 0; \ 501*f0865ec9SKyle Evans const char *op_string = NULL;\ 502*f0865ec9SKyle Evans unsigned int n_len ATTRIBUTE_UNUSED = 0;\ 503*f0865ec9SKyle Evans int fun_out_value = 0;\ 504*f0865ec9SKyle Evans u8 there_is_output = 0;\ 505*f0865ec9SKyle Evans unsigned int nn_out_local_cnt = 0, fp_out_local_cnt = 0;\ 506*f0865ec9SKyle Evans fp_ctx_t fp_ctx_param ATTRIBUTE_UNUSED = NULL;\ 507*f0865ec9SKyle Evans int fp_ctx_initialized ATTRIBUTE_UNUSED = 0;\ 508*f0865ec9SKyle Evans \ 509*f0865ec9SKyle Evans const char parameters_types[] = parameters_types_;\ 510*f0865ec9SKyle Evans const char parameters_io[] = parameters_io_;\ 511*f0865ec9SKyle Evans \ 512*f0865ec9SKyle Evans const char operation[] = #operation_;\ 513*f0865ec9SKyle Evans \ 514*f0865ec9SKyle Evans /* Our words used as output of functions */\ 515*f0865ec9SKyle Evans word_t word_out[MAX_PARAMS] ATTRIBUTE_UNUSED = { 0 };\ 516*f0865ec9SKyle Evans int int_out[MAX_PARAMS] ATTRIBUTE_UNUSED = { 0 };\ 517*f0865ec9SKyle Evans \ 518*f0865ec9SKyle Evans assert(memcmp(operation, op, sizeof(operation)) == 0);\ 519*f0865ec9SKyle Evans \ 520*f0865ec9SKyle Evans /* Sanity check: check that the parameters passed from the file are the same as the ones declared in the test */\ 521*f0865ec9SKyle Evans if(memcmp(global_parameters, parameters_types, LOCAL_MIN(MAX_PARAMS, strlen(parameters_types))) != 0){\ 522*f0865ec9SKyle Evans printf("Error: parameters %s given in the test file differ from the test expected parameters (%s)\n", parameters_types, global_parameters);\ 523*f0865ec9SKyle Evans return -1;\ 524*f0865ec9SKyle Evans }\ 525*f0865ec9SKyle Evans \ 526*f0865ec9SKyle Evans PARAMETERS_SANITY_CHECK(test_num, parameters_types, parameters_io);\ 527*f0865ec9SKyle Evans \ 528*f0865ec9SKyle Evans /* If we find an fp or nn, assume its length is the common length. */\ 529*f0865ec9SKyle Evans for(i=0; i<sizeof(parameters_io)-1; i++){\ 530*f0865ec9SKyle Evans if((parameters_io[i] == 'o') && (parameters_types[i] == 'f')){\ 531*f0865ec9SKyle Evans n_len = (FP_T_GENERIC_IN(i))->fp_val.wlen;\ 532*f0865ec9SKyle Evans break;\ 533*f0865ec9SKyle Evans }\ 534*f0865ec9SKyle Evans if((parameters_io[i] == 'o') && (parameters_types[i] == 'n')){\ 535*f0865ec9SKyle Evans n_len = (NN_T_GENERIC_IN(i))->wlen;\ 536*f0865ec9SKyle Evans break;\ 537*f0865ec9SKyle Evans }\ 538*f0865ec9SKyle Evans }\ 539*f0865ec9SKyle Evans for(i=0; i<sizeof(parameters_io)-1; i++){\ 540*f0865ec9SKyle Evans if(parameters_types[i] == 'c'){\ 541*f0865ec9SKyle Evans fp_ctx_param = (FP_CTX_T_GENERIC_IN(i));\ 542*f0865ec9SKyle Evans fp_ctx_initialized = 1;\ 543*f0865ec9SKyle Evans break;\ 544*f0865ec9SKyle Evans }\ 545*f0865ec9SKyle Evans }\ 546*f0865ec9SKyle Evans GENERIC_TEST_NN_DECL_INIT##nn_out_num(nn_out, n_len * WORD_BYTES);\ 547*f0865ec9SKyle Evans assert(fp_out_num == 0 || fp_ctx_initialized != 0);\ 548*f0865ec9SKyle Evans GENERIC_TEST_FP_DECL_INIT##fp_out_num(fp_out, fp_ctx_param);\ 549*f0865ec9SKyle Evans if(ret){\ 550*f0865ec9SKyle Evans goto err;\ 551*f0865ec9SKyle Evans }\ 552*f0865ec9SKyle Evans \ 553*f0865ec9SKyle Evans CHECK_FUN_##fun_output fun_name(__VA_ARGS__);\ 554*f0865ec9SKyle Evans /* Check generic value return is 0 */\ 555*f0865ec9SKyle Evans if(there_is_output == 0){\ 556*f0865ec9SKyle Evans assert(fun_out_value == 0);\ 557*f0865ec9SKyle Evans }\ 558*f0865ec9SKyle Evans \ 559*f0865ec9SKyle Evans /* Check result is what we expect */\ 560*f0865ec9SKyle Evans FIND_HELPER_IN_DISPATCH_TABLE(operation, op_string);\ 561*f0865ec9SKyle Evans assert(op_string != NULL);\ 562*f0865ec9SKyle Evans \ 563*f0865ec9SKyle Evans for(i=0; i<sizeof(parameters_io)-1; i++){\ 564*f0865ec9SKyle Evans if(parameters_io[i] == 'o'){\ 565*f0865ec9SKyle Evans /* We have an input that is an output, check it */\ 566*f0865ec9SKyle Evans if (parameters_types[i] == 'f') {\ 567*f0865ec9SKyle Evans ret = fp_cmp(fp_out_ptr[i], FP_T_GENERIC_IN(i), &cmp); \ 568*f0865ec9SKyle Evans if(ret || cmp){\ 569*f0865ec9SKyle Evans printf("[-] Test %d (%s): result mismatch\n", test_num, op_string);\ 570*f0865ec9SKyle Evans /* Print the expected outputs */\ 571*f0865ec9SKyle Evans PRINT_ALL(parameters_types, parameters_io, params, nn_out_ptr, fp_out_ptr, fun_out_value, there_is_output, parameters_string_names, i);\ 572*f0865ec9SKyle Evans mismatch = 1;\ 573*f0865ec9SKyle Evans break;\ 574*f0865ec9SKyle Evans }\ 575*f0865ec9SKyle Evans fp_out_local_cnt++;\ 576*f0865ec9SKyle Evans }\ 577*f0865ec9SKyle Evans if (parameters_types[i] == 'n') {\ 578*f0865ec9SKyle Evans ret = nn_cmp(nn_out_ptr[i], NN_T_GENERIC_IN(i), &cmp); \ 579*f0865ec9SKyle Evans if(ret || cmp){\ 580*f0865ec9SKyle Evans printf("[-] Test %d (%s): result mismatch\n", test_num, op_string);\ 581*f0865ec9SKyle Evans /* Print the expected outputs */\ 582*f0865ec9SKyle Evans PRINT_ALL(parameters_types, parameters_io, params, nn_out_ptr, fp_out_ptr, fun_out_value, there_is_output, parameters_string_names, i);\ 583*f0865ec9SKyle Evans mismatch = 1;\ 584*f0865ec9SKyle Evans break;\ 585*f0865ec9SKyle Evans }\ 586*f0865ec9SKyle Evans nn_out_local_cnt++;\ 587*f0865ec9SKyle Evans }\ 588*f0865ec9SKyle Evans if (parameters_types[i] == 'u') {\ 589*f0865ec9SKyle Evans if((*(WORD_T_GENERIC_OUT(i))) != WORD_T_GENERIC_IN(i)){\ 590*f0865ec9SKyle Evans printf("[-] Test %d (%s): result mismatch\n", test_num, op_string);\ 591*f0865ec9SKyle Evans /* Print the expected outputs */\ 592*f0865ec9SKyle Evans PRINT_ALL(parameters_types, parameters_io, params, nn_out_ptr, fp_out_ptr, fun_out_value, there_is_output, parameters_string_names, i);\ 593*f0865ec9SKyle Evans mismatch = 1;\ 594*f0865ec9SKyle Evans break;\ 595*f0865ec9SKyle Evans }\ 596*f0865ec9SKyle Evans }\ 597*f0865ec9SKyle Evans if (parameters_types[i] == 's') {\ 598*f0865ec9SKyle Evans if((*(INT_GENERIC_OUT(i))) != INT_GENERIC_IN(i)){\ 599*f0865ec9SKyle Evans printf("[-] Test %d (%s): result mismatch\n", test_num, op_string);\ 600*f0865ec9SKyle Evans /* Print the expected outputs */\ 601*f0865ec9SKyle Evans PRINT_ALL(parameters_types, parameters_io, params, nn_out_ptr, fp_out_ptr, fun_out_value, there_is_output, parameters_string_names, i);\ 602*f0865ec9SKyle Evans mismatch = 1;\ 603*f0865ec9SKyle Evans break;\ 604*f0865ec9SKyle Evans }\ 605*f0865ec9SKyle Evans }\ 606*f0865ec9SKyle Evans }\ 607*f0865ec9SKyle Evans if(parameters_io[i] == 'O'){\ 608*f0865ec9SKyle Evans /* We have a function output, check it */\ 609*f0865ec9SKyle Evans if(fun_out_value != INT_GENERIC_IN(i)){\ 610*f0865ec9SKyle Evans printf("[-] Test %d (%s): result mismatch\n", test_num, op_string);\ 611*f0865ec9SKyle Evans /* Print the expected outputs */\ 612*f0865ec9SKyle Evans PRINT_ALL(parameters_types, parameters_io, params, nn_out_ptr, fp_out_ptr, fun_out_value, there_is_output, parameters_string_names, i);\ 613*f0865ec9SKyle Evans mismatch = 1;\ 614*f0865ec9SKyle Evans break;\ 615*f0865ec9SKyle Evans }\ 616*f0865ec9SKyle Evans }\ 617*f0865ec9SKyle Evans }\ 618*f0865ec9SKyle Evans \ 619*f0865ec9SKyle Evans GENERIC_TEST_nn_uninit##nn_out_num(nn_out);\ 620*f0865ec9SKyle Evans GENERIC_TEST_FP_CLEAR##fp_out_num(fp_out);\ 621*f0865ec9SKyle Evans \ 622*f0865ec9SKyle Evans return !mismatch;\ 623*f0865ec9SKyle Evans err:\ 624*f0865ec9SKyle Evans printf("[-] Error: general error when initializing variables ...\n");\ 625*f0865ec9SKyle Evans exit(-1);\ 626*f0865ec9SKyle Evans }\ 627*f0865ec9SKyle Evans ADD_TO_DISPATCH_TABLE(test_##test_name, #operation_, given_string_helper) 628*f0865ec9SKyle Evans 629*f0865ec9SKyle Evans #define GENERIC_TEST_NN(test_name, operation_, given_string_helper, fun_name, parameters_types_, parameters_io_, parameters_string_names, fun_output, nn_out_num, ...) \ 630*f0865ec9SKyle Evans GENERIC_TEST(test_name, operation_, given_string_helper, fun_name, parameters_types_, parameters_io_, parameters_string_names, fun_output, nn_out_num, 0, __VA_ARGS__) 631*f0865ec9SKyle Evans 632*f0865ec9SKyle Evans #define GENERIC_TEST_FP(test_name, operation_, given_string_helper, fun_name, parameters_types_, parameters_io_, parameters_string_names, fun_output, nn_out_num, ...) \ 633*f0865ec9SKyle Evans GENERIC_TEST(test_name, operation_, given_string_helper, fun_name, parameters_types_, parameters_io_, parameters_string_names, fun_output, nn_out_num, __VA_ARGS__) 634*f0865ec9SKyle Evans 635*f0865ec9SKyle Evans 636*f0865ec9SKyle Evans /* Global variable to keep track of parameters */ 637*f0865ec9SKyle Evans static char global_parameters[MAX_PARAMS]; 638*f0865ec9SKyle Evans 639*f0865ec9SKyle Evans /*********** NN layer tests ************************************************/ 640*f0865ec9SKyle Evans /* Testing shifts and rotates */ 641*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_lshift_fixedlen, NN_SHIFT_LEFT_FIXEDLEN, "(fixed)<<", nn_lshift_fixedlen, "nnu", "oii", 642*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "output", "input", "fixed lshift"), NO_RET, 1, 643*f0865ec9SKyle Evans NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), (bitcnt_t)UINT_GENERIC_IN(2)) 644*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_rshift_fixedlen, NN_SHIFT_RIGHT_FIXEDLEN, "(fixed)>>", nn_rshift_fixedlen, "nnu", "oii", 645*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "output", "input", "fixed rshift"), NO_RET, 1, 646*f0865ec9SKyle Evans NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), (bitcnt_t)UINT_GENERIC_IN(2)) 647*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_lshift, NN_SHIFT_LEFT, "<<", nn_lshift, "nnu", "oii", 648*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "output", "input", "lshift"), NO_RET, 1, 649*f0865ec9SKyle Evans NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), (bitcnt_t)UINT_GENERIC_IN(2)) 650*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_rshift, NN_SHIFT_RIGHT, ">>", nn_rshift, "nnu", "oii", 651*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "output", "input", "rshift"), NO_RET, 1, 652*f0865ec9SKyle Evans NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), (bitcnt_t)UINT_GENERIC_IN(2)) 653*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_lrot, NN_ROTATE_LEFT, "lrot", nn_lrot, "nnuu", "oiii", 654*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "output", "input", "lrot", "bitlen_base"), NO_RET, 1, 655*f0865ec9SKyle Evans NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), (bitcnt_t)UINT_GENERIC_IN(2), (bitcnt_t)UINT_GENERIC_IN(3)) 656*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_rrot, NN_ROTATE_RIGHT, "rrot", nn_rrot, "nnuu", "oiii", 657*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "output", "input", "rrot", "bitlen_base"), NO_RET, 1, 658*f0865ec9SKyle Evans NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), (bitcnt_t)UINT_GENERIC_IN(2), (bitcnt_t)UINT_GENERIC_IN(3)) 659*f0865ec9SKyle Evans 660*f0865ec9SKyle Evans 661*f0865ec9SKyle Evans /* Testing xor, or, and, not */ 662*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_xor, NN_XOR, "^", nn_xor, "nnn", "iio", 663*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "input1", "input2", "output"), NO_RET, 3, 664*f0865ec9SKyle Evans NN_T_GENERIC_OUT(2), NN_T_GENERIC_IN(0), NN_T_GENERIC_IN(1)) 665*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_or, NN_OR, "|", nn_or, "nnn", "iio", 666*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "input1", "input2", "output"), NO_RET, 3, 667*f0865ec9SKyle Evans NN_T_GENERIC_OUT(2), NN_T_GENERIC_IN(0), NN_T_GENERIC_IN(1)) 668*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_and, NN_AND, "&", nn_and, "nnn", "iio", 669*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "input1", "input2", "output"), NO_RET, 3, 670*f0865ec9SKyle Evans NN_T_GENERIC_OUT(2), NN_T_GENERIC_IN(0), NN_T_GENERIC_IN(1)) 671*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_not, NN_NOT, "~", nn_not, "nn", "io", 672*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(2, "input", "output"), NO_RET, 2, 673*f0865ec9SKyle Evans NN_T_GENERIC_OUT(1), NN_T_GENERIC_IN(0)) 674*f0865ec9SKyle Evans 675*f0865ec9SKyle Evans /* Testing add and sub */ 676*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_add, NN_ADD, "+", nn_add, "nnn", "iio", 677*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "input1", "input2", "output"), 678*f0865ec9SKyle Evans NO_RET, 3, NN_T_GENERIC_OUT(2), NN_T_GENERIC_IN(0), 679*f0865ec9SKyle Evans NN_T_GENERIC_IN(1)) 680*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_sub, NN_SUB, "-", nn_sub, "nnn", "iio", 681*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "input1", "input2", "output"), 682*f0865ec9SKyle Evans NO_RET, 3, NN_T_GENERIC_OUT(2), NN_T_GENERIC_IN(0), 683*f0865ec9SKyle Evans NN_T_GENERIC_IN(1)) 684*f0865ec9SKyle Evans 685*f0865ec9SKyle Evans /* Testing inc and dec */ 686*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_inc, NN_INC, "++", nn_inc, "nn", "io", 687*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(2, "input", "output"), NO_RET, 2, 688*f0865ec9SKyle Evans NN_T_GENERIC_OUT(1), NN_T_GENERIC_IN(0)) 689*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_dec, NN_DEC, "--", nn_dec, "nn", "io", 690*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(2, "input", "output"), NO_RET, 2, 691*f0865ec9SKyle Evans NN_T_GENERIC_OUT(1), NN_T_GENERIC_IN(0)) 692*f0865ec9SKyle Evans 693*f0865ec9SKyle Evans /* Testing modular add, sub, inc, dec, mul, exp (inputs are supposed < p except for exp) */ 694*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mod_add, NN_MOD_ADD, "+%", nn_mod_add, "nnnn", "iiio", 695*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "input1", "input2", "modulo", "output"), 696*f0865ec9SKyle Evans NO_RET, 4, NN_T_GENERIC_OUT(3), NN_T_GENERIC_IN(0), 697*f0865ec9SKyle Evans NN_T_GENERIC_IN(1), NN_T_GENERIC_IN(2)) 698*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mod_sub, NN_MOD_SUB, "-%", nn_mod_sub, "nnnn", "iiio", 699*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "input1", "input2", "modulo", "output"), 700*f0865ec9SKyle Evans NO_RET, 4, NN_T_GENERIC_OUT(3), NN_T_GENERIC_IN(0), 701*f0865ec9SKyle Evans NN_T_GENERIC_IN(1), NN_T_GENERIC_IN(2)) 702*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mod_inc, NN_MOD_INC, "++%", nn_mod_inc, "nnn", "iio", 703*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "input1", "modulo", "output"), 704*f0865ec9SKyle Evans NO_RET, 3, NN_T_GENERIC_OUT(2), NN_T_GENERIC_IN(0), 705*f0865ec9SKyle Evans NN_T_GENERIC_IN(1)) 706*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mod_dec, NN_MOD_DEC, "--%", nn_mod_dec, "nnn", "iio", 707*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "input1", "modulo", "output"), 708*f0865ec9SKyle Evans NO_RET, 3, NN_T_GENERIC_OUT(2), NN_T_GENERIC_IN(0), 709*f0865ec9SKyle Evans NN_T_GENERIC_IN(1)) 710*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mod_mul, NN_MOD_MUL, "*%", nn_mod_mul, "nnnn", "iiio", 711*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "input1", "input2", "modulo", "output"), 712*f0865ec9SKyle Evans NO_RET, 4, NN_T_GENERIC_OUT(3), NN_T_GENERIC_IN(0), 713*f0865ec9SKyle Evans NN_T_GENERIC_IN(1), NN_T_GENERIC_IN(2)) 714*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mod_pow, NN_MOD_POW, "exp%", nn_mod_pow, "nnnn", "iiio", 715*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "base", "exp", "modulo", "output"), 716*f0865ec9SKyle Evans NO_RET, 4, NN_T_GENERIC_OUT(3), NN_T_GENERIC_IN(0), 717*f0865ec9SKyle Evans NN_T_GENERIC_IN(1), NN_T_GENERIC_IN(2)) 718*f0865ec9SKyle Evans 719*f0865ec9SKyle Evans 720*f0865ec9SKyle Evans /* Testing mul */ 721*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mul, NN_MUL, "*", nn_mul, "nnn", "oii", 722*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "output1", "input1", "input2"), 723*f0865ec9SKyle Evans NO_RET, 1, NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), 724*f0865ec9SKyle Evans NN_T_GENERIC_IN(2)) 725*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_sqr, NN_SQR, "(^2)", nn_sqr, "nn", "oi", 726*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(2, "output1", "input1"), 727*f0865ec9SKyle Evans NO_RET, 1, NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1)) 728*f0865ec9SKyle Evans 729*f0865ec9SKyle Evans /* Testing division */ 730*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_divrem, NN_DIVREM, "/", nn_divrem, "nnnn", "ooii", 731*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "quotient", "remainder", "input1", "input2"), 732*f0865ec9SKyle Evans NO_RET, 2, NN_T_GENERIC_OUT(0), NN_T_GENERIC_OUT(1), 733*f0865ec9SKyle Evans NN_T_GENERIC_IN(2), NN_T_GENERIC_IN(3)) 734*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_xgcd, NN_XGCD, "xgcd", nn_xgcd, "nnnnns", "oooiio", 735*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(6, "xgcd", "u", "v", "input1", "input2", "sign"), 736*f0865ec9SKyle Evans NO_RET, 3, NN_T_GENERIC_OUT(0), NN_T_GENERIC_OUT(1), NN_T_GENERIC_OUT(2), 737*f0865ec9SKyle Evans NN_T_GENERIC_IN(3), NN_T_GENERIC_IN(4), INT_GENERIC_OUT(5)) 738*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_gcd, NN_GCD, "gcd", nn_gcd, "nnns", "oiio", 739*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "gcd", "input1", "input2", "sign"), 740*f0865ec9SKyle Evans NO_RET, 1, NN_T_GENERIC_OUT(0), 741*f0865ec9SKyle Evans NN_T_GENERIC_IN(1), NN_T_GENERIC_IN(2), INT_GENERIC_OUT(3)) 742*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mod, NN_MOD, "%", nn_mod, "nnn", "oii", 743*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "output", "input1", "input2"), 744*f0865ec9SKyle Evans NO_RET, 1, NN_T_GENERIC_OUT(0), 745*f0865ec9SKyle Evans NN_T_GENERIC_IN(1), NN_T_GENERIC_IN(2)) 746*f0865ec9SKyle Evans 747*f0865ec9SKyle Evans /* Testing modular inversion */ 748*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_modinv, NN_MODINV, "(^-1%)", nn_modinv, "nnns", "oiiO", 749*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "output", "input1", "input2", "ret"), 750*f0865ec9SKyle Evans RET, 1, NN_T_GENERIC_OUT(0), 751*f0865ec9SKyle Evans NN_T_GENERIC_IN(1), NN_T_GENERIC_IN(2)) 752*f0865ec9SKyle Evans 753*f0865ec9SKyle Evans /* Testing modular inversion modulo a 2**n */ 754*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_modinv_2exp, NN_MODINV_2EXP, "(^-1%)(2exp)", nn_modinv_2exp, "nnus", "oiio", 755*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "output", "input1", "input2", "isodd"), 756*f0865ec9SKyle Evans NO_RET, 1, NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), 757*f0865ec9SKyle Evans UINT_GENERIC_IN(2), INT_GENERIC_OUT(3)) 758*f0865ec9SKyle Evans 759*f0865ec9SKyle Evans /* Check Montgomery multiplication redcify primitives */ 760*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_compute_redc1_coefs, NN_COEF_REDC1, "coef_redc1", nn_compute_redc1_coefs, "nnnu", "ooio", 761*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "r", "r_square", "p", "mpinv"), 762*f0865ec9SKyle Evans NO_RET, 3, NN_T_GENERIC_OUT(0), NN_T_GENERIC_OUT(1), NN_T_GENERIC_IN(2), WORD_T_GENERIC_OUT(3)) 763*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_compute_div_coefs, NN_COEF_DIV, "coef_div", nn_compute_div_coefs, "nuun", "oooi", 764*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "p_normalized", "p_shift", "p_reciprocal", "p"), 765*f0865ec9SKyle Evans NO_RET, 3, NN_T_GENERIC_OUT(0), WORD_T_GENERIC_OUT(1), WORD_T_GENERIC_OUT(2), NN_T_GENERIC_IN(3)) 766*f0865ec9SKyle Evans GENERIC_TEST_NN(nn_mul_redc1, NN_MUL_REDC1, "*_redc1", nn_mul_redc1, "nnnnu", "oiiii", 767*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(5, "output", "input1", "input2", "p", "mpinv"), 768*f0865ec9SKyle Evans NO_RET, 1, NN_T_GENERIC_OUT(0), NN_T_GENERIC_IN(1), NN_T_GENERIC_IN(2), 769*f0865ec9SKyle Evans NN_T_GENERIC_IN(3), WORD_T_GENERIC_IN(4)) 770*f0865ec9SKyle Evans 771*f0865ec9SKyle Evans 772*f0865ec9SKyle Evans 773*f0865ec9SKyle Evans /*********** Fp layer tests ************************************************/ 774*f0865ec9SKyle Evans /* Testing addition in F_p */ 775*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_add, FP_ADD, "+", fp_add, "cfff", "ioii", 776*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "p", "sum", "input1", "input2"), 777*f0865ec9SKyle Evans NO_RET, 0, 2, 778*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_IN(2), FP_T_GENERIC_IN(3)) 779*f0865ec9SKyle Evans 780*f0865ec9SKyle Evans /* Testing subtraction in F_p */ 781*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_sub, FP_SUB, "-", fp_sub, "cfff", "ioii", 782*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "p", "diff", "input1", "input2"), 783*f0865ec9SKyle Evans NO_RET, 0, 2, 784*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_IN(2), FP_T_GENERIC_IN(3)) 785*f0865ec9SKyle Evans 786*f0865ec9SKyle Evans /* Testing multiplication in F_p */ 787*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_mul, FP_MUL, "*", fp_mul, "cfff", "ioii", 788*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "p", "prod", "input1", "input2"), 789*f0865ec9SKyle Evans NO_RET, 0, 2, 790*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_IN(2), FP_T_GENERIC_IN(3)) 791*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_sqr, FP_SQR, "(^2)", fp_sqr, "cff", "ioi", 792*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "p", "prod", "input1"), 793*f0865ec9SKyle Evans NO_RET, 0, 2, 794*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_IN(2)) 795*f0865ec9SKyle Evans 796*f0865ec9SKyle Evans /* Testing division in F_p */ 797*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_div, FP_DIV, "/", fp_div, "cfff", "ioii", 798*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "p", "quo", "input1", "input2"), 799*f0865ec9SKyle Evans NO_RET, 0, 2, 800*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_IN(2), FP_T_GENERIC_IN(3)) 801*f0865ec9SKyle Evans 802*f0865ec9SKyle Evans /* Testing Montgomery multiplication in F_p */ 803*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_mul_monty, FP_MUL_MONTY, "*_monty", fp_mul_monty, "cfff", "ioii", 804*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "p", "prod", "input1", "input2"), 805*f0865ec9SKyle Evans NO_RET, 0, 2, 806*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_IN(2), FP_T_GENERIC_IN(3)) 807*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_sqr_monty, FP_SQR_MONTY, "(^2)_monty", fp_sqr_monty, "cff", "ioi", 808*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(3, "p", "prod", "input1"), 809*f0865ec9SKyle Evans NO_RET, 0, 2, 810*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_IN(2)) 811*f0865ec9SKyle Evans 812*f0865ec9SKyle Evans /* Testing exponentiation in F_p */ 813*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_pow, FP_POW, "exp", fp_pow, "cffn", "ioii", 814*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "p", "pow", "input", "exp"), 815*f0865ec9SKyle Evans NO_RET, 0, 2, 816*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_IN(2), NN_T_GENERIC_IN(3)) 817*f0865ec9SKyle Evans 818*f0865ec9SKyle Evans /* Testing square residue in F_p */ 819*f0865ec9SKyle Evans GENERIC_TEST_FP(fp_sqrt, FP_SQRT, "sqrt", fp_sqrt, "cfffs", "iooiO", 820*f0865ec9SKyle Evans SET_PARAMETER_PRETTY_NAME(4, "sqrt1", "sqrt2", "p", "ret"), 821*f0865ec9SKyle Evans RET, 0, 3, 822*f0865ec9SKyle Evans FP_T_GENERIC_OUT(1), FP_T_GENERIC_OUT(2), FP_T_GENERIC_IN(3)) 823*f0865ec9SKyle Evans 824*f0865ec9SKyle Evans /*****************************************************************/ 825*f0865ec9SKyle Evans 826*f0865ec9SKyle Evans /* 827*f0865ec9SKyle Evans * Read data on given fd until first newline character and put it in buf 828*f0865ec9SKyle Evans * followed by a null character. buffer size is passed via buflen. The 829*f0865ec9SKyle Evans * length of read line is returned to the caller in buflen on success 830*f0865ec9SKyle Evans * (not including null character terminating read string). 831*f0865ec9SKyle Evans * 832*f0865ec9SKyle Evans * 0 is returned on success. 833*f0865ec9SKyle Evans * -1 is returned on end of file. 834*f0865ec9SKyle Evans * -2 is returned on error (buffer not sufficient, etc) 835*f0865ec9SKyle Evans */ 836*f0865ec9SKyle Evans int read_string(int fd, char *buf, unsigned int *buflen); 837*f0865ec9SKyle Evans int read_string(int fd, char *buf, unsigned int *buflen) 838*f0865ec9SKyle Evans { 839*f0865ec9SKyle Evans unsigned int pos = 0, len; 840*f0865ec9SKyle Evans int ret = -1; 841*f0865ec9SKyle Evans char c; 842*f0865ec9SKyle Evans 843*f0865ec9SKyle Evans MUST_HAVE((buf != NULL) && (buflen != NULL), ret, err); 844*f0865ec9SKyle Evans 845*f0865ec9SKyle Evans len = *buflen; 846*f0865ec9SKyle Evans 847*f0865ec9SKyle Evans if (len < 2) { 848*f0865ec9SKyle Evans ret = -2; 849*f0865ec9SKyle Evans goto err; 850*f0865ec9SKyle Evans } 851*f0865ec9SKyle Evans 852*f0865ec9SKyle Evans len -= 1; /* keep some space to terminate the string */ 853*f0865ec9SKyle Evans 854*f0865ec9SKyle Evans while ((len > 0) && ((ret = read(fd, &c, 1)) != 0) && (c != '\n')) { 855*f0865ec9SKyle Evans buf[pos++] = c; 856*f0865ec9SKyle Evans len -= 1; 857*f0865ec9SKyle Evans } 858*f0865ec9SKyle Evans 859*f0865ec9SKyle Evans if (len == 0) { 860*f0865ec9SKyle Evans ret = -2; 861*f0865ec9SKyle Evans goto err; 862*f0865ec9SKyle Evans } 863*f0865ec9SKyle Evans 864*f0865ec9SKyle Evans if (!ret) { 865*f0865ec9SKyle Evans ret = -1; 866*f0865ec9SKyle Evans goto err; 867*f0865ec9SKyle Evans } 868*f0865ec9SKyle Evans 869*f0865ec9SKyle Evans /* Terminate the string */ 870*f0865ec9SKyle Evans buf[pos] = 0; 871*f0865ec9SKyle Evans *buflen = pos; 872*f0865ec9SKyle Evans ret = 0; 873*f0865ec9SKyle Evans 874*f0865ec9SKyle Evans err: 875*f0865ec9SKyle Evans return ret; 876*f0865ec9SKyle Evans } 877*f0865ec9SKyle Evans 878*f0865ec9SKyle Evans 879*f0865ec9SKyle Evans /* 880*f0865ec9SKyle Evans * Parse a test file and perform the tests it provides, one 881*f0865ec9SKyle Evans * by one, in order. 882*f0865ec9SKyle Evans */ 883*f0865ec9SKyle Evans int main(int argc, char *argv[]) 884*f0865ec9SKyle Evans { 885*f0865ec9SKyle Evans nn fp_ctx_modulus, fp_ctx_r, fp_ctx_r_square, fp_ctx_mpinv; 886*f0865ec9SKyle Evans nn fp_ctx_pshift, fp_ctx_pnorm, fp_ctx_prec; 887*f0865ec9SKyle Evans fp_ctx fp_ctx_param; 888*f0865ec9SKyle Evans int ret, cmp; 889*f0865ec9SKyle Evans u64 u_params[MAX_PARAMS]; 890*f0865ec9SKyle Evans void *params[MAX_PARAMS]; 891*f0865ec9SKyle Evans unsigned int ibuflen = BIT_LEN_WORDS(NN_MAX_BIT_LEN) * WORD_BYTES * 10; 892*f0865ec9SKyle Evans unsigned long int test_num, line = 0, oktests = 0; 893*f0865ec9SKyle Evans int test_ret; 894*f0865ec9SKyle Evans unsigned int len = ibuflen; 895*f0865ec9SKyle Evans int nrecs; 896*f0865ec9SKyle Evans int fd = 0, nn_local_cnt = 0, fp_local_cnt = 0, fp_ctx_local_cnt = 0; 897*f0865ec9SKyle Evans unsigned int nn_len; 898*f0865ec9SKyle Evans char op[1024]; 899*f0865ec9SKyle Evans char *ibuf = NULL, *rec = NULL; 900*f0865ec9SKyle Evans nn *tmp; 901*f0865ec9SKyle Evans fp *fp_tmp; 902*f0865ec9SKyle Evans int (*curr_test_fun) (const char *, void **, int); 903*f0865ec9SKyle Evans unsigned long p_tmp; 904*f0865ec9SKyle Evans 905*f0865ec9SKyle Evans ret = nn_init(&fp_ctx_modulus, 0); 906*f0865ec9SKyle Evans ret |= nn_init(&fp_ctx_r, 0); 907*f0865ec9SKyle Evans ret |= nn_init(&fp_ctx_r_square, 0); 908*f0865ec9SKyle Evans ret |= nn_init(&fp_ctx_mpinv, 0); 909*f0865ec9SKyle Evans ret |= nn_init(&fp_ctx_pshift, 0); 910*f0865ec9SKyle Evans ret |= nn_init(&fp_ctx_pnorm, 0); 911*f0865ec9SKyle Evans ret |= nn_init(&fp_ctx_prec, 0); 912*f0865ec9SKyle Evans 913*f0865ec9SKyle Evans /* First "fake" context initialization with junk value 914*f0865ec9SKyle Evans * one as prime number 915*f0865ec9SKyle Evans */ 916*f0865ec9SKyle Evans ret |= nn_one(&fp_ctx_modulus); 917*f0865ec9SKyle Evans ret |= fp_ctx_init_from_p(&fp_ctx_param, &fp_ctx_modulus); 918*f0865ec9SKyle Evans GENERIC_TEST_FP_DECL_INIT_MAX(fp_params, &fp_ctx_param) 919*f0865ec9SKyle Evans GENERIC_TEST_NN_DECL_INIT_MAX(nn_params, 0) 920*f0865ec9SKyle Evans 921*f0865ec9SKyle Evans if(ret){ 922*f0865ec9SKyle Evans goto err; 923*f0865ec9SKyle Evans } 924*f0865ec9SKyle Evans 925*f0865ec9SKyle Evans #ifdef WITH_ASSERT_BACKTRACE 926*f0865ec9SKyle Evans memset(backtrace_buffer, 0, sizeof(backtrace_buffer) - 1); 927*f0865ec9SKyle Evans if (signal(SIGINT, assert_signal_handler) == SIG_ERR) { 928*f0865ec9SKyle Evans printf("Error: can't catch SIGINT signal ...\n"); 929*f0865ec9SKyle Evans return -1; 930*f0865ec9SKyle Evans } 931*f0865ec9SKyle Evans #endif 932*f0865ec9SKyle Evans 933*f0865ec9SKyle Evans if (argc > 2) { 934*f0865ec9SKyle Evans printf("Usage: %s [test_file]\n", argv[0]); 935*f0865ec9SKyle Evans printf(" If no test_file provided, stdin is taken\n"); 936*f0865ec9SKyle Evans return -1; 937*f0865ec9SKyle Evans } 938*f0865ec9SKyle Evans 939*f0865ec9SKyle Evans /* Special case where we want to dump information */ 940*f0865ec9SKyle Evans if (argc == 2) { 941*f0865ec9SKyle Evans if (memcmp(argv[1], "-info", sizeof("-info")) == 0){ 942*f0865ec9SKyle Evans printf("%d %d\n", WORDSIZE, NN_MAX_BASE); 943*f0865ec9SKyle Evans return 0; 944*f0865ec9SKyle Evans } 945*f0865ec9SKyle Evans } 946*f0865ec9SKyle Evans 947*f0865ec9SKyle Evans ibuf = (char*)malloc(ibuflen); 948*f0865ec9SKyle Evans if (!ibuf) { 949*f0865ec9SKyle Evans return -1; 950*f0865ec9SKyle Evans } 951*f0865ec9SKyle Evans memset(ibuf, 0, ibuflen); 952*f0865ec9SKyle Evans 953*f0865ec9SKyle Evans if(argc == 2){ 954*f0865ec9SKyle Evans fd = open(argv[1], O_RDONLY); 955*f0865ec9SKyle Evans } 956*f0865ec9SKyle Evans else{ 957*f0865ec9SKyle Evans fd = STDIN_FILENO; 958*f0865ec9SKyle Evans } 959*f0865ec9SKyle Evans while (read_string(fd, ibuf, &len) == 0) { 960*f0865ec9SKyle Evans char *t, *s = ibuf; 961*f0865ec9SKyle Evans int i; 962*f0865ec9SKyle Evans 963*f0865ec9SKyle Evans /* Find end of first record (the test number) */ 964*f0865ec9SKyle Evans t = strchr(s, ' '); 965*f0865ec9SKyle Evans if (t == NULL) { 966*f0865ec9SKyle Evans printf("\nLine %lu: unable to find record #1\n", line); 967*f0865ec9SKyle Evans return -1; 968*f0865ec9SKyle Evans } 969*f0865ec9SKyle Evans *t = 0; /* mark end of record */ 970*f0865ec9SKyle Evans test_num = strtoul(s, NULL, 10); 971*f0865ec9SKyle Evans assert(line == test_num); 972*f0865ec9SKyle Evans s = t + 1; /* jump to beginning of next record */ 973*f0865ec9SKyle Evans 974*f0865ec9SKyle Evans /* Find end of second record (operation type) */ 975*f0865ec9SKyle Evans t = strchr(s, ' '); 976*f0865ec9SKyle Evans if (t == NULL) { 977*f0865ec9SKyle Evans printf("\nLine %lu: unable to find record #2\n", line); 978*f0865ec9SKyle Evans return -1; 979*f0865ec9SKyle Evans } 980*f0865ec9SKyle Evans *t = 0; /* mark end of record */ 981*f0865ec9SKyle Evans strncpy(op, s, sizeof(op) - 1); /* Copy opcode */ 982*f0865ec9SKyle Evans s = t + 1; /* jump to beginning of next record */ 983*f0865ec9SKyle Evans 984*f0865ec9SKyle Evans /* Pretty print the evolution of our tests */ 985*f0865ec9SKyle Evans if((line % 1000 == 0) && (line != 0)){ 986*f0865ec9SKyle Evans printf("\r%*s", 40, ""); 987*f0865ec9SKyle Evans printf("\rTest %lu on the go [%s]", line, op); 988*f0865ec9SKyle Evans fflush(stdout); 989*f0865ec9SKyle Evans } 990*f0865ec9SKyle Evans 991*f0865ec9SKyle Evans /* Find end of third record (str of types for next records) */ 992*f0865ec9SKyle Evans t = strchr(s, ' '); 993*f0865ec9SKyle Evans if (t == NULL) { 994*f0865ec9SKyle Evans printf("\nLine %lu: unable to find record #3\n", line); 995*f0865ec9SKyle Evans return -1; 996*f0865ec9SKyle Evans } 997*f0865ec9SKyle Evans *t = 0; /* mark end of record */ 998*f0865ec9SKyle Evans nrecs = (int)(t - s); 999*f0865ec9SKyle Evans 1000*f0865ec9SKyle Evans rec = t + 1; 1001*f0865ec9SKyle Evans ADD_TO_BACKTRACE("--------------\n"); 1002*f0865ec9SKyle Evans for (i = 0; i < nrecs; i++) { 1003*f0865ec9SKyle Evans /* Find end of record */ 1004*f0865ec9SKyle Evans t = strchr(rec, ' '); 1005*f0865ec9SKyle Evans if (t == NULL) { 1006*f0865ec9SKyle Evans t = ibuf + len; 1007*f0865ec9SKyle Evans } 1008*f0865ec9SKyle Evans *t = 0; 1009*f0865ec9SKyle Evans switch (s[i]) { 1010*f0865ec9SKyle Evans case 'c': /* fp_ctx */ 1011*f0865ec9SKyle Evans if (fp_ctx_local_cnt > 0) { 1012*f0865ec9SKyle Evans printf("\nLine %lu: Only one fp_ctx allowed\n", line); 1013*f0865ec9SKyle Evans ret = -1; 1014*f0865ec9SKyle Evans goto err; 1015*f0865ec9SKyle Evans } 1016*f0865ec9SKyle Evans /* 1017*f0865ec9SKyle Evans * We expect a 3 nn of the same size (p, r, r^2) 1018*f0865ec9SKyle Evans * followed by a single word providing mpinv 1019*f0865ec9SKyle Evans * and an additional nn and two words. 1020*f0865ec9SKyle Evans */ 1021*f0865ec9SKyle Evans assert(((t - rec) % 2) == 0); 1022*f0865ec9SKyle Evans nn_len = (unsigned int)(t - rec - 1023*f0865ec9SKyle Evans 3 * (WORD_BYTES * 2)) / 1024*f0865ec9SKyle Evans (2 * 4); 1025*f0865ec9SKyle Evans assert((nn_len % WORD_BYTES) == 0); 1026*f0865ec9SKyle Evans fp_ctx_local_cnt++; 1027*f0865ec9SKyle Evans tmp = &fp_ctx_modulus; 1028*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, (u8)(nn_len / WORD_BYTES)); EG(ret, err); 1029*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec, 2 * nn_len); EG(ret, err); 1030*f0865ec9SKyle Evans 1031*f0865ec9SKyle Evans /* Initialize fp context from the prime modulus */ 1032*f0865ec9SKyle Evans ret = fp_ctx_init_from_p(&fp_ctx_param, &fp_ctx_modulus); EG(ret, err); 1033*f0865ec9SKyle Evans /* Now get the other Fp context values and check that 1034*f0865ec9SKyle Evans * everything is OK 1035*f0865ec9SKyle Evans */ 1036*f0865ec9SKyle Evans tmp = &fp_ctx_r; 1037*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, (u8)(nn_len / WORD_BYTES)); EG(ret, err); 1038*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec + (2 * nn_len), 1039*f0865ec9SKyle Evans 2 * nn_len); EG(ret, err); 1040*f0865ec9SKyle Evans 1041*f0865ec9SKyle Evans /* Compare r */ 1042*f0865ec9SKyle Evans ret = nn_cmp(&fp_ctx_r, &(fp_ctx_param.r), &cmp); 1043*f0865ec9SKyle Evans if(ret || cmp){ 1044*f0865ec9SKyle Evans printf("\nLine %lu: Fp context import failed\n", line); 1045*f0865ec9SKyle Evans nn_print("Imported r from file =", &fp_ctx_r); 1046*f0865ec9SKyle Evans nn_print("Computed r from modulus=", &(fp_ctx_param.r)); 1047*f0865ec9SKyle Evans ret = -1; 1048*f0865ec9SKyle Evans goto err; 1049*f0865ec9SKyle Evans } 1050*f0865ec9SKyle Evans tmp = &fp_ctx_r_square; 1051*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, (u8)(nn_len / WORD_BYTES)); EG(ret, err); 1052*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec + (4 * nn_len), 1053*f0865ec9SKyle Evans 2 * nn_len); EG(ret, err); 1054*f0865ec9SKyle Evans 1055*f0865ec9SKyle Evans /* Compare r_square */ 1056*f0865ec9SKyle Evans ret = nn_cmp(&fp_ctx_r_square, &(fp_ctx_param.r_square), &cmp); 1057*f0865ec9SKyle Evans if(ret || cmp){ 1058*f0865ec9SKyle Evans printf("\nLine %lu: Fp context import failed\n", line); 1059*f0865ec9SKyle Evans nn_print("Imported r_square from file =", &fp_ctx_r_square); 1060*f0865ec9SKyle Evans nn_print("Computed r_square from modulus=", &(fp_ctx_param.r_square)); 1061*f0865ec9SKyle Evans ret = -1; 1062*f0865ec9SKyle Evans goto err; 1063*f0865ec9SKyle Evans } 1064*f0865ec9SKyle Evans tmp = &fp_ctx_mpinv; 1065*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, 1); EG(ret, err); 1066*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec + (6 * nn_len), 1067*f0865ec9SKyle Evans WORD_BYTES * 2); EG(ret, err); 1068*f0865ec9SKyle Evans 1069*f0865ec9SKyle Evans /* Compare mpinv */ 1070*f0865ec9SKyle Evans if(fp_ctx_mpinv.val[0] != fp_ctx_param.mpinv){ 1071*f0865ec9SKyle Evans printf("\nLine %lu: Fp context import failed\n", line); 1072*f0865ec9SKyle Evans printf("Imported mpinv from modulus=" PRINTF_WORD_HEX_FMT, fp_ctx_mpinv.val[0]); 1073*f0865ec9SKyle Evans printf("Computed mpiv from file =" PRINTF_WORD_HEX_FMT, fp_ctx_param.mpinv); 1074*f0865ec9SKyle Evans ret = -1; 1075*f0865ec9SKyle Evans goto err; 1076*f0865ec9SKyle Evans } 1077*f0865ec9SKyle Evans tmp = &fp_ctx_pshift; 1078*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, 1); EG(ret, err); 1079*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec + (6 * nn_len + 2 * WORD_BYTES), 1080*f0865ec9SKyle Evans WORD_BYTES * 2); EG(ret, err); 1081*f0865ec9SKyle Evans 1082*f0865ec9SKyle Evans /* Compare p_shift */ 1083*f0865ec9SKyle Evans if((bitcnt_t)fp_ctx_pshift.val[0] != fp_ctx_param.p_shift){ 1084*f0865ec9SKyle Evans printf("\nLine %lu: Fp context import failed\n", line); 1085*f0865ec9SKyle Evans printf("Imported mpinv from modulus=%d", (bitcnt_t)fp_ctx_pshift.val[0]); 1086*f0865ec9SKyle Evans printf("Computed mpiv from file =%d", fp_ctx_param.p_shift); 1087*f0865ec9SKyle Evans ret = -1; 1088*f0865ec9SKyle Evans goto err; 1089*f0865ec9SKyle Evans } 1090*f0865ec9SKyle Evans tmp = &fp_ctx_pnorm; 1091*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, (u8)(nn_len / WORD_BYTES)); EG(ret, err); 1092*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec + (6 * nn_len + 4 * WORD_BYTES), 1093*f0865ec9SKyle Evans nn_len * 2); EG(ret, err); 1094*f0865ec9SKyle Evans 1095*f0865ec9SKyle Evans /* Compare p_normalized */ 1096*f0865ec9SKyle Evans ret = nn_cmp(&fp_ctx_pnorm, &(fp_ctx_param.p_normalized), &cmp); 1097*f0865ec9SKyle Evans if(ret || (cmp != 0)){ 1098*f0865ec9SKyle Evans printf("\nLine %lu: Fp context import failed\n", line); 1099*f0865ec9SKyle Evans nn_print("Imported r_square from file =", &fp_ctx_pnorm); 1100*f0865ec9SKyle Evans nn_print("Computed r_square from modulus=", &(fp_ctx_param.p_normalized)); 1101*f0865ec9SKyle Evans return -1; 1102*f0865ec9SKyle Evans } 1103*f0865ec9SKyle Evans tmp = &fp_ctx_prec; 1104*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, 1); EG(ret, err); 1105*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec + (8 * nn_len + 4 * WORD_BYTES), 1106*f0865ec9SKyle Evans WORD_BYTES * 2); EG(ret, err); 1107*f0865ec9SKyle Evans 1108*f0865ec9SKyle Evans /* Compare p_reciprocal */ 1109*f0865ec9SKyle Evans if(fp_ctx_prec.val[0] != fp_ctx_param.p_reciprocal){ 1110*f0865ec9SKyle Evans printf("\nLine %lu: Fp context import failed\n", line); 1111*f0865ec9SKyle Evans printf("Imported mpinv from modulus=" PRINTF_WORD_HEX_FMT, fp_ctx_prec.val[0]); 1112*f0865ec9SKyle Evans printf("Computed mpiv from file =" PRINTF_WORD_HEX_FMT, fp_ctx_param.p_reciprocal); 1113*f0865ec9SKyle Evans ret = -1; 1114*f0865ec9SKyle Evans goto err; 1115*f0865ec9SKyle Evans } 1116*f0865ec9SKyle Evans params[i] = &fp_ctx_param; 1117*f0865ec9SKyle Evans ADD_TO_BACKTRACE("'c' param: %s\n", rec); 1118*f0865ec9SKyle Evans break; 1119*f0865ec9SKyle Evans case 'f': /* fp */ 1120*f0865ec9SKyle Evans if (fp_ctx_local_cnt != 1) { 1121*f0865ec9SKyle Evans printf("\nLine %lu: No fp_ctx available\n", line); 1122*f0865ec9SKyle Evans ret = -1; 1123*f0865ec9SKyle Evans goto err; 1124*f0865ec9SKyle Evans } 1125*f0865ec9SKyle Evans if (fp_local_cnt >= NUM_PRE_ALLOCATED_FP) { 1126*f0865ec9SKyle Evans printf("\nLine %lu: Not enough fp\n", 1127*f0865ec9SKyle Evans line); 1128*f0865ec9SKyle Evans ret = -1; 1129*f0865ec9SKyle Evans goto err; 1130*f0865ec9SKyle Evans } 1131*f0865ec9SKyle Evans assert(((t - rec) % 2) == 0); 1132*f0865ec9SKyle Evans nn_len = (unsigned int)(t - rec) / 2; 1133*f0865ec9SKyle Evans assert((nn_len / WORD_BYTES) <= 1134*f0865ec9SKyle Evans fp_ctx_param.p.wlen); 1135*f0865ec9SKyle Evans fp_tmp = fp_params_ptr[fp_local_cnt++]; 1136*f0865ec9SKyle Evans fp_tmp->ctx = &fp_ctx_param; 1137*f0865ec9SKyle Evans tmp = &(fp_tmp->fp_val); 1138*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, (u8)(nn_len / WORD_BYTES)); EG(ret, err); 1139*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec, 2 * nn_len); EG(ret, err); 1140*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, fp_ctx_param.p.wlen); EG(ret, err); 1141*f0865ec9SKyle Evans params[i] = fp_tmp; 1142*f0865ec9SKyle Evans ADD_TO_BACKTRACE("'f' param: %s\n", rec); 1143*f0865ec9SKyle Evans break; 1144*f0865ec9SKyle Evans case 'p': /* raw pointer value. Useful for NULL */ 1145*f0865ec9SKyle Evans p_tmp = strtoull(rec, NULL, 10); 1146*f0865ec9SKyle Evans params[i] = (void *)p_tmp; 1147*f0865ec9SKyle Evans ADD_TO_BACKTRACE("'p' param: %s\n", rec); 1148*f0865ec9SKyle Evans /* If this is not a NULL pointer, this is weird! 1149*f0865ec9SKyle Evans * Abort ... 1150*f0865ec9SKyle Evans */ 1151*f0865ec9SKyle Evans if(params[i] != NULL){ 1152*f0865ec9SKyle Evans printf("\nLine %lu: imported a pointer (type 'p') non NULL\n", 1153*f0865ec9SKyle Evans line); 1154*f0865ec9SKyle Evans ret = -1; 1155*f0865ec9SKyle Evans goto err; 1156*f0865ec9SKyle Evans } 1157*f0865ec9SKyle Evans break; 1158*f0865ec9SKyle Evans case 'n': /* nn */ 1159*f0865ec9SKyle Evans if (nn_local_cnt >= NUM_PRE_ALLOCATED_NN) { 1160*f0865ec9SKyle Evans printf("\nLine %lu: Not enough nn\n", 1161*f0865ec9SKyle Evans line); 1162*f0865ec9SKyle Evans return -1; 1163*f0865ec9SKyle Evans } 1164*f0865ec9SKyle Evans assert(((t - rec) % 2) == 0); 1165*f0865ec9SKyle Evans nn_len = (unsigned int)(t - rec) / 2; 1166*f0865ec9SKyle Evans assert((nn_len % WORD_BYTES) == 0); 1167*f0865ec9SKyle Evans tmp = nn_params_ptr[nn_local_cnt++]; 1168*f0865ec9SKyle Evans ret = nn_set_wlen(tmp, (u8)(nn_len / WORD_BYTES)); EG(ret, err); 1169*f0865ec9SKyle Evans ret = nn_import_from_hexbuf(tmp, rec, 2 * nn_len); EG(ret, err); 1170*f0865ec9SKyle Evans params[i] = tmp; 1171*f0865ec9SKyle Evans ADD_TO_BACKTRACE("'n' param: %s\n", rec); 1172*f0865ec9SKyle Evans break; 1173*f0865ec9SKyle Evans case 'u': /* unsigned long int (in base 10) */ 1174*f0865ec9SKyle Evans u_params[i] = (u64)strtoull(rec, NULL, 10); 1175*f0865ec9SKyle Evans params[i] = &u_params[i]; 1176*f0865ec9SKyle Evans ADD_TO_BACKTRACE("'u' param: %s\n", rec); 1177*f0865ec9SKyle Evans break; 1178*f0865ec9SKyle Evans case 's': /* signed long int (in base 10) */ 1179*f0865ec9SKyle Evans u_params[i] = (u64)strtoll(rec, NULL, 10); 1180*f0865ec9SKyle Evans params[i] = &u_params[i]; 1181*f0865ec9SKyle Evans ADD_TO_BACKTRACE("'s' param: %s\n", rec); 1182*f0865ec9SKyle Evans break; 1183*f0865ec9SKyle Evans default: 1184*f0865ec9SKyle Evans printf("\nUnknown record type '%c'\n", s[i]); 1185*f0865ec9SKyle Evans ret = -1; 1186*f0865ec9SKyle Evans goto err; 1187*f0865ec9SKyle Evans } 1188*f0865ec9SKyle Evans rec = t + 1; 1189*f0865ec9SKyle Evans } 1190*f0865ec9SKyle Evans /* Save current parameters format in the global variable */ 1191*f0865ec9SKyle Evans memcpy(global_parameters, s, LOCAL_MIN(nrecs, MAX_PARAMS)); 1192*f0865ec9SKyle Evans curr_test_fun = NULL; 1193*f0865ec9SKyle Evans FIND_FUN_IN_DISPATCH_TABLE(op, curr_test_fun); 1194*f0865ec9SKyle Evans if (curr_test_fun == NULL) { 1195*f0865ec9SKyle Evans printf("\nLine %lu: unknown opcode %s\n", line, op); 1196*f0865ec9SKyle Evans } else { 1197*f0865ec9SKyle Evans ADD_TO_BACKTRACE("\nLine %lu: testing opcode %s\n", line, op); 1198*f0865ec9SKyle Evans test_ret = curr_test_fun(op, params, (int)test_num); 1199*f0865ec9SKyle Evans if (test_ret == 1) { 1200*f0865ec9SKyle Evans ADD_TO_BACKTRACE("-- TEST OK ---\n"); 1201*f0865ec9SKyle Evans oktests += (unsigned long)test_ret; 1202*f0865ec9SKyle Evans } else { 1203*f0865ec9SKyle Evans ADD_TO_BACKTRACE("-- TEST NOK --\n"); 1204*f0865ec9SKyle Evans } 1205*f0865ec9SKyle Evans } 1206*f0865ec9SKyle Evans line += 1; 1207*f0865ec9SKyle Evans len = ibuflen; 1208*f0865ec9SKyle Evans nn_local_cnt = 0; 1209*f0865ec9SKyle Evans fp_local_cnt = 0; 1210*f0865ec9SKyle Evans fp_ctx_local_cnt = 0; 1211*f0865ec9SKyle Evans } 1212*f0865ec9SKyle Evans 1213*f0865ec9SKyle Evans printf("\n%lu/%lu tests passed successfully (%lu on error)\n", 1214*f0865ec9SKyle Evans oktests, line, line - oktests); 1215*f0865ec9SKyle Evans 1216*f0865ec9SKyle Evans if(fd != 0){ 1217*f0865ec9SKyle Evans close(fd); 1218*f0865ec9SKyle Evans } 1219*f0865ec9SKyle Evans if(ibuf != NULL){ 1220*f0865ec9SKyle Evans free(ibuf); 1221*f0865ec9SKyle Evans } 1222*f0865ec9SKyle Evans 1223*f0865ec9SKyle Evans return 0; 1224*f0865ec9SKyle Evans err: 1225*f0865ec9SKyle Evans printf("Error: critical error occured! Leaving ...\n"); 1226*f0865ec9SKyle Evans if(fd != 0){ 1227*f0865ec9SKyle Evans close(fd); 1228*f0865ec9SKyle Evans } 1229*f0865ec9SKyle Evans if(ibuf != NULL){ 1230*f0865ec9SKyle Evans free(ibuf); 1231*f0865ec9SKyle Evans } 1232*f0865ec9SKyle Evans return -1; 1233*f0865ec9SKyle Evans } 1234