/* spritz.h */ /* (C)2015 Marc Alexander Lehmann, all rights reserved */ #include #include /*******************************************************************************/ /* spritz parameters/state type */ enum { spritz_N = 256 }; typedef struct { uint8_t a, i, j, k, z, w; uint8_t S[spritz_N]; } spritz_state; /*******************************************************************************/ /* the spritz primitives */ void spritz_init (spritz_state *s); void spritz_update (spritz_state *s); void spritz_whip (spritz_state *s, uint_fast16_t r); void spritz_crush (spritz_state *s); void spritz_shuffle (spritz_state *s); void spritz_absorb_nibble (spritz_state *s, uint8_t x); void spritz_absorb (spritz_state *s, const void *I, size_t I_len); void spritz_absorb_stop (spritz_state *s); void spritz_absorb_and_stop (spritz_state *s, const void *I, size_t I_len); /* commonly used helper function */ uint8_t spritz_output (spritz_state *s); void spritz_squeeze (spritz_state *s, void *P, size_t P_len); uint8_t spritz_drip (spritz_state *s); /*******************************************************************************/ /* the spritz-xor cipher */ /* no IV is used if IV_len == 0 */ void spritz_xor_init (spritz_state *s, const void *K, size_t K_len, const void *IV, size_t IV_len); /* can be called multiple times/incrementally */ /* can work inplace */ /* works for both encryption and decryption */ void spritz_xor_crypt (spritz_state *s, const void *I, void *O, size_t len); /*******************************************************************************/ /* the spritz hash */ static void spritz_hash_init (spritz_state *s); static void spritz_hash_add (spritz_state *s, const void *M, size_t M_len); /* can be called multiple times/incrementally */ void spritz_hash_finish (spritz_state *s, void *H, size_t H_len); /* must be called at most once at the end */ /*******************************************************************************/ /* the spritz MAC */ void spritz_mac_init (spritz_state *s, const void *K, size_t K_len); static void spritz_mac_add (spritz_state *s, const void *M, size_t M_len); /* can be called multiple times/incrementally */ static void spritz_mac_finish (spritz_state *s, void *H, size_t H_len); /* must be called at most once at the end */ /*******************************************************************************/ /* spritz authenticated encryption */ void spritz_aead_init (spritz_state *s, const void *K, size_t K_len); static void spritz_aead_nonce (spritz_state *s, const void *N, size_t N_len); /* must be called after construction, before associated_data */ static void spritz_aead_associated_data (spritz_state *s, const void *D, size_t D_len); /* must be called after nonce, before crypt */ void spritz_aead_crypt (spritz_state *s, const void *I, void *O, size_t len); /* must be called after associated_data, only once, before finish */ /* works for both encryption and decryption */ static void spritz_aead_finish (spritz_state *s, void *H, size_t H_len); /* must be called at most once at the end */ /*******************************************************************************/ /* the spritz drbg/csprng */ /* constructor takes a seed if S_len != 0, same add spritz_prng_put */ void spritz_prng_init (spritz_state *s, const void *S, size_t S_len); static void spritz_prng_put (spritz_state *s, const void *S, size_t S_len); /* add additional entropy */ static void spritz_prng_get (spritz_state *s, void *R, size_t R_len); /* get random bytes */ /*******************************************************************************/ /* inline functions - some functions are so simple, they are defined inline */ /* the spritz hash inline functions */ static void spritz_hash_init (spritz_state *s) { spritz_init (s); } static void spritz_hash_add (spritz_state *s, const void *M, size_t M_len) { spritz_absorb (s, M, M_len); } /* the spritz MAC inline functions */ static void spritz_mac_add (spritz_state *s, const void *M, size_t M_len) { spritz_hash_add (s, M, M_len); } static void spritz_mac_finish (spritz_state *s, void *H, size_t H_len) { spritz_hash_finish (s, H, H_len); } /* spritz authenticated encryption inline functions */ static void spritz_aead_nonce (spritz_state *s, const void *N, size_t N_len) { spritz_absorb_and_stop (s, N, N_len); } static void spritz_aead_associated_data (spritz_state *s, const void *D, size_t D_len) { spritz_absorb_and_stop (s, D, D_len); } static void spritz_aead_finish (spritz_state *s, void *H, size_t H_len) { spritz_mac_finish (s, H, H_len); } /* the spritz drbg/csprng inline functions */ static void spritz_prng_put (spritz_state *s, const void *S, size_t S_len) { spritz_absorb (s, S, S_len); } /* get random bytes */ static void spritz_prng_get (spritz_state *s, void *R, size_t R_len) { spritz_squeeze (s, R, R_len); }