Sitemap
Everything is MindGame

Everything is MindGame

Comparing New Age programming Languages, Distributed Systems, Blockchain

Hashes for Integrity

4 min readJun 27, 2025

--

What is Integrity

Ensuring that data or systems remain accurate, consistent, and unaltered by unauthorized entities.

Data Integrity: Data is not modified, deleted, or corrupted, either accidentally or maliciously, during storage, processing, or transmission
System Integrity State of a system (e.g., software or hardware) remains unchanged from its intended configuration unless authorized changes are made

Methods to Achieve Integrity

  1. Access Control: Restrict access to data and systems to authorized users only through authentication and authorization mechanisms
  2. Encryption: Send, save the data after encryption to prevent unauthorized modifications
  3. Hashing

Hashing or Message Digest

Hashing is method to achieve Integrity

What is Hashing?

Transforming String into FIXED-LENGTH string Value. From Hash Message cannot be retrieved back. Hash function should not generate same value for different input strings.
MD5 started producing that and hence considered broken.

Kumar >  | Hash Function |  > random_string

Why to use Hash

For security, password Hash is stored. Whenever someone enters password hashes are compared.

How GPU can crack a Hash?

  • GPUs are particularly effective at performing parallel computations.
    They contain numerous cores that can execute instructions simultaneously, making them well-suited for tasks like hashing, which involve performing the same operation on multiple inputs simultaneously.
  • GPUs can test a large number of password guesses(Brute force) in parallel, making them much faster at trying different combinations.
    But Argon2 hash is GPU resistant.

Hashing Algorithms

SHA1, SHA0(broken)

Published: 1995. Input: 2128 bit. Output Hash(bits): 160

SHA256(not broken)

Published: 2012. Input: 2128 bit. Output Hash(bits): 256

SHA3_512(Keccak)

Published: 2015. Input: 264 bit. Output Hash(bits): 512

MD4,MD5(broken)

Published: 2015. Input: Infinite. Output Hash(bits): 128
MD4 Implementation

1. Take four 32-bit words, initialized to fixed constants.
C1(01 23 45 67), C2:(89 ab cd ef), C3(fe dc ba 98), C4(76 54 32 10)

2. Take 4 Functions
f(x,y,z) = (x & y) | ((~x) & z)
g(x,y,z) = (x & z)| (y & (~z))
h(x,y,z) = x ^ y ^ z
i(x,y,z) = y ^ (x | (~z))

3. Break input into 32-bit words
Input(512 bits) -> |Break into 16 pieces| -> m1 .. m16
if input is not 512 bit pad it

4. Perform 4 or 16 round Operations.
//AM: Addition Modulo
Round-1: F(K2,K3,K4) -> AM -> AM -> |Rotate left bit by s places| -> AM -> K2
/\ /\ /\
C1 m1 C2
Round-2: For m2 and so on..

Argon2

How Argon2 is GPU resistant?
1. Memory Hardness:
Argon2 is a memory-hard hashing algorithm, meaning that it requires a lot of memory to be computed.
Since GPU typically have less memory available compared to CPUs. As a result, even though GPUs can perform computations quickly, they may struggle with the memory requirements of Argon2.

Get Everything is MindGame’s stories in your inbox

Join Medium for free to get updates from this writer.

2. Parallelism resistance:
While GPUs excel at parallel computations, Argon2 is designed to require significant serial computation as well.
This means that even though GPUs can try many password guesses in parallel, they may still be limited by the sequential nature of certain parts of the Argon2 algorithm.

3. Configuration parameters
Argon2 allows for the adjustment of parameters(such as the memory cost, time cost, and parallelism degree)
By appropriately configuring these parameters, it’s possible to tune Argon2 to be less susceptible to GPU-based attacks

Press enter or click to view image in full size

bcrypt(based on Blowfish cipher)

Output: Fixed 60 characters

Go Code to produce bcrypt hash

See everytime different hash is produced even for same password

package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
func main() {
password := []byte("password")
hashedPassword, err := bcrypt.GenerateFromPassword(password, 10)
if err == nil {
fmt.Println(string(hashedPassword))
}
err = bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
if err != nil {
fmt.Println("Password mismatch", err)
} else {
fmt.Println("Password mismatched successfully")
}
}
> go run main.go
$2a$10$CaqDrA3GmB9LkbBuUxuohO1YekAW1h4HeWqhSOY0lYav3OZAragFC
Password mismatched successfully
> go run main.go
$2a$10$Hy1V1itBzEe7c7eINFKADenbFWapCX8DKp6fgMlL9XbdL9Ky2vMx6
Password mismatched successfully
> go run main.go
$2a$10$a89EOl.nq53g2AGA5kBAgertEqSyVZyrcocC..wMTNJnHcYYmjsN.
Password mismatched successfully

Different parts of the hash:
$2a$10$CaqDrA3GmB9LkbBuUxuohO1YekAW1h4HeWqhSOY0lYav3OZAragFC

$2a       $10   $Hy1V1itBzEe7c7eINFKADe  nbFWapCX8DKp6fgMlL9XbdL9Ky2vMx6
│ │ │ │
Algorithm Cost Salt (22 chars) Hash (31 chars)

2a Version of bcrypt

10 Cost factor. This means 2¹⁰ = 1024 iterations. How computationally expensive the hash is

Hy1V1itBzEe7c7eINFKADe (22 Characters) Salt. Randomly generated for each hash

nbFWapCX8DKp6fgMlL9XbdL9Ky2vMx6 (31 characters)Hash. The actual hash of the password

Why different hash is produced every time?
bcrypt automatically generates a new random salt each time you hash a password.
The salt is stored as part of the hash (the first 22 characters after the version/cost info)

How Verification Works?
extracts the version,cost,salt from the stored hash
Hashes the input password using: same version,cost,salt
Compares the newly generated hash with the stored hash

MAC

Examples: CMAC, SHA1-HMAC, MD5-HMAC, UMAC

(Message + Pvt Key) > |Hash function| > MAC

HMAC(Hashed MAC)

More complex way of calculating MAC

secret Key ->(XOR) <- Inner Pad     Secret Key-> (XOR) <- Outer Pad
\/ \/
M1 M2
|M-1| Message | M2 |

--

--

Written by Everything is MindGame

Comparing New Age programming Languages, Distributed Systems, Blockchain