@@ -71,27 +71,7 @@ impl Mul<&EdwardsScalar> for &MontgomeryXpoint {
71
71
72
72
#[ allow( clippy:: suspicious_arithmetic_impl) ]
73
73
fn mul ( self , scalar : & EdwardsScalar ) -> ProjectiveMontgomeryXpoint {
74
- // Algorithm 8 of Costello-Smith 2017
75
- let affine_u = FieldElement :: from_bytes ( & self . 0 ) ;
76
- let mut x0 = ProjectiveMontgomeryXpoint :: IDENTITY ;
77
- let mut x1 = ProjectiveMontgomeryXpoint {
78
- U : affine_u,
79
- W : FieldElement :: ONE ,
80
- } ;
81
-
82
- let bits = scalar. bits ( ) ;
83
- let mut swap = 0 ;
84
- for s in ( 0 ..448 ) . rev ( ) {
85
- let bit = bits[ s] as u8 ;
86
- let choice: u8 = swap ^ bit;
87
-
88
- ProjectiveMontgomeryXpoint :: conditional_swap ( & mut x0, & mut x1, Choice :: from ( choice) ) ;
89
- differential_add_and_double ( & mut x0, & mut x1, & affine_u) ;
90
-
91
- swap = bit;
92
- }
93
-
94
- x0
74
+ self . mul_internal ( scalar) . 0
95
75
}
96
76
}
97
77
@@ -134,6 +114,30 @@ impl MontgomeryXpoint {
134
114
self . to_projective ( ) . y ( sign) . to_bytes ( )
135
115
}
136
116
117
+ pub ( super ) fn mul_internal (
118
+ & self ,
119
+ scalar : & EdwardsScalar ,
120
+ ) -> ( ProjectiveMontgomeryXpoint , ProjectiveMontgomeryXpoint ) {
121
+ // Algorithm 8 of Costello-Smith 2017
122
+ let mut x0 = ProjectiveMontgomeryXpoint :: IDENTITY ;
123
+ let mut x1 = self . to_projective ( ) ;
124
+ let diff = x1. U ;
125
+
126
+ let bits = scalar. bits ( ) ;
127
+ let mut swap = 0 ;
128
+ for s in ( 0 ..448 ) . rev ( ) {
129
+ let bit = bits[ s] as u8 ;
130
+ let choice: u8 = swap ^ bit;
131
+
132
+ ProjectiveMontgomeryXpoint :: conditional_swap ( & mut x0, & mut x1, Choice :: from ( choice) ) ;
133
+ differential_add_and_double ( & mut x0, & mut x1, & diff) ;
134
+
135
+ swap = bit;
136
+ }
137
+
138
+ ( x0, x1)
139
+ }
140
+
137
141
/// Convert the point to a ProjectiveMontgomeryPoint
138
142
pub fn to_projective ( & self ) -> ProjectiveMontgomeryXpoint {
139
143
ProjectiveMontgomeryXpoint {
0 commit comments