package com.greenaddress.greenapi; import com.blockstream.libwally.Wally; import org.bitcoinj.core.ECKey; import org.bitcoinj.core.Transaction; import org.bitcoinj.crypto.DeterministicKey; import org.bitcoinj.crypto.TransactionSignature; import java.util.List; public abstract class ISigningWallet { protected Network mNetwork; protected static final int HARDENED = 0x80000000; protected static final int PASSWORD_PATH = 0x70617373 | HARDENED; // 'pass' protected static final int GA_PATH = 0x4741 | HARDENED; // 'GA' protected static final byte[] PASSWORD_SALT = new byte[] { 0x70, 0x61, 0x73, 0x73, 0x73, 0x61, 0x6c, 0x74 // 'passsalt' }; private static final String GA_KEY = "GreenAddress.it HD wallet path"; public abstract DeterministicKey getSubAccountPublicKey(int subAccount); public abstract List<byte[]> signTransaction(PreparedTransaction ptx); public abstract List<byte[]> signTransaction(Transaction tx, PreparedTransaction ptx, List<Output> prevOuts); // FIXME: This is only needed until the challenge RPC is unified public abstract Object[] getChallengeArguments(); public abstract String[] signChallenge(String challengeString, String[] challengePath); public static byte[] getTxSignature(final ECKey.ECDSASignature sig) { final TransactionSignature txSig = new TransactionSignature(sig, Transaction.SigHash.ALL, false); return txSig.encodeToBitcoin(); } // Derive a local password for encryption of client side data. // This takes a hardened public key using PASSWORD_PATH and returns // the pbkdf2_hmac_sha512 of its serialized bytes with PASSWORD_SALT. public abstract byte[] getLocalEncryptionPassword(); public abstract byte[] getGAPath(); public abstract byte[] signBitcoinMessageHash(final byte[] sha256d, final int[] path); protected static byte[] extendedKeyToPath(final byte[] publicKey, final byte[] chainCode) { final byte[] data = new byte[publicKey.length + chainCode.length]; System.arraycopy(chainCode, 0, data, 0, chainCode.length); System.arraycopy(publicKey, 0, data, chainCode.length, publicKey.length); return Wally.hmac_sha512(GA_KEY.getBytes(), data); } }