diff --git a/ethereumj-core/src/main/java/org/ethereum/crypto/ECKey.java b/ethereumj-core/src/main/java/org/ethereum/crypto/ECKey.java index fa7f5a194d..15bfe7db51 100644 --- a/ethereumj-core/src/main/java/org/ethereum/crypto/ECKey.java +++ b/ethereumj-core/src/main/java/org/ethereum/crypto/ECKey.java @@ -1107,6 +1107,9 @@ public static byte[] recoverPubBytesFromSignature(int recId, ECDSASignature sig, BigInteger srInv = rInv.multiply(sig.s).mod(n); BigInteger eInvrInv = rInv.multiply(eInv).mod(n); ECPoint.Fp q = (ECPoint.Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv); + // result sanity check: point must not be at infinity + if (q.isInfinity()) + return null; return q.getEncoded(/* compressed */ false); } diff --git a/ethereumj-core/src/test/java/org/ethereum/crypto/ECKeyTest.java b/ethereumj-core/src/test/java/org/ethereum/crypto/ECKeyTest.java index dc313ee224..a87a01b450 100644 --- a/ethereumj-core/src/test/java/org/ethereum/crypto/ECKeyTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/crypto/ECKeyTest.java @@ -250,6 +250,22 @@ public void testVerifySignature3() throws SignatureException { // todo: add test assertion when the sign/verify part actually works. } + @Test // result is a point at infinity + public void testVerifySignature4() { + + byte[] hash = Hex.decode("acb1c19ac0832320815b5e886c6b73ad7d6177853d44b026f2a7a9e11bb899fc"); + byte[] r = Hex.decode("89ea49159b334f9aebbf54481b69d000d285baa341899db355a4030f6838394e"); + byte[] s = Hex.decode("540e9f9fa17bef441e32d98d5f4554cfefdc6a56101352e4b92efafd0d9646e8"); + byte v = (byte) 28; + + ECDSASignature sig = ECKey.ECDSASignature.fromComponents(r, s, v); + + try { + ECKey.signatureToKey(hash, sig); + fail("Result is a point at infinity, recovery must fail"); + } catch (SignatureException e) { + } + } @Test public void testSValue() throws Exception {