myl7/fss 1.1.0
Function secret sharing (FSS) primitives including distributed point/comparison function (DPF/DCF)
Loading...
Searching...
No Matches
chacha.cuh
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
8#pragma once
9#include <fss/prg.cuh>
10#include <cuda_runtime.h>
11#include <cuda/std/array>
12#include <fss/util.cuh>
13
14namespace fss::prg {
15
24template <int mul, int rounds = 20>
25 requires(rounds % 2 == 0 && (mul == 1 || mul == 2 || mul == 4))
26class ChaCha {
27private:
28 const int *nonce_;
29
30 template <int n>
31 __host__ __device__ static int RotateLeft(int a) {
32 auto u = static_cast<unsigned>(a);
33 return static_cast<int>((u << n) | (u >> (32 - n)));
34 }
35
36 __host__ __device__ static void QuarterRound(int &a, int &b, int &c, int &d) {
37 a += b;
38 d ^= a;
39 d = RotateLeft<16>(d);
40 c += d;
41 b ^= c;
42 b = RotateLeft<12>(b);
43 a += b;
44 d ^= a;
45 d = RotateLeft<8>(d);
46 c += d;
47 b ^= c;
48 b = RotateLeft<7>(b);
49 }
50
51 __host__ __device__ static void Rounds(int4 x[4]) {
52 for (int i = 0; i < rounds; i += 2) {
53 // Column rounds
54 QuarterRound(x[0].x, x[1].x, x[2].x, x[3].x);
55 QuarterRound(x[0].y, x[1].y, x[2].y, x[3].y);
56 QuarterRound(x[0].z, x[1].z, x[2].z, x[3].z);
57 QuarterRound(x[0].w, x[1].w, x[2].w, x[3].w);
58 // Diagonal rounds
59 QuarterRound(x[0].x, x[1].y, x[2].z, x[3].w);
60 QuarterRound(x[0].y, x[1].z, x[2].w, x[3].x);
61 QuarterRound(x[0].z, x[1].w, x[2].x, x[3].y);
62 QuarterRound(x[0].w, x[1].x, x[2].y, x[3].z);
63 }
64 }
65
66 __host__ __device__ static void ExpandKey(int4 x[4]) {
67 x[2] = x[1];
68 }
69
70 // The nothing-up-my-sleeve constant for 32B key: "expand 32-byte k"
71 constexpr static int4 kConstant32 = {
72 0x61707865, // "expa"
73 0x3320646e, // "nd 3"
74 0x79622d32, // "2-by"
75 0x6b206574, // "te k"
76 };
77 // The nothing-up-my-sleeve constant for 16B key: "expand 16-byte k"
78 constexpr static int4 kConstant16 = {
79 0x61707865, // "expa"
80 0x3120646e, // "nd 1"
81 0x79622d36, // "6-by"
82 0x6b206574, // "te k"
83 };
84
85public:
93 __host__ __device__ ChaCha(const int *nonce) : nonce_(nonce) {}
94
95 __host__ __device__ cuda::std::array<int4, mul> Gen(int4 seed) {
96 int4 buf[4];
97
98 // Constant
99 if constexpr (mul <= 2) buf[0] = kConstant16;
100 else buf[0] = kConstant32;
101
102 // Key from the seed
103 buf[1] = seed;
104 ExpandKey(buf);
105
106 // Counter is always 0 because we only gen one block
107 buf[3].x = 0;
108 buf[3].y = 0;
109 // Nonce
110 buf[3].z = nonce_[0];
111 buf[3].w = nonce_[1];
112
113 Rounds(buf);
114
115 buf[1] = util::Xor(buf[1], seed);
116 if constexpr (mul == 1) {
117 return {buf[1]};
118 } else if constexpr (mul == 2) {
119 buf[0] = util::Xor(buf[0], kConstant16);
120 return {buf[0], buf[1]};
121 } else {
122 buf[0] = util::Xor(buf[0], kConstant32);
123 buf[2] = util::Xor(buf[2], seed);
124 buf[3] = util::Xor(buf[3], {0, 0, nonce_[0], nonce_[1]});
125 return {buf[0], buf[1], buf[2], buf[3]};
126 }
127 }
128};
129static_assert(Prgable<ChaCha<1>, 1> && Prgable<ChaCha<2>, 2> && Prgable<ChaCha<4>, 4>);
130
131} // namespace fss::prg
ChaCha as a PRG.
Definition chacha.cuh:26
ChaCha(const int *nonce)
Constructor.
Definition chacha.cuh:93
Pseudorandom generator (PRG) interface.
Definition prg.cuh:21