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>
pull/1965/head
Daniel Lehrner 4 years ago committed by GitHub
parent e2963d69af
commit 8315ba6dc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 26
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/account/Account.java
  2. 2
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java
  3. 22
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java
  4. 10
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java
  5. 17
      besu/src/main/java/org/hyperledger/besu/chainimport/internal/TransactionData.java
  6. 7
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  7. 20
      besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java
  8. 23
      besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java
  9. 4
      besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java
  10. 16
      besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java
  11. 10
      besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java
  12. 4
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueBlockHashing.java
  13. 30
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueExtraData.java
  14. 6
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueBlockInterfaceTest.java
  15. 5
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueDifficultyCalculatorTest.java
  16. 21
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueExtraDataTest.java
  17. 8
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/NodeCanProduceNextBlockTest.java
  18. 9
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/TestHelpers.java
  19. 5
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java
  20. 5
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockSchedulerTest.java
  21. 13
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMiningCoordinatorTest.java
  22. 5
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/CliqueDifficultyValidationRuleTest.java
  23. 7
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/CliqueExtraDataValidationRuleTest.java
  24. 13
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java
  25. 4
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftHelpers.java
  26. 6
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/messagewrappers/BftMessage.java
  27. 8
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/payload/SignedData.java
  28. 4
      consensus/common/src/test-support/java/org/hyperledger/besu/consensus/common/bft/inttest/DefaultValidatorPeer.java
  29. 5
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/VoteTallyUpdaterTest.java
  30. 4
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BftExtraDataFixture.java
  31. 59
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BftExtraDataTest.java
  32. 8
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/network/ValidatorPeersTest.java
  33. 4
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/queries/BftQueryServiceImplTest.java
  34. 4
      consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/IntegrationTestHelpers.java
  35. 4
      consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/RoundSpecificPeers.java
  36. 6
      consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/ValidatorPeer.java
  37. 4
      consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/tests/SpuriousBehaviourTest.java
  38. 8
      consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/tests/round/IbftRoundIntegrationTest.java
  39. 4
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/messagewrappers/Commit.java
  40. 4
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/network/IbftMessageTransmitter.java
  41. 12
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/payload/CommitPayload.java
  42. 6
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/payload/MessageFactory.java
  43. 17
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/payload/PayloadDeserializers.java
  44. 6
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRound.java
  45. 4
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/RoundState.java
  46. 15
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/BftBlockHashingTest.java
  47. 7
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/payload/CommitPayloadTest.java
  48. 15
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/payload/PreparedCertificateTest.java
  49. 7
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/payload/RoundChangeCertificateTest.java
  50. 15
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/payload/RoundChangePayloadTest.java
  51. 5
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java
  52. 12
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundTest.java
  53. 11
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/RoundStateTest.java
  54. 4
      consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHashing.java
  55. 29
      consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftExtraData.java
  56. 6
      consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/IbftBlockCreator.java
  57. 37
      consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftExtraDataTest.java
  58. 25
      consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactoryTest.java
  59. 6
      consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterfaceTest.java
  60. 9
      consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/TestHelpers.java
  61. 5
      consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/BftBlockCreatorTest.java
  62. 34
      consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/BftExtraDataValidationRuleTest.java
  63. 1
      consensus/qbft/build.gradle
  64. 4
      consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/IntegrationTestHelpers.java
  65. 4
      consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/RoundSpecificPeers.java
  66. 6
      consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/ValidatorPeer.java
  67. 4
      consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/SpuriousBehaviourTest.java
  68. 8
      consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java
  69. 4
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Commit.java
  70. 4
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/network/QbftMessageTransmitter.java
  71. 12
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/CommitPayload.java
  72. 6
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/MessageFactory.java
  73. 6
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java
  74. 4
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundState.java
  75. 15
      consensus/qbft/src/reference-test/java/org/hyperledger/besu/consensus/qbt/support/CommitMessage.java
  76. 5
      consensus/qbft/src/reference-test/java/org/hyperledger/besu/consensus/qbt/support/PrepareMessage.java
  77. 6
      consensus/qbft/src/reference-test/java/org/hyperledger/besu/consensus/qbt/support/ProposalMessage.java
  78. 6
      consensus/qbft/src/reference-test/java/org/hyperledger/besu/consensus/qbt/support/RoundChangeMessage.java
  79. 5
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/CommitTest.java
  80. 5
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java
  81. 10
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java
  82. 20
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundStateTest.java
  83. 14
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/CommitValidatorTest.java
  84. 8
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidatorTest.java
  85. 4
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangePayloadValidatorTest.java
  86. 86
      crypto/src/main/java/org/hyperledger/besu/crypto/KeyPair.java
  87. 21
      crypto/src/main/java/org/hyperledger/besu/crypto/KeyPairSecurityModule.java
  88. 31
      crypto/src/main/java/org/hyperledger/besu/crypto/KeyPairUtil.java
  89. 13
      crypto/src/main/java/org/hyperledger/besu/crypto/NodeKey.java
  90. 544
      crypto/src/main/java/org/hyperledger/besu/crypto/SECP256K1.java
  91. 87
      crypto/src/main/java/org/hyperledger/besu/crypto/SECPPrivateKey.java
  92. 137
      crypto/src/main/java/org/hyperledger/besu/crypto/SECPPublicKey.java
  93. 149
      crypto/src/main/java/org/hyperledger/besu/crypto/SECPSignature.java
  94. 77
      crypto/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java
  95. 24
      crypto/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithmFactory.java
  96. 5
      crypto/src/test-support/java/org/hyperledger/besu/crypto/NodeKeyUtils.java
  97. 5
      crypto/src/test/java/org/hyperledger/besu/crypto/KeyPairSecurityModuleTest.java
  98. 99
      crypto/src/test/java/org/hyperledger/besu/crypto/KeyPairTest.java
  99. 5
      crypto/src/test/java/org/hyperledger/besu/crypto/NodeKeyTest.java
  100. 206
      crypto/src/test/java/org/hyperledger/besu/crypto/SECP256K1Test.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -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

Loading…
Cancel
Save