@@ -259,6 +259,7 @@ impl From<AffinePoint> for ProjectivePoint {
259259impl < const N : usize > BatchNormalize < [ ProjectivePoint ; N ] > for ProjectivePoint {
260260 type Output = [ Self :: AffineRepr ; N ] ;
261261
262+ #[ inline]
262263 fn batch_normalize ( points : & [ Self ; N ] ) -> [ Self :: AffineRepr ; N ] {
263264 let mut zs = [ FieldElement :: ONE ; N ] ;
264265 let mut affine_points = [ AffinePoint :: IDENTITY ; N ] ;
@@ -271,6 +272,7 @@ impl<const N: usize> BatchNormalize<[ProjectivePoint; N]> for ProjectivePoint {
271272impl BatchNormalize < [ ProjectivePoint ] > for ProjectivePoint {
272273 type Output = Vec < Self :: AffineRepr > ;
273274
275+ #[ inline]
274276 fn batch_normalize ( points : & [ Self ] ) -> Vec < Self :: AffineRepr > {
275277 let mut zs = vec ! [ FieldElement :: ONE ; points. len( ) ] ;
276278 let mut affine_points = vec ! [ AffinePoint :: IDENTITY ; points. len( ) ] ;
@@ -290,23 +292,23 @@ where
290292 let out = out. as_mut ( ) ;
291293
292294 for i in 0 ..points. len ( ) {
293- if points[ i] . z != FieldElement :: ZERO {
294- // Even a single zero value will fail inversion for the entire batch.
295- // Put a dummy value (above `FieldElement::ONE`) so inversion succeeds
296- // and treat that case specially later-on.
297- zs. as_mut ( ) [ i] = points[ i] . z ;
298- }
295+ // Even a single zero value will fail inversion for the entire batch.
296+ // Put a dummy value (above `FieldElement::ONE`) so inversion succeeds
297+ // and treat that case specially later-on.
298+ zs. as_mut ( ) [ i] . conditional_assign ( & points[ i] . z , !points[ i] . z . ct_eq ( & FieldElement :: ZERO ) ) ;
299299 }
300300
301301 // This is safe to unwrap since we assured that all elements are non-zero
302302 let zs_inverses = <FieldElement as BatchInvert < Z > >:: batch_invert ( zs) . unwrap ( ) ;
303303
304304 for i in 0 ..out. len ( ) {
305- if points[ i] . z != FieldElement :: ZERO {
306- // If the `z` coordinate is non-zero, we can use it to invert;
307- // otherwise it defaults to the `IDENTITY` value in initialization.
308- out[ i] = points[ i] . to_affine_internal ( zs_inverses. as_ref ( ) [ i] )
309- }
305+ // If the `z` coordinate is non-zero, we can use it to invert;
306+ // otherwise it defaults to the `IDENTITY` value.
307+ out[ i] = AffinePoint :: conditional_select (
308+ & points[ i] . to_affine_internal ( zs_inverses. as_ref ( ) [ i] ) ,
309+ & AffinePoint :: IDENTITY ,
310+ points[ i] . z . ct_eq ( & FieldElement :: ZERO ) ,
311+ ) ;
310312 }
311313}
312314
@@ -449,13 +451,9 @@ impl Curve for ProjectivePoint {
449451 }
450452
451453 #[ cfg( feature = "alloc" ) ]
454+ #[ inline]
452455 fn batch_normalize ( projective : & [ Self ] , affine : & mut [ Self :: AffineRepr ] ) {
453456 assert_eq ! ( projective. len( ) , affine. len( ) ) ;
454-
455- for point in affine. iter_mut ( ) {
456- * point = AffinePoint :: IDENTITY ;
457- }
458-
459457 let mut zs = vec ! [ FieldElement :: ONE ; projective. len( ) ] ;
460458 batch_normalize_generic ( projective, zs. as_mut_slice ( ) , affine) ;
461459 }
0 commit comments