Botan 3.13.0
Crypto and TLS for C&
salsa20_avx2.cpp
Go to the documentation of this file.
1/*
2* (C) 2026 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/internal/salsa20.h>
8
9#include <botan/assert.h>
10#include <botan/internal/simd_avx2.h>
11
12namespace Botan {
13
14//static
15void BOTAN_FN_ISA_AVX2 Salsa20::salsa20_avx2_x8(uint8_t output[64 * 8], uint32_t state[16], size_t rounds) {
17
18 BOTAN_ASSERT(rounds % 2 == 0, "Valid rounds");
19
20 const SIMD_8x32 CTR_LO = SIMD_8x32::splat(state[8]) + SIMD_8x32(0, 1, 2, 3, 4, 5, 6, 7);
21 // Carry into the high counter word for lanes whose low word wrapped
22 const SIMD_8x32 CTR_HI = SIMD_8x32::splat(state[9]) - CTR_LO.unsigned_lt(SIMD_8x32::splat(state[8]));
23
24 SIMD_8x32 R00 = SIMD_8x32::splat(state[0]);
25 SIMD_8x32 R01 = SIMD_8x32::splat(state[1]);
26 SIMD_8x32 R02 = SIMD_8x32::splat(state[2]);
27 SIMD_8x32 R03 = SIMD_8x32::splat(state[3]);
28 SIMD_8x32 R04 = SIMD_8x32::splat(state[4]);
29 SIMD_8x32 R05 = SIMD_8x32::splat(state[5]);
30 SIMD_8x32 R06 = SIMD_8x32::splat(state[6]);
31 SIMD_8x32 R07 = SIMD_8x32::splat(state[7]);
32 SIMD_8x32 R08 = CTR_LO;
33 SIMD_8x32 R09 = CTR_HI;
34 SIMD_8x32 R10 = SIMD_8x32::splat(state[10]);
35 SIMD_8x32 R11 = SIMD_8x32::splat(state[11]);
36 SIMD_8x32 R12 = SIMD_8x32::splat(state[12]);
37 SIMD_8x32 R13 = SIMD_8x32::splat(state[13]);
38 SIMD_8x32 R14 = SIMD_8x32::splat(state[14]);
39 SIMD_8x32 R15 = SIMD_8x32::splat(state[15]);
40
41 for(size_t r = 0; r != rounds / 2; ++r) {
42 R04 ^= (R00 + R12).rotl<7>();
43 R09 ^= (R05 + R01).rotl<7>();
44 R14 ^= (R10 + R06).rotl<7>();
45 R03 ^= (R15 + R11).rotl<7>();
46
47 R08 ^= (R04 + R00).rotl<9>();
48 R13 ^= (R09 + R05).rotl<9>();
49 R02 ^= (R14 + R10).rotl<9>();
50 R07 ^= (R03 + R15).rotl<9>();
51
52 R12 ^= (R08 + R04).rotl<13>();
53 R01 ^= (R13 + R09).rotl<13>();
54 R06 ^= (R02 + R14).rotl<13>();
55 R11 ^= (R07 + R03).rotl<13>();
56
57 R00 ^= (R12 + R08).rotl<18>();
58 R05 ^= (R01 + R13).rotl<18>();
59 R10 ^= (R06 + R02).rotl<18>();
60 R15 ^= (R11 + R07).rotl<18>();
61
62 R01 ^= (R00 + R03).rotl<7>();
63 R06 ^= (R05 + R04).rotl<7>();
64 R11 ^= (R10 + R09).rotl<7>();
65 R12 ^= (R15 + R14).rotl<7>();
66
67 R02 ^= (R01 + R00).rotl<9>();
68 R07 ^= (R06 + R05).rotl<9>();
69 R08 ^= (R11 + R10).rotl<9>();
70 R13 ^= (R12 + R15).rotl<9>();
71
72 R03 ^= (R02 + R01).rotl<13>();
73 R04 ^= (R07 + R06).rotl<13>();
74 R09 ^= (R08 + R11).rotl<13>();
75 R14 ^= (R13 + R12).rotl<13>();
76
77 R00 ^= (R03 + R02).rotl<18>();
78 R05 ^= (R04 + R07).rotl<18>();
79 R10 ^= (R09 + R08).rotl<18>();
80 R15 ^= (R14 + R13).rotl<18>();
81 }
82
83 R00 += SIMD_8x32::splat(state[0]);
84 R01 += SIMD_8x32::splat(state[1]);
85 R02 += SIMD_8x32::splat(state[2]);
86 R03 += SIMD_8x32::splat(state[3]);
87 R04 += SIMD_8x32::splat(state[4]);
88 R05 += SIMD_8x32::splat(state[5]);
89 R06 += SIMD_8x32::splat(state[6]);
90 R07 += SIMD_8x32::splat(state[7]);
91 R08 += CTR_LO;
92 R09 += CTR_HI;
93 R10 += SIMD_8x32::splat(state[10]);
94 R11 += SIMD_8x32::splat(state[11]);
95 R12 += SIMD_8x32::splat(state[12]);
96 R13 += SIMD_8x32::splat(state[13]);
97 R14 += SIMD_8x32::splat(state[14]);
98 R15 += SIMD_8x32::splat(state[15]);
99
100 SIMD_8x32::transpose(R00, R01, R02, R03, R04, R05, R06, R07);
101 SIMD_8x32::transpose(R08, R09, R10, R11, R12, R13, R14, R15);
102
103 R00.store_le(output);
104 R08.store_le(output + 32 * 1);
105 R01.store_le(output + 32 * 2);
106 R09.store_le(output + 32 * 3);
107 R02.store_le(output + 32 * 4);
108 R10.store_le(output + 32 * 5);
109 R03.store_le(output + 32 * 6);
110 R11.store_le(output + 32 * 7);
111 R04.store_le(output + 32 * 8);
112 R12.store_le(output + 32 * 9);
113 R05.store_le(output + 32 * 10);
114 R13.store_le(output + 32 * 11);
115 R06.store_le(output + 32 * 12);
116 R14.store_le(output + 32 * 13);
117 R07.store_le(output + 32 * 14);
118 R15.store_le(output + 32 * 15);
119
121
122 state[8] += 8;
123 if(state[8] < 8) {
124 state[9]++;
125 }
126}
127} // namespace Botan
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
static BOTAN_FN_ISA_AVX2 void reset_registers() noexcept
Definition simd_avx2.h:346
static BOTAN_FN_ISA_AVX2 void transpose(SIMD_8x32 &B0, SIMD_8x32 &B1, SIMD_8x32 &B2, SIMD_8x32 &B3) noexcept
Definition simd_avx2.h:264
static BOTAN_FN_ISA_AVX2 void zero_registers() noexcept
Definition simd_avx2.h:349
static BOTAN_FN_ISA_AVX2 SIMD_8x32 splat(uint32_t B) noexcept
Definition simd_avx2.h:58
SIMD_8x32 BOTAN_FN_ISA_AVX2 unsigned_lt(const SIMD_8x32 &other) const noexcept
Definition simd_avx2.h:317
BOTAN_FORCE_INLINE constexpr T rotl(T input)
Definition rotate.h:23