Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <stdbool.h>
- bool debug;
- uint8_t *hex = NULL;
- uint8_t *currentHash = NULL;
- uint8_t *workingHash = NULL;
- int workingHashMaxSize;
- void debug_messages();
- void exercise_messages();
- void setCurrentHash (uint8_t *msg, int size);
- void bruteforce_messages();
- void print (uint8_t *old);
- void print_s (uint8_t *old, int size);
- void bruteNext (uint8_t *old, int cnt);
- void brute();
- bool compare (uint8_t *newHash, int cnt);
- void hashAndPrint (uint8_t *msg, int size);
- uint8_t* hash (uint8_t *msg, int size);
- uint8_t* block (int blockID, uint8_t *xi, uint8_t *Hi);
- /*
- * Prints solutions to the debug questions given on the walk through
- * Select debug = true for extended output.
- */
- void debug_messages() {
- int size;
- printf("\nDebug Message i\n");
- uint8_t msg1[] = {0xC,0x5,0x4,0xF,0xF,0xD,0xD,0xF};
- size = sizeof(msg1)/sizeof(uint8_t);
- hashAndPrint(msg1,size);
- printf("\nDebug Message ii\n");
- uint8_t msg2[] = {0xF,0x9,0x9,0xD,0xE,0xE,0x7,0x9};
- size = sizeof(msg2)/sizeof(uint8_t);
- hashAndPrint(msg2,size);
- printf("\nDebug Message iii\n");
- uint8_t msg3[] = {0xA,0x0,0x2,0x8,0xE,0xA,0x0,0xE,0x0,0xC,0x8,0xC,0xC,0x7,0xA,0x6,0x4,0x3,0x0,0x7,0xD,0x4,0x6,0x2,0xB,0xE,0xC,0xC};
- size = sizeof(msg3)/sizeof(uint8_t);
- hashAndPrint(msg3,size);
- printf("\nDebug Message iv\n");
- uint8_t msg4[] = {0xC,0xF,0xA,0xE,0x5,0xC,0x6,0xB,0x4,0xA,0xF,0xA,0x3,0xC,0xC,0x8,0x2,0x4,0x7,0xE,0x0,0x9,0x8,0xC,0x6,0x8,0x3,0xD};
- size = sizeof(msg4)/sizeof(uint8_t);
- hashAndPrint(msg4,size);
- }
- /*
- * Prints solutions to the exercise questions given in the handout
- * Select debug = true for extended output.
- */
- void exercise_messages() {
- int size;
- printf("\nMessage i\n");
- //0xFAB17E668145A9BCC783BFEE70013522734
- uint8_t msg1[] = {0xF,0xA,0xB,0x1,0x7,0xE,0x6,0x6,0x8,0x1,0x4,0x5,0xA,0x9,0xB,0xC,0xC,0x7,0x8,0x3,0xB,0xF,0xE,0xE,0x7,0x0,0x0,0x1,0x3,0x5,0x2,0x2,0x7,0x3,0x4};
- size = sizeof(msg1)/sizeof(uint8_t);
- hashAndPrint(msg1,size);
- printf("\nMessage ii\n");
- //0xFAB17E668145A9BCC783BFEE70013521912
- uint8_t msg2[] = {0xF,0xA,0xB,0x1,0x7,0xE,0x6,0x6,0x8,0x1,0x4,0x5,0xA,0x9,0xB,0xC,0xC,0x7,0x8,0x3,0xB,0xF,0xE,0xE,0x7,0x0,0x0,0x1,0x3,0x5,0x2,0x1,0x9,0x1,0x2};
- size = sizeof(msg2)/sizeof(uint8_t);
- hashAndPrint(msg2,size);
- printf("\nMessage iii\n");
- //0xEAB17E668145A9BCC783BFEE70013521558
- uint8_t msg3[] = {0xE,0xA,0xB,0x1,0x7,0xE,0x6,0x6,0x8,0x1,0x4,0x5,0xA,0x9,0xB,0xC,0xC,0x7,0x8,0x3,0xB,0xF,0xE,0xE,0x7,0x0,0x0,0x1,0x3,0x5,0x2,0x1,0x5,0x5,0x8};
- size = sizeof(msg3)/sizeof(uint8_t);
- hashAndPrint(msg3,size);
- printf("\nMessage iv\n");
- //0x24A7B9FD294AFE569BB23197FFEAB67D
- uint8_t msg4[] = {0x2,0x4,0xA,0x7,0xB,0x9,0xF,0xD,0x2,0x9,0x4,0xA,0xF,0xE,0x5,0x6,0x9,0xB,0xB,0x2,0x3,0x1,0x9,0x7,0xF,0xF,0xE,0xA,0xB,0x6,0x7,0xD};
- size = sizeof(msg4)/sizeof(uint8_t);
- hashAndPrint(msg4,size);
- }
- void setCurrentHash (uint8_t *msg, int size) {
- printf("Searching for this Hash: \n");
- currentHash = msg;
- print(currentHash);
- }
- /*
- * Prints collisions found for brute force question
- * Select debug = true for extended output.
- */
- void bruteforce_messages() {
- clock_t start_h=clock();
- printf("\nBegin Brute Force i\n");
- //uint8_t bmsg1[] = {0xA,0xB,0xC,0xD,0xE,0xF,0x1,0x2,0x3,0x4};
- uint8_t bmsg1[] = {0xC,0x5,0x4,0xF,0xF,0xD,0xD,0xF};
- uint8_t *hsh = hash(bmsg1, 8);
- print(hsh);
- setCurrentHash(hsh,5);
- brute();
- free(hsh);
- clock_t end_h = clock();
- double time_h = (double)(end_h-start_h)/CLOCKS_PER_SEC;
- printf("Brute Force speed %f \n", time_h);
- }
- /*
- * Prints out a given hash
- * Assumes hash size is 5
- */
- void print (uint8_t *old) {
- int size = 5;
- for (int i = 0; i < size; i++) {
- printf("%#x\n", old[i]);
- }
- }
- /*
- * Prints out a given hash
- * does not assume size
- */
- void print_s (uint8_t *old, int size) {
- for (int i = 0; i < size; i++) {
- printf("%#x\n", old[i]);
- }
- }
- /*
- * Will recursively brute force the next message
- * Check workingHashMaxSize for the maximum size the message can be
- */
- void bruteNext (uint8_t *old, int cnt) {
- cnt += 1;
- uint8_t *hsh = hash(old, cnt);
- if (compare(hsh,5) == true) {
- printf("found collision\n");
- print_s(old, cnt);
- printf("for hash\n");
- print(hsh);
- }
- free(hsh);
- if (cnt < workingHashMaxSize) {
- for (int i = 0; i < 16; i++) {
- old[cnt] = hex[i];
- bruteNext(old,cnt);
- }
- } else {
- //free(old);
- }
- }
- /*
- * Call this method to brute force new messages
- * This method calls bruteNext recursively.
- */
- void brute() {
- int count = 0;
- // Initially give the working hash capacity for 80 bits
- // Each element in the array has 4 bits masked
- // Effectively 40 bits of working data
- workingHashMaxSize = 10;
- workingHash = (uint8_t *)malloc(10);
- for (int i = 0; i < 16; i++) {
- workingHash[0] = hex[i];
- bruteNext(workingHash,count);
- count = 0;
- }
- free(workingHash);
- }
- /*
- * Compares the generated hash with the hashes we're looking for
- * Used when looking for possible collisions
- */
- bool compare (uint8_t *newHash, int cnt) {
- int size = cnt;
- bool ok = true;
- for ( int i = 0; i < size; i++ ) {
- if ( newHash[i] == currentHash[i] ) {
- // Looks good!
- } else {
- ok = false;
- break;
- }
- }
- return ok;
- }
- /*
- * This method is used for printing out the final hash value of a message
- * Useful when debug = false
- */
- void hashAndPrint (uint8_t *msg, int size) {
- uint8_t *msg_r = NULL;;
- msg_r = (uint8_t *)malloc(size * sizeof(uint8_t));
- memcpy (msg_r,msg,size);
- uint8_t *hsh = hash(msg_r, size);
- print(hsh);
- // Free memory on the heap
- free(hsh);
- free(msg_r);
- }
- /*
- * Hash will first break the message into blocks of 4 bit, and append any nessisary padding
- * It will call the block method when hashing each 4 bit block
- * Finally, it will then combine the blocks to produce the final hash.
- */
- uint8_t* hash (uint8_t* msg, int size) {
- // if (debug == true) { clock_t start_h=clock(); }
- //print_s(msg, size);
- uint8_t *msg_r = NULL;;
- int toAppend = 0;
- // Check to see if message is correct size
- if ( size >= 1 ) {
- if (debug == true) { printf("Message size = %d\n", size); }
- if ( size%5 != 0 ) {
- if (debug == true) { printf("!!! ERROR !!! size of Message is falset 20 bit blocks\n"); }
- while (size%5 != 0) {
- size += 1;
- toAppend += 1;
- }
- } else {
- if (debug == true) { printf("Size of Message is in 20 bit blocks: OK\n"); }
- }
- } else {
- if (debug == true) { printf("!!! FAIL !!! size of message is Zero\n"); }
- }
- if ( toAppend > 0 ) {
- // Allocate storage for the new size
- msg_r = (uint8_t *)malloc(size * sizeof(uint8_t));
- // Copy contents
- memcpy (msg_r,msg,size-toAppend);
- while (!(toAppend < 0)) {
- // Append 0x0 to elements falset in array
- msg_r[size-toAppend] = 0x0;
- toAppend -= 1;
- if (debug == true) { printf("!!! Attempting to fix !!! appended 0x0 for padding\n"); }
- }
- } else {
- // Just copy contents
- msg_r = (uint8_t *)malloc(size * sizeof(uint8_t));
- memcpy (msg_r,msg,size);
- }
- int id = 0;
- uint8_t *nextBlock = NULL;
- uint8_t blck[5];
- for ( int i = 0; i < size; i+=5) {
- for ( int u = 0; u < 5; u++) {
- blck[u] = msg_r[i+u];
- }
- id += 1;
- if ( i == 0 ) {
- if (debug == true) { printf("Creating block with ID: %d\n", id); }
- uint8_t Hi[5] = {0x2,0x5,0x9,0xB,0xE};
- nextBlock = block(id,blck,Hi);
- } else {
- if (debug == true) { printf("Creating block with ID: %d\n", id); }
- uint8_t Hi[5] = {nextBlock[0],nextBlock[1],nextBlock[2],nextBlock[3],nextBlock[4]};
- nextBlock = block(id,blck,Hi);
- }
- }
- // Print results
- if (debug == true) { printf("Final Hash value \n"); }
- if (debug == true) { printf("A: %#x\n", nextBlock[0]); }
- if (debug == true) { printf("B: %#x\n", nextBlock[1]); }
- if (debug == true) { printf("C: %#x\n", nextBlock[2]); }
- if (debug == true) { printf("D: %#x\n", nextBlock[3]); }
- if (debug == true) { printf("E: %#x\n", nextBlock[4]); }
- // Free memory on the Heap
- free(msg_r);
- // Finish
- // if (debug == true) { clock_t end_h = clock(); }
- // if (debug == true) { double time_h = (double)(end_h-start_h)/CLOCKS_PER_SEC; }
- // if (debug == true) { printf("hash speed: %f \n", time_h); }
- return nextBlock;
- }
- uint8_t *block (int blockID, uint8_t *xi, uint8_t *Hi) {
- if (debug == true) { printf("process block %d\n", blockID); }
- if (debug == true) { printf("ABCDE = %#x %#x %#x %#x %#x \n", Hi[0], Hi[1], Hi[2], Hi[3], Hi[4] ); }
- // left shift with carry for 4 bit
- // (foo << 1 | foo >> 3)
- // & 0xF to mask the leading bit
- for (int i=5; i<20;i++){
- uint8_t num = xi[i-1]^xi[i-4]^xi[i-5];
- num = (num << 1 | num >> 3) & 0xF;
- if (debug == true) { printf("%#x\n", num); }
- xi[i] = num;
- }
- // Copy the ABCDE array for later use
- uint8_t H15[5] = {Hi[0],Hi[1],Hi[2],Hi[3],Hi[4]};
- if (debug == true) { printf("begin round 1\n"); }
- for (int i=0; i<10;i++){
- if (debug == true) { printf("step %d\n", i); }
- // components
- uint8_t A = Hi[0];
- A = (A << 1 | A >> 3) & 0xF;
- uint8_t F = (Hi[1]&Hi[2])|(~Hi[1]&Hi[3]) & 0xF;
- uint8_t Xi = xi[i];
- uint8_t E = Hi[4];
- // product in modulo arithmatic 2^4
- uint8_t t = (A + F + Xi + E)%0x10;
- // temp variables
- uint8_t tempA = Hi[0];
- uint8_t tempB = Hi[1];
- uint8_t tempC = Hi[2];
- uint8_t tempD = Hi[3];
- // remap
- // shift t i times
- for (int j = 1; j <= i; j++){
- t = (t << 1 | t >> 3) & 0xF;
- }
- // shift b 3 times
- for (int j = 1; j <= 3; j++){
- tempB = (tempB << 1 | tempB >> 3) & 0xF;
- }
- Hi[0] = t; if (debug == true) { printf("%#x\n", Hi[0]); }
- Hi[1] = tempA; if (debug == true) { printf("%#x\n", Hi[1]); }
- Hi[2] = tempB; if (debug == true) { printf("%#x\n", Hi[2]); }
- Hi[3] = tempC; if (debug == true) { printf("%#x\n", Hi[3]); }
- Hi[4] = tempD; if (debug == true) { printf("%#x\n", Hi[4]); }
- }
- if (debug == true) { printf("begin round 2\n"); }
- for (int i=10; i<20;i++){
- if (debug == true) { printf("step %d\n", i); }
- // components
- uint8_t A = Hi[0];
- // shift A i times
- for (int j = 1; j <= 3; j++){
- A = (A << 1 | A >> 3) & 0xF;
- }
- uint8_t G = (Hi[1]&Hi[3])|(Hi[2]&(~Hi[3])) & 0xF;
- uint8_t Xi = xi[i];
- uint8_t E = Hi[4];
- // product in modulo arithmatic 2^4
- uint8_t t = (A + G + Xi + E)%0x10;
- // temp variables
- uint8_t tempA = Hi[0];
- uint8_t tempB = Hi[1];
- uint8_t tempC = Hi[2];
- uint8_t tempD = Hi[3];
- // remap
- // shift t i times
- for (int j = 1; j <= i; j++){
- t = (t << 1 | t >> 3) & 0xF;
- }
- // shift b 3 times
- for (int j = 1; j <= 1; j++){
- tempB = (tempB << 1 | tempB >> 3) & 0xF;
- }
- Hi[0] = t; if (debug == true) { printf("%#x\n", Hi[0]); }
- Hi[1] = tempA; if (debug == true) { printf("%#x\n", Hi[1]); }
- Hi[2] = tempB; if (debug == true) { printf("%#x\n", Hi[2]); }
- Hi[3] = tempC; if (debug == true) { printf("%#x\n", Hi[3]); }
- Hi[4] = tempD; if (debug == true) { printf("%#x\n", Hi[4]); }
- }
- if (debug == true) { printf("finalisation step\n"); }
- uint8_t a = (Hi[0]+H15[0])%0x10;
- uint8_t b = (Hi[1]+H15[1])%0x10;
- uint8_t c = (Hi[2]+H15[2])%0x10;
- uint8_t d = (Hi[3]+H15[3])%0x10;
- uint8_t e = (Hi[4]+H15[4])%0x10;
- int retElements = 5*sizeof(uint8_t);
- uint8_t *ret = (uint8_t *)malloc(retElements);
- ret[0] = a; if (debug == true) { printf("A: %#x\n", ret[0]); }
- ret[1] = b; if (debug == true) { printf("B: %#x\n", ret[1]); }
- ret[2] = c; if (debug == true) { printf("C: %#x\n", ret[2]); }
- ret[3] = d; if (debug == true) { printf("D: %#x\n", ret[3]); }
- ret[4] = e; if (debug == true) { printf("E: %#x\n", ret[4]); }
- //free(xi);
- //free(Hi);
- return ret;
- }
- int main(int argc,char **argv) {
- debug = false;
- hex = (uint8_t *)malloc(16 * sizeof(uint8_t));
- hex[0] = 0x0; hex[1] = 0x1; hex[2] = 0x2; hex[3] = 0x3; hex[4] = 0x4; hex[5] = 0x5;
- hex[6] = 0x6; hex[7] = 0x7; hex[8] = 0x8; hex[9] = 0x9; hex[10] = 0xA; hex[11] = 0xB;
- hex[12] = 0xC; hex[13] = 0xD; hex[14] = 0xE; hex[15] = 0xF;
- //debug_messages();
- //exercise_messages();
- bruteforce_messages();
- free(hex);
- return 0;
- }
Add Comment
Please, Sign In to add comment