summaryrefslogtreecommitdiff
path: root/libs/libsodium/src/crypto_core/hchacha20/core_hchacha20.c
blob: 84d3dc61b566b5d2e2f92ca000c409ab5b864592 (plain)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

#include <stdint.h>
#include <stdlib.h>

#include "crypto_core_hchacha20.h"
#include "private/common.h"

#define QUARTERROUND(A, B, C, D)     \
  do {                               \
      A += B; D = ROTL32(D ^ A, 16); \
      C += D; B = ROTL32(B ^ C, 12); \
      A += B; D = ROTL32(D ^ A,  8); \
      C += D; B = ROTL32(B ^ C,  7); \
  } while(0)

int
crypto_core_hchacha20(unsigned char *out, const unsigned char *in,
                      const unsigned char *k, const unsigned char *c)
{
    int      i;
    uint32_t x0, x1, x2, x3, x4, x5, x6, x7;
    uint32_t x8, x9, x10, x11, x12, x13, x14, x15;

    if (c == NULL) {
        x0 = 0x61707865;
        x1 = 0x3320646e;
        x2 = 0x79622d32;
        x3 = 0x6b206574;
    } else {
        x0 = LOAD32_LE(c +  0);
        x1 = LOAD32_LE(c +  4);
        x2 = LOAD32_LE(c +  8);
        x3 = LOAD32_LE(c + 12);
    }
    x4  = LOAD32_LE(k +  0);
    x5  = LOAD32_LE(k +  4);
    x6  = LOAD32_LE(k +  8);
    x7  = LOAD32_LE(k + 12);
    x8  = LOAD32_LE(k + 16);
    x9  = LOAD32_LE(k + 20);
    x10 = LOAD32_LE(k + 24);
    x11 = LOAD32_LE(k + 28);
    x12 = LOAD32_LE(in +  0);
    x13 = LOAD32_LE(in +  4);
    x14 = LOAD32_LE(in +  8);
    x15 = LOAD32_LE(in + 12);

    for (i = 0; i < 10; i++) {
        QUARTERROUND(x0, x4,  x8, x12);
        QUARTERROUND(x1, x5,  x9, x13);
        QUARTERROUND(x2, x6, x10, x14);
        QUARTERROUND(x3, x7, x11, x15);
        QUARTERROUND(x0, x5, x10, x15);
        QUARTERROUND(x1, x6, x11, x12);
        QUARTERROUND(x2, x7,  x8, x13);
        QUARTERROUND(x3, x4,  x9, x14);
    }

    STORE32_LE(out +  0, x0);
    STORE32_LE(out +  4, x1);
    STORE32_LE(out +  8, x2);
    STORE32_LE(out + 12, x3);
    STORE32_LE(out + 16, x12);
    STORE32_LE(out + 20, x13);
    STORE32_LE(out + 24, x14);
    STORE32_LE(out + 28, x15);

    return 0;
}

size_t
crypto_core_hchacha20_outputbytes(void)
{
    return crypto_core_hchacha20_OUTPUTBYTES;
}

size_t
crypto_core_hchacha20_inputbytes(void)
{
    return crypto_core_hchacha20_INPUTBYTES;
}

size_t
crypto_core_hchacha20_keybytes(void)
{
    return crypto_core_hchacha20_KEYBYTES;
}

size_t
crypto_core_hchacha20_constbytes(void)
{
    return crypto_core_hchacha20_CONSTBYTES;
}