diff options
Diffstat (limited to 'src/tspi/daa/big_integer')
-rw-r--r-- | src/tspi/daa/big_integer/bi.c | 237 | ||||
-rw-r--r-- | src/tspi/daa/big_integer/bi_gmp.c | 261 | ||||
-rw-r--r-- | src/tspi/daa/big_integer/bi_openssl.c | 181 | ||||
-rw-r--r-- | src/tspi/daa/big_integer/test/Makefile.am | 9 | ||||
-rw-r--r-- | src/tspi/daa/big_integer/test/multi_exp.c | 29 | ||||
-rw-r--r-- | src/tspi/daa/big_integer/test/test.c | 296 |
6 files changed, 1013 insertions, 0 deletions
diff --git a/src/tspi/daa/big_integer/bi.c b/src/tspi/daa/big_integer/bi.c new file mode 100644 index 0000000..b86b2c1 --- /dev/null +++ b/src/tspi/daa/big_integer/bi.c @@ -0,0 +1,237 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <bi.h> + +#include "tcslog.h" + +#undef INLINE_DECL +#define INLINE_DECL + +/*********************************************************************************** + CONSTANT +*************************************************************************************/ + +bi_t bi_0; +bi_t bi_1; +bi_t bi_2; + +/*********************************************************************************** + WORK VARIABLE +*************************************************************************************/ + +// Buffer to load bi from a file . A static field is used, this should not be +// refere in any SPI calls. +#define BUFFER_SIZE 10000 +static char buffer[BUFFER_SIZE]; // used for loading bi + +#define SAFETY_PARAM 80 + +// keep the list of allocated memory, usually used for the format functions +list_ptr allocs = NULL; + +/*********************************************************************************** + DUMP LIB +*************************************************************************************/ + +// !! to use only for debugging +// do not used it in the same call, as a static buffer is used +char *dump_byte_array(int len, unsigned char *array) { + int i, j=0; + char c, str[3]; + + for( i=0; i<len; i++) { + c = array[i]; + sprintf( str, "%02X", (int)(c & 0xFF)); + buffer[j] = str[0]; + buffer[j+1] = str[1]; + j+=2; + } + buffer[j] = 0; + return buffer; +} + +/* convert <strings> and return it into a byte array <result> of length <length> */ +unsigned char *retrieve_byte_array( int *len, const char *strings) { + int index_str = 0, index_result = 0; + int str_len = strlen( strings); + char read_buffer[3]; + int c; + unsigned char *result; + + read_buffer[2]=0; + *len = ( str_len >> 1); + #ifdef BI_DEBUG + printf("[%s]\n", strings); + printf("[retrieve_byte_array] strlen=%d len=%d\n", str_len, *len); + #endif + result = (unsigned char *)malloc( *len+1); + if( result == NULL) { + LogError("malloc of %d bytes failed", *len+1); + return NULL; + } + if( (str_len & 1) ==1) { + // impair => 1 12 23 -> 01 12 23 + read_buffer[0]='0'; + read_buffer[1]=strings[index_str++]; + sscanf( read_buffer, "%2X", &c); + #ifdef BI_DEBUG + printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer); + #endif + result[index_result++] = c&0xFF; + (*len)++; + } + while( index_str < str_len) { + read_buffer[0] = strings[ index_str++]; + read_buffer[1] = strings[ index_str++]; + sscanf( read_buffer, "%02X", &c); + #ifdef BI_DEBUG + printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer); + #endif + result[index_result++] = c&0xFF; + } + return result; +} + +/* create a <big integer> array */ +INLINE_DECL void bi_new_array( bi_array array, const int length) { + int i=0; + + bi_new_array2( array, length); + if( array->array == NULL) return; + for( i = 0; i< length; i++) { + array->array[i] = bi_new_ptr(); + } +} + +/* create a <big integer> array */ +INLINE_DECL void bi_new_array2( bi_array array, const int length) { + array->length = length; + array->array = (bi_ptr *)malloc( sizeof(bi_ptr) * length); + if( array->array == NULL) { + LogError("malloc of %d bytes failed", sizeof(bi_ptr)*length); + return; + } +} + +/* free resources allocated to the big integer <i> */ +INLINE_DECL void bi_free_array(bi_array array) { + int length = array->length; + int i=0; + + for( i = 0; i< length; i++) { + bi_free_ptr( array->array[i]); + } + free( array->array); +} + +/* copy length pointers from the array <src, offset_src> to array <dest, offset_dest> */ +INLINE_DECL void bi_copy_array(bi_array_ptr src, + int offset_src, + bi_array_ptr dest, + int offset_dest, + int length) { + int i=0; + + for( i = 0; i< length; i++) { + dest->array[ offset_dest + i] = src->array[ offset_src + i]; + } +} + +/* debug function -> dump a field of type bi_array */ +void dump_bi_array( char *field, const bi_array_ptr array) { + int i; + + for( i=0; i<array->length; i++) { + printf("%s->array[%d] = %s\n", field, i, bi_2_hex_char(array->array[i])); + } +} + +/*********************************************************************************** + SAFE RANDOM +*************************************************************************************/ + +/* Returns a random number in the range of [0,element-1] */ +bi_ptr compute_random_number( bi_ptr result, const bi_ptr element) { + bi_urandom( result, bi_length( element) + SAFETY_PARAM); + bi_mod( result, result, element); + return result; +} + +/*********************************************************************************** + SAVE / LOAD +*************************************************************************************/ + +/* load an big integer from an open file handler */ +void bi_load( bi_ptr bi, FILE *file) { + int i=0; + char c; + + fgets( buffer, BUFFER_SIZE, file); + do { + c = buffer[i]; + i++; + } while( c != 0 && c != ' '); + buffer[i-1] = 0; + bi_set_as_hex( bi, buffer); +} + +/* load an big integer array from an open file handler */ +void bi_load_array( bi_array_ptr array, FILE *file) { + int i, j = 0, length; + char c; + + fgets( buffer, BUFFER_SIZE, file); + do { + c = buffer[ j]; + j++; + } while( c != 0 && c != ' '); + buffer[ j -1] = 0; + sscanf( buffer, "%d", &length); + bi_new_array( array, length); + for( i=0; i<array->length; i++) { + bi_load( array->array[i], file); + } +} + +/* save an big integer to an open file handler */ +void bi_save( const bi_ptr bi, const char *name, FILE *file) { + fprintf( file, "%s # %s [%ld]\n", bi_2_hex_char( bi), name, bi_nbin_size( bi)); +} + +/* save an big integer array to an open file handler */ +void bi_save_array( const bi_array_ptr array, const char *name, FILE *file) { + int i; + char new_name[100]; + + fprintf(file, "%d # %s.length\n", array->length, name); + for( i=0; i<array->length; i++) { + sprintf( new_name, "%s[%d]", name, i); + bi_save( array->array[i], new_name, file); + } +} + +/* convert <bi> to a byte array of length result, the beginning of */ +/* this buffer is feel with '0' if needed */ +void bi_2_byte_array( unsigned char *result, int length, bi_ptr bi) { + int i, result_length; + + bi_2_nbin1( &result_length, buffer, bi); + int delta = length - result_length; + #ifdef BI_DEBUG + fprintf( stderr, "[bi_2_byte_array] result_length=%d length=%d\n", result_length, length); + #endif + if( delta < 0) { + LogError( "[bi_2_byte_array] asked length:%d found:%d\n", length, result_length); + return; + } + for( i=0; i<delta; i++) result[i] = 0; + for( ; i<length; i++) result[ i] = buffer[ i - delta]; +} diff --git a/src/tspi/daa/big_integer/bi_gmp.c b/src/tspi/daa/big_integer/bi_gmp.c new file mode 100644 index 0000000..f03bf4c --- /dev/null +++ b/src/tspi/daa/big_integer/bi_gmp.c @@ -0,0 +1,261 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#ifdef BI_GMP + +#include <time.h> +#include <stdio.h> +#include <stdlib.h> + +#include <bi.h> + +#undef INLINE_DECL +#define INLINE_DECL + +gmp_randstate_t state; + +/* + reps controls how many tests should be done in mpz_probable_prime_p: + 5 to 10 are reasonable number +*/ +static int reps = 20; + +static int initialized = 0; +void * (*bi_alloc)(size_t size); + +/*********************************************************************************** + BITS OPERATION +*************************************************************************************/ + +// for conversion from and to byte[] see mpz_export and mpz_import + +/* return the size of a network byte order representation of <i> */ +long bi_nbin_size(const bi_ptr i) { + int word_size = 1; // 1 byte per word + int numb = 8 * word_size - 0; + int count = (mpz_sizeinbase ( i, 2) + numb-1) / numb; + + return count * word_size; +} + +/* return a BYTE * - in network byte order - and update the length <length> */ +unsigned char *bi_2_nbin( int *length, const bi_ptr i) { + unsigned char *buffer = (unsigned char *)bi_alloc( bi_nbin_size( i)); + + if( buffer == NULL) return NULL; + mpz_export(buffer, length, 1, 1, 1, 0, i); + return buffer; +} + +/* return a BYTE * - in network byte order - and update the length <length> */ +/* different from bi_2_nbin: you should reserve enough memory for the storage */ +void bi_2_nbin1( int *length, unsigned char *buffer, const bi_ptr i) { + mpz_export(buffer, length, 1, 1, 1, 0, i); +} + +/* return a bi_ptr that correspond to the big endian encoded BYTE array of length <n_length> */ +INLINE_DECL bi_ptr bi_set_as_nbin( const unsigned long length, const unsigned char *buffer) { + bi_ptr ret = bi_new_ptr(); + + if( ret == NULL) return NULL; + mpz_import( ret, length, 1, 1, 1, 0, buffer); + return ret; +} + + +/*********************************************************************************** + BASIC MATH OPERATION +*************************************************************************************/ + +/* multiple-exponentiation */ +/* <result> := mod( Multi( <g>i, <e>i), number of byte <m>) with 0 <= i <= <n> */ +bi_ptr bi_multi_mod_exp( bi_ptr result, + const int n, + const bi_t g[], + const long e[], + const int m) { + mpz_t temp, bi_m; + int i; + + mpz_init( temp); + mpz_init( bi_m); + mpz_set_si( bi_m, m); + // result := (g[0] ^ e[0]) mod m + mpz_powm_ui( result, g[0], e[0], bi_m); + for( i=1; i<n; i++) { + // temp := (g[i] ^ e[i]) mod bi_m + mpz_powm_ui( temp, g[i], e[i], bi_m); + // result := result * temp + mpz_mul( result, result, temp); + } + mpz_mod_ui( result, result, m); + mpz_clear( bi_m); + mpz_clear( temp); + return result; +} + +/*********************************************************************************** + NUMBER THEORIE OPERATION +*************************************************************************************/ +/* generate prime number of <length> bits */ +INLINE_DECL bi_ptr bi_generate_prime( bi_ptr result, const long length) { + do { + mpz_urandomb( result, state, length); // i := random( length) + bi_setbit( result, 0); + bi_setbit( result, length - 1); + bi_setbit( result, length - 2); + mpz_nextprime( result, result); // i := nextPrime( i) + } while( mpz_sizeinbase( result, 2) != (unsigned long)length && + bi_is_probable_prime( result) ); + return result; +} + +/* generate a safe prime number of <length> bits */ +/* by safe we mean a prime p so that (p-1)/2 is also prime */ +INLINE_DECL bi_ptr bi_generate_safe_prime( bi_ptr result, long length) { + mpz_t temp; + + mpz_init(temp); + do { + bi_generate_prime( result, length); + mpz_sub_ui( temp, result, 1); // temp := result - 1 + mpz_div_2exp( temp, temp, 1); // temp := temp / 2 + } while( mpz_probab_prime_p( temp, 10) == 0); +#ifdef BI_DEBUG + printf("GENERATE SAFE PRIME DONE");fflush(stdout); +#endif + mpz_clear( temp); + return result; +} + +/* return true if <i> is a probably prime */ +INLINE_DECL int bi_is_probable_prime( bi_ptr i) { + /* + This function does some trial divisions and after some Miller-Rabin probabilistic + primality tests. The second parameter controls how many tests should be done, + 5 to 10 are reasonable number + */ + return mpz_probab_prime_p( i, reps)>=1 ? 1 : 0; +} + +/* return in <result> the greatest common divisor of <a> and <b> */ +/* <result> := gcd( <a>, <b>) */ +INLINE_DECL bi_ptr bi_gcd( bi_ptr result, bi_ptr a, bi_ptr b) { + // result := gcd( a, b) + mpz_gcd( result, a, b); + return result; +} + + +/*********************************************************************************** + INIT/RELEASE LIBRARY +*************************************************************************************/ + +/* bi_alloc_p allocation function used only for exporting a bi struct, so for bi_2_nbin +if define as NULL, a stdlib malloc() will be used */ +void bi_init( void * (*bi_alloc_p)(size_t size)) { + time_t start; + unsigned long seed; + FILE *f; +#ifdef INTERACTIVE + int c, i; +#endif + + if( initialized == 1) return; + if( bi_alloc_p == NULL) bi_alloc = &malloc; + else bi_alloc = bi_alloc_p; + mpz_init( bi_0); + mpz_set_ui( bi_0, 0); + mpz_init( bi_1); + mpz_set_ui( bi_1, 1); + mpz_init( bi_2); + mpz_set_ui( bi_2, 2); + allocs = list_new(); + if( allocs == NULL) { + LogError("malloc of list failed"); + return; + } +#ifdef BI_DEBUG + printf("bi_init() -> gmp lib\n"); +#endif + time( &start); + // first try /dev/random, the most secure random generator + f = fopen("/dev/random", "r"); + // in case of failure, but les secure :( + if( f== NULL) f = fopen("/dev/urandom", "r"); + if( f != NULL) { + fread( &seed, sizeof(unsigned long int), 1, f); + fclose(f); + } +#ifdef INTERACTIVE + else { + printf("! devices /dev/random and /dev/urandom not found\n"); + printf("type some characters to generate a random seed (follow by enter)\n"); + fflush(stdout); + i=0; + while( (c = fgetc(stdin)) != 10) { + time_t temps; + time( &temps); + seed += temps +( c << i); + i++; + } + time_t temps; + time( &temps); + seed += temps; +#ifdef BI_DEBUG + printf("temps=%lx\n", temps - start); +#endif // BI_DEBUG + seed = (long)( temps * start); + } +#endif // INTERACTIVE +#ifdef BI_DEBUG + printf("seed=%lx\n", seed); +#endif + gmp_randinit_default( state); + gmp_randseed_ui( state, seed); + initialized = 1; +} + +void bi_release(void) { + if( initialized) { + bi_flush_memory(); + bi_free( bi_0); + bi_free( bi_1); + bi_free( bi_2); + initialized = 0; + } +} +void bi_flush_memory(void) { + node_t *current; + list_ptr list = allocs; + + if( list->head == NULL) return; // list is empty + else { + current = list->head; // go to first node + do { + LogDebug("[flush memory] free %lx\n", current->obj); + free( current->obj); + current = current->next; // traverse through the list + } while(current != NULL); // until current node is NULL + } + list_freeall( allocs); + allocs = list_new(); + if( allocs == NULL) { + LogError("malloc of list failed"); + return; + } +} + + +int bi_is_initialized(void) { + return initialized; +} + +#endif diff --git a/src/tspi/daa/big_integer/bi_openssl.c b/src/tspi/daa/big_integer/bi_openssl.c new file mode 100644 index 0000000..50ef030 --- /dev/null +++ b/src/tspi/daa/big_integer/bi_openssl.c @@ -0,0 +1,181 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#ifdef BI_OPENSSL + +#define INSIDE_LIB + +#include <time.h> +#include <stdio.h> +#include <stdlib.h> + +#include <bi.h> + +#include "tcslog.h" + +#undef INLINE_DECL +#define INLINE_DECL + +#include <string.h> +#include <openssl/rand.h> + +BN_CTX *context; +static int initialized = 0; + +void * (*bi_alloc)(size_t size); + +/* return true if <i> is a probably prime */ +INLINE_DECL int bi_is_probable_prime( const bi_ptr i) { + /* + * start tests using some small prime numbers. Continue by performing a Miller-Rabin + * probabilistic primality test with checks iterations, and with some iterations that + * yields a false positive rate of at most 2^-80 for random input. + * return: + * 0 if the number is composite + * 1 if it is prime with an error probability of less than 0.25^checks, and on error. + */ + return BN_is_prime_fasttest( i, BN_prime_checks, NULL, context, NULL, 1); +} + +/* <result> := ( <g> ^ <e> ) mod <m> */ +INLINE_DECL bi_ptr bi_mod_exp_si( bi_ptr result, const bi_ptr g, const bi_ptr e, const long m) { + bi_t bi_tmp; + + bi_new( bi_tmp); + BN_set_word( bi_tmp, m); +#ifdef BI_DEBUG + printf("[bi_mod_exp] (g=%s ^ e=%s) mod=%s\n", + BN_bn2dec( g), + BN_bn2dec( e), + BN_bn2dec( bi_tmp)); +#endif + BN_mod_exp( result, g, e, bi_tmp, context); // result := (g ^ e) mod bi_tmp9 +#ifdef BI_DEBUG + printf("[bi_mod_exp] res=%s\n", BN_bn2dec( result)); +#endif + bi_free( bi_tmp); + return result; +} + +/* multiple-exponentiation */ +/* <result> := mod( Multi( <g>i, <e>i), number of byte <m>) with 0 <= i <= <n> */ +bi_ptr bi_multi_mod_exp( bi_ptr result, + const int n, + const bi_t g[], + const long e[], + const int m +) { + BIGNUM *temp = BN_new(); + BIGNUM *bi_m = BN_new(); + BIGNUM *bi_e = BN_new(); + int i; + + BN_set_word( bi_m, m); + BN_set_word( bi_e, e[0]); + // result := (g[0] ^ e[0]) mod bi_m + BN_mod_exp( result, g[0], bi_e, bi_m, context); + for( i=1; i<n; i++) { + BN_set_word( bi_e, e[i]); + // temp := (g[i] ^ e[i]) mod bi_m + BN_mod_exp( temp, g[i], bi_e, bi_m, context); + // result := result * temp + BN_mul( result, result, temp, context); + } + BN_mod( result, result, bi_m, context); + BN_free(bi_e); + BN_free(bi_m); + BN_free(temp); + return result; +} + + +/*********************************************************************************** + INIT/RELEASE LIBRARY +************************************************************************************/ + +/* bi_alloc_p allocation function used only for exporting a bi struct, +so for bi_2_nbin? for example. if define as NULL, a stdlib malloc() will be used +*/ +void bi_init( void * (*bi_alloc_p)(size_t size)) { + if( initialized == 1) return; + if( bi_alloc_p == NULL) bi_alloc = &malloc; + else bi_alloc = bi_alloc_p; + bi_new( bi_0); + bi_set_as_si( bi_1, 0); + bi_new( bi_1); + bi_set_as_si( bi_1, 1); + bi_new( bi_2); + bi_set_as_si( bi_2, 2); + allocs = list_new(); + if( allocs == NULL) { + LogError("malloc of list failed"); + return; + } + LogDebug("bi_init() -> openssl lib\n"); + LogDebug("bi_init() -> seed status = %d\n", RAND_status()); + context = BN_CTX_new(); + if( RAND_status() != 1) { + LogError("! PRNG has not been seeded with enough data\n"); +#ifdef INTERACTIVE + printf("type some characters to regenerate a random seed\n"); + fflush(stdout); + int c, i=0, seed; + char str[2] = "a"; + while( RAND_status() !=1 ) { + c = fgetc(stdin); + time_t temps; + time( &temps); + seed += temps +( c << i); + i++; + str[0]=c; + RAND_seed( str, 1); + } +#endif + } + initialized = 1; +} + +void bi_release(void) { + if( initialized) { + bi_flush_memory(); + bi_free( bi_0); + bi_free( bi_1); + bi_free( bi_2); + BN_CTX_free( context); + initialized = 0; + } +} + +void bi_flush_memory(void) { + node_t *current; + list_ptr list = allocs; + + if( list->head == NULL) return; // list is empty + else { + current = list->head; // go to first node + do { + LogDebug("[flush memory] free %lx\n", (long)current->obj); + free( current->obj); + current = current->next; // traverse through the list + } while(current != NULL); // until current node is NULL + } + list_freeall( allocs); + allocs = list_new(); + if( allocs == NULL) { + LogError("malloc of list failed"); + return; + } +} + +int bi_is_initialized(void) { + return initialized; +} + +#endif diff --git a/src/tspi/daa/big_integer/test/Makefile.am b/src/tspi/daa/big_integer/test/Makefile.am new file mode 100644 index 0000000..d631c2a --- /dev/null +++ b/src/tspi/daa/big_integer/test/Makefile.am @@ -0,0 +1,9 @@ +bin_PROGRAMS = test + + +test_SOURCES=test.c multi_exp.c ../bi_gmp.c ../bi_openssl.c ../bi.c \ + ../../../include/bi.h ../../../include/bi_openssl.h ../../../include/bi_gmp.h +test_CFLAGS=-G + +# test_CFLAGS=-I../../../include -DBI_OPENSSL + diff --git a/src/tspi/daa/big_integer/test/multi_exp.c b/src/tspi/daa/big_integer/test/multi_exp.c new file mode 100644 index 0000000..2ff80fc --- /dev/null +++ b/src/tspi/daa/big_integer/test/multi_exp.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +#include <bi.h> + +// use standard C definition to avoid .h +int test_exp_multi(void) { + bi_t result; + bi_t g[3]; + unsigned long e[3]; + + bi_new( result); + bi_new( g[0]); + bi_new( g[1]); + bi_new( g[2]); + // result = (2^2 * 5^4 * 7^7) mod 56 -> should give 28 + bi_set_as_dec( g[0], "2"); + bi_set_as_dec( g[1], "5"); + bi_set_as_dec( g[2], "7"); + e[0] = 2L; + e[1] = 4L; + e[2] = 7L; + bi_multi_mod_exp( result, 3, g, e, 56); + printf("multi-exponentiation <result>=%s\n", bi_2_dec_char(result)); + bi_free( g[0]); + bi_free( g[1]); + bi_free( g[2]); + bi_free( result); + return 0; +} diff --git a/src/tspi/daa/big_integer/test/test.c b/src/tspi/daa/big_integer/test/test.c new file mode 100644 index 0000000..4cc3a7f --- /dev/null +++ b/src/tspi/daa/big_integer/test/test.c @@ -0,0 +1,296 @@ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#include <bi.h> + +/* for the logging system used by TSS */ +setenv("TCSD_FOREGROUND", "1", 1); + + /* + * standard bit length extension to obtain a uniformly distributed number + * [0,element] + */ +int test_exp_multi(void); + +void foo (bi_t result, const bi_ptr param, unsigned long n) { + unsigned long i; + + bi_set( result, param); + bi_mul_si( result, result, n); + for (i = 1; i < n; i++) bi_add_si( result, result, i*7); +} + +void *my_malloc(size_t size) { + void *ret = malloc( size); + + printf("my_malloc() -> %ld\n", (long)ret); + return ret; +} + + /** + * Returns a random number in the range of [0,element-1]. + * + * @param element + * the upper limit + * @param random + * the secure random source + * @return the random number + */ +void computeRandomNumber(bi_t res, const bi_ptr element) { + int length = 80 + bi_length( res); // give the length + bi_urandom( res, length); // res = random( of length); + int element_length = bi_length( element); + bi_mod_si( res, res, element_length); // res = res mod <number byte of element> +} + +int main (int argc, char **argv) { + bi_t bi_tmp, bi_tmp1, bi_tmp2, bi_tmp3, bi_tmp4, bi_tmp5, bi_tmp6; + bi_t r; + bi_t n; + int i; + unsigned char result1[5]; + int len; + char *byte_array; + FILE *file; + unsigned char ret[] = { (unsigned char)1, 0, (unsigned char)254 }; + int length; + unsigned char *buffer; + unsigned char byte; + bi_ptr nn; + + bi_init( &my_malloc); + printf("test(%s,%s)\n", __DATE__, __TIME__); + #ifdef BI_GMP + printf("using BMP\n"); + #endif + #ifdef BI_OPENSSL + printf("using OPENSSL\n"); + #endif + + bi_new( bi_tmp); + bi_new( bi_tmp1); + bi_new( bi_tmp2); + bi_new( bi_tmp3); + bi_new( bi_tmp4); + bi_new( bi_tmp5); + bi_new( bi_tmp6); + bi_new( n); + bi_new( r); + bi_set_as_hex( n, "75E8F38669C531EB78C7ACD62CCDEFFB5E5BE15E2AA55B3AD28B1A35F6E937097CE09A49C689AC335FBA669205CEF209275CFF273F8F81C5B864E5029EECDFA0743BC15D6E4D2C2CB0DED2DC7119A7E0D61669D417BB3B12BA1D10FD40326A49CA6C9E77F8585F25D8C897D9C73284152E103582C018C964F02ADDBA56CB1161A949AAE2847ADE8BC1152716C8B4AF37A87011C2569F646FD3EDA83099048B9525A6401C47A372F3EA43C91066AD5851AE11DEF1EAC7108FFB06AD94D0B849C339A5E8793C4C054456D3D22D30ACCCF7EF33EF7A7D65799E7908D95B0538A9EFC91BF104CE5008D79625394DB1E5883B2F202B95320BBD868BF65C996FC0DFC5"); + bi_set_as_hex( r, "35A624E6607CFD37162C6052547450B2267ECC749F10CDAEB5C294491321EEB47CA0229F423ADCEF3FA7806F5C4DB3C3445D8E7039EBC457149A1343BECF3B1078385C06EE74351A476BE0D5203633C81F7B8D68548DB763F0C096B20615B6016C180291EF32CC064A173BB22F6B46B3240ACC0B50D8338757FA28D5B0313BC4201CD2B35472842E71994C8FCA557B08004B2495304D13A93D796134BB8078E2EE371707DE5809D72474A7CCE1F865ECD8876105D3DB9AFA9426052D0120C755C60F56A0C0F30FAED2053CEB3129FAB6F57F6E209A8E7B2A559D734B339E19E1F2A147BC94DB2FF491CB5ACCEEEED7F2EA75AFF7CAD33E1E420A09135D9C5C1F"); + DUMP_BI( n); + DUMP_BI( r); + printf("big number n=n*r\n"); + bi_mul( n, n, r); + DUMP_BI( n); + bi_set_as_hex( r, "D7E7028DA181DADAC29C95143C865702453465115AFA7576AADF1E57DD84DA7FF4C8F66530D1E9D1AB69BC12342B89FA0A9755F9F4EE1DA445D50016CEF50622ED905CC9B987FCC7910CAA841641814C1994BC442A15CB05FE5C145626F1454E90435FBC6A529856EF29BDBCBFCB62FB69EDBD11DC33357667867278E1679EABCDBEEA02E9A6911804DF47ACA6B2D63A31E258AD542D71A8178A5E072F5E221EADBB10E16D5533AE427101FF94C5967575FABCD18305C5F15C103CEA1A8ACD01898E88426EDA7C0DF58AA48435808A840F6EEE1D7205D33F356E20FE0D4136B401BF386F11869C3CE4A808B96435694748EF3706F58756548A71E4CF4D2BE157"); + bi_mod( n, n, r); + printf("mod big number n=n mod r\n"); + DUMP_BI( n); + if( bi_get_si( bi_set_as_si( n, 13)) != 13) { + printf("!!! bi_set_as_si 13(%s) = 13\n", bi_2_dec_char( n )); + exit(-1); + } + if( bi_get_si( bi_set_as_si( n, -13)) != -13) { + printf("!!! bi_set_as_si -13(%s) = -13\n", bi_2_dec_char( n )); + exit(-1); + } + if( bi_get_si( bi_inc(bi_set_as_si( n, 13))) != 14) { + puts("!!! bi_inc 13++ = 14\n"); + exit(-1); + } + if( bi_get_si( bi_dec(bi_set_as_si( n, 13))) != 12) { + puts("!!! bi_dec 13-- = 12\n"); + exit(-1); + } + if( bi_get_si( bi_setbit(bi_set_as_si( n, 0), 10)) != 1024) { + puts("!!! bi_setbit set[10] = 1024\n"); + exit(-1); + } + if( bi_get_si( bi_mod_si(bi_tmp, bi_set_as_si( n, 12), 10)) != 2) { + puts("!!! bi_mod_si 12 mod 10 = 2\n"); + exit(-1); + } + if( bi_get_si( bi_mul_si(bi_tmp, bi_set_as_si( n, 12), 10)) != 120) { + puts("!!! bi_mul_si 12 * 10 = 120\n"); + exit(-1); + } + if( bi_get_si( bi_mul(bi_tmp, bi_set_as_si( n, 12), bi_set_as_si( bi_tmp1, 10))) != 120) { + puts("!!! bi_mul_si 12 * 10 = 120\n"); + exit(-1); + } + if( bi_get_si( bi_mod_exp_si(bi_tmp, bi_set_as_si( bi_tmp1, 4), bi_2, 10)) != 6) { + puts("!!! bi_mod_exp_si 4 ^ 2 mod 10 = 6\n"); + exit(-1); + } + if( bi_get_si( bi_mod_exp(bi_tmp, bi_set_as_si( bi_tmp1, 4), bi_2, bi_set_as_si( bi_tmp2, 10))) != 6) { + puts("!!! bi_mod_exp 4 ^ 2 mod 10 = 6\n"); + exit(-1); + } + if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, 12), bi_set_as_si(bi_tmp1, 10))) != 2) { printf("!!! bi_mod 12 mod 10 = 2 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); } + if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, -12), bi_set_as_si(bi_tmp1, 10))) != 8) { printf("!!! bi_mod -12 mod 10 = 8 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); } + if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, -27), bi_set_as_si(bi_tmp1, 10))) != 3) { printf("!!! bi_mod -27 mod 10 = 3 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); } + bi_set_as_si(n, 0x12345678); + bi_2_byte_array( result1, 5, n); + if( result1[0] != 0x00 || result1[1] != 0x12 || result1[2] != 0x34 || result1[3] != 0x56 || result1[4] != 0x78 ) { + printf("!!! bi_2_byte_array[0x123456578] [0]=%x [1]=%x [2]=%x [3]=%x [4]=%x \n", result1[0], result1[1], result1[2], result1[3], result1[4]); + exit( -1); + } + byte_array = retrieve_byte_array( &len, "12345"); + printf("test dump_byte_array len=%d \n", len); + printf("test dump_byte_array(\"12345\")=%s\n", dump_byte_array( len, byte_array)); + free( byte_array); + byte_array = retrieve_byte_array( &len, "12345678"); + printf("test dump_byte_array len=%d \n", len); + printf("test dump_byte_array(\"12345678\")=%s\n", dump_byte_array( len, byte_array)); + + // test save end load of bi_t and bi_array + ///////////////////////////////////////////////////////////////////////////////////// + bi_array result; + bi_new_array( result, 2); + bi_set_as_si( bi_tmp, 6); + bi_set_as_si( result->array[0], 314159); + bi_set_as_si( result->array[1], 123456789); + file = fopen("/tmp/test.todel", "w"); + bi_save_array( result, "result", file); + bi_save( bi_tmp, "bi_tmp", file); + fclose( file); + bi_set_as_si( result->array[0], 0); + bi_set_as_si( result->array[1], 0); + bi_set_as_si( bi_tmp, 0); + file = fopen("/tmp/test.todel", "r"); + bi_load_array( result, file); + bi_load( bi_tmp, file); + fclose( file); + if( bi_get_si( result->array[0]) != 314159) { puts("!!! save/load array[0] = 314159\n"); exit(-1); } + if( bi_get_si( result->array[1]) != 123456789) { puts("!!! save/load array[1] = 123456789\n"); exit(-1); } + if( bi_get_si( bi_tmp) != 6) { puts("!!! save/load bi_tmp = 6\n"); exit(-1); } + + // conversion from bi_t 2 big endian BYTE* + ///////////////////////////////////////////////////////////////////////////////////// + bi_set_as_si( n, 254+(1 << 16)); + buffer = bi_2_nbin( &length, n); + printf("value 2 convert=%s length=%ld\n", bi_2_hex_char( n), bi_nbin_size( n)); + for( i=0; i<length; i++) { + byte = (unsigned char)(buffer[i] & 0xFF); + if( byte != ret[i]) { printf("\n!!! bi_2_nbin[%d] %x = %x\n", i, byte, ret[i]); exit(-1); } + printf("[buffer[%d]=%x]", i, (int)(byte)); + } + printf("\n"); + nn = bi_set_as_nbin( length, buffer); + if( bi_equals_si( nn, 254+(1 << 16) ) == 0) { + printf("\n!!! bi_set_as_nbin %s = %x\n", bi_2_hex_char( nn), 254+(1 << 16)); + exit(-1); + } + if( !bi_equals( bi_sub_si( bi_tmp, bi_set_as_si( bi_tmp1, 9), 1), + bi_mod( bi_tmp2, + bi_mul( bi_tmp3, bi_set_as_si(bi_tmp4, 6), + bi_set_as_si( bi_tmp5, 3)), + bi_set_as_si( bi_tmp6, 10)))) { + puts("!!! 9-1 == (6*3) mod 10\n"); + printf("!!! tmp(8) = %s tmp1(9)=%s tmp2(8)=%s tmp3(6*3)=%s tmp4(6)=%s\ + tmp5(3)=%s tmp6(10)=%s\n", + bi_2_dec_char(bi_tmp), + bi_2_dec_char(bi_tmp1), + bi_2_dec_char(bi_tmp2), + bi_2_dec_char(bi_tmp3), + bi_2_dec_char(bi_tmp4), + bi_2_dec_char(bi_tmp5), + bi_2_dec_char(bi_tmp6)); + exit(-1); + puts("!!! 9-1 == (6*3) mod 10\n"); exit(-1); + } + bi_set_as_si(n, 1); + bi_shift_left(n, n, 10); + printf("1 << 10 = %s\n", bi_2_dec_char( n)); + bi_set_as_si(n, 1); + printf("(1 << 10) >> 5 = %s\n", bi_2_dec_char( bi_shift_right(bi_tmp, bi_shift_left(bi_tmp1, n, 10), 5))); + bi_set_as_si(n, 1); + printf("[* (1 << 10) >> 5 *] = (2^10) / (2^5) -> %s\n", bi_2_dec_char( bi_shift_right( bi_tmp, ( bi_shift_left( bi_tmp1, n, 10)), 5))); + bi_set_as_si( n, 10); + printf(" (2^10) = %s\n", bi_2_dec_char( bi_mod_exp_si( bi_tmp, bi_2, n, 2000))); + printf(" (1<<5) = %s\n", bi_2_dec_char( bi_shift_left( bi_tmp, bi_set_as_si( bi_tmp1, 1), 5))); + printf(" 1024 / 500 = %s\n", bi_2_dec_char( bi_div( bi_tmp, bi_set_as_si( bi_tmp1, 1024), bi_set_as_si( bi_tmp2, 500)))); + printf(" 1024 / 500 = %s\n", bi_2_dec_char( bi_div_si( bi_tmp, bi_set_as_si( bi_tmp1, 1024), 500))); + printf(" (1 << 10) >> 5 = [* (2^10) / (2^5) *] -> %s\n", bi_2_dec_char( bi_div( bi_tmp1, + bi_mod_exp_si( bi_tmp2, bi_2, bi_set_as_si( bi_tmp3, 10), 2000), + bi_mod_exp_si( bi_tmp4, bi_2, bi_set_as_si( bi_tmp5, 5), 2000) ))); + + printf("(1 << 10) >> 5 = (2^10) / (1<<5) -> %d\n", bi_equals( bi_shift_right( bi_tmp, ( bi_shift_left( bi_tmp1, bi_1, 10)), 5), + bi_div( bi_tmp2, + bi_mod_exp_si( bi_tmp3, bi_2, bi_set_as_si( bi_tmp4, 10), 2000), + bi_mod_exp_si( bi_tmp5, bi_2, bi_set_as_si( bi_tmp6, 5), 2000)))); + printf("( 45 ^ -5 ) %% 10 == ( 1 / ( (45 ^ 5) %% 10) ) %% 10\n"); + bi_set_as_si( bi_tmp, 45); + bi_set_as_si( bi_tmp1, 5); + // bi_negate( bi_tmp1); + bi_set_as_si( bi_tmp2, 10); + bi_mod_exp( bi_tmp3, bi_tmp, bi_tmp1, bi_tmp2); + bi_set_as_si( bi_tmp1, 5); + bi_mod_exp( bi_tmp4, bi_tmp, bi_tmp1, bi_tmp2); + printf("\t( 45 ^ -5 ) %% 10 = %s\n", bi_2_dec_char( bi_tmp3)); + printf("\t( 1 / ( (45 ^ 5) %% 10) ) %% 10 = %s\n", bi_2_dec_char( bi_tmp4)); + if( bi_equals( bi_tmp3, bi_tmp4) == 0) { + printf("!!! error !\n"); + exit( -1); + } + for( i=0; i<5; i++) { + bi_generate_prime( bi_tmp, 1024); + printf("bi=%s\n", bi_2_hex_char( bi_tmp)); + printf("bi.length=%ld \n", bi_length( bi_tmp)); + if( bi_length( bi_tmp) != 1024) { puts("!!! length(random(1024)) != 1024\n"); exit(-1); } + } + bi_set_as_si(n, 0); + bi_setbit( n, 10); + printf("setbit(10) = %s\n", bi_2_dec_char( n)); + bi_set_as_dec(n, "123456"); + foo( r, n, 20L); + printf("TEST:%s\n", bi_2_dec_char( r)); + bi_urandom( n, 1024); + bi_urandom( r, 1024); + computeRandomNumber( r, n); + printf("r:%s n:%s\n", bi_2_hex_char( r), bi_2_hex_char( n)); + bi_generate_prime( r, 1024); + printf("prime:%s\nIs probable prime:%d\n", bi_2_hex_char( r), bi_is_probable_prime( r)); + int error = bi_invert_mod( r, r, n); + printf("Invert mod return:%d\nInvert(r):%s\n", error, bi_2_hex_char( r)); + bi_negate( r); + printf("negate(r):%s\n", bi_2_hex_char( r)); + bi_generate_safe_prime( r, 128); + bi_sub_si( n, r, 1); // n= r - 1 + bi_shift_right( n, n, 1); // n = n / 2 + printf("safe prime(r):%s probable_prime:%d\n", bi_2_hex_char( r), bi_is_probable_prime( r)); + printf("safe prime( (r-1)/2):%s probable_prime:%d\n", bi_2_hex_char( n), bi_is_probable_prime( n)); + test_exp_multi(); + bi_free( r); + bi_free( n); + + bi_set_as_si( result->array[0], 1); + printf("result-> 1<<20:%s\n", bi_2_dec_char( bi_shift_left( result->array[0], result->array[0], 20))); + bi_set_as_si( result->array[1], 1); + printf("result1-> 1<<10:%s\n", bi_2_dec_char( bi_shift_right( result->array[1], result->array[0], 10))); + // copy arrays + bi_array new_result; bi_new_array2( new_result, 4); + bi_new_array2( new_result, 4); + bi_copy_array( result, 0, new_result, 0, 2); + bi_copy_array( result, 0, new_result, 2, 2); + for( i = 0; i<4; i++) { + printf("new_result[%d]-> [even-> 1<<20] [odd-> 1<<10] :%s\n", i, bi_2_dec_char( new_result->array[i])); + } + + bi_free( bi_tmp); + bi_free( bi_tmp1); + bi_free( bi_tmp2); + bi_free( bi_tmp3); + bi_free( bi_tmp4); + bi_free( bi_tmp5); + bi_free( bi_tmp6); + bi_release(); + printf("THE END [%s,%s]\n", __DATE__, __TIME__); + fflush(stdout); + return 0; + +} + |