1 if (bytes > 0) {
2     __m128i diag0 = _mm_loadu_si128((__m128i *) (x + 0));
3     __m128i diag1 = _mm_loadu_si128((__m128i *) (x + 4));
4     __m128i diag2 = _mm_loadu_si128((__m128i *) (x + 8));
5     __m128i diag3 = _mm_loadu_si128((__m128i *) (x + 12));
6     __m128i a0, a1, a2, a3, a4, a5, a6, a7;
7     __m128i b0, b1, b2, b3, b4, b5, b6, b7;
8     uint8_t partialblock[64];
9 
10     unsigned int i;
11 
12     a0 = diag1;
13     for (i = 0; i < ROUNDS; i += 4) {
14         a0    = _mm_add_epi32(a0, diag0);
15         a1    = diag0;
16         b0    = a0;
17         a0    = _mm_slli_epi32(a0, 7);
18         b0    = _mm_srli_epi32(b0, 25);
19         diag3 = _mm_xor_si128(diag3, a0);
20 
21         diag3 = _mm_xor_si128(diag3, b0);
22 
23         a1    = _mm_add_epi32(a1, diag3);
24         a2    = diag3;
25         b1    = a1;
26         a1    = _mm_slli_epi32(a1, 9);
27         b1    = _mm_srli_epi32(b1, 23);
28         diag2 = _mm_xor_si128(diag2, a1);
29         diag3 = _mm_shuffle_epi32(diag3, 0x93);
30         diag2 = _mm_xor_si128(diag2, b1);
31 
32         a2    = _mm_add_epi32(a2, diag2);
33         a3    = diag2;
34         b2    = a2;
35         a2    = _mm_slli_epi32(a2, 13);
36         b2    = _mm_srli_epi32(b2, 19);
37         diag1 = _mm_xor_si128(diag1, a2);
38         diag2 = _mm_shuffle_epi32(diag2, 0x4e);
39         diag1 = _mm_xor_si128(diag1, b2);
40 
41         a3    = _mm_add_epi32(a3, diag1);
42         a4    = diag3;
43         b3    = a3;
44         a3    = _mm_slli_epi32(a3, 18);
45         b3    = _mm_srli_epi32(b3, 14);
46         diag0 = _mm_xor_si128(diag0, a3);
47         diag1 = _mm_shuffle_epi32(diag1, 0x39);
48         diag0 = _mm_xor_si128(diag0, b3);
49 
50         a4    = _mm_add_epi32(a4, diag0);
51         a5    = diag0;
52         b4    = a4;
53         a4    = _mm_slli_epi32(a4, 7);
54         b4    = _mm_srli_epi32(b4, 25);
55         diag1 = _mm_xor_si128(diag1, a4);
56 
57         diag1 = _mm_xor_si128(diag1, b4);
58 
59         a5    = _mm_add_epi32(a5, diag1);
60         a6    = diag1;
61         b5    = a5;
62         a5    = _mm_slli_epi32(a5, 9);
63         b5    = _mm_srli_epi32(b5, 23);
64         diag2 = _mm_xor_si128(diag2, a5);
65         diag1 = _mm_shuffle_epi32(diag1, 0x93);
66         diag2 = _mm_xor_si128(diag2, b5);
67 
68         a6    = _mm_add_epi32(a6, diag2);
69         a7    = diag2;
70         b6    = a6;
71         a6    = _mm_slli_epi32(a6, 13);
72         b6    = _mm_srli_epi32(b6, 19);
73         diag3 = _mm_xor_si128(diag3, a6);
74         diag2 = _mm_shuffle_epi32(diag2, 0x4e);
75         diag3 = _mm_xor_si128(diag3, b6);
76 
77         a7    = _mm_add_epi32(a7, diag3);
78         a0    = diag1;
79         b7    = a7;
80         a7    = _mm_slli_epi32(a7, 18);
81         b7    = _mm_srli_epi32(b7, 14);
82         diag0 = _mm_xor_si128(diag0, a7);
83         diag3 = _mm_shuffle_epi32(diag3, 0x39);
84         diag0 = _mm_xor_si128(diag0, b7);
85 
86         a0    = _mm_add_epi32(a0, diag0);
87         a1    = diag0;
88         b0    = a0;
89         a0    = _mm_slli_epi32(a0, 7);
90         b0    = _mm_srli_epi32(b0, 25);
91         diag3 = _mm_xor_si128(diag3, a0);
92 
93         diag3 = _mm_xor_si128(diag3, b0);
94 
95         a1    = _mm_add_epi32(a1, diag3);
96         a2    = diag3;
97         b1    = a1;
98         a1    = _mm_slli_epi32(a1, 9);
99         b1    = _mm_srli_epi32(b1, 23);
100         diag2 = _mm_xor_si128(diag2, a1);
101         diag3 = _mm_shuffle_epi32(diag3, 0x93);
102         diag2 = _mm_xor_si128(diag2, b1);
103 
104         a2    = _mm_add_epi32(a2, diag2);
105         a3    = diag2;
106         b2    = a2;
107         a2    = _mm_slli_epi32(a2, 13);
108         b2    = _mm_srli_epi32(b2, 19);
109         diag1 = _mm_xor_si128(diag1, a2);
110         diag2 = _mm_shuffle_epi32(diag2, 0x4e);
111         diag1 = _mm_xor_si128(diag1, b2);
112 
113         a3    = _mm_add_epi32(a3, diag1);
114         a4    = diag3;
115         b3    = a3;
116         a3    = _mm_slli_epi32(a3, 18);
117         b3    = _mm_srli_epi32(b3, 14);
118         diag0 = _mm_xor_si128(diag0, a3);
119         diag1 = _mm_shuffle_epi32(diag1, 0x39);
120         diag0 = _mm_xor_si128(diag0, b3);
121 
122         a4    = _mm_add_epi32(a4, diag0);
123         a5    = diag0;
124         b4    = a4;
125         a4    = _mm_slli_epi32(a4, 7);
126         b4    = _mm_srli_epi32(b4, 25);
127         diag1 = _mm_xor_si128(diag1, a4);
128 
129         diag1 = _mm_xor_si128(diag1, b4);
130 
131         a5    = _mm_add_epi32(a5, diag1);
132         a6    = diag1;
133         b5    = a5;
134         a5    = _mm_slli_epi32(a5, 9);
135         b5    = _mm_srli_epi32(b5, 23);
136         diag2 = _mm_xor_si128(diag2, a5);
137         diag1 = _mm_shuffle_epi32(diag1, 0x93);
138         diag2 = _mm_xor_si128(diag2, b5);
139 
140         a6    = _mm_add_epi32(a6, diag2);
141         a7    = diag2;
142         b6    = a6;
143         a6    = _mm_slli_epi32(a6, 13);
144         b6    = _mm_srli_epi32(b6, 19);
145         diag3 = _mm_xor_si128(diag3, a6);
146         diag2 = _mm_shuffle_epi32(diag2, 0x4e);
147         diag3 = _mm_xor_si128(diag3, b6);
148 
149         a7    = _mm_add_epi32(a7, diag3);
150         a0    = diag1;
151         b7    = a7;
152         a7    = _mm_slli_epi32(a7, 18);
153         b7    = _mm_srli_epi32(b7, 14);
154         diag0 = _mm_xor_si128(diag0, a7);
155         diag3 = _mm_shuffle_epi32(diag3, 0x39);
156         diag0 = _mm_xor_si128(diag0, b7);
157     }
158 
159     diag0 = _mm_add_epi32(diag0, _mm_loadu_si128((__m128i *) (x + 0)));
160     diag1 = _mm_add_epi32(diag1, _mm_loadu_si128((__m128i *) (x + 4)));
161     diag2 = _mm_add_epi32(diag2, _mm_loadu_si128((__m128i *) (x + 8)));
162     diag3 = _mm_add_epi32(diag3, _mm_loadu_si128((__m128i *) (x + 12)));
163 
164 #define ONEQUAD_SHUFFLE(A, B, C, D)                      \
165     do {                                                 \
166         uint32_t in##A = _mm_cvtsi128_si32(diag0);       \
167         uint32_t in##B = _mm_cvtsi128_si32(diag1);       \
168         uint32_t in##C = _mm_cvtsi128_si32(diag2);       \
169         uint32_t in##D = _mm_cvtsi128_si32(diag3);       \
170         diag0          = _mm_shuffle_epi32(diag0, 0x39); \
171         diag1          = _mm_shuffle_epi32(diag1, 0x39); \
172         diag2          = _mm_shuffle_epi32(diag2, 0x39); \
173         diag3          = _mm_shuffle_epi32(diag3, 0x39); \
174         *(uint32_t *) (partialblock + (A * 4)) = in##A;  \
175         *(uint32_t *) (partialblock + (B * 4)) = in##B;  \
176         *(uint32_t *) (partialblock + (C * 4)) = in##C;  \
177         *(uint32_t *) (partialblock + (D * 4)) = in##D;  \
178     } while (0)
179 
180 #define ONEQUAD(A, B, C, D) ONEQUAD_SHUFFLE(A, B, C, D)
181 
182     ONEQUAD(0, 12, 8, 4);
183     ONEQUAD(5, 1, 13, 9);
184     ONEQUAD(10, 6, 2, 14);
185     ONEQUAD(15, 11, 7, 3);
186 
187 #undef ONEQUAD
188 #undef ONEQUAD_SHUFFLE
189 
190     for (i = 0; i < bytes; i++) {
191         c[i] = m[i] ^ partialblock[i];
192     }
193 
194     sodium_memzero(partialblock, sizeof partialblock);
195 }
196