Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cryptash-Research

Cross-implementation research for Cryptash -- hash-based encrypt/decrypt using a single hash function as the only cryptographic primitive.

What is Cryptash

Cryptash is an encryption scheme built entirely on a hash function. No block ciphers, no key exchange protocols, no external crypto libraries. Any cryptographic hash function can serve as the foundation -- these implementations use SHA-256.

Algorithm

Given a hash function H, password, data, and parameters ivsz and macsz:

Encrypt:

  1. Generate ivsz bytes of iv_outer and ivsz bytes of iv_inner from random
  2. Key1 = H( iv_outer || password )
  3. MAC = H( iv_inner || data || Key1 ), truncated to macsz bytes
  4. prefix = iv_outer || MAC
  5. Encrypt iv_inner || data using CBC mode with prefix and Key1 as initial parameters:
    • K[0] = H( prefix || Key1 )
    • ct[i] = block[i] XOR K[i]
    • K[i+1] = H( ct[i] || K[i] )
  6. Output: prefix || ciphertext

Decrypt:

  1. Extract iv_outer and MAC from prefix
  2. Key1 = H( iv_outer || password )
  3. Decrypt ciphertext using CBC mode with prefix and Key1
  4. Verify MAC against H( decrypted || Key1 ), truncated to macsz bytes
  5. Strip iv_inner, return data

Properties:

  • Outer IV is public, inner IV is encrypted -- effective IV space is ivsz * 2
  • MAC depends on data and Key1, then feeds back into keystream derivation
  • Each CBC block key depends on the previous ciphertext block
  • Minimum 3 hash calls per operation

Implementations

Language Path Hash source Random source
C C/ pure (sha256_pure.h) /dev/urandom (lazy CSPRNG)
JavaScript js/ pure (built-in) crypto.getRandomValues
Go go/ crypto/sha256 (stdlib) crypto/rand (stdlib)
PHP deemru/Cryptash hash() (stdlib) random_bytes() (stdlib)

C and JS implementations have zero external dependencies.

Tests

All implementations are validated against shared test vector files and self-tests covering roundtrip, uniqueness, tamper detection, wrong password, truncation, and determinism.

# C
cd C && make test

# JavaScript
cd js && node test_sha256.mjs && node test_vectors.mjs && node selftest.mjs

# Go
cd go && go test ./...

# PHP (vector generation, requires deemru/Cryptash submodule)
cd php && php gen_vectors.php

Benchmarks

iv = 16, mac = 16, typical single-threaded performance:

Language Plaintext Encrypt Decrypt
C 16 B 343 Kops (2.9 us) 674 Kops (1.5 us)
C 200 B 122 Kops (8.2 us) 171 Kops (5.9 us)
C 1000 B 34 Kops (30 us) 41 Kops (25 us)
Go 16 B 492 Kops (2.0 us) 566 Kops (1.8 us)
Go 200 B 137 Kops (7.3 us) 143 Kops (7.0 us)
Go 1000 B 33 Kops (30 us) 34 Kops (29 us)
PHP 16 B 233 Kops (4.3 us) 497 Kops (2.0 us)
PHP 200 B 100 Kops (10 us) 134 Kops (7.4 us)
PHP 1000 B 31 Kops (32 us) 32 Kops (31 us)
JS 16 B 96 Kops (10 us) 270 Kops (3.7 us)
JS 200 B 50 Kops (20 us) 79 Kops (13 us)
JS 1000 B 17 Kops (58 us) 20 Kops (50 us)

Security

With iv = 16 and mac = 16 (recommended):

  • IV space: outer IV (16 bytes, public) + inner IV (16 bytes, encrypted) = 256 bits effective randomization
  • MAC brute-force: MAC enters the keystream derivation, creating a fixed-point equation rather than a simple search. Experimental results show Poisson distribution (lambda = 1) for collisions, with ~37% of cases having zero collisions beyond the original
  • Interdependence: all elements (outer IV, inner IV, MAC, keys, ciphertext) are interdependent -- changing any one invalidates all others. Attack on ciphertext reduces to preimage attack on the underlying hash function

Recommended parameters: iv = 16, mac = 16 (48 bytes overhead: outer IV + MAC + inner IV).

References

About

Cryptash cross-implementation research: PHP, JS, C, Go

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages