📄 ytest.c
字号:
/* -*- Mode: C; c-file-style: "bsd" -*- *//* * Yarrow - Cryptographic Pseudo-Random Number Generator * Copyright (c) 2000 Zero-Knowledge Systems, Inc. * * See the accompanying LICENSE file for license information. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include "yarrow.h"#include "yexcep.h"#include "ystate.h"void hex_print( FILE* f, const char* var, void* data, size_t size );void dump_yarrow_state( FILE* f, Yarrow_CTX* y );#define YARROW_SEED_FILE "seed"static void print_yarrow_status( Yarrow_CTX *y ){ int sid, pool; Source* source; for ( pool = 0; pool < 2; pool++ ) { printf( " %s: ", pool == YARROW_SLOW_POOL ? "slow" : "fast" ); for ( sid = 0; sid < y->num_sources; sid++ ) { source = &y->source[ sid ]; printf( "#%d=%d/%d, ", sid, source->entropy[pool], pool == YARROW_SLOW_POOL ? y->slow_thresh : y->fast_thresh ); } } printf( "\n" );}int yarrow_verbose = 0;#define VERBOSE( x ) if ( yarrow_verbose ) { x }int Instrumented_Yarrow_Input( Yarrow_CTX* y, int sid, void* sample, size_t size, int entropy ){ int ret; VERBOSE( printf( "Yarrow_Input( #%d, %d bits, %s ) = [", sid, entropy, y->source[sid].pool == YARROW_SLOW_POOL ? "slow" : "fast" ); ); ret = Yarrow_Input( y, sid, sample, size, entropy ); VERBOSE( printf( "%s]\n", Yarrow_Str_Error( ret ) ); ); VERBOSE( print_yarrow_status( y ); ); return (ret);}typedef int (*test_fn)( void );int test_1( void );int test_2( void );int test_3( void );int test_4( void );int test_5( void );test_fn test_func[] ={ test_1, test_2, test_3, test_4, test_5};#define num_tests ( sizeof(test_func) / sizeof(test_fn) )int do_test( int t ){ EXCEP_DECL; int ret; printf( "doing test %d ... ", t ); fflush( stdout ); ret = test_func[ t-1 ](); VERBOSE( printf( "\ndone test %d ", t ); ); printf( "[%s]\n", Yarrow_Str_Error( ret ) ); fflush( stdout ); THROW( ret ); CATCH: THROW( EXCEP_BOOL ); EXCEP_RET;}int main( int argc, char* argv[] ){ EXCEP_DECL; int test = 0; char** argvp; char* arg; char* conv_ok = NULL; int ok = YARROW_OK; int done_some_tests = 0; int i; int ret;#if defined(__MWERKS__) && defined(macintosh) argc = ccommand(&argv);#endif for ( argvp = argv+1, i = 1; i < argc; i++, argvp++ ) { arg = *argvp; if ( arg[0] == '-' ) { switch ( arg[1] ) { case 'v': yarrow_verbose = 1; continue; default: fprintf( stderr, "usage: test [-v] [[test] ... ]\n" ); THROW( YARROW_FAIL ); } } conv_ok = NULL; test = strtoul( arg, &conv_ok, 10 ); if ( !conv_ok || test < 1 || test > num_tests ) { fprintf( stderr, "usage: test [-v] [[test] ... ]\n" ); THROW( YARROW_FAIL ); } else { ret = do_test( test ); if ( ok ) { ok = ret; } done_some_tests = 1; } } if ( !done_some_tests ) { for ( i = 1; i <= num_tests; i++ ) { ret = do_test( i ); if ( ok ) { ok = ret; } } } THROW( ok ); CATCH: switch (EXCEPTION) { case YARROW_OK: exit( EXIT_SUCCESS ); default: exit( EXIT_FAILURE ); }}int printhex( FILE* f, byte* bin, int size ){ int i; for ( i = 0; i < size; i++ ) { if ( fprintf( f, "%02x", bin[i] ) != 2 ) { return YARROW_FAIL; } } return YARROW_OK;}int hex2bin( byte* bin, const char* hex, int size ){ int i, d; char pair[3]; if ( strlen( hex ) != size * 2 ) { return YARROW_FAIL; } pair[2]='\0'; for ( i = 0; i < size; i++ ) { pair[0] = hex[i*2]; pair[1] = hex[i*2+1]; if ( sscanf( pair, "%x", &d ) < 1 ) { return YARROW_FAIL; } bin[i] = (byte)d; } return YARROW_OK;}typedef struct { char* string; int reps; char* result;} Hash_Test;int test_1( void ){ EXCEP_DECL; byte digest[ HASH_DIGEST_SIZE ]; byte expected_digest[ HASH_DIGEST_SIZE ]; HASH_CTX hash; int i, j;#if defined(YARROW_HASH_SHA1) /* test vectors from FIPS-180-1 */ Hash_Test hash_test[] = { { "abc", 1, "A9993E364706816ABA3E25717850C26C9CD0D89D" } , { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1, "84983E441C3BD26EBAAE4AA1F95129E5E54670F1" }, { "aaaaaaaaaa", 100000, "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" } }; VERBOSE( printf( "\nsha1 test\n\n" ); );#elif defined(YARROW_HASH_MD5) /* test vectors from RFC1321 */ Hash_Test hash_test[] = { { "", 1, "d41d8cd98f00b204e9800998ecf8427e" }, { "a", 1, "0cc175b9c0f1b6a831c399e269772661" }, { "abc", 1, "900150983cd24fb0d6963f7d28e17f72" }, { "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0" }, { "abcdefghijklmnopqrstuvwxyz", 1, "c3fcd3d76192e4007dfb496cca67e13b" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1, "d174ab98d277d9f5a5611c2c9f419d9f" }, { "123456789012345678901234567890123456789012345678901234567890123456" "78901234567890", 1, "57edf4a22be3c955ac49da2e2107b67a" } }; VERBOSE( printf( "\nmd5 test\n\n" ); );#else VERBOSE( printf( "\nunknown hash function\n\n" ); ); THROW( YARROW_NOT_IMPL );#endif#define hash_test_num_tests ( sizeof( hash_test ) / sizeof( Hash_Test ) ) for ( i = 0; i < hash_test_num_tests; i++ ) { TRY( hex2bin( expected_digest, hash_test[ i ].result, HASH_DIGEST_SIZE ) ); VERBOSE( printf( "test %c\n", 'a'+i ); printf( "HASH( \"%s\" ", hash_test[ i ].string ); if ( hash_test[ i ].reps > 1 ) { printf( "x%d ", hash_test[ i ].reps ); } printf( ")\n" ); printf( "expected = " ); printhex( stdout, expected_digest, HASH_DIGEST_SIZE ); printf( "\n" ); ); HASH_Init( &hash ); for ( j = 0; j < hash_test[ i ].reps; j++ ) { HASH_Update( &hash, hash_test[ i ].string, strlen( hash_test[ i ].string ) ); } HASH_Final( &hash, digest ); VERBOSE( printf( "result = " ); printhex( stdout, digest, HASH_DIGEST_SIZE ); printf( "\n" ); ); if ( memcmp( digest, expected_digest, HASH_DIGEST_SIZE ) != 0 ) { THROW( YARROW_FAIL ); } } CATCH: EXCEP_RET;}int test_2( void ){ EXCEP_DECL;#if defined(YARROW_CIPHER_3DES) VERBOSE( printf( "\n3des test\n\n" ); ); THROW( YARROW_NOT_IMPL );#elif defined(YARROW_CIPHER_BLOWFISH) VERBOSE( printf( "\nblowfish test\n\n" ); ); THROW( YARROW_NOT_IMPL );#elif defined(YARROW_CIPHER_IDEA) VERBOSE( printf( "\nidea test\n\n" ); ); THROW( YARROW_NOT_IMPL );#else VERBOSE( printf( "\nunknown encryption function\n\n" ); ); THROW( YARROW_NOT_IMPL );#endif CATCH: EXCEP_RET;}int test_3( void ){ EXCEP_DECL;#if !defined(YARROW_CIPHER_3DES) || !defined(YARROW_HASH_SHA1) VERBOSE( printf( "\nnot Yarrow-SHA1-3DES (aka Yarrow-160)\n\n" ); ); THROW( YARROW_NOT_IMPL );#endif VERBOSE( printf( "\nYarrow_Stretch\n\n" ); ); THROW( YARROW_NOT_IMPL ); CATCH: EXCEP_RET;}int test_4( void ){ EXCEP_DECL;#if defined( YARROW_SAVE_STATE ) if ( unlink( YARROW_SEED_FILE ) != 0 && errno != ENOENT ) { THROW( YARROW_STATE_ERROR ); }#endif TRY( test_general() ); CATCH: EXCEP_RET;}int state_to_load = 0;int test_5( void ){ EXCEP_DECL; Yarrow_STATE state; byte* state_b = (byte*) &state; int i;#if !defined( YARROW_SAVE_STATE ) VERBOSE( print( "state saving off, so test not relevant\n" ); ); THROW( YARROW_OK );#endif for ( i = 0; i < sizeof( state ); i++ ) { state_b[ i ] = i % 256; } TRY( STATE_Save( YARROW_SEED_FILE, &state ) ); state_to_load = 1; TRY( test_general() ); CATCH: state_to_load = 0; EXCEP_RET;}int test_general( void ){ EXCEP_DECL; Yarrow_CTX yarrow; int initialized = 0; unsigned user, mouse, keyboard; int i, ret; byte user_sample[ 20 ]; byte mouse_sample[ 4 ]; byte keyboard_sample[ 2 ]; byte random[ 30 ]; byte expected_random[ 30 ]; byte junk[ 48 ]; Yarrow_STATE state; const char* expected_random_no_load_str = "0573f728da11381cfc7db5d386ad9a2f30e75c7df0411f307ed3c1000fdb"; const char* expected_random_with_load_str = "a02c2492cca9ac5f1244eb05cbccc9bc17cfd095f35307927ef7e2c5f881"; TRY( hex2bin( expected_random, state_to_load ? expected_random_with_load_str : expected_random_no_load_str, sizeof( expected_random ) ) ); memset( user_sample, 3, sizeof( user_sample ) ); memset( mouse_sample, 1, sizeof( mouse_sample ) ); memset( keyboard_sample, 2, sizeof( keyboard_sample ) ); VERBOSE( printf( "\nGeneral workout test" ); if ( state_to_load ) { printf( " with state to load" ); } printf( "\n\n" ); ); if ( !state_to_load ) { ret = STATE_Load( YARROW_SEED_FILE, &state ); if ( ret == YARROW_OK ) { VERBOSE( printf( "found state where there should be none\n" ); ); THROW( YARROW_STATE_ERROR ); } } VERBOSE( printf( "Yarrow_Init() = [" ); ); ret = Yarrow_Init( &yarrow, YARROW_SEED_FILE ); VERBOSE( printf( "%s]\n", Yarrow_Str_Error( ret ) ); ); if ( ret != YARROW_OK && ret != YARROW_NOT_SEEDED ) { THROW( ret ); } initialized = 1;#if defined( YARROW_DEBUG ) dump_yarrow_state( stdout, &yarrow );#endif ret = Yarrow_New_Source( &yarrow, &user ); VERBOSE( printf( "Yarrow_New_Source() = [%s]\n", Yarrow_Str_Error( ret ) ); ); if ( ret != YARROW_OK ) { THROW( ret ); } VERBOSE( printf( "Yarrow_Poll( #%d ) = [", user ); ); ret = Yarrow_Poll( &yarrow, user ); VERBOSE( printf( "%s]\n", Yarrow_Str_Error( ret ) ); ); ret = Yarrow_New_Source( &yarrow, &mouse ); VERBOSE( printf( "Yarrow_New_Source() = [%s]\n", Yarrow_Str_Error( ret ) ); ); if ( ret != YARROW_OK ) { THROW( ret ); } ret = Yarrow_New_Source( &yarrow, &keyboard ); VERBOSE( printf( "Yarrow_New_Source() = [%s]\n", Yarrow_Str_Error( ret ) ); ); if ( ret != YARROW_OK ) { THROW( ret ); }/* prematurely try to draw output, to check failure when no * seed file, or state saving turned off */ VERBOSE( printf( "Yarrow_Output( %d ) = [", (int)sizeof( random ) ); ); ret = Yarrow_Output( &yarrow, random, sizeof( random ) ); VERBOSE( printf( "%s]\n", Yarrow_Str_Error( ret ) ); );/* do it twice so that we some slow samples * (first sample goes to fast pool, and then samples alternate) */ for ( i = 0; i < 2; i++ ) { TRY( Instrumented_Yarrow_Input( &yarrow, mouse, mouse_sample, sizeof( mouse_sample ), 2 ) ); TRY( Instrumented_Yarrow_Input( &yarrow, keyboard, keyboard_sample, sizeof( keyboard_sample ), 2 ) ); TRY( Instrumented_Yarrow_Input( &yarrow, user, user_sample, sizeof( user_sample ), 2 ) ); } #if defined( YARROW_DEBUG ) dump_yarrow_state( stdout, &yarrow );#endif VERBOSE( printf( "\nInduce user source (#%d) to reach " "slow threshold\n\n", user ); ); /* induce fast reseed */ for ( i = 0; i < 7; i++ ) { TRY( Instrumented_Yarrow_Input( &yarrow, user, user_sample, sizeof( user_sample ), sizeof( user_sample ) * 3 ) ); } VERBOSE( printf( "\nInduce mouse source (#%d) to reach " "slow threshold reseed\n\n", mouse ); ); /* induce slow reseed, by triggering a second source to reach it's threshold */ for ( i = 0; i < 40; i++ ) { TRY( Instrumented_Yarrow_Input( &yarrow, mouse, mouse_sample, sizeof( mouse_sample ), sizeof( mouse_sample )*2 ) ); } VERBOSE( printf( "\nProduce some output\n\n" ); ); for ( i = 0; i < 30; i++ ) { VERBOSE( printf( "Yarrow_Output( %d ) = [", (int)sizeof( junk ) ); ); ret = Yarrow_Output( &yarrow, junk, sizeof( junk ) ); VERBOSE( printf( "%s]\n", Yarrow_Str_Error( ret ) ); ); if ( ret != YARROW_OK ) { THROW( ret ); } } memset( junk, 0, sizeof( junk ) ); VERBOSE( printf( "\nTrigger some fast and slow reseeds\n\n" ); ); for ( i = 0; i < 30; i++ ) { /* odd input to a different source so there are some slow reseeds */ if ( i % 16 == 0 ) { TRY( Instrumented_Yarrow_Input( &yarrow, mouse, junk, sizeof( junk ), sizeof( junk ) * 3 ) ); } else { TRY( Instrumented_Yarrow_Input( &yarrow, user, junk, sizeof( junk ), sizeof( junk ) * 3 ) ); } } VERBOSE( printf( "\nPrint some random output\n\n" ); ); VERBOSE( hex_print( stdout, "expected random", expected_random, sizeof( expected_random ) ); ); VERBOSE( printf( "Yarrow_Output( %d ) = [", (int)sizeof( random ) ); ); ret = Yarrow_Output( &yarrow, random, sizeof( random ) ); VERBOSE( printf( "%s]\n", Yarrow_Str_Error( ret ) ); ); VERBOSE( hex_print( stdout, "result random", random, sizeof( random ) ); ); if ( ret != YARROW_OK ) { THROW( ret ); } VERBOSE( printf( "\nClose down Yarrow\n\n" ); ); CATCH: if ( initialized ) { VERBOSE( printf( "Yarrow_Final() = [" ); ); ret = Yarrow_Final( &yarrow ); VERBOSE( printf( "%s]\n", Yarrow_Str_Error( ret ) ); ); THROW( ret ); } EXCEP_RET;}void hex_print( FILE* f, const char* var, void* data, size_t size ){ const char* conv = "0123456789abcdef"; size_t i; char* p = (char*) data; char c, d; fprintf( f, var ); fprintf( f, " = " ); for ( i = 0; i < size; i++ ) { c = conv[ (p[ i ] >> 4) & 0xf ]; d = conv[ p[ i ] & 0xf ]; fprintf( f, "%c%c", c, d ); } fprintf( f, "\n" );}void dump_yarrow_state( FILE* f, Yarrow_CTX* y ){ fprintf( f, "===Yarrow State===\n" ); hex_print( f, "C", y->C, sizeof( y->C ) ); hex_print( f, "K", y->K, sizeof( y->K ) );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -