From 0353a6f3d392b880aa33fdc1e7899ae5c60a63aa Mon Sep 17 00:00:00 2001 From: Miguel Angel Rojo Date: Wed, 26 Jan 2022 12:12:07 +0000 Subject: [PATCH] Padding of the R and S components in case they are smaller than 31 bytes for SECP256r1 (#52) * code modified to allow 30 bytes signature and test added Signed-off-by: Miguel Rojo --- .../nativelib/secp256r1/LibSECP256R1.java | 8 ++++---- .../nativelib/secp256r1/LibSECP256R1Test.java | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/secp256r1/src/main/java/org/hyperledger/besu/nativelib/secp256r1/LibSECP256R1.java b/secp256r1/src/main/java/org/hyperledger/besu/nativelib/secp256r1/LibSECP256R1.java index 0c9c5b9d..12da6462 100644 --- a/secp256r1/src/main/java/org/hyperledger/besu/nativelib/secp256r1/LibSECP256R1.java +++ b/secp256r1/src/main/java/org/hyperledger/besu/nativelib/secp256r1/LibSECP256R1.java @@ -113,13 +113,13 @@ private byte[] convertToNativeRepresentation(final byte[] signature) { return nativeSignature; } - // the first byte in the native representation was 0, but in the Java representation this is ignored. + // the first bytes in the native representation were 0, but in the Java representation this is ignored. // the signature needs to be shifted to the right for the native representation - if (signature.length == CURVE_BYTE_LENGTH - 1) { + if (signature.length < CURVE_BYTE_LENGTH) { byte[] nativeSignature = new byte[CURVE_BYTE_LENGTH]; - // copy signature to nativeSignature, shifting it one to the right - System.arraycopy(signature, 0, nativeSignature, 1, signature.length); + // copy signature to nativeSignature, shifting it to the right + System.arraycopy(signature, 0, nativeSignature, CURVE_BYTE_LENGTH - signature.length, signature.length); return nativeSignature; } diff --git a/secp256r1/src/test/java/org/hyperledger/besu/nativelib/secp256r1/LibSECP256R1Test.java b/secp256r1/src/test/java/org/hyperledger/besu/nativelib/secp256r1/LibSECP256R1Test.java index c9a95e6f..48932089 100644 --- a/secp256r1/src/test/java/org/hyperledger/besu/nativelib/secp256r1/LibSECP256R1Test.java +++ b/secp256r1/src/test/java/org/hyperledger/besu/nativelib/secp256r1/LibSECP256R1Test.java @@ -16,9 +16,11 @@ package org.hyperledger.besu.nativelib.secp256r1; import org.apache.tuweni.bytes.Bytes; +import org.assertj.core.util.Hexadecimals; import org.junit.Before; import org.junit.Test; +import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -93,6 +95,24 @@ public void keyRecovery_should_return_expected_public_key() { } + @Test + public void keyRecovery_should_return_expected_public_key_if_r_is_less_than_32_bytes_long() { + final BigInteger r = new BigInteger("607232317131644998607993399928086035368869502933999419429470745918733484"); + final BigInteger s = new BigInteger("909326537358980219114547956988636184748037502936154044628658501523731230682"); + final byte v = (byte) 1; + final Bytes dataHash = Bytes.fromHexString("0x5d2a686cbe81873192db62f069cc1f0c10a1580c89d19c21407dcd1cde48ad06"); + + + byte[] actualPublicKey = libSecp256r1.keyRecovery( + dataHash.toArrayUnsafe(), + r.toByteArray(), + s.toByteArray(), + v + ); + + assertThat(Hexadecimals.toHexString(actualPublicKey)).isEqualTo("33F004F357282E13036385D3F52A90F5E62FA0D51C39DFF99CB72FD06CB5FAB72F2DC5E05786154DD7A349DC3FDD9BE2F0B9665C4E08FA6CDC1FD447112ACF3F"); + } + @Test(expected = IllegalArgumentException.class) public void keyRecovery_should_throw_exception_if_parameter_is_invalid() { libSecp256r1.keyRecovery(