curve25519_dalek/backend/vector/scalar_mul/
vartime_double_base.rs1#![allow(non_snake_case)]
13
14#[curve25519_dalek_derive::unsafe_target_feature_specialize(
15 "avx2",
16 conditional(
17 "avx512ifma,avx512vl",
18 all(curve25519_dalek_backend = "unstable_avx512", nightly)
19 )
20)]
21pub mod spec {
22
23 use core::cmp::Ordering;
24
25 #[for_target_feature("avx2")]
26 use crate::backend::vector::avx2::{CachedPoint, ExtendedPoint};
27
28 #[for_target_feature("avx512ifma")]
29 use crate::backend::vector::ifma::{CachedPoint, ExtendedPoint};
30
31 #[cfg(feature = "precomputed-tables")]
32 #[for_target_feature("avx2")]
33 use crate::backend::vector::avx2::constants::BASEPOINT_ODD_LOOKUP_TABLE;
34
35 #[cfg(feature = "precomputed-tables")]
36 #[for_target_feature("avx512ifma")]
37 use crate::backend::vector::ifma::constants::BASEPOINT_ODD_LOOKUP_TABLE;
38
39 use crate::edwards::EdwardsPoint;
40 use crate::scalar::Scalar;
41 use crate::traits::Identity;
42 use crate::window::NafLookupTable5;
43
44 pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint {
46 let a_naf = a.non_adjacent_form(5);
47
48 #[cfg(feature = "precomputed-tables")]
49 let b_naf = b.non_adjacent_form(8);
50 #[cfg(not(feature = "precomputed-tables"))]
51 let b_naf = b.non_adjacent_form(5);
52
53 let mut i: usize = 255;
55 for j in (0..256).rev() {
56 i = j;
57 if a_naf[i] != 0 || b_naf[i] != 0 {
58 break;
59 }
60 }
61
62 let table_A = NafLookupTable5::<CachedPoint>::from(A);
63
64 #[cfg(feature = "precomputed-tables")]
65 let table_B = &BASEPOINT_ODD_LOOKUP_TABLE;
66
67 #[cfg(not(feature = "precomputed-tables"))]
68 let table_B =
69 &NafLookupTable5::<CachedPoint>::from(&crate::constants::ED25519_BASEPOINT_POINT);
70
71 let mut Q = ExtendedPoint::identity();
72
73 loop {
74 Q = Q.double();
75
76 match a_naf[i].cmp(&0) {
77 Ordering::Greater => {
78 Q = &Q + &table_A.select(a_naf[i] as usize);
79 }
80 Ordering::Less => {
81 Q = &Q - &table_A.select(-a_naf[i] as usize);
82 }
83 Ordering::Equal => {}
84 }
85
86 match b_naf[i].cmp(&0) {
87 Ordering::Greater => {
88 Q = &Q + &table_B.select(b_naf[i] as usize);
89 }
90 Ordering::Less => {
91 Q = &Q - &table_B.select(-b_naf[i] as usize);
92 }
93 Ordering::Equal => {}
94 }
95
96 if i == 0 {
97 break;
98 }
99 i -= 1;
100 }
101
102 Q.into()
103 }
104}