@@ -308,6 +308,17 @@ public void IsZeroTest(uint u0, uint u1, uint u2, uint u3, uint u4, uint u5, uin
308
308
Assert . Equal ( expected , scalar . IsZero ) ;
309
309
}
310
310
311
+ [ Fact ]
312
+ public void StaticPropTest ( )
313
+ {
314
+ Assert . True ( Scalar8x32 . Zero . IsZero ) ;
315
+ Scalar8x32 zero = new ( 0 ) ;
316
+ Assert . Equal ( zero , Scalar8x32 . Zero ) ;
317
+
318
+ Assert . True ( Scalar8x32 . One . IsOne ) ;
319
+ Scalar8x32 one = new ( 1 ) ;
320
+ Assert . Equal ( one , Scalar8x32 . One ) ;
321
+ }
311
322
312
323
public static IEnumerable < object [ ] > GetMultCases ( )
313
324
{
@@ -619,8 +630,78 @@ public void Libsecp256k1Tests() // run_scalar_tests
619
630
{
620
631
ScalarTest ( rng ) ;
621
632
}
633
+
634
+ // Check that the scalar constants secp256k1_scalar_zero and
635
+ // secp256k1_scalar_one contain the expected values.
636
+ // Note: these are tested in StaticPropTest()
637
+
638
+ {
639
+ // (-1)+1 should be zero
640
+ Scalar8x32 o = Scalar8x32 . One . Negate ( ) ;
641
+ o = o . Add ( Scalar8x32 . One , out _ ) ;
642
+ Assert . True ( o . IsZero ) ;
643
+ o = o . Negate ( ) ;
644
+ Assert . True ( o . IsZero ) ;
645
+ }
646
+
647
+ // Note: HALF_TESTS is turned into Libsecp256k1_HalfTest()
648
+
649
+ {
650
+ Span < uint > arr = new uint [ 8 ] ;
651
+ arr . Fill ( uint . MaxValue ) ;
652
+ unsafe
653
+ {
654
+ fixed ( uint * ptr = arr )
655
+ {
656
+ Scalar8x32 s = new ( ptr ) ;
657
+ Assert . True ( s . CheckOverflow ( ) == 1 ) ;
658
+ }
659
+ }
660
+ }
661
+ }
662
+
663
+ public static IEnumerable < object [ ] > GetLibsecp256k1_HalfCases ( )
664
+ {
665
+ // Test that halving and doubling roundtrips on some fixed values.
666
+ // Note: our ctors are in reverse (take lowest limb first)
667
+ Scalar8x32 [ ] HALF_TESTS =
668
+ [
669
+ // 0
670
+ new Scalar8x32 ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ,
671
+ // 1
672
+ new Scalar8x32 ( 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ,
673
+ // -1
674
+ new ( 0xd0364140u , 0xbfd25e8cu , 0xaf48a03bu , 0xbaaedce6u , 0xfffffffeu , 0xffffffffu , 0xffffffffu , 0xffffffffu ) ,
675
+ // -2 (largest odd value)
676
+ new ( 0xd036413Fu , 0xbfd25e8cu , 0xaf48a03bu , 0xbaaedce6u , 0xfffffffeu , 0xffffffffu , 0xffffffffu , 0xffffffffu ) ,
677
+ // Half the secp256k1 order
678
+ new ( 0x681b20a0u , 0xdfe92f46u , 0x57a4501du , 0x5d576e73u , 0xffffffffu , 0xffffffffu , 0xffffffffu , 0x7fffffffu ) ,
679
+ // Half the secp256k1 order + 1
680
+ new ( 0x681b20a1u , 0xdfe92f46u , 0x57a4501du , 0x5d576e73u , 0xffffffffu , 0xffffffffu , 0xffffffffu , 0x7fffffffu ) ,
681
+ // 2^255
682
+ new ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x80000000u ) ,
683
+ // 2^255 - 1
684
+ new ( 0xffffffffu , 0xffffffffu , 0xffffffffu , 0xffffffffu , 0xffffffffu , 0xffffffffu , 0xffffffffu , 0x7fffffffu ) ,
685
+ ] ;
686
+
687
+ foreach ( var item in HALF_TESTS )
688
+ {
689
+ yield return new object [ ] { item } ;
690
+ }
691
+ }
692
+ [ Theory ]
693
+ [ MemberData ( nameof ( GetLibsecp256k1_HalfCases ) ) ]
694
+ public void Libsecp256k1_HalfTest ( in Scalar8x32 n )
695
+ {
696
+ Scalar8x32 s = n . Half ( ) ;
697
+ s = s . Add ( s , out _ ) ;
698
+ Assert . Equal ( n , s ) ;
699
+ s = s . Add ( s , out _ ) ;
700
+ s = s . Half ( ) ;
701
+ Assert . Equal ( n , s ) ;
622
702
}
623
703
704
+
624
705
#endregion
625
706
}
626
707
}
0 commit comments