Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Blake2bf native implementation if available by default #4264

Merged
merged 5 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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