Add test coverage for java precompiles (#7446)

For tests that have a native/java switch ensure that the java path gets
the same tests native paths do.

Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: Danno Ferrin <danno@numisight.com>
This commit is contained in:
Danno Ferrin
2024-08-13 12:21:49 -06:00
committed by GitHub
parent 1a9154586f
commit a55c331e21
11 changed files with 123 additions and 51 deletions

View File

@@ -397,7 +397,9 @@ public abstract class AbstractSECP256 implements SignatureAlgorithm {
final Bytes32 dataHash, final SECPSignature signature) {
final BigInteger publicKeyBI =
recoverFromSignature(signature.getRecId(), signature.getR(), signature.getS(), dataHash);
return Optional.of(SECPPublicKey.create(publicKeyBI, ALGORITHM));
return publicKeyBI == null
? Optional.empty()
: Optional.of(SECPPublicKey.create(publicKeyBI, ALGORITHM));
}
@Override

View File

@@ -44,9 +44,10 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
/**
* Implementation of the `F` compression function of the Blake2b cryptographic hash function.
*
* <p>RFC - https://tools.ietf.org/html/rfc7693
* <p>RFC - <a href="https://tools.ietf.org/html/rfc7693">...</a>
*
* <p>Adapted from - https://github.com/keep-network/blake2b/blob/master/compression/f.go
* <p>Adapted from - <a
* href="https://github.com/keep-network/blake2b/blob/master/compression/f.go">...</a>
*
* <p>Optimized for 64-bit platforms
*/
@@ -93,12 +94,7 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
private static boolean useNative;
static {
try {
useNative = LibBlake2bf.ENABLED;
} catch (UnsatisfiedLinkError ule) {
LOG.info("blake2bf native precompile not available: {}", ule.getMessage());
useNative = false;
}
maybeEnableNative();
}
/** Instantiates a new Blake2bf digest. */
@@ -130,6 +126,21 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
return cloned;
}
/**
* Attempt to enable the native libreary
*
* @return true if the native library was successfully enabled.
*/
public static boolean maybeEnableNative() {
try {
useNative = LibBlake2bf.ENABLED;
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
LOG.info("blake2bf native precompile not available: {}", e.getMessage());
useNative = false;
}
return useNative;
}
/** Disable native. */
public static void disableNative() {
useNative = false;

View File

@@ -72,6 +72,7 @@ public class SECP256K1 extends AbstractSECP256 {
*
* @return true if the native library was enabled.
*/
@Override
public boolean maybeEnableNative() {
try {
useNative = LibSecp256k1.CONTEXT != null;

View File

@@ -61,6 +61,22 @@ public class SECP256R1 extends AbstractSECP256 {
return useNative;
}
/**
* Attempt to enable the native library for secp256r1
*
* @return true if the native library was enabled.
*/
@Override
public boolean maybeEnableNative() {
try {
useNative = BesuNativeEC.INSTANCE != null;
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
LOG.info("Native secp256r1 not available - {}", e.getMessage());
useNative = false;
}
return useNative;
}
/**
* SECP256R1 is using the non-deterministic implementation of K calculation (standard)
*

View File

@@ -31,6 +31,13 @@ public interface SignatureAlgorithm {
/** Disable native. */
void disableNative();
/**
* Attempt to enable the native library.
*
* @return true if the native library was enabled
*/
boolean maybeEnableNative();
/**
* Is native enabled.
*

View File

@@ -127,7 +127,7 @@ public class SECP256R1Test {
}
@Test
public void recoverPublicKeyFromSignature() {
void recoverPublicKeyFromSignature() {
final SECPPrivateKey privateKey =
secp256R1.createPrivateKey(
new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16));
@@ -139,20 +139,20 @@ public class SECP256R1Test {
final SECPPublicKey recoveredPublicKey =
secp256R1.recoverPublicKeyFromSignature(dataHash, signature).get();
assertThat(recoveredPublicKey.toString()).isEqualTo(keyPair.getPublicKey().toString());
assertThat(recoveredPublicKey).hasToString(keyPair.getPublicKey().toString());
}
@Test
public void signatureGenerationVerificationAndPubKeyRecovery() {
void signatureGenerationVerificationAndPubKeyRecovery() {
signTestVectors.forEach(
signTestVector -> {
final SECPPrivateKey privateKey =
secp256R1.createPrivateKey(new BigInteger(signTestVector.getPrivateKey(), 16));
final BigInteger publicKeyBigInt = new BigInteger(signTestVector.getPublicKey(), 16);
secp256R1.createPrivateKey(new BigInteger(signTestVector.privateKey(), 16));
final BigInteger publicKeyBigInt = new BigInteger(signTestVector.publicKey(), 16);
final SECPPublicKey publicKey = secp256R1.createPublicKey(publicKeyBigInt);
final KeyPair keyPair = secp256R1.createKeyPair(privateKey);
final Bytes32 dataHash = keccak256(Bytes.wrap(signTestVector.getData().getBytes(UTF_8)));
final Bytes32 dataHash = keccak256(Bytes.wrap(signTestVector.data().getBytes(UTF_8)));
final SECPSignature signature = secp256R1.sign(dataHash, keyPair);
assertThat(secp256R1.verify(dataHash, signature, publicKey)).isTrue();
@@ -165,44 +165,22 @@ public class SECP256R1Test {
}
@Test
public void invalidFileThrowsInvalidKeyPairException() throws Exception {
void invalidFileThrowsInvalidKeyPairException() throws Exception {
final File tempFile = Files.createTempFile(suiteName(), ".keypair").toFile();
tempFile.deleteOnExit();
Files.write(tempFile.toPath(), "not valid".getBytes(UTF_8));
Files.writeString(tempFile.toPath(), "not valid");
assertThatThrownBy(() -> KeyPairUtil.load(tempFile))
.isInstanceOf(IllegalArgumentException.class);
}
@Test
public void invalidMultiLineFileThrowsInvalidIdException() throws Exception {
void invalidMultiLineFileThrowsInvalidIdException() throws Exception {
final File tempFile = Files.createTempFile(suiteName(), ".keypair").toFile();
tempFile.deleteOnExit();
Files.write(tempFile.toPath(), "not\n\nvalid".getBytes(UTF_8));
Files.writeString(tempFile.toPath(), "not\n\nvalid");
assertThatThrownBy(() -> KeyPairUtil.load(tempFile))
.isInstanceOf(IllegalArgumentException.class);
}
private static class SignTestVector {
private final String privateKey;
private final String publicKey;
private final String data;
public SignTestVector(final String privateKey, final String publicKey, final String data) {
this.privateKey = privateKey;
this.publicKey = publicKey;
this.data = data;
}
public String getPrivateKey() {
return privateKey;
}
public String getPublicKey() {
return publicKey;
}
public String getData() {
return data;
}
}
private record SignTestVector(String privateKey, String publicKey, String data) {}
}