use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BridgeStorageProviderTest method createSaveAndRecreateInstanceWithTxsWaitingForSignatures.
@Test
public void createSaveAndRecreateInstanceWithTxsWaitingForSignatures() throws IOException {
BtcTransaction tx1 = createTransaction();
BtcTransaction tx2 = createTransaction();
BtcTransaction tx3 = createTransaction();
Keccak256 hash1 = PegTestUtils.createHash3();
Keccak256 hash2 = PegTestUtils.createHash3();
Keccak256 hash3 = PegTestUtils.createHash3();
Repository repository = new RepositoryImpl(config);
Repository track = repository.startTracking();
BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
provider0.getRskTxsWaitingForSignatures().put(hash1, tx1);
provider0.getRskTxsWaitingForSignatures().put(hash2, tx2);
provider0.getRskTxsWaitingForSignatures().put(hash3, tx3);
provider0.save();
track.commit();
track = repository.startTracking();
BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
SortedMap<Keccak256, BtcTransaction> signatures = provider.getRskTxsWaitingForSignatures();
Assert.assertNotNull(signatures);
Assert.assertTrue(signatures.containsKey(hash1));
Assert.assertTrue(signatures.containsKey(hash2));
Assert.assertTrue(signatures.containsKey(hash3));
Assert.assertEquals(tx1.getHash(), signatures.get(hash1).getHash());
Assert.assertEquals(tx2.getHash(), signatures.get(hash2).getHash());
Assert.assertEquals(tx3.getHash(), signatures.get(hash3).getHash());
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BridgeSupportTest method addSignatureFromValidFederator.
/**
* Helper method to test addSignature() with a valid federatorPublicKey parameter and both valid/invalid signatures
* @param privateKeysToSignWith keys used to sign the tx. Federator key when we want to produce a valid signature, a random key when we want to produce an invalid signature
* @param numberOfInputsToSign There is just 1 input. 1 when testing the happy case, other values to test attacks/bugs.
* @param signatureCanonical Signature should be canonical. true when testing the happy case, false to test attacks/bugs.
* @param signTwice Sign again with the same key
* @param expectedResult "InvalidParameters", "PartiallySigned" or "FullySigned"
*/
private void addSignatureFromValidFederator(List<BtcECKey> privateKeysToSignWith, int numberOfInputsToSign, boolean signatureCanonical, boolean signTwice, String expectedResult) throws Exception {
// Federation is the genesis federation ATM
Federation federation = bridgeConstants.getGenesisFederation();
Repository repository = new RepositoryImpl(config);
final Keccak256 keccak256 = PegTestUtils.createHash3();
Repository track = repository.startTracking();
BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
BtcTransaction prevTx = new BtcTransaction(btcParams);
TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, federation.getAddress());
prevTx.addOutput(prevOut);
BtcTransaction t = new BtcTransaction(btcParams);
TransactionOutput output = new TransactionOutput(btcParams, t, Coin.COIN, new BtcECKey().toAddress(btcParams));
t.addOutput(output);
t.addInput(prevOut).setScriptSig(PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation));
provider.getRskTxsWaitingForSignatures().put(keccak256, t);
provider.save();
track.commit();
track = repository.startTracking();
List<LogInfo> logs = new ArrayList<>();
BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeConstants, logs);
BridgeSupport bridgeSupport = new BridgeSupport(config, track, eventLogger, contractAddress, (Block) null);
Script inputScript = t.getInputs().get(0).getScriptSig();
List<ScriptChunk> chunks = inputScript.getChunks();
byte[] program = chunks.get(chunks.size() - 1).data;
Script redeemScript = new Script(program);
Sha256Hash sighash = t.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false);
BtcECKey.ECDSASignature sig = privateKeysToSignWith.get(0).sign(sighash);
if (!signatureCanonical) {
sig = new BtcECKey.ECDSASignature(sig.r, BtcECKey.CURVE.getN().subtract(sig.s));
}
byte[] derEncodedSig = sig.encodeToDER();
List derEncodedSigs = new ArrayList();
for (int i = 0; i < numberOfInputsToSign; i++) {
derEncodedSigs.add(derEncodedSig);
}
bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeysToSignWith.get(0)), derEncodedSigs, keccak256.getBytes());
if (signTwice) {
// Create another valid signature with the same private key
ECDSASigner signer = new ECDSASigner();
ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKeysToSignWith.get(0).getPrivKey(), BtcECKey.CURVE);
signer.init(true, privKey);
BigInteger[] components = signer.generateSignature(sighash.getBytes());
BtcECKey.ECDSASignature sig2 = new BtcECKey.ECDSASignature(components[0], components[1]).toCanonicalised();
bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeysToSignWith.get(0)), Lists.newArrayList(sig2.encodeToDER()), keccak256.getBytes());
}
if (privateKeysToSignWith.size() > 1) {
BtcECKey.ECDSASignature sig2 = privateKeysToSignWith.get(1).sign(sighash);
byte[] derEncodedSig2 = sig2.encodeToDER();
List derEncodedSigs2 = new ArrayList();
for (int i = 0; i < numberOfInputsToSign; i++) {
derEncodedSigs2.add(derEncodedSig2);
}
bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeysToSignWith.get(1)), derEncodedSigs2, keccak256.getBytes());
}
bridgeSupport.save();
track.commit();
provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
if ("FullySigned".equals(expectedResult)) {
Assert.assertTrue(provider.getRskTxsWaitingForSignatures().isEmpty());
Assert.assertThat(logs, is(not(empty())));
Assert.assertThat(logs, hasSize(3));
LogInfo releaseTxEvent = logs.get(2);
Assert.assertThat(releaseTxEvent.getTopics(), hasSize(1));
Assert.assertThat(releaseTxEvent.getTopics(), hasItem(Bridge.RELEASE_BTC_TOPIC));
BtcTransaction releaseTx = new BtcTransaction(bridgeConstants.getBtcParams(), ((RLPList) RLP.decode2(releaseTxEvent.getData()).get(0)).get(1).getRLPData());
Script retrievedScriptSig = releaseTx.getInput(0).getScriptSig();
Assert.assertEquals(4, retrievedScriptSig.getChunks().size());
Assert.assertEquals(true, retrievedScriptSig.getChunks().get(1).data.length > 0);
Assert.assertEquals(true, retrievedScriptSig.getChunks().get(2).data.length > 0);
} else {
Script retrievedScriptSig = provider.getRskTxsWaitingForSignatures().get(keccak256).getInput(0).getScriptSig();
Assert.assertEquals(4, retrievedScriptSig.getChunks().size());
// for "InvalidParameters"
boolean expectSignatureToBePersisted = false;
if ("PartiallySigned".equals(expectedResult)) {
expectSignatureToBePersisted = true;
}
Assert.assertEquals(expectSignatureToBePersisted, retrievedScriptSig.getChunks().get(1).data.length > 0);
Assert.assertEquals(false, retrievedScriptSig.getChunks().get(2).data.length > 0);
}
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BridgeSupportTest method addSignatureCreateEventLog.
@Test
public void addSignatureCreateEventLog() throws Exception {
// Setup
Federation federation = bridgeConstants.getGenesisFederation();
Repository track = new RepositoryImpl(config).startTracking();
BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants);
// Build prev btc tx
BtcTransaction prevTx = new BtcTransaction(btcParams);
TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, federation.getAddress());
prevTx.addOutput(prevOut);
// Build btc tx to be signed
BtcTransaction btcTx = new BtcTransaction(btcParams);
btcTx.addInput(prevOut).setScriptSig(PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation));
TransactionOutput output = new TransactionOutput(btcParams, btcTx, Coin.COIN, new BtcECKey().toAddress(btcParams));
btcTx.addOutput(output);
// Save btc tx to be signed
final Keccak256 rskTxHash = PegTestUtils.createHash3();
provider.getRskTxsWaitingForSignatures().put(rskTxHash, btcTx);
provider.save();
track.commit();
// Setup BridgeSupport
List<LogInfo> eventLogs = new ArrayList<>();
BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeConstants, eventLogs);
BridgeSupport bridgeSupport = new BridgeSupport(config, track, eventLogger, contractAddress, null);
// Create signed hash of Btc tx
Script inputScript = btcTx.getInputs().get(0).getScriptSig();
List<ScriptChunk> chunks = inputScript.getChunks();
byte[] program = chunks.get(chunks.size() - 1).data;
Script redeemScript = new Script(program);
Sha256Hash sigHash = btcTx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false);
BtcECKey privateKeyToSignWith = ((BridgeRegTestConstants) bridgeConstants).getFederatorPrivateKeys().get(0);
BtcECKey.ECDSASignature sig = privateKeyToSignWith.sign(sigHash);
List derEncodedSigs = Collections.singletonList(sig.encodeToDER());
BtcECKey federatorPubKey = findPublicKeySignedBy(federation.getPublicKeys(), privateKeyToSignWith);
bridgeSupport.addSignature(1, federatorPubKey, derEncodedSigs, rskTxHash.getBytes());
Assert.assertEquals(1, eventLogs.size());
// Assert address that made the log
LogInfo result = eventLogs.get(0);
Assert.assertArrayEquals(PrecompiledContracts.BRIDGE_ADDR.getBytes(), result.getAddress());
// Assert log topics
Assert.assertEquals(1, result.getTopics().size());
Assert.assertEquals(Bridge.ADD_SIGNATURE_TOPIC, result.getTopics().get(0));
// Assert log data
Assert.assertNotNull(result.getData());
List<RLPElement> rlpData = RLP.decode2(result.getData());
Assert.assertEquals(1, rlpData.size());
RLPList dataList = (RLPList) rlpData.get(0);
Assert.assertEquals(3, dataList.size());
Assert.assertArrayEquals(btcTx.getHashAsString().getBytes(), dataList.get(0).getRLPData());
Assert.assertArrayEquals(federatorPubKey.getPubKeyHash(), dataList.get(1).getRLPData());
Assert.assertArrayEquals(rskTxHash.getBytes(), dataList.get(2).getRLPData());
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class PegTestUtils method createHash3.
public static Keccak256 createHash3() {
byte[] bytes = new byte[32];
nhash++;
bytes[0] = (byte) (nhash & 0xFF);
bytes[1] = (byte) (nhash >> 8 & 0xFF);
Keccak256 hash = new Keccak256(bytes);
return hash;
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class MinerServerTest method buildBlockToMineCheckThatLastTransactionIsForREMASC.
@Test
public void buildBlockToMineCheckThatLastTransactionIsForREMASC() {
EthereumImpl ethereumImpl = Mockito.mock(EthereumImpl.class);
Repository repository = Mockito.mock(Repository.class);
Mockito.when(repository.getSnapshotTo(Mockito.any())).thenReturn(repository);
Mockito.when(repository.getRoot()).thenReturn(blockchain.getRepository().getRoot());
Mockito.when(repository.startTracking()).thenReturn(repository);
Transaction tx1 = Tx.create(config, 0, 21000, 100, 0, 0, 0);
byte[] s1 = new byte[32];
s1[0] = 0;
Mockito.when(tx1.getHash()).thenReturn(new Keccak256(s1));
Mockito.when(tx1.getEncoded()).thenReturn(new byte[32]);
Mockito.when(repository.getNonce(tx1.getSender())).thenReturn(BigInteger.ZERO);
Mockito.when(repository.getNonce(RemascTransaction.REMASC_ADDRESS)).thenReturn(BigInteger.ZERO);
Mockito.when(repository.getBalance(tx1.getSender())).thenReturn(Coin.valueOf(4200000L));
Mockito.when(repository.getBalance(RemascTransaction.REMASC_ADDRESS)).thenReturn(Coin.valueOf(4200000L));
List<Transaction> txs = new ArrayList<>(Collections.singletonList(tx1));
TransactionPool localTransactionPool = Mockito.mock(TransactionPool.class);
Mockito.when(localTransactionPool.getPendingTransactions()).thenReturn(txs);
BlockUnclesValidationRule unclesValidationRule = Mockito.mock(BlockUnclesValidationRule.class);
Mockito.when(unclesValidationRule.isValid(Mockito.any())).thenReturn(true);
MinerServerImpl minerServer = new MinerServerImpl(config, ethereumImpl, this.blockchain, null, DIFFICULTY_CALCULATOR, new ProofOfWorkRule(config).setFallbackMiningEnabled(false), new BlockToMineBuilder(ConfigUtils.getDefaultMiningConfig(), repository, this.blockchain.getBlockStore(), localTransactionPool, DIFFICULTY_CALCULATOR, new GasLimitCalculator(config), unclesValidationRule, config, null), ConfigUtils.getDefaultMiningConfig());
minerServer.buildBlockToMine(blockchain.getBestBlock(), false);
Block blockAtHeightOne = minerServer.getBlocksWaitingforPoW().entrySet().iterator().next().getValue();
List<Transaction> blockTransactions = blockAtHeightOne.getTransactionsList();
assertNotNull(blockTransactions);
assertEquals(2, blockTransactions.size());
Transaction remascTransaction = blockTransactions.get(1);
assertThat(remascTransaction, instanceOf(RemascTransaction.class));
}
Aggregations