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

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * makeprime.c
  3.  *
  4.  * A simple prime generator function (and test driver).  Prints out the
  5.  * first prime it finds greater than or equal to the starting value.
  6.  *
  7.  * Usage: makeprime <start>
  8.  *
  9.  * The contents of this file are subject to the Mozilla Public
  10.  * License Version 1.1 (the "License"); you may not use this file
  11.  * except in compliance with the License. You may obtain a copy of
  12.  * the License at http://www.mozilla.org/MPL/
  13.  *
  14.  * Software distributed under the License is distributed on an "AS
  15.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  16.  * implied. See the License for the specific language governing
  17.  * rights and limitations under the License.
  18.  *
  19.  * The Original Code is the MPI Arbitrary Precision Integer Arithmetic
  20.  * library.
  21.  *
  22.  * The Initial Developer of the Original Code is Michael J. Fromberger.
  23.  * Portions created by Michael J. Fromberger are 
  24.  * Copyright (C) 1998, 1999, 2000 Michael J. Fromberger. 
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s):
  28.  *
  29.  * Alternatively, the contents of this file may be used under the
  30.  * terms of the GNU General Public License Version 2 or later (the
  31.  * "GPL"), in which case the provisions of the GPL are applicable
  32.  * instead of those above.  If you wish to allow use of your
  33.  * version of this file only under the terms of the GPL and not to
  34.  * allow others to use your version of this file under the MPL,
  35.  * indicate your decision by deleting the provisions above and
  36.  * replace them with the notice and other provisions required by
  37.  * the GPL.  If you do not delete the provisions above, a recipient
  38.  * may use your version of this file under either the MPL or the GPL.
  39.  *
  40.  * $Id: makeprime.c,v 1.1 2000/07/14 00:44:59 nelsonb%netscape.com Exp $
  41.  */
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <ctype.h>
  45. /* These two must be included for make_prime() to work */
  46. #include "mpi.h"
  47. #include "mpprime.h"
  48. /*
  49.   make_prime(p, nr)
  50.   Find the smallest prime integer greater than or equal to p, where
  51.   primality is verified by 'nr' iterations of the Rabin-Miller
  52.   probabilistic primality test.  The caller is responsible for
  53.   generating the initial value of p.
  54.   Returns MP_OKAY if a prime has been generated, otherwise the error
  55.   code indicates some other problem.  The value of p is clobbered; the
  56.   caller should keep a copy if the value is needed.  
  57.  */
  58. mp_err   make_prime(mp_int *p, int nr);
  59. /* The main() is not required -- it's just a test driver */
  60. int main(int argc, char *argv[])
  61. {
  62.   mp_int    start;
  63.   mp_err    res;
  64.   if(argc < 2) {
  65.     fprintf(stderr, "Usage: %s <start-value>n", argv[0]);
  66.     return 1;
  67.   }
  68.     
  69.   mp_init(&start);
  70.   if(argv[1][0] == '0' && tolower(argv[1][1]) == 'x') {
  71.     mp_read_radix(&start, argv[1] + 2, 16);
  72.   } else {
  73.     mp_read_radix(&start, argv[1], 10);
  74.   }
  75.   mp_abs(&start, &start);
  76.   if((res = make_prime(&start, 5)) != MP_OKAY) {
  77.     fprintf(stderr, "%s: error: %sn", argv[0], mp_strerror(res));
  78.     mp_clear(&start);
  79.     return 1;
  80.   } else {
  81.     char  *buf = malloc(mp_radix_size(&start, 10));
  82.     mp_todecimal(&start, buf);
  83.     printf("%sn", buf);
  84.     free(buf);
  85.     
  86.     mp_clear(&start);
  87.     return 0;
  88.   }
  89.   
  90. } /* end main() */
  91. /*------------------------------------------------------------------------*/
  92. mp_err   make_prime(mp_int *p, int nr)
  93. {
  94.   mp_err  res;
  95.   if(mp_iseven(p)) {
  96.     mp_add_d(p, 1, p);
  97.   }
  98.   do {
  99.     mp_digit   which = prime_tab_size;
  100.     /*  First test for divisibility by a few small primes */
  101.     if((res = mpp_divis_primes(p, &which)) == MP_YES)
  102.       continue;
  103.     else if(res != MP_NO)
  104.       goto CLEANUP;
  105.     /* If that passes, try one iteration of Fermat's test */
  106.     if((res = mpp_fermat(p, 2)) == MP_NO)
  107.       continue;
  108.     else if(res != MP_YES)
  109.       goto CLEANUP;
  110.     /* If that passes, run Rabin-Miller as often as requested */
  111.     if((res = mpp_pprime(p, nr)) == MP_YES)
  112.       break;
  113.     else if(res != MP_NO)
  114.       goto CLEANUP;
  115.       
  116.   } while((res = mp_add_d(p, 2, p)) == MP_OKAY);
  117.  CLEANUP:
  118.   return res;
  119. } /* end make_prime() */
  120. /*------------------------------------------------------------------------*/
  121. /* HERE THERE BE DRAGONS                                                  */