1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
#define DEBUG 2
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
typedef unsigned int uint;
typedef unsigned long int uint32_t;
typedef unsigned long long int uint64_t;
union block
{
char msg[];
uint32_t word[];
};
int main(int argc, char* argv[])
{
if( !argv[1] )
{
cout <<"you did it wrong!\n ";
return -1;
}
/************************************PADDING********************************/
/* the number of bits in the message. placed convieniently in a 64bit type */
const uint64_t msgsize_bit = strlen( argv[1] ) * 8;
if(DEBUG > 0) cout << "Bitwise message size:\t" << msgsize_bit <<endl;
/* quantum number of 512 blocks required */
uint blocks = ceil( ((float)msgsize_bit + 1 + 64) / 512 );
if(DEBUG > 0) cout << "No. of 512 bit blocks:\t" << blocks <<endl;
/* The actual number of BYTES that the message will be padded to */
uint padlength = (512 * blocks) / 8;
if(DEBUG > 0) cout << "Overall padding length (bytes):\t" << padlength <<endl;
/* this is a union so the message can later be accessed in chunks */
block padding;
if(DEBUG > 1) cout << "Initilizing padding block."<<endl;
/* Creates a character array of padlength + 1, including the null bit */
padding.msg[ padlength ];
if(DEBUG > 1) cout << "Generating padding array."<<endl;
/* insert the actual message in to the padding at position zero*/
memcpy(&padding.msg[0] , argv[1] , strlen(argv[1]) );
if(DEBUG > 1) cout << "Copying message to padding block."<<endl;
/* Since the final padded length has to be a multiple of 512, we know */
/* that the final digits are 64 bits and the message is a multiple of */
/* 8 bits. the padding (1 and consecutive zeros) must be at least */
/* 8 bits. therefore the next few lines should be a safe assumption. */
padding.msg[ strlen( argv[1] ) ] = 0x80;
if(DEBUG > 1) cout << "Generating padding start bit."<<endl;
if(DEBUG > 1) cout << "Original message size (bits):" <<msgsize_bit<<endl;
uint fillerbits = ((padlength * 8) - 64 - msgsize_bit);
if(DEBUG > 1) cout << "Calculating required Filler padding bits, "<< fillerbits <<endl;
uint nullbytes = (fillerbits / 8) - 1;
if(DEBUG > 1) cout << "Calculating required NULL padding bytes, "<< nullbytes <<endl;
int pos = 1;
while( (pos-1) < nullbytes )
{
padding.msg[ strlen( argv[1] ) + pos ] = 0x00;
if(DEBUG > 1) cout << "Added NULL bit at padding position ("<< strlen( argv[1] ) + pos<<"/"<< fillerbits <<")"<<endl;
pos++;
}
/* These next few lines append the last 64 bits of the padding with the */
/* bit length of the message. Bitwise operation is necessary to ensure */
/* that the casted 64 bit integer actually consumes 64 bits */
//msgsize_bit = (msgsize_bit | 0x0000000000000000);
memcpy(&padding.msg[ padlength - 8 ] , &msgsize_bit , 8 );
cout <<padding.msg<<endl;
/**********************************PARSING*******************************/
/* According to FIPS180-4, SHA-256 the padded message (Mij) is to be */
/* is to be broken in to i 512 bit blocks and j 32-bit words */
/* i is cardinal, j is ordinal*/
/*
long *parsemsg_blocks[ blocks + 1 ][ 16 ];
#define M(i,j) parsemsg_blocks[i+1][j]
for(int x = 1; x >= blocks; x++)
{
M(x,0) = &padding[0]
}
cout << *M(1,0)<<endl;
*/
return 0;
}
|