package salsa20

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file salsa20.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
module Cs = Cstruct

type t = {
  mutable state: Cs.t;
  mutable buffer: Cs.t;
  hash: Cs.t -> Cs.t;
}

let expand key nonce =
  if Cs.length nonce <> 8 then invalid_arg "nonce must be 8 byte long"
  else
    let (s, k0, k1) = match Cs.length key with
        32 -> let (k0, k1) = Cs.split key 16 in ("expand 32-byte k", k0, k1)
      | 16 -> ("expand 16-byte k", key, key)
      | _ -> invalid_arg "key must be either 32 (recommended) or 16 byte long)" in
    let state = Cs.create 64 in
    Cs.blit_from_string s 0 state 0 4;
    Cs.blit k0 0 state 4 16;
    Cs.blit_from_string s 4 state 20 4;
    Cs.blit nonce 0 state 24 8;
    Cs.LE.set_uint64 state 32 Int64.zero;
    Cs.blit_from_string s 8 state 40 4;
    Cs.blit k1 0 state 44 16;
    Cs.blit_from_string s 12 state 60 4;
    state

let create ?(hash=Salsa20_core.salsa20_20_core) key nonce =
  let state = expand key nonce in
  let buffer = Cs.create 0 in
  {state; buffer; hash}

let hash state =
  state.buffer <- state.hash state.state;
  let nonce = Int32.add (Cs.LE.get_uint32 state.state 32) Int32.one in
  Cs.LE.set_uint32 state.state 32 nonce;
  if nonce = Int32.zero then
    let nonce = Int32.add (Cs.LE.get_uint32 state.state 36) Int32.one in
    Cs.LE.set_uint32 state.state 36 nonce

let encrypt input state =
  let l = Cs.length input in
  let output = Cs.create l in
  let i = ref 0 in
  while !i < l do
    if Cs.length state.buffer = 0 then hash state;
    let count = min (Cs.length state.buffer) (l - !i) in
    let buffer = Cs.create count in
    Cs.blit input !i buffer 0 count;
    Mirage_crypto.Uncommon.Cs.xor_into state.buffer buffer count;
    Cs.blit buffer 0 output !i count;
    i := !i + count;
    state.buffer <- Cs.shift state.buffer count
  done;
  output

let decrypt = encrypt
OCaml

Innovation. Community. Security.