1 /* $NetBSD: test_bn.c,v 1.1.1.1 2011/04/13 18:14:51 elric Exp $ */ 2 3 /* 4 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <config.h> 37 38 #include <sys/types.h> 39 #include <limits.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 44 #include <bn.h> 45 #include <rand.h> 46 47 static int 48 set_get(unsigned long num) 49 { 50 BIGNUM *bn; 51 52 bn = BN_new(); 53 if (!BN_set_word(bn, num)) 54 return 1; 55 56 if (BN_get_word(bn) != num) 57 return 1; 58 59 BN_free(bn); 60 return 0; 61 } 62 63 #define CHECK(x) do { ret += x; } while(0) 64 65 static int 66 test_BN_set_get(void) 67 { 68 int ret = 0; 69 CHECK(set_get(0)); 70 CHECK(set_get(1)); 71 CHECK(set_get(0xff)); 72 CHECK(set_get(0x1ff)); 73 CHECK(set_get(0xffff)); 74 CHECK(set_get(0xf000)); 75 CHECK(set_get(ULONG_MAX / 2)); 76 CHECK(set_get(ULONG_MAX - 1)); 77 78 return ret; 79 } 80 81 static int 82 test_BN_bit(void) 83 { 84 BIGNUM *bn; 85 int ret = 0; 86 87 bn = BN_new(); 88 89 /* test setting and getting of "word" */ 90 if (!BN_set_word(bn, 1)) 91 return 1; 92 if (!BN_is_bit_set(bn, 0)) 93 ret += 1; 94 if (!BN_is_bit_set(bn, 0)) 95 ret += 1; 96 97 if (!BN_set_word(bn, 2)) 98 return 1; 99 if (!BN_is_bit_set(bn, 1)) 100 ret += 1; 101 102 if (!BN_set_word(bn, 3)) 103 return 1; 104 if (!BN_is_bit_set(bn, 0)) 105 ret += 1; 106 if (!BN_is_bit_set(bn, 1)) 107 ret += 1; 108 109 if (!BN_set_word(bn, 0x100)) 110 return 1; 111 if (!BN_is_bit_set(bn, 8)) 112 ret += 1; 113 114 if (!BN_set_word(bn, 0x1000)) 115 return 1; 116 if (!BN_is_bit_set(bn, 12)) 117 ret += 1; 118 119 /* test bitsetting */ 120 if (!BN_set_word(bn, 1)) 121 return 1; 122 if (!BN_set_bit(bn, 1)) 123 return 1; 124 if (BN_get_word(bn) != 3) 125 return 1; 126 if (!BN_clear_bit(bn, 0)) 127 return 1; 128 if (BN_get_word(bn) != 2) 129 return 1; 130 131 /* test bitsetting past end of current end */ 132 BN_clear(bn); 133 if (!BN_set_bit(bn, 12)) 134 return 1; 135 if (BN_get_word(bn) != 0x1000) 136 return 1; 137 138 /* test bit and byte counting functions */ 139 if (BN_num_bits(bn) != 13) 140 return 1; 141 if (BN_num_bytes(bn) != 2) 142 return 1; 143 144 BN_free(bn); 145 return ret; 146 } 147 148 struct ietest { 149 char *data; 150 size_t len; 151 unsigned long num; 152 } ietests[] = { 153 { "", 0, 0 }, 154 { "\x01", 1, 1 }, 155 { "\x02", 1, 2 }, 156 { "\xf2", 1, 0xf2 }, 157 { "\x01\x00", 2, 256 } 158 }; 159 160 static int 161 test_BN_import_export(void) 162 { 163 BIGNUM *bn; 164 int ret = 0; 165 int i; 166 167 bn = BN_new(); 168 169 for (i = 0; i < sizeof(ietests)/sizeof(ietests[0]); i++) { 170 size_t len; 171 unsigned char *p; 172 if (!BN_bin2bn((unsigned char*)ietests[i].data, ietests[i].len, bn)) 173 return 1; 174 if (BN_get_word(bn) != ietests[i].num) 175 return 1; 176 len = BN_num_bytes(bn); 177 if (len != ietests[i].len) 178 return 1; 179 p = malloc(len + 1); 180 p[len] = 0xf4; 181 BN_bn2bin(bn, p); 182 if (p[len] != 0xf4) 183 return 1; 184 if (memcmp(p, ietests[i].data, ietests[i].len) != 0) 185 return 1; 186 free(p); 187 } 188 189 BN_free(bn); 190 return ret; 191 } 192 193 static int 194 test_BN_uadd(void) 195 { 196 BIGNUM *a, *b, *c; 197 char *p; 198 199 a = BN_new(); 200 b = BN_new(); 201 c = BN_new(); 202 203 BN_set_word(a, 1); 204 BN_set_word(b, 2); 205 206 BN_uadd(c, a, b); 207 208 if (BN_get_word(c) != 3) 209 return 1; 210 211 BN_uadd(c, b, a); 212 213 if (BN_get_word(c) != 3) 214 return 1; 215 216 BN_set_word(b, 0xff); 217 218 BN_uadd(c, a, b); 219 if (BN_get_word(c) != 0x100) 220 return 1; 221 222 BN_uadd(c, b, a); 223 if (BN_get_word(c) != 0x100) 224 return 1; 225 226 BN_set_word(a, 0xff); 227 228 BN_uadd(c, a, b); 229 if (BN_get_word(c) != 0x1fe) 230 return 1; 231 232 BN_uadd(c, b, a); 233 if (BN_get_word(c) != 0x1fe) 234 return 1; 235 236 237 BN_free(a); 238 BN_free(b); 239 240 BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD2"); 241 BN_hex2bn(&b, "84B6C7E8D28ACA1614954DA"); 242 243 BN_uadd(c, b, a); 244 p = BN_bn2hex(c); 245 if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) { 246 free(p); 247 return 1; 248 } 249 free(p); 250 251 BN_uadd(c, a, b); 252 p = BN_bn2hex(c); 253 if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) { 254 free(p); 255 return 1; 256 } 257 free(p); 258 259 BN_free(a); 260 BN_free(b); 261 BN_free(c); 262 263 return 0; 264 } 265 266 static int 267 test_BN_cmp(void) 268 { 269 BIGNUM *a, *b; 270 271 a = BN_new(); 272 b = BN_new(); 273 274 if (!BN_set_word(a, 1)) 275 return 1; 276 if (!BN_set_word(b, 1)) 277 return 1; 278 279 if (BN_cmp(a, b) != 0) 280 return 1; 281 if (BN_cmp(b, a) != 0) 282 return 1; 283 284 if (!BN_set_word(b, 2)) 285 return 1; 286 287 if (BN_cmp(a, b) >= 0) 288 return 1; 289 if (BN_cmp(b, a) <= 0) 290 return 1; 291 292 BN_set_negative(b, 1); 293 294 if (BN_cmp(a, b) <= 0) 295 return 1; 296 if (BN_cmp(b, a) >= 0) 297 return 1; 298 299 BN_free(a); 300 BN_free(b); 301 302 BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD1"); 303 BN_hex2bn(&b, "50212A3B611D46642C825A16A354CE0FD4D85DD2"); 304 305 if (BN_cmp(a, b) >= 0) 306 return 1; 307 if (BN_cmp(b, a) <= 0) 308 return 1; 309 310 BN_set_negative(b, 1); 311 312 if (BN_cmp(a, b) <= 0) 313 return 1; 314 if (BN_cmp(b, a) >= 0) 315 return 1; 316 317 BN_free(a); 318 BN_free(b); 319 return 0; 320 } 321 322 static int 323 test_BN_rand(void) 324 { 325 BIGNUM *bn; 326 327 if (RAND_status() != 1) 328 return 0; 329 330 bn = BN_new(); 331 if (bn == NULL) 332 return 1; 333 334 if (!BN_rand(bn, 1024, 0, 0)) 335 return 1; 336 337 BN_free(bn); 338 return 0; 339 } 340 341 #define testnum 100 342 #define testnum2 10 343 344 static int 345 test_BN_CTX(void) 346 { 347 unsigned int i, j; 348 BIGNUM *bn; 349 BN_CTX *c; 350 351 if ((c = BN_CTX_new()) == NULL) 352 return 1; 353 354 for (i = 0; i < testnum; i++) { 355 BN_CTX_start(c); 356 BN_CTX_end(c); 357 } 358 359 for (i = 0; i < testnum; i++) 360 BN_CTX_start(c); 361 for (i = 0; i < testnum; i++) 362 BN_CTX_end(c); 363 364 for (i = 0; i < testnum; i++) { 365 BN_CTX_start(c); 366 if ((bn = BN_CTX_get(c)) == NULL) 367 return 1; 368 BN_CTX_end(c); 369 } 370 371 for (i = 0; i < testnum; i++) { 372 BN_CTX_start(c); 373 for (j = 0; j < testnum2; j++) 374 if ((bn = BN_CTX_get(c)) == NULL) 375 return 1; 376 } 377 for (i = 0; i < testnum; i++) 378 BN_CTX_end(c); 379 380 BN_CTX_free(c); 381 return 0; 382 } 383 384 385 int 386 main(int argc, char **argv) 387 { 388 int ret = 0; 389 390 ret += test_BN_set_get(); 391 ret += test_BN_bit(); 392 ret += test_BN_import_export(); 393 ret += test_BN_uadd(); 394 ret += test_BN_cmp(); 395 ret += test_BN_rand(); 396 ret += test_BN_CTX(); 397 398 return ret; 399 } 400