1*6822f9c8Santon /* $OpenBSD: bn_word.c,v 1.2 2024/08/23 12:56:26 anton Exp $ */ 2e3cbfed8Sjsing /* 3e3cbfed8Sjsing * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> 4e3cbfed8Sjsing * 5e3cbfed8Sjsing * Permission to use, copy, modify, and distribute this software for any 6e3cbfed8Sjsing * purpose with or without fee is hereby granted, provided that the above 7e3cbfed8Sjsing * copyright notice and this permission notice appear in all copies. 8e3cbfed8Sjsing * 9e3cbfed8Sjsing * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10e3cbfed8Sjsing * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11e3cbfed8Sjsing * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12e3cbfed8Sjsing * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13e3cbfed8Sjsing * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14e3cbfed8Sjsing * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15e3cbfed8Sjsing * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16e3cbfed8Sjsing */ 17e3cbfed8Sjsing 18e3cbfed8Sjsing #include <err.h> 19e3cbfed8Sjsing #include <string.h> 20e3cbfed8Sjsing 21e3cbfed8Sjsing #include <openssl/bn.h> 22e3cbfed8Sjsing 23e3cbfed8Sjsing struct bn_word_test { 24e3cbfed8Sjsing const char *in_hex; 25e3cbfed8Sjsing BN_ULONG in_word; 26e3cbfed8Sjsing BN_ULONG mod_word; 27e3cbfed8Sjsing BN_ULONG out_word; 28e3cbfed8Sjsing const char *out_hex; 29e3cbfed8Sjsing int out_is_negative; 30e3cbfed8Sjsing }; 31e3cbfed8Sjsing 32e3cbfed8Sjsing static int 33e3cbfed8Sjsing check_bn_word_test(const char *op_name, const BIGNUM *bn, 34e3cbfed8Sjsing const struct bn_word_test *bwt) 35e3cbfed8Sjsing { 36e3cbfed8Sjsing char *out_hex = NULL; 37e3cbfed8Sjsing BN_ULONG out_word; 38e3cbfed8Sjsing int failed = 1; 39e3cbfed8Sjsing 40e3cbfed8Sjsing if ((out_word = BN_get_word(bn)) != bwt->out_word) { 41e3cbfed8Sjsing fprintf(stderr, "FAIL %s: Got word %lx, want %lx\n", 42e3cbfed8Sjsing op_name, (unsigned long)out_word, 43e3cbfed8Sjsing (unsigned long)bwt->out_word); 44e3cbfed8Sjsing goto failure; 45e3cbfed8Sjsing } 46e3cbfed8Sjsing 47e3cbfed8Sjsing if (BN_is_negative(bn) != bwt->out_is_negative) { 48e3cbfed8Sjsing fprintf(stderr, "FAIL %s: Got is negative %d, want %d\n", 49e3cbfed8Sjsing op_name, BN_is_negative(bn), bwt->out_is_negative); 50e3cbfed8Sjsing goto failure; 51e3cbfed8Sjsing } 52e3cbfed8Sjsing 53e3cbfed8Sjsing if ((out_hex = BN_bn2hex(bn)) == NULL) 54*6822f9c8Santon errx(1, "BN_bn2hex() failed"); 55e3cbfed8Sjsing 56e3cbfed8Sjsing if (strcmp(out_hex, bwt->out_hex) != 0) { 57e3cbfed8Sjsing fprintf(stderr, "FAIL %s: Got hex %s, want %s\n", 58e3cbfed8Sjsing op_name, out_hex, bwt->out_hex); 59e3cbfed8Sjsing goto failure; 60e3cbfed8Sjsing } 61e3cbfed8Sjsing 62e3cbfed8Sjsing if (BN_is_zero(bn) && BN_is_negative(bn) != 0) { 63e3cbfed8Sjsing fprintf(stderr, "FAIL %s: Got negative zero\n", op_name); 64e3cbfed8Sjsing goto failure; 65e3cbfed8Sjsing } 66e3cbfed8Sjsing 67e3cbfed8Sjsing failed = 0; 68e3cbfed8Sjsing 69e3cbfed8Sjsing failure: 70e3cbfed8Sjsing free(out_hex); 71e3cbfed8Sjsing 72e3cbfed8Sjsing return failed; 73e3cbfed8Sjsing } 74e3cbfed8Sjsing 75e3cbfed8Sjsing static int 76e3cbfed8Sjsing test_bn_word(int (*bn_word_op)(BIGNUM *, BN_ULONG), const char *op_name, 77e3cbfed8Sjsing const struct bn_word_test *bwts, size_t num_tests) 78e3cbfed8Sjsing { 79e3cbfed8Sjsing const struct bn_word_test *bwt; 80e3cbfed8Sjsing BIGNUM *bn; 81e3cbfed8Sjsing size_t i; 82e3cbfed8Sjsing int failed = 0; 83e3cbfed8Sjsing 84e3cbfed8Sjsing if ((bn = BN_new()) == NULL) 85*6822f9c8Santon errx(1, "BN_new() failed"); 86e3cbfed8Sjsing 87e3cbfed8Sjsing for (i = 0; i < num_tests; i++) { 88e3cbfed8Sjsing bwt = &bwts[i]; 89e3cbfed8Sjsing 90e3cbfed8Sjsing if (!BN_hex2bn(&bn, bwt->in_hex)) { 91e3cbfed8Sjsing fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n", 92e3cbfed8Sjsing bwt->in_hex); 93e3cbfed8Sjsing failed = 1; 94e3cbfed8Sjsing continue; 95e3cbfed8Sjsing } 96e3cbfed8Sjsing 97e3cbfed8Sjsing if (!bn_word_op(bn, bwt->in_word)) { 98e3cbfed8Sjsing fprintf(stderr, "FAIL: %s(%lx) failed\n", op_name, 99e3cbfed8Sjsing (unsigned long)bwt->in_word); 100e3cbfed8Sjsing failed = 1; 101e3cbfed8Sjsing continue; 102e3cbfed8Sjsing } 103e3cbfed8Sjsing 104e3cbfed8Sjsing failed |= check_bn_word_test(op_name, bn, bwt); 105e3cbfed8Sjsing } 106e3cbfed8Sjsing 107e3cbfed8Sjsing BN_free(bn); 108e3cbfed8Sjsing 109e3cbfed8Sjsing return failed; 110e3cbfed8Sjsing } 111e3cbfed8Sjsing 112e3cbfed8Sjsing static const struct bn_word_test bn_add_word_tests[] = { 113e3cbfed8Sjsing { 114e3cbfed8Sjsing .in_hex = "1", 115e3cbfed8Sjsing .in_word = 0, 116e3cbfed8Sjsing .out_word = 1, 117e3cbfed8Sjsing .out_hex = "01", 118e3cbfed8Sjsing }, 119e3cbfed8Sjsing { 120e3cbfed8Sjsing .in_hex = "0", 121e3cbfed8Sjsing .in_word = 1, 122e3cbfed8Sjsing .out_word = 1, 123e3cbfed8Sjsing .out_hex = "01", 124e3cbfed8Sjsing }, 125e3cbfed8Sjsing { 126e3cbfed8Sjsing .in_hex = "1", 127e3cbfed8Sjsing .in_word = 1, 128e3cbfed8Sjsing .out_word = 2, 129e3cbfed8Sjsing .out_hex = "02", 130e3cbfed8Sjsing }, 131e3cbfed8Sjsing { 132e3cbfed8Sjsing .in_hex = "-1", 133e3cbfed8Sjsing .in_word = 2, 134e3cbfed8Sjsing .out_word = 1, 135e3cbfed8Sjsing .out_hex = "01", 136e3cbfed8Sjsing }, 137e3cbfed8Sjsing { 138e3cbfed8Sjsing .in_hex = "-1", 139e3cbfed8Sjsing .in_word = 1, 140e3cbfed8Sjsing .out_word = 0, 141e3cbfed8Sjsing .out_hex = "0", 142e3cbfed8Sjsing }, 143e3cbfed8Sjsing { 144e3cbfed8Sjsing .in_hex = "-3", 145e3cbfed8Sjsing .in_word = 2, 146e3cbfed8Sjsing .out_word = 1, 147e3cbfed8Sjsing .out_hex = "-01", 148e3cbfed8Sjsing .out_is_negative = 1, 149e3cbfed8Sjsing }, 150e3cbfed8Sjsing { 151e3cbfed8Sjsing .in_hex = "1", 152e3cbfed8Sjsing .in_word = 0xfffffffeUL, 153e3cbfed8Sjsing .out_word = 0xffffffffUL, 154e3cbfed8Sjsing .out_hex = "FFFFFFFF", 155e3cbfed8Sjsing }, 156e3cbfed8Sjsing { 157e3cbfed8Sjsing .in_hex = "FFFFFFFFFFFFFFFF", 158e3cbfed8Sjsing .in_word = 1, 159e3cbfed8Sjsing .out_word = BN_MASK2, 160e3cbfed8Sjsing .out_hex = "010000000000000000", 161e3cbfed8Sjsing }, 162e3cbfed8Sjsing }; 163e3cbfed8Sjsing 164e3cbfed8Sjsing #define N_BN_ADD_WORD_TESTS \ 165e3cbfed8Sjsing (sizeof(bn_add_word_tests) / sizeof(bn_add_word_tests[0])) 166e3cbfed8Sjsing 167e3cbfed8Sjsing static int 168e3cbfed8Sjsing test_bn_add_word(void) 169e3cbfed8Sjsing { 170e3cbfed8Sjsing return test_bn_word(BN_add_word, "BN_add_word", bn_add_word_tests, 171e3cbfed8Sjsing N_BN_ADD_WORD_TESTS); 172e3cbfed8Sjsing } 173e3cbfed8Sjsing 174e3cbfed8Sjsing static const struct bn_word_test bn_sub_word_tests[] = { 175e3cbfed8Sjsing { 176e3cbfed8Sjsing .in_hex = "1", 177e3cbfed8Sjsing .in_word = 0, 178e3cbfed8Sjsing .out_word = 1, 179e3cbfed8Sjsing .out_hex = "01", 180e3cbfed8Sjsing }, 181e3cbfed8Sjsing { 182e3cbfed8Sjsing .in_hex = "0", 183e3cbfed8Sjsing .in_word = 1, 184e3cbfed8Sjsing .out_word = 1, 185e3cbfed8Sjsing .out_hex = "-01", 186e3cbfed8Sjsing .out_is_negative = 1, 187e3cbfed8Sjsing }, 188e3cbfed8Sjsing { 189e3cbfed8Sjsing .in_hex = "1", 190e3cbfed8Sjsing .in_word = 1, 191e3cbfed8Sjsing .out_word = 0, 192e3cbfed8Sjsing .out_hex = "0", 193e3cbfed8Sjsing }, 194e3cbfed8Sjsing { 195e3cbfed8Sjsing .in_hex = "2", 196e3cbfed8Sjsing .in_word = 1, 197e3cbfed8Sjsing .out_word = 1, 198e3cbfed8Sjsing .out_hex = "01", 199e3cbfed8Sjsing }, 200e3cbfed8Sjsing { 201e3cbfed8Sjsing .in_hex = "-1", 202e3cbfed8Sjsing .in_word = 2, 203e3cbfed8Sjsing .out_word = 3, 204e3cbfed8Sjsing .out_hex = "-03", 205e3cbfed8Sjsing .out_is_negative = 1, 206e3cbfed8Sjsing }, 207e3cbfed8Sjsing { 208e3cbfed8Sjsing .in_hex = "1", 209e3cbfed8Sjsing .in_word = 1, 210e3cbfed8Sjsing .out_word = 0, 211e3cbfed8Sjsing .out_hex = "0", 212e3cbfed8Sjsing }, 213e3cbfed8Sjsing { 214e3cbfed8Sjsing .in_hex = "3", 215e3cbfed8Sjsing .in_word = 2, 216e3cbfed8Sjsing .out_word = 1, 217e3cbfed8Sjsing .out_hex = "01", 218e3cbfed8Sjsing }, 219e3cbfed8Sjsing { 220e3cbfed8Sjsing .in_hex = "-3", 221e3cbfed8Sjsing .in_word = 2, 222e3cbfed8Sjsing .out_word = 5, 223e3cbfed8Sjsing .out_hex = "-05", 224e3cbfed8Sjsing .out_is_negative = 1, 225e3cbfed8Sjsing }, 226e3cbfed8Sjsing { 227e3cbfed8Sjsing .in_hex = "-1", 228e3cbfed8Sjsing .in_word = 0xfffffffeUL, 229e3cbfed8Sjsing .out_word = 0xffffffffUL, 230e3cbfed8Sjsing .out_hex = "-FFFFFFFF", 231e3cbfed8Sjsing .out_is_negative = 1, 232e3cbfed8Sjsing }, 233e3cbfed8Sjsing { 234e3cbfed8Sjsing .in_hex = "010000000000000000", 235e3cbfed8Sjsing .in_word = 1, 236e3cbfed8Sjsing .out_word = BN_MASK2, 237e3cbfed8Sjsing .out_hex = "FFFFFFFFFFFFFFFF", 238e3cbfed8Sjsing }, 239e3cbfed8Sjsing }; 240e3cbfed8Sjsing 241e3cbfed8Sjsing #define N_BN_SUB_WORD_TESTS \ 242e3cbfed8Sjsing (sizeof(bn_sub_word_tests) / sizeof(bn_sub_word_tests[0])) 243e3cbfed8Sjsing 244e3cbfed8Sjsing static int 245e3cbfed8Sjsing test_bn_sub_word(void) 246e3cbfed8Sjsing { 247e3cbfed8Sjsing return test_bn_word(BN_sub_word, "BN_sub_word", bn_sub_word_tests, 248e3cbfed8Sjsing N_BN_SUB_WORD_TESTS); 249e3cbfed8Sjsing } 250e3cbfed8Sjsing 251e3cbfed8Sjsing static const struct bn_word_test bn_mul_word_tests[] = { 252e3cbfed8Sjsing { 253e3cbfed8Sjsing .in_hex = "1", 254e3cbfed8Sjsing .in_word = 0, 255e3cbfed8Sjsing .out_word = 0, 256e3cbfed8Sjsing .out_hex = "0", 257e3cbfed8Sjsing }, 258e3cbfed8Sjsing { 259e3cbfed8Sjsing .in_hex = "0", 260e3cbfed8Sjsing .in_word = 1, 261e3cbfed8Sjsing .out_word = 0, 262e3cbfed8Sjsing .out_hex = "0", 263e3cbfed8Sjsing }, 264e3cbfed8Sjsing { 265e3cbfed8Sjsing .in_hex = "1", 266e3cbfed8Sjsing .in_word = 1, 267e3cbfed8Sjsing .out_word = 1, 268e3cbfed8Sjsing .out_hex = "01", 269e3cbfed8Sjsing }, 270e3cbfed8Sjsing { 271e3cbfed8Sjsing .in_hex = "-1", 272e3cbfed8Sjsing .in_word = 0, 273e3cbfed8Sjsing .out_word = 0, 274e3cbfed8Sjsing .out_hex = "0", 275e3cbfed8Sjsing }, 276e3cbfed8Sjsing { 277e3cbfed8Sjsing .in_hex = "-1", 278e3cbfed8Sjsing .in_word = 1, 279e3cbfed8Sjsing .out_word = 1, 280e3cbfed8Sjsing .out_hex = "-01", 281e3cbfed8Sjsing .out_is_negative = 1, 282e3cbfed8Sjsing }, 283e3cbfed8Sjsing { 284e3cbfed8Sjsing .in_hex = "-3", 285e3cbfed8Sjsing .in_word = 2, 286e3cbfed8Sjsing .out_word = 6, 287e3cbfed8Sjsing .out_hex = "-06", 288e3cbfed8Sjsing .out_is_negative = 1, 289e3cbfed8Sjsing }, 290e3cbfed8Sjsing { 291e3cbfed8Sjsing .in_hex = "1", 292e3cbfed8Sjsing .in_word = 0xfffffffeUL, 293e3cbfed8Sjsing .out_word = 0xfffffffeUL, 294e3cbfed8Sjsing .out_hex = "FFFFFFFE", 295e3cbfed8Sjsing }, 296e3cbfed8Sjsing { 297e3cbfed8Sjsing .in_hex = "010000000000000000", 298e3cbfed8Sjsing .in_word = 2, 299e3cbfed8Sjsing .out_word = BN_MASK2, 300e3cbfed8Sjsing .out_hex = "020000000000000000", 301e3cbfed8Sjsing }, 302e3cbfed8Sjsing }; 303e3cbfed8Sjsing 304e3cbfed8Sjsing #define N_BN_MUL_WORD_TESTS \ 305e3cbfed8Sjsing (sizeof(bn_mul_word_tests) / sizeof(bn_mul_word_tests[0])) 306e3cbfed8Sjsing 307e3cbfed8Sjsing static int 308e3cbfed8Sjsing test_bn_mul_word(void) 309e3cbfed8Sjsing { 310e3cbfed8Sjsing return test_bn_word(BN_mul_word, "BN_mul_word", bn_mul_word_tests, 311e3cbfed8Sjsing N_BN_MUL_WORD_TESTS); 312e3cbfed8Sjsing } 313e3cbfed8Sjsing 314e3cbfed8Sjsing static const struct bn_word_test bn_div_word_tests[] = { 315e3cbfed8Sjsing { 316e3cbfed8Sjsing .in_hex = "1", 317e3cbfed8Sjsing .in_word = 0, 318e3cbfed8Sjsing .mod_word = BN_MASK2, 319e3cbfed8Sjsing .out_word = 1, 320e3cbfed8Sjsing .out_hex = "01", 321e3cbfed8Sjsing }, 322e3cbfed8Sjsing { 323e3cbfed8Sjsing .in_hex = "0", 324e3cbfed8Sjsing .in_word = 1, 325e3cbfed8Sjsing .mod_word = 0, 326e3cbfed8Sjsing .out_word = 0, 327e3cbfed8Sjsing .out_hex = "0", 328e3cbfed8Sjsing }, 329e3cbfed8Sjsing { 330e3cbfed8Sjsing .in_hex = "4", 331e3cbfed8Sjsing .in_word = 2, 332e3cbfed8Sjsing .mod_word = 0, 333e3cbfed8Sjsing .out_word = 2, 334e3cbfed8Sjsing .out_hex = "02", 335e3cbfed8Sjsing }, 336e3cbfed8Sjsing { 337e3cbfed8Sjsing .in_hex = "7", 338e3cbfed8Sjsing .in_word = 3, 339e3cbfed8Sjsing .mod_word = 1, 340e3cbfed8Sjsing .out_word = 2, 341e3cbfed8Sjsing .out_hex = "02", 342e3cbfed8Sjsing }, 343e3cbfed8Sjsing { 344e3cbfed8Sjsing .in_hex = "1", 345e3cbfed8Sjsing .in_word = 1, 346e3cbfed8Sjsing .mod_word = 0, 347e3cbfed8Sjsing .out_word = 1, 348e3cbfed8Sjsing .out_hex = "01", 349e3cbfed8Sjsing }, 350e3cbfed8Sjsing { 351e3cbfed8Sjsing .in_hex = "-2", 352e3cbfed8Sjsing .in_word = 1, 353e3cbfed8Sjsing .mod_word = 0, 354e3cbfed8Sjsing .out_word = 2, 355e3cbfed8Sjsing .out_hex = "-02", 356e3cbfed8Sjsing .out_is_negative = 1, 357e3cbfed8Sjsing }, 358e3cbfed8Sjsing { 359e3cbfed8Sjsing .in_hex = "-1", 360e3cbfed8Sjsing .in_word = 2, 361e3cbfed8Sjsing .mod_word = 1, 362e3cbfed8Sjsing .out_word = 0, 363e3cbfed8Sjsing .out_hex = "0", 364e3cbfed8Sjsing }, 365e3cbfed8Sjsing { 366e3cbfed8Sjsing .in_hex = "-3", 367e3cbfed8Sjsing .in_word = 2, 368e3cbfed8Sjsing .mod_word = 1, 369e3cbfed8Sjsing .out_word = 1, 370e3cbfed8Sjsing .out_hex = "-01", 371e3cbfed8Sjsing .out_is_negative = 1, 372e3cbfed8Sjsing }, 373e3cbfed8Sjsing { 374e3cbfed8Sjsing .in_hex = "1", 375e3cbfed8Sjsing .in_word = 0xffffffffUL, 376e3cbfed8Sjsing .mod_word = 1, 377e3cbfed8Sjsing .out_word = 0, 378e3cbfed8Sjsing .out_hex = "0", 379e3cbfed8Sjsing }, 380e3cbfed8Sjsing { 381e3cbfed8Sjsing .in_hex = "FFFFFFFF", 382e3cbfed8Sjsing .in_word = 1, 383e3cbfed8Sjsing .mod_word = 0, 384e3cbfed8Sjsing .out_word = 0xffffffffUL, 385e3cbfed8Sjsing .out_hex = "FFFFFFFF", 386e3cbfed8Sjsing }, 387e3cbfed8Sjsing { 388e3cbfed8Sjsing .in_hex = "FFFFFFFE", 389e3cbfed8Sjsing .in_word = 0xffffffffUL, 390e3cbfed8Sjsing .mod_word = 0xfffffffeUL, 391e3cbfed8Sjsing .out_word = 0, 392e3cbfed8Sjsing .out_hex = "0", 393e3cbfed8Sjsing }, 394e3cbfed8Sjsing { 395e3cbfed8Sjsing .in_hex = "FFFFFFFFFFFFFFFF", 396e3cbfed8Sjsing .in_word = 1, 397e3cbfed8Sjsing .mod_word = 0, 398e3cbfed8Sjsing .out_word = BN_MASK2, 399e3cbfed8Sjsing .out_hex = "FFFFFFFFFFFFFFFF", 400e3cbfed8Sjsing }, 401e3cbfed8Sjsing { 402e3cbfed8Sjsing .in_hex = "FFFFFFFF", 403e3cbfed8Sjsing .in_word = 0xff, 404e3cbfed8Sjsing .mod_word = 0, 405e3cbfed8Sjsing .out_word = 0x1010101UL, 406e3cbfed8Sjsing .out_hex = "01010101", 407e3cbfed8Sjsing }, 408e3cbfed8Sjsing { 409e3cbfed8Sjsing .in_hex = "FFFFFFFF", 410e3cbfed8Sjsing .in_word = 0x10, 411e3cbfed8Sjsing .mod_word = 0xf, 412e3cbfed8Sjsing .out_word = 0xfffffffUL, 413e3cbfed8Sjsing .out_hex = "0FFFFFFF", 414e3cbfed8Sjsing }, 415e3cbfed8Sjsing }; 416e3cbfed8Sjsing 417e3cbfed8Sjsing #define N_BN_DIV_WORD_TESTS \ 418e3cbfed8Sjsing (sizeof(bn_div_word_tests) / sizeof(bn_div_word_tests[0])) 419e3cbfed8Sjsing 420e3cbfed8Sjsing static int 421e3cbfed8Sjsing test_bn_div_word(void) 422e3cbfed8Sjsing { 423e3cbfed8Sjsing const char *op_name = "BN_div_word"; 424e3cbfed8Sjsing const struct bn_word_test *bwt; 425e3cbfed8Sjsing BN_ULONG mod_word; 426e3cbfed8Sjsing BIGNUM *bn; 427e3cbfed8Sjsing size_t i; 428e3cbfed8Sjsing int failed = 0; 429e3cbfed8Sjsing 430e3cbfed8Sjsing if ((bn = BN_new()) == NULL) 431*6822f9c8Santon errx(1, "BN_new() failed"); 432e3cbfed8Sjsing 433e3cbfed8Sjsing for (i = 0; i < N_BN_DIV_WORD_TESTS; i++) { 434e3cbfed8Sjsing bwt = &bn_div_word_tests[i]; 435e3cbfed8Sjsing 436e3cbfed8Sjsing if (!BN_hex2bn(&bn, bwt->in_hex)) { 437e3cbfed8Sjsing fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n", 438e3cbfed8Sjsing bwt->in_hex); 439e3cbfed8Sjsing failed = 1; 440e3cbfed8Sjsing continue; 441e3cbfed8Sjsing } 442e3cbfed8Sjsing 443e3cbfed8Sjsing if ((mod_word = BN_div_word(bn, bwt->in_word)) != bwt->mod_word) { 444e3cbfed8Sjsing fprintf(stderr, "FAIL %s: Got mod word %lx, want %lx\n", 445e3cbfed8Sjsing op_name, (unsigned long)mod_word, 446e3cbfed8Sjsing (unsigned long)bwt->mod_word); 447e3cbfed8Sjsing failed = 1; 448e3cbfed8Sjsing continue; 449e3cbfed8Sjsing } 450e3cbfed8Sjsing 451e3cbfed8Sjsing failed |= check_bn_word_test(op_name, bn, bwt); 452e3cbfed8Sjsing } 453e3cbfed8Sjsing 454e3cbfed8Sjsing BN_free(bn); 455e3cbfed8Sjsing 456e3cbfed8Sjsing return failed; 457e3cbfed8Sjsing } 458e3cbfed8Sjsing 459e3cbfed8Sjsing static const struct bn_word_test bn_mod_word_tests[] = { 460e3cbfed8Sjsing { 461e3cbfed8Sjsing .in_hex = "1", 462e3cbfed8Sjsing .in_word = 0, 463e3cbfed8Sjsing .mod_word = BN_MASK2, 464e3cbfed8Sjsing .out_word = 1, 465e3cbfed8Sjsing .out_hex = "01", 466e3cbfed8Sjsing }, 467e3cbfed8Sjsing { 468e3cbfed8Sjsing .in_hex = "0", 469e3cbfed8Sjsing .in_word = 1, 470e3cbfed8Sjsing .mod_word = 0, 471e3cbfed8Sjsing .out_word = 0, 472e3cbfed8Sjsing .out_hex = "0", 473e3cbfed8Sjsing }, 474e3cbfed8Sjsing { 475e3cbfed8Sjsing .in_hex = "4", 476e3cbfed8Sjsing .in_word = 2, 477e3cbfed8Sjsing .mod_word = 0, 478e3cbfed8Sjsing .out_word = 4, 479e3cbfed8Sjsing .out_hex = "04", 480e3cbfed8Sjsing }, 481e3cbfed8Sjsing { 482e3cbfed8Sjsing .in_hex = "7", 483e3cbfed8Sjsing .in_word = 3, 484e3cbfed8Sjsing .mod_word = 1, 485e3cbfed8Sjsing .out_word = 7, 486e3cbfed8Sjsing .out_hex = "07", 487e3cbfed8Sjsing }, 488e3cbfed8Sjsing { 489e3cbfed8Sjsing .in_hex = "1", 490e3cbfed8Sjsing .in_word = 1, 491e3cbfed8Sjsing .mod_word = 0, 492e3cbfed8Sjsing .out_word = 1, 493e3cbfed8Sjsing .out_hex = "01", 494e3cbfed8Sjsing }, 495e3cbfed8Sjsing { 496e3cbfed8Sjsing .in_hex = "-2", 497e3cbfed8Sjsing .in_word = 1, 498e3cbfed8Sjsing .mod_word = 0, 499e3cbfed8Sjsing .out_word = 2, 500e3cbfed8Sjsing .out_hex = "-02", 501e3cbfed8Sjsing .out_is_negative = 1, 502e3cbfed8Sjsing }, 503e3cbfed8Sjsing { 504e3cbfed8Sjsing .in_hex = "-1", 505e3cbfed8Sjsing .in_word = 2, 506e3cbfed8Sjsing .mod_word = 1, 507e3cbfed8Sjsing .out_word = 1, 508e3cbfed8Sjsing .out_hex = "-01", 509e3cbfed8Sjsing .out_is_negative = 1, 510e3cbfed8Sjsing }, 511e3cbfed8Sjsing { 512e3cbfed8Sjsing .in_hex = "-3", 513e3cbfed8Sjsing .in_word = 2, 514e3cbfed8Sjsing .mod_word = 1, 515e3cbfed8Sjsing .out_word = 3, 516e3cbfed8Sjsing .out_hex = "-03", 517e3cbfed8Sjsing .out_is_negative = 1, 518e3cbfed8Sjsing }, 519e3cbfed8Sjsing { 520e3cbfed8Sjsing .in_hex = "1", 521e3cbfed8Sjsing .in_word = 0xffffffffUL, 522e3cbfed8Sjsing .mod_word = 1, 523e3cbfed8Sjsing .out_word = 1, 524e3cbfed8Sjsing .out_hex = "01", 525e3cbfed8Sjsing }, 526e3cbfed8Sjsing { 527e3cbfed8Sjsing .in_hex = "FFFFFFFF", 528e3cbfed8Sjsing .in_word = 1, 529e3cbfed8Sjsing .mod_word = 0, 530e3cbfed8Sjsing .out_word = 0xffffffffUL, 531e3cbfed8Sjsing .out_hex = "FFFFFFFF", 532e3cbfed8Sjsing }, 533e3cbfed8Sjsing { 534e3cbfed8Sjsing .in_hex = "FFFFFFFE", 535e3cbfed8Sjsing .in_word = 0xffffffffUL, 536e3cbfed8Sjsing .mod_word = 0xfffffffeUL, 537e3cbfed8Sjsing .out_word = 0xfffffffeUL, 538e3cbfed8Sjsing .out_hex = "FFFFFFFE", 539e3cbfed8Sjsing }, 540e3cbfed8Sjsing { 541e3cbfed8Sjsing .in_hex = "FFFFFFFFFFFFFFFF", 542e3cbfed8Sjsing .in_word = 1, 543e3cbfed8Sjsing .mod_word = 0, 544e3cbfed8Sjsing .out_word = BN_MASK2, 545e3cbfed8Sjsing .out_hex = "FFFFFFFFFFFFFFFF", 546e3cbfed8Sjsing }, 547e3cbfed8Sjsing { 548e3cbfed8Sjsing .in_hex = "FFFFFFFF", 549e3cbfed8Sjsing .in_word = 0xff, 550e3cbfed8Sjsing .mod_word = 0, 551e3cbfed8Sjsing .out_word = 0xffffffff, 552e3cbfed8Sjsing .out_hex = "FFFFFFFF", 553e3cbfed8Sjsing }, 554e3cbfed8Sjsing { 555e3cbfed8Sjsing .in_hex = "FFFFFFFF", 556e3cbfed8Sjsing .in_word = 0x10, 557e3cbfed8Sjsing .mod_word = 0xf, 558e3cbfed8Sjsing .out_word = 0xffffffffUL, 559e3cbfed8Sjsing .out_hex = "FFFFFFFF", 560e3cbfed8Sjsing }, 561e3cbfed8Sjsing }; 562e3cbfed8Sjsing 563e3cbfed8Sjsing #define N_BN_MOD_WORD_TESTS \ 564e3cbfed8Sjsing (sizeof(bn_mod_word_tests) / sizeof(bn_mod_word_tests[0])) 565e3cbfed8Sjsing 566e3cbfed8Sjsing static int 567e3cbfed8Sjsing test_bn_mod_word(void) 568e3cbfed8Sjsing { 569e3cbfed8Sjsing const char *op_name = "BN_mod_word"; 570e3cbfed8Sjsing const struct bn_word_test *bwt; 571e3cbfed8Sjsing BN_ULONG mod_word; 572e3cbfed8Sjsing BIGNUM *bn; 573e3cbfed8Sjsing size_t i; 574e3cbfed8Sjsing int failed = 0; 575e3cbfed8Sjsing 576e3cbfed8Sjsing if ((bn = BN_new()) == NULL) 577*6822f9c8Santon errx(1, "BN_new() failed"); 578e3cbfed8Sjsing 579e3cbfed8Sjsing for (i = 0; i < N_BN_MOD_WORD_TESTS; i++) { 580e3cbfed8Sjsing bwt = &bn_mod_word_tests[i]; 581e3cbfed8Sjsing 582e3cbfed8Sjsing if (!BN_hex2bn(&bn, bwt->in_hex)) { 583e3cbfed8Sjsing fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n", 584e3cbfed8Sjsing bwt->in_hex); 585e3cbfed8Sjsing failed = 1; 586e3cbfed8Sjsing continue; 587e3cbfed8Sjsing } 588e3cbfed8Sjsing 589e3cbfed8Sjsing if ((mod_word = BN_mod_word(bn, bwt->in_word)) != bwt->mod_word) { 590e3cbfed8Sjsing fprintf(stderr, "FAIL %s: Got mod word %lx, want %lx\n", 591e3cbfed8Sjsing op_name, (unsigned long)mod_word, 592e3cbfed8Sjsing (unsigned long)bwt->mod_word); 593e3cbfed8Sjsing failed = 1; 594e3cbfed8Sjsing continue; 595e3cbfed8Sjsing } 596e3cbfed8Sjsing 597e3cbfed8Sjsing failed |= check_bn_word_test(op_name, bn, bwt); 598e3cbfed8Sjsing } 599e3cbfed8Sjsing 600e3cbfed8Sjsing BN_free(bn); 601e3cbfed8Sjsing 602e3cbfed8Sjsing return failed; 603e3cbfed8Sjsing } 604e3cbfed8Sjsing 605e3cbfed8Sjsing int 606e3cbfed8Sjsing main(int argc, char **argv) 607e3cbfed8Sjsing { 608e3cbfed8Sjsing int failed = 0; 609e3cbfed8Sjsing 610e3cbfed8Sjsing failed |= test_bn_add_word(); 611e3cbfed8Sjsing failed |= test_bn_sub_word(); 612e3cbfed8Sjsing failed |= test_bn_mul_word(); 613e3cbfed8Sjsing failed |= test_bn_div_word(); 614e3cbfed8Sjsing failed |= test_bn_mod_word(); 615e3cbfed8Sjsing 616e3cbfed8Sjsing return failed; 617e3cbfed8Sjsing } 618