@@ -482,6 +482,30 @@ mod conversion_impls {
482482    #[ cfg( feature = "std" ) ]  
483483    impl < T >  std:: error:: Error  for  ScalarTooLarge < T >  { } 
484484
485+     /// Error returned when trying to convert a zero value into a NonZero scalar 
486+      pub  struct  ZeroScalar < T > ( PhantomData < T > ) ; 
487+ 
488+     impl < T >  core:: fmt:: Display  for  ZeroScalar < T >  { 
489+         fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
490+             write ! ( 
491+                 f, 
492+                 "cannot convert zero {} to NonZero scalar" , 
493+                 type_name:: <T >( ) 
494+             ) 
495+         } 
496+     } 
497+ 
498+     impl < T >  core:: fmt:: Debug  for  ZeroScalar < T >  { 
499+         fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
500+             f. debug_tuple ( "ZeroScalar" ) 
501+                 . field ( & type_name :: < T > ( ) ) 
502+                 . finish ( ) 
503+         } 
504+     } 
505+ 
506+     #[ cfg( feature = "std" ) ]  
507+     impl < T >  std:: error:: Error  for  ZeroScalar < T >  { } 
508+ 
485509    /// Implements `From<$t> for $scalar` **and** 
486510     /// `TryFrom<$scalar> for $t` for every `$t` supplied. 
487511     macro_rules!  impl_scalar_conversions { 
@@ -497,6 +521,27 @@ mod conversion_impls {
497521                    } 
498522                } 
499523
524+                 impl <S > TryFrom <$t> for  Scalar <S ,  NonZero > { 
525+                     type  Error  = ZeroScalar <$t>; 
526+ 
527+                     fn  try_from( value:  $t)  -> Result <Self ,  Self :: Error > { 
528+                         // big-endian integer → 32-byte array 
529+                         let  mut  bytes = [ 0u8 ;  32 ] ; 
530+                         let  int_bytes = value. to_be_bytes( ) ; 
531+                         bytes[ 32  - int_bytes. len( )  ..] . copy_from_slice( & int_bytes) ; 
532+                         let  scalar = Scalar :: <S ,  Zero >:: from_bytes( bytes) . unwrap( ) ; 
533+ 
534+                         // Check if value is zero 
535+                         if  value == 0  { 
536+                             Err ( ZeroScalar ( PhantomData ) ) 
537+                         }  else { 
538+                             Ok ( scalar. non_zero( ) . unwrap( ) ) 
539+                         } 
540+                     } 
541+                 } 
542+ 
543+ 
544+ 
500545                impl <S ,  Z > TryFrom <Scalar <S ,  Z >> for  $t { 
501546                    type  Error  = ScalarTooLarge <$t>; 
502547
@@ -759,4 +804,34 @@ mod test {
759804        assert ! ( Scalar :: <Public ,  _>:: from( 41u32 )  < Scalar :: <Public ,  _>:: from( 42u32 ) ) ; 
760805        assert ! ( Scalar :: <Public ,  _>:: from( 42u32 )  <= Scalar :: <Public ,  _>:: from( 42u32 ) ) ; 
761806    } 
807+ 
808+     #[ test]  
809+     fn  try_from_zero_to_nonzero ( )  { 
810+         use  core:: convert:: TryFrom ; 
811+ 
812+         // Test that converting zero to NonZero fails 
813+         let  result = Scalar :: < Secret ,  NonZero > :: try_from ( 0u32 ) ; 
814+         assert ! ( result. is_err( ) ) ; 
815+ 
816+         // Test that converting non-zero to NonZero succeeds 
817+         let  result = Scalar :: < Secret ,  NonZero > :: try_from ( 42u32 ) ; 
818+         assert ! ( result. is_ok( ) ) ; 
819+         assert_eq ! ( 
820+             result. unwrap( ) , 
821+             Scalar :: <Secret ,  Zero >:: from( 42u32 ) . non_zero( ) . unwrap( ) 
822+         ) ; 
823+ 
824+         // Test with different integer types 
825+         assert ! ( Scalar :: <Public ,  NonZero >:: try_from( 0u8 ) . is_err( ) ) ; 
826+         assert ! ( Scalar :: <Public ,  NonZero >:: try_from( 0u16 ) . is_err( ) ) ; 
827+         assert ! ( Scalar :: <Public ,  NonZero >:: try_from( 0u64 ) . is_err( ) ) ; 
828+ 
829+         assert ! ( Scalar :: <Public ,  NonZero >:: try_from( 1u8 ) . is_ok( ) ) ; 
830+         assert ! ( Scalar :: <Public ,  NonZero >:: try_from( 1u16 ) . is_ok( ) ) ; 
831+         assert ! ( Scalar :: <Public ,  NonZero >:: try_from( 1u64 ) . is_ok( ) ) ; 
832+ 
833+         // Test that infallible From still works for Zero 
834+         let  _zero_scalar:  Scalar < Secret ,  Zero >  = 0u32 . into ( ) ; 
835+         let  _nonzero_scalar:  Scalar < Secret ,  Zero >  = 42u32 . into ( ) ; 
836+     } 
762837} 
0 commit comments