Sha 256
Sha 256
// 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;
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];
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;
}
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);
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);
return 0;
}
- CH, MAJ, EP0, EP1, SIG0, SIG1: These are the six logical functions used in SHA-256
2. SHA256_CTX struct:
- data: Buffer for input data (64 bytes, which is the block size for SHA-256)
3. sha256_transform function:
- 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:
- It fills the data buffer, and when it reaches 64 bytes, it calls sha256_transform
6. sha256_final function:
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).