PageRenderTime 25ms CodeModel.GetById 19ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/security/nss/lib/freebl/mpi/utils/makeprime.c

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