summaryrefslogtreecommitdiff
path: root/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h
blob: ac78e5bb1e9fa992200b1892b1d8cc65060191e6 (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
94
95
96
97
98
99
100
101
102
103

#ifndef blake2b_compress_sse41_H
#define blake2b_compress_sse41_H

#define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p))
#define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r)

#define _mm_roti_epi64(x, c)                                         \
    (-(c) == 32)                                                     \
        ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1))            \
        : (-(c) == 24)                                               \
              ? _mm_shuffle_epi8((x), r24)                           \
              : (-(c) == 16)                                         \
                    ? _mm_shuffle_epi8((x), r16)                     \
                    : (-(c) == 63)                                   \
                          ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
                                          _mm_add_epi64((x), (x)))   \
                          : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
                                          _mm_slli_epi64((x), 64 - (-(c))))

#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \
    row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l);                \
    row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h);                \
                                                                           \
    row4l = _mm_xor_si128(row4l, row1l);                                   \
    row4h = _mm_xor_si128(row4h, row1h);                                   \
                                                                           \
    row4l = _mm_roti_epi64(row4l, -32);                                    \
    row4h = _mm_roti_epi64(row4h, -32);                                    \
                                                                           \
    row3l = _mm_add_epi64(row3l, row4l);                                   \
    row3h = _mm_add_epi64(row3h, row4h);                                   \
                                                                           \
    row2l = _mm_xor_si128(row2l, row3l);                                   \
    row2h = _mm_xor_si128(row2h, row3h);                                   \
                                                                           \
    row2l = _mm_roti_epi64(row2l, -24);                                    \
    row2h = _mm_roti_epi64(row2h, -24);

#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \
    row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l);                \
    row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h);                \
                                                                           \
    row4l = _mm_xor_si128(row4l, row1l);                                   \
    row4h = _mm_xor_si128(row4h, row1h);                                   \
                                                                           \
    row4l = _mm_roti_epi64(row4l, -16);                                    \
    row4h = _mm_roti_epi64(row4h, -16);                                    \
                                                                           \
    row3l = _mm_add_epi64(row3l, row4l);                                   \
    row3h = _mm_add_epi64(row3h, row4h);                                   \
                                                                           \
    row2l = _mm_xor_si128(row2l, row3l);                                   \
    row2h = _mm_xor_si128(row2h, row3h);                                   \
                                                                           \
    row2l = _mm_roti_epi64(row2l, -63);                                    \
    row2h = _mm_roti_epi64(row2h, -63);

#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
    t0    = _mm_alignr_epi8(row2h, row2l, 8);                               \
    t1    = _mm_alignr_epi8(row2l, row2h, 8);                               \
    row2l = t0;                                                             \
    row2h = t1;                                                             \
                                                                            \
    t0    = row3l;                                                          \
    row3l = row3h;                                                          \
    row3h = t0;                                                             \
                                                                            \
    t0    = _mm_alignr_epi8(row4h, row4l, 8);                               \
    t1    = _mm_alignr_epi8(row4l, row4h, 8);                               \
    row4l = t1;                                                             \
    row4h = t0;

#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
    t0    = _mm_alignr_epi8(row2l, row2h, 8);                                 \
    t1    = _mm_alignr_epi8(row2h, row2l, 8);                                 \
    row2l = t0;                                                               \
    row2h = t1;                                                               \
                                                                              \
    t0    = row3l;                                                            \
    row3l = row3h;                                                            \
    row3h = t0;                                                               \
                                                                              \
    t0    = _mm_alignr_epi8(row4l, row4h, 8);                                 \
    t1    = _mm_alignr_epi8(row4h, row4l, 8);                                 \
    row4l = t1;                                                               \
    row4h = t0;

#include "blake2b-load-sse41.h"

#define ROUND(r)                                                         \
    LOAD_MSG_##r##_1(b0, b1);                                            \
    G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1);  \
    LOAD_MSG_##r##_2(b0, b1);                                            \
    G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1);  \
    DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
    LOAD_MSG_##r##_3(b0, b1);                                            \
    G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1);  \
    LOAD_MSG_##r##_4(b0, b1);                                            \
    G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1);  \
    UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);

#endif