primegen.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:6k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  *  primegen.c
  3.  *
  4.  * Generates random integers which are prime with a high degree of
  5.  * probability using the Miller-Rabin probabilistic primality testing
  6.  * algorithm.
  7.  *
  8.  * Usage:
  9.  *    primegen <bits> [<num>]
  10.  *
  11.  *    <bits>   - number of significant bits each prime should have
  12.  *    <num>    - number of primes to generate
  13.  *
  14.  * The contents of this file are subject to the Mozilla Public
  15.  * License Version 1.1 (the "License"); you may not use this file
  16.  * except in compliance with the License. You may obtain a copy of
  17.  * the License at http://www.mozilla.org/MPL/
  18.  *
  19.  * Software distributed under the License is distributed on an "AS
  20.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  21.  * implied. See the License for the specific language governing
  22.  * rights and limitations under the License.
  23.  *
  24.  * The Original Code is the MPI Arbitrary Precision Integer Arithmetic
  25.  * library.
  26.  *
  27.  * The Initial Developer of the Original Code is Michael J. Fromberger.
  28.  * Portions created by Michael J. Fromberger are 
  29.  * Copyright (C) 1998, 1999, 2000 Michael J. Fromberger. 
  30.  * All Rights Reserved.
  31.  *
  32.  * Contributor(s):
  33.  *
  34.  * Alternatively, the contents of this file may be used under the
  35.  * terms of the GNU General Public License Version 2 or later (the
  36.  * "GPL"), in which case the provisions of the GPL are applicable
  37.  * instead of those above.  If you wish to allow use of your
  38.  * version of this file only under the terms of the GPL and not to
  39.  * allow others to use your version of this file under the MPL,
  40.  * indicate your decision by deleting the provisions above and
  41.  * replace them with the notice and other provisions required by
  42.  * the GPL.  If you do not delete the provisions above, a recipient
  43.  * may use your version of this file under either the MPL or the GPL.
  44.  *
  45.  * $Id: primegen.c,v 1.4 2000/07/26 05:41:59 nelsonb%netscape.com Exp $
  46.  */
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50. #include <limits.h>
  51. #include <time.h>
  52. #include "mpi.h"
  53. #include "mplogic.h"
  54. #include "mpprime.h"
  55. #undef MACOS /* define if running on a Macintosh */
  56. #ifdef MACOS
  57. #include <console.h>
  58. #endif
  59. #define NUM_TESTS 5  /* Number of Rabin-Miller iterations to test with */
  60. #ifdef DEBUG
  61. #define FPUTC(x,y) fputc(x,y)
  62. #else
  63. #define FPUTC(x,y) 
  64. #endif
  65. int main(int argc, char *argv[])
  66. {
  67.   unsigned char *raw;
  68.   char          *out;
  69.   unsigned long nTries;
  70.   int rawlen, bits, outlen, ngen, ix, jx;
  71.   int           g_strong = 0;
  72.   mp_int testval;
  73.   mp_err res;
  74.   clock_t start, end;
  75. #ifdef MACOS
  76.   argc = ccommand(&argv);
  77. #endif
  78.   /* We'll just use the C library's rand() for now, although this
  79.      won't be good enough for cryptographic purposes */
  80.   if((out = getenv("SEED")) == NULL) {
  81.     srand((unsigned int)time(NULL));
  82.   } else {
  83.     srand((unsigned int)atoi(out));
  84.   }
  85.   if(argc < 2) {
  86.     fprintf(stderr, "Usage: %s <bits> [<count> [strong]]n", argv[0]);
  87.     return 1;
  88.   }
  89.   if((bits = abs(atoi(argv[1]))) < CHAR_BIT) {
  90.     fprintf(stderr, "%s: please request at least %d bits.n",
  91.     argv[0], CHAR_BIT);
  92.     return 1;
  93.   }
  94.   /* If optional third argument is given, use that as the number of
  95.      primes to generate; otherwise generate one prime only.
  96.    */
  97.   if(argc < 3) {
  98.     ngen = 1;
  99.   } else {
  100.     ngen = abs(atoi(argv[2]));
  101.   }
  102.   /* If fourth argument is given, and is the word "strong", we'll 
  103.      generate strong (Sophie Germain) primes. 
  104.    */
  105.   if(argc > 3 && strcmp(argv[3], "strong") == 0)
  106.     g_strong = 1;
  107.   /* testval - candidate being tested; nTries - number tried so far */
  108.   if ((res = mp_init(&testval)) != MP_OKAY) {
  109.     fprintf(stderr, "%s: error: %sn", argv[0], mp_strerror(res));
  110.     return 1;
  111.   }
  112.   
  113.   if(g_strong) {
  114.     printf("Requested %d strong prime value(s) of %d bits.n", 
  115.    ngen, bits);
  116.   } else {
  117.     printf("Requested %d prime value(s) of %d bits.n", ngen, bits);
  118.   }
  119.   rawlen = (bits / CHAR_BIT) + ((bits % CHAR_BIT) ? 1 : 0) + 1;
  120.   if((raw = calloc(rawlen, sizeof(unsigned char))) == NULL) {
  121.     fprintf(stderr, "%s: out of memory, sorry.n", argv[0]);
  122.     return 1;
  123.   }
  124.   /* This loop is one for each prime we need to generate */
  125.   for(jx = 0; jx < ngen; jx++) {
  126.     raw[0] = 0;  /* sign is positive */
  127.     /* Pack the initializer with random bytes */
  128.     for(ix = 1; ix < rawlen; ix++) 
  129.       raw[ix] = (rand() * rand()) & UCHAR_MAX;
  130.     raw[1] |= 0x80;             /* set high-order bit of test value     */
  131.     raw[rawlen - 1] |= 1;       /* set low-order bit of test value      */
  132.     /* Make an mp_int out of the initializer */
  133.     mp_read_raw(&testval, (char *)raw, rawlen);
  134.     /* Initialize candidate counter */
  135.     nTries = 0;
  136.     start = clock(); /* time generation for this prime */
  137.     do {
  138.       res = mpp_make_prime(&testval, bits, g_strong, &nTries);
  139.       if (res != MP_NO)
  140. break;
  141.       /* This code works whether digits are 16 or 32 bits */
  142.       res = mp_add_d(&testval, 32 * 1024, &testval);
  143.       res = mp_add_d(&testval, 32 * 1024, &testval);
  144.       FPUTC(',', stderr);
  145.     } while (1);
  146.     end = clock();
  147.     if (res != MP_YES) {
  148.       break;
  149.     }
  150.     FPUTC('n', stderr);
  151.     printf("After %d tests, the following value is still probably prime:n",
  152.    NUM_TESTS);
  153.     outlen = mp_radix_size(&testval, 10);
  154.     out = calloc(outlen, sizeof(unsigned char));
  155.     mp_toradix(&testval, (char *)out, 10);
  156.     printf("10: %sn", out);
  157.     mp_toradix(&testval, (char *)out, 16);
  158.     printf("16: %snn", out);
  159.     free(out);
  160.     
  161.     printf("Number of candidates tried: %lun", nTries);
  162.     printf("This computation took %ld clock ticks (%.2f seconds)n",
  163.    (end - start), ((double)(end - start) / CLOCKS_PER_SEC));
  164.     
  165.     FPUTC('n', stderr);
  166.   } /* end of loop to generate all requested primes */
  167.   
  168.   if(res != MP_OKAY) 
  169.     fprintf(stderr, "%s: error: %sn", argv[0], mp_strerror(res));
  170.   free(raw);
  171.   mp_clear(&testval);
  172.   
  173.   return 0;
  174. }