Use Blake2bf native implementation if available by default (#4264)

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Co-authored-by: Antoine Toulme <antoine@lunar-ocean.com>
pull/4303/head
Fabio Di Fabio 2 years ago committed by GitHub
parent 98e214cedc
commit 465d7f24c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 9
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  3. 13
      besu/src/main/java/org/hyperledger/besu/cli/options/unstable/NativeLibraryOptions.java
  4. 1
      crypto/build.gradle
  5. 85
      crypto/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java
  6. 28
      crypto/src/test/java/org/hyperledger/besu/crypto/Blake2bfMessageDigestTest.java
  7. 6
      crypto/src/test/resources/org/hyperledger/besu/crypto/eip152TestCases.csv
  8. 7
      gradle/versions.gradle

@ -3,6 +3,7 @@
## 22.7.2
### Additions and Improvements
- Upgrade besu-native to 0.6.0 and use Blake2bf native implementation if available by default [#4264](https://github.com/hyperledger/besu/pull/4264)
### Bug Fixes

@ -92,6 +92,7 @@ import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration;
import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfigurationProvider;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.controller.BesuControllerBuilder;
import org.hyperledger.besu.crypto.Blake2bfMessageDigest;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.KeyPairSecurityModule;
import org.hyperledger.besu.crypto.KeyPairUtil;
@ -1718,6 +1719,14 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
SignatureAlgorithmFactory.getInstance().disableNative();
logger.info("Using the Java implementation of the signature algorithm");
}
if (unstableNativeLibraryOptions.getNativeBlake2bf()
&& Blake2bfMessageDigest.Blake2bfDigest.isNative()) {
logger.info("Using the native implementation of the blake2bf algorithm");
} else {
Blake2bfMessageDigest.Blake2bfDigest.disableNative();
logger.info("Using the Java implementation of the blake2bf algorithm");
}
}
private void validateOptions() {

@ -36,6 +36,15 @@ public class NativeLibraryOptions {
arity = "1")
private final Boolean nativeAltbn128 = Boolean.TRUE;
@CommandLine.Option(
hidden = true,
names = {"--Xblake2bf-native-enabled"},
description =
"Per default a native library is used for blake2bf if present. "
+ "If the Java implementation should be used instead, this option must be set to false",
arity = "1")
private final Boolean nativeBlake2bf = Boolean.TRUE;
public static NativeLibraryOptions create() {
return new NativeLibraryOptions();
}
@ -47,4 +56,8 @@ public class NativeLibraryOptions {
public Boolean getNativeAltbn128() {
return nativeAltbn128;
}
public Boolean getNativeBlake2bf() {
return nativeBlake2bf;
}
}

@ -38,6 +38,7 @@ dependencies {
implementation 'org.apache.tuweni:tuweni-units'
implementation 'org.hyperledger.besu:secp256k1'
implementation 'org.hyperledger.besu:secp256r1'
implementation 'org.hyperledger.besu:blake2bf'
testImplementation 'junit:junit'
testImplementation 'org.assertj:assertj-core'

@ -16,12 +16,17 @@ package org.hyperledger.besu.crypto;
import static java.util.Arrays.copyOfRange;
import org.hyperledger.besu.nativelib.blake2bf.LibBlake2bf;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.jcajce.provider.digest.BCMessageDigest;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Pack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable {
private static final Logger LOG = LoggerFactory.getLogger(Blake2bfMessageDigest.class);
public Blake2bfMessageDigest() {
super(new Blake2bfDigest());
@ -37,7 +42,6 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
* <p>Optimized for 64-bit platforms
*/
public static class Blake2bfDigest implements Digest {
public static final int MESSAGE_LENGTH_BYTES = 213;
private static final long[] IV = {
@ -76,8 +80,13 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
private long rounds; // unsigned integer represented as long
private final long[] v;
private static boolean useNative = LibBlake2bf.ENABLED;
Blake2bfDigest() {
if (!useNative) {
LOG.info("Native blake2bf not available");
}
buffer = new byte[MESSAGE_LENGTH_BYTES];
bufferPos = 0;
@ -90,20 +99,12 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
v = new long[16];
}
// for tests
Blake2bfDigest(
final long[] h, final long[] m, final long[] t, final boolean f, final long rounds) {
assert rounds <= 4294967295L; // uint max value
buffer = new byte[MESSAGE_LENGTH_BYTES];
bufferPos = 0;
this.h = h;
this.m = m;
this.t = t;
this.f = f;
this.rounds = rounds;
public static void disableNative() {
useNative = false;
}
v = new long[16];
public static boolean isNative() {
return useNative;
}
@Override
@ -123,16 +124,10 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
*/
@Override
public void update(final byte in) {
if (bufferPos == MESSAGE_LENGTH_BYTES) { // full buffer
throw new IllegalArgumentException();
} else {
buffer[bufferPos] = in;
bufferPos++;
if (bufferPos == MESSAGE_LENGTH_BYTES) {
initialize();
}
}
checkSize(1);
buffer[bufferPos] = in;
bufferPos++;
maybeInitialize();
}
/**
@ -148,6 +143,15 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
return;
}
checkSize(len);
System.arraycopy(in, offset, buffer, bufferPos, len);
bufferPos += len;
maybeInitialize();
}
private void checkSize(final int len) {
if (len > MESSAGE_LENGTH_BYTES - bufferPos) {
throw new IllegalArgumentException(
"Attempting to update buffer with "
@ -156,12 +160,10 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
+ (MESSAGE_LENGTH_BYTES - bufferPos)
+ " byte(s) left to fill");
}
}
System.arraycopy(in, offset, buffer, bufferPos, len);
bufferPos += len;
if (bufferPos == MESSAGE_LENGTH_BYTES) {
private void maybeInitialize() {
if (!useNative && bufferPos == MESSAGE_LENGTH_BYTES) {
initialize();
}
}
@ -178,10 +180,13 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
throw new IllegalStateException("The buffer must be filled with 213 bytes");
}
compress();
for (int i = 0; i < h.length; i++) {
System.arraycopy(Pack.longToLittleEndian(h[i]), 0, out, i * 8, 8);
if (useNative) {
LibBlake2bf.blake2bf_eip152(out, buffer);
} else {
compress();
for (int i = 0; i < h.length; i++) {
System.arraycopy(Pack.longToLittleEndian(h[i]), 0, out, i * 8, 8);
}
}
reset();
@ -194,12 +199,14 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
public void reset() {
bufferPos = 0;
Arrays.fill(buffer, (byte) 0);
Arrays.fill(h, 0);
Arrays.fill(m, (byte) 0);
Arrays.fill(t, 0);
f = false;
rounds = 12;
Arrays.fill(v, 0);
if (!useNative) {
Arrays.fill(h, 0);
Arrays.fill(m, (byte) 0);
Arrays.fill(t, 0);
f = false;
rounds = 12;
Arrays.fill(v, 0);
}
}
private void initialize() {

@ -18,8 +18,10 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import org.bouncycastle.util.Pack;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
/**
* Test vectors adapted from
@ -47,7 +49,7 @@ public class Blake2bfMessageDigestTest {
-61, 120, -93, -42, -38
};
@Before
@BeforeEach
public void setUp() {
messageDigest = new Blake2bfMessageDigest();
}
@ -121,4 +123,24 @@ public class Blake2bfMessageDigestTest {
})
.isInstanceOf(IllegalArgumentException.class);
}
@ParameterizedTest
@CsvFileSource(resources = "eip152TestCases.csv", numLinesToSkip = 1)
public void eip152TestCases(final String hexIn, final String hexExpected) {
System.out.println("in=" + hexIn);
byte[] in = hexStringToByteArray(hexIn);
byte[] expected = hexStringToByteArray(hexExpected);
messageDigest.update(in, 0, 213);
assertThat(messageDigest.digest()).isEqualTo(expected);
}
private static byte[] hexStringToByteArray(final String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] =
(byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}

@ -0,0 +1,6 @@
input,expected
0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001,08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b
0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001,ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923
0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000,75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735
0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001,b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421
ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001,fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615
1 input expected
2 0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001 08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b
3 0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001 ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923
4 0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000 75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735
5 0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001 b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421
6 ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001 fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615

@ -147,9 +147,10 @@ dependencyManagement {
dependency 'org.fusesource.jansi:jansi:2.4.0'
dependency 'org.hyperledger.besu:bls12-381:0.5.0'
dependency 'org.hyperledger.besu:secp256k1:0.5.0'
dependency 'org.hyperledger.besu:secp256r1:0.5.0'
dependency 'org.hyperledger.besu:bls12-381:0.6.0'
dependency 'org.hyperledger.besu:secp256k1:0.6.0'
dependency 'org.hyperledger.besu:secp256r1:0.6.0'
dependency 'org.hyperledger.besu:blake2bf:0.6.0'
dependency 'org.immutables:value-annotations:2.9.0'
dependency 'org.immutables:value:2.9.0'

Loading…
Cancel
Save