1 1.4 andvar /* $NetBSD: qsieve.c,v 1.4 2025/02/17 22:58:34 andvar Exp $ */ 2 1.1 elad 3 1.1 elad /*- 4 1.1 elad * Copyright 1994 Phil Karn <karn (at) qualcomm.com> 5 1.1 elad * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson (at) greendragon.com> 6 1.1 elad * Copyright 2000 Niels Provos <provos (at) citi.umich.edu> 7 1.1 elad * All rights reserved. 8 1.1 elad * 9 1.1 elad * Redistribution and use in source and binary forms, with or without 10 1.1 elad * modification, are permitted provided that the following conditions 11 1.1 elad * are met: 12 1.1 elad * 1. Redistributions of source code must retain the above copyright 13 1.1 elad * notice, this list of conditions and the following disclaimer. 14 1.1 elad * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 elad * notice, this list of conditions and the following disclaimer in the 16 1.1 elad * documentation and/or other materials provided with the distribution. 17 1.1 elad * 18 1.1 elad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 elad * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 elad * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 elad * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 elad * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 elad * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 elad * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 elad * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 elad * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 elad * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 elad */ 29 1.1 elad 30 1.1 elad /* 31 1.1 elad * Sieve candidates for "safe" primes, 32 1.1 elad * suitable for use as Diffie-Hellman moduli; 33 1.1 elad * that is, where q = (p-1)/2 is also prime. 34 1.1 elad * 35 1.1 elad * This is the first of two steps. 36 1.1 elad * This step is memory intensive. 37 1.1 elad * 38 1.1 elad * 1996 May William Allen Simpson 39 1.1 elad * extracted from earlier code by Phil Karn, April 1994. 40 1.1 elad * save large primes list for later processing. 41 1.1 elad * 1998 May William Allen Simpson 42 1.1 elad * parameterized. 43 1.1 elad * 2000 Dec Niels Provos 44 1.1 elad * convert from GMP to openssl BN. 45 1.1 elad * 2003 Jun William Allen Simpson 46 1.1 elad * change outfile definition slightly to match openssh mistake. 47 1.1 elad * move common file i/o to own file for better documentation. 48 1.1 elad * redo memory again. 49 1.1 elad */ 50 1.1 elad 51 1.1 elad #include <stdio.h> 52 1.1 elad #include <stdlib.h> 53 1.1 elad #include <time.h> 54 1.1 elad #include <openssl/bn.h> 55 1.1 elad #include <string.h> 56 1.1 elad #include <err.h> 57 1.1 elad #include "qfile.h" 58 1.1 elad 59 1.1 elad /* define DEBUG_LARGE 1 */ 60 1.1 elad /* define DEBUG_SMALL 1 */ 61 1.1 elad 62 1.1 elad /* 63 1.1 elad * Using virtual memory can cause thrashing. This should be the largest 64 1.1 elad * number that is supported without a large amount of disk activity -- 65 1.1 elad * that would increase the run time from hours to days or weeks! 66 1.1 elad */ 67 1.1 elad #define LARGE_MINIMUM (8UL) /* megabytes */ 68 1.1 elad 69 1.1 elad /* 70 1.1 elad * Do not increase this number beyond the unsigned integer bit size. 71 1.1 elad * Due to a multiple of 4, it must be LESS than 128 (yielding 2**30 bits). 72 1.1 elad */ 73 1.1 elad #define LARGE_MAXIMUM (127UL) /* megabytes */ 74 1.1 elad 75 1.1 elad /* 76 1.1 elad * Constant: assuming 8 bit bytes and 32 bit words 77 1.1 elad */ 78 1.1 elad #define SHIFT_BIT (3) 79 1.1 elad #define SHIFT_BYTE (2) 80 1.1 elad #define SHIFT_WORD (SHIFT_BIT+SHIFT_BYTE) 81 1.1 elad #define SHIFT_MEGABYTE (20) 82 1.1 elad #define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) 83 1.1 elad 84 1.1 elad /* 85 1.1 elad * Constant: when used with 32-bit integers, the largest sieve prime 86 1.1 elad * has to be less than 2**32. 87 1.1 elad */ 88 1.1 elad #define SMALL_MAXIMUM (0xffffffffUL) 89 1.1 elad 90 1.1 elad /* 91 1.1 elad * Constant: can sieve all primes less than 2**32, as 65537**2 > 2**32-1. 92 1.1 elad */ 93 1.1 elad #define TINY_NUMBER (1UL<<16) 94 1.1 elad 95 1.1 elad /* 96 1.1 elad * Ensure enough bit space for testing 2*q. 97 1.1 elad */ 98 1.1 elad #define TEST_MAXIMUM (1UL<<16) 99 1.1 elad #define TEST_MINIMUM (QSIZE_MINIMUM + 1) 100 1.1 elad /* real TEST_MINIMUM (1UL << (SHIFT_WORD - TEST_POWER)) */ 101 1.1 elad #define TEST_POWER (3) /* 2**n, n < SHIFT_WORD */ 102 1.1 elad 103 1.1 elad /* 104 1.1 elad * bit operations on 32-bit words 105 1.1 elad */ 106 1.1 elad #define BIT_CLEAR(a,n) ((a)[(n)>>SHIFT_WORD] &= ~(1U << ((n) & 31))) 107 1.1 elad #define BIT_SET(a,n) ((a)[(n)>>SHIFT_WORD] |= (1U << ((n) & 31))) 108 1.1 elad #define BIT_TEST(a,n) ((a)[(n)>>SHIFT_WORD] & (1U << ((n) & 31))) 109 1.1 elad 110 1.1 elad /* 111 1.1 elad * sieve relative to the initial value 112 1.1 elad */ 113 1.3 joerg static uint32_t *LargeSieve; 114 1.3 joerg static uint32_t largewords; 115 1.3 joerg static uint32_t largetries; 116 1.3 joerg static uint32_t largenumbers; 117 1.3 joerg static uint32_t largememory; /* megabytes */ 118 1.3 joerg static uint32_t largebits; 119 1.3 joerg static BIGNUM *largebase; 120 1.1 elad 121 1.1 elad /* 122 1.1 elad * sieve 2**30 in 2**16 parts 123 1.1 elad */ 124 1.3 joerg static uint32_t *SmallSieve; 125 1.3 joerg static uint32_t smallbits; 126 1.3 joerg static uint32_t smallbase; 127 1.1 elad 128 1.1 elad /* 129 1.1 elad * sieve 2**16 130 1.1 elad */ 131 1.3 joerg static uint32_t *TinySieve; 132 1.3 joerg static uint32_t tinybits; 133 1.1 elad 134 1.3 joerg __dead static void usage(void); 135 1.3 joerg static void sieve_large(uint32_t); 136 1.1 elad 137 1.1 elad /* 138 1.1 elad * Sieve p's and q's with small factors 139 1.1 elad */ 140 1.3 joerg static void 141 1.1 elad sieve_large(uint32_t s) 142 1.1 elad { 143 1.1 elad BN_ULONG r; 144 1.1 elad BN_ULONG u; 145 1.1 elad 146 1.1 elad #ifdef DEBUG_SMALL 147 1.1 elad (void)fprintf(stderr, "%lu\n", s); 148 1.1 elad #endif 149 1.1 elad largetries++; 150 1.1 elad /* r = largebase mod s */ 151 1.1 elad r = BN_mod_word(largebase, (BN_ULONG) s); 152 1.1 elad if (r == 0) { 153 1.1 elad /* s divides into largebase exactly */ 154 1.1 elad u = 0; 155 1.1 elad } else { 156 1.1 elad /* largebase+u is first entry divisible by s */ 157 1.1 elad u = s - r; 158 1.1 elad } 159 1.1 elad 160 1.1 elad if (u < largebits * 2) { 161 1.1 elad /* 162 1.1 elad * The sieve omits p's and q's divisible by 2, so ensure that 163 1.1 elad * largebase+u is odd. Then, step through the sieve in 164 1.1 elad * increments of 2*s 165 1.1 elad */ 166 1.1 elad if (u & 0x1) { 167 1.1 elad /* Make largebase+u odd, and u even */ 168 1.1 elad u += s; 169 1.1 elad } 170 1.1 elad 171 1.1 elad /* Mark all multiples of 2*s */ 172 1.1 elad for (u /= 2; u < largebits; u += s) { 173 1.1 elad BIT_SET(LargeSieve, (uint32_t)u); 174 1.1 elad } 175 1.1 elad } 176 1.1 elad 177 1.1 elad /* r = p mod s */ 178 1.1 elad r = (2 * r + 1) % s; 179 1.1 elad 180 1.1 elad if (r == 0) { 181 1.1 elad /* s divides p exactly */ 182 1.1 elad u = 0; 183 1.1 elad } else { 184 1.1 elad /* p+u is first entry divisible by s */ 185 1.1 elad u = s - r; 186 1.1 elad } 187 1.1 elad 188 1.1 elad if (u < largebits * 4) { 189 1.1 elad /* 190 1.1 elad * The sieve omits p's divisible by 4, so ensure that 191 1.1 elad * largebase+u is not. Then, step through the sieve in 192 1.1 elad * increments of 4*s 193 1.1 elad */ 194 1.1 elad while (u & 0x3) { 195 1.1 elad if (SMALL_MAXIMUM - u < s) { 196 1.1 elad return; 197 1.1 elad } 198 1.1 elad 199 1.1 elad u += s; 200 1.1 elad } 201 1.1 elad 202 1.1 elad /* Mark all multiples of 4*s */ 203 1.1 elad for (u /= 4; u < largebits; u += s) { 204 1.1 elad BIT_SET(LargeSieve, (uint32_t)u); 205 1.1 elad } 206 1.1 elad } 207 1.1 elad } 208 1.1 elad 209 1.1 elad /* 210 1.1 elad * list candidates for Sophie-Germaine primes 211 1.1 elad * (where q = (p-1)/2) 212 1.1 elad * to standard output. 213 1.1 elad * The list is checked against small known primes 214 1.1 elad * (less than 2**30). 215 1.1 elad */ 216 1.1 elad int 217 1.1 elad main(int argc, char *argv[]) 218 1.1 elad { 219 1.1 elad BIGNUM *q; 220 1.1 elad uint32_t j; 221 1.1 elad int power; 222 1.1 elad uint32_t r; 223 1.1 elad uint32_t s; 224 1.1 elad uint32_t smallwords = TINY_NUMBER >> 6; 225 1.1 elad uint32_t t; 226 1.1 elad time_t time_start; 227 1.1 elad time_t time_stop; 228 1.1 elad uint32_t tinywords = TINY_NUMBER >> 6; 229 1.1 elad unsigned int i; 230 1.1 elad 231 1.1 elad setprogname(argv[0]); 232 1.1 elad 233 1.1 elad if (argc < 3) { 234 1.1 elad usage(); 235 1.1 elad } 236 1.1 elad 237 1.1 elad /* 238 1.1 elad * Set power to the length in bits of the prime to be generated. 239 1.1 elad * This is changed to 1 less than the desired safe prime moduli p. 240 1.1 elad */ 241 1.1 elad power = (int) strtoul(argv[2], NULL, 10); 242 1.2 lukem if ((unsigned)power > TEST_MAXIMUM) { 243 1.1 elad errx(1, "Too many bits: %d > %lu.", power, 244 1.1 elad (unsigned long)TEST_MAXIMUM); 245 1.1 elad } else if (power < TEST_MINIMUM) { 246 1.1 elad errx(1, "Too few bits: %d < %lu.", power, 247 1.1 elad (unsigned long)TEST_MINIMUM); 248 1.1 elad } 249 1.1 elad 250 1.1 elad power--; /* decrement before squaring */ 251 1.1 elad 252 1.1 elad /* 253 1.1 elad * The density of ordinary primes is on the order of 1/bits, so the 254 1.1 elad * density of safe primes should be about (1/bits)**2. Set test range 255 1.1 elad * to something well above bits**2 to be reasonably sure (but not 256 1.1 elad * guaranteed) of catching at least one safe prime. 257 1.1 elad */ 258 1.1 elad largewords = (uint32_t)((unsigned long) 259 1.1 elad (power * power) >> (SHIFT_WORD - TEST_POWER)); 260 1.1 elad 261 1.1 elad /* 262 1.1 elad * Need idea of how much memory is available. We don't have to use all 263 1.1 elad * of it. 264 1.1 elad */ 265 1.1 elad largememory = (uint32_t)strtoul(argv[1], NULL, 10); 266 1.1 elad if (largememory > LARGE_MAXIMUM) { 267 1.1 elad warnx("Limited memory: %u MB; limit %lu MB.", largememory, 268 1.1 elad LARGE_MAXIMUM); 269 1.1 elad largememory = LARGE_MAXIMUM; 270 1.1 elad } 271 1.1 elad 272 1.1 elad if (largewords <= (largememory << SHIFT_MEGAWORD)) { 273 1.1 elad warnx("Increased memory: %u MB; need %u bytes.", 274 1.1 elad largememory, (largewords << SHIFT_BYTE)); 275 1.1 elad largewords = (largememory << SHIFT_MEGAWORD); 276 1.1 elad } else if (largememory > 0) { 277 1.1 elad warnx("Decreased memory: %u MB; want %u bytes.", 278 1.1 elad largememory, (largewords << SHIFT_BYTE)); 279 1.1 elad largewords = (largememory << SHIFT_MEGAWORD); 280 1.1 elad } 281 1.1 elad 282 1.1 elad if ((TinySieve = (uint32_t *) calloc((size_t) tinywords, sizeof(uint32_t))) == NULL) { 283 1.4 andvar errx(1, "Insufficient memory for tiny sieve: need %u bytes.", 284 1.1 elad tinywords << SHIFT_BYTE); 285 1.1 elad } 286 1.1 elad tinybits = tinywords << SHIFT_WORD; 287 1.1 elad 288 1.1 elad if ((SmallSieve = (uint32_t *) calloc((size_t) smallwords, sizeof(uint32_t))) == NULL) { 289 1.1 elad errx(1, "Insufficient memory for small sieve: need %u bytes.", 290 1.1 elad smallwords << SHIFT_BYTE); 291 1.1 elad } 292 1.1 elad smallbits = smallwords << SHIFT_WORD; 293 1.1 elad 294 1.1 elad /* 295 1.1 elad * dynamically determine available memory 296 1.1 elad */ 297 1.1 elad while ((LargeSieve = (uint32_t *)calloc((size_t)largewords, 298 1.1 elad sizeof(uint32_t))) == NULL) { 299 1.1 elad /* 1/4 MB chunks */ 300 1.1 elad largewords -= (1L << (SHIFT_MEGAWORD - 2)); 301 1.1 elad } 302 1.1 elad largebits = largewords << SHIFT_WORD; 303 1.1 elad largenumbers = largebits * 2; /* even numbers excluded */ 304 1.1 elad 305 1.1 elad /* validation check: count the number of primes tried */ 306 1.1 elad largetries = 0; 307 1.1 elad 308 1.1 elad q = BN_new(); 309 1.1 elad largebase = BN_new(); 310 1.1 elad 311 1.1 elad /* 312 1.1 elad * Generate random starting point for subprime search, or use 313 1.1 elad * specified parameter. 314 1.1 elad */ 315 1.1 elad if (argc < 4) { 316 1.1 elad BN_rand(largebase, power, 1, 1); 317 1.1 elad } else { 318 1.1 elad BIGNUM *a; 319 1.1 elad 320 1.1 elad a = largebase; 321 1.1 elad BN_hex2bn(&a, argv[2]); 322 1.1 elad } 323 1.1 elad 324 1.1 elad /* ensure odd */ 325 1.1 elad if (!BN_is_odd(largebase)) { 326 1.1 elad BN_set_bit(largebase, 0); 327 1.1 elad } 328 1.1 elad 329 1.1 elad time(&time_start); 330 1.1 elad (void)fprintf(stderr, 331 1.1 elad "%.24s Sieve next %u plus %d-bit start point:\n# ", 332 1.1 elad ctime(&time_start), largenumbers, power); 333 1.1 elad BN_print_fp(stderr, largebase); 334 1.1 elad (void)fprintf(stderr, "\n"); 335 1.1 elad 336 1.1 elad /* 337 1.1 elad * TinySieve 338 1.1 elad */ 339 1.1 elad for (i = 0; i < tinybits; i++) { 340 1.1 elad if (BIT_TEST(TinySieve, i)) { 341 1.1 elad /* 2*i+3 is composite */ 342 1.1 elad continue; 343 1.1 elad } 344 1.1 elad 345 1.1 elad /* The next tiny prime */ 346 1.1 elad t = 2 * i + 3; 347 1.1 elad 348 1.1 elad /* Mark all multiples of t */ 349 1.1 elad for (j = i + t; j < tinybits; j += t) { 350 1.1 elad BIT_SET(TinySieve, j); 351 1.1 elad } 352 1.1 elad 353 1.1 elad sieve_large(t); 354 1.1 elad } 355 1.1 elad 356 1.1 elad /* 357 1.1 elad * Start the small block search at the next possible prime. To avoid 358 1.1 elad * fencepost errors, the last pass is skipped. 359 1.1 elad */ 360 1.1 elad for (smallbase = TINY_NUMBER + 3; 361 1.1 elad smallbase < (SMALL_MAXIMUM - TINY_NUMBER); 362 1.1 elad smallbase += TINY_NUMBER) { 363 1.1 elad for (i = 0; i < tinybits; i++) { 364 1.1 elad if (BIT_TEST(TinySieve, i)) { 365 1.1 elad /* 2*i+3 is composite */ 366 1.1 elad continue; 367 1.1 elad } 368 1.1 elad 369 1.1 elad /* The next tiny prime */ 370 1.1 elad t = 2 * i + 3; 371 1.1 elad r = smallbase % t; 372 1.1 elad 373 1.1 elad if (r == 0) { 374 1.1 elad /* t divides into smallbase exactly */ 375 1.1 elad s = 0; 376 1.1 elad } else { 377 1.1 elad /* smallbase+s is first entry divisible by t */ 378 1.1 elad s = t - r; 379 1.1 elad } 380 1.1 elad 381 1.1 elad /* 382 1.1 elad * The sieve omits even numbers, so ensure that 383 1.1 elad * smallbase+s is odd. Then, step through the sieve in 384 1.1 elad * increments of 2*t 385 1.1 elad */ 386 1.1 elad if (s & 1) { 387 1.1 elad /* Make smallbase+s odd, and s even */ 388 1.1 elad s += t; 389 1.1 elad } 390 1.1 elad 391 1.1 elad /* Mark all multiples of 2*t */ 392 1.1 elad for (s /= 2; s < smallbits; s += t) { 393 1.1 elad BIT_SET(SmallSieve, s); 394 1.1 elad } 395 1.1 elad } 396 1.1 elad 397 1.1 elad /* 398 1.1 elad * SmallSieve 399 1.1 elad */ 400 1.1 elad for (i = 0; i < smallbits; i++) { 401 1.1 elad if (BIT_TEST(SmallSieve, i)) { 402 1.1 elad /* 2*i+smallbase is composite */ 403 1.1 elad continue; 404 1.1 elad } 405 1.1 elad 406 1.1 elad /* The next small prime */ 407 1.1 elad sieve_large((2 * i) + smallbase); 408 1.1 elad } 409 1.1 elad 410 1.1 elad memset(SmallSieve, 0, (size_t)(smallwords << SHIFT_BYTE)); 411 1.1 elad } 412 1.1 elad 413 1.1 elad time(&time_stop); 414 1.1 elad (void)fprintf(stderr, 415 1.1 elad "%.24s Sieved with %u small primes in %lu seconds\n", 416 1.1 elad ctime(&time_stop), largetries, 417 1.1 elad (long) (time_stop - time_start)); 418 1.1 elad 419 1.1 elad for (j = r = 0; j < largebits; j++) { 420 1.1 elad if (BIT_TEST(LargeSieve, j)) { 421 1.1 elad /* Definitely composite, skip */ 422 1.1 elad continue; 423 1.1 elad } 424 1.1 elad 425 1.1 elad #ifdef DEBUG_LARGE 426 1.1 elad (void)fprintf(stderr, "test q = largebase+%lu\n", 2 * j); 427 1.1 elad #endif 428 1.1 elad 429 1.1 elad BN_set_word(q, (unsigned long)(2 * j)); 430 1.1 elad BN_add(q, q, largebase); 431 1.1 elad 432 1.1 elad if (0 > qfileout(stdout, 433 1.1 elad (uint32_t) QTYPE_SOPHIE_GERMAINE, 434 1.1 elad (uint32_t) QTEST_SIEVE, 435 1.1 elad largetries, 436 1.1 elad (uint32_t) (power - 1), /* MSB */ 437 1.1 elad (uint32_t) (0), /* generator unknown */ 438 1.1 elad q)) { 439 1.1 elad break; 440 1.1 elad } 441 1.1 elad 442 1.1 elad r++; /* count q */ 443 1.1 elad } 444 1.1 elad 445 1.1 elad time(&time_stop); 446 1.1 elad 447 1.1 elad free(LargeSieve); 448 1.1 elad free(SmallSieve); 449 1.1 elad free(TinySieve); 450 1.1 elad 451 1.1 elad fflush(stdout); 452 1.1 elad /* fclose(stdout); */ 453 1.1 elad 454 1.1 elad (void) fprintf(stderr, "%.24s Found %u candidates\n", 455 1.1 elad ctime(&time_stop), r); 456 1.1 elad 457 1.1 elad return (0); 458 1.1 elad } 459 1.1 elad 460 1.1 elad static void 461 1.1 elad usage(void) 462 1.1 elad { 463 1.1 elad (void)fprintf(stderr, "Usage: %s <megabytes> <bits> [initial]\n" 464 1.1 elad "Possible values for <megabytes>: 0, %lu to %lu\n" 465 1.1 elad "Possible values for <bits>: %lu to %lu\n", 466 1.1 elad getprogname(), 467 1.1 elad LARGE_MINIMUM, 468 1.1 elad LARGE_MAXIMUM, 469 1.1 elad (unsigned long) TEST_MINIMUM, 470 1.1 elad (unsigned long) TEST_MAXIMUM); 471 1.1 elad 472 1.1 elad exit(1); 473 1.1 elad } 474