upstream: https://github.com/mirage/mirage-crypto
at main 55 lines 1.8 kB view raw
1/* Based on https://github.com/abeaumont/ocaml-chacha.git */ 2 3#include "crypto.h" 4 5extern void mc_chacha_core_generic(int count, const uint32_t *src, uint32_t *dst); 6 7#ifdef __mc_ACCELERATE__ 8 9static inline void mc_chacha_quarterround(uint32_t *x, int a, int b, int c, int d) { 10 x[a] += x[b]; x[d] = rol32(x[d] ^ x[a], 16); 11 x[c] += x[d]; x[b] = rol32(x[b] ^ x[c], 12); 12 x[a] += x[b]; x[d] = rol32(x[d] ^ x[a], 8); 13 x[c] += x[d]; x[b] = rol32(x[b] ^ x[c], 7); 14} 15 16static void mc_chacha_core(int count, const uint32_t *src, uint32_t *dst) { 17 uint32_t x[16]; 18 cpu_to_le32_array(x, src, 16); 19 for (int i = 0; i < count; i++) { 20 mc_chacha_quarterround(x, 0, 4, 8, 12); 21 mc_chacha_quarterround(x, 1, 5, 9, 13); 22 mc_chacha_quarterround(x, 2, 6, 10, 14); 23 mc_chacha_quarterround(x, 3, 7, 11, 15); 24 25 mc_chacha_quarterround(x, 0, 5, 10, 15); 26 mc_chacha_quarterround(x, 1, 6, 11, 12); 27 mc_chacha_quarterround(x, 2, 7, 8, 13); 28 mc_chacha_quarterround(x, 3, 4, 9, 14); 29 } 30 for (int i = 0; i < 16; i++) { 31 uint32_t xi = x[i]; 32 uint32_t hj = cpu_to_le32(src[i]); 33 dst[i] = le32_to_cpu(xi + hj); 34 } 35} 36 37CAMLprim value 38mc_chacha_round(value count, value src, value dst, value off) 39{ 40 _mc_switch_accel(ssse3, 41 mc_chacha_core_generic(Int_val(count), (const uint32_t *)(String_val(src)), (uint32_t *)(Bytes_val(dst) + Long_val(off))), 42 mc_chacha_core(Int_val(count), (const uint32_t *)(String_val(src)), (uint32_t *)(Bytes_val(dst) + Long_val(off)))); 43 return Val_unit; 44} 45 46#else //#ifdef __mc_ACCELERATE__ 47 48CAMLprim value 49mc_chacha_round(value count, value src, value dst, value off) 50{ 51 mc_chacha_core_generic(Int_val(count), (const uint32_t *)(String_val(src)), (uint32_t *)(Bytes_val(dst) + Long_val(off))); 52 return Val_unit; 53} 54 55#endif