* options.h, g10.c (main), keylist.c (list_keyblock_print): Add
[gnupg.git] / cipher / primegen.c
index 9bf1085..1f30957 100644 (file)
@@ -1,5 +1,5 @@
 /* primegen.c - prime number generator
- *     Copyright (C) 1998 Free Software Foundation, Inc.
+ *     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -38,11 +38,24 @@ static int check_prime( MPI prime, MPI val_2 );
 static int is_prime( MPI n, int steps, int *count );
 static void m_out_of_n( char *array, int m, int n );
 
+static void (*progress_cb) ( void *, int );
+static void *progress_cb_data;
+
+void
+register_primegen_progress ( void (*cb)( void *, int), void *cb_data )
+{
+    progress_cb = cb;
+    progress_cb_data = cb_data;
+}
+
 
 static void
 progress( int c )
 {
-    fputc( c, stderr );
+    if ( progress_cb )
+       progress_cb ( progress_cb_data, c );
+    else
+       fputc( c, stderr );
 }
 
 
@@ -117,8 +130,8 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
        log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
                    pbits, req_qbits, qbits, fbits, n  );
     prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) /  BITS_PER_MPI_LIMB );
-    q = gen_prime( qbits, 0, 1 );
-    q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
+    q = gen_prime( qbits, 0, 0 );
+    q_factor = mode==1? gen_prime( req_qbits, 0, 0 ) : NULL;
 
     /* allocate an array to hold the factors + 2 for later usage */
     factors = m_alloc_clear( (n+2) * sizeof *factors );
@@ -145,7 +158,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
            perms = m_alloc_clear( m );
            for(i=0; i < n; i++ ) {
                perms[i] = 1;
-               pool[i] = gen_prime( fbits, 0, 1 );
+               pool[i] = gen_prime( fbits, 0, 0 );
                factors[i] = pool[i];
            }
        }
@@ -154,7 +167,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
            for(i=j=0; i < m && j < n ; i++ )
                if( perms[i] ) {
                    if( !pool[i] )
-                       pool[i] = gen_prime( fbits, 0, 1 );
+                       pool[i] = gen_prime( fbits, 0, 0 );
                    factors[j++] = pool[i];
                }
            if( i == n ) {
@@ -177,7 +190,8 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
                count1 = 0;
                qbits++;
                progress('>');
-               q = gen_prime( qbits, 0, 1 );
+                mpi_free (q);
+               q = gen_prime( qbits, 0, 0 );
                goto next_try;
            }
        }
@@ -188,7 +202,8 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
                count2 = 0;
                qbits--;
                progress('<');
-               q = gen_prime( qbits, 0, 1 );
+                mpi_free (q);
+               q = gen_prime( qbits, 0, 0 );
                goto next_try;
            }
        }
@@ -214,11 +229,11 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
 
     if( ret_factors ) { /* caller wants the factors */
        *ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
+        i = 0;
        if( mode == 1 ) {
-           i = 0;
            (*ret_factors)[i++] = mpi_copy( q_factor );
            for(; i <= n; i++ )
-               (*ret_factors)[i] = mpi_copy( factors[i] );
+               (*ret_factors)[i] = mpi_copy( factors[i-1] );
        }
        else {
            for(; i < n; i++ )
@@ -270,6 +285,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
     m_free( pool );
     m_free(perms);
     mpi_free(val_2);
+    mpi_free(q);
     return prime;
 }
 
@@ -282,7 +298,7 @@ gen_prime( unsigned  nbits, int secret, int randomlevel )
     MPI prime, ptest, pminus1, val_2, val_3, result;
     int i;
     unsigned x, step;
-    unsigned count1, count2;
+    int count1, count2;
     int *mods;
 
     if( 0 && DBG_CIPHER )
@@ -311,8 +327,13 @@ gen_prime( unsigned  nbits, int secret, int randomlevel )
            m_free(p);
        }
 
-       /* set high order bit to 1, set low order bit to 1 */
+       /* Set high order bit to 1, set low order bit to 0.
+           If we are generating a secret prime we are most probably
+           doing that for RSA, to make sure that the modulus does have
+           the requested keysize we set the 2 high order bits */
        mpi_set_highbit( prime, nbits-1 );
+        if (secret)
+          mpi_set_bit (prime, nbits-2);
        mpi_set_bit( prime, 0 );
 
        /* calculate all remainders */