Back to index

lightning-sunbird  0.9+nobinonly
isprime.c
Go to the documentation of this file.
00001 /*
00002  *  isprime.c
00003  *
00004  *  Probabilistic primality tester command-line tool
00005  *
00006  * ***** BEGIN LICENSE BLOCK *****
00007  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00008  *
00009  * The contents of this file are subject to the Mozilla Public License Version
00010  * 1.1 (the "License"); you may not use this file except in compliance with
00011  * the License. You may obtain a copy of the License at
00012  * http://www.mozilla.org/MPL/
00013  *
00014  * Software distributed under the License is distributed on an "AS IS" basis,
00015  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00016  * for the specific language governing rights and limitations under the
00017  * License.
00018  *
00019  * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
00020  *
00021  * The Initial Developer of the Original Code is
00022  * Michael J. Fromberger.
00023  * Portions created by the Initial Developer are Copyright (C) 1998
00024  * the Initial Developer. All Rights Reserved.
00025  *
00026  * Contributor(s):
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either the GNU General Public License Version 2 or later (the "GPL"), or
00030  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 /* $Id: isprime.c,v 1.3 2004/04/27 23:04:37 gerv%gerv.net Exp $ */
00042 
00043 #include <stdio.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 
00047 #include "mpi.h"
00048 #include "mpprime.h"
00049 
00050 #define  RM_TESTS       15   /* how many iterations of Rabin-Miller? */
00051 #define  MINIMUM        1024 /* don't bother us with a < this        */
00052 
00053 int      g_tests = RM_TESTS;
00054 char    *g_prog = NULL;
00055 
00056 int main(int argc, char *argv[])
00057 {
00058   mp_int   a;
00059   mp_digit np = prime_tab_size; /* from mpprime.h */
00060   int      res = 0;
00061 
00062   g_prog = argv[0];
00063 
00064   if(argc < 2) {
00065     fprintf(stderr, "Usage: %s <a>, where <a> is a decimal integer\n"
00066            "Use '0x' prefix for a hexadecimal value\n", g_prog);
00067     return 1;
00068   }
00069 
00070   /* Read number of tests from environment, if present */
00071   {
00072     char *tmp;
00073 
00074     if((tmp = getenv("RM_TESTS")) != NULL) {
00075       if((g_tests = atoi(tmp)) <= 0)
00076        g_tests = RM_TESTS;
00077     }
00078   }
00079 
00080   mp_init(&a);
00081   if(argv[1][0] == '0' && argv[1][1] == 'x')
00082     mp_read_radix(&a, argv[1] + 2, 16);
00083   else
00084     mp_read_radix(&a, argv[1], 10);
00085 
00086   if(mp_cmp_d(&a, MINIMUM) <= 0) {
00087     fprintf(stderr, "%s: please use a value greater than %d\n", 
00088            g_prog, MINIMUM);
00089     mp_clear(&a);
00090     return 1;
00091   }
00092 
00093   /* Test for divisibility by small primes */
00094   if(mpp_divis_primes(&a, &np) != MP_NO) {
00095     printf("Not prime (divisible by small prime %d)\n", np);
00096     res = 2;
00097     goto CLEANUP;
00098   }
00099 
00100   /* Test with Fermat's test, using 2 as a witness */
00101   if(mpp_fermat(&a, 2) != MP_YES) {
00102     printf("Not prime (failed Fermat test)\n");
00103     res = 2;
00104     goto CLEANUP;
00105   }
00106  
00107   /* Test with Rabin-Miller probabilistic test */
00108   if(mpp_pprime(&a, g_tests) == MP_NO) {
00109       printf("Not prime (failed pseudoprime test)\n");
00110       res = 2;
00111       goto CLEANUP;
00112   }
00113 
00114   printf("Probably prime, 1 in 4^%d chance of false positive\n", g_tests);
00115 
00116 CLEANUP:
00117   mp_clear(&a);
00118   
00119   return res;
00120 
00121 }