1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 /* The implementation is based on:
5  * "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
6  * and salsa20-ref.c version 20051118
7  * Public domain from D. J. Bernstein
8  */
9 
10 #include "tomcrypt_private.h"
11 
12 #ifdef LTC_SALSA20
13 
14 static const char * const sigma = "expand 32-byte k";
15 static const char * const tau   = "expand 16-byte k";
16 
17 /**
18    Initialize an Salsa20 context (only the key)
19    @param st        [out] The destination of the Salsa20 state
20    @param key       The secret key
21    @param keylen    The length of the secret key (octets)
22    @param rounds    Number of rounds (e.g. 20 for Salsa20)
23    @return CRYPT_OK if successful
24 */
salsa20_setup(salsa20_state * st,const unsigned char * key,unsigned long keylen,int rounds)25 int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, int rounds)
26 {
27    const char *constants;
28 
29    LTC_ARGCHK(st  != NULL);
30    LTC_ARGCHK(key != NULL);
31    LTC_ARGCHK(keylen == 32 || keylen == 16);
32 
33    if (rounds == 0) rounds = 20;
34    LTC_ARGCHK(rounds % 2 == 0); /* number of rounds must be evenly divisible by 2 */
35 
36    LOAD32L(st->input[1],  key + 0);
37    LOAD32L(st->input[2],  key + 4);
38    LOAD32L(st->input[3],  key + 8);
39    LOAD32L(st->input[4],  key + 12);
40    if (keylen == 32) { /* 256bit */
41       key += 16;
42       constants = sigma;
43    } else { /* 128bit */
44       constants = tau;
45    }
46    LOAD32L(st->input[11], key + 0);
47    LOAD32L(st->input[12], key + 4);
48    LOAD32L(st->input[13], key + 8);
49    LOAD32L(st->input[14], key + 12);
50    LOAD32L(st->input[ 0],  constants + 0);
51    LOAD32L(st->input[ 5],  constants + 4);
52    LOAD32L(st->input[10],  constants + 8);
53    LOAD32L(st->input[15],  constants + 12);
54    st->rounds = rounds;     /* default is 20 for salsa20 */
55    st->ivlen = 0;           /* will be set later by salsa20_ivctr(32|64) */
56    return CRYPT_OK;
57 }
58 
59 #endif
60