#include #include #include typedef union { unsigned char uc[32]; uint64_t u64[4]; } yescrypt_binary_t; typedef enum { ENC = 1, DEC = -1 } encrypt_dir_t; static void encrypt(yescrypt_binary_t *data, const yescrypt_binary_t *key, encrypt_dir_t dir) { size_t half = 0; uint8_t round = 0, target = 6; /* 7 rounds */ if (dir == DEC) { round = target; target = 0; } do { yescrypt_binary_t f; SHA256_CTX ctx; SHA256_Init(&ctx); SHA256_Update(&ctx, &data->u64[half], 16); SHA256_Update(&ctx, key, sizeof(*key)); SHA256_Update(&ctx, &round, 1); SHA256_Final(f.uc, &ctx); half ^= 2; data->u64[half] ^= f.u64[0]; data->u64[half + 1] ^= f.u64[1]; if (round == target) break; round += dir; } while (1); /* zeroize f and ctx here */ } static void print(yescrypt_binary_t *data) { printf("%" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", data->u64[0], data->u64[1], data->u64[2], data->u64[3]); } static const yescrypt_binary_t key = {.uc={'k', 'e', 'y'}}; int main(void) { yescrypt_binary_t data = {.u64={1001, 2002, 3003, 4004}}; encrypt(&data, &key, ENC); print(&data); encrypt(&data, &key, DEC); print(&data); return 0; }