Skip to content

Commit

Permalink
Use Blake2bf native implementation if available by default (hyperledg…
Browse files Browse the repository at this point in the history
…er#4264)

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Co-authored-by: Antoine Toulme <antoine@lunar-ocean.com>
  • Loading branch information
fab-10 and atoulme authored Aug 23, 2022
1 parent 98e214c commit 465d7f2
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 9 additions & 0 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
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;
Expand Down Expand Up @@ -1718,6 +1719,14 @@ private void configureNativeLibs() {
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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -47,4 +56,8 @@ public Boolean getNativeSecp() {
public Boolean getNativeAltbn128() {
return nativeAltbn128;
}

public Boolean getNativeBlake2bf() {
return nativeBlake2bf;
}
}
1 change: 1 addition & 0 deletions crypto/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@

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());
Expand All @@ -37,7 +42,6 @@ public Blake2bfMessageDigest() {
* <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 = {
Expand Down Expand Up @@ -76,8 +80,13 @@ public static class Blake2bfDigest implements Digest {
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;

Expand All @@ -90,20 +99,12 @@ public static class Blake2bfDigest implements Digest {
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
Expand All @@ -123,16 +124,10 @@ public int getDigestSize() {
*/
@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();
}

/**
Expand All @@ -148,6 +143,15 @@ public void update(final byte[] in, final int offset, final int len) {
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 "
Expand All @@ -156,12 +160,10 @@ public void update(final byte[] in, final int offset, final int len) {
+ (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();
}
}
Expand All @@ -178,10 +180,13 @@ public int doFinal(final byte[] out, final int offset) {
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();
Expand All @@ -194,12 +199,14 @@ public int doFinal(final byte[] out, final int offset) {
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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
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
Expand Down Expand Up @@ -47,7 +49,7 @@ public class Blake2bfMessageDigestTest {
-61, 120, -93, -42, -38
};

@Before
@BeforeEach
public void setUp() {
messageDigest = new Blake2bfMessageDigest();
}
Expand Down Expand Up @@ -121,4 +123,24 @@ public void throwsIfEmptyBufferUpdatedLargeByteArray() {
})
.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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
input,expected
0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001,08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b
0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001,ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923
0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000,75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735
0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001,b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421
ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001,fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615
7 changes: 4 additions & 3 deletions gradle/versions.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down

0 comments on commit 465d7f2

Please sign in to comment.