A fast implementation of the Kuznechik (GOST R 34.12-2015) block cipher in Zig. Kuznechik is a symmetric block cipher with a block size of 128 bits and a key length of 256 bits, standardized as GOST R 34.12-2015.
- Pure Zig implementation
- Optimized using precomputed lookup tables
- Includes both encryption and decryption
- Performance benchmarks
const kuznechik = @import("kuznechik");
// Initialize cipher with 256-bit key
var key = kuznechik.key{
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
};
var cipher = kuznechik.Cipher.init(key);
// Create a 128-bit block
var block = kuznechik.block{
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00,
0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
};
// Encrypt
cipher.encrypt(&block);
// Decrypt
cipher.decrypt(&block);
zig build
To achieve better performance, compile with -Doptimize=ReleaseFast
zig build test
zig build bench
The implementation is optimized using precomputed lookup tables for the S-box, inverse S-box, and linear transformations. Benchmark results on Apple M2:
Running benchmark: Encrypt Benchmark (65535 iterations)
Encrypt Benchmark:
Iterations: 65535
Total time: 5056195 ns
Average time: 77 ns
Min time: 0 ns
Max time: 18375 ns
Running benchmark: Decrypt Benchmark (65535 iterations)
Decrypt Benchmark:
Iterations: 65535
Total time: 5698981 ns
Average time: 86 ns
Min time: 0 ns
Max time: 10167 ns
Kuznechik is a symmetric block cipher that operates on 128-bit blocks using a 256-bit key. The encryption process consists of:
- 10 rounds of transformations
- Key schedule generating 10 round keys
- Each round applies:
- Key addition (XOR)
- Substitution layer (S-box)
- Linear transformation (L)
MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Add fuzzing tests
- Improve performance further
- Add cipher operation modes