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