2005-04-17 07:37:13 -04:00
# include <tomcrypt_test.h>
2003-07-10 22:09:41 -04:00
2005-04-17 07:37:13 -04:00
prng_state yarrow_prng ;
2003-12-24 13:59:57 -05:00
2005-04-17 07:37:13 -04:00
struct list results [ 100 ] ;
2003-12-24 13:59:57 -05:00
int no_results ;
int sorter ( const void * a , const void * b )
{
const struct list * A , * B ;
A = a ;
B = b ;
if ( A - > avg < B - > avg ) return - 1 ;
if ( A - > avg > B - > avg ) return 1 ;
return 0 ;
}
void tally_results ( int type )
{
int x ;
// qsort the results
qsort ( results , no_results , sizeof ( struct list ) , & sorter ) ;
printf ( " \n " ) ;
if ( type = = 0 ) {
for ( x = 0 ; x < no_results ; x + + ) {
printf ( " %-20s: Schedule at %6lu \n " , cipher_descriptor [ results [ x ] . id ] . name , ( unsigned long ) results [ x ] . spd1 ) ;
}
} else if ( type = = 1 ) {
for ( x = 0 ; x < no_results ; x + + ) {
printf
2005-04-17 07:37:13 -04:00
( " %-20s[%3d]: Encrypt at %5lu, Decrypt at %5lu \n " , cipher_descriptor [ results [ x ] . id ] . name , cipher_descriptor [ results [ x ] . id ] . ID , results [ x ] . spd1 , results [ x ] . spd2 ) ;
2003-12-24 13:59:57 -05:00
}
} else {
for ( x = 0 ; x < no_results ; x + + ) {
printf
( " %-20s: Process at %5lu \n " , hash_descriptor [ results [ x ] . id ] . name , results [ x ] . spd1 / 1000 ) ;
}
}
}
2003-07-10 22:09:41 -04:00
/* RDTSC from Scott Duplichan */
2005-04-17 07:37:13 -04:00
ulong64 rdtsc ( void )
2003-07-10 22:09:41 -04:00
{
# if defined __GNUC__
2005-04-17 07:37:13 -04:00
# ifdef INTEL_CC
ulong64 a ;
asm ( " rdtsc " : " =A " ( a ) ) ;
return a ;
# elif defined(__i386__) || defined(__x86_64__)
ulong64 a ;
asm __volatile__ ( " rdtsc \n movl %%eax,(%0) \ nmovl % % edx , 4 ( % 0 ) \ n " :: " r " (&a): " % eax " , " % edx " ) ;
2003-07-10 22:09:41 -04:00
return a ;
2005-04-19 07:30:30 -04:00
# elif defined(__ia64__) /* gcc-IA64 version */
2003-07-10 22:09:41 -04:00
unsigned long result ;
__asm__ __volatile__ ( " mov %0=ar.itc " : " =r " ( result ) : : " memory " ) ;
while ( __builtin_expect ( ( int ) result = = - 1 , 0 ) )
__asm__ __volatile__ ( " mov %0=ar.itc " : " =r " ( result ) : : " memory " ) ;
return result ;
2005-04-19 07:30:30 -04:00
# else
return XCLOCK ( ) ;
2003-07-10 22:09:41 -04:00
# endif
// Microsoft and Intel Windows compilers
# elif defined _M_IX86
__asm rdtsc
# elif defined _M_AMD64
return __rdtsc ( ) ;
# elif defined _M_IA64
# if defined __INTEL_COMPILER
# include <ia64intrin.h>
# endif
return __getReg ( 3116 ) ;
# else
2005-04-19 07:30:30 -04:00
return XCLOCK ( ) ;
2003-07-10 22:09:41 -04:00
# endif
}
2005-04-17 07:37:13 -04:00
static ulong64 timer , skew = 0 ;
2003-07-10 22:09:41 -04:00
void t_start ( void )
{
timer = rdtsc ( ) ;
}
ulong64 t_read ( void )
{
return rdtsc ( ) - timer ;
}
void init_timer ( void )
{
ulong64 c1 , c2 , t1 , t2 , t3 ;
unsigned long y1 ;
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
c1 = c2 = ( ulong64 ) - 1 ;
for ( y1 = 0 ; y1 < TIMES * 100 ; y1 + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
t3 = t_read ( ) ;
2005-04-17 07:37:13 -04:00
t2 = ( t_read ( ) - t1 ) > > 1 ;
2003-09-25 21:16:18 -04:00
2005-04-17 07:37:13 -04:00
c1 = ( t1 > c1 ) ? t1 : c1 ;
c2 = ( t2 > c2 ) ? t2 : c2 ;
2003-07-10 22:09:41 -04:00
}
skew = c2 - c1 ;
printf ( " Clock Skew: %lu \n " , ( unsigned long ) skew ) ;
2003-09-25 21:16:18 -04:00
}
2003-07-10 22:09:41 -04:00
void reg_algs ( void )
{
2004-10-29 23:00:26 -04:00
int err ;
2003-07-10 22:09:41 -04:00
# ifdef RIJNDAEL
register_cipher ( & aes_desc ) ;
# endif
# ifdef BLOWFISH
register_cipher ( & blowfish_desc ) ;
# endif
# ifdef XTEA
register_cipher ( & xtea_desc ) ;
# endif
# ifdef RC5
register_cipher ( & rc5_desc ) ;
# endif
# ifdef RC6
register_cipher ( & rc6_desc ) ;
# endif
# ifdef SAFERP
register_cipher ( & saferp_desc ) ;
# endif
# ifdef TWOFISH
register_cipher ( & twofish_desc ) ;
# endif
# ifdef SAFER
register_cipher ( & safer_k64_desc ) ;
register_cipher ( & safer_sk64_desc ) ;
register_cipher ( & safer_k128_desc ) ;
register_cipher ( & safer_sk128_desc ) ;
# endif
# ifdef RC2
register_cipher ( & rc2_desc ) ;
# endif
# ifdef DES
register_cipher ( & des_desc ) ;
register_cipher ( & des3_desc ) ;
# endif
# ifdef CAST5
register_cipher ( & cast5_desc ) ;
# endif
# ifdef NOEKEON
register_cipher ( & noekeon_desc ) ;
# endif
2003-12-24 13:59:57 -05:00
# ifdef SKIPJACK
register_cipher ( & skipjack_desc ) ;
# endif
2004-12-30 18:55:53 -05:00
# ifdef KHAZAD
register_cipher ( & khazad_desc ) ;
# endif
# ifdef ANUBIS
register_cipher ( & anubis_desc ) ;
# endif
2003-07-10 22:09:41 -04:00
# ifdef TIGER
register_hash ( & tiger_desc ) ;
# endif
# ifdef MD2
register_hash ( & md2_desc ) ;
# endif
# ifdef MD4
register_hash ( & md4_desc ) ;
# endif
# ifdef MD5
register_hash ( & md5_desc ) ;
# endif
# ifdef SHA1
register_hash ( & sha1_desc ) ;
# endif
2003-12-24 13:59:57 -05:00
# ifdef SHA224
register_hash ( & sha224_desc ) ;
# endif
2003-07-10 22:09:41 -04:00
# ifdef SHA256
register_hash ( & sha256_desc ) ;
# endif
# ifdef SHA384
register_hash ( & sha384_desc ) ;
# endif
# ifdef SHA512
register_hash ( & sha512_desc ) ;
# endif
2003-09-07 21:06:11 -04:00
# ifdef RIPEMD128
register_hash ( & rmd128_desc ) ;
# endif
2003-09-25 21:16:18 -04:00
# ifdef RIPEMD160
register_hash ( & rmd160_desc ) ;
# endif
2004-02-20 15:03:32 -05:00
# ifdef WHIRLPOOL
register_hash ( & whirlpool_desc ) ;
# endif
2004-10-29 23:00:26 -04:00
# ifdef CHC_HASH
register_hash ( & chc_desc ) ;
if ( ( err = chc_register ( register_cipher ( & aes_desc ) ) ) ! = CRYPT_OK ) {
printf ( " chc_register error: %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
# endif
2003-07-10 22:09:41 -04:00
2004-08-06 12:42:41 -04:00
# ifndef YARROW
# error This demo requires Yarrow.
# endif
2003-12-24 13:59:57 -05:00
register_prng ( & yarrow_desc ) ;
2004-08-06 12:42:41 -04:00
# ifdef FORTUNA
2004-07-23 11:40:22 -04:00
register_prng ( & fortuna_desc ) ;
2004-08-06 12:42:41 -04:00
# endif
# ifdef RC4
2004-07-23 11:40:22 -04:00
register_prng ( & rc4_desc ) ;
2004-08-06 12:42:41 -04:00
# endif
# ifdef SOBER128
register_prng ( & sober128_desc ) ;
# endif
2004-07-23 11:40:22 -04:00
2005-04-17 07:37:13 -04:00
rng_make_prng ( 128 , find_prng ( " yarrow " ) , & yarrow_prng , NULL ) ;
2003-07-10 22:09:41 -04:00
}
int time_keysched ( void )
{
2004-08-06 12:42:41 -04:00
unsigned long x , y1 ;
2003-07-10 22:09:41 -04:00
ulong64 t1 , c1 ;
symmetric_key skey ;
int kl ;
int ( * func ) ( const unsigned char * , int , int , symmetric_key * ) ;
unsigned char key [ MAXBLOCKSIZE ] ;
printf ( " \n \n Key Schedule Time Trials for the Symmetric Ciphers: \n (Times are cycles per key) \n " ) ;
2003-12-24 13:59:57 -05:00
no_results = 0 ;
for ( x = 0 ; cipher_descriptor [ x ] . name ! = NULL ; x + + ) {
2003-07-10 22:09:41 -04:00
# define DO1(k) func(k, kl, 0, &skey);
func = cipher_descriptor [ x ] . setup ;
kl = cipher_descriptor [ x ] . min_key_length ;
c1 = ( ulong64 ) - 1 ;
for ( y1 = 0 ; y1 < KTIMES ; y1 + + ) {
2005-04-17 07:37:13 -04:00
yarrow_read ( key , kl , & yarrow_prng ) ;
2003-07-10 22:09:41 -04:00
t_start ( ) ;
DO1 ( key ) ;
t1 = t_read ( ) ;
c1 = ( t1 > c1 ) ? c1 : t1 ;
}
t1 = c1 - skew ;
2003-12-24 13:59:57 -05:00
results [ no_results ] . spd1 = results [ no_results ] . avg = t1 ;
results [ no_results + + ] . id = x ;
printf ( " . " ) ; fflush ( stdout ) ;
2003-07-10 22:09:41 -04:00
# undef DO1
}
2003-12-24 13:59:57 -05:00
tally_results ( 0 ) ;
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
return 0 ;
}
int time_cipher ( void )
{
unsigned long x , y1 ;
ulong64 t1 , t2 , c1 , c2 , a1 , a2 ;
2005-04-17 07:37:13 -04:00
symmetric_ECB ecb ;
unsigned char key [ MAXBLOCKSIZE ] , pt [ 4096 ] ;
2004-08-06 12:42:41 -04:00
int err ;
2003-07-10 22:09:41 -04:00
printf ( " \n \n ECB Time Trials for the Symmetric Ciphers: \n " ) ;
2003-12-24 13:59:57 -05:00
no_results = 0 ;
2003-07-10 22:09:41 -04:00
for ( x = 0 ; cipher_descriptor [ x ] . name ! = NULL ; x + + ) {
2005-04-17 07:37:13 -04:00
ecb_start ( x , key , cipher_descriptor [ x ] . min_key_length , 0 , & ecb ) ;
2003-07-10 22:09:41 -04:00
2004-08-06 12:42:41 -04:00
/* sanity check on cipher */
if ( ( err = cipher_descriptor [ x ] . test ( ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n ERROR: Cipher %s failed self-test %s \n " , cipher_descriptor [ x ] . name , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
2005-04-17 07:37:13 -04:00
# define DO1 ecb_encrypt(pt, pt, sizeof(pt), &ecb);
2003-07-10 22:09:41 -04:00
# define DO2 DO1 DO1
c1 = c2 = ( ulong64 ) - 1 ;
2005-04-17 07:37:13 -04:00
for ( y1 = 0 ; y1 < 100 ; y1 + + ) {
2003-07-10 22:09:41 -04:00
t_start ( ) ;
DO1 ;
t1 = t_read ( ) ;
DO2 ;
t2 = t_read ( ) ;
t2 - = t1 ;
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
c1 = ( t1 > c1 ? c1 : t1 ) ;
c2 = ( t2 > c2 ? c2 : t2 ) ;
}
a1 = c2 - c1 - skew ;
2003-09-25 21:16:18 -04:00
2005-04-17 07:37:13 -04:00
# undef DO1
# undef DO2
# define DO1 ecb_decrypt(pt, pt, sizeof(pt), &ecb);
# define DO2 DO1 DO1
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
c1 = c2 = ( ulong64 ) - 1 ;
2005-04-17 07:37:13 -04:00
for ( y1 = 0 ; y1 < 100 ; y1 + + ) {
t_start ( ) ;
DO1 ;
t1 = t_read ( ) ;
DO2 ;
t2 = t_read ( ) ;
t2 - = t1 ;
c1 = ( t1 > c1 ? c1 : t1 ) ;
c2 = ( t2 > c2 ? c2 : t2 ) ;
}
a2 = c2 - c1 - skew ;
results [ no_results ] . id = x ;
results [ no_results ] . spd1 = a1 / ( sizeof ( pt ) / cipher_descriptor [ x ] . block_length ) ;
results [ no_results ] . spd2 = a2 / ( sizeof ( pt ) / cipher_descriptor [ x ] . block_length ) ;
results [ no_results ] . avg = ( results [ no_results ] . spd1 + results [ no_results ] . spd2 + 1 ) / 2 ;
+ + no_results ;
printf ( " . " ) ; fflush ( stdout ) ;
# undef DO2
# undef DO1
}
tally_results ( 1 ) ;
return 0 ;
}
# ifdef CBC
int time_cipher2 ( void )
{
unsigned long x , y1 ;
ulong64 t1 , t2 , c1 , c2 , a1 , a2 ;
symmetric_CBC cbc ;
unsigned char key [ MAXBLOCKSIZE ] , pt [ 4096 ] ;
int err ;
printf ( " \n \n CBC Time Trials for the Symmetric Ciphers: \n " ) ;
no_results = 0 ;
for ( x = 0 ; cipher_descriptor [ x ] . name ! = NULL ; x + + ) {
cbc_start ( x , pt , key , cipher_descriptor [ x ] . min_key_length , 0 , & cbc ) ;
/* sanity check on cipher */
if ( ( err = cipher_descriptor [ x ] . test ( ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n ERROR: Cipher %s failed self-test %s \n " , cipher_descriptor [ x ] . name , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
# define DO1 cbc_encrypt(pt, pt, sizeof(pt), &cbc);
# define DO2 DO1 DO1
c1 = c2 = ( ulong64 ) - 1 ;
for ( y1 = 0 ; y1 < 100 ; y1 + + ) {
t_start ( ) ;
DO1 ;
t1 = t_read ( ) ;
DO2 ;
t2 = t_read ( ) ;
t2 - = t1 ;
c1 = ( t1 > c1 ? c1 : t1 ) ;
c2 = ( t2 > c2 ? c2 : t2 ) ;
}
a1 = c2 - c1 - skew ;
# undef DO1
# undef DO2
# define DO1 cbc_decrypt(pt, pt, sizeof(pt), &cbc);
# define DO2 DO1 DO1
c1 = c2 = ( ulong64 ) - 1 ;
for ( y1 = 0 ; y1 < 100 ; y1 + + ) {
2003-07-10 22:09:41 -04:00
t_start ( ) ;
DO1 ;
t1 = t_read ( ) ;
DO2 ;
t2 = t_read ( ) ;
t2 - = t1 ;
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
c1 = ( t1 > c1 ? c1 : t1 ) ;
c2 = ( t2 > c2 ? c2 : t2 ) ;
}
a2 = c2 - c1 - skew ;
2003-12-24 13:59:57 -05:00
results [ no_results ] . id = x ;
2005-04-17 07:37:13 -04:00
results [ no_results ] . spd1 = a1 / ( sizeof ( pt ) / cipher_descriptor [ x ] . block_length ) ;
results [ no_results ] . spd2 = a2 / ( sizeof ( pt ) / cipher_descriptor [ x ] . block_length ) ;
2003-12-24 13:59:57 -05:00
results [ no_results ] . avg = ( results [ no_results ] . spd1 + results [ no_results ] . spd2 + 1 ) / 2 ;
+ + no_results ;
printf ( " . " ) ; fflush ( stdout ) ;
2003-07-10 22:09:41 -04:00
# undef DO2
# undef DO1
}
2003-12-24 13:59:57 -05:00
tally_results ( 1 ) ;
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
return 0 ;
}
2005-04-17 07:37:13 -04:00
# else
int time_cipher2 ( void ) { printf ( " NO CBC \n " ) ; return 0 ; }
# endif
# ifdef CTR
int time_cipher3 ( void )
{
unsigned long x , y1 ;
ulong64 t1 , t2 , c1 , c2 , a1 , a2 ;
symmetric_CTR ctr ;
unsigned char key [ MAXBLOCKSIZE ] , pt [ 4096 ] ;
int err ;
printf ( " \n \n CTR Time Trials for the Symmetric Ciphers: \n " ) ;
no_results = 0 ;
for ( x = 0 ; cipher_descriptor [ x ] . name ! = NULL ; x + + ) {
ctr_start ( x , pt , key , cipher_descriptor [ x ] . min_key_length , 0 , & ctr ) ;
/* sanity check on cipher */
if ( ( err = cipher_descriptor [ x ] . test ( ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n ERROR: Cipher %s failed self-test %s \n " , cipher_descriptor [ x ] . name , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
# define DO1 ctr_encrypt(pt, pt, sizeof(pt), &ctr);
# define DO2 DO1 DO1
c1 = c2 = ( ulong64 ) - 1 ;
for ( y1 = 0 ; y1 < 100 ; y1 + + ) {
t_start ( ) ;
DO1 ;
t1 = t_read ( ) ;
DO2 ;
t2 = t_read ( ) ;
t2 - = t1 ;
c1 = ( t1 > c1 ? c1 : t1 ) ;
c2 = ( t2 > c2 ? c2 : t2 ) ;
}
a1 = c2 - c1 - skew ;
# undef DO1
# undef DO2
# define DO1 ctr_decrypt(pt, pt, sizeof(pt), &ctr);
# define DO2 DO1 DO1
c1 = c2 = ( ulong64 ) - 1 ;
for ( y1 = 0 ; y1 < 100 ; y1 + + ) {
t_start ( ) ;
DO1 ;
t1 = t_read ( ) ;
DO2 ;
t2 = t_read ( ) ;
t2 - = t1 ;
c1 = ( t1 > c1 ? c1 : t1 ) ;
c2 = ( t2 > c2 ? c2 : t2 ) ;
}
a2 = c2 - c1 - skew ;
results [ no_results ] . id = x ;
results [ no_results ] . spd1 = a1 / ( sizeof ( pt ) / cipher_descriptor [ x ] . block_length ) ;
results [ no_results ] . spd2 = a2 / ( sizeof ( pt ) / cipher_descriptor [ x ] . block_length ) ;
results [ no_results ] . avg = ( results [ no_results ] . spd1 + results [ no_results ] . spd2 + 1 ) / 2 ;
+ + no_results ;
printf ( " . " ) ; fflush ( stdout ) ;
# undef DO2
# undef DO1
}
tally_results ( 1 ) ;
return 0 ;
}
# else
int time_cipher3 ( void ) { printf ( " NO CTR \n " ) ; return 0 ; }
# endif
2003-07-10 22:09:41 -04:00
int time_hash ( void )
{
unsigned long x , y1 , len ;
ulong64 t1 , t2 , c1 , c2 ;
hash_state md ;
2004-08-06 12:42:41 -04:00
int ( * func ) ( hash_state * , const unsigned char * , unsigned long ) , err ;
2003-07-10 22:09:41 -04:00
unsigned char pt [ MAXBLOCKSIZE ] ;
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
printf ( " \n \n HASH Time Trials for: \n " ) ;
2003-12-24 13:59:57 -05:00
no_results = 0 ;
2003-07-10 22:09:41 -04:00
for ( x = 0 ; hash_descriptor [ x ] . name ! = NULL ; x + + ) {
2004-08-06 12:42:41 -04:00
/* sanity check on hash */
if ( ( err = hash_descriptor [ x ] . test ( ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n ERROR: Hash %s failed self-test %s \n " , hash_descriptor [ x ] . name , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
2003-07-10 22:09:41 -04:00
hash_descriptor [ x ] . init ( & md ) ;
# define DO1 func(&md,pt,len);
# define DO2 DO1 DO1
func = hash_descriptor [ x ] . process ;
len = hash_descriptor [ x ] . blocksize ;
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
c1 = c2 = ( ulong64 ) - 1 ;
for ( y1 = 0 ; y1 < TIMES ; y1 + + ) {
t_start ( ) ;
DO1 ;
t1 = t_read ( ) ;
DO2 ;
t2 = t_read ( ) - t1 ;
c1 = ( t1 > c1 ) ? c1 : t1 ;
c2 = ( t2 > c2 ) ? c2 : t2 ;
}
2003-09-25 21:16:18 -04:00
t1 = c2 - c1 - skew ;
2003-07-10 22:09:41 -04:00
t1 = ( ( t1 * CONST64 ( 1000 ) ) ) / ( ( ulong64 ) hash_descriptor [ x ] . blocksize ) ;
2003-12-24 13:59:57 -05:00
results [ no_results ] . id = x ;
results [ no_results ] . spd1 = results [ no_results ] . avg = t1 ;
+ + no_results ;
printf ( " . " ) ; fflush ( stdout ) ;
2003-07-10 22:09:41 -04:00
# undef DO2
# undef DO1
}
2003-12-24 13:59:57 -05:00
tally_results ( 2 ) ;
2003-09-25 21:16:18 -04:00
2003-07-10 22:09:41 -04:00
return 0 ;
}
2005-04-17 07:37:13 -04:00
# ifdef MPI
2004-07-23 11:40:22 -04:00
void time_mult ( void )
{
ulong64 t1 , t2 ;
unsigned long x , y ;
mp_int a , b , c ;
printf ( " Timing Multiplying: \n " ) ;
mp_init_multi ( & a , & b , & c , NULL ) ;
2004-12-30 18:55:53 -05:00
for ( x = 128 / DIGIT_BIT ; x < = 1536 / DIGIT_BIT ; x + = 128 / DIGIT_BIT ) {
2004-07-23 11:40:22 -04:00
mp_rand ( & a , x ) ;
mp_rand ( & b , x ) ;
# define DO1 mp_mul(&a, &b, &c);
# define DO2 DO1; DO1;
t2 = - 1 ;
for ( y = 0 ; y < TIMES ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
DO2 ;
t1 = ( t_read ( ) - t1 ) > > 1 ;
if ( t1 < t2 ) t2 = t1 ;
}
2004-12-30 18:55:53 -05:00
printf ( " %4lu bits: %9llu cycles \n " , x * DIGIT_BIT , t2 ) ;
2004-07-23 11:40:22 -04:00
}
mp_clear_multi ( & a , & b , & c , NULL ) ;
# undef DO1
# undef DO2
2005-04-17 07:37:13 -04:00
}
2004-07-23 11:40:22 -04:00
void time_sqr ( void )
{
ulong64 t1 , t2 ;
unsigned long x , y ;
mp_int a , b ;
printf ( " Timing Squaring: \n " ) ;
mp_init_multi ( & a , & b , NULL ) ;
2004-12-30 18:55:53 -05:00
for ( x = 128 / DIGIT_BIT ; x < = 1536 / DIGIT_BIT ; x + = 128 / DIGIT_BIT ) {
2004-07-23 11:40:22 -04:00
mp_rand ( & a , x ) ;
# define DO1 mp_sqr(&a, &b);
# define DO2 DO1; DO1;
t2 = - 1 ;
for ( y = 0 ; y < TIMES ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
DO2 ;
t1 = ( t_read ( ) - t1 ) > > 1 ;
if ( t1 < t2 ) t2 = t1 ;
}
2004-12-30 18:55:53 -05:00
printf ( " %4lu bits: %9llu cycles \n " , x * DIGIT_BIT , t2 ) ;
2004-07-23 11:40:22 -04:00
}
mp_clear_multi ( & a , & b , NULL ) ;
# undef DO1
# undef DO2
2005-04-17 07:37:13 -04:00
}
# else
void time_mult ( void ) { printf ( " NO MULT \n " ) ; }
void time_sqr ( void ) { printf ( " NO SQR \n " ) ; }
# endif
2004-07-23 11:40:22 -04:00
void time_prng ( void )
{
ulong64 t1 , t2 ;
unsigned char buf [ 4096 ] ;
2004-08-06 12:42:41 -04:00
prng_state tprng ;
2004-07-23 11:40:22 -04:00
unsigned long x , y ;
2004-08-06 12:42:41 -04:00
int err ;
2004-07-23 11:40:22 -04:00
2004-08-06 12:42:41 -04:00
printf ( " Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) : \n " ) ;
2004-07-23 11:40:22 -04:00
for ( x = 0 ; prng_descriptor [ x ] . name ! = NULL ; x + + ) {
2004-08-06 12:42:41 -04:00
/* sanity check on prng */
if ( ( err = prng_descriptor [ x ] . test ( ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n ERROR: PRNG %s failed self-test %s \n " , prng_descriptor [ x ] . name , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
prng_descriptor [ x ] . start ( & tprng ) ;
2004-07-23 11:40:22 -04:00
zeromem ( buf , 256 ) ;
2004-08-06 12:42:41 -04:00
prng_descriptor [ x ] . add_entropy ( buf , 256 , & tprng ) ;
prng_descriptor [ x ] . ready ( & tprng ) ;
2004-07-23 11:40:22 -04:00
t2 = - 1 ;
2004-08-06 12:42:41 -04:00
# define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { printf("\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); }
2004-07-23 11:40:22 -04:00
# define DO2 DO1 DO1
2004-08-06 12:42:41 -04:00
for ( y = 0 ; y < 10000 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
DO2 ;
t1 = ( t_read ( ) - t1 ) > > 1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " %20s: %5llu " , prng_descriptor [ x ] . name , t2 > > 12 ) ;
# undef DO2
# undef DO1
2004-07-23 11:40:22 -04:00
2004-08-06 12:42:41 -04:00
# define DO1 prng_descriptor[x].start(&tprng); prng_descriptor[x].add_entropy(buf, 32, &tprng); prng_descriptor[x].ready(&tprng); prng_descriptor[x].done(&tprng);
# define DO2 DO1 DO1
2004-07-23 11:40:22 -04:00
for ( y = 0 ; y < 10000 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
DO2 ;
t1 = ( t_read ( ) - t1 ) > > 1 ;
if ( t1 < t2 ) t2 = t1 ;
}
2004-08-06 12:42:41 -04:00
printf ( " %5llu \n " , t2 ) ;
2004-07-23 11:40:22 -04:00
# undef DO2
# undef DO1
2004-08-06 12:42:41 -04:00
}
2004-07-23 11:40:22 -04:00
}
2005-04-17 07:37:13 -04:00
# ifdef MRSA
2004-08-06 12:42:41 -04:00
/* time various RSA operations */
void time_rsa ( void )
{
rsa_key key ;
ulong64 t1 , t2 ;
unsigned char buf [ 2 ] [ 4096 ] ;
unsigned long x , y , z , zzz ;
int err , zz ;
for ( x = 1024 ; x < = 2048 ; x + = 512 ) {
t2 = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
2005-04-17 07:37:13 -04:00
if ( ( err = rsa_make_key ( & yarrow_prng , find_prng ( " yarrow " ) , x / 8 , 65537 , & key ) ) ! = CRYPT_OK ) {
2004-08-06 12:42:41 -04:00
fprintf ( stderr , " \n \n rsa_make_key says %s, wait...no it should say %s...damn you! \n " , error_to_string ( err ) , error_to_string ( CRYPT_OK ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
t2 + = t1 ;
if ( y < 15 ) {
rsa_free ( & key ) ;
}
}
t2 > > = 4 ;
printf ( " RSA-%lu make_key took %15llu cycles \n " , x , t2 ) ;
t2 = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = sizeof ( buf [ 1 ] ) ;
2005-04-17 07:37:13 -04:00
if ( ( err = rsa_encrypt_key ( buf [ 0 ] , 32 , buf [ 1 ] , & z , " testprog " , 8 , & yarrow_prng ,
2004-08-06 12:42:41 -04:00
find_prng ( " yarrow " ) , find_hash ( " sha1 " ) ,
& key ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n rsa_encrypt_key says %s, wait...no it should say %s...damn you! \n " , error_to_string ( err ) , error_to_string ( CRYPT_OK ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
t2 + = t1 ;
}
t2 > > = 4 ;
printf ( " RSA-%lu encrypt_key took %15llu cycles \n " , x , t2 ) ;
t2 = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
zzz = sizeof ( buf [ 0 ] ) ;
2004-12-30 18:55:53 -05:00
if ( ( err = rsa_decrypt_key ( buf [ 1 ] , z , buf [ 0 ] , & zzz , " testprog " , 8 , find_hash ( " sha1 " ) ,
2004-08-06 12:42:41 -04:00
& zz , & key ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n rsa_decrypt_key says %s, wait...no it should say %s...damn you! \n " , error_to_string ( err ) , error_to_string ( CRYPT_OK ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
t2 + = t1 ;
}
t2 > > = 4 ;
printf ( " RSA-%lu decrypt_key took %15llu cycles \n " , x , t2 ) ;
rsa_free ( & key ) ;
}
}
2005-04-17 07:37:13 -04:00
# else
void time_rsa ( void ) { printf ( " NO RSA \n " ) ; }
# endif
2004-07-23 11:40:22 -04:00
2005-04-17 07:37:13 -04:00
# ifdef MECC
2004-08-06 12:42:41 -04:00
/* time various ECC operations */
void time_ecc ( void )
{
ecc_key key ;
ulong64 t1 , t2 ;
unsigned char buf [ 2 ] [ 4096 ] ;
unsigned long i , x , y , z ;
int err ;
static unsigned long sizes [ ] = { 160 / 8 , 256 / 8 , 521 / 8 , 100000 } ;
for ( x = sizes [ i = 0 ] ; x < 100000 ; x = sizes [ + + i ] ) {
t2 = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
2005-04-17 07:37:13 -04:00
if ( ( err = ecc_make_key ( & yarrow_prng , find_prng ( " yarrow " ) , x , & key ) ) ! = CRYPT_OK ) {
2004-08-06 12:42:41 -04:00
fprintf ( stderr , " \n \n ecc_make_key says %s, wait...no it should say %s...damn you! \n " , error_to_string ( err ) , error_to_string ( CRYPT_OK ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
t2 + = t1 ;
if ( y < 15 ) {
ecc_free ( & key ) ;
}
}
t2 > > = 4 ;
printf ( " ECC-%lu make_key took %15llu cycles \n " , x * 8 , t2 ) ;
t2 = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = sizeof ( buf [ 1 ] ) ;
2005-04-17 07:37:13 -04:00
if ( ( err = ecc_encrypt_key ( buf [ 0 ] , 20 , buf [ 1 ] , & z , & yarrow_prng , find_prng ( " yarrow " ) , find_hash ( " sha1 " ) ,
2004-08-06 12:42:41 -04:00
& key ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n ecc_encrypt_key says %s, wait...no it should say %s...damn you! \n " , error_to_string ( err ) , error_to_string ( CRYPT_OK ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
t2 + = t1 ;
}
t2 > > = 4 ;
printf ( " ECC-%lu encrypt_key took %15llu cycles \n " , x * 8 , t2 ) ;
ecc_free ( & key ) ;
}
}
2005-04-17 07:37:13 -04:00
# else
void time_ecc ( void ) { printf ( " NO ECC \n " ) ; }
# endif
2004-08-06 12:42:41 -04:00
2005-04-17 07:37:13 -04:00
# ifdef MDH
2004-08-06 12:42:41 -04:00
/* time various DH operations */
void time_dh ( void )
{
dh_key key ;
ulong64 t1 , t2 ;
unsigned char buf [ 2 ] [ 4096 ] ;
unsigned long i , x , y , z ;
int err ;
static unsigned long sizes [ ] = { 768 / 8 , 1024 / 8 , 1536 / 8 , 2048 / 8 , 3072 / 8 , 4096 / 8 , 100000 } ;
for ( x = sizes [ i = 0 ] ; x < 100000 ; x = sizes [ + + i ] ) {
t2 = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
2005-04-17 07:37:13 -04:00
if ( ( err = dh_make_key ( & yarrow_prng , find_prng ( " yarrow " ) , x , & key ) ) ! = CRYPT_OK ) {
2004-08-06 12:42:41 -04:00
fprintf ( stderr , " \n \n dh_make_key says %s, wait...no it should say %s...damn you! \n " , error_to_string ( err ) , error_to_string ( CRYPT_OK ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
t2 + = t1 ;
if ( y < 15 ) {
dh_free ( & key ) ;
}
}
t2 > > = 4 ;
printf ( " DH-%4lu make_key took %15llu cycles \n " , x * 8 , t2 ) ;
t2 = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = sizeof ( buf [ 1 ] ) ;
2005-04-17 07:37:13 -04:00
if ( ( err = dh_encrypt_key ( buf [ 0 ] , 20 , buf [ 1 ] , & z , & yarrow_prng , find_prng ( " yarrow " ) , find_hash ( " sha1 " ) ,
2004-08-06 12:42:41 -04:00
& key ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n dh_encrypt_key says %s, wait...no it should say %s...damn you! \n " , error_to_string ( err ) , error_to_string ( CRYPT_OK ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
t2 + = t1 ;
}
t2 > > = 4 ;
printf ( " DH-%4lu encrypt_key took %15llu cycles \n " , x * 8 , t2 ) ;
dh_free ( & key ) ;
}
}
2005-04-17 07:37:13 -04:00
# else
void time_dh ( void ) { printf ( " NO DH \n " ) ; }
# endif
2004-08-06 12:42:41 -04:00
2005-04-17 07:37:13 -04:00
void time_macs_ ( unsigned long MAC_SIZE )
2004-08-06 12:42:41 -04:00
{
unsigned char * buf , key [ 16 ] , tag [ 16 ] ;
ulong64 t1 , t2 ;
unsigned long x , z ;
int err , cipher_idx , hash_idx ;
printf ( " \n MAC Timings (cycles/byte on %dKB blocks): \n " , MAC_SIZE ) ;
buf = XMALLOC ( MAC_SIZE * 1024 ) ;
if ( buf = = NULL ) {
fprintf ( stderr , " \n \n out of heap yo \n \n " ) ;
exit ( EXIT_FAILURE ) ;
}
cipher_idx = find_cipher ( " aes " ) ;
hash_idx = find_hash ( " md5 " ) ;
2005-04-17 07:37:13 -04:00
yarrow_read ( buf , MAC_SIZE * 1024 , & yarrow_prng ) ;
yarrow_read ( key , 16 , & yarrow_prng ) ;
2004-08-06 12:42:41 -04:00
2005-04-17 07:37:13 -04:00
# ifdef OMAC
2004-08-06 12:42:41 -04:00
t2 = - 1 ;
for ( x = 0 ; x < 10000 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = omac_memory ( cipher_idx , key , 16 , buf , MAC_SIZE * 1024 , tag , & z ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n omac error... %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " OMAC-AES \t \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
2005-04-17 07:37:13 -04:00
# endif
2004-08-06 12:42:41 -04:00
2005-04-17 07:37:13 -04:00
# ifdef PMAC
2004-08-06 12:42:41 -04:00
t2 = - 1 ;
for ( x = 0 ; x < 10000 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = pmac_memory ( cipher_idx , key , 16 , buf , MAC_SIZE * 1024 , tag , & z ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n pmac error... %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " PMAC-AES \t \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
2005-04-17 07:37:13 -04:00
# endif
# ifdef PELICAN
t2 = - 1 ;
for ( x = 0 ; x < 10000 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = pelican_memory ( key , 16 , buf , MAC_SIZE * 1024 , tag ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n pelican error... %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " PELICAN \t \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
# endif
2004-08-06 12:42:41 -04:00
2005-04-17 07:37:13 -04:00
# ifdef HMAC
2004-08-06 12:42:41 -04:00
t2 = - 1 ;
for ( x = 0 ; x < 10000 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = hmac_memory ( hash_idx , key , 16 , buf , MAC_SIZE * 1024 , tag , & z ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n \n hmac error... %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " HMAC-MD5 \t \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
2005-04-17 07:37:13 -04:00
# endif
2004-08-06 12:42:41 -04:00
XFREE ( buf ) ;
}
2004-07-23 11:40:22 -04:00
2005-04-17 07:37:13 -04:00
void time_macs ( void )
2003-07-10 22:09:41 -04:00
{
2005-04-17 07:37:13 -04:00
time_macs_ ( 1 ) ;
time_macs_ ( 4 ) ;
time_macs_ ( 32 ) ;
2003-09-25 21:16:18 -04:00
}
2003-07-10 22:09:41 -04:00
2005-04-17 07:37:13 -04:00
void time_encmacs_ ( unsigned long MAC_SIZE )
{
unsigned char * buf , IV [ 16 ] , key [ 16 ] , tag [ 16 ] ;
ulong64 t1 , t2 ;
unsigned long x , z ;
int err , cipher_idx ;
printf ( " \n ENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %dKB blocks): \n " , MAC_SIZE ) ;
buf = XMALLOC ( MAC_SIZE * 1024 ) ;
if ( buf = = NULL ) {
fprintf ( stderr , " \n \n out of heap yo \n \n " ) ;
exit ( EXIT_FAILURE ) ;
}
cipher_idx = find_cipher ( " aes " ) ;
yarrow_read ( buf , MAC_SIZE * 1024 , & yarrow_prng ) ;
yarrow_read ( key , 16 , & yarrow_prng ) ;
yarrow_read ( IV , 16 , & yarrow_prng ) ;
# ifdef EAX_MODE
t2 = - 1 ;
for ( x = 0 ; x < 10000 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = eax_encrypt_authenticate_memory ( cipher_idx , key , 16 , IV , 16 , NULL , 0 , buf , MAC_SIZE * 1024 , buf , tag , & z ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n EAX error... %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " EAX \t \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
# endif
# ifdef OCB_MODE
t2 = - 1 ;
for ( x = 0 ; x < 10000 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = ocb_encrypt_authenticate_memory ( cipher_idx , key , 16 , IV , buf , MAC_SIZE * 1024 , buf , tag , & z ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n OCB error... %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " OCB \t \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
# endif
# ifdef CCM_MODE
t2 = - 1 ;
for ( x = 0 ; x < 10000 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = ccm_memory ( cipher_idx , key , 16 , IV , 16 , NULL , 0 , buf , MAC_SIZE * 1024 , buf , tag , & z , CCM_ENCRYPT ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n CCM error... %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " CCM \t \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
# endif
# ifdef GCM_MODE
t2 = - 1 ;
for ( x = 0 ; x < 100 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = gcm_memory ( cipher_idx , key , 16 , IV , 16 , NULL , 0 , buf , MAC_SIZE * 1024 , buf , tag , & z , GCM_ENCRYPT ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n GCM error... %s \n " , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " GCM (no-precomp) \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
{
gcm_state gcm ;
if ( ( err = gcm_init ( & gcm , cipher_idx , key , 16 ) ) ! = CRYPT_OK ) { printf ( " gcm_init: %s \n " , error_to_string ( err ) ) ; exit ( EXIT_FAILURE ) ; }
t2 = - 1 ;
for ( x = 0 ; x < 10000 ; x + + ) {
t_start ( ) ;
t1 = t_read ( ) ;
z = 16 ;
if ( ( err = gcm_reset ( & gcm ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n GCM error[%d]... %s \n " , __LINE__ , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
if ( ( err = gcm_add_iv ( & gcm , IV , 16 ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n GCM error[%d]... %s \n " , __LINE__ , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
if ( ( err = gcm_add_aad ( & gcm , NULL , 0 ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n GCM error[%d]... %s \n " , __LINE__ , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
if ( ( err = gcm_process ( & gcm , buf , MAC_SIZE * 1024 , buf , GCM_ENCRYPT ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n GCM error[%d]... %s \n " , __LINE__ , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
if ( ( err = gcm_done ( & gcm , tag , & z ) ) ! = CRYPT_OK ) {
fprintf ( stderr , " \n GCM error[%d]... %s \n " , __LINE__ , error_to_string ( err ) ) ;
exit ( EXIT_FAILURE ) ;
}
t1 = t_read ( ) - t1 ;
if ( t1 < t2 ) t2 = t1 ;
}
printf ( " GCM (precomp) \t %9llu \n " , t2 / ( MAC_SIZE * 1024 ) ) ;
}
# endif
}
void time_encmacs ( void )
{
time_encmacs_ ( 1 ) ;
time_encmacs_ ( 4 ) ;
time_encmacs_ ( 32 ) ;
}