upstream: github.com/robur-coop/kdf
at main 65 lines 1.8 kB view raw
1#include <stdint.h> 2 3#define CAML_NAME_SPACE 4#include <caml/mlvalues.h> 5#include <caml/bigarray.h> 6 7static inline uint32_t r(uint32_t a, int b) { 8 int rs = 32 - b; 9 return (a << b) | (a >> rs); 10} 11 12static inline uint32_t combine(uint32_t y0, uint32_t y1, uint32_t y2, int shift) { 13 return r(y1 + y2, shift) ^ y0; 14} 15 16static inline void quarterround(uint32_t *x, int y0, int y1, int y2, int y3) { 17 x[y1] = combine(x[y1], x[y0], x[y3], 7); 18 x[y2] = combine(x[y2], x[y1], x[y0], 9); 19 x[y3] = combine(x[y3], x[y2], x[y1], 13); 20 x[y0] = combine(x[y0], x[y3], x[y2], 18); 21} 22 23static inline uint32_t get_u32_le(const uint8_t *input, int offset) { 24 return input[offset] 25 | (input[offset + 1] << 8) 26 | (input[offset + 2] << 16) 27 | (input[offset + 3] << 24); 28} 29 30static inline void set_u32_le(uint8_t *input, int offset, uint32_t value) { 31 input[offset] = (uint8_t) value; 32 input[offset + 1] = (uint8_t) (value >> 8); 33 input[offset + 2] = (uint8_t) (value >> 16); 34 input[offset + 3] = (uint8_t) (value >> 24); 35} 36 37static void salsa_core(int count, const uint8_t *src, uint8_t *dst) { 38 uint32_t x[16]; 39 for (int i = 0; i < 16; i++) { 40 x[i] = get_u32_le(src, i * 4); 41 } 42 for (int i = 0; i < count; i++) { 43 quarterround(x, 0, 4, 8, 12); 44 quarterround(x, 5, 9, 13, 1); 45 quarterround(x, 10, 14, 2, 6); 46 quarterround(x, 15, 3, 7, 11); 47 48 quarterround(x, 0, 1, 2, 3); 49 quarterround(x, 5, 6, 7, 4); 50 quarterround(x, 10, 11, 8, 9); 51 quarterround(x, 15, 12, 13, 14); 52 } 53 for (int i = 0; i < 16; i++) { 54 uint32_t xi = x[i]; 55 uint32_t hj = get_u32_le(src, i * 4); 56 set_u32_le(dst, i * 4, xi + hj); 57 } 58} 59 60CAMLprim value 61caml_salsa_core(value count, value src, value dst) 62{ 63 salsa_core(Int_val(count), (const uint8_t*)(String_val(src)), Bytes_val(dst)); 64 return Val_unit; 65}