0% found this document useful (0 votes)
42 views5 pages

Sha 256

Encyrption
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views5 pages

Sha 256

Encyrption
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Certainly. I'll provide a full implementation of SHA-256 in C, including all the necessary functions and constants.

This will give you a


complete, working example of a cryptographic hash function.

Hash Function Implementations in C


#include <stdio.h>
#include <stdint.h>
#include <string.h>

// Simple hash function: djb2


unsigned long djb2_hash(const unsigned char *str) {
unsigned long hash = 5381;
int c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; // hash * 33 + c
return hash;
}

// More complex hash function: FNV-1a


#define FNV_PRIME 0x100000001b3
#define FNV_OFFSET 0xcbf29ce484222325

uint64_t fnv1a_hash(const unsigned char *data, size_t len) {


uint64_t hash = FNV_OFFSET;
for (size_t i = 0; i < len; i++) {
hash ^= data[i];
hash *= FNV_PRIME;
}
return hash;
}

// SHA-256 Implementation
#define SHA256_BLOCK_SIZE 32

typedef struct {
uint8_t data[64];
uint32_t datalen;
uint64_t bitlen;
uint32_t state[8];
} SHA256_CTX;

#define ROTRIGHT(word,bits) (((word) >> (bits)) | ((word) << (32-(bits))))


#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))

static const uint32_t k[64] = {


0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};

void sha256_transform(SHA256_CTX *ctx, const uint8_t data[]) {


uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];

for (i = 0, j = 0; i < 16; ++i, j += 4)


m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
for ( ; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];

a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
f = ctx->state[5];
g = ctx->state[6];
h = ctx->state[7];

for (i = 0; i < 64; ++i) {


t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
t2 = EP0(a) + MAJ(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}

ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
ctx->state[5] += f;
ctx->state[6] += g;
ctx->state[7] += h;
}

void sha256_init(SHA256_CTX *ctx) {


ctx->datalen = 0;
ctx->bitlen = 0;
ctx->state[0] = 0x6a09e667;
ctx->state[1] = 0xbb67ae85;
ctx->state[2] = 0x3c6ef372;
ctx->state[3] = 0xa54ff53a;
ctx->state[4] = 0x510e527f;
ctx->state[5] = 0x9b05688c;
ctx->state[6] = 0x1f83d9ab;
ctx->state[7] = 0x5be0cd19;
}

void sha256_update(SHA256_CTX *ctx, const uint8_t data[], size_t len) {


for (size_t i = 0; i < len; ++i) {
ctx->data[ctx->datalen] = data[i];
ctx->datalen++;
if (ctx->datalen == 64) {
sha256_transform(ctx, ctx->data);
ctx->bitlen += 512;
ctx->datalen = 0;
}
}
}
void sha256_final(SHA256_CTX *ctx, uint8_t hash[]) {
uint32_t i = ctx->datalen;

if (ctx->datalen < 56) {


ctx->data[i++] = 0x80;
while (i < 56)
ctx->data[i++] = 0x00;
}
else {
ctx->data[i++] = 0x80;
while (i < 64)
ctx->data[i++] = 0x00;
sha256_transform(ctx, ctx->data);
memset(ctx->data, 0, 56);
}

ctx->bitlen += ctx->datalen * 8;
ctx->data[63] = ctx->bitlen;
ctx->data[62] = ctx->bitlen >> 8;
ctx->data[61] = ctx->bitlen >> 16;
ctx->data[60] = ctx->bitlen >> 24;
ctx->data[59] = ctx->bitlen >> 32;
ctx->data[58] = ctx->bitlen >> 40;
ctx->data[57] = ctx->bitlen >> 48;
ctx->data[56] = ctx->bitlen >> 56;
sha256_transform(ctx, ctx->data);

for (i = 0; i < 4; ++i) {


hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
}
}

int main() {
const char *input = "Hello, PhD candidate!";

// djb2 hash
printf("djb2 hash: %lu\n", djb2_hash((const unsigned char *)input));

// FNV-1a hash
printf("FNV-1a hash: %llu\n", fnv1a_hash((const unsigned char *)input, strlen(input)));

// SHA-256 hash
SHA256_CTX ctx;
uint8_t hash[SHA256_BLOCK_SIZE];
sha256_init(&ctx);
sha256_update(&ctx, (const uint8_t *)input, strlen(input));
sha256_final(&ctx, hash);

printf("SHA-256 hash: ");


for (int i = 0; i < SHA256_BLOCK_SIZE; i++) {
printf("%02x", hash[i]);
}
printf("\n");

return 0;
}

Now, let's go through the SHA-256 implementation in detail:

1. Constants and Macros:

- We define several macros for bitwise operations used in SHA-256:

- ROTRIGHT: Circular right rotation

- CH, MAJ, EP0, EP1, SIG0, SIG1: These are the six logical functions used in SHA-256

- We also define an array of 64 constants (k) used in the hash computation

2. SHA256_CTX struct:

- This structure holds the state of the SHA-256 algorithm:

- data: Buffer for input data (64 bytes, which is the block size for SHA-256)

- datalen: Current length of data in the buffer

- bitlen: Total number of bits processed

- state: Current hash state (8 32-bit words)

3. sha256_transform function:

- This is the core function that processes a 64-byte block of data

- It implements the main loop of SHA-256, updating the hash state

- The function uses the logical functions and constants defined earlier

4. sha256_init function:

- Initializes the SHA256_CTX structure with the initial hash values (defined by the SHA-256 standard)

5. sha256_update function:

- Processes input data in chunks

- It fills the data buffer, and when it reaches 64 bytes, it calls sha256_transform

- This allows for processing of arbitrary-length input

6. sha256_final function:

- Finalizes the hash computation

- It pads the remaining data according to the SHA-256 specification

- Processes any remaining data

- Converts the final state to a 256-bit (32-byte) hash value

7. main function:

- Demonstrates the usage of all three hash functions (djb2, FNV-1a, and SHA-256)
- For SHA-256, it initializes the context, updates it with the input data, finalizes the hash, and prints the result

This implementation provides a complete, working example of the SHA-256 algorithm. It's important to note that while this
implementation is correct and functional, it may not be optimized for performance or hardened against side-channel attacks. In a
production environment, it's generally recommended to use well-vetted cryptographic libraries.

The SHA-256 algorithm is significantly more complex than djb2 or FNV-1a, reflecting its design as a cryptographic hash function. It provides
strong collision resistance and one-way properties, making it suitable for security-critical applications such as digital signatures, integrity
verification, and password hashing (when combined with appropriate key derivation functions and salting).

You might also like