00001 /* 00002 * Diffie-Hellman-Merkle key exchange (prime generation) 00003 * 00004 * Copyright (C) 2006-2007 Christophe Devine 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #ifndef _CRT_SECURE_NO_DEPRECATE 00022 #define _CRT_SECURE_NO_DEPRECATE 1 00023 #endif 00024 00025 #include <stdio.h> 00026 00027 #include "xyssl/bignum.h" 00028 #include "xyssl/config.h" 00029 #include "xyssl/havege.h" 00030 00031 /* 00032 * Note: G = 4 is always a quadratic residue mod P, 00033 * so it is a generator of order Q (with P = 2*Q+1). 00034 */ 00035 #define DH_P_SIZE 1024 00036 #define GENERATOR "4" 00037 00038 int main( void ) 00039 { 00040 int ret = 1; 00041 00042 #if defined(XYSSL_GENPRIME) 00043 mpi G, P, Q; 00044 havege_state hs; 00045 FILE *fout; 00046 00047 mpi_init( &G, &P, &Q, NULL ); 00048 mpi_read_string( &G, 10, GENERATOR ); 00049 00050 printf( "\n . Seeding the random number generator..." ); 00051 fflush( stdout ); 00052 00053 havege_init( &hs ); 00054 00055 printf( " ok\n . Generating the modulus, please wait..." ); 00056 fflush( stdout ); 00057 00058 /* 00059 * This can take a long time... 00060 */ 00061 if( ( ret = mpi_gen_prime( &P, DH_P_SIZE, 1, 00062 havege_rand, &hs ) ) != 0 ) 00063 { 00064 printf( " failed\n ! mpi_gen_prime returned %d\n\n", ret ); 00065 goto exit; 00066 } 00067 00068 printf( " ok\n . Verifying that Q = (P-1)/2 is prime..." ); 00069 fflush( stdout ); 00070 00071 if( ( ret = mpi_sub_int( &Q, &P, 1 ) ) != 0 ) 00072 { 00073 printf( " failed\n ! mpi_sub_int returned %d\n\n", ret ); 00074 goto exit; 00075 } 00076 00077 if( ( ret = mpi_div_int( &Q, NULL, &Q, 2 ) ) != 0 ) 00078 { 00079 printf( " failed\n ! mpi_div_int returned %d\n\n", ret ); 00080 goto exit; 00081 } 00082 00083 if( ( ret = mpi_is_prime( &Q, havege_rand, &hs ) ) != 0 ) 00084 { 00085 printf( " failed\n ! mpi_is_prime returned %d\n\n", ret ); 00086 goto exit; 00087 } 00088 00089 printf( " ok\n . Exporting the value in dh_prime.txt..." ); 00090 fflush( stdout ); 00091 00092 if( ( fout = fopen( "dh_prime.txt", "wb+" ) ) == NULL ) 00093 { 00094 ret = 1; 00095 printf( " failed\n ! Could not create dh_prime.txt\n\n" ); 00096 goto exit; 00097 } 00098 00099 if( ( ret = mpi_write_file( "P = ", &P, 16, fout ) != 0 ) || 00100 ( ret = mpi_write_file( "G = ", &G, 16, fout ) != 0 ) ) 00101 { 00102 printf( " failed\n ! mpi_write_file returned %d\n\n", ret ); 00103 goto exit; 00104 } 00105 00106 printf( " ok\n\n" ); 00107 fclose( fout ); 00108 00109 exit: 00110 00111 mpi_free( &Q, &P, &G, NULL ); 00112 #else 00113 printf( "\n ! Prime-number generation is not available.\n\n" ); 00114 #endif 00115 00116 #ifdef WIN32 00117 printf( " Press Enter to exit this program.\n" ); 00118 fflush( stdout ); getchar(); 00119 #endif 00120 00121 return( ret ); 00122 }