58template <
size_t bits,
size_t bit_position>
inline uint64_t
get_wnaf_bits_const(
const uint64_t* scalar)
noexcept
60 if constexpr (bits == 0) {
63 constexpr size_t lo_limb_idx = bit_position / 64;
64 constexpr size_t hi_limb_idx = (bit_position + bits - 1) / 64;
65 constexpr uint64_t lo_shift = bit_position & 63UL;
66 constexpr uint64_t bit_mask = (1UL <<
static_cast<uint64_t
>(bits)) - 1UL;
68 uint64_t lo = (scalar[lo_limb_idx] >> lo_shift);
69 if constexpr (lo_limb_idx == hi_limb_idx) {
72 constexpr uint64_t hi_shift = 64UL - (bit_position & 63UL);
73 uint64_t hi = ((scalar[hi_limb_idx] << (hi_shift)));
74 return (lo | hi) & bit_mask;
87inline uint64_t
get_wnaf_bits(
const uint64_t* scalar,
const uint64_t bits,
const uint64_t bit_position)
noexcept
89 const auto lo_limb_idx =
static_cast<size_t>(bit_position >> 6);
90 const auto hi_limb_idx =
static_cast<size_t>((bit_position + bits - 1) >> 6);
91 const uint64_t lo_shift = bit_position & 63UL;
92 const uint64_t bit_mask = (1UL <<
static_cast<uint64_t
>(bits)) - 1UL;
93 const bool spans_limbs = (lo_limb_idx != hi_limb_idx);
95 const uint64_t lo = scalar[lo_limb_idx] >> lo_shift;
98 const uint64_t hi = spans_limbs ? (scalar[hi_limb_idx] << (64UL - lo_shift)) : 0UL;
100 return (lo | hi) & bit_mask;
113inline void wnaf_round(uint64_t* scalar, uint64_t* wnaf,
const uint64_t point_index,
const uint64_t previous)
noexcept
115 constexpr size_t wnaf_entries = (
SCALAR_BITS + wnaf_bits - 1) / wnaf_bits;
116 constexpr auto log2_num_points =
static_cast<size_t>(
numeric::get_msb(
static_cast<uint32_t
>(num_points)));
118 if constexpr (round_i < wnaf_entries - 1) {
120 uint64_t predicate = ((
slice & 1UL) == 0UL);
121 wnaf[(wnaf_entries - round_i) << log2_num_points] =
122 ((((previous - (predicate << wnaf_bits)) ^ (0UL - predicate)) >> 1UL) | (predicate << 31UL)) |
123 (point_index << 32UL);
124 wnaf_round<num_points, wnaf_bits, round_i + 1>(scalar, wnaf, point_index,
slice + predicate);
128 uint64_t predicate = ((
slice & 1UL) == 0UL);
130 ((((previous - (predicate << wnaf_bits)) ^ (0UL - predicate)) >> 1UL) | (predicate << 31UL)) |
131 (point_index << 32UL);
132 wnaf[0] = ((
slice + predicate) >> 1UL) | (point_index << 32UL);
146inline void wnaf_round(uint64_t* scalar, uint64_t* wnaf,
const uint64_t point_index,
const uint64_t previous)
noexcept
148 constexpr size_t wnaf_entries = (scalar_bits + wnaf_bits - 1) / wnaf_bits;
149 constexpr auto log2_num_points =
static_cast<uint64_t
>(
numeric::get_msb(
static_cast<uint32_t
>(num_points)));
151 if constexpr (round_i < wnaf_entries - 1) {
152 uint64_t
slice = get_wnaf_bits_const<wnaf_bits, round_i * wnaf_bits>(scalar);
153 uint64_t predicate = ((
slice & 1UL) == 0UL);
154 wnaf[(wnaf_entries - round_i) << log2_num_points] =
155 ((((previous - (predicate << wnaf_bits)) ^ (0UL - predicate)) >> 1UL) | (predicate << 31UL)) |
156 (point_index << 32UL);
157 wnaf_round<scalar_bits, num_points, wnaf_bits, round_i + 1>(scalar, wnaf, point_index,
slice + predicate);
159 constexpr size_t final_bits = ((scalar_bits / wnaf_bits) * wnaf_bits == scalar_bits)
161 : scalar_bits - (scalar_bits / wnaf_bits) * wnaf_bits;
163 uint64_t predicate = ((
slice & 1UL) == 0UL);
165 ((((previous - (predicate << wnaf_bits)) ^ (0UL - predicate)) >> 1UL) | (predicate << 31UL)) |
166 (point_index << 32UL);
167 wnaf[0] = ((
slice + predicate) >> 1UL) | (point_index << 32UL);
172inline void fixed_wnaf(uint64_t* scalar, uint64_t* wnaf,
bool& skew_map,
const size_t point_index)
noexcept
174 skew_map = ((scalar[0] & 1) == 0);
175 uint64_t previous = get_wnaf_bits_const<wnaf_bits, 0>(scalar) +
static_cast<uint64_t
>(skew_map);
176 wnaf_round<num_points, wnaf_bits, 1UL>(scalar, wnaf, point_index, previous);
180inline void fixed_wnaf(uint64_t* scalar, uint64_t* wnaf,
bool& skew_map,
const size_t point_index)
noexcept
182 skew_map = ((scalar[0] & 1) == 0);
183 uint64_t previous = get_wnaf_bits_const<wnaf_bits, 0>(scalar) +
static_cast<uint64_t
>(skew_map);
184 wnaf_round<num_bits, num_points, wnaf_bits, 1UL>(scalar, wnaf, point_index, previous);