From 64c3a870cdf5026a506c85f4eb3335608cd6e0c5 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 15 Sep 2020 13:27:54 +0200 Subject: [PATCH] Enforce ecdsa length (#1934) * Enforce ecdsa length * Optimize * use ReadOnlySpan * Remove using * Optimize * Optimize Co-authored-by: Erik Zhang --- src/neo/Cryptography/ECC/ECDsa.cs | 8 +++----- .../Cryptography/ECC/UT_ECDSA.cs | 20 ++++++++++++------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/neo/Cryptography/ECC/ECDsa.cs b/src/neo/Cryptography/ECC/ECDsa.cs index 08f48b1dc3..b14fc67ead 100644 --- a/src/neo/Cryptography/ECC/ECDsa.cs +++ b/src/neo/Cryptography/ECC/ECDsa.cs @@ -24,13 +24,11 @@ public ECDsa(ECPoint publicKey) private BigInteger CalculateE(BigInteger n, ReadOnlySpan message) { - int messageBitLength = message.Length * 8; - BigInteger trunc = new BigInteger(message, isUnsigned: true, isBigEndian: true); - if (n.GetBitLength() < messageBitLength) + if (n.GetBitLength() != (message.Length * 8)) { - trunc >>= messageBitLength - n.GetBitLength(); + throw new ArgumentException($"Message must be {n.GetBitLength()} bit length"); } - return trunc; + return new BigInteger(message, isUnsigned: true, isBigEndian: true); } public BigInteger[] GenerateSignature(ReadOnlySpan message) diff --git a/tests/neo.UnitTests/Cryptography/ECC/UT_ECDSA.cs b/tests/neo.UnitTests/Cryptography/ECC/UT_ECDSA.cs index 2abc85ed45..b776fd4eff 100644 --- a/tests/neo.UnitTests/Cryptography/ECC/UT_ECDSA.cs +++ b/tests/neo.UnitTests/Cryptography/ECC/UT_ECDSA.cs @@ -1,5 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Cryptography.ECC; +using Neo.IO; using System; using ECCurve = Neo.Cryptography.ECC.ECCurve; @@ -12,19 +13,24 @@ public class UT_ECDSA public void GenerateSignature() { var ecdsa = new ECDsa(ECCurve.Secp256k1.Infinity); - Assert.ThrowsException(() => ecdsa.GenerateSignature(new byte[0])); + Assert.ThrowsException(() => ecdsa.GenerateSignature(UInt256.Zero.ToArray())); + Assert.ThrowsException(() => ecdsa.VerifySignature(new byte[0], 1, 2)); var pk = new byte[32]; for (int x = 0; x < pk.Length; x++) pk[x] = (byte)x; ecdsa = new ECDsa(pk, ECCurve.Secp256k1); - var sig = ecdsa.GenerateSignature(new byte[] { 1 }); - Assert.IsTrue(ecdsa.VerifySignature(new byte[] { 1 }, sig[0], sig[1])); - Assert.IsFalse(ecdsa.VerifySignature(new byte[] { 2 }, sig[0], sig[1])); - Assert.IsFalse(ecdsa.VerifySignature(new byte[] { 1 }, sig[0] + 1, sig[1])); - Assert.IsFalse(ecdsa.VerifySignature(new byte[] { 1 }, sig[0], sig[1] + 1)); - Assert.IsFalse(ecdsa.VerifySignature(new byte[33], sig[0], sig[1])); + var zero = UInt256.Zero.ToArray(); + var one = UInt256.Parse("0100000000000000000000000000000000000000000000000000000000000000").ToArray(); + var two = UInt256.Parse("0200000000000000000000000000000000000000000000000000000000000000").ToArray(); + var sig = ecdsa.GenerateSignature(one); + + Assert.IsTrue(ecdsa.VerifySignature(one, sig[0], sig[1])); + Assert.IsFalse(ecdsa.VerifySignature(two, sig[0], sig[1])); + Assert.IsFalse(ecdsa.VerifySignature(one, sig[0] + 1, sig[1])); + Assert.IsFalse(ecdsa.VerifySignature(one, sig[0], sig[1] + 1)); + Assert.IsFalse(ecdsa.VerifySignature(zero, sig[0], sig[1])); } } }