myl7/fss 2.0.0
Function secret sharing (FSS) primitives including distributed point/comparison function (DPF/DCF)
Loading...
Searching...
No Matches
uint.cuh
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
7
8#pragma once
9#include <fss/group.cuh>
10#include <fss/compat.cuh>
11#include <fss/group/uint128.cuh>
12#include <cuda_runtime.h>
13#include <type_traits>
14#include <cassert>
15#include <cstdint>
16
17namespace fss::group {
18
29#if FSS_ENABLE_V1_COMPAT
30// Under the v1 compatibility switch the primary also admits __uint128_t with
31// a uint64-range positive modulus so the deprecated partial specialization
32// below is reachable: naming Uint<__uint128_t, ...> checks this requires-
33// clause even when the specialization wins partial ordering. Every other
34// __uint128_t modulus still fails the clause, and the specialization covers
35// the whole admitted __uint128_t domain, so the primary body below never
36// instantiates for __uint128_t and keeps no wide arithmetic.
37template <typename T, T mod = 0>
38 requires((std::is_unsigned_v<T> && sizeof(T) <= 8) ||
39 (std::is_same_v<T, __uint128_t> && mod > 0 && mod <= static_cast<__uint128_t>(UINT64_MAX)))
40class Uint {
41#else
42template <typename T, T mod = 0>
43 requires(std::is_unsigned_v<T> && sizeof(T) <= 8)
44class Uint {
45#endif
46public:
47 // Groupable interface.
48
50 __host__ __device__ Uint operator+(Uint rhs) const {
51 if constexpr (mod == 0) return {static_cast<T>(val_ + rhs.val_)};
52
53 if (val_ >= mod - rhs.val_) return {static_cast<T>(val_ + rhs.val_ - mod)};
54 else return {static_cast<T>(val_ + rhs.val_)};
55 }
56
58 __host__ __device__ Uint operator-() const {
59 if constexpr (mod == 0) return {static_cast<T>(-val_)};
60
61 if (val_ == 0) return {0};
62 else return {static_cast<T>(mod - val_)};
63 }
64
66 __host__ __device__ Uint() : val_(0) {}
67
69 __host__ __device__ static Uint From(int4 buf) {
70 assert((buf.w & 1) == 0);
71
72 T value = 0;
73 if constexpr (sizeof(T) < 4) value = buf.x & ((1 << 8 * sizeof(T)) - 1);
74 // Cast to unsigned int first to prevent sign extension when promoting to larger types
75 else if constexpr (sizeof(T) == 4) value = static_cast<unsigned int>(buf.x);
76 else if constexpr (sizeof(T) == 8)
77 value = static_cast<T>(static_cast<unsigned int>(buf.x)) | static_cast<T>(static_cast<unsigned int>(buf.y)) << 32;
78 else __builtin_unreachable();
79
80 if constexpr (mod > 0) value %= mod;
81
82 return {value};
83 }
84
86 __host__ __device__ int4 Into() const {
87 int4 buf = {0, 0, 0, 0};
88 if constexpr (sizeof(T) <= 4) buf.x = static_cast<int>(val_);
89 else if constexpr (sizeof(T) == 8) {
90 buf.x = static_cast<int>(val_ & 0xffffffff);
91 buf.y = static_cast<int>(val_ >> 32);
92 } else __builtin_unreachable();
93 return buf;
94 }
95
96 // Additional public API.
97 // Temporary access for the host DCF full-domain fast path. Revisit after
98 // comparing it with the generic Groupable implementation.
100 __host__ __device__ T Value() const { return val_; }
101
102private:
103 T val_;
104
105 __host__ __device__ Uint(T v) : val_(v) {}
106};
107static_assert(Groupable<Uint<uint8_t>>);
108static_assert(Groupable<Uint<uint16_t>>);
109static_assert(Groupable<Uint<uint32_t>>);
110static_assert(Groupable<Uint<uint64_t>>);
111
112#if FSS_ENABLE_V1_COMPAT
127// Directly naming this class with a modulus at or above 2^63 makes the nvcc
128// host pass spell the template argument as an unsuffixed decimal. The probed
129// CUDA 12.6/GCC 11.4 host pass warns about that literal while still parsing
130// the value correctly. The warning is informational; do not suppress it.
131template <__uint128_t mod>
132 requires(mod > 0 && mod <= static_cast<__uint128_t>(UINT64_MAX))
133class [[deprecated("use fss::group::Uint128<fss::group::Uint128Modulus{.low = mod, .high = 0}> instead")]]
134 Uint<__uint128_t, mod> {
135public:
136 // Groupable interface.
137
139 __host__ __device__ Uint operator+(Uint rhs) const { return Uint(impl_ + rhs.impl_); }
140
142 __host__ __device__ Uint operator-() const { return Uint(-impl_); }
143
145 __host__ __device__ Uint() : impl_() {}
146
148 __host__ __device__ static Uint From(int4 buf) { return Uint(Underlying::From(buf)); }
149
151 __host__ __device__ int4 Into() const { return impl_.Into(); }
152
153 // Additional public API.
155 __host__ __device__ __uint128_t Value() const { return impl_.Value(); }
156
157private:
158 using Underlying = Uint128<Uint128Modulus{static_cast<uint64_t>(mod), 0}>;
159
160 Underlying impl_;
161
162 __host__ __device__ explicit Uint(Underlying impl) : impl_(impl) {}
163};
164#endif // FSS_ENABLE_V1_COMPAT
165
166} // namespace fss::group
Unsigned integers with arithmetic addition and optional modulo as a group.
Definition uint.cuh:44
Uint operator+(Uint rhs) const
Return the group sum.
Definition uint.cuh:50
Uint operator-() const
Return the additive inverse.
Definition uint.cuh:58
int4 Into() const
Encode this group element as a clamped block.
Definition uint.cuh:86
Uint()
Construct the additive identity.
Definition uint.cuh:66
static Uint From(int4 buf)
Convert a clamped block to a group element, reducing modulo mod when set.
Definition uint.cuh:69
T Value() const
Return a copy of the underlying unsigned integer value.
Definition uint.cuh:100
Single build-time switch for the deprecated v1 Cw-form compatibility entries.
Group interface.
Definition group.cuh:49