Skip to content

Commit fdb9683

Browse files
Add scalar static half + static property tests
1 parent c03dd7d commit fdb9683

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

Src/Autarkysoft.Bitcoin/Cryptography/EllipticCurve/Scalar8x32.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ public Scalar8x32 Half()
354354
}
355355

356356

357-
private uint CheckOverflow()
357+
public uint CheckOverflow()
358358
{
359359
uint yes = 0U;
360360
uint no = 0U;

Src/Tests/Bitcoin/Cryptography/EllipticCurve/Scalar8x32Tests.cs

+81
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,17 @@ public void IsZeroTest(uint u0, uint u1, uint u2, uint u3, uint u4, uint u5, uin
308308
Assert.Equal(expected, scalar.IsZero);
309309
}
310310

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+
}
311322

312323
public static IEnumerable<object[]> GetMultCases()
313324
{
@@ -619,8 +630,78 @@ public void Libsecp256k1Tests() // run_scalar_tests
619630
{
620631
ScalarTest(rng);
621632
}
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);
622702
}
623703

704+
624705
#endregion
625706
}
626707
}

0 commit comments

Comments
 (0)