Botan 3.13.0
Crypto and TLS for C&
salsa20_avx512.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_avx512.h>
11
12namespace Botan {
13
14//static
15void BOTAN_FN_ISA_AVX512 Salsa20::salsa20_avx512_x16(uint8_t output[64 * 16], uint32_t state[16], size_t rounds) {
16 BOTAN_ASSERT(rounds % 2 == 0, "Valid rounds");
17
18 const SIMD_16x32 CTR_LO =
19 SIMD_16x32::splat(state[8]) + SIMD_16x32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
20 // Carry into the high counter word for lanes whose low word wrapped
21 const SIMD_16x32 CTR_HI = SIMD_16x32::splat(state[9]) - CTR_LO.unsigned_lt(SIMD_16x32::splat(state[8]));
22
23 SIMD_16x32 R00 = SIMD_16x32::splat(state[0]);
24 SIMD_16x32 R01 = SIMD_16x32::splat(state[1]);
25 SIMD_16x32 R02 = SIMD_16x32::splat(state[2]);
26 SIMD_16x32 R03 = SIMD_16x32::splat(state[3]);
27 SIMD_16x32 R04 = SIMD_16x32::splat(state[4]);
28 SIMD_16x32 R05 = SIMD_16x32::splat(state[5]);
29 SIMD_16x32 R06 = SIMD_16x32::splat(state[6]);
30 SIMD_16x32 R07 = SIMD_16x32::splat(state[7]);
31 SIMD_16x32 R08 = CTR_LO;
32 SIMD_16x32 R09 = CTR_HI;
33 SIMD_16x32 R10 = SIMD_16x32::splat(state[10]);
34 SIMD_16x32 R11 = SIMD_16x32::splat(state[11]);
35 SIMD_16x32 R12 = SIMD_16x32::splat(state[12]);
36 SIMD_16x32 R13 = SIMD_16x32::splat(state[13]);
37 SIMD_16x32 R14 = SIMD_16x32::splat(state[14]);
38 SIMD_16x32 R15 = SIMD_16x32::splat(state[15]);
39
40 for(size_t r = 0; r != rounds / 2; ++r) {
41 // column round
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 // row round
63 R01 ^= (R00 + R03).rotl<7>();
64 R06 ^= (R05 + R04).rotl<7>();
65 R11 ^= (R10 + R09).rotl<7>();
66 R12 ^= (R15 + R14).rotl<7>();
67
68 R02 ^= (R01 + R00).rotl<9>();
69 R07 ^= (R06 + R05).rotl<9>();
70 R08 ^= (R11 + R10).rotl<9>();
71 R13 ^= (R12 + R15).rotl<9>();
72
73 R03 ^= (R02 + R01).rotl<13>();
74 R04 ^= (R07 + R06).rotl<13>();
75 R09 ^= (R08 + R11).rotl<13>();
76 R14 ^= (R13 + R12).rotl<13>();
77
78 R00 ^= (R03 + R02).rotl<18>();
79 R05 ^= (R04 + R07).rotl<18>();
80 R10 ^= (R09 + R08).rotl<18>();
81 R15 ^= (R14 + R13).rotl<18>();
82 }
83
84 R00 += SIMD_16x32::splat(state[0]);
85 R01 += SIMD_16x32::splat(state[1]);
86 R02 += SIMD_16x32::splat(state[2]);
87 R03 += SIMD_16x32::splat(state[3]);
88 R04 += SIMD_16x32::splat(state[4]);
89 R05 += SIMD_16x32::splat(state[5]);
90 R06 += SIMD_16x32::splat(state[6]);
91 R07 += SIMD_16x32::splat(state[7]);
92 R08 += CTR_LO;
93 R09 += CTR_HI;
94 R10 += SIMD_16x32::splat(state[10]);
95 R11 += SIMD_16x32::splat(state[11]);
96 R12 += SIMD_16x32::splat(state[12]);
97 R13 += SIMD_16x32::splat(state[13]);
98 R14 += SIMD_16x32::splat(state[14]);
99 R15 += SIMD_16x32::splat(state[15]);
100
101 SIMD_16x32::transpose(R00, R01, R02, R03, R04, R05, R06, R07, R08, R09, R10, R11, R12, R13, R14, R15);
102
103 R00.store_le(output);
104 R01.store_le(output + 64 * 1);
105 R02.store_le(output + 64 * 2);
106 R03.store_le(output + 64 * 3);
107 R04.store_le(output + 64 * 4);
108 R05.store_le(output + 64 * 5);
109 R06.store_le(output + 64 * 6);
110 R07.store_le(output + 64 * 7);
111 R08.store_le(output + 64 * 8);
112 R09.store_le(output + 64 * 9);
113 R10.store_le(output + 64 * 10);
114 R11.store_le(output + 64 * 11);
115 R12.store_le(output + 64 * 12);
116 R13.store_le(output + 64 * 13);
117 R14.store_le(output + 64 * 14);
118 R15.store_le(output + 64 * 15);
119
121
122 state[8] += 16;
123 if(state[8] < 16) {
124 state[9]++;
125 }
126}
127} // namespace Botan
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
static BOTAN_FN_ISA_AVX512 void transpose(SIMD_16x32 &B0, SIMD_16x32 &B1, SIMD_16x32 &B2, SIMD_16x32 &B3)
SIMD_16x32 BOTAN_FN_ISA_AVX512 unsigned_lt(const SIMD_16x32 &other) const noexcept
static BOTAN_FN_ISA_AVX512 void zero_registers()
static BOTAN_FN_ISA_AVX512 SIMD_16x32 splat(uint32_t B)
Definition simd_avx512.h:60
BOTAN_FORCE_INLINE constexpr T rotl(T input)
Definition rotate.h:23