diff --git a/src/main/java/io/bitsquare/btc/WalletFacade.java b/src/main/java/io/bitsquare/btc/WalletFacade.java index 51a76816a9..ca85ed96ab 100644 --- a/src/main/java/io/bitsquare/btc/WalletFacade.java +++ b/src/main/java/io/bitsquare/btc/WalletFacade.java @@ -33,6 +33,8 @@ import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN; + /** * TODO: use walletextension (with protobuffer) instead of saving addressEntryList via storage * TODO: use HD wallet features instead of addressEntryList @@ -605,9 +607,8 @@ public class WalletFacade Transaction tx = new Transaction(params); - //TODO priv key is null, use other signing key or find out why it is null at that moment - //byte[] data = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressInfo().getKey(), stringifiedBankAccounts); - //tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, new ScriptBuilder().op(OP_RETURN).data(data).build()); + byte[] data = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressInfo().getKey(), stringifiedBankAccounts); + tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, new ScriptBuilder().op(OP_RETURN).data(data).build()); Coin fee = FeePolicy.ACCOUNT_REGISTRATION_FEE.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(FeePolicy.TX_FEE); log.trace("fee: " + fee.toFriendlyString()); diff --git a/src/main/java/io/bitsquare/crypto/CryptoFacade.java b/src/main/java/io/bitsquare/crypto/CryptoFacade.java index 082dc82339..c0edb4db58 100644 --- a/src/main/java/io/bitsquare/crypto/CryptoFacade.java +++ b/src/main/java/io/bitsquare/crypto/CryptoFacade.java @@ -1,12 +1,18 @@ package io.bitsquare.crypto; import com.google.bitcoin.core.ECKey; +import com.google.bitcoin.core.Sha256Hash; import com.google.bitcoin.core.Utils; +import com.google.bitcoin.crypto.KeyCrypterException; import com.google.common.base.Charsets; +import java.nio.charset.Charset; import java.security.SignatureException; +import javax.annotation.Nullable; import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.spongycastle.crypto.params.KeyParameter; +import org.spongycastle.util.encoders.Base64; /** * That facade delivers crypto functionality from the bitcoinJ library @@ -21,16 +27,42 @@ public class CryptoFacade { } + // DeterministicKey does not support signMessage yet. + private String signMessage(ECKey key, String message, @Nullable KeyParameter aesKey) throws KeyCrypterException + { + byte[] data = Utils.formatMessageForSigning(message); + Sha256Hash hash = Sha256Hash.createDouble(data); + ECKey.ECDSASignature sig = key.sign(hash, aesKey); + // Now we have to work backwards to figure out the recId needed to recover the signature. + int recId = -1; + for (int i = 0; i < 4; i++) + { + ECKey k = ECKey.recoverFromSignature(i, sig, hash, key.isCompressed()); + if (k != null && k.getPubKeyPoint().equals(key.getPubKeyPoint())) + { + recId = i; + break; + } + } + if (recId == -1) + throw new RuntimeException("Could not construct a recoverable key. This should never happen."); + int headerByte = recId + 27 + (key.isCompressed() ? 4 : 0); + byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S + sigData[0] = (byte) headerByte; + System.arraycopy(Utils.bigIntegerToBytes(sig.r, 32), 0, sigData, 1, 32); + System.arraycopy(Utils.bigIntegerToBytes(sig.s, 32), 0, sigData, 33, 32); + return new String(Base64.encode(sigData), Charset.forName("UTF-8")); + } public byte[] getEmbeddedAccountRegistrationData(ECKey registrationKey, String stringifiedBankAccounts) { - String signedBankAccountIDs = registrationKey.signMessage(stringifiedBankAccounts); + String signedBankAccountIDs = signMessage(registrationKey, stringifiedBankAccounts, null); return Utils.sha256hash160(concatenateChunks(stringifiedBankAccounts, signedBankAccountIDs).getBytes(Charsets.UTF_8)); } public String signContract(ECKey key, String contractAsJson) { - return key.signMessage(contractAsJson); + return signMessage(key, contractAsJson, null); } // registration @@ -38,7 +70,7 @@ public class CryptoFacade { try { - ECKey key = new ECKey(null, pubKey, true); + ECKey key = ECKey.fromPublicOnly(pubKey); key.verifyMessage(msg, sig); return true; } catch (SignatureException e) diff --git a/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml b/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml index b041edc628..0ddd7ffff5 100644 --- a/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml +++ b/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationView.fxml @@ -26,19 +26,19 @@