You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.5 KiB
196 lines
5.5 KiB
/**
|
|
*--------------------------------------------------------------------\n
|
|
* HSLU T&A Hochschule Luzern Technik+Architektur \n
|
|
*--------------------------------------------------------------------\n
|
|
*
|
|
* \brief ASYD assignment crypto 05
|
|
* \file
|
|
* \author Basil Estermann, basil.estermann@stud.hslu.ch
|
|
* Simon Frei, simon.frei@stud.hslu.ch
|
|
* Jonas Arnold, jonas.arnold@stud.hslu.ch
|
|
* \date 23.03.2023
|
|
*
|
|
*--------------------------------------------------------------------
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
|
|
#define VALUE_LENGTH 32
|
|
#define MESSAGE_DIGEST_LENGTH 160
|
|
#define BLOCK_LENGTH (512/8)
|
|
#define INPUT_MESSAGE ("Testnachricht 123")
|
|
|
|
#pragma region SHA1-Constants
|
|
// initial hash values
|
|
#define H0 0x67452301
|
|
#define H1 0xEFCDAB89
|
|
#define H2 0x98BADCFE
|
|
#define H3 0x10325476
|
|
#define H4 0xC3D2E1F0
|
|
// constants Kt
|
|
#define K1 0x5A827999
|
|
#define K2 0x6ED9EBA1
|
|
#define K3 0x8F1BBCDC
|
|
#define K4 0xCA62C1D6
|
|
#pragma endregion
|
|
|
|
void printBits(size_t const size, void const* const ptr);
|
|
uint32_t leftRotate(uint32_t n, uint32_t d);
|
|
uint32_t SHA1_f1(uint32_t b, uint32_t c, uint32_t d);
|
|
uint32_t SHA1_f2(uint32_t b, uint32_t c, uint32_t d);
|
|
uint32_t SHA1_f3(uint32_t b, uint32_t c, uint32_t d);
|
|
uint32_t SHA1_f4(uint32_t b, uint32_t c, uint32_t d);
|
|
|
|
void main(void) {
|
|
|
|
int result = 0;
|
|
|
|
printf("****** SHA1 preprocessing ******\n\n");
|
|
#pragma region Preprocessing
|
|
|
|
printf("------ Set initial hash value ------\n\n");
|
|
#pragma region Initial Hash values
|
|
uint32_t a, b, c, d, e;
|
|
uint32_t h[5] = { H0, H1, H2, H3, H4 };
|
|
uint32_t k[5] = { 0, K1, K2, K3, K4 }; // 5 so the array can be accessed by 1, 2, 3, 4
|
|
a = h[0];
|
|
b = h[1];
|
|
c = h[2];
|
|
d = h[3];
|
|
e = h[4];
|
|
|
|
#pragma endregion
|
|
|
|
if (sizeof(INPUT_MESSAGE) * 8 > 447) {
|
|
printf("Message too long!");
|
|
return 1000002;
|
|
}
|
|
|
|
printf("------ Padding message ------\n\n");
|
|
#pragma region Padding
|
|
unsigned char messageNoPadding[] = INPUT_MESSAGE;
|
|
printf("Size of message without padding: %i bits\n", (int)(sizeof(INPUT_MESSAGE) * 8));
|
|
printf("Message without padding\n");
|
|
printBits(sizeof(messageNoPadding), &messageNoPadding);
|
|
unsigned char message[BLOCK_LENGTH] = "";
|
|
// fill in message
|
|
for (uint32_t i = 0; i < sizeof(INPUT_MESSAGE); i++)
|
|
{
|
|
message[i] = INPUT_MESSAGE[i];
|
|
}
|
|
// set bit
|
|
message[sizeof(INPUT_MESSAGE)] = 0b10000000;
|
|
printf("\nMessage after adding 1: \n");
|
|
printBits(sizeof(message), &message);
|
|
message[BLOCK_LENGTH - 1] = sizeof(INPUT_MESSAGE) * 8;
|
|
printf("\nMessage after adding length: \n");
|
|
printBits(sizeof(message), &message);
|
|
#pragma endregion
|
|
|
|
#pragma endregion
|
|
|
|
printf("****** Hash computation ******\n\n");
|
|
#pragma region Hash computation
|
|
|
|
printf("\n------ Prepare message schedule ------\n\n");
|
|
#pragma region Prepare message schedule
|
|
uint32_t WordArray[80] = { 0 };
|
|
for (uint32_t i = 0; i < 16; i++) {
|
|
uint32_t currentbyte = message[i] << 24;
|
|
uint32_t tmp = (uint32_t)(((uint8_t)(message[i * 4]) << 24) + ((uint8_t)(message[4 * i + 1]) << 16) + ((uint8_t)(message[4 * i + 2]) << 8) + (uint8_t)(message[4 * i + 3]));
|
|
WordArray[i] = tmp;
|
|
}
|
|
for (uint32_t i = 16; i < 80; i++) {
|
|
WordArray[i] = leftRotate((WordArray[i - 3] ^ WordArray[i - 8] ^ WordArray[i - 14] ^ WordArray[i - 16]), 1);
|
|
}
|
|
#pragma endregion
|
|
|
|
printf("\n------ Stages ------\n\n");
|
|
#pragma region Stages calculations
|
|
uint32_t (*f_ptr)(uint32_t, uint32_t, uint32_t) = &SHA1_f1; // use: (*f_ptr)(b,c,d);
|
|
uint8_t t = 1;
|
|
|
|
// stage 1...4
|
|
for (uint32_t i = 0; i < 80; i++) {
|
|
uint32_t T = leftRotate(a, 5) + ((*f_ptr)(b, c, d)) + e + k[t] + WordArray[i];
|
|
e = d;
|
|
d = c;
|
|
c = leftRotate(b, 30);
|
|
b = a;
|
|
a = T;
|
|
|
|
// switch stages
|
|
if (i == 19) { f_ptr = SHA1_f2; t = 2; }
|
|
else if (i == 39) { f_ptr = SHA1_f3; t = 3; }
|
|
else if (i == 59) { f_ptr = SHA1_f4; t = 4; }
|
|
}
|
|
#pragma endregion
|
|
|
|
printf("\n------ Intermediate hash calculation ------\n\n");
|
|
#pragma region intermediate hash calculation
|
|
h[0] = a + h[0];
|
|
h[1] = b + h[1];
|
|
h[2] = c + h[2];
|
|
h[3] = d + h[3];
|
|
h[4] = e + h[4];
|
|
#pragma endregion
|
|
#pragma endregion
|
|
|
|
printf("\n****** Resulting hash ******\n\n");
|
|
for (uint8_t i = 0; i < 5; i++) {
|
|
printf("%X", h[i]);
|
|
}
|
|
printf("\n\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint32_t SHA1_f1(uint32_t b, uint32_t c, uint32_t d) {
|
|
return (b & c) | (~b & d);
|
|
}
|
|
|
|
uint32_t SHA1_f2(uint32_t b, uint32_t c, uint32_t d) {
|
|
return b ^ c ^ d;
|
|
}
|
|
|
|
uint32_t SHA1_f3(uint32_t b, uint32_t c, uint32_t d) {
|
|
return (b & c) | (b & d) | (c & d);
|
|
}
|
|
|
|
uint32_t SHA1_f4(uint32_t b, uint32_t c, uint32_t d) {
|
|
return b ^ c ^ d;
|
|
}
|
|
|
|
uint32_t leftRotate(uint32_t n, uint32_t d)
|
|
{
|
|
/* In n<<d, last d bits are 0. To put first 3 bits of n at
|
|
last, do bitwise or of n<<d with n >>(INT_BITS - d) */
|
|
return (n << d) | (n >> (VALUE_LENGTH - d));
|
|
}
|
|
|
|
// Assumes little endian
|
|
void printBits(size_t const size, void const* const ptr)
|
|
{
|
|
unsigned char* b = (unsigned char*)ptr;
|
|
unsigned char byte;
|
|
int i, j;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
for (j = 7; j >= 0; j--) {
|
|
byte = (b[i] >> j) & 1;
|
|
printf("%u", byte);
|
|
}
|
|
}
|
|
/*original:
|
|
for (i = size - 1; i >= 0; i--) {
|
|
for (j = 7; j >= 0; j--) {
|
|
byte = (b[i] >> j) & 1;
|
|
printf("%u", byte);
|
|
}
|
|
}*/
|
|
puts("");
|
|
} |