mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 16:31:01 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
693 lines
21 KiB
C
693 lines
21 KiB
C
/*
|
|
File: Hash.c
|
|
|
|
Contains: some killer hash, Man
|
|
|
|
Written by: Patrick Dyson
|
|
|
|
Copyright: © 1989-1992 by Apple Computer, Inc., all rights reserved.
|
|
|
|
Change History (most recent first):
|
|
|
|
<SM3> 12/10/92 chp Cleaned up EASE to BBS change history conversion.
|
|
<SM2> 12/10/92 chp Added an #include <stdlib.h> to supply a prototype for exit().
|
|
<1.1> 12/11/89 PWD Changed hash size input to always strip the low bits of the size
|
|
to avoid illegal input.
|
|
<1.0> 10/31/89 PWD Adding to EASE
|
|
|
|
*/
|
|
|
|
#include <Types.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <Errors.h>
|
|
#include <Memory.h>
|
|
#include <Quickdraw.h>
|
|
#include <Fonts.h>
|
|
#include <Events.h>
|
|
|
|
|
|
#define hashSize 4
|
|
#define maxSBoxCount 8
|
|
#define errorFile 2 /* normally set up for standard error */
|
|
#define NUMTIMES 100
|
|
typedef unsigned long int sBox[256];
|
|
typedef unsigned long int rotatedsBox[4][8][256];
|
|
typedef unsigned long int sBoxs[8][256];
|
|
|
|
|
|
//extern sBox standardSBoxes[maxSBoxCount];
|
|
|
|
/* The following routine is a simple error exit routine -- it prints a
|
|
message and aborts */
|
|
void errAbort (s)
|
|
char *s;
|
|
{
|
|
int length;
|
|
|
|
for (length = 0; s[length] != 0; length++);
|
|
write (errorFile, s, length);
|
|
write (errorFile, "\n", 1);
|
|
exit (1);
|
|
};
|
|
|
|
/* Hash512
|
|
|
|
Takes as parameters an output buffer, some input data, initial keys, and the
|
|
base address of the pre-rotated s-block table.
|
|
|
|
The output parameter is modified to include the signature of the block which
|
|
should be hashed down when it too reaches 64 bytes.
|
|
|
|
This routine is taken from Ralph Merkle's (Xerox Corp) reference implementation and has
|
|
been slightly modified for speed and environment by Patrick Dyson.
|
|
*/
|
|
|
|
void Hash512 (output, input, p0, p1, p2, rotatedRightBase)
|
|
unsigned long int output[]; /* keys to carry, or signature */
|
|
unsigned long int input[]; /* block of input data */
|
|
unsigned long int p0, p1, p2; /* initial, or carried over, keys */
|
|
rotatedsBox rotatedRightBase; /* pointer to base of s-box table */
|
|
|
|
{
|
|
|
|
/* This routine is a specialized version of HashN. It is optimized
|
|
for speed, and assumes that the parameter wordCount is always 16,
|
|
and that hashSize is always 4. It hashes 512 bits, hence its name. */
|
|
/* You need not try to figure out this routine unless you wish to
|
|
figure out a fast implementation of Snefru */
|
|
|
|
/* the following are two pointers to S-boxes */
|
|
unsigned long int *SBox0;
|
|
unsigned long int *SBox1;
|
|
|
|
|
|
/* the array 'block' is divided into 16 distinct variables */
|
|
unsigned long int block0, block1, block2, block3;
|
|
unsigned long int block4, block5, block6, block7;
|
|
unsigned long int block8, block9, block10, block11;
|
|
unsigned long int block12, block13, block14, block15;
|
|
#ifdef DEBUG
|
|
short i;
|
|
#endif
|
|
|
|
unsigned long int SBoxEntry; /* just a temporary */
|
|
|
|
#ifdef DEBUG
|
|
if (wordCount != 16)
|
|
errAbort ("Hash512 called with wordCount != 16");
|
|
if (hashSize != 4)
|
|
errAbort ("Hash512 called with hashSize != 4");
|
|
#endif
|
|
|
|
/* initialize the block to be encrypted from the input */
|
|
/* Note that in theory block<i> should be kept in register. Not all
|
|
compilers can do this, even when there are enough registers --
|
|
this will degrade performance significantly. */
|
|
block0 = input[0];
|
|
block1 = input[1];
|
|
block2 = input[2];
|
|
block3 = input[3];
|
|
block4 = input[4];
|
|
block5 = input[5];
|
|
block6 = input[6];
|
|
block7 = input[7];
|
|
block8 = input[8];
|
|
block9 = input[9];
|
|
block10 = input[10];
|
|
block11 = input[11];
|
|
block12 = input[12];
|
|
block13 = input[13];
|
|
block14 = input[14];
|
|
block15 = input[15];
|
|
|
|
|
|
#ifdef DEBUG
|
|
for (index = 0; index < 2 * localSecurityLevel; index += 2) {
|
|
#endif
|
|
|
|
/* Mix in the parameter that parameterizes this instance of
|
|
the hash function */
|
|
block0 ^= p0;
|
|
block1 ^= p1;
|
|
block2 ^= p2;
|
|
|
|
/* set up the base address for the two S-box pointers. */
|
|
SBox0 = rotatedRightBase[0][0];
|
|
SBox1 = SBox0 + 256;
|
|
|
|
|
|
/* In the following unrolled code, the basic 'assembly
|
|
language' block that is repeated is:
|
|
|
|
1 temp1 = shift(block<i>, shiftConstant) 2 temp2 =
|
|
temp1 & 0x3fc 3 temp3 = SBox<0 or 1> + temp2 4 temp4
|
|
= *temp3 5 block<i-1> ^= temp4 6 block<i+1> ^= temp4
|
|
|
|
In step 1, we simply shift the ith 32-bit block to bring the
|
|
8-bit byte into the right position. Note that we will
|
|
also build-in a left-shift by 2 bits at this stage, to
|
|
eliminate the left shift required later because we are
|
|
indexing into an array of 4-byte table entries.
|
|
|
|
In step 2, we mask off the desired 8 bits. Note that 0x3fc
|
|
is simply 0xff << 2.
|
|
|
|
In step 3, we use a normal integer add to compute the actual
|
|
address of the S-box entry. Note that one of two pointers
|
|
is used, as appropriate. Temp3 then holds the actual byte
|
|
address of the desired S-box entry.
|
|
|
|
In step 4, we load the 4-byte S-box entry.
|
|
|
|
In steps 5 and 6, we XOR the loaded S-box entry with both the
|
|
previous and the next 32-bit entries in the 'block' array.
|
|
|
|
Typical optimizing comilers might fail to put all the
|
|
block<i> variables into registers. This can result in
|
|
significant performance degradation. Also, most compilers
|
|
will use a separate left-shift-by-2 after masking off the
|
|
needed 8 bits, but the performance degradation caused by
|
|
this oversight should be modest.
|
|
|
|
*/
|
|
|
|
SBoxEntry = SBox0[block0 & 0xff];
|
|
block1 ^= SBoxEntry;
|
|
block15 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block1 & 0xff];
|
|
block2 ^= SBoxEntry;
|
|
block0 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block2 & 0xff];
|
|
block3 ^= SBoxEntry;
|
|
block1 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block3 & 0xff];
|
|
block4 ^= SBoxEntry;
|
|
block2 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block4 & 0xff];
|
|
block5 ^= SBoxEntry;
|
|
block3 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block5 & 0xff];
|
|
block6 ^= SBoxEntry;
|
|
block4 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block6 & 0xff];
|
|
block7 ^= SBoxEntry;
|
|
block5 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block7 & 0xff];
|
|
block8 ^= SBoxEntry;
|
|
block6 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block8 & 0xff];
|
|
block9 ^= SBoxEntry;
|
|
block7 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block9 & 0xff];
|
|
block10 ^= SBoxEntry;
|
|
block8 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block10 & 0xff];
|
|
block11 ^= SBoxEntry;
|
|
block9 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block11 & 0xff];
|
|
block12 ^= SBoxEntry;
|
|
block10 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block12 & 0xff];
|
|
block13 ^= SBoxEntry;
|
|
block11 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block13 & 0xff];
|
|
block14 ^= SBoxEntry;
|
|
block12 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block14 & 0xff];
|
|
block15 ^= SBoxEntry;
|
|
block13 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block15 & 0xff];
|
|
block0 ^= SBoxEntry;
|
|
block14 ^= SBoxEntry;
|
|
|
|
/* SBox0 = rotatedRightStandardSBoxes[2][index]; */
|
|
SBox0 += 2 * maxSBoxCount * 256;
|
|
SBox1 = SBox0 + 256;
|
|
|
|
SBoxEntry = SBox0[(block0 >> 16) & 0xff];
|
|
block1 ^= SBoxEntry;
|
|
block15 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block1 >> 16) & 0xff];
|
|
block2 ^= SBoxEntry;
|
|
block0 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block2 >> 16) & 0xff];
|
|
block3 ^= SBoxEntry;
|
|
block1 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block3 >> 16) & 0xff];
|
|
block4 ^= SBoxEntry;
|
|
block2 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block4 >> 16) & 0xff];
|
|
block5 ^= SBoxEntry;
|
|
block3 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block5 >> 16) & 0xff];
|
|
block6 ^= SBoxEntry;
|
|
block4 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block6 >> 16) & 0xff];
|
|
block7 ^= SBoxEntry;
|
|
block5 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block7 >> 16) & 0xff];
|
|
block8 ^= SBoxEntry;
|
|
block6 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block8 >> 16) & 0xff];
|
|
block9 ^= SBoxEntry;
|
|
block7 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block9 >> 16) & 0xff];
|
|
block10 ^= SBoxEntry;
|
|
block8 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block10 >> 16) & 0xff];
|
|
block11 ^= SBoxEntry;
|
|
block9 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block11 >> 16) & 0xff];
|
|
block12 ^= SBoxEntry;
|
|
block10 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block12 >> 16) & 0xff];
|
|
block13 ^= SBoxEntry;
|
|
block11 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block13 >> 16) & 0xff];
|
|
block14 ^= SBoxEntry;
|
|
block12 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block14 >> 16) & 0xff];
|
|
block15 ^= SBoxEntry;
|
|
block13 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block15 >> 16) & 0xff];
|
|
block0 ^= SBoxEntry;
|
|
block14 ^= SBoxEntry;
|
|
|
|
|
|
/* SBox0 = rotatedRightStandardSBoxes[1][index]; */
|
|
SBox0 -= maxSBoxCount * 256;
|
|
SBox1 = SBox0 + 256;
|
|
|
|
SBoxEntry = SBox0[block0 >> 24];
|
|
block1 ^= SBoxEntry;
|
|
block15 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block1 >> 24];
|
|
block2 ^= SBoxEntry;
|
|
block0 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block2 >> 24];
|
|
block3 ^= SBoxEntry;
|
|
block1 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block3 >> 24];
|
|
block4 ^= SBoxEntry;
|
|
block2 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block4 >> 24];
|
|
block5 ^= SBoxEntry;
|
|
block3 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block5 >> 24];
|
|
block6 ^= SBoxEntry;
|
|
block4 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block6 >> 24];
|
|
block7 ^= SBoxEntry;
|
|
block5 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block7 >> 24];
|
|
block8 ^= SBoxEntry;
|
|
block6 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block8 >> 24];
|
|
block9 ^= SBoxEntry;
|
|
block7 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block9 >> 24];
|
|
block10 ^= SBoxEntry;
|
|
block8 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block10 >> 24];
|
|
block11 ^= SBoxEntry;
|
|
block9 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block11 >> 24];
|
|
block12 ^= SBoxEntry;
|
|
block10 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block12 >> 24];
|
|
block13 ^= SBoxEntry;
|
|
block11 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[block13 >> 24];
|
|
block14 ^= SBoxEntry;
|
|
block12 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block14 >> 24];
|
|
block15 ^= SBoxEntry;
|
|
block13 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[block15 >> 24];
|
|
block0 ^= SBoxEntry;
|
|
block14 ^= SBoxEntry;
|
|
|
|
|
|
/* SBox0 = rotatedRightStandardSBoxes[3][index]; */
|
|
SBox0 += 2 * maxSBoxCount * 256;
|
|
SBox1 = SBox0 + 256;
|
|
|
|
SBoxEntry = SBox0[(block0 >> 8) & 0xff];
|
|
block1 ^= SBoxEntry;
|
|
block15 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block1 >> 8) & 0xff];
|
|
block2 ^= SBoxEntry;
|
|
block0 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block2 >> 8) & 0xff];
|
|
block3 ^= SBoxEntry;
|
|
block1 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block3 >> 8) & 0xff];
|
|
block4 ^= SBoxEntry;
|
|
block2 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block4 >> 8) & 0xff];
|
|
block5 ^= SBoxEntry;
|
|
block3 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block5 >> 8) & 0xff];
|
|
block6 ^= SBoxEntry;
|
|
block4 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block6 >> 8) & 0xff];
|
|
block7 ^= SBoxEntry;
|
|
block5 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block7 >> 8) & 0xff];
|
|
block8 ^= SBoxEntry;
|
|
block6 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block8 >> 8) & 0xff];
|
|
block9 ^= SBoxEntry;
|
|
block7 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block9 >> 8) & 0xff];
|
|
block10 ^= SBoxEntry;
|
|
block8 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block10 >> 8) & 0xff];
|
|
block11 ^= SBoxEntry;
|
|
block9 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block11 >> 8) & 0xff];
|
|
block12 ^= SBoxEntry;
|
|
block10 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block12 >> 8) & 0xff];
|
|
block13 ^= SBoxEntry;
|
|
block11 ^= SBoxEntry;
|
|
SBoxEntry = SBox0[(block13 >> 8) & 0xff];
|
|
block14 ^= SBoxEntry;
|
|
block12 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block14 >> 8) & 0xff];
|
|
block15 ^= SBoxEntry;
|
|
block13 ^= SBoxEntry;
|
|
SBoxEntry = SBox1[(block15 >> 8) & 0xff];
|
|
block0 ^= SBoxEntry;
|
|
block14 ^= SBoxEntry;
|
|
|
|
|
|
#ifdef DEBUG
|
|
}; /* end of index going from 0 to
|
|
2*localSecurityLevel-2 in steps of 2 */
|
|
#endif
|
|
|
|
/* XOR the parameter with the next-to-the-last three words of the block */
|
|
block14 ^= p0;
|
|
block13 ^= p1;
|
|
block12 ^= p2;
|
|
|
|
output[0] = input[0] ^ block15;
|
|
output[1] = input[1] ^ block14;
|
|
output[2] = input[2] ^ block13;
|
|
output[3] = input[3] ^ block12;
|
|
|
|
|
|
};
|
|
|
|
|
|
int do_hash(rotatedsBox rotatedRightStandardSBoxes)
|
|
|
|
{
|
|
|
|
int i;
|
|
unsigned long int hasharray[16];
|
|
unsigned long int p0=0,p1=1,p2=2;
|
|
int starttime;
|
|
|
|
|
|
starttime = TickCount();
|
|
|
|
for (i=0;i<NUMTIMES;i++) {
|
|
Hash512(hasharray,hasharray,p0,p1,p2,rotatedRightStandardSBoxes);
|
|
};
|
|
|
|
fprintf(stderr,"%d iterations took%d\n",NUMTIMES,TickCount()-starttime);
|
|
|
|
starttime = TickCount();
|
|
|
|
for (i=0;i<NUMTIMES;i++) ;
|
|
|
|
fprintf(stderr,"%d iterations of a blank loop took %d\n",
|
|
NUMTIMES,TickCount()-starttime);
|
|
return 0;
|
|
};
|
|
|
|
extern sBoxs *GetsBoxBase(); // from hash.a
|
|
|
|
/* generate_boxes
|
|
Takes a pointer to the unrotated sBoxs, allocates and generates a pre-rotated
|
|
substitution box for the Hash512 routine.
|
|
*/
|
|
short generate_boxes( sBoxs *thesBoxBase, /* unrotated substitution boxes */
|
|
rotatedsBox **rotatedRightStandardSBoxes) /* target boxes */
|
|
{
|
|
*rotatedRightStandardSBoxes = (rotatedsBox *) NewPtr(sizeof(sBox)*hashSize*maxSBoxCount);
|
|
if (*rotatedRightStandardSBoxes == NULL) return MemError();
|
|
|
|
{
|
|
int index; /* ranges over the S box indices */
|
|
register unsigned long int *sBoxEntry;
|
|
register unsigned long int *SBox0;
|
|
register short i;
|
|
register char leftshift,rightshift;
|
|
|
|
for (index = 0; index < maxSBoxCount; index++) {
|
|
|
|
sBoxEntry = (*thesBoxBase)[index];
|
|
SBox0 = (**rotatedRightStandardSBoxes)[0][index];
|
|
for (i = 0; i < 256; i++) /* rotation = 0 */
|
|
*SBox0++ = *sBoxEntry++;
|
|
|
|
sBoxEntry = (*thesBoxBase)[index];
|
|
SBox0 = (**rotatedRightStandardSBoxes)[1][index];
|
|
leftshift = 24;
|
|
rightshift = 8;
|
|
for (i = 0; i < 256; i++) /* rotation = 1 */
|
|
*SBox0++ = ((*sBoxEntry >> rightshift) | (*sBoxEntry++ << leftshift));
|
|
|
|
sBoxEntry = (*thesBoxBase)[index];
|
|
SBox0 = (**rotatedRightStandardSBoxes)[2][index];
|
|
leftshift = rightshift = 16;
|
|
for (i = 0; i < 256; i++) /* rotation = 2 */
|
|
*SBox0++ = ((*sBoxEntry >> rightshift) | (*sBoxEntry++ << leftshift));
|
|
|
|
sBoxEntry = (*thesBoxBase)[index];
|
|
SBox0 = (**rotatedRightStandardSBoxes)[3][index];
|
|
leftshift = 8;
|
|
rightshift = 24;
|
|
for (i = 0; i < 256; i++) /* rotation = 3 */
|
|
*SBox0++ = ((*sBoxEntry >> rightshift) | (*sBoxEntry++ << leftshift));
|
|
};
|
|
|
|
};
|
|
return 0;
|
|
};
|
|
|
|
/* generate_hash
|
|
Takes an arbitrary (assumed multiple of 64 bytes) buffer (input) and initial keys
|
|
(p0,p1,p2) and generates a signature (output). The signature is 128 bits long. The
|
|
rotated s-boxs will be created if passed in as NULL, assumed generated already otherwise.
|
|
The input buffer is assumed (size) bytes.
|
|
|
|
The output buffer is used in repeated calls to Hash512 and therefore has an undefined
|
|
value during the call, becoming defined only on exit.
|
|
|
|
The basis of the hash function is to take 64 byte inputs and generate 16 byte outputs.
|
|
the outputs are accumulated 4 times, then hashed into the lower 16 bytes. This means
|
|
that the Hash512 function is called size/64 + size/(256-64) - 1 times. The size/64
|
|
is the number of calls for the image, the size/(256-64) is to hash down the 64 byte
|
|
output into the lower sixteen bytes, using the upper 192 bytes as output buffers
|
|
for the ongoing hash, the - 1 because you get to use the first 16 bytes of the
|
|
output buffer once.
|
|
|
|
This procedure allocates memory for the rotated sboxes with a newptr call from the
|
|
current heap. It will never dispose of memory, but will return an error if it
|
|
runs out of memory.
|
|
*/
|
|
short generate_hash( sBoxs *sBoxs, // unrotated substitution boxes
|
|
rotatedsBox **rotatedRightStandardSBoxes, // place for rotated ones
|
|
unsigned int *input, // input buffer
|
|
unsigned int *output, // output buffer
|
|
unsigned int size) // size of input buffer
|
|
{ short error; // returned by generate_boxes
|
|
unsigned int temp_output[16]; // temporary holder of the unhashed output
|
|
register int datasize = size, output_loc;
|
|
|
|
register unsigned int p0 = 0, /* initial keys */
|
|
p1 = 0,
|
|
p2 = size*8; // varies directly as the number of input bits
|
|
|
|
size = size & 0xFFFFFC0; // make sure we are multiple of 64 bytes
|
|
|
|
if (*rotatedRightStandardSBoxes == NULL)
|
|
if(error = generate_boxes(sBoxs,rotatedRightStandardSBoxes)) return error;
|
|
|
|
// initialize our temporary output buffer
|
|
for (output_loc = 0;output_loc < 16;output_loc++) temp_output[output_loc] = 0;
|
|
output_loc = 0;
|
|
|
|
do {
|
|
Hash512(&temp_output[output_loc],input,p0,p1,p2,*rotatedRightStandardSBoxes); // generate hash
|
|
p2 += 1;
|
|
size -= 64; // decrement by (512/8) bits
|
|
input += 16; // bump by 64 bytes
|
|
output_loc += 4; // bump the output buffer pointer
|
|
|
|
if (output_loc >= 16) { // the output buffer is full, hash it down
|
|
|
|
Hash512(temp_output,temp_output,p0,p1,p2,*rotatedRightStandardSBoxes);
|
|
output_loc = 4; // point at the first unused block
|
|
p2 += 1;
|
|
};
|
|
} while (size > 0);
|
|
|
|
// final hash down into the passed output buffer
|
|
|
|
Hash512(output,temp_output,p0,p1,p2,*rotatedRightStandardSBoxes);
|
|
|
|
return 0; // no errors after generate_boxes
|
|
};
|
|
|
|
|
|
main(){
|
|
int rotatetime = TickCount();
|
|
int numrotates = NUMTIMES / 100;
|
|
rotatedsBox *rotatedRightStandardSBoxes
|
|
= NewPtr(sizeof(sBox)*hashSize*maxSBoxCount);
|
|
rotatedsBox *checkrotatedRightStandardSBoxes
|
|
= NewPtr(sizeof(sBox)*hashSize*maxSBoxCount);
|
|
sBoxs *sBoxBase;
|
|
rotatedsBox *theFastsBox;
|
|
unsigned int input[16],output[4],p0=0,p1=0,p2=0,k;
|
|
short error;
|
|
|
|
for (k=0;k<16;k++) input[k] = 0; // init the input & output buffers
|
|
for (k=0;k<4;k++) output[k]= 0;
|
|
|
|
sBoxBase = GetsBoxBase();
|
|
theFastsBox = NULL;
|
|
//
|
|
// try the pup here!!
|
|
//
|
|
// prime it.. make the memory manager give us the block and build the rotated boxes
|
|
rotatetime = TickCount();
|
|
error = generate_hash( sBoxBase,
|
|
&theFastsBox,
|
|
input,
|
|
output,
|
|
1024*1024);
|
|
if (error == NULL) DisposPtr((Ptr)theFastsBox);
|
|
rotatetime = TickCount()-rotatetime;
|
|
fprintf(stderr,"hash of 1 meg took %d ticks, %d seconds\n "
|
|
,rotatetime,rotatetime/60);
|
|
|
|
fprintf(stderr,"we got... %d for error,\n %X\t%X\t%X\t%X\t\n",
|
|
error,output[0],output[1],output[2],output[3]);
|
|
|
|
#ifdef SPEED_TESTS
|
|
if ((rotatedRightStandardSBoxes == NULL) || (checkrotatedRightStandardSBoxes == NULL))
|
|
DebugStr("\p whoops, out of memory");
|
|
while (numrotates--)
|
|
/* Set up the rotated array for the fast hash routine */
|
|
{
|
|
int index; /* ranges over the S box indices */
|
|
register unsigned long int *sBoxEntry;
|
|
register unsigned long int *SBox0;
|
|
register short i;
|
|
register char leftshift,rightshift;
|
|
|
|
for (index = 0; index < maxSBoxCount; index++) {
|
|
|
|
sBoxEntry = (*sBoxBase)[index];
|
|
SBox0 = (*rotatedRightStandardSBoxes)[0][index];
|
|
for (i = 0; i < 256; i++) /* rotation = 0 */
|
|
*SBox0++ = *sBoxEntry++;
|
|
|
|
sBoxEntry = (*sBoxBase)[index];
|
|
SBox0 = (*rotatedRightStandardSBoxes)[1][index];
|
|
leftshift = 24;
|
|
rightshift = 8;
|
|
for (i = 0; i < 256; i++) /* rotation = 1 */
|
|
*SBox0++ = ((*sBoxEntry >> rightshift) | (*sBoxEntry++ << leftshift));
|
|
|
|
sBoxEntry = (*sBoxBase)[index];
|
|
SBox0 = (*rotatedRightStandardSBoxes)[2][index];
|
|
leftshift = rightshift = 16;
|
|
for (i = 0; i < 256; i++) /* rotation = 2 */
|
|
*SBox0++ = ((*sBoxEntry >> rightshift) | (*sBoxEntry++ << leftshift));
|
|
|
|
sBoxEntry = (*sBoxBase)[index];
|
|
SBox0 = (*rotatedRightStandardSBoxes)[3][index];
|
|
leftshift = 8;
|
|
rightshift = 24;
|
|
for (i = 0; i < 256; i++) /* rotation = 3 */
|
|
*SBox0++ = ((*sBoxEntry >> rightshift) | (*sBoxEntry++ << leftshift));
|
|
};
|
|
|
|
};
|
|
|
|
fprintf(stderr,"The initial rotation took %d\n",
|
|
TickCount()-rotatetime);
|
|
|
|
//
|
|
// Set up the reference version of the same thing
|
|
//
|
|
/* Set up the rotated array for the fast hash routine */
|
|
{
|
|
int index; /* ranges over the S box indices */
|
|
int rotation; /* ranges over the four possible
|
|
byte-rotations */
|
|
int i; /* ranges over the 256 possible S-box entries */
|
|
int lineno = 0;
|
|
|
|
for (index = 0; index < maxSBoxCount; index++)
|
|
for (rotation = 0; rotation < 4; rotation++)
|
|
for (i = 0; i < 256; i++)
|
|
(*checkrotatedRightStandardSBoxes)[rotation][index][i] =
|
|
((*sBoxBase)[index][i] >> (rotation * 8)) |
|
|
((*sBoxBase)[index][i] << (32 - rotation * 8));
|
|
|
|
//
|
|
// Now check if our version worked...
|
|
//
|
|
for (index = 0; index < maxSBoxCount; index++)
|
|
for (rotation = 0; rotation < 4; rotation++)
|
|
for (i = 0; i < 256; i++) {
|
|
#ifdef DUMPSBOXES
|
|
fprintf(stdout,"%d)\t%X\n",
|
|
++lineno,
|
|
(*rotatedRightStandardSBoxes)[rotation][index][i]);
|
|
#else
|
|
if ((*checkrotatedRightStandardSBoxes)[rotation][index][i] !=
|
|
(*rotatedRightStandardSBoxes)[rotation][index][i]) DebugStr("\pCheck failed");
|
|
#endif
|
|
};
|
|
|
|
};
|
|
|
|
// do_hash(*rotatedRightStandardSBoxes);
|
|
/* Now try hashing something. Note that we're testing both HashN and
|
|
Hash512 here */
|
|
{
|
|
unsigned long int testInput[16];
|
|
unsigned long int testOutput[hashSize];
|
|
unsigned long int testP;
|
|
int j,i;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
testInput[i] = 0; /* zero the input */
|
|
for (i = 0; i < 50; i++) {
|
|
testP = i;
|
|
Hash512(testOutput, testInput, testP, testP, testP, *rotatedRightStandardSBoxes);
|
|
for (j = 0; j < hashSize; j++)
|
|
testInput[j] = testOutput[j];
|
|
};
|
|
if ((testOutput[0] != 3322084822) || (testOutput[1] != 2015524574) ||
|
|
(testOutput[2] != 2594724576) || (testOutput[3] != 532340662)
|
|
)
|
|
errAbort ("Test hash of 64 bytes of 0 failed");
|
|
};
|
|
|
|
#endif
|
|
DisposPtr((Ptr)rotatedRightStandardSBoxes);
|
|
DisposPtr((Ptr)checkrotatedRightStandardSBoxes);
|
|
};
|