mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 23:47:57 -05:00
Replacing the static references of SECP256K1 by an interface (#1933)
* Replacing the static references of SECP256K1 by an interface Signed-off-by: Daniel Lehrner <daniel@io.builders>
This commit is contained in:
@@ -14,9 +14,11 @@
|
||||
*/
|
||||
package org.hyperledger.besu.tests.acceptance.dsl.account;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.PrivateKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.PublicKey;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPPrivateKey;
|
||||
import org.hyperledger.besu.crypto.SECPPublicKey;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.tests.acceptance.dsl.blockchain.Amount;
|
||||
@@ -30,6 +32,8 @@ import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.web3j.crypto.Credentials;
|
||||
import org.web3j.utils.Convert.Unit;
|
||||
@@ -38,11 +42,14 @@ public class Account {
|
||||
|
||||
private final EthTransactions eth;
|
||||
private final String name;
|
||||
private final Optional<PrivateKey> privateKey;
|
||||
private final Optional<PublicKey> publicKey;
|
||||
private final Optional<SECPPrivateKey> privateKey;
|
||||
private final Optional<SECPPublicKey> publicKey;
|
||||
private final Address address;
|
||||
private long nonce = 0;
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
private Account(
|
||||
final EthTransactions eth,
|
||||
final String name,
|
||||
@@ -68,13 +75,18 @@ public class Account {
|
||||
}
|
||||
|
||||
public static Account create(final EthTransactions eth, final String name) {
|
||||
return new Account(eth, name, KeyPair.generate());
|
||||
return new Account(eth, name, SIGNATURE_ALGORITHM.get().generateKeyPair());
|
||||
}
|
||||
|
||||
static Account fromPrivateKey(
|
||||
final EthTransactions eth, final String name, final String privateKey) {
|
||||
return new Account(
|
||||
eth, name, KeyPair.create(PrivateKey.create(Bytes32.fromHexString(privateKey))));
|
||||
eth,
|
||||
name,
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createKeyPair(
|
||||
SIGNATURE_ALGORITHM.get().createPrivateKey(Bytes32.fromHexString(privateKey))));
|
||||
}
|
||||
|
||||
public Optional<Credentials> web3jCredentials() {
|
||||
|
||||
@@ -18,8 +18,8 @@ import static java.util.Collections.unmodifiableList;
|
||||
import static org.apache.logging.log4j.LogManager.getLogger;
|
||||
import static org.apache.tuweni.io.file.Files.copyResource;
|
||||
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPairUtil;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
|
||||
@@ -23,7 +23,9 @@ import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.hyperledger.besu.ethereum.core.Address.DEFAULT_PRIVACY;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.enclave.types.PrivacyGroup;
|
||||
import org.hyperledger.besu.enclave.types.ReceiveResponse;
|
||||
import org.hyperledger.besu.enclave.types.SendResponse;
|
||||
@@ -45,6 +47,8 @@ import java.util.List;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.tomakehurst.wiremock.junit.WireMockRule;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.io.Base64;
|
||||
import org.junit.After;
|
||||
@@ -57,11 +61,17 @@ public class MultiTenancyAcceptanceTest extends AcceptanceTestBase {
|
||||
private final ObjectMapper mapper = new ObjectMapper();
|
||||
private Cluster multiTenancyCluster;
|
||||
|
||||
private static final SECP256K1.KeyPair TEST_KEY =
|
||||
SECP256K1.KeyPair.create(
|
||||
SECP256K1.PrivateKey.create(
|
||||
new BigInteger(
|
||||
"853d7f0010fd86d0d7811c1f9d968ea89a24484a8127b4a483ddf5d2cfec766d", 16)));
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
private static final KeyPair TEST_KEY =
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createKeyPair(
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createPrivateKey(
|
||||
new BigInteger(
|
||||
"853d7f0010fd86d0d7811c1f9d968ea89a24484a8127b4a483ddf5d2cfec766d", 16)));
|
||||
private static final String PRIVACY_GROUP_ID = "B1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
|
||||
private static final String PARTICIPANT_ENCLAVE_KEY0 =
|
||||
"A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
|
||||
|
||||
@@ -24,7 +24,8 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRp
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.GET_PRIVATE_TRANSACTION_NONCE_ERROR;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.PRIVATE_FROM_DOES_NOT_MATCH_ENCLAVE_PUBLIC_KEY;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.enclave.types.PrivacyGroup;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
@@ -204,6 +205,9 @@ public class MultiTenancyValidationFailAcceptanceTest extends AcceptanceTestBase
|
||||
|
||||
private static PrivateTransaction getValidSignedPrivateTransaction(
|
||||
final Address senderAddress, final String privateFrom) {
|
||||
|
||||
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||||
|
||||
return PrivateTransaction.builder()
|
||||
.nonce(0)
|
||||
.gasPrice(Wei.ZERO)
|
||||
@@ -217,8 +221,8 @@ public class MultiTenancyValidationFailAcceptanceTest extends AcceptanceTestBase
|
||||
.restriction(Restriction.RESTRICTED)
|
||||
.privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID))
|
||||
.signAndBuild(
|
||||
SECP256K1.KeyPair.create(
|
||||
SECP256K1.PrivateKey.create(
|
||||
signatureAlgorithm.createKeyPair(
|
||||
signatureAlgorithm.createPrivateKey(
|
||||
new BigInteger(
|
||||
"853d7f0010fd86d0d7811c1f9d968ea89a24484a8127b4a483ddf5d2cfec766d", 16))));
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
*/
|
||||
package org.hyperledger.besu.chainimport.internal;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.PrivateKey;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPPrivateKey;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.Wei;
|
||||
@@ -25,6 +27,8 @@ import java.util.Optional;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
@@ -37,7 +41,10 @@ public class TransactionData {
|
||||
private final Bytes data;
|
||||
private final Wei value;
|
||||
private final Optional<Address> to;
|
||||
private final PrivateKey privateKey;
|
||||
private final SECPPrivateKey privateKey;
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
@JsonCreator
|
||||
public TransactionData(
|
||||
@@ -52,11 +59,11 @@ public class TransactionData {
|
||||
this.data = data.map(Bytes::fromHexString).orElse(Bytes.EMPTY);
|
||||
this.value = value.map(Wei::fromHexString).orElse(Wei.ZERO);
|
||||
this.to = to.map(Address::fromHexString);
|
||||
this.privateKey = PrivateKey.create(Bytes32.fromHexString(secretKey));
|
||||
this.privateKey = SIGNATURE_ALGORITHM.get().createPrivateKey(Bytes32.fromHexString(secretKey));
|
||||
}
|
||||
|
||||
public Transaction getSignedTransaction(final NonceProvider nonceProvider) {
|
||||
final KeyPair keyPair = KeyPair.create(privateKey);
|
||||
final KeyPair keyPair = SIGNATURE_ALGORITHM.get().createKeyPair(privateKey);
|
||||
|
||||
final Address fromAddress = Address.extract(keyPair.getPublicKey());
|
||||
final long nonce = nonceProvider.get(fromAddress);
|
||||
|
||||
@@ -80,10 +80,11 @@ import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.controller.BesuControllerBuilder;
|
||||
import org.hyperledger.besu.controller.TargetingGasLimitCalculator;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPairSecurityModule;
|
||||
import org.hyperledger.besu.crypto.KeyPairUtil;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.enclave.EnclaveFactory;
|
||||
import org.hyperledger.besu.enclave.GoQuorumEnclave;
|
||||
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
|
||||
@@ -1274,7 +1275,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
SECP256K1.KeyPair loadKeyPair() {
|
||||
KeyPair loadKeyPair() {
|
||||
return KeyPairUtil.loadKeyPair(nodePrivateKeyFile());
|
||||
}
|
||||
|
||||
@@ -1370,7 +1371,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
AbstractAltBnPrecompiledContract.enableNative();
|
||||
}
|
||||
if (unstableNativeLibraryOptions.getNativeSecp256k1()) {
|
||||
SECP256K1.enableNative();
|
||||
SignatureAlgorithmFactory.getInstance().enableNative();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,11 @@ import org.hyperledger.besu.cli.DefaultCommandValues;
|
||||
import org.hyperledger.besu.config.JsonGenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.JsonUtil;
|
||||
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPPrivateKey;
|
||||
import org.hyperledger.besu.crypto.SECPPublicKey;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
|
||||
@@ -39,6 +43,8 @@ import java.util.stream.IntStream;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeType;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.io.Resources;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -54,6 +60,9 @@ import picocli.CommandLine.ParentCommand;
|
||||
class GenerateBlockchainConfig implements Runnable {
|
||||
private static final Logger LOG = LogManager.getLogger();
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
@Option(
|
||||
required = true,
|
||||
names = "--config-file",
|
||||
@@ -156,8 +165,8 @@ class GenerateBlockchainConfig implements Runnable {
|
||||
final String publicKeyText = publicKeyJson.asText();
|
||||
|
||||
try {
|
||||
final SECP256K1.PublicKey publicKey =
|
||||
SECP256K1.PublicKey.create(Bytes.fromHexString(publicKeyText));
|
||||
final SECPPublicKey publicKey =
|
||||
SIGNATURE_ALGORITHM.get().createPublicKey(Bytes.fromHexString(publicKeyText));
|
||||
writeKeypair(publicKey, null);
|
||||
LOG.info("Public key imported from configuration.({})", publicKey.toString());
|
||||
} catch (final IOException e) {
|
||||
@@ -180,7 +189,7 @@ class GenerateBlockchainConfig implements Runnable {
|
||||
private void generateNodeKeypair(final int node) {
|
||||
try {
|
||||
LOG.info("Generating keypair for node {}.", node);
|
||||
final SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.generate();
|
||||
final KeyPair keyPair = SIGNATURE_ALGORITHM.get().generateKeyPair();
|
||||
writeKeypair(keyPair.getPublicKey(), keyPair.getPrivateKey());
|
||||
|
||||
} catch (final IOException e) {
|
||||
@@ -196,8 +205,7 @@ class GenerateBlockchainConfig implements Runnable {
|
||||
* @param privateKey The private key. No file is created if privateKey is NULL.
|
||||
* @throws IOException If the file cannot be written or accessed.
|
||||
*/
|
||||
private void writeKeypair(
|
||||
final SECP256K1.PublicKey publicKey, final SECP256K1.PrivateKey privateKey)
|
||||
private void writeKeypair(final SECPPublicKey publicKey, final SECPPrivateKey privateKey)
|
||||
throws IOException {
|
||||
final Address nodeAddress = Util.publicKeyToAddress(publicKey);
|
||||
addressesForGenesisExtraData.add(nodeAddress);
|
||||
|
||||
@@ -22,8 +22,10 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.enclave.Enclave;
|
||||
import org.hyperledger.besu.enclave.EnclaveFactory;
|
||||
import org.hyperledger.besu.enclave.types.PrivacyGroup;
|
||||
@@ -71,6 +73,8 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import io.vertx.core.Vertx;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
@@ -83,11 +87,18 @@ import org.junit.rules.TemporaryFolder;
|
||||
public class PrivacyReorgTest {
|
||||
@Rule public final TemporaryFolder folder = new TemporaryFolder();
|
||||
|
||||
private static final SECP256K1.KeyPair KEY_PAIR =
|
||||
SECP256K1.KeyPair.create(
|
||||
SECP256K1.PrivateKey.create(
|
||||
new BigInteger(
|
||||
"8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16)));
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
private static final KeyPair KEY_PAIR =
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createKeyPair(
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createPrivateKey(
|
||||
new BigInteger(
|
||||
"8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16)));
|
||||
private static final Bytes ENCLAVE_PUBLIC_KEY =
|
||||
Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=");
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.hyperledger.besu.consensus.common.bft.protocol.BftProtocolManager;
|
||||
import org.hyperledger.besu.consensus.ibft.protocol.IbftSubProtocol;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SECPPublicKey;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
|
||||
@@ -72,7 +72,7 @@ public final class RunnerBuilderTest {
|
||||
final EthContext ethContext = mock(EthContext.class);
|
||||
final ProtocolContext protocolContext = mock(ProtocolContext.class);
|
||||
final NodeKey nodeKey = mock(NodeKey.class);
|
||||
final SECP256K1.PublicKey publicKey = mock(SECP256K1.PublicKey.class);
|
||||
final SECPPublicKey publicKey = mock(SECPPublicKey.class);
|
||||
|
||||
when(subProtocolConfiguration.getProtocolManagers())
|
||||
.thenReturn(
|
||||
|
||||
@@ -40,8 +40,10 @@ import org.hyperledger.besu.cli.options.unstable.TransactionPoolOptions;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.controller.BesuControllerBuilder;
|
||||
import org.hyperledger.besu.controller.NoopPluginServiceFactory;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
|
||||
@@ -116,7 +118,7 @@ public abstract class CommandTestAbstract {
|
||||
private final HashMap<String, String> environment = new HashMap<>();
|
||||
|
||||
private final List<TestBesuCommand> besuCommands = new ArrayList<>();
|
||||
private SECP256K1.KeyPair keyPair;
|
||||
private KeyPair keyPair;
|
||||
|
||||
@Mock protected RunnerBuilder mockRunnerBuilder;
|
||||
@Mock protected Runner mockRunner;
|
||||
@@ -241,9 +243,11 @@ public abstract class CommandTestAbstract {
|
||||
when(mockRunnerBuilder.forkIdSupplier(any())).thenReturn(mockRunnerBuilder);
|
||||
when(mockRunnerBuilder.build()).thenReturn(mockRunner);
|
||||
|
||||
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||||
|
||||
final Bytes32 keyPairPrvKey =
|
||||
Bytes32.fromHexString("0xf7a58d5e755d51fa2f6206e91dd574597c73248aaf946ec1964b8c6268d6207b");
|
||||
keyPair = SECP256K1.KeyPair.create(SECP256K1.PrivateKey.create(keyPairPrvKey));
|
||||
keyPair = signatureAlgorithm.createKeyPair(signatureAlgorithm.createPrivateKey(keyPairPrvKey));
|
||||
|
||||
lenient().when(nodeKey.getPublicKey()).thenReturn(keyPair.getPublicKey());
|
||||
|
||||
@@ -332,12 +336,12 @@ public abstract class CommandTestAbstract {
|
||||
@CommandLine.Spec CommandLine.Model.CommandSpec spec;
|
||||
private Vertx vertx;
|
||||
private final NodeKey mockNodeKey;
|
||||
private final SECP256K1.KeyPair keyPair;
|
||||
private final KeyPair keyPair;
|
||||
|
||||
TestBesuCommand(
|
||||
final Logger mockLogger,
|
||||
final NodeKey mockNodeKey,
|
||||
final SECP256K1.KeyPair keyPair,
|
||||
final KeyPair keyPair,
|
||||
final Supplier<RlpBlockImporter> mockBlockImporter,
|
||||
final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory,
|
||||
final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory,
|
||||
@@ -380,7 +384,7 @@ public abstract class CommandTestAbstract {
|
||||
}
|
||||
|
||||
@Override
|
||||
SECP256K1.KeyPair loadKeyPair() {
|
||||
KeyPair loadKeyPair() {
|
||||
// for testing.
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
@@ -68,6 +70,8 @@ import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -78,7 +82,9 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class BesuEventsImplTest {
|
||||
|
||||
private static final KeyPair KEY_PAIR1 = KeyPair.generate();
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
private static final KeyPair KEY_PAIR1 = SIGNATURE_ALGORITHM.get().generateKeyPair();
|
||||
private static final org.hyperledger.besu.ethereum.core.Transaction TX1 = createTransaction(1);
|
||||
private static final org.hyperledger.besu.ethereum.core.Transaction TX2 = createTransaction(2);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.consensus.clique;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
@@ -69,7 +69,7 @@ public class CliqueBlockHashing {
|
||||
private static Bytes encodeExtraDataWithoutProposerSeal(final CliqueExtraData cliqueExtraData) {
|
||||
final Bytes extraDataBytes = cliqueExtraData.encode();
|
||||
// Always trim off final 65 bytes (which maybe zeros)
|
||||
return extraDataBytes.slice(0, extraDataBytes.size() - Signature.BYTES_REQUIRED);
|
||||
return extraDataBytes.slice(0, extraDataBytes.size() - SECPSignature.BYTES_REQUIRED);
|
||||
}
|
||||
|
||||
private static Bytes serializeHeader(
|
||||
|
||||
@@ -17,7 +17,8 @@ package org.hyperledger.besu.consensus.clique;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.ParsedExtraData;
|
||||
@@ -42,12 +43,12 @@ public class CliqueExtraData implements ParsedExtraData {
|
||||
|
||||
private final Bytes vanityData;
|
||||
private final List<Address> validators;
|
||||
private final Optional<Signature> proposerSeal;
|
||||
private final Optional<SECPSignature> proposerSeal;
|
||||
private final Supplier<Address> proposerAddress;
|
||||
|
||||
public CliqueExtraData(
|
||||
final Bytes vanityData,
|
||||
final Signature proposerSeal,
|
||||
final SECPSignature proposerSeal,
|
||||
final List<Address> validators,
|
||||
final BlockHeader header) {
|
||||
|
||||
@@ -81,12 +82,13 @@ public class CliqueExtraData implements ParsedExtraData {
|
||||
|
||||
static CliqueExtraData decodeRaw(final BlockHeader header) {
|
||||
final Bytes input = header.getExtraData();
|
||||
if (input.size() < EXTRA_VANITY_LENGTH + Signature.BYTES_REQUIRED) {
|
||||
if (input.size() < EXTRA_VANITY_LENGTH + SECPSignature.BYTES_REQUIRED) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Bytes supplied - too short to produce a valid Clique Extra Data object.");
|
||||
}
|
||||
|
||||
final int validatorByteCount = input.size() - EXTRA_VANITY_LENGTH - Signature.BYTES_REQUIRED;
|
||||
final int validatorByteCount =
|
||||
input.size() - EXTRA_VANITY_LENGTH - SECPSignature.BYTES_REQUIRED;
|
||||
if ((validatorByteCount % Address.SIZE) != 0) {
|
||||
throw new IllegalArgumentException("Bytes is of invalid size - i.e. contains unused bytes.");
|
||||
}
|
||||
@@ -95,8 +97,8 @@ public class CliqueExtraData implements ParsedExtraData {
|
||||
final List<Address> validators =
|
||||
extractValidators(input.slice(EXTRA_VANITY_LENGTH, validatorByteCount));
|
||||
|
||||
final int proposerSealStartIndex = input.size() - Signature.BYTES_REQUIRED;
|
||||
final Signature proposerSeal = parseProposerSeal(input.slice(proposerSealStartIndex));
|
||||
final int proposerSealStartIndex = input.size() - SECPSignature.BYTES_REQUIRED;
|
||||
final SECPSignature proposerSeal = parseProposerSeal(input.slice(proposerSealStartIndex));
|
||||
|
||||
return new CliqueExtraData(vanityData, proposerSeal, validators, header);
|
||||
}
|
||||
@@ -105,8 +107,10 @@ public class CliqueExtraData implements ParsedExtraData {
|
||||
return proposerAddress.get();
|
||||
}
|
||||
|
||||
private static Signature parseProposerSeal(final Bytes proposerSealRaw) {
|
||||
return proposerSealRaw.isZero() ? null : Signature.decode(proposerSealRaw);
|
||||
private static SECPSignature parseProposerSeal(final Bytes proposerSealRaw) {
|
||||
return proposerSealRaw.isZero()
|
||||
? null
|
||||
: SignatureAlgorithmFactory.getInstance().decodeSignature(proposerSealRaw);
|
||||
}
|
||||
|
||||
private static List<Address> extractValidators(final Bytes validatorsRaw) {
|
||||
@@ -130,21 +134,21 @@ public class CliqueExtraData implements ParsedExtraData {
|
||||
private static Bytes encode(
|
||||
final Bytes vanityData,
|
||||
final List<Address> validators,
|
||||
final Optional<Signature> proposerSeal) {
|
||||
final Optional<SECPSignature> proposerSeal) {
|
||||
final Bytes validatorData = Bytes.concatenate(validators.toArray(new Bytes[0]));
|
||||
return Bytes.concatenate(
|
||||
vanityData,
|
||||
validatorData,
|
||||
proposerSeal
|
||||
.map(Signature::encodedBytes)
|
||||
.orElse(Bytes.wrap(new byte[Signature.BYTES_REQUIRED])));
|
||||
.map(SECPSignature::encodedBytes)
|
||||
.orElse(Bytes.wrap(new byte[SECPSignature.BYTES_REQUIRED])));
|
||||
}
|
||||
|
||||
public Bytes getVanityData() {
|
||||
return vanityData;
|
||||
}
|
||||
|
||||
public Optional<Signature> getProposerSeal() {
|
||||
public Optional<SECPSignature> getProposerSeal() {
|
||||
return proposerSeal;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ import static org.hyperledger.besu.consensus.common.VoteType.ADD;
|
||||
import static org.hyperledger.besu.consensus.common.VoteType.DROP;
|
||||
|
||||
import org.hyperledger.besu.consensus.common.ValidatorVote;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
@@ -36,7 +37,8 @@ import org.junit.Test;
|
||||
|
||||
public class CliqueBlockInterfaceTest {
|
||||
|
||||
private static final KeyPair proposerKeys = KeyPair.generate();
|
||||
private static final KeyPair proposerKeys =
|
||||
SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private static final Address proposerAddress =
|
||||
Util.publicKeyToAddress(proposerKeys.getPublicKey());
|
||||
private static final List<Address> validatorList = singletonList(proposerAddress);
|
||||
|
||||
@@ -22,7 +22,8 @@ import static org.mockito.Mockito.when;
|
||||
import org.hyperledger.besu.consensus.common.VoteProposer;
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
@@ -39,7 +40,7 @@ import org.junit.Test;
|
||||
|
||||
public class CliqueDifficultyCalculatorTest {
|
||||
|
||||
private final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
private final KeyPair proposerKeyPair = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private Address localAddr;
|
||||
|
||||
private final List<Address> validatorList = Lists.newArrayList();
|
||||
|
||||
@@ -17,8 +17,10 @@ package org.hyperledger.besu.consensus.clique;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
@@ -30,6 +32,8 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
@@ -37,9 +41,13 @@ import org.junit.Test;
|
||||
|
||||
public class CliqueExtraDataTest {
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
@Test
|
||||
public void encodeAndDecodingDoNotAlterData() {
|
||||
final Signature proposerSeal = Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final SECPSignature proposerSeal =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final List<Address> validators =
|
||||
Arrays.asList(
|
||||
AddressHelpers.ofValue(1), AddressHelpers.ofValue(2), AddressHelpers.ofValue(3));
|
||||
@@ -82,7 +90,8 @@ public class CliqueExtraDataTest {
|
||||
@Test
|
||||
public void insufficientDataResultsInAnIllegalArgumentException() {
|
||||
final Bytes illegalData =
|
||||
Bytes.wrap(new byte[Signature.BYTES_REQUIRED + CliqueExtraData.EXTRA_VANITY_LENGTH - 1]);
|
||||
Bytes.wrap(
|
||||
new byte[SECPSignature.BYTES_REQUIRED + CliqueExtraData.EXTRA_VANITY_LENGTH - 1]);
|
||||
|
||||
assertThatThrownBy(() -> CliqueExtraData.decodeRaw(createHeaderWithExtraData(illegalData)))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
@@ -95,7 +104,7 @@ public class CliqueExtraDataTest {
|
||||
final Bytes illegalData =
|
||||
Bytes.wrap(
|
||||
new byte
|
||||
[Signature.BYTES_REQUIRED
|
||||
[SECPSignature.BYTES_REQUIRED
|
||||
+ CliqueExtraData.EXTRA_VANITY_LENGTH
|
||||
+ Address.SIZE
|
||||
- 1]);
|
||||
@@ -109,7 +118,7 @@ public class CliqueExtraDataTest {
|
||||
public void addressToExtraDataString() {
|
||||
final List<KeyPair> nodeKeys = Lists.newArrayList();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
nodeKeys.add(KeyPair.generate());
|
||||
nodeKeys.add(SIGNATURE_ALGORITHM.get().generateKeyPair());
|
||||
}
|
||||
|
||||
final List<Address> addresses =
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.hyperledger.besu.consensus.clique.headervalidationrules.SignerRateLim
|
||||
import org.hyperledger.besu.consensus.common.VoteProposer;
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
@@ -45,9 +46,10 @@ import org.junit.Test;
|
||||
|
||||
public class NodeCanProduceNextBlockTest {
|
||||
|
||||
private final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
private final KeyPair proposerKeyPair = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private Address localAddress;
|
||||
private final KeyPair otherNodeKeyPair = KeyPair.generate();
|
||||
private final KeyPair otherNodeKeyPair =
|
||||
SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private final List<Address> validatorList = Lists.newArrayList();
|
||||
private final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture();
|
||||
private ProtocolContext cliqueProtocolContext;
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
*/
|
||||
package org.hyperledger.besu.consensus.clique;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
@@ -43,7 +43,8 @@ public class TestHelpers {
|
||||
final Hash signingHash =
|
||||
CliqueBlockHashing.calculateDataHashForProposerSeal(unsealedHeader, unsignedExtraData);
|
||||
|
||||
final Signature proposerSignature = SECP256K1.sign(signingHash, signer);
|
||||
final SECPSignature proposerSignature =
|
||||
SignatureAlgorithmFactory.getInstance().sign(signingHash, signer);
|
||||
|
||||
final Bytes signedExtraData =
|
||||
new CliqueExtraData(
|
||||
|
||||
@@ -32,9 +32,10 @@ import org.hyperledger.besu.consensus.common.EpochManager;
|
||||
import org.hyperledger.besu.consensus.common.VoteProposer;
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.GenesisState;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
@@ -65,7 +66,7 @@ public class CliqueBlockCreatorTest {
|
||||
|
||||
private final NodeKey proposerNodeKey = NodeKeyUtils.generate();
|
||||
private final Address proposerAddress = Util.publicKeyToAddress(proposerNodeKey.getPublicKey());
|
||||
private final KeyPair otherKeyPair = KeyPair.generate();
|
||||
private final KeyPair otherKeyPair = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private final List<Address> validatorList = Lists.newArrayList();
|
||||
private final MetricsSystem metricsSystem = new NoOpMetricsSystem();
|
||||
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();
|
||||
|
||||
@@ -21,7 +21,8 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.blockcreation.AbstractBlockScheduler.BlockCreationTimeResult;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
@@ -38,7 +39,7 @@ import org.junit.Test;
|
||||
|
||||
public class CliqueBlockSchedulerTest {
|
||||
|
||||
private final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
private final KeyPair proposerKeyPair = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private Address localAddr;
|
||||
|
||||
private final List<Address> validatorList = Lists.newArrayList();
|
||||
|
||||
@@ -30,7 +30,9 @@ import org.hyperledger.besu.consensus.clique.CliqueMiningTracker;
|
||||
import org.hyperledger.besu.consensus.clique.TestHelpers;
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
@@ -45,6 +47,8 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -56,8 +60,11 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CliqueMiningCoordinatorTest {
|
||||
|
||||
private final KeyPair proposerKeys = KeyPair.generate();
|
||||
private final KeyPair validatorKeys = KeyPair.generate();
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
private final KeyPair proposerKeys = SIGNATURE_ALGORITHM.get().generateKeyPair();
|
||||
private final KeyPair validatorKeys = SIGNATURE_ALGORITHM.get().generateKeyPair();
|
||||
private final Address proposerAddress = Util.publicKeyToAddress(proposerKeys.getPublicKey());
|
||||
private final Address validatorAddress = Util.publicKeyToAddress(validatorKeys.getPublicKey());
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.hyperledger.besu.consensus.clique.TestHelpers;
|
||||
import org.hyperledger.besu.consensus.common.VoteProposer;
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
@@ -42,7 +43,7 @@ import org.junit.Test;
|
||||
|
||||
public class CliqueDifficultyValidationRuleTest {
|
||||
|
||||
private final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
private final KeyPair proposerKeyPair = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private final List<Address> validatorList = Lists.newArrayList();
|
||||
private ProtocolContext cliqueProtocolContext;
|
||||
private BlockHeaderTestFixture blockHeaderBuilder;
|
||||
|
||||
@@ -26,7 +26,8 @@ import org.hyperledger.besu.consensus.clique.TestHelpers;
|
||||
import org.hyperledger.besu.consensus.common.EpochManager;
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
@@ -43,7 +44,7 @@ import org.junit.Test;
|
||||
|
||||
public class CliqueExtraDataValidationRuleTest {
|
||||
|
||||
private final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
private final KeyPair proposerKeyPair = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private Address localAddr;
|
||||
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();
|
||||
|
||||
@@ -82,7 +83,7 @@ public class CliqueExtraDataValidationRuleTest {
|
||||
|
||||
@Test
|
||||
public void signerNotInExpectedValidatorsFailsValidation() {
|
||||
final KeyPair otherSigner = KeyPair.generate();
|
||||
final KeyPair otherSigner = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
|
||||
final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture();
|
||||
final BlockHeader parent = headerBuilder.number(1).buildHeader();
|
||||
|
||||
@@ -16,7 +16,8 @@ package org.hyperledger.besu.consensus.common.bft;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.ParsedExtraData;
|
||||
@@ -44,14 +45,14 @@ public class BftExtraData implements ParsedExtraData {
|
||||
public static final int EXTRA_VANITY_LENGTH = 32;
|
||||
|
||||
private final Bytes vanityData;
|
||||
private final Collection<Signature> seals;
|
||||
private final Collection<SECPSignature> seals;
|
||||
private final Optional<Vote> vote;
|
||||
private final int round;
|
||||
private final Collection<Address> validators;
|
||||
|
||||
public BftExtraData(
|
||||
final Bytes vanityData,
|
||||
final Collection<Signature> seals,
|
||||
final Collection<SECPSignature> seals,
|
||||
final Optional<Vote> vote,
|
||||
final int round,
|
||||
final Collection<Address> validators) {
|
||||
@@ -101,7 +102,9 @@ public class BftExtraData implements ParsedExtraData {
|
||||
vote = Optional.of(Vote.readFrom(rlpInput));
|
||||
}
|
||||
final int round = rlpInput.readInt();
|
||||
final List<Signature> seals = rlpInput.readList(rlp -> Signature.decode(rlp.readBytes()));
|
||||
final List<SECPSignature> seals =
|
||||
rlpInput.readList(
|
||||
rlp -> SignatureAlgorithmFactory.getInstance().decodeSignature(rlp.readBytes()));
|
||||
rlpInput.leaveList();
|
||||
|
||||
return new BftExtraData(vanityData, seals, vote, round, validators);
|
||||
@@ -160,7 +163,7 @@ public class BftExtraData implements ParsedExtraData {
|
||||
return vanityData;
|
||||
}
|
||||
|
||||
public Collection<Signature> getSeals() {
|
||||
public Collection<SECPSignature> getSeals() {
|
||||
return seals;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.consensus.common.bft;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
||||
@@ -37,7 +37,7 @@ public class BftHelpers {
|
||||
}
|
||||
|
||||
public static Block createSealedBlock(
|
||||
final Block block, final Collection<Signature> commitSeals) {
|
||||
final Block block, final Collection<SECPSignature> commitSeals) {
|
||||
final BlockHeader initialHeader = block.getHeader();
|
||||
final BftExtraData initialExtraData = BftExtraData.decode(initialHeader);
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ import org.hyperledger.besu.consensus.common.bft.payload.Authored;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.Payload;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.RoundSpecific;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
@@ -76,7 +77,8 @@ public class BftMessage<P extends Payload> implements Authored, RoundSpecific {
|
||||
final RLPInput rlpInput, final Function<RLPInput, T> decoder) {
|
||||
rlpInput.enterList();
|
||||
final T unsignedMessageData = decoder.apply(rlpInput);
|
||||
final Signature signature = rlpInput.readBytes((Signature::decode));
|
||||
final SECPSignature signature =
|
||||
rlpInput.readBytes((SignatureAlgorithmFactory.getInstance()::decodeSignature));
|
||||
rlpInput.leaveList();
|
||||
|
||||
return SignedData.create(unsignedMessageData, signature);
|
||||
|
||||
@@ -16,7 +16,7 @@ package org.hyperledger.besu.consensus.common.bft.payload;
|
||||
|
||||
import static org.hyperledger.besu.consensus.common.bft.payload.PayloadHelpers.hashForSignature;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
@@ -31,16 +31,16 @@ import org.apache.tuweni.bytes.Bytes;
|
||||
public class SignedData<M extends Payload> implements Authored {
|
||||
|
||||
private final Address sender;
|
||||
private final Signature signature;
|
||||
private final SECPSignature signature;
|
||||
private final M unsignedPayload;
|
||||
|
||||
public static <T extends Payload> SignedData<T> create(
|
||||
final T payload, final Signature signature) {
|
||||
final T payload, final SECPSignature signature) {
|
||||
final Hash msgHash = hashForSignature(payload);
|
||||
return new SignedData<>(payload, Util.signatureToAddress(signature, msgHash), signature);
|
||||
}
|
||||
|
||||
private SignedData(final M unsignedPayload, final Address sender, final Signature signature) {
|
||||
private SignedData(final M unsignedPayload, final Address sender, final SECPSignature signature) {
|
||||
this.unsignedPayload = unsignedPayload;
|
||||
this.sender = sender;
|
||||
this.signature = signature;
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.hyperledger.besu.consensus.common.bft.inttest;
|
||||
import org.hyperledger.besu.consensus.common.bft.EventMultiplexer;
|
||||
import org.hyperledger.besu.consensus.common.bft.events.BftEvents;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection;
|
||||
@@ -62,7 +62,7 @@ public abstract class DefaultValidatorPeer {
|
||||
return peerConnection;
|
||||
}
|
||||
|
||||
public Signature getBlockSignature(final Hash digest) {
|
||||
public SECPSignature getBlockSignature(final Hash digest) {
|
||||
return nodeKey.sign(digest);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
@@ -39,7 +40,7 @@ public class VoteTallyUpdaterTest {
|
||||
private static final long EPOCH_LENGTH = 30_000;
|
||||
private final VoteTally voteTally = mock(VoteTally.class);
|
||||
private final MutableBlockchain blockchain = mock(MutableBlockchain.class);
|
||||
private final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
private final KeyPair proposerKeyPair = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
private final Address subject = Address.fromHexString("007f4a23ca00cd043d25c2888c1aa5688f81a344");
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.hyperledger.besu.consensus.common.bft;
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
@@ -67,7 +67,7 @@ public class BftExtraDataFixture {
|
||||
|
||||
// if useDifferentRoundNumbersForCommittedSeals is true then each committed seal will be
|
||||
// calculated for an extraData field with a different round number
|
||||
List<Signature> commitSeals =
|
||||
List<SECPSignature> commitSeals =
|
||||
IntStream.range(0, committerNodeKeys.size())
|
||||
.mapToObj(
|
||||
i -> {
|
||||
|
||||
@@ -18,7 +18,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import org.hyperledger.besu.consensus.common.VoteType;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||||
@@ -31,12 +33,17 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BftExtraDataTest {
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
private final String RAW_HEX_ENCODING_STRING =
|
||||
"f8f1a00102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20ea9400000000000000000000000000000000000"
|
||||
+ "00001940000000000000000000000000000000000000002d794000000000000000000000000000000000000000181ff8400fedc"
|
||||
@@ -52,10 +59,10 @@ public class BftExtraDataTest {
|
||||
Arrays.asList(Address.fromHexString("1"), Address.fromHexString("2"));
|
||||
final Optional<Vote> vote = Optional.of(Vote.authVote(Address.fromHexString("1")));
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals =
|
||||
final List<SECPSignature> committerSeals =
|
||||
Arrays.asList(
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
Signature.create(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = createNonEmptyVanityData();
|
||||
@@ -70,7 +77,7 @@ public class BftExtraDataTest {
|
||||
final Optional<Vote> vote = Optional.of(Vote.authVote(Address.fromHexString("1")));
|
||||
final int round = 0x00FEDCBA;
|
||||
final byte[] roundAsByteArray = new byte[] {(byte) 0x00, (byte) 0xFE, (byte) 0xDC, (byte) 0xBA};
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = new byte[32];
|
||||
@@ -108,7 +115,7 @@ public class BftExtraDataTest {
|
||||
final List<Address> validators = Lists.newArrayList();
|
||||
final Optional<Vote> vote = Optional.of(Vote.authVote(Address.fromHexString("1")));
|
||||
final byte[] roundAsByteArray = new byte[] {(byte) 0xFE, (byte) 0xDC, (byte) 0xBA};
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = new byte[32];
|
||||
@@ -138,7 +145,7 @@ public class BftExtraDataTest {
|
||||
public void nullVoteAndListConstituteValidContent() {
|
||||
final List<Address> validators = Lists.newArrayList();
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = new byte[32];
|
||||
@@ -172,7 +179,7 @@ public class BftExtraDataTest {
|
||||
final List<Address> validators = Lists.newArrayList();
|
||||
final Optional<Vote> vote = Optional.empty();
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = new byte[32];
|
||||
@@ -191,7 +198,7 @@ public class BftExtraDataTest {
|
||||
final List<Address> validators = Lists.newArrayList();
|
||||
final Optional<Vote> vote = Optional.of(Vote.dropVote(Address.fromHexString("1")));
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = new byte[32];
|
||||
@@ -224,7 +231,7 @@ public class BftExtraDataTest {
|
||||
final List<Address> validators = Lists.newArrayList();
|
||||
final Optional<Vote> vote = Optional.of(Vote.authVote(Address.fromHexString("1")));
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = new byte[32];
|
||||
@@ -243,10 +250,10 @@ public class BftExtraDataTest {
|
||||
final List<Address> validators =
|
||||
Arrays.asList(Address.fromHexString("1"), Address.fromHexString("2"));
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals =
|
||||
final List<SECPSignature> committerSeals =
|
||||
Arrays.asList(
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
Signature.create(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
|
||||
// Create randomised vanity data.
|
||||
final byte[] vanity_bytes = createNonEmptyVanityData();
|
||||
@@ -286,10 +293,10 @@ public class BftExtraDataTest {
|
||||
Arrays.asList(Address.fromHexString("1"), Address.fromHexString("2"));
|
||||
final Optional<Vote> vote = Optional.of(Vote.authVote(Address.fromHexString("1")));
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals =
|
||||
final List<SECPSignature> committerSeals =
|
||||
Arrays.asList(
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
Signature.create(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = createNonEmptyVanityData();
|
||||
@@ -327,10 +334,10 @@ public class BftExtraDataTest {
|
||||
Arrays.asList(Address.fromHexString("1"), Address.fromHexString("2"));
|
||||
final Optional<Vote> vote = Optional.of(Vote.authVote(Address.fromHexString("1")));
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals =
|
||||
final List<SECPSignature> committerSeals =
|
||||
Arrays.asList(
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
Signature.create(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = createNonEmptyVanityData();
|
||||
@@ -362,10 +369,10 @@ public class BftExtraDataTest {
|
||||
Arrays.asList(Address.fromHexString("1"), Address.fromHexString("2"));
|
||||
final Optional<Vote> vote = Optional.of(Vote.authVote(Address.fromHexString("1")));
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals =
|
||||
final List<SECPSignature> committerSeals =
|
||||
Arrays.asList(
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
Signature.create(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = createNonEmptyVanityData();
|
||||
@@ -395,7 +402,7 @@ public class BftExtraDataTest {
|
||||
final List<Address> validators = Lists.newArrayList();
|
||||
final Optional<Vote> vote = Optional.of(Vote.authVote(Address.fromHexString("1")));
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = new byte[32];
|
||||
@@ -427,10 +434,10 @@ public class BftExtraDataTest {
|
||||
final Address voteRecipient = Address.fromHexString("1");
|
||||
final byte voteType = (byte) 0xAA;
|
||||
final int round = 0x00FEDCBA;
|
||||
final List<Signature> committerSeals =
|
||||
final List<SECPSignature> committerSeals =
|
||||
Arrays.asList(
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
Signature.create(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
|
||||
// Create a byte buffer with no data.
|
||||
final byte[] vanity_bytes = new byte[32];
|
||||
|
||||
@@ -24,7 +24,8 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.PublicKey;
|
||||
import org.hyperledger.besu.crypto.SECPPublicKey;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection;
|
||||
@@ -48,7 +49,7 @@ public class ValidatorPeersTest {
|
||||
|
||||
public static final String PROTOCOL_NAME = "BFT";
|
||||
private final List<Address> validators = newArrayList();
|
||||
private final List<PublicKey> publicKeys = newArrayList();
|
||||
private final List<SECPPublicKey> publicKeys = newArrayList();
|
||||
|
||||
private final List<PeerConnection> peerConnections = newArrayList();
|
||||
@Mock private VoteTallyCache voteTallyCache;
|
||||
@@ -56,7 +57,8 @@ public class ValidatorPeersTest {
|
||||
@Before
|
||||
public void setup() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
final PublicKey pubKey = PublicKey.create(BigInteger.valueOf(i));
|
||||
final SECPPublicKey pubKey =
|
||||
SignatureAlgorithmFactory.getInstance().createPublicKey(BigInteger.valueOf(i));
|
||||
publicKeys.add(pubKey);
|
||||
final Address address = Util.publicKeyToAddress(pubKey);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
|
||||
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
@@ -84,7 +84,7 @@ public class BftQueryServiceImplTest {
|
||||
|
||||
final BlockHeader unsignedBlockHeader = blockHeaderTestFixture.buildHeader();
|
||||
|
||||
final Collection<Signature> validatorSignatures =
|
||||
final Collection<SECPSignature> validatorSignatures =
|
||||
signingKeys.stream()
|
||||
.map(
|
||||
nodeKey ->
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.hyperledger.besu.consensus.ibft.payload.CommitPayload;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.ibft.statemachine.PreparedRoundArtifacts;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -36,7 +36,7 @@ public class IntegrationTestHelpers {
|
||||
|
||||
final BftExtraData extraData = BftExtraData.decode(block.getHeader());
|
||||
|
||||
final Signature commitSeal =
|
||||
final SECPSignature commitSeal =
|
||||
nodeKey.sign(
|
||||
BftBlockHashing.calculateDataHashForCommittedSeal(block.getHeader(), extraData));
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.hyperledger.besu.consensus.ibft.messagewrappers.RoundChange;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.consensus.ibft.statemachine.PreparedRoundArtifacts;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
|
||||
|
||||
@@ -72,7 +72,7 @@ public class RoundSpecificPeers {
|
||||
peers.forEach(ValidatorPeer::clearReceivedMessages);
|
||||
}
|
||||
|
||||
public List<Signature> sign(final Hash digest) {
|
||||
public List<SECPSignature> sign(final Hash digest) {
|
||||
return peers.stream().map(peer -> peer.getBlockSignature(digest)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.hyperledger.besu.consensus.ibft.messagewrappers.RoundChange;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.RoundChangeCertificate;
|
||||
import org.hyperledger.besu.consensus.ibft.statemachine.PreparedRoundArtifacts;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
|
||||
@@ -62,13 +62,13 @@ public class ValidatorPeer extends DefaultValidatorPeer {
|
||||
}
|
||||
|
||||
public Commit injectCommit(final ConsensusRoundIdentifier rId, final Hash digest) {
|
||||
final Signature commitSeal = nodeKey.sign(digest);
|
||||
final SECPSignature commitSeal = nodeKey.sign(digest);
|
||||
|
||||
return injectCommit(rId, digest, commitSeal);
|
||||
}
|
||||
|
||||
public Commit injectCommit(
|
||||
final ConsensusRoundIdentifier rId, final Hash digest, final Signature commitSeal) {
|
||||
final ConsensusRoundIdentifier rId, final Hash digest, final SECPSignature commitSeal) {
|
||||
final Commit payload = messageFactory.createCommit(rId, digest, commitSeal);
|
||||
injectMessage(CommitMessageData.create(payload));
|
||||
return payload;
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.hyperledger.besu.consensus.ibft.support.TestContextBuilder;
|
||||
import org.hyperledger.besu.consensus.ibft.support.ValidatorPeer;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
@@ -145,7 +145,7 @@ public class SpuriousBehaviourTest {
|
||||
|
||||
// nonProposer-2 will generate an invalid seal
|
||||
final ValidatorPeer badSealPeer = peers.getNonProposing(2);
|
||||
final Signature illegalSeal = badSealPeer.getnodeKey().sign(Hash.ZERO);
|
||||
final SECPSignature illegalSeal = badSealPeer.getnodeKey().sign(Hash.ZERO);
|
||||
|
||||
badSealPeer.injectCommit(roundId, proposedBlock.getHash(), illegalSeal);
|
||||
assertThat(context.getCurrentChainHeight()).isEqualTo(0);
|
||||
|
||||
@@ -35,7 +35,8 @@ import org.hyperledger.besu.consensus.ibft.statemachine.RoundState;
|
||||
import org.hyperledger.besu.consensus.ibft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
@@ -81,8 +82,9 @@ public class IbftRoundIntegrationTest {
|
||||
|
||||
private Block proposedBlock;
|
||||
|
||||
private final Signature remoteCommitSeal =
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1);
|
||||
private final SECPSignature remoteCommitSeal =
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 1);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.CommitPayload;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.PayloadDeserializers;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Commit extends BftMessage<CommitPayload> {
|
||||
super(payload);
|
||||
}
|
||||
|
||||
public Signature getCommitSeal() {
|
||||
public SECPSignature getCommitSeal() {
|
||||
return getPayload().getCommitSeal();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.hyperledger.besu.consensus.ibft.messagewrappers.RoundChange;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.RoundChangeCertificate;
|
||||
import org.hyperledger.besu.consensus.ibft.statemachine.PreparedRoundArtifacts;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException;
|
||||
@@ -81,7 +81,7 @@ public class IbftMessageTransmitter {
|
||||
public void multicastCommit(
|
||||
final ConsensusRoundIdentifier roundIdentifier,
|
||||
final Hash digest,
|
||||
final Signature commitSeal) {
|
||||
final SECPSignature commitSeal) {
|
||||
try {
|
||||
final Commit data = messageFactory.createCommit(roundIdentifier, digest, commitSeal);
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ package org.hyperledger.besu.consensus.ibft.payload;
|
||||
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.Payload;
|
||||
import org.hyperledger.besu.consensus.ibft.messagedata.IbftV2;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||||
@@ -29,12 +30,12 @@ public class CommitPayload implements Payload {
|
||||
private static final int TYPE = IbftV2.COMMIT;
|
||||
private final ConsensusRoundIdentifier roundIdentifier;
|
||||
private final Hash digest;
|
||||
private final Signature commitSeal;
|
||||
private final SECPSignature commitSeal;
|
||||
|
||||
public CommitPayload(
|
||||
final ConsensusRoundIdentifier roundIdentifier,
|
||||
final Hash digest,
|
||||
final Signature commitSeal) {
|
||||
final SECPSignature commitSeal) {
|
||||
this.roundIdentifier = roundIdentifier;
|
||||
this.digest = digest;
|
||||
this.commitSeal = commitSeal;
|
||||
@@ -44,7 +45,8 @@ public class CommitPayload implements Payload {
|
||||
rlpInput.enterList();
|
||||
final ConsensusRoundIdentifier roundIdentifier = ConsensusRoundIdentifier.readFrom(rlpInput);
|
||||
final Hash digest = Payload.readDigest(rlpInput);
|
||||
final Signature commitSeal = rlpInput.readBytes(Signature::decode);
|
||||
final SECPSignature commitSeal =
|
||||
rlpInput.readBytes(SignatureAlgorithmFactory.getInstance()::decodeSignature);
|
||||
rlpInput.leaveList();
|
||||
|
||||
return new CommitPayload(roundIdentifier, digest, commitSeal);
|
||||
@@ -68,7 +70,7 @@ public class CommitPayload implements Payload {
|
||||
return digest;
|
||||
}
|
||||
|
||||
public Signature getCommitSeal() {
|
||||
public SECPSignature getCommitSeal() {
|
||||
return commitSeal;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.hyperledger.besu.consensus.ibft.messagewrappers.Proposal;
|
||||
import org.hyperledger.besu.consensus.ibft.messagewrappers.RoundChange;
|
||||
import org.hyperledger.besu.consensus.ibft.statemachine.PreparedRoundArtifacts;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
|
||||
@@ -59,7 +59,7 @@ public class MessageFactory {
|
||||
public Commit createCommit(
|
||||
final ConsensusRoundIdentifier roundIdentifier,
|
||||
final Hash digest,
|
||||
final Signature commitSeal) {
|
||||
final SECPSignature commitSeal) {
|
||||
|
||||
final CommitPayload payload = new CommitPayload(roundIdentifier, digest, commitSeal);
|
||||
|
||||
@@ -79,7 +79,7 @@ public class MessageFactory {
|
||||
}
|
||||
|
||||
private <M extends Payload> SignedData<M> createSignedMessage(final M payload) {
|
||||
final Signature signature = nodeKey.sign(hashForSignature(payload));
|
||||
final SECPSignature signature = nodeKey.sign(hashForSignature(payload));
|
||||
return SignedData.create(payload, signature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ package org.hyperledger.besu.consensus.ibft.payload;
|
||||
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.Payload;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
|
||||
public class PayloadDeserializers {
|
||||
@@ -25,7 +26,7 @@ public class PayloadDeserializers {
|
||||
|
||||
rlpInput.enterList();
|
||||
final ProposalPayload unsignedMessageData = ProposalPayload.readFrom(rlpInput);
|
||||
final Signature signature = readSignature(rlpInput);
|
||||
final SECPSignature signature = readSignature(rlpInput);
|
||||
rlpInput.leaveList();
|
||||
|
||||
return from(unsignedMessageData, signature);
|
||||
@@ -35,7 +36,7 @@ public class PayloadDeserializers {
|
||||
|
||||
rlpInput.enterList();
|
||||
final PreparePayload unsignedMessageData = PreparePayload.readFrom(rlpInput);
|
||||
final Signature signature = readSignature(rlpInput);
|
||||
final SECPSignature signature = readSignature(rlpInput);
|
||||
rlpInput.leaveList();
|
||||
|
||||
return from(unsignedMessageData, signature);
|
||||
@@ -45,7 +46,7 @@ public class PayloadDeserializers {
|
||||
|
||||
rlpInput.enterList();
|
||||
final CommitPayload unsignedMessageData = CommitPayload.readFrom(rlpInput);
|
||||
final Signature signature = readSignature(rlpInput);
|
||||
final SECPSignature signature = readSignature(rlpInput);
|
||||
rlpInput.leaveList();
|
||||
|
||||
return from(unsignedMessageData, signature);
|
||||
@@ -56,18 +57,18 @@ public class PayloadDeserializers {
|
||||
|
||||
rlpInput.enterList();
|
||||
final RoundChangePayload unsignedMessageData = RoundChangePayload.readFrom(rlpInput);
|
||||
final Signature signature = readSignature(rlpInput);
|
||||
final SECPSignature signature = readSignature(rlpInput);
|
||||
rlpInput.leaveList();
|
||||
|
||||
return from(unsignedMessageData, signature);
|
||||
}
|
||||
|
||||
protected static <M extends Payload> SignedData<M> from(
|
||||
final M unsignedMessageData, final Signature signature) {
|
||||
final M unsignedMessageData, final SECPSignature signature) {
|
||||
return SignedData.create(unsignedMessageData, signature);
|
||||
}
|
||||
|
||||
protected static Signature readSignature(final RLPInput signedMessage) {
|
||||
return signedMessage.readBytes(Signature::decode);
|
||||
protected static SECPSignature readSignature(final RLPInput signedMessage) {
|
||||
return signedMessage.readBytes(SignatureAlgorithmFactory.getInstance()::decodeSignature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.hyperledger.besu.consensus.ibft.network.IbftMessageTransmitter;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.ibft.payload.RoundChangeCertificate;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
@@ -172,7 +172,7 @@ public class IbftRound {
|
||||
if (blockAccepted) {
|
||||
final Block block = roundState.getProposedBlock().get();
|
||||
|
||||
final Signature commitSeal;
|
||||
final SECPSignature commitSeal;
|
||||
try {
|
||||
commitSeal = createCommitSeal(block);
|
||||
} catch (final SecurityModuleException e) {
|
||||
@@ -258,7 +258,7 @@ public class IbftRound {
|
||||
}
|
||||
}
|
||||
|
||||
private Signature createCommitSeal(final Block block) {
|
||||
private SECPSignature createCommitSeal(final Block block) {
|
||||
final BlockHeader proposedHeader = block.getHeader();
|
||||
final BftExtraData extraData = BftExtraData.decode(proposedHeader);
|
||||
final Hash commitHash =
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.hyperledger.besu.consensus.ibft.messagewrappers.Commit;
|
||||
import org.hyperledger.besu.consensus.ibft.messagewrappers.Prepare;
|
||||
import org.hyperledger.besu.consensus.ibft.messagewrappers.Proposal;
|
||||
import org.hyperledger.besu.consensus.ibft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -123,7 +123,7 @@ public class RoundState {
|
||||
return committed;
|
||||
}
|
||||
|
||||
public Collection<Signature> getCommitSeals() {
|
||||
public Collection<SECPSignature> getCommitSeals() {
|
||||
return commitMessages.stream()
|
||||
.map(cp -> cp.getSignedPayload().getPayload().getCommitSeal())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -23,9 +23,9 @@ import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
||||
import org.hyperledger.besu.consensus.common.bft.Vote;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.PrivateKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
||||
@@ -85,7 +85,7 @@ public class BftBlockHashingTest {
|
||||
|
||||
BlockHeaderBuilder builder = setHeaderFieldsExceptForExtraData();
|
||||
|
||||
List<Signature> commitSeals =
|
||||
List<SECPSignature> commitSeals =
|
||||
COMMITTERS_NODE_KEYS.stream()
|
||||
.map(nodeKey -> nodeKey.sign(dataHahsForCommittedSeal))
|
||||
.collect(Collectors.toList());
|
||||
@@ -99,11 +99,14 @@ public class BftBlockHashingTest {
|
||||
}
|
||||
|
||||
private static List<NodeKey> committersNodeKeys() {
|
||||
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||||
|
||||
return IntStream.rangeClosed(1, 4)
|
||||
.mapToObj(
|
||||
i ->
|
||||
NodeKeyUtils.createFrom(
|
||||
(KeyPair.create(PrivateKey.create(UInt256.valueOf(i).toBytes())))))
|
||||
(signatureAlgorithm.createKeyPair(
|
||||
signatureAlgorithm.createPrivateKey(UInt256.valueOf(i).toBytes())))))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -159,7 +162,7 @@ public class BftBlockHashingTest {
|
||||
BytesValueRLPOutput rlpForHeaderFroCommittersSigning = new BytesValueRLPOutput();
|
||||
builder.buildBlockHeader().writeTo(rlpForHeaderFroCommittersSigning);
|
||||
|
||||
List<Signature> commitSeals =
|
||||
List<SECPSignature> commitSeals =
|
||||
COMMITTERS_NODE_KEYS.stream()
|
||||
.map(nodeKey -> nodeKey.sign(Hash.hash(rlpForHeaderFroCommittersSigning.encoded())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -18,7 +18,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
||||
import org.hyperledger.besu.consensus.ibft.messagedata.IbftV2;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
@@ -34,7 +35,9 @@ public class CommitPayloadTest {
|
||||
|
||||
@Test
|
||||
public void roundTripRlp() {
|
||||
final Signature signature = Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
final SECPSignature signature =
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
final Hash hash = Hash.fromHexStringLenient("0x8523ba6e7c5f59ae87");
|
||||
|
||||
final CommitPayload expectedCommitPayload =
|
||||
|
||||
@@ -20,7 +20,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
||||
import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
@@ -32,6 +34,8 @@ import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -40,6 +44,9 @@ public class PreparedCertificateTest {
|
||||
private static final ConsensusRoundIdentifier ROUND_IDENTIFIER =
|
||||
new ConsensusRoundIdentifier(0x1234567890ABCDEFL, 0xFEDCBA98);
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
@Test
|
||||
public void roundTripRlpWithNoPreparePayloads() {
|
||||
final SignedData<ProposalPayload> signedProposalPayload = signedProposal();
|
||||
@@ -63,7 +70,8 @@ public class PreparedCertificateTest {
|
||||
final SignedData<ProposalPayload> signedProposalPayload = signedProposal();
|
||||
final PreparePayload preparePayload =
|
||||
new PreparePayload(ROUND_IDENTIFIER, Hash.fromHexStringLenient("0x8523ba6e7c5f59ae87"));
|
||||
final Signature signature = Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
final SECPSignature signature =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
final SignedData<PreparePayload> signedPrepare =
|
||||
PayloadDeserializers.from(preparePayload, signature);
|
||||
|
||||
@@ -85,7 +93,8 @@ public class PreparedCertificateTest {
|
||||
ProposedBlockHelpers.createProposalBlock(
|
||||
singletonList(AddressHelpers.ofValue(1)), ROUND_IDENTIFIER);
|
||||
final ProposalPayload proposalPayload = new ProposalPayload(ROUND_IDENTIFIER, block.getHash());
|
||||
final Signature signature = Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
final SECPSignature signature =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
return PayloadDeserializers.from(proposalPayload, signature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
||||
import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.consensus.ibft.messagedata.IbftV2;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
@@ -60,7 +61,9 @@ public class RoundChangeCertificateTest {
|
||||
ProposedBlockHelpers.createProposalBlock(
|
||||
singletonList(AddressHelpers.ofValue(1)), ROUND_IDENTIFIER);
|
||||
final ProposalPayload proposalPayload = new ProposalPayload(ROUND_IDENTIFIER, block.getHash());
|
||||
final Signature signature = Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
final SECPSignature signature =
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
SignedData<ProposalPayload> signedProposal =
|
||||
PayloadDeserializers.from(proposalPayload, signature);
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
||||
import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.consensus.ibft.messagedata.IbftV2;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
@@ -34,6 +36,8 @@ import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -41,8 +45,10 @@ public class RoundChangePayloadTest {
|
||||
|
||||
private static final ConsensusRoundIdentifier ROUND_IDENTIFIER =
|
||||
new ConsensusRoundIdentifier(0x1234567890ABCDEFL, 0xFEDCBA98);
|
||||
private static final Signature SIGNATURE =
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
private static final SECPSignature SIGNATURE =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
|
||||
@Test
|
||||
public void roundTripRlpWithNoPreparedCertificate() {
|
||||
@@ -106,7 +112,8 @@ public class RoundChangePayloadTest {
|
||||
ProposedBlockHelpers.createProposalBlock(
|
||||
singletonList(AddressHelpers.ofValue(1)), ROUND_IDENTIFIER);
|
||||
final ProposalPayload proposalPayload = new ProposalPayload(ROUND_IDENTIFIER, block.getHash());
|
||||
final Signature signature = Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
final SECPSignature signature =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
return PayloadDeserializers.from(proposalPayload, signature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ import org.hyperledger.besu.consensus.ibft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.consensus.ibft.validation.MessageValidatorFactory;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
@@ -315,7 +315,8 @@ public class IbftBlockHeightManagerTest {
|
||||
.createCommit(
|
||||
futureRoundIdentifier,
|
||||
Hash.fromHexStringLenient("0"),
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1));
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 1));
|
||||
|
||||
manager.handlePreparePayload(prepare);
|
||||
manager.handleCommitPayload(commit);
|
||||
|
||||
@@ -39,7 +39,8 @@ import org.hyperledger.besu.consensus.ibft.payload.RoundChangeCertificate;
|
||||
import org.hyperledger.besu.consensus.ibft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
@@ -89,8 +90,9 @@ public class IbftRoundTest {
|
||||
private Block proposedBlock;
|
||||
private BftExtraData proposedExtraData;
|
||||
|
||||
private final Signature remoteCommitSeal =
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1);
|
||||
private final SECPSignature remoteCommitSeal =
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 1);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -216,7 +218,7 @@ public class IbftRoundTest {
|
||||
final Hash commitSealHash =
|
||||
BftBlockHashing.calculateDataHashForCommittedSeal(
|
||||
proposedBlock.getHeader(), proposedExtraData);
|
||||
final Signature localCommitSeal = nodeKey.sign(commitSealHash);
|
||||
final SECPSignature localCommitSeal = nodeKey.sign(commitSealHash);
|
||||
|
||||
// Receive Proposal Message
|
||||
round.handleProposalMessage(
|
||||
@@ -259,7 +261,7 @@ public class IbftRoundTest {
|
||||
final Hash commitSealHash =
|
||||
BftBlockHashing.calculateDataHashForCommittedSeal(
|
||||
proposedBlock.getHeader(), proposedExtraData);
|
||||
final Signature localCommitSeal = nodeKey.sign(commitSealHash);
|
||||
final SECPSignature localCommitSeal = nodeKey.sign(commitSealHash);
|
||||
|
||||
round.createAndSendProposalMessage(15);
|
||||
verify(transmitter, never()).multicastCommit(any(), any(), any());
|
||||
|
||||
@@ -28,7 +28,8 @@ import org.hyperledger.besu.consensus.ibft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.ibft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
@@ -132,7 +133,8 @@ public class RoundStateTest {
|
||||
.createCommit(
|
||||
roundIdentifier,
|
||||
block.getHash(),
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1));
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 1));
|
||||
|
||||
roundState.addCommitMessage(commit);
|
||||
assertThat(roundState.isPrepared()).isTrue();
|
||||
@@ -233,6 +235,7 @@ public class RoundStateTest {
|
||||
when(messageValidator.validateCommit(any())).thenReturn(true);
|
||||
|
||||
final RoundState roundState = new RoundState(roundIdentifier, 2, messageValidator);
|
||||
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||||
|
||||
final Commit firstCommit =
|
||||
validatorMessageFactories
|
||||
@@ -240,7 +243,7 @@ public class RoundStateTest {
|
||||
.createCommit(
|
||||
roundIdentifier,
|
||||
block.getHash(),
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 1));
|
||||
signatureAlgorithm.createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 1));
|
||||
|
||||
final Commit secondCommit =
|
||||
validatorMessageFactories
|
||||
@@ -248,7 +251,7 @@ public class RoundStateTest {
|
||||
.createCommit(
|
||||
roundIdentifier,
|
||||
block.getHash(),
|
||||
Signature.create(BigInteger.TEN, BigInteger.TEN, (byte) 1));
|
||||
signatureAlgorithm.createSignature(BigInteger.TEN, BigInteger.TEN, (byte) 1));
|
||||
|
||||
final Proposal proposal =
|
||||
validatorMessageFactories.get(0).createProposal(roundIdentifier, block, Optional.empty());
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.consensus.ibftlegacy;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
@@ -116,7 +116,7 @@ public class IbftBlockHashing {
|
||||
}
|
||||
|
||||
private static Bytes encodeExtraDataWithoutCommittedSeals(
|
||||
final IbftExtraData ibftExtraData, final Signature proposerSeal) {
|
||||
final IbftExtraData ibftExtraData, final SECPSignature proposerSeal) {
|
||||
final BytesValueRLPOutput extraDataEncoding = new BytesValueRLPOutput();
|
||||
extraDataEncoding.startList();
|
||||
extraDataEncoding.writeList(
|
||||
|
||||
@@ -17,7 +17,9 @@ package org.hyperledger.besu.consensus.ibftlegacy;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.ParsedExtraData;
|
||||
@@ -27,6 +29,8 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
@@ -39,16 +43,18 @@ public class IbftExtraData implements ParsedExtraData {
|
||||
private static final Logger LOG = LogManager.getLogger();
|
||||
|
||||
public static final int EXTRA_VANITY_LENGTH = 32;
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
private final Bytes vanityData;
|
||||
private final Collection<Signature> seals;
|
||||
private final Signature proposerSeal;
|
||||
private final Collection<SECPSignature> seals;
|
||||
private final SECPSignature proposerSeal;
|
||||
private final Collection<Address> validators;
|
||||
|
||||
public IbftExtraData(
|
||||
final Bytes vanityData,
|
||||
final Collection<Signature> seals,
|
||||
final Signature proposerSeal,
|
||||
final Collection<SECPSignature> seals,
|
||||
final SECPSignature proposerSeal,
|
||||
final Collection<Address> validators) {
|
||||
|
||||
checkNotNull(vanityData);
|
||||
@@ -84,16 +90,17 @@ public class IbftExtraData implements ParsedExtraData {
|
||||
|
||||
rlpInput.enterList(); // This accounts for the "root node" which contains IBFT data items.
|
||||
final Collection<Address> validators = rlpInput.readList(Address::readFrom);
|
||||
final Signature proposerSeal = parseProposerSeal(rlpInput);
|
||||
final Collection<Signature> seals = rlpInput.readList(rlp -> Signature.decode(rlp.readBytes()));
|
||||
final SECPSignature proposerSeal = parseProposerSeal(rlpInput);
|
||||
final Collection<SECPSignature> seals =
|
||||
rlpInput.readList(rlp -> SIGNATURE_ALGORITHM.get().decodeSignature(rlp.readBytes()));
|
||||
rlpInput.leaveList();
|
||||
|
||||
return new IbftExtraData(vanityData, seals, proposerSeal, validators);
|
||||
}
|
||||
|
||||
private static Signature parseProposerSeal(final RLPInput rlpInput) {
|
||||
private static SECPSignature parseProposerSeal(final RLPInput rlpInput) {
|
||||
final Bytes data = rlpInput.readBytes();
|
||||
return data.isZero() ? null : Signature.decode(data);
|
||||
return data.isZero() ? null : SIGNATURE_ALGORITHM.get().decodeSignature(data);
|
||||
}
|
||||
|
||||
public Bytes encode() {
|
||||
@@ -116,11 +123,11 @@ public class IbftExtraData implements ParsedExtraData {
|
||||
return vanityData;
|
||||
}
|
||||
|
||||
public Collection<Signature> getSeals() {
|
||||
public Collection<SECPSignature> getSeals() {
|
||||
return seals;
|
||||
}
|
||||
|
||||
public Signature getProposerSeal() {
|
||||
public SECPSignature getProposerSeal() {
|
||||
return proposerSeal;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ package org.hyperledger.besu.consensus.ibftlegacy.blockcreation;
|
||||
import org.hyperledger.besu.consensus.ibftlegacy.IbftBlockHashing;
|
||||
import org.hyperledger.besu.consensus.ibftlegacy.IbftExtraData;
|
||||
import org.hyperledger.besu.consensus.ibftlegacy.IbftHelpers;
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.blockcreation.AbstractBlockCreator;
|
||||
import org.hyperledger.besu.ethereum.blockcreation.GasLimitCalculator;
|
||||
@@ -110,7 +110,7 @@ public class IbftBlockCreator extends AbstractBlockCreator {
|
||||
return new IbftExtraData(
|
||||
extraData.getVanityData(),
|
||||
extraData.getSeals(),
|
||||
SECP256K1.sign(hashToSign, nodeKeys),
|
||||
SignatureAlgorithmFactory.getInstance().sign(hashToSign, nodeKeys),
|
||||
extraData.getValidators());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ package org.hyperledger.besu.consensus.ibftlegacy;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPException;
|
||||
@@ -26,6 +28,8 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
@@ -33,11 +37,15 @@ import org.junit.Test;
|
||||
|
||||
public class BftExtraDataTest {
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
@Test
|
||||
public void emptyListsConstituteValidContent() {
|
||||
final Signature proposerSeal = Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final SECPSignature proposerSeal =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final List<Address> validators = Lists.newArrayList();
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
final BytesValueRLPOutput encoder = new BytesValueRLPOutput();
|
||||
encoder.startList();
|
||||
@@ -62,11 +70,12 @@ public class BftExtraDataTest {
|
||||
@Test
|
||||
public void fullyPopulatedDataProducesCorrectlyFormedExtraDataObject() {
|
||||
final List<Address> validators = Arrays.asList(Address.ECREC, Address.SHA256);
|
||||
final Signature proposerSeal = Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final List<Signature> committerSeals =
|
||||
final SECPSignature proposerSeal =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final List<SECPSignature> committerSeals =
|
||||
Arrays.asList(
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
Signature.create(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
|
||||
final BytesValueRLPOutput encoder = new BytesValueRLPOutput();
|
||||
encoder.startList(); // This is required to create a "root node" for all RLP'd data
|
||||
@@ -91,9 +100,10 @@ public class BftExtraDataTest {
|
||||
|
||||
@Test(expected = RLPException.class)
|
||||
public void incorrectlyStructuredRlpThrowsException() {
|
||||
final Signature proposerSeal = Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final SECPSignature proposerSeal =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final List<Address> validators = Lists.newArrayList();
|
||||
final List<Signature> committerSeals = Lists.newArrayList();
|
||||
final List<SECPSignature> committerSeals = Lists.newArrayList();
|
||||
|
||||
final BytesValueRLPOutput encoder = new BytesValueRLPOutput();
|
||||
encoder.startList();
|
||||
@@ -111,11 +121,12 @@ public class BftExtraDataTest {
|
||||
@Test(expected = RLPException.class)
|
||||
public void incorrectlySizedVanityDataThrowsException() {
|
||||
final List<Address> validators = Arrays.asList(Address.ECREC, Address.SHA256);
|
||||
final Signature proposerSeal = Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final List<Signature> committerSeals =
|
||||
final SECPSignature proposerSeal =
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0);
|
||||
final List<SECPSignature> committerSeals =
|
||||
Arrays.asList(
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
Signature.create(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0));
|
||||
|
||||
final BytesValueRLPOutput encoder = new BytesValueRLPOutput();
|
||||
encoder.startList();
|
||||
|
||||
@@ -24,9 +24,10 @@ import static org.mockito.Mockito.when;
|
||||
import org.hyperledger.besu.consensus.common.VoteTally;
|
||||
import org.hyperledger.besu.consensus.common.VoteTallyCache;
|
||||
import org.hyperledger.besu.consensus.common.bft.BftContext;
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
@@ -40,11 +41,16 @@ import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.Test;
|
||||
|
||||
public class IbftBlockHeaderValidationRulesetFactoryTest {
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
private ProtocolContext setupContextWithValidators(final Collection<Address> validators) {
|
||||
final BftContext bftContext = mock(BftContext.class);
|
||||
final VoteTallyCache mockCache = mock(VoteTallyCache.class);
|
||||
@@ -58,7 +64,7 @@ public class IbftBlockHeaderValidationRulesetFactoryTest {
|
||||
|
||||
@Test
|
||||
public void ibftValidateHeaderPasses() {
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = SIGNATURE_ALGORITHM.get().generateKeyPair();
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
@@ -81,7 +87,7 @@ public class IbftBlockHeaderValidationRulesetFactoryTest {
|
||||
|
||||
@Test
|
||||
public void ibftValidateHeaderFails() {
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = SIGNATURE_ALGORITHM.get().generateKeyPair();
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
@@ -126,7 +132,7 @@ public class IbftBlockHeaderValidationRulesetFactoryTest {
|
||||
new IbftExtraData(
|
||||
Bytes.wrap(new byte[IbftExtraData.EXTRA_VANITY_LENGTH]),
|
||||
emptyList(),
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 0),
|
||||
SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0),
|
||||
validators);
|
||||
|
||||
builder.extraData(initialIbftExtraData.encode());
|
||||
@@ -134,7 +140,8 @@ public class IbftBlockHeaderValidationRulesetFactoryTest {
|
||||
final Hash proposerSealHash =
|
||||
IbftBlockHashing.calculateDataHashForProposerSeal(parentHeader, initialIbftExtraData);
|
||||
|
||||
final Signature proposerSignature = SECP256K1.sign(proposerSealHash, proposerKeyPair);
|
||||
final SECPSignature proposerSignature =
|
||||
SIGNATURE_ALGORITHM.get().sign(proposerSealHash, proposerKeyPair);
|
||||
|
||||
final IbftExtraData proposedData =
|
||||
new IbftExtraData(
|
||||
@@ -145,8 +152,8 @@ public class IbftBlockHeaderValidationRulesetFactoryTest {
|
||||
|
||||
final Hash headerHashForCommitters =
|
||||
IbftBlockHashing.calculateDataHashForCommittedSeal(parentHeader, proposedData);
|
||||
final Signature proposerAsCommitterSignature =
|
||||
SECP256K1.sign(headerHashForCommitters, proposerKeyPair);
|
||||
final SECPSignature proposerAsCommitterSignature =
|
||||
SIGNATURE_ALGORITHM.get().sign(headerHashForCommitters, proposerKeyPair);
|
||||
|
||||
final IbftExtraData sealedData =
|
||||
new IbftExtraData(
|
||||
|
||||
@@ -20,7 +20,8 @@ import static org.hyperledger.besu.consensus.common.VoteType.ADD;
|
||||
import static org.hyperledger.besu.consensus.common.VoteType.DROP;
|
||||
|
||||
import org.hyperledger.besu.consensus.common.ValidatorVote;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
@@ -37,7 +38,8 @@ import org.junit.Test;
|
||||
|
||||
public class IbftLegacyBlockInterfaceTest {
|
||||
|
||||
private static final KeyPair proposerKeys = KeyPair.generate();
|
||||
private static final KeyPair proposerKeys =
|
||||
SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
private static final Address proposerAddress =
|
||||
Util.publicKeyToAddress(proposerKeys.getPublicKey());
|
||||
private static final List<Address> validatorList = singletonList(proposerAddress);
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
*/
|
||||
package org.hyperledger.besu.consensus.ibftlegacy;
|
||||
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
@@ -42,7 +42,8 @@ public class TestHelpers {
|
||||
IbftBlockHashing.calculateDataHashForProposerSeal(
|
||||
blockHeaderBuilder.buildHeader(), unsignedExtraData);
|
||||
|
||||
final Signature proposerSignature = SECP256K1.sign(signingHash, signer);
|
||||
final SECPSignature proposerSignature =
|
||||
SignatureAlgorithmFactory.getInstance().sign(signingHash, signer);
|
||||
|
||||
final IbftExtraData signedExtraData =
|
||||
new IbftExtraData(
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.consensus.ibftlegacy.IbftBlockHeaderValidationRulesetFactory;
|
||||
import org.hyperledger.besu.consensus.ibftlegacy.IbftExtraData;
|
||||
import org.hyperledger.besu.consensus.ibftlegacy.IbftProtocolSchedule;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
@@ -68,7 +69,7 @@ public class BftBlockCreatorTest {
|
||||
when(blockchain.getChainHeadHash()).thenReturn(parentHeader.getHash());
|
||||
when(blockchain.getBlockHeader(any())).thenReturn(optionalHeader);
|
||||
|
||||
final KeyPair nodeKeys = KeyPair.generate();
|
||||
final KeyPair nodeKeys = SignatureAlgorithmFactory.getInstance().generateKeyPair();
|
||||
// Add the local node as a validator (can't propose a block if node is not a validator).
|
||||
final Address localAddr = Address.extract(Hash.hash(nodeKeys.getPublicKey().getEncodedBytes()));
|
||||
final List<Address> initialValidatorList =
|
||||
|
||||
@@ -21,9 +21,10 @@ import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupC
|
||||
|
||||
import org.hyperledger.besu.consensus.ibftlegacy.IbftBlockHashing;
|
||||
import org.hyperledger.besu.consensus.ibftlegacy.IbftExtraData;
|
||||
import org.hyperledger.besu.crypto.SECP256K1;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
@@ -43,6 +44,8 @@ import org.junit.Test;
|
||||
|
||||
public class BftExtraDataValidationRuleTest {
|
||||
|
||||
private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||||
|
||||
private BlockHeader createProposedBlockHeader(
|
||||
final KeyPair proposerKeyPair, final List<Address> validators) {
|
||||
final BlockHeaderTestFixture builder = new BlockHeaderTestFixture();
|
||||
@@ -58,7 +61,8 @@ public class BftExtraDataValidationRuleTest {
|
||||
// Hash the header (ignoring committer and proposer seals), and create signature
|
||||
final Hash proposerSealHash =
|
||||
IbftBlockHashing.calculateDataHashForProposerSeal(header, initialIbftExtraData);
|
||||
final Signature proposerSignature = SECP256K1.sign(proposerSealHash, proposerKeyPair);
|
||||
final SECPSignature proposerSignature =
|
||||
signatureAlgorithm.sign(proposerSealHash, proposerKeyPair);
|
||||
|
||||
// Construct a new extraData block, containing the constructed proposer signature
|
||||
final IbftExtraData proposedData =
|
||||
@@ -80,9 +84,9 @@ public class BftExtraDataValidationRuleTest {
|
||||
final Hash headerHashForCommitters =
|
||||
IbftBlockHashing.calculateDataHashForCommittedSeal(header, extraDataInHeader);
|
||||
|
||||
final List<Signature> commitSeals =
|
||||
final List<SECPSignature> commitSeals =
|
||||
committerKeyPairs.stream()
|
||||
.map(keys -> SECP256K1.sign(headerHashForCommitters, keys))
|
||||
.map(keys -> signatureAlgorithm.sign(headerHashForCommitters, keys))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return new IbftExtraData(
|
||||
@@ -96,7 +100,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
public void correctlyConstructedHeaderPassesValidation() {
|
||||
final BlockHeaderTestFixture builder = new BlockHeaderTestFixture();
|
||||
builder.number(1); // must NOT be block 0, as that should not contain seals at all
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
@@ -122,7 +126,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
public void insufficientCommitSealsFailsValidation() {
|
||||
final BlockHeaderTestFixture builder = new BlockHeaderTestFixture();
|
||||
builder.number(1); // must NOT be block 0, as that should not contain seals at all
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
@@ -146,7 +150,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
public void outOfOrderValidatorListFailsValidation() {
|
||||
final BlockHeaderTestFixture builder = new BlockHeaderTestFixture();
|
||||
builder.number(1); // must NOT be block 0, as that should not contain seals at all
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
@@ -175,7 +179,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
public void proposerNotInValidatorListFailsValidation() {
|
||||
final BlockHeaderTestFixture builder = new BlockHeaderTestFixture();
|
||||
builder.number(1); // must NOT be block 0, as that should not contain seals at all
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
@@ -204,7 +208,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
public void mismatchingReportedValidatorsVsLocallyStoredListFailsValidation() {
|
||||
final BlockHeaderTestFixture builder = new BlockHeaderTestFixture();
|
||||
builder.number(1); // must NOT be block 0, as that should not contain seals at all
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
@@ -235,7 +239,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
public void committerNotInValidatorListFailsValidation() {
|
||||
final BlockHeaderTestFixture builder = new BlockHeaderTestFixture();
|
||||
builder.number(1); // must NOT be block 0, as that should not contain seals at all
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
@@ -244,7 +248,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
BlockHeader header = createProposedBlockHeader(proposerKeyPair, validators);
|
||||
|
||||
// Insert an extraData block with committer seals.
|
||||
final KeyPair nonValidatorKeyPair = KeyPair.generate();
|
||||
final KeyPair nonValidatorKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
final IbftExtraData commitedExtraData =
|
||||
createExtraDataWithCommitSeals(header, singletonList(nonValidatorKeyPair));
|
||||
builder.extraData(commitedExtraData.encode());
|
||||
@@ -293,7 +297,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
final int validatorCount, final int committerCount, final boolean useTwoThirds) {
|
||||
final BlockHeaderTestFixture builder = new BlockHeaderTestFixture();
|
||||
builder.number(1); // must NOT be block 0, as that should not contain seals at all
|
||||
final KeyPair proposerKeyPair = KeyPair.generate();
|
||||
final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
|
||||
final Address proposerAddress =
|
||||
Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes()));
|
||||
@@ -303,7 +307,7 @@ public class BftExtraDataValidationRuleTest {
|
||||
validators.add(proposerAddress);
|
||||
committerKeys.add(proposerKeyPair);
|
||||
for (int i = 0; i < validatorCount - 1; i++) { // need -1 to account for proposer
|
||||
final KeyPair committerKeyPair = KeyPair.generate();
|
||||
final KeyPair committerKeyPair = signatureAlgorithm.generateKeyPair();
|
||||
committerKeys.add(committerKeyPair);
|
||||
validators.add(Address.extract(Hash.hash(committerKeyPair.getPublicKey().getEncodedBytes())));
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ dependencies {
|
||||
integrationTestImplementation 'org.mockito:mockito-core'
|
||||
|
||||
referenceTestImplementation 'junit:junit'
|
||||
referenceTestImplementation 'com.google.guava:guava'
|
||||
referenceTestImplementation 'org.assertj:assertj-core'
|
||||
referenceTestImplementation 'org.mockito:mockito-core'
|
||||
referenceTestImplementation 'com.fasterxml.jackson.core:jackson-databind'
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.hyperledger.besu.consensus.qbft.payload.CommitPayload;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
|
||||
public class IntegrationTestHelpers {
|
||||
@@ -32,7 +32,7 @@ public class IntegrationTestHelpers {
|
||||
|
||||
final BftExtraData extraData = BftExtraData.decode(block.getHeader());
|
||||
|
||||
final Signature commitSeal =
|
||||
final SECPSignature commitSeal =
|
||||
nodeKey.sign(
|
||||
BftBlockHashing.calculateDataHashForCommittedSeal(block.getHeader(), extraData));
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
|
||||
|
||||
@@ -72,7 +72,7 @@ public class RoundSpecificPeers {
|
||||
peers.forEach(ValidatorPeer::clearReceivedMessages);
|
||||
}
|
||||
|
||||
public List<Signature> sign(final Hash digest) {
|
||||
public List<SECPSignature> sign(final Hash digest) {
|
||||
return peers.stream().map(peer -> peer.getBlockSignature(digest)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.hyperledger.besu.consensus.qbft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
|
||||
@@ -64,13 +64,13 @@ public class ValidatorPeer extends DefaultValidatorPeer {
|
||||
}
|
||||
|
||||
public Commit injectCommit(final ConsensusRoundIdentifier rId, final Hash digest) {
|
||||
final Signature commitSeal = nodeKey.sign(digest);
|
||||
final SECPSignature commitSeal = nodeKey.sign(digest);
|
||||
|
||||
return injectCommit(rId, digest, commitSeal);
|
||||
}
|
||||
|
||||
public Commit injectCommit(
|
||||
final ConsensusRoundIdentifier rId, final Hash digest, final Signature commitSeal) {
|
||||
final ConsensusRoundIdentifier rId, final Hash digest, final SECPSignature commitSeal) {
|
||||
final Commit payload = messageFactory.createCommit(rId, digest, commitSeal);
|
||||
injectMessage(CommitMessageData.create(payload));
|
||||
return payload;
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder;
|
||||
import org.hyperledger.besu.consensus.qbft.support.ValidatorPeer;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
@@ -146,7 +146,7 @@ public class SpuriousBehaviourTest {
|
||||
|
||||
// nonProposer-2 will generate an invalid seal
|
||||
final ValidatorPeer badSealPeer = peers.getNonProposing(2);
|
||||
final Signature illegalSeal = badSealPeer.getnodeKey().sign(Hash.ZERO);
|
||||
final SECPSignature illegalSeal = badSealPeer.getnodeKey().sign(Hash.ZERO);
|
||||
|
||||
badSealPeer.injectCommit(roundId, proposedBlock.getHash(), illegalSeal);
|
||||
assertThat(context.getCurrentChainHeight()).isEqualTo(0);
|
||||
|
||||
@@ -35,7 +35,8 @@ import org.hyperledger.besu.consensus.qbft.statemachine.RoundState;
|
||||
import org.hyperledger.besu.consensus.qbft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
@@ -80,8 +81,9 @@ public class QbftRoundIntegrationTest {
|
||||
|
||||
private Block proposedBlock;
|
||||
|
||||
private final Signature remoteCommitSeal =
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1);
|
||||
private final SECPSignature remoteCommitSeal =
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 1);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.hyperledger.besu.consensus.qbft.messagewrappers;
|
||||
import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.CommitPayload;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
@@ -30,7 +30,7 @@ public class Commit extends BftMessage<CommitPayload> {
|
||||
super(payload);
|
||||
}
|
||||
|
||||
public Signature getCommitSeal() {
|
||||
public SECPSignature getCommitSeal() {
|
||||
return getPayload().getCommitSeal();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.hyperledger.besu.consensus.qbft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException;
|
||||
@@ -85,7 +85,7 @@ public class QbftMessageTransmitter {
|
||||
public void multicastCommit(
|
||||
final ConsensusRoundIdentifier roundIdentifier,
|
||||
final Hash digest,
|
||||
final Signature commitSeal) {
|
||||
final SECPSignature commitSeal) {
|
||||
try {
|
||||
final Commit data = messageFactory.createCommit(roundIdentifier, digest, commitSeal);
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ package org.hyperledger.besu.consensus.qbft.payload;
|
||||
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.Payload;
|
||||
import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||||
@@ -29,12 +30,12 @@ public class CommitPayload implements Payload {
|
||||
private static final int TYPE = QbftV1.COMMIT;
|
||||
private final ConsensusRoundIdentifier roundIdentifier;
|
||||
private final Hash digest;
|
||||
private final Signature commitSeal;
|
||||
private final SECPSignature commitSeal;
|
||||
|
||||
public CommitPayload(
|
||||
final ConsensusRoundIdentifier roundIdentifier,
|
||||
final Hash digest,
|
||||
final Signature commitSeal) {
|
||||
final SECPSignature commitSeal) {
|
||||
this.roundIdentifier = roundIdentifier;
|
||||
this.digest = digest;
|
||||
this.commitSeal = commitSeal;
|
||||
@@ -44,7 +45,8 @@ public class CommitPayload implements Payload {
|
||||
rlpInput.enterList();
|
||||
final ConsensusRoundIdentifier roundIdentifier = ConsensusRoundIdentifier.readFrom(rlpInput);
|
||||
final Hash digest = Payload.readDigest(rlpInput);
|
||||
final Signature commitSeal = rlpInput.readBytes(Signature::decode);
|
||||
final SECPSignature commitSeal =
|
||||
rlpInput.readBytes(SignatureAlgorithmFactory.getInstance()::decodeSignature);
|
||||
rlpInput.leaveList();
|
||||
|
||||
return new CommitPayload(roundIdentifier, digest, commitSeal);
|
||||
@@ -68,7 +70,7 @@ public class CommitPayload implements Payload {
|
||||
return digest;
|
||||
}
|
||||
|
||||
public Signature getCommitSeal() {
|
||||
public SECPSignature getCommitSeal() {
|
||||
return commitSeal;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal;
|
||||
import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange;
|
||||
import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
|
||||
@@ -60,7 +60,7 @@ public class MessageFactory {
|
||||
public Commit createCommit(
|
||||
final ConsensusRoundIdentifier roundIdentifier,
|
||||
final Hash digest,
|
||||
final Signature commitSeal) {
|
||||
final SECPSignature commitSeal) {
|
||||
final CommitPayload payload = new CommitPayload(roundIdentifier, digest, commitSeal);
|
||||
return new Commit(createSignedMessage(payload));
|
||||
}
|
||||
@@ -93,7 +93,7 @@ public class MessageFactory {
|
||||
}
|
||||
|
||||
private <M extends Payload> SignedData<M> createSignedMessage(final M payload) {
|
||||
final Signature signature = nodeKey.sign(hashForSignature(payload));
|
||||
final SECPSignature signature = nodeKey.sign(hashForSignature(payload));
|
||||
return SignedData.create(payload, signature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.hyperledger.besu.consensus.qbft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
@@ -189,7 +189,7 @@ public class QbftRound {
|
||||
if (blockAccepted) {
|
||||
final Block block = roundState.getProposedBlock().get();
|
||||
|
||||
final Signature commitSeal;
|
||||
final SECPSignature commitSeal;
|
||||
try {
|
||||
commitSeal = createCommitSeal(block);
|
||||
} catch (final SecurityModuleException e) {
|
||||
@@ -275,7 +275,7 @@ public class QbftRound {
|
||||
}
|
||||
}
|
||||
|
||||
private Signature createCommitSeal(final Block block) {
|
||||
private SECPSignature createCommitSeal(final Block block) {
|
||||
final BlockHeader proposedHeader = block.getHeader();
|
||||
final BftExtraData extraData = BftExtraData.decode(proposedHeader);
|
||||
final Hash commitHash =
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit;
|
||||
import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare;
|
||||
import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal;
|
||||
import org.hyperledger.besu.consensus.qbft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -119,7 +119,7 @@ public class RoundState {
|
||||
return committed;
|
||||
}
|
||||
|
||||
public Collection<Signature> getCommitSeals() {
|
||||
public Collection<SECPSignature> getCommitSeals() {
|
||||
return commitMessages.stream()
|
||||
.map(cp -> cp.getSignedPayload().getPayload().getCommitSeal())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -19,14 +19,19 @@ import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.CommitPayload;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public class CommitMessage implements RlpTestCaseMessage {
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
private final UnsignedCommit unsignedCommit;
|
||||
private final String signature;
|
||||
|
||||
@@ -49,9 +54,13 @@ public class CommitMessage implements RlpTestCaseMessage {
|
||||
new CommitPayload(
|
||||
new ConsensusRoundIdentifier(unsignedCommit.sequence, unsignedCommit.round),
|
||||
Hash.fromHexStringLenient(unsignedCommit.digest),
|
||||
Signature.decode(Bytes.fromHexString(unsignedCommit.commitSeal)));
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.decodeSignature(Bytes.fromHexString(unsignedCommit.commitSeal)));
|
||||
final SignedData<CommitPayload> signedCommitPayload =
|
||||
SignedData.create(commitPayload, Signature.decode(Bytes.fromHexString(signature)));
|
||||
SignedData.create(
|
||||
commitPayload,
|
||||
SIGNATURE_ALGORITHM.get().decodeSignature(Bytes.fromHexString(signature)));
|
||||
return new Commit(signedCommitPayload);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage;
|
||||
import org.hyperledger.besu.consensus.common.bft.payload.SignedData;
|
||||
import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
@@ -55,7 +55,8 @@ public class PrepareMessage implements RlpTestCaseMessage {
|
||||
new PreparePayload(
|
||||
new ConsensusRoundIdentifier(unsignedPrepare.sequence, unsignedPrepare.round),
|
||||
Hash.fromHexString(unsignedPrepare.digest)),
|
||||
Signature.decode(Bytes.fromHexString(prepareMessage.signature)));
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.decodeSignature(Bytes.fromHexString(prepareMessage.signature)));
|
||||
}
|
||||
|
||||
public static class UnsignedPrepare {
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.hyperledger.besu.consensus.qbft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.ProposalPayload;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.consensus.qbt.support.RoundChangeMessage.SignedRoundChange;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
|
||||
@@ -75,7 +75,9 @@ public class ProposalMessage implements RlpTestCaseMessage {
|
||||
block);
|
||||
final SignedData<ProposalPayload> signedProposalPayload =
|
||||
SignedData.create(
|
||||
proposalPayload, Signature.decode(Bytes.fromHexString(signedProposal.signature)));
|
||||
proposalPayload,
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.decodeSignature(Bytes.fromHexString(signedProposal.signature)));
|
||||
return new Proposal(signedProposalPayload, signedRoundChanges, signedPrepares);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
@@ -115,7 +115,9 @@ public class RoundChangeMessage implements RlpTestCaseMessage {
|
||||
new ConsensusRoundIdentifier(unsignedRoundChange.sequence, unsignedRoundChange.round),
|
||||
preparedRoundMetadata);
|
||||
return SignedData.create(
|
||||
roundChangePayload, Signature.decode(Bytes.fromHexString(signedRoundChange.signature)));
|
||||
roundChangePayload,
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.decodeSignature(Bytes.fromHexString(signedRoundChange.signature)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.CommitPayload;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
@@ -43,7 +43,8 @@ public class CommitTest {
|
||||
new CommitPayload(
|
||||
new ConsensusRoundIdentifier(1, 1),
|
||||
Hash.ZERO,
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 0));
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0));
|
||||
|
||||
final SignedData<CommitPayload> signedCommitPayload =
|
||||
SignedData.create(commitPayload, nodeKey.sign(hashForSignature(commitPayload)));
|
||||
|
||||
@@ -51,7 +51,7 @@ import org.hyperledger.besu.consensus.qbft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.consensus.qbft.validation.MessageValidatorFactory;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
@@ -317,7 +317,8 @@ public class QbftBlockHeightManagerTest {
|
||||
.createCommit(
|
||||
futureRoundIdentifier,
|
||||
Hash.fromHexStringLenient("0"),
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1));
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 1));
|
||||
|
||||
manager.handlePreparePayload(prepare);
|
||||
manager.handleCommitPayload(commit);
|
||||
|
||||
@@ -42,7 +42,8 @@ import org.hyperledger.besu.consensus.qbft.payload.PreparePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
@@ -93,8 +94,9 @@ public class QbftRoundTest {
|
||||
private Block proposedBlock;
|
||||
private BftExtraData proposedExtraData;
|
||||
|
||||
private final Signature remoteCommitSeal =
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1);
|
||||
private final SECPSignature remoteCommitSeal =
|
||||
SignatureAlgorithmFactory.getInstance()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 1);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -223,7 +225,7 @@ public class QbftRoundTest {
|
||||
final Hash commitSealHash =
|
||||
BftBlockHashing.calculateDataHashForCommittedSeal(
|
||||
proposedBlock.getHeader(), proposedExtraData);
|
||||
final Signature localCommitSeal = nodeKey.sign(commitSealHash);
|
||||
final SECPSignature localCommitSeal = nodeKey.sign(commitSealHash);
|
||||
|
||||
round.createAndSendProposalMessage(15);
|
||||
verify(transmitter, never()).multicastCommit(any(), any(), any());
|
||||
|
||||
@@ -28,7 +28,8 @@ import org.hyperledger.besu.consensus.qbft.payload.MessageFactory;
|
||||
import org.hyperledger.besu.consensus.qbft.validation.MessageValidator;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.ethereum.core.Address;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
@@ -38,6 +39,8 @@ import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -48,6 +51,9 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RoundStateTest {
|
||||
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
private final List<NodeKey> validatorKeys = Lists.newArrayList();
|
||||
private final List<MessageFactory> validatorMessageFactories = Lists.newArrayList();
|
||||
private final ConsensusRoundIdentifier roundIdentifier = new ConsensusRoundIdentifier(1, 1);
|
||||
@@ -118,7 +124,9 @@ public class RoundStateTest {
|
||||
.createCommit(
|
||||
roundIdentifier,
|
||||
block.getHash(),
|
||||
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1));
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 1));
|
||||
|
||||
roundState.addCommitMessage(commit);
|
||||
assertThat(roundState.isPrepared()).isFalse();
|
||||
@@ -250,7 +258,9 @@ public class RoundStateTest {
|
||||
.createCommit(
|
||||
roundIdentifier,
|
||||
block.getHash(),
|
||||
Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 1));
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 1));
|
||||
|
||||
final Commit secondCommit =
|
||||
validatorMessageFactories
|
||||
@@ -258,7 +268,9 @@ public class RoundStateTest {
|
||||
.createCommit(
|
||||
roundIdentifier,
|
||||
block.getHash(),
|
||||
Signature.create(BigInteger.TEN, BigInteger.TEN, (byte) 1));
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createSignature(BigInteger.TEN, BigInteger.TEN, (byte) 1));
|
||||
|
||||
final Proposal proposal =
|
||||
validatorMessageFactories
|
||||
|
||||
@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers;
|
||||
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
|
||||
import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -37,7 +37,7 @@ public class CommitValidatorTest {
|
||||
@Test
|
||||
public void commitIsValidIfItMatchesExpectedValues() {
|
||||
for (int i = 0; i < VALIDATOR_COUNT; i++) {
|
||||
final Signature commitSeal = validators.getNode(i).getNodeKey().sign(expectedHash);
|
||||
final SECPSignature commitSeal = validators.getNode(i).getNodeKey().sign(expectedHash);
|
||||
final Commit msg =
|
||||
validators.getMessageFactory(i).createCommit(round, expectedHash, commitSeal);
|
||||
assertThat(validator.validate(msg)).isTrue();
|
||||
@@ -47,7 +47,7 @@ public class CommitValidatorTest {
|
||||
@Test
|
||||
public void commitSignedByANonValidatorFails() {
|
||||
final QbftNode nonValidator = QbftNode.create();
|
||||
final Signature commitSeal = nonValidator.getNodeKey().sign(expectedHash);
|
||||
final SECPSignature commitSeal = nonValidator.getNodeKey().sign(expectedHash);
|
||||
final Commit msg =
|
||||
nonValidator.getMessageFactory().createCommit(round, expectedHash, commitSeal);
|
||||
assertThat(validator.validate(msg)).isFalse();
|
||||
@@ -55,7 +55,7 @@ public class CommitValidatorTest {
|
||||
|
||||
@Test
|
||||
public void commitForWrongRoundFails() {
|
||||
final Signature commitSeal = validators.getNode(0).getNodeKey().sign(expectedHash);
|
||||
final SECPSignature commitSeal = validators.getNode(0).getNodeKey().sign(expectedHash);
|
||||
final Commit msg =
|
||||
validators
|
||||
.getMessageFactory(0)
|
||||
@@ -65,7 +65,7 @@ public class CommitValidatorTest {
|
||||
|
||||
@Test
|
||||
public void commitForWrongSequenceFails() {
|
||||
final Signature commitSeal = validators.getNode(0).getNodeKey().sign(expectedHash);
|
||||
final SECPSignature commitSeal = validators.getNode(0).getNodeKey().sign(expectedHash);
|
||||
final Commit msg =
|
||||
validators
|
||||
.getMessageFactory(0)
|
||||
@@ -75,7 +75,7 @@ public class CommitValidatorTest {
|
||||
|
||||
@Test
|
||||
public void commitWithWrongDigestFails() {
|
||||
final Signature commitSeal = validators.getNode(0).getNodeKey().sign(expectedHash);
|
||||
final SECPSignature commitSeal = validators.getNode(0).getNodeKey().sign(expectedHash);
|
||||
final Commit msg =
|
||||
validators
|
||||
.getMessageFactory(0)
|
||||
@@ -85,7 +85,7 @@ public class CommitValidatorTest {
|
||||
|
||||
@Test
|
||||
public void commitWithMismatchedSealFails() {
|
||||
final Signature commitSeal =
|
||||
final SECPSignature commitSeal =
|
||||
validators.getNode(0).getNodeKey().sign(Hash.fromHexStringLenient("0x2"));
|
||||
final Commit msg =
|
||||
validators.getMessageFactory(0).createCommit(round, expectedHash, commitSeal);
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.BlockValidator;
|
||||
import org.hyperledger.besu.ethereum.BlockValidator.BlockProcessingOutputs;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
@@ -404,7 +404,8 @@ public class RoundChangeMessageValidatorTest {
|
||||
ProposedBlockHelpers.createProposalBlock(Collections.emptyList(), roundIdentifier);
|
||||
|
||||
final RoundChangePayload payload = new RoundChangePayload(targetRound, Optional.empty());
|
||||
final Signature signature = validators.getNode(0).getNodeKey().sign(hashForSignature(payload));
|
||||
final SECPSignature signature =
|
||||
validators.getNode(0).getNodeKey().sign(hashForSignature(payload));
|
||||
|
||||
final RoundChange message =
|
||||
new RoundChange(SignedData.create(payload, signature), Optional.of(block), emptyList());
|
||||
@@ -436,7 +437,8 @@ public class RoundChangeMessageValidatorTest {
|
||||
Optional.of(
|
||||
new PreparedRoundMetadata(
|
||||
Hash.fromHexStringLenient("0x1"), roundIdentifier.getRoundNumber())));
|
||||
final Signature signature = validators.getNode(0).getNodeKey().sign(hashForSignature(payload));
|
||||
final SECPSignature signature =
|
||||
validators.getNode(0).getNodeKey().sign(hashForSignature(payload));
|
||||
|
||||
final RoundChange message =
|
||||
new RoundChange(
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata;
|
||||
import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload;
|
||||
import org.hyperledger.besu.crypto.NodeKey;
|
||||
import org.hyperledger.besu.crypto.NodeKeyUtils;
|
||||
import org.hyperledger.besu.crypto.SECP256K1.Signature;
|
||||
import org.hyperledger.besu.crypto.SECPSignature;
|
||||
import org.hyperledger.besu.ethereum.core.Hash;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -153,7 +153,7 @@ public class RoundChangePayloadValidatorTest {
|
||||
|
||||
private SignedData<RoundChangePayload> createSignedPayload(
|
||||
final RoundChangePayload payload, final NodeKey nodeKey) {
|
||||
final Signature signature = nodeKey.sign(hashForSignature(payload));
|
||||
final SECPSignature signature = nodeKey.sign(hashForSignature(payload));
|
||||
return SignedData.create(payload, signature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
|
||||
|
||||
public class KeyPair {
|
||||
|
||||
private final SECPPrivateKey privateKey;
|
||||
private final SECPPublicKey publicKey;
|
||||
|
||||
public KeyPair(final SECPPrivateKey privateKey, final SECPPublicKey publicKey) {
|
||||
checkNotNull(privateKey);
|
||||
checkNotNull(publicKey);
|
||||
this.privateKey = privateKey;
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public static KeyPair create(
|
||||
final SECPPrivateKey privateKey, final ECDomainParameters curve, final String algorithm) {
|
||||
return new KeyPair(privateKey, SECPPublicKey.create(privateKey, curve, algorithm));
|
||||
}
|
||||
|
||||
public static KeyPair generate(final KeyPairGenerator keyPairGenerator, final String algorithm) {
|
||||
final java.security.KeyPair rawKeyPair = keyPairGenerator.generateKeyPair();
|
||||
final BCECPrivateKey privateKey = (BCECPrivateKey) rawKeyPair.getPrivate();
|
||||
final BCECPublicKey publicKey = (BCECPublicKey) rawKeyPair.getPublic();
|
||||
|
||||
final BigInteger privateKeyValue = privateKey.getD();
|
||||
|
||||
// Ethereum does not use encoded public keys like bitcoin - see
|
||||
// https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm for details
|
||||
// Additionally, as the first bit is a constant prefix (0x04) we ignore this value
|
||||
final byte[] publicKeyBytes = publicKey.getQ().getEncoded(false);
|
||||
final BigInteger publicKeyValue =
|
||||
new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length));
|
||||
|
||||
return new KeyPair(
|
||||
SECPPrivateKey.create(privateKeyValue, algorithm),
|
||||
SECPPublicKey.create(publicKeyValue, algorithm));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(privateKey, publicKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof KeyPair)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final KeyPair that = (KeyPair) other;
|
||||
return this.privateKey.equals(that.privateKey) && this.publicKey.equals(that.publicKey);
|
||||
}
|
||||
|
||||
public SECPPrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public SECPPublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
}
|
||||
@@ -32,17 +32,19 @@ import org.apache.tuweni.bytes.Bytes32;
|
||||
* operations via SECP256K1 class
|
||||
*/
|
||||
public class KeyPairSecurityModule implements SecurityModule {
|
||||
private final SECP256K1.KeyPair keyPair;
|
||||
private final KeyPair keyPair;
|
||||
private final PublicKey publicKey;
|
||||
private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||||
|
||||
public KeyPairSecurityModule(final SECP256K1.KeyPair keyPair) {
|
||||
public KeyPairSecurityModule(final KeyPair keyPair) {
|
||||
this.keyPair = keyPair;
|
||||
this.publicKey = convertPublicKey(keyPair.getPublicKey());
|
||||
}
|
||||
|
||||
private PublicKey convertPublicKey(final SECP256K1.PublicKey publicKey) {
|
||||
private PublicKey convertPublicKey(final SECPPublicKey publicKey) {
|
||||
try {
|
||||
return new PublicKeyImpl(fromBouncyCastleECPoint(publicKey.asEcPoint()));
|
||||
return new PublicKeyImpl(
|
||||
fromBouncyCastleECPoint(signatureAlgorithm.publicKeyAsEcPoint(publicKey)));
|
||||
} catch (final Exception e) {
|
||||
throw new SecurityModuleException(
|
||||
"Unexpected error while converting ECPoint: " + e.getMessage(), e);
|
||||
@@ -52,7 +54,7 @@ public class KeyPairSecurityModule implements SecurityModule {
|
||||
@Override
|
||||
public Signature sign(final Bytes32 dataHash) throws SecurityModuleException {
|
||||
try {
|
||||
final SECP256K1.Signature signature = SECP256K1.sign(dataHash, keyPair);
|
||||
final SECPSignature signature = signatureAlgorithm.sign(dataHash, keyPair);
|
||||
return new SignatureImpl(signature);
|
||||
} catch (final Exception e) {
|
||||
throw new SecurityModuleException("Unexpected error while signing: " + e.getMessage(), e);
|
||||
@@ -69,8 +71,9 @@ public class KeyPairSecurityModule implements SecurityModule {
|
||||
throws SecurityModuleException {
|
||||
try {
|
||||
final Bytes encodedECPoint = ECPointUtil.getEncodedBytes(partyKey.getW());
|
||||
final SECP256K1.PublicKey secp256KPartyKey = SECP256K1.PublicKey.create(encodedECPoint);
|
||||
return SECP256K1.calculateECDHKeyAgreement(keyPair.getPrivateKey(), secp256KPartyKey);
|
||||
final SECPPublicKey secp256KPartyKey = signatureAlgorithm.createPublicKey(encodedECPoint);
|
||||
return signatureAlgorithm.calculateECDHKeyAgreement(
|
||||
keyPair.getPrivateKey(), secp256KPartyKey);
|
||||
} catch (final Exception e) {
|
||||
throw new SecurityModuleException(
|
||||
"Unexpected error while calculating ECDH Key Agreement: " + e.getMessage(), e);
|
||||
@@ -79,9 +82,9 @@ public class KeyPairSecurityModule implements SecurityModule {
|
||||
|
||||
private static class SignatureImpl implements Signature {
|
||||
|
||||
private final SECP256K1.Signature signature;
|
||||
private final SECPSignature signature;
|
||||
|
||||
SignatureImpl(final SECP256K1.Signature signature) {
|
||||
SignatureImpl(final SECPSignature signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.io.Resources;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -32,6 +34,8 @@ import org.apache.tuweni.bytes.Bytes32;
|
||||
|
||||
public class KeyPairUtil {
|
||||
private static final Logger LOG = LogManager.getLogger();
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
public static String loadResourceFile(final String resourcePath) {
|
||||
try {
|
||||
@@ -42,29 +46,30 @@ public class KeyPairUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static SECP256K1.KeyPair loadKeyPairFromResource(final String resourcePath) {
|
||||
final SECP256K1.KeyPair keyPair;
|
||||
public static KeyPair loadKeyPairFromResource(final String resourcePath) {
|
||||
final KeyPair keyPair;
|
||||
String keyData = loadResourceFile(resourcePath);
|
||||
if (keyData == null || keyData.isEmpty()) {
|
||||
throw new IllegalArgumentException("Unable to load resource: " + resourcePath);
|
||||
}
|
||||
SECP256K1.PrivateKey privateKey = SECP256K1.PrivateKey.create(Bytes32.fromHexString((keyData)));
|
||||
keyPair = SECP256K1.KeyPair.create(privateKey);
|
||||
SECPPrivateKey privateKey =
|
||||
SIGNATURE_ALGORITHM.get().createPrivateKey(Bytes32.fromHexString((keyData)));
|
||||
keyPair = SIGNATURE_ALGORITHM.get().createKeyPair(privateKey);
|
||||
|
||||
LOG.info("Loaded keyPair {} from {}", keyPair.getPublicKey().toString(), resourcePath);
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
public static SECP256K1.KeyPair loadKeyPair(final File keyFile) {
|
||||
public static KeyPair loadKeyPair(final File keyFile) {
|
||||
|
||||
final SECP256K1.KeyPair key;
|
||||
final KeyPair key;
|
||||
if (keyFile.exists()) {
|
||||
|
||||
key = load(keyFile);
|
||||
LOG.info(
|
||||
"Loaded public key {} from {}", key.getPublicKey().toString(), keyFile.getAbsolutePath());
|
||||
} else {
|
||||
key = SECP256K1.KeyPair.generate();
|
||||
key = SIGNATURE_ALGORITHM.get().generateKeyPair();
|
||||
try {
|
||||
storeKeyPair(key, keyFile);
|
||||
} catch (IOException e) {
|
||||
@@ -78,7 +83,7 @@ public class KeyPairUtil {
|
||||
return key;
|
||||
}
|
||||
|
||||
public static SECP256K1.KeyPair loadKeyPair(final Path homeDirectory) {
|
||||
public static KeyPair loadKeyPair(final Path homeDirectory) {
|
||||
return loadKeyPair(getDefaultKeyFile(homeDirectory));
|
||||
}
|
||||
|
||||
@@ -86,23 +91,23 @@ public class KeyPairUtil {
|
||||
return homeDirectory.resolve("key").toFile();
|
||||
}
|
||||
|
||||
public static SECP256K1.KeyPair load(final File file) {
|
||||
return SECP256K1.KeyPair.create(loadPrivateKey(file));
|
||||
public static KeyPair load(final File file) {
|
||||
return SIGNATURE_ALGORITHM.get().createKeyPair(loadPrivateKey(file));
|
||||
}
|
||||
|
||||
static SECP256K1.PrivateKey loadPrivateKey(final File file) {
|
||||
static SECPPrivateKey loadPrivateKey(final File file) {
|
||||
try {
|
||||
final List<String> info = Files.readAllLines(file.toPath());
|
||||
if (info.size() != 1) {
|
||||
throw new IllegalArgumentException("Supplied file does not contain valid keyPair pair.");
|
||||
}
|
||||
return SECP256K1.PrivateKey.create(Bytes32.fromHexString((info.get(0))));
|
||||
return SIGNATURE_ALGORITHM.get().createPrivateKey(Bytes32.fromHexString((info.get(0))));
|
||||
} catch (IOException ex) {
|
||||
throw new IllegalArgumentException("Supplied file does not contain valid keyPair pair.");
|
||||
}
|
||||
}
|
||||
|
||||
static void storeKeyPair(final SECP256K1.KeyPair keyKair, final File file) throws IOException {
|
||||
static void storeKeyPair(final KeyPair keyKair, final File file) throws IOException {
|
||||
final File privateKeyDir = file.getParentFile();
|
||||
privateKeyDir.mkdirs();
|
||||
final Path tempPath = Files.createTempFile(privateKeyDir.toPath(), ".tmp", "");
|
||||
|
||||
@@ -22,25 +22,26 @@ import org.apache.tuweni.bytes.Bytes32;
|
||||
public class NodeKey {
|
||||
|
||||
private final SecurityModule securityModule;
|
||||
private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||||
|
||||
public NodeKey(final SecurityModule securityModule) {
|
||||
this.securityModule = securityModule;
|
||||
}
|
||||
|
||||
public SECP256K1.Signature sign(final Bytes32 dataHash) {
|
||||
public SECPSignature sign(final Bytes32 dataHash) {
|
||||
final Signature signature = securityModule.sign(dataHash);
|
||||
|
||||
return SECP256K1.normaliseSignature(
|
||||
return signatureAlgorithm.normaliseSignature(
|
||||
signature.getR(), signature.getS(), getPublicKey(), dataHash);
|
||||
}
|
||||
|
||||
public SECP256K1.PublicKey getPublicKey() {
|
||||
return SECP256K1.PublicKey.create(
|
||||
public SECPPublicKey getPublicKey() {
|
||||
return signatureAlgorithm.createPublicKey(
|
||||
ECPointUtil.getEncodedBytes(securityModule.getPublicKey().getW()));
|
||||
}
|
||||
|
||||
public Bytes32 calculateECDHKeyAgreement(final SECP256K1.PublicKey partyKey) {
|
||||
public Bytes32 calculateECDHKeyAgreement(final SECPPublicKey partyKey) {
|
||||
return securityModule.calculateECDHKeyAgreement(
|
||||
() -> ECPointUtil.fromBouncyCastleECPoint(partyKey.asEcPoint()));
|
||||
() -> ECPointUtil.fromBouncyCastleECPoint(signatureAlgorithm.publicKeyAsEcPoint(partyKey)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.hyperledger.besu.nativelib.secp256k1.LibSecp256k1.SECP256K1_EC_UNCOMPRESSED;
|
||||
|
||||
import org.hyperledger.besu.nativelib.secp256k1.LibSecp256k1;
|
||||
@@ -30,19 +29,15 @@ import java.security.KeyPairGenerator;
|
||||
import java.security.Security;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import com.sun.jna.ptr.LongByReference;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.bytes.MutableBytes;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||
@@ -54,12 +49,9 @@ import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.crypto.signers.ECDSASigner;
|
||||
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.math.ec.ECAlgorithms;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
|
||||
import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve;
|
||||
|
||||
/*
|
||||
@@ -70,48 +62,49 @@ import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve;
|
||||
* Adapted from the web3j (Apache 2 License) implementations:
|
||||
* https://github.com/web3j/web3j/crypto/src/main/java/org/web3j/crypto/*.java
|
||||
*/
|
||||
public class SECP256K1 {
|
||||
public class SECP256K1 implements SignatureAlgorithm {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger();
|
||||
|
||||
private static boolean useNative = true;
|
||||
private boolean useNative = true;
|
||||
|
||||
public static final String ALGORITHM = "ECDSA";
|
||||
public static final String CURVE_NAME = "secp256k1";
|
||||
public static final String PROVIDER = "BC";
|
||||
|
||||
public static final ECDomainParameters CURVE;
|
||||
public static final BigInteger HALF_CURVE_ORDER;
|
||||
private final ECDomainParameters curve;
|
||||
private final BigInteger halfCurveOrder;
|
||||
|
||||
private static final KeyPairGenerator KEY_PAIR_GENERATOR;
|
||||
private static final BigInteger CURVE_ORDER;
|
||||
private final KeyPairGenerator keyPairGenerator;
|
||||
private final BigInteger curveOrder;
|
||||
|
||||
static {
|
||||
public SECP256K1() {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
final X9ECParameters params = SECNamedCurves.getByName(CURVE_NAME);
|
||||
CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
|
||||
CURVE_ORDER = CURVE.getN();
|
||||
HALF_CURVE_ORDER = CURVE_ORDER.shiftRight(1);
|
||||
curve = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
|
||||
curveOrder = curve.getN();
|
||||
halfCurveOrder = curveOrder.shiftRight(1);
|
||||
try {
|
||||
KEY_PAIR_GENERATOR = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
|
||||
keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
final ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec(CURVE_NAME);
|
||||
try {
|
||||
KEY_PAIR_GENERATOR.initialize(ecGenParameterSpec, SecureRandomProvider.createSecureRandom());
|
||||
keyPairGenerator.initialize(ecGenParameterSpec, SecureRandomProvider.createSecureRandom());
|
||||
} catch (final InvalidAlgorithmParameterException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void enableNative() {
|
||||
@Override
|
||||
public void enableNative() {
|
||||
useNative = LibSecp256k1.CONTEXT != null;
|
||||
LOG.info(useNative ? "Using native secp256k1" : "Native secp256k1 requested but not available");
|
||||
}
|
||||
|
||||
public static Signature sign(final Bytes32 dataHash, final KeyPair keyPair) {
|
||||
@Override
|
||||
public SECPSignature sign(final Bytes32 dataHash, final KeyPair keyPair) {
|
||||
if (useNative) {
|
||||
return signNative(dataHash, keyPair);
|
||||
} else {
|
||||
@@ -130,7 +123,8 @@ public class SECP256K1 {
|
||||
* @param pub The public key bytes to use.
|
||||
* @return True if the verification is successful.
|
||||
*/
|
||||
public static boolean verify(final Bytes data, final Signature signature, final PublicKey pub) {
|
||||
@Override
|
||||
public boolean verify(final Bytes data, final SECPSignature signature, final SECPPublicKey pub) {
|
||||
if (useNative) {
|
||||
return verifyNative(data, signature, pub);
|
||||
} else {
|
||||
@@ -139,13 +133,13 @@ public class SECP256K1 {
|
||||
}
|
||||
|
||||
/** Decompress a compressed public key (x co-ord and low-bit of y-coord). */
|
||||
private static ECPoint decompressKey(final BigInteger xBN, final boolean yBit) {
|
||||
private ECPoint decompressKey(final BigInteger xBN, final boolean yBit) {
|
||||
final X9IntegerConverter x9 = new X9IntegerConverter();
|
||||
final byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE.getCurve()));
|
||||
final byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(curve.getCurve()));
|
||||
compEnc[0] = (byte) (yBit ? 0x03 : 0x02);
|
||||
// TODO: Find a better way to handle an invalid point compression here.
|
||||
// Currently ECCurve#decodePoint throws an IllegalArgumentException.
|
||||
return CURVE.getCurve().decodePoint(compEnc);
|
||||
return curve.getCurve().decodePoint(compEnc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,7 +158,7 @@ public class SECP256K1 {
|
||||
* @param dataHash Hash of the data that was signed.
|
||||
* @return An ECKey containing only the public part, or null if recovery wasn't possible.
|
||||
*/
|
||||
private static BigInteger recoverFromSignature(
|
||||
private BigInteger recoverFromSignature(
|
||||
final int recId, final BigInteger r, final BigInteger s, final Bytes32 dataHash) {
|
||||
assert (recId >= 0);
|
||||
assert (r.signum() >= 0);
|
||||
@@ -173,7 +167,7 @@ public class SECP256K1 {
|
||||
|
||||
// 1.0 For j from 0 to h (h == recId here and the loop is outside this function)
|
||||
// 1.1 Let x = r + jn
|
||||
final BigInteger n = CURVE.getN(); // Curve order.
|
||||
final BigInteger n = curve.getN(); // Curve order.
|
||||
final BigInteger i = BigInteger.valueOf((long) recId / 2);
|
||||
final BigInteger x = r.add(i.multiply(n));
|
||||
// 1.2. Convert the integer x to an octet string X of length mlen using the conversion
|
||||
@@ -216,7 +210,7 @@ public class SECP256K1 {
|
||||
final BigInteger rInv = r.modInverse(n);
|
||||
final BigInteger srInv = rInv.multiply(s).mod(n);
|
||||
final BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
|
||||
final ECPoint q = ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv);
|
||||
final ECPoint q = ECAlgorithms.sumOfTwoMultiplies(curve.getG(), eInvrInv, R, srInv);
|
||||
|
||||
if (q.isInfinity()) {
|
||||
return null;
|
||||
@@ -227,12 +221,12 @@ public class SECP256K1 {
|
||||
return new BigInteger(1, Arrays.copyOfRange(qBytes, 1, qBytes.length));
|
||||
}
|
||||
|
||||
private static Signature signDefault(final Bytes32 dataHash, final KeyPair keyPair) {
|
||||
private SECPSignature signDefault(final Bytes32 dataHash, final KeyPair keyPair) {
|
||||
final ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
|
||||
|
||||
final ECPrivateKeyParameters privKey =
|
||||
new ECPrivateKeyParameters(
|
||||
keyPair.getPrivateKey().getEncodedBytes().toUnsignedBigInteger(), CURVE);
|
||||
keyPair.getPrivateKey().getEncodedBytes().toUnsignedBigInteger(), curve);
|
||||
signer.init(true, privKey);
|
||||
|
||||
final BigInteger[] components = signer.generateSignature(dataHash.toArrayUnsafe());
|
||||
@@ -240,10 +234,11 @@ public class SECP256K1 {
|
||||
return normaliseSignature(components[0], components[1], keyPair.getPublicKey(), dataHash);
|
||||
}
|
||||
|
||||
public static Signature normaliseSignature(
|
||||
@Override
|
||||
public SECPSignature normaliseSignature(
|
||||
final BigInteger nativeR,
|
||||
final BigInteger nativeS,
|
||||
final PublicKey publicKey,
|
||||
final SECPPublicKey publicKey,
|
||||
final Bytes32 dataHash) {
|
||||
|
||||
BigInteger s = nativeS;
|
||||
@@ -253,14 +248,14 @@ public class SECP256K1 {
|
||||
// ability to modify the bits of a Bitcoin transaction after it's been signed, as that
|
||||
// violates various assumed invariants. Thus in future only one of those forms will be
|
||||
// considered legal and the other will be banned.
|
||||
if (s.compareTo(HALF_CURVE_ORDER) > 0) {
|
||||
if (s.compareTo(halfCurveOrder) > 0) {
|
||||
// The order of the curve is the number of valid points that exist on that curve.
|
||||
// If S is in the upper half of the number of valid points, then bring it back to
|
||||
// the lower half. Otherwise, imagine that
|
||||
// N = 10
|
||||
// s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) are valid solutions.
|
||||
// 10 - 8 == 2, giving us always the latter solution, which is canonical.
|
||||
s = CURVE.getN().subtract(s);
|
||||
s = curve.getN().subtract(s);
|
||||
}
|
||||
|
||||
// Now we have to work backwards to figure out the recId needed to recover the signature.
|
||||
@@ -278,18 +273,18 @@ public class SECP256K1 {
|
||||
"Could not construct a recoverable key. This should never happen.");
|
||||
}
|
||||
|
||||
return new Signature(nativeR, s, (byte) recId);
|
||||
return new SECPSignature(nativeR, s, (byte) recId);
|
||||
}
|
||||
|
||||
private static boolean verifyDefault(
|
||||
final Bytes data, final Signature signature, final PublicKey pub) {
|
||||
private boolean verifyDefault(
|
||||
final Bytes data, final SECPSignature signature, final SECPPublicKey pub) {
|
||||
final ECDSASigner signer = new ECDSASigner();
|
||||
final Bytes toDecode = Bytes.wrap(Bytes.of((byte) 4), pub.getEncodedBytes());
|
||||
final ECPublicKeyParameters params =
|
||||
new ECPublicKeyParameters(CURVE.getCurve().decodePoint(toDecode.toArrayUnsafe()), CURVE);
|
||||
new ECPublicKeyParameters(curve.getCurve().decodePoint(toDecode.toArrayUnsafe()), curve);
|
||||
signer.init(false, params);
|
||||
try {
|
||||
return signer.verifySignature(data.toArrayUnsafe(), signature.r, signature.s);
|
||||
return signer.verifySignature(data.toArrayUnsafe(), signature.getR(), signature.getS());
|
||||
} catch (final NullPointerException e) {
|
||||
// Bouncy Castle contains a bug that can cause NPEs given specially crafted signatures. Those
|
||||
// signatures
|
||||
@@ -309,10 +304,11 @@ public class SECP256K1 {
|
||||
* a hashing function.
|
||||
* @return True if the verification is successful.
|
||||
*/
|
||||
public static boolean verify(
|
||||
@Override
|
||||
public boolean verify(
|
||||
final Bytes data,
|
||||
final Signature signature,
|
||||
final PublicKey pub,
|
||||
final SECPSignature signature,
|
||||
final SECPPublicKey pub,
|
||||
final UnaryOperator<Bytes> preprocessor) {
|
||||
checkArgument(preprocessor != null, "preprocessor must not be null");
|
||||
return verify(preprocessor.apply(data), signature, pub);
|
||||
@@ -325,13 +321,15 @@ public class SECP256K1 {
|
||||
* @param theirPubKey The public key.
|
||||
* @return The agreed secret.
|
||||
*/
|
||||
public static Bytes32 calculateECDHKeyAgreement(
|
||||
final PrivateKey privKey, final PublicKey theirPubKey) {
|
||||
@Override
|
||||
public Bytes32 calculateECDHKeyAgreement(
|
||||
final SECPPrivateKey privKey, final SECPPublicKey theirPubKey) {
|
||||
checkArgument(privKey != null, "missing private key");
|
||||
checkArgument(theirPubKey != null, "missing remote public key");
|
||||
|
||||
final ECPrivateKeyParameters privKeyP = new ECPrivateKeyParameters(privKey.getD(), CURVE);
|
||||
final ECPublicKeyParameters pubKeyP = new ECPublicKeyParameters(theirPubKey.asEcPoint(), CURVE);
|
||||
final ECPrivateKeyParameters privKeyP = new ECPrivateKeyParameters(privKey.getD(), curve);
|
||||
final ECPublicKeyParameters pubKeyP =
|
||||
new ECPublicKeyParameters(theirPubKey.asEcPoint(curve), curve);
|
||||
|
||||
final ECDHBasicAgreement agreement = new ECDHBasicAgreement();
|
||||
agreement.init(privKeyP);
|
||||
@@ -340,7 +338,84 @@ public class SECP256K1 {
|
||||
return UInt256.valueOf(agreed).toBytes();
|
||||
}
|
||||
|
||||
private static Signature signNative(final Bytes32 dataHash, final KeyPair keyPair) {
|
||||
@Override
|
||||
public SECPPrivateKey createPrivateKey(final BigInteger key) {
|
||||
return SECPPrivateKey.create(key, ALGORITHM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SECPPrivateKey createPrivateKey(final Bytes32 key) {
|
||||
return SECPPrivateKey.create(key, ALGORITHM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SECPPublicKey createPublicKey(final SECPPrivateKey privateKey) {
|
||||
return SECPPublicKey.create(privateKey, curve, ALGORITHM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SECPPublicKey createPublicKey(final BigInteger key) {
|
||||
return SECPPublicKey.create(key, ALGORITHM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SECPPublicKey createPublicKey(final Bytes encoded) {
|
||||
return SECPPublicKey.create(encoded, ALGORITHM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SECPPublicKey> recoverPublicKeyFromSignature(
|
||||
final Bytes32 dataHash, final SECPSignature signature) {
|
||||
if (useNative) {
|
||||
return recoverFromSignatureNative(dataHash, signature);
|
||||
} else {
|
||||
final BigInteger publicKeyBI =
|
||||
recoverFromSignature(signature.getRecId(), signature.getR(), signature.getS(), dataHash);
|
||||
return Optional.of(SECPPublicKey.create(publicKeyBI, ALGORITHM));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ECPoint publicKeyAsEcPoint(final SECPPublicKey publicKey) {
|
||||
return publicKey.asEcPoint(curve);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPair createKeyPair(final SECPPrivateKey privateKey) {
|
||||
return KeyPair.create(privateKey, curve, ALGORITHM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPair generateKeyPair() {
|
||||
return KeyPair.generate(keyPairGenerator, ALGORITHM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SECPSignature createSignature(final BigInteger r, final BigInteger s, final byte recId) {
|
||||
return SECPSignature.create(r, s, recId, curveOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SECPSignature decodeSignature(final Bytes bytes) {
|
||||
return SECPSignature.decode(bytes, curveOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getHalfCurveOrder() {
|
||||
return halfCurveOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvider() {
|
||||
return PROVIDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurveName() {
|
||||
return CURVE_NAME;
|
||||
}
|
||||
|
||||
private SECPSignature signNative(final Bytes32 dataHash, final KeyPair keyPair) {
|
||||
final LibSecp256k1.secp256k1_ecdsa_recoverable_signature signature =
|
||||
new secp256k1_ecdsa_recoverable_signature();
|
||||
// sign in internal form
|
||||
@@ -348,7 +423,7 @@ public class SECP256K1 {
|
||||
LibSecp256k1.CONTEXT,
|
||||
signature,
|
||||
dataHash.toArrayUnsafe(),
|
||||
keyPair.privateKey.getEncoded(),
|
||||
keyPair.getPrivateKey().getEncoded(),
|
||||
null,
|
||||
null)
|
||||
== 0) {
|
||||
@@ -367,12 +442,12 @@ public class SECP256K1 {
|
||||
// wrap in signature object
|
||||
final Bytes32 r = Bytes32.wrap(sig, 0);
|
||||
final Bytes32 s = Bytes32.wrap(sig, 32);
|
||||
return Signature.create(
|
||||
r.toUnsignedBigInteger(), s.toUnsignedBigInteger(), (byte) recId.getValue());
|
||||
return SECPSignature.create(
|
||||
r.toUnsignedBigInteger(), s.toUnsignedBigInteger(), (byte) recId.getValue(), curveOrder);
|
||||
}
|
||||
|
||||
private static boolean verifyNative(
|
||||
final Bytes data, final Signature signature, final PublicKey pub) {
|
||||
private boolean verifyNative(
|
||||
final Bytes data, final SECPSignature signature, final SECPPublicKey pub) {
|
||||
|
||||
// translate signature
|
||||
final LibSecp256k1.secp256k1_ecdsa_signature _signature = new secp256k1_ecdsa_signature();
|
||||
@@ -396,8 +471,8 @@ public class SECP256K1 {
|
||||
!= 0;
|
||||
}
|
||||
|
||||
private static Optional<PublicKey> recoverFromSignatureNative(
|
||||
final Bytes32 dataHash, final Signature signature) {
|
||||
private Optional<SECPPublicKey> recoverFromSignatureNative(
|
||||
final Bytes32 dataHash, final SECPSignature signature) {
|
||||
|
||||
// parse the sig
|
||||
final LibSecp256k1.secp256k1_ecdsa_recoverable_signature parsedSignature =
|
||||
@@ -426,360 +501,7 @@ public class SECP256K1 {
|
||||
LibSecp256k1.secp256k1_ec_pubkey_serialize(
|
||||
LibSecp256k1.CONTEXT, recoveredKey, keySize, newPubKey, SECP256K1_EC_UNCOMPRESSED);
|
||||
|
||||
return Optional.of(PublicKey.create(Bytes.wrapByteBuffer(recoveredKey).slice(1)));
|
||||
}
|
||||
|
||||
public static class PrivateKey implements java.security.PrivateKey {
|
||||
|
||||
private final Bytes32 encoded;
|
||||
|
||||
private PrivateKey(final Bytes32 encoded) {
|
||||
checkNotNull(encoded);
|
||||
this.encoded = encoded;
|
||||
}
|
||||
|
||||
public static PrivateKey create(final BigInteger key) {
|
||||
checkNotNull(key);
|
||||
return create(UInt256.valueOf(key).toBytes());
|
||||
}
|
||||
|
||||
public static PrivateKey create(final Bytes32 key) {
|
||||
return new PrivateKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof PrivateKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PrivateKey that = (PrivateKey) other;
|
||||
return this.encoded.equals(that.encoded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return encoded.toArrayUnsafe();
|
||||
}
|
||||
|
||||
public Bytes32 getEncodedBytes() {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
public BigInteger getD() {
|
||||
return encoded.toUnsignedBigInteger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return ALGORITHM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return encoded.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return encoded.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class PublicKey implements java.security.PublicKey {
|
||||
|
||||
public static final int BYTE_LENGTH = 64;
|
||||
|
||||
private final Bytes encoded;
|
||||
|
||||
public static PublicKey create(final PrivateKey privateKey) {
|
||||
BigInteger privKey = privateKey.getEncodedBytes().toUnsignedBigInteger();
|
||||
|
||||
/*
|
||||
* TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group
|
||||
* order, but that could change in future versions.
|
||||
*/
|
||||
if (privKey.bitLength() > CURVE.getN().bitLength()) {
|
||||
privKey = privKey.mod(CURVE.getN());
|
||||
}
|
||||
|
||||
final ECPoint point = new FixedPointCombMultiplier().multiply(CURVE.getG(), privKey);
|
||||
return PublicKey.create(Bytes.wrap(Arrays.copyOfRange(point.getEncoded(false), 1, 65)));
|
||||
}
|
||||
|
||||
private static Bytes toBytes64(final byte[] backing) {
|
||||
if (backing.length == BYTE_LENGTH) {
|
||||
return Bytes.wrap(backing);
|
||||
} else if (backing.length > BYTE_LENGTH) {
|
||||
return Bytes.wrap(backing, backing.length - BYTE_LENGTH, BYTE_LENGTH);
|
||||
} else {
|
||||
final MutableBytes res = MutableBytes.create(BYTE_LENGTH);
|
||||
Bytes.wrap(backing).copyTo(res, BYTE_LENGTH - backing.length);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public static PublicKey create(final BigInteger key) {
|
||||
checkNotNull(key);
|
||||
return create(toBytes64(key.toByteArray()));
|
||||
}
|
||||
|
||||
public static PublicKey create(final Bytes encoded) {
|
||||
return new PublicKey(encoded);
|
||||
}
|
||||
|
||||
public static Optional<PublicKey> recoverFromSignature(
|
||||
final Bytes32 dataHash, final Signature signature) {
|
||||
if (useNative) {
|
||||
return recoverFromSignatureNative(dataHash, signature);
|
||||
} else {
|
||||
final BigInteger publicKeyBI =
|
||||
SECP256K1.recoverFromSignature(
|
||||
signature.getRecId(), signature.getR(), signature.getS(), dataHash);
|
||||
return Optional.ofNullable(publicKeyBI).map(PublicKey::create);
|
||||
}
|
||||
}
|
||||
|
||||
private PublicKey(final Bytes encoded) {
|
||||
checkNotNull(encoded);
|
||||
checkArgument(
|
||||
encoded.size() == BYTE_LENGTH,
|
||||
"Encoding must be %s bytes long, got %s",
|
||||
BYTE_LENGTH,
|
||||
encoded.size());
|
||||
this.encoded = encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this public key as an {@link ECPoint} of Bouncy Castle, to facilitate cryptographic
|
||||
* operations.
|
||||
*
|
||||
* @return This public key represented as an Elliptic Curve point.
|
||||
*/
|
||||
public ECPoint asEcPoint() {
|
||||
// 0x04 is the prefix for uncompressed keys.
|
||||
final Bytes val = Bytes.concatenate(Bytes.of(0x04), encoded);
|
||||
return CURVE.getCurve().decodePoint(val.toArrayUnsafe());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof PublicKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PublicKey that = (PublicKey) other;
|
||||
return this.encoded.equals(that.encoded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return encoded.toArrayUnsafe();
|
||||
}
|
||||
|
||||
public Bytes getEncodedBytes() {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return ALGORITHM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return encoded.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return encoded.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class KeyPair {
|
||||
|
||||
private final PrivateKey privateKey;
|
||||
private final PublicKey publicKey;
|
||||
|
||||
public KeyPair(final PrivateKey privateKey, final PublicKey publicKey) {
|
||||
checkNotNull(privateKey);
|
||||
checkNotNull(publicKey);
|
||||
this.privateKey = privateKey;
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public static KeyPair create(final PrivateKey privateKey) {
|
||||
return new KeyPair(privateKey, PublicKey.create(privateKey));
|
||||
}
|
||||
|
||||
public static KeyPair generate() {
|
||||
final java.security.KeyPair rawKeyPair = KEY_PAIR_GENERATOR.generateKeyPair();
|
||||
final BCECPrivateKey privateKey = (BCECPrivateKey) rawKeyPair.getPrivate();
|
||||
final BCECPublicKey publicKey = (BCECPublicKey) rawKeyPair.getPublic();
|
||||
|
||||
final BigInteger privateKeyValue = privateKey.getD();
|
||||
|
||||
// Ethereum does not use encoded public keys like bitcoin - see
|
||||
// https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm for details
|
||||
// Additionally, as the first bit is a constant prefix (0x04) we ignore this value
|
||||
final byte[] publicKeyBytes = publicKey.getQ().getEncoded(false);
|
||||
final BigInteger publicKeyValue =
|
||||
new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length));
|
||||
|
||||
return new KeyPair(PrivateKey.create(privateKeyValue), PublicKey.create(publicKeyValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(privateKey, publicKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof KeyPair)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final KeyPair that = (KeyPair) other;
|
||||
return this.privateKey.equals(that.privateKey) && this.publicKey.equals(that.publicKey);
|
||||
}
|
||||
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Signature {
|
||||
|
||||
public static final int BYTES_REQUIRED = 65;
|
||||
/**
|
||||
* The recovery id to reconstruct the public key used to create the signature.
|
||||
*
|
||||
* <p>The recId is an index from 0 to 3 which indicates which of the 4 possible keys is the
|
||||
* correct one. Because the key recovery operation yields multiple potential keys, the correct
|
||||
* key must either be stored alongside the signature, or you must be willing to try each recId
|
||||
* in turn until you find one that outputs the key you are expecting.
|
||||
*/
|
||||
private final byte recId;
|
||||
|
||||
private final BigInteger r;
|
||||
private final BigInteger s;
|
||||
|
||||
private final Supplier<Bytes> encoded = Suppliers.memoize(this::_encodedBytes);
|
||||
|
||||
Signature(final BigInteger r, final BigInteger s, final byte recId) {
|
||||
this.r = r;
|
||||
this.s = s;
|
||||
this.recId = recId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new signature object given its parameters.
|
||||
*
|
||||
* @param r the 'r' part of the signature.
|
||||
* @param s the 's' part of the signature.
|
||||
* @param recId the recovery id part of the signature.
|
||||
* @return the created {@link Signature} object.
|
||||
* @throws NullPointerException if {@code r} or {@code s} are {@code null}.
|
||||
* @throws IllegalArgumentException if any argument is invalid (for instance, {@code v} is
|
||||
* neither 27 or 28).
|
||||
*/
|
||||
public static Signature create(final BigInteger r, final BigInteger s, final byte recId) {
|
||||
checkNotNull(r);
|
||||
checkNotNull(s);
|
||||
checkInBounds("r", r);
|
||||
checkInBounds("s", s);
|
||||
if (recId != 0 && recId != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid 'recId' value, should be 0 or 1 but got " + recId);
|
||||
}
|
||||
return new Signature(r, s, recId);
|
||||
}
|
||||
|
||||
private static void checkInBounds(final String name, final BigInteger i) {
|
||||
if (i.compareTo(BigInteger.ONE) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Invalid '%s' value, should be >= 1 but got %s", name, i));
|
||||
}
|
||||
|
||||
if (i.compareTo(CURVE_ORDER) >= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Invalid '%s' value, should be < %s but got %s", CURVE_ORDER, name, i));
|
||||
}
|
||||
}
|
||||
|
||||
public static Signature decode(final Bytes bytes) {
|
||||
checkArgument(
|
||||
bytes.size() == BYTES_REQUIRED, "encoded SECP256K1 signature must be 65 bytes long");
|
||||
|
||||
final BigInteger r = bytes.slice(0, 32).toUnsignedBigInteger();
|
||||
final BigInteger s = bytes.slice(32, 32).toUnsignedBigInteger();
|
||||
final byte recId = bytes.get(64);
|
||||
return SECP256K1.Signature.create(r, s, recId);
|
||||
}
|
||||
|
||||
public Bytes encodedBytes() {
|
||||
return encoded.get();
|
||||
}
|
||||
|
||||
private Bytes _encodedBytes() {
|
||||
final MutableBytes bytes = MutableBytes.create(BYTES_REQUIRED);
|
||||
UInt256.valueOf(r).toBytes().copyTo(bytes, 0);
|
||||
UInt256.valueOf(s).toBytes().copyTo(bytes, 32);
|
||||
bytes.set(64, recId);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof Signature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Signature that = (Signature) other;
|
||||
return this.r.equals(that.r) && this.s.equals(that.s) && this.recId == that.recId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(r, s, recId);
|
||||
}
|
||||
|
||||
public byte getRecId() {
|
||||
return recId;
|
||||
}
|
||||
|
||||
public BigInteger getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
public BigInteger getS() {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("SECP256K1.Signature").append("{");
|
||||
sb.append("r=").append(r).append(", ");
|
||||
sb.append("s=").append(s).append(", ");
|
||||
sb.append("recId=").append(recId);
|
||||
return sb.append("}").toString();
|
||||
}
|
||||
return Optional.of(
|
||||
SECPPublicKey.create(Bytes.wrapByteBuffer(recoveredKey).slice(1), ALGORITHM));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
public class SECPPrivateKey implements java.security.PrivateKey {
|
||||
|
||||
private final Bytes32 encoded;
|
||||
private final String algorithm;
|
||||
|
||||
private SECPPrivateKey(final Bytes32 encoded, final String algorithm) {
|
||||
checkNotNull(encoded);
|
||||
checkNotNull(algorithm);
|
||||
this.encoded = encoded;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public static SECPPrivateKey create(final BigInteger key, final String algorithm) {
|
||||
checkNotNull(key);
|
||||
return create(UInt256.valueOf(key).toBytes(), algorithm);
|
||||
}
|
||||
|
||||
public static SECPPrivateKey create(final Bytes32 key, final String algorithm) {
|
||||
return new SECPPrivateKey(key, algorithm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof SECPPrivateKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final SECPPrivateKey that = (SECPPrivateKey) other;
|
||||
return this.encoded.equals(that.encoded) && this.algorithm.equals(that.algorithm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return encoded.toArrayUnsafe();
|
||||
}
|
||||
|
||||
public Bytes32 getEncodedBytes() {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
public BigInteger getD() {
|
||||
return encoded.toUnsignedBigInteger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return encoded.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return encoded.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.MutableBytes;
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
|
||||
|
||||
public class SECPPublicKey implements java.security.PublicKey {
|
||||
|
||||
public static final int BYTE_LENGTH = 64;
|
||||
|
||||
private final Bytes encoded;
|
||||
private final String algorithm;
|
||||
|
||||
public static SECPPublicKey create(final BigInteger key, final String algorithm) {
|
||||
checkNotNull(key);
|
||||
return create(toBytes64(key.toByteArray()), algorithm);
|
||||
}
|
||||
|
||||
public static SECPPublicKey create(final Bytes encoded, final String algorithm) {
|
||||
return new SECPPublicKey(encoded, algorithm);
|
||||
}
|
||||
|
||||
public static SECPPublicKey create(
|
||||
final SECPPrivateKey privateKey, final ECDomainParameters curve, final String algorithm) {
|
||||
BigInteger privKey = privateKey.getEncodedBytes().toUnsignedBigInteger();
|
||||
|
||||
/*
|
||||
* TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group
|
||||
* order, but that could change in future versions.
|
||||
*/
|
||||
if (privKey.bitLength() > curve.getN().bitLength()) {
|
||||
privKey = privKey.mod(curve.getN());
|
||||
}
|
||||
|
||||
final ECPoint point = new FixedPointCombMultiplier().multiply(curve.getG(), privKey);
|
||||
return SECPPublicKey.create(
|
||||
Bytes.wrap(Arrays.copyOfRange(point.getEncoded(false), 1, 65)), algorithm);
|
||||
}
|
||||
|
||||
private static Bytes toBytes64(final byte[] backing) {
|
||||
if (backing.length == BYTE_LENGTH) {
|
||||
return Bytes.wrap(backing);
|
||||
} else if (backing.length > BYTE_LENGTH) {
|
||||
return Bytes.wrap(backing, backing.length - BYTE_LENGTH, BYTE_LENGTH);
|
||||
} else {
|
||||
final MutableBytes res = MutableBytes.create(BYTE_LENGTH);
|
||||
Bytes.wrap(backing).copyTo(res, BYTE_LENGTH - backing.length);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
private SECPPublicKey(final Bytes encoded, final String algorithm) {
|
||||
checkNotNull(encoded);
|
||||
checkNotNull(algorithm);
|
||||
checkArgument(
|
||||
encoded.size() == BYTE_LENGTH,
|
||||
"Encoding must be %s bytes long, got %s",
|
||||
BYTE_LENGTH,
|
||||
encoded.size());
|
||||
this.encoded = encoded;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this public key as an {@link ECPoint} of Bouncy Castle, to facilitate cryptographic
|
||||
* operations.
|
||||
*
|
||||
* @param curve The elliptic curve (e.g. SECP256K1) represented as its domain parameters
|
||||
* @return This public key represented as an Elliptic Curve point.
|
||||
*/
|
||||
public ECPoint asEcPoint(final ECDomainParameters curve) {
|
||||
// 0x04 is the prefix for uncompressed keys.
|
||||
final Bytes val = Bytes.concatenate(Bytes.of(0x04), encoded);
|
||||
return curve.getCurve().decodePoint(val.toArrayUnsafe());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof SECPPublicKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final SECPPublicKey that = (SECPPublicKey) other;
|
||||
return this.encoded.equals(that.encoded) && this.algorithm.equals(that.algorithm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return encoded.toArrayUnsafe();
|
||||
}
|
||||
|
||||
public Bytes getEncodedBytes() {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return encoded.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return encoded.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.MutableBytes;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
public class SECPSignature {
|
||||
|
||||
public static final int BYTES_REQUIRED = 65;
|
||||
/**
|
||||
* The recovery id to reconstruct the public key used to create the signature.
|
||||
*
|
||||
* <p>The recId is an index from 0 to 3 which indicates which of the 4 possible keys is the
|
||||
* correct one. Because the key recovery operation yields multiple potential keys, the correct key
|
||||
* must either be stored alongside the signature, or you must be willing to try each recId in turn
|
||||
* until you find one that outputs the key you are expecting.
|
||||
*/
|
||||
private final byte recId;
|
||||
|
||||
private final BigInteger r;
|
||||
private final BigInteger s;
|
||||
|
||||
private final Supplier<Bytes> encoded = Suppliers.memoize(this::_encodedBytes);
|
||||
|
||||
SECPSignature(final BigInteger r, final BigInteger s, final byte recId) {
|
||||
this.r = r;
|
||||
this.s = s;
|
||||
this.recId = recId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new signature object given its parameters.
|
||||
*
|
||||
* @param r the 'r' part of the signature.
|
||||
* @param s the 's' part of the signature.
|
||||
* @param recId the recovery id part of the signature.
|
||||
* @param curveOrder The order (n) of the used curve
|
||||
* @return the created {@link SECPSignature} object.
|
||||
* @throws NullPointerException if {@code r} or {@code s} are {@code null}.
|
||||
* @throws IllegalArgumentException if any argument is invalid (for instance, {@code v} is neither
|
||||
* 27 or 28).
|
||||
*/
|
||||
public static SECPSignature create(
|
||||
final BigInteger r, final BigInteger s, final byte recId, final BigInteger curveOrder) {
|
||||
checkNotNull(r);
|
||||
checkNotNull(s);
|
||||
checkInBounds("r", r, curveOrder);
|
||||
checkInBounds("s", s, curveOrder);
|
||||
if (recId != 0 && recId != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid 'recId' value, should be 0 or 1 but got " + recId);
|
||||
}
|
||||
return new SECPSignature(r, s, recId);
|
||||
}
|
||||
|
||||
private static void checkInBounds(
|
||||
final String name, final BigInteger i, final BigInteger curveOrder) {
|
||||
if (i.compareTo(BigInteger.ONE) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Invalid '%s' value, should be >= 1 but got %s", name, i));
|
||||
}
|
||||
|
||||
if (i.compareTo(curveOrder) >= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Invalid '%s' value, should be < %s but got %s", curveOrder, name, i));
|
||||
}
|
||||
}
|
||||
|
||||
public static SECPSignature decode(final Bytes bytes, final BigInteger curveOrder) {
|
||||
checkArgument(
|
||||
bytes.size() == BYTES_REQUIRED, "encoded SECP256K1 signature must be 65 bytes long");
|
||||
|
||||
final BigInteger r = bytes.slice(0, 32).toUnsignedBigInteger();
|
||||
final BigInteger s = bytes.slice(32, 32).toUnsignedBigInteger();
|
||||
final byte recId = bytes.get(64);
|
||||
return SECPSignature.create(r, s, recId, curveOrder);
|
||||
}
|
||||
|
||||
public Bytes encodedBytes() {
|
||||
return encoded.get();
|
||||
}
|
||||
|
||||
private Bytes _encodedBytes() {
|
||||
final MutableBytes bytes = MutableBytes.create(BYTES_REQUIRED);
|
||||
UInt256.valueOf(r).toBytes().copyTo(bytes, 0);
|
||||
UInt256.valueOf(s).toBytes().copyTo(bytes, 32);
|
||||
bytes.set(64, recId);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof SECPSignature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final SECPSignature that = (SECPSignature) other;
|
||||
return this.r.equals(that.r) && this.s.equals(that.s) && this.recId == that.recId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(r, s, recId);
|
||||
}
|
||||
|
||||
public byte getRecId() {
|
||||
return recId;
|
||||
}
|
||||
|
||||
public BigInteger getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
public BigInteger getS() {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Signature").append("{");
|
||||
sb.append("r=").append(r).append(", ");
|
||||
sb.append("s=").append(s).append(", ");
|
||||
sb.append("recId=").append(recId);
|
||||
return sb.append("}").toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Optional;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
|
||||
public interface SignatureAlgorithm {
|
||||
// needs to be known at compile time otherwise triggers InsecureCryptoUsage error
|
||||
String ALGORITHM = "ECDSA";
|
||||
|
||||
void enableNative();
|
||||
|
||||
SECPSignature sign(final Bytes32 dataHash, final KeyPair keyPair);
|
||||
|
||||
boolean verify(final Bytes data, final SECPSignature signature, final SECPPublicKey pub);
|
||||
|
||||
boolean verify(
|
||||
final Bytes data,
|
||||
final SECPSignature signature,
|
||||
final SECPPublicKey pub,
|
||||
final UnaryOperator<Bytes> preprocessor);
|
||||
|
||||
SECPSignature normaliseSignature(
|
||||
final BigInteger nativeR,
|
||||
final BigInteger nativeS,
|
||||
final SECPPublicKey publicKey,
|
||||
final Bytes32 dataHash);
|
||||
|
||||
Bytes32 calculateECDHKeyAgreement(final SECPPrivateKey privKey, final SECPPublicKey theirPubKey);
|
||||
|
||||
BigInteger getHalfCurveOrder();
|
||||
|
||||
String getProvider();
|
||||
|
||||
String getCurveName();
|
||||
|
||||
SECPPrivateKey createPrivateKey(final BigInteger key);
|
||||
|
||||
SECPPrivateKey createPrivateKey(final Bytes32 key);
|
||||
|
||||
SECPPublicKey createPublicKey(final SECPPrivateKey privateKey);
|
||||
|
||||
SECPPublicKey createPublicKey(final BigInteger key);
|
||||
|
||||
SECPPublicKey createPublicKey(final Bytes encoded);
|
||||
|
||||
Optional<SECPPublicKey> recoverPublicKeyFromSignature(
|
||||
final Bytes32 dataHash, final SECPSignature signature);
|
||||
|
||||
ECPoint publicKeyAsEcPoint(final SECPPublicKey publicKey);
|
||||
|
||||
KeyPair createKeyPair(final SECPPrivateKey privateKey);
|
||||
|
||||
KeyPair generateKeyPair();
|
||||
|
||||
SECPSignature createSignature(final BigInteger r, final BigInteger s, final byte recId);
|
||||
|
||||
SECPSignature decodeSignature(final Bytes bytes);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
public class SignatureAlgorithmFactory {
|
||||
|
||||
private static final SignatureAlgorithm instance = new SECP256K1();
|
||||
|
||||
public static SignatureAlgorithm getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,12 @@ package org.hyperledger.besu.crypto;
|
||||
|
||||
public class NodeKeyUtils {
|
||||
|
||||
public static NodeKey createFrom(final SECP256K1.KeyPair keyPair) {
|
||||
public static NodeKey createFrom(final KeyPair keyPair) {
|
||||
return new NodeKey(new KeyPairSecurityModule(keyPair));
|
||||
}
|
||||
|
||||
public static NodeKey generate() {
|
||||
return new NodeKey(new KeyPairSecurityModule(SECP256K1.KeyPair.generate()));
|
||||
return new NodeKey(
|
||||
new KeyPairSecurityModule(SignatureAlgorithmFactory.getInstance().generateKeyPair()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +33,13 @@ public class KeyPairSecurityModuleTest {
|
||||
final File keyDirectory = temp.newFolder();
|
||||
final File keyFile = new File(keyDirectory, "key");
|
||||
|
||||
final SECP256K1.KeyPair keyPair = KeyPairUtil.loadKeyPair(keyFile);
|
||||
final KeyPair keyPair = KeyPairUtil.loadKeyPair(keyFile);
|
||||
|
||||
final KeyPairSecurityModule keyPairSecurityModule = new KeyPairSecurityModule(keyPair);
|
||||
final ECPoint ecPoint = keyPairSecurityModule.getPublicKey().getW();
|
||||
final Bytes encodedBytes = ECPointUtil.getEncodedBytes(ecPoint);
|
||||
final SECP256K1.PublicKey publicKey = SECP256K1.PublicKey.create(encodedBytes);
|
||||
final SECPPublicKey publicKey =
|
||||
SignatureAlgorithmFactory.getInstance().createPublicKey(encodedBytes);
|
||||
|
||||
Assertions.assertThat(keyPair.getPublicKey().getEncodedBytes())
|
||||
.isEqualByComparingTo(publicKey.getEncodedBytes());
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import static org.apache.tuweni.bytes.Bytes.fromHexString;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.Security;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class KeyPairTest {
|
||||
public static final String ALGORITHM = SignatureAlgorithm.ALGORITHM;
|
||||
public static final String PROVIDER = "BC";
|
||||
public static final String CURVE_NAME = "secp256k1";
|
||||
|
||||
public static KeyPairGenerator keyPairGenerator;
|
||||
public static ECDomainParameters curve;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
try {
|
||||
keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
final X9ECParameters params = SECNamedCurves.getByName(CURVE_NAME);
|
||||
curve = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createKeyPair_PublicKeyNull() {
|
||||
new KeyPair(null, SECPPublicKey.create(Bytes.wrap(new byte[64]), ALGORITHM));
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createKeyPair_PrivateKeyNull() {
|
||||
new KeyPair(SECPPrivateKey.create(Bytes32.wrap(new byte[32]), ALGORITHM), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keyPairGeneration() {
|
||||
final KeyPair keyPair = KeyPair.generate(keyPairGenerator, ALGORITHM);
|
||||
assertThat(keyPair).isNotNull();
|
||||
assertThat(keyPair.getPrivateKey()).isNotNull();
|
||||
assertThat(keyPair.getPublicKey()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keyPairEquals() {
|
||||
final SECPPrivateKey privateKey1 = SECPPrivateKey.create(BigInteger.TEN, ALGORITHM);
|
||||
final SECPPrivateKey privateKey2 = SECPPrivateKey.create(BigInteger.TEN, ALGORITHM);
|
||||
final SECPPublicKey publicKey1 =
|
||||
SECPPublicKey.create(
|
||||
fromHexString(
|
||||
"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7"),
|
||||
ALGORITHM);
|
||||
final SECPPublicKey publicKey2 =
|
||||
SECPPublicKey.create(
|
||||
fromHexString(
|
||||
"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7"),
|
||||
ALGORITHM);
|
||||
|
||||
final KeyPair keyPair1 = new KeyPair(privateKey1, publicKey1);
|
||||
final KeyPair keyPair2 = new KeyPair(privateKey2, publicKey2);
|
||||
|
||||
assertThat(keyPair2).isEqualTo(keyPair1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keyPairHashCode() {
|
||||
final KeyPair keyPair = KeyPair.generate(keyPairGenerator, ALGORITHM);
|
||||
assertThat(keyPair.hashCode()).isNotZero();
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,9 @@ public class NodeKeyTest {
|
||||
final Bytes32 keyPairPrvKey =
|
||||
Bytes32.fromHexString("0xf7a58d5e755d51fa2f6206e91dd574597c73248aaf946ec1964b8c6268d6207b");
|
||||
|
||||
final SECP256K1.KeyPair keyPair =
|
||||
SECP256K1.KeyPair.create(SECP256K1.PrivateKey.create(keyPairPrvKey));
|
||||
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
|
||||
final KeyPair keyPair =
|
||||
signatureAlgorithm.createKeyPair(signatureAlgorithm.createPrivateKey(keyPairPrvKey));
|
||||
final KeyPairSecurityModule keyPairSecurityModule = new KeyPairSecurityModule(keyPair);
|
||||
final NodeKey nodeKey = new NodeKey(keyPairSecurityModule);
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.apache.tuweni.bytes.Bytes.fromHexString;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.crypto.Hash.keccak256;
|
||||
|
||||
@@ -28,11 +27,14 @@ import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SECP256K1Test {
|
||||
|
||||
protected SECP256K1 secp256K1;
|
||||
|
||||
protected static String suiteStartTime = null;
|
||||
protected static String suiteName = null;
|
||||
|
||||
@@ -42,6 +44,12 @@ public class SECP256K1Test {
|
||||
LocalDateTime.now(ZoneId.systemDefault())
|
||||
.format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss"));
|
||||
suiteName(SECP256K1Test.class);
|
||||
;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
secp256K1 = new SECP256K1();
|
||||
}
|
||||
|
||||
public static void suiteName(final Class<?> clazz) {
|
||||
@@ -52,218 +60,60 @@ public class SECP256K1Test {
|
||||
return suiteName;
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createPrivateKey_NullEncoding() {
|
||||
SECP256K1.PrivateKey.create((Bytes32) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void privateKeyEquals() {
|
||||
final SECP256K1.PrivateKey privateKey1 = SECP256K1.PrivateKey.create(BigInteger.TEN);
|
||||
final SECP256K1.PrivateKey privateKey2 = SECP256K1.PrivateKey.create(BigInteger.TEN);
|
||||
|
||||
assertThat(privateKey2).isEqualTo(privateKey1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void privateHashCode() {
|
||||
final SECP256K1.PrivateKey privateKey = SECP256K1.PrivateKey.create(BigInteger.TEN);
|
||||
|
||||
assertThat(privateKey.hashCode()).isNotZero();
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createPublicKey_NullEncoding() {
|
||||
SECP256K1.PublicKey.create((Bytes) null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createPublicKey_EncodingTooShort() {
|
||||
SECP256K1.PublicKey.create(Bytes.wrap(new byte[63]));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createPublicKey_EncodingTooLong() {
|
||||
SECP256K1.PublicKey.create(Bytes.wrap(new byte[65]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publicKeyEquals() {
|
||||
final SECP256K1.PublicKey publicKey1 =
|
||||
SECP256K1.PublicKey.create(
|
||||
fromHexString(
|
||||
"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7"));
|
||||
final SECP256K1.PublicKey publicKey2 =
|
||||
SECP256K1.PublicKey.create(
|
||||
fromHexString(
|
||||
"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7"));
|
||||
|
||||
assertThat(publicKey2).isEqualTo(publicKey1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publicHashCode() {
|
||||
final SECP256K1.PublicKey publicKey =
|
||||
SECP256K1.PublicKey.create(
|
||||
fromHexString(
|
||||
"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7"));
|
||||
|
||||
assertThat(publicKey.hashCode()).isNotZero();
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createKeyPair_PublicKeyNull() {
|
||||
new SECP256K1.KeyPair(null, SECP256K1.PublicKey.create(Bytes.wrap(new byte[64])));
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createKeyPair_PrivateKeyNull() {
|
||||
new SECP256K1.KeyPair(SECP256K1.PrivateKey.create(Bytes32.wrap(new byte[32])), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keyPairGeneration() {
|
||||
final SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.generate();
|
||||
assertThat(keyPair).isNotNull();
|
||||
assertThat(keyPair.getPrivateKey()).isNotNull();
|
||||
assertThat(keyPair.getPublicKey()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keyPairEquals() {
|
||||
final SECP256K1.PrivateKey privateKey1 = SECP256K1.PrivateKey.create(BigInteger.TEN);
|
||||
final SECP256K1.PrivateKey privateKey2 = SECP256K1.PrivateKey.create(BigInteger.TEN);
|
||||
final SECP256K1.PublicKey publicKey1 =
|
||||
SECP256K1.PublicKey.create(
|
||||
fromHexString(
|
||||
"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7"));
|
||||
final SECP256K1.PublicKey publicKey2 =
|
||||
SECP256K1.PublicKey.create(
|
||||
fromHexString(
|
||||
"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7"));
|
||||
|
||||
final SECP256K1.KeyPair keyPair1 = new SECP256K1.KeyPair(privateKey1, publicKey1);
|
||||
final SECP256K1.KeyPair keyPair2 = new SECP256K1.KeyPair(privateKey2, publicKey2);
|
||||
|
||||
assertThat(keyPair2).isEqualTo(keyPair1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keyPairHashCode() {
|
||||
final SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.generate();
|
||||
assertThat(keyPair.hashCode()).isNotZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keyPairGeneration_PublicKeyRecovery() {
|
||||
final SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.generate();
|
||||
assertThat(SECP256K1.PublicKey.create(keyPair.getPrivateKey()))
|
||||
final KeyPair keyPair = secp256K1.generateKeyPair();
|
||||
assertThat(secp256K1.createPublicKey(keyPair.getPrivateKey()))
|
||||
.isEqualTo(keyPair.getPublicKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publicKeyRecovery() {
|
||||
final SECP256K1.PrivateKey privateKey = SECP256K1.PrivateKey.create(BigInteger.TEN);
|
||||
final SECP256K1.PublicKey expectedPublicKey =
|
||||
SECP256K1.PublicKey.create(
|
||||
fromHexString(
|
||||
"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7"));
|
||||
|
||||
final SECP256K1.PublicKey publicKey = SECP256K1.PublicKey.create(privateKey);
|
||||
assertThat(publicKey).isEqualTo(expectedPublicKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSignature() {
|
||||
final SECP256K1.Signature signature =
|
||||
SECP256K1.Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 0);
|
||||
assertThat(signature.getR()).isEqualTo(BigInteger.ONE);
|
||||
assertThat(signature.getS()).isEqualTo(BigInteger.TEN);
|
||||
assertThat(signature.getRecId()).isEqualTo((byte) 0);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createSignature_NoR() {
|
||||
SECP256K1.Signature.create(null, BigInteger.ZERO, (byte) 27);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createSignature_NoS() {
|
||||
SECP256K1.Signature.create(BigInteger.ZERO, null, (byte) 27);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recoverPublicKeyFromSignature() {
|
||||
final SECP256K1.PrivateKey privateKey =
|
||||
SECP256K1.PrivateKey.create(
|
||||
final SECPPrivateKey privateKey =
|
||||
secp256K1.createPrivateKey(
|
||||
new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16));
|
||||
final SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.create(privateKey);
|
||||
final KeyPair keyPair = secp256K1.createKeyPair(privateKey);
|
||||
|
||||
final Bytes data = Bytes.wrap("This is an example of a signed message.".getBytes(UTF_8));
|
||||
final Bytes32 dataHash = keccak256(data);
|
||||
final SECP256K1.Signature signature = SECP256K1.sign(dataHash, keyPair);
|
||||
final SECPSignature signature = secp256K1.sign(dataHash, keyPair);
|
||||
|
||||
final SECP256K1.PublicKey recoveredPublicKey =
|
||||
SECP256K1.PublicKey.recoverFromSignature(dataHash, signature).get();
|
||||
final SECPPublicKey recoveredPublicKey =
|
||||
secp256K1.recoverPublicKeyFromSignature(dataHash, signature).get();
|
||||
assertThat(recoveredPublicKey.toString()).isEqualTo(keyPair.getPublicKey().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signatureGeneration() {
|
||||
final SECP256K1.PrivateKey privateKey =
|
||||
SECP256K1.PrivateKey.create(
|
||||
final SECPPrivateKey privateKey =
|
||||
secp256K1.createPrivateKey(
|
||||
new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16));
|
||||
final SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.create(privateKey);
|
||||
final KeyPair keyPair = secp256K1.createKeyPair(privateKey);
|
||||
|
||||
final Bytes data = Bytes.wrap("This is an example of a signed message.".getBytes(UTF_8));
|
||||
final Bytes32 dataHash = keccak256(data);
|
||||
final SECP256K1.Signature expectedSignature =
|
||||
SECP256K1.Signature.create(
|
||||
final SECPSignature expectedSignature =
|
||||
secp256K1.createSignature(
|
||||
new BigInteger("d2ce488f4da29e68f22cb05cac1b19b75df170a12b4ad1bdd4531b8e9115c6fb", 16),
|
||||
new BigInteger("75c1fe50a95e8ccffcbb5482a1e42fbbdd6324131dfe75c3b3b7f9a7c721eccb", 16),
|
||||
(byte) 1);
|
||||
|
||||
final SECP256K1.Signature actualSignature = SECP256K1.sign(dataHash, keyPair);
|
||||
final SECPSignature actualSignature = secp256K1.sign(dataHash, keyPair);
|
||||
assertThat(actualSignature).isEqualTo(expectedSignature);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signatureVerification() {
|
||||
final SECP256K1.PrivateKey privateKey =
|
||||
SECP256K1.PrivateKey.create(
|
||||
final SECPPrivateKey privateKey =
|
||||
secp256K1.createPrivateKey(
|
||||
new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16));
|
||||
final SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.create(privateKey);
|
||||
final KeyPair keyPair = secp256K1.createKeyPair(privateKey);
|
||||
|
||||
final Bytes data = Bytes.wrap("This is an example of a signed message.".getBytes(UTF_8));
|
||||
final Bytes32 dataHash = keccak256(data);
|
||||
|
||||
final SECP256K1.Signature signature = SECP256K1.sign(dataHash, keyPair);
|
||||
assertThat(SECP256K1.verify(data, signature, keyPair.getPublicKey(), Hash::keccak256)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fileContainsValidPrivateKey() throws Exception {
|
||||
final File file =
|
||||
new File(
|
||||
this.getClass()
|
||||
.getResource("/org/hyperledger/besu/crypto/validPrivateKey.txt")
|
||||
.toURI());
|
||||
final SECP256K1.PrivateKey privateKey = KeyPairUtil.loadPrivateKey(file);
|
||||
assertThat(privateKey.getEncodedBytes())
|
||||
.isEqualTo(
|
||||
Bytes.fromHexString(
|
||||
"000000000000000000000000000000000000000000000000000000000000000A"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readWritePrivateKeyString() throws Exception {
|
||||
final SECP256K1.PrivateKey privateKey = SECP256K1.PrivateKey.create(BigInteger.TEN);
|
||||
final SECP256K1.KeyPair keyPair1 = SECP256K1.KeyPair.create(privateKey);
|
||||
final File tempFile = Files.createTempFile(suiteName(), ".keypair").toFile();
|
||||
tempFile.deleteOnExit();
|
||||
KeyPairUtil.storeKeyPair(keyPair1, tempFile);
|
||||
final SECP256K1.KeyPair keyPair2 = KeyPairUtil.load(tempFile);
|
||||
assertThat(keyPair2).isEqualTo(keyPair1);
|
||||
final SECPSignature signature = secp256K1.sign(dataHash, keyPair);
|
||||
assertThat(secp256K1.verify(data, signature, keyPair.getPublicKey(), Hash::keccak256)).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user