#include #include #include #include #include #include "nmglobal.h" #include "nbench1.h" /******************** ** IDEA Encryption ** ********************* ** IDEA - International Data Encryption Algorithm. ** Based on code presented in Applied Cryptography by Bruce Schneier. ** Which was based on code developed by Xuejia Lai and James L. Massey. ** Other modifications made by Colin Plumb. ** */ /* ** DEFINES */ #define IDEAKEYSIZE 16 #define IDEABLOCKSIZE 8 #define ROUNDS 8 #define KEYLEN (6*ROUNDS+4) /* ** MACROS */ #define low16(x) ((x) & 0x0FFFF) #define MUL(x,y) (x=mul(low16(x),y)) typedef uint16_t IDEAkey[KEYLEN]; /* ** PROTOTYPES */ static unsigned long DoIDEAIteration(unsigned char *plain1, unsigned char *crypt1, unsigned char *plain2, unsigned long arraysize, unsigned long nloops, IDEAkey Z, IDEAkey DK); static uint16_t mul(register uint16_t a, register uint16_t b); static uint16_t inv(uint16_t x); static void en_key_idea(uint16_t userkey[8], IDEAkey Z); static void de_key_idea(IDEAkey Z, IDEAkey DK); static void cipher_idea(uint16_t in[4], uint16_t out[4], IDEAkey Z); /*********** ** DoIDEA ** ************ ** Perform IDEA encryption. Note that we time encryption & decryption ** time as being a single loop. */ void DoIDEA(void) { IDEAStruct *locideastruct; /* Loc pointer to global structure */ int i; IDEAkey Z,DK; uint16_t userkey[8]; unsigned long accumtime; double iterations; char *context; unsigned char *plain1 = NULL; /* First plaintext buffer */ unsigned char *crypt1 = NULL; /* Encryption buffer */ unsigned char *plain2 = NULL; /* Second plaintext buffer */ /* ** Link to global data */ locideastruct=&global_ideastruct; /* ** Set error context */ context="CPU:IDEA"; /* ** Re-init random-number generator. */ /* randnum(3L); */ randnum(3); /* ** Build an encryption/decryption key */ for (i=0;i<8;i++) /* userkey[i]=(uint16_t)(abs_randwc(60000L) & 0xFFFF); */ userkey[i]=(uint16_t)(abs_randwc((int32_t)60000) & 0xFFFF); for(i=0;i>encrypt>> crypt1 >>decrypt>> plain2. ** So, plain1 and plain2 should match. ** Also, fill up plain1 with sample text. */ plain1 = malloc(locideastruct->arraysize); if (!plain1) { fprintf(stderr, "Error in %s, could not allocate memory. Exitting...\n", context); exit(1); } crypt1 = malloc(locideastruct->arraysize); if (!crypt1) { fprintf(stderr, "Error in %s, could not allocate memory. Exitting...\n", context); free(plain1); exit(1); } plain2 = malloc(locideastruct->arraysize); if (!plain2) { fprintf(stderr, "Error in %s, could not allocate memory. Exitting...\n", context); free(plain1); free(plain2); exit(1); } /* ** Note that we build the "plaintext" by simply loading ** the array up with random numbers. */ for(i=0;iarraysize;i++) plain1[i]=(unsigned char)(abs_randwc(255) & 0xFF); /* ** See if we need to perform self adjustment loop. */ if(locideastruct->adjust==0) { /* ** Do self-adjustment. This involves initializing the ** # of loops and increasing the loop count until we ** get a number of loops that we can use. */ for(locideastruct->loops=100L; locideastruct->loopsloops+=10L) if(DoIDEAIteration(plain1,crypt1,plain2, locideastruct->arraysize, locideastruct->loops, Z,DK)>global_min_ticks) break; } /* ** All's well if we get here. Do the test. */ accumtime=0L; iterations=(double)0.0; do { accumtime+=DoIDEAIteration(plain1,crypt1,plain2, locideastruct->arraysize, locideastruct->loops,Z,DK); iterations+=(double)locideastruct->loops; } while(TicksToSecs(accumtime)request_secs); /* ** Clean up, calculate results, and go home. Be sure to ** show that we don't have to rerun adjustment code. */ free(plain1); free(crypt1); free(plain2); locideastruct->iterspersec=iterations / TicksToFracSecs(accumtime); if(locideastruct->adjust==0) locideastruct->adjust=1; return; } /******************** ** DoIDEAIteration ** ********************* ** Execute a single iteration of the IDEA encryption algorithm. ** Actually, a single iteration is one encryption and one ** decryption. */ static unsigned long DoIDEAIteration(unsigned char *plain1, unsigned char *crypt1, unsigned char *plain2, unsigned long arraysize, unsigned long nloops, IDEAkey Z, IDEAkey DK) { register unsigned long i; register unsigned long j; unsigned long elapsed; #ifdef DEBUG int status=0; #endif /* ** Start the stopwatch. */ elapsed=StartStopwatch(); /* ** Do everything for nloops. */ for(i=0;i>16); return(b-a+(b> 7); Z+=i&8; i&=7; } return; } /**************** ** de_key_idea ** ***************** ** Compute IDEA decryption subkeys DK from encryption ** subkeys Z. */ static void de_key_idea(IDEAkey Z, IDEAkey DK) { IDEAkey TT; int j; uint16_t t1, t2, t3; uint16_t *p; p=(uint16_t *)(TT+KEYLEN); t1=inv(*Z++); t2=-*Z++; t3=-*Z++; *--p=inv(*Z++); *--p=t3; *--p=t2; *--p=t1; for(j=1;j