curve25519_dalek/
window.rs1#![allow(non_snake_case)]
15
16use core::fmt::Debug;
17
18use cfg_if::cfg_if;
19
20use subtle::Choice;
21use subtle::ConditionallyNegatable;
22use subtle::ConditionallySelectable;
23use subtle::ConstantTimeEq;
24
25use crate::traits::Identity;
26
27use crate::backend::serial::curve_models::AffineNielsPoint;
28use crate::backend::serial::curve_models::ProjectiveNielsPoint;
29use crate::edwards::EdwardsPoint;
30
31#[cfg(feature = "zeroize")]
32use zeroize::Zeroize;
33
34macro_rules! impl_lookup_table {
35 (Name = $name:ident, Size = $size:expr, SizeNeg = $neg:expr, SizeRange = $range:expr, ConversionRange = $conv_range:expr) => {
36 #[derive(Copy, Clone)]
47 pub struct $name<T>(pub(crate) [T; $size]);
48
49 impl<T> $name<T>
50 where
51 T: Identity + ConditionallySelectable + ConditionallyNegatable,
52 {
53 pub fn select(&self, x: i8) -> T {
55 debug_assert!(x >= $neg);
56 debug_assert!(x as i16 <= $size as i16); let xmask = x as i16 >> 7;
60 let xabs = (x as i16 + xmask) ^ xmask;
61
62 let mut t = T::identity();
64 for j in $range {
65 let c = (xabs as u16).ct_eq(&(j as u16));
67 t.conditional_assign(&self.0[j - 1], c);
68 }
69 let neg_mask = Choice::from((xmask & 1) as u8);
72 t.conditional_negate(neg_mask);
73 t
76 }
77 }
78
79 impl<T: Copy + Default> Default for $name<T> {
80 fn default() -> $name<T> {
81 $name([T::default(); $size])
82 }
83 }
84
85 impl<T: Debug> Debug for $name<T> {
86 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
87 write!(f, "{:?}(", stringify!($name))?;
88
89 for x in self.0.iter() {
90 write!(f, "{:?}", x)?;
91 }
92
93 write!(f, ")")
94 }
95 }
96
97 impl<'a> From<&'a EdwardsPoint> for $name<ProjectiveNielsPoint> {
98 fn from(P: &'a EdwardsPoint) -> Self {
99 let mut points = [P.as_projective_niels(); $size];
100 for j in $conv_range {
101 points[j + 1] = (P + &points[j]).as_extended().as_projective_niels();
102 }
103 $name(points)
104 }
105 }
106
107 impl<'a> From<&'a EdwardsPoint> for $name<AffineNielsPoint> {
108 fn from(P: &'a EdwardsPoint) -> Self {
109 let mut points = [P.as_affine_niels(); $size];
110 for j in $conv_range {
112 points[j + 1] = (P + &points[j]).as_extended().as_affine_niels()
113 }
114 $name(points)
115 }
116 }
117
118 #[cfg(feature = "zeroize")]
119 impl<T> Zeroize for $name<T>
120 where
121 T: Copy + Default + Zeroize,
122 {
123 fn zeroize(&mut self) {
124 self.0.iter_mut().zeroize();
125 }
126 }
127 };
128} impl_lookup_table! {
133 Name = LookupTable,
134 Size = 8,
135 SizeNeg = -8,
136 SizeRange = 1..9,
137 ConversionRange = 0..7
138}
139
140cfg_if! {
142 if #[cfg(feature = "precomputed-tables")] {
143 impl_lookup_table! {
145 Name = LookupTableRadix32,
146 Size = 16,
147 SizeNeg = -16,
148 SizeRange = 1..17,
149 ConversionRange = 0..15
150 }
151 impl_lookup_table! {
153 Name = LookupTableRadix64,
154 Size = 32,
155 SizeNeg = -32,
156 SizeRange = 1..33,
157 ConversionRange = 0..31
158 }
159 impl_lookup_table! {
161 Name = LookupTableRadix128,
162 Size = 64,
163 SizeNeg = -64,
164 SizeRange = 1..65,
165 ConversionRange = 0..63
166 }
167 impl_lookup_table! {
169 Name = LookupTableRadix256,
170 Size = 128,
171 SizeNeg = -128,
172 SizeRange = 1..129,
173 ConversionRange = 0..127
174 }
175
176 pub(crate) type LookupTableRadix16<T> = LookupTable<T>;
178 }
179}
180
181#[derive(Copy, Clone)]
183pub(crate) struct NafLookupTable5<T>(pub(crate) [T; 8]);
184
185impl<T: Copy> NafLookupTable5<T> {
186 pub fn select(&self, x: usize) -> T {
188 debug_assert_eq!(x & 1, 1);
189 debug_assert!(x < 16);
190
191 self.0[x / 2]
192 }
193}
194
195impl<T: Debug> Debug for NafLookupTable5<T> {
196 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
197 write!(f, "NafLookupTable5({:?})", self.0)
198 }
199}
200
201impl<'a> From<&'a EdwardsPoint> for NafLookupTable5<ProjectiveNielsPoint> {
202 fn from(A: &'a EdwardsPoint) -> Self {
203 let mut Ai = [A.as_projective_niels(); 8];
204 let A2 = A.double();
205 for i in 0..7 {
206 Ai[i + 1] = (&A2 + &Ai[i]).as_extended().as_projective_niels();
207 }
208 NafLookupTable5(Ai)
210 }
211}
212
213impl<'a> From<&'a EdwardsPoint> for NafLookupTable5<AffineNielsPoint> {
214 fn from(A: &'a EdwardsPoint) -> Self {
215 let mut Ai = [A.as_affine_niels(); 8];
216 let A2 = A.double();
217 for i in 0..7 {
218 Ai[i + 1] = (&A2 + &Ai[i]).as_extended().as_affine_niels();
219 }
220 NafLookupTable5(Ai)
222 }
223}
224
225#[cfg(any(feature = "precomputed-tables", feature = "alloc"))]
228#[derive(Copy, Clone)]
229pub(crate) struct NafLookupTable8<T>(pub(crate) [T; 64]);
230
231#[cfg(any(feature = "precomputed-tables", feature = "alloc"))]
232impl<T: Copy> NafLookupTable8<T> {
233 pub fn select(&self, x: usize) -> T {
234 debug_assert_eq!(x & 1, 1);
235 debug_assert!(x < 128);
236
237 self.0[x / 2]
238 }
239}
240
241#[cfg(any(feature = "precomputed-tables", feature = "alloc"))]
242impl<T: Debug> Debug for NafLookupTable8<T> {
243 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
244 writeln!(f, "NafLookupTable8([")?;
245 for i in 0..64 {
246 writeln!(f, "\t{:?},", &self.0[i])?;
247 }
248 write!(f, "])")
249 }
250}
251
252#[cfg(any(feature = "precomputed-tables", feature = "alloc"))]
253impl<'a> From<&'a EdwardsPoint> for NafLookupTable8<ProjectiveNielsPoint> {
254 fn from(A: &'a EdwardsPoint) -> Self {
255 let mut Ai = [A.as_projective_niels(); 64];
256 let A2 = A.double();
257 for i in 0..63 {
258 Ai[i + 1] = (&A2 + &Ai[i]).as_extended().as_projective_niels();
259 }
260 NafLookupTable8(Ai)
262 }
263}
264
265#[cfg(any(feature = "precomputed-tables", feature = "alloc"))]
266impl<'a> From<&'a EdwardsPoint> for NafLookupTable8<AffineNielsPoint> {
267 fn from(A: &'a EdwardsPoint) -> Self {
268 let mut Ai = [A.as_affine_niels(); 64];
269 let A2 = A.double();
270 for i in 0..63 {
271 Ai[i + 1] = (&A2 + &Ai[i]).as_extended().as_affine_niels();
272 }
273 NafLookupTable8(Ai)
275 }
276}