gt:         byte[] p3 = Tools.hexStringToByteArray("08 79 66 88");
context: package network.thunder.core.etc;
  
  import org.bitcoinj.core.*;
  import org.bitcoinj.crypto.TransactionSignature;
  import org.bitcoinj.script.Script;
  import org.bitcoinj.script.ScriptBuilder;
  import org.junit.Before;
  import org.junit.Test;
  
  import java.security.NoSuchAlgorithmException;
  import java.util.Arrays;
  
  import static junit.framework.TestCase.assertFalse;
  import static org.junit.Assert.assertTrue;
  
  /**
   * Created by matsjerratsch on 04/11/15.
   */
  public class ScriptToolsTest {
  
      ECKey keyServer = ECKey.fromPrivate(Tools.hexStringToByteArray("95b9ba99ce547d0346ae69adeef116b51c77f3285fe8941c9bfe83a0857d606e"));
      ECKey keyClient = ECKey.fromPrivate(Tools.hexStringToByteArray("514651734ecf29afc45e520854842ad0aff937418be72b7e5b688b0fc0ef8661"));
      ECKey keyServerA = ECKey.fromPrivate(Tools.hexStringToByteArray("ea827f0b72fad12d46ce11da5db814433711fa15bcd834b9a94de5fb3319b71d"));
      ECKey keyClientA = ECKey.fromPrivate(Tools.hexStringToByteArray("1ae1c7ca3d0e0d8372d7111a231a0d45bf7abeff22342db7ab3d4d200b7f4ce5"));
  
      Transaction transactionOutput;
      Transaction transactionInput;
  
      byte[] secretServer = Tools.hexStringToByteArray("E34BAF76398A2E167EC4CB8BE4A8C75E19255CB0");
      byte[] secretClient = Tools.hexStringToByteArray("E650A18B973A949DDF1854E6206620F07F8C49ED");
      byte[] secretServerHash = Tools.hashSecret(secretServer);
      byte[] secretClientHash = Tools.hashSecret(secretClient);
  
      byte[] revocationServer = Tools.hexStringToByteArray("E3411336485A2E167EC4CB8BE4A8C75E19255CB0");
      byte[] revocationClient = Tools.hexStringToByteArray("E65AA748832A949DDF1854E6206620F07F8C49ED");
      byte[] revocationServerHash = Tools.hashSecret(revocationServer);
      byte[] revocationClientHash = Tools.hashSecret(revocationClient);
  
      NetworkParameters params = NetworkParameters.testNet3();
  
      @Before
      public void setup () throws NoSuchAlgorithmException {
          Context.getOrCreate(params);
  
          transactionOutput = new Transaction(params);
          transactionInput = new Transaction(params);
      }
  
      @Test
      public void shouldCreateSpendableAnchorTransactionWithEscapeTransaction () {
  
          Script outputScript = ScriptTools.getAnchorOutputScript(secretServerHash, keyClient, keyClientA, keyServer);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureClientA = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyClientA);
          TransactionSignature signatureServer = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyServer);
  
          Script inputScript = ScriptTools.getEscapeInputScript(signatureClientA.encodeToBitcoin(), signatureServer.encodeToBitcoin(), secretServer,
                  secretServerHash, keyClient, keyClientA, keyServer);
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test
      public void shouldCreateSpendableAnchorTransactionWithCommitmentTransaction () {
  
          Script outputScript = ScriptTools.getAnchorOutputScript(secretServerHash, keyClient, keyClientA, keyServer);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureClient = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyClient);
          TransactionSignature signatureServer = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyServer);
  
          Script inputScript = ScriptTools.getCommitInputScript(signatureClient.encodeToBitcoin(), signatureServer.encodeToBitcoin(),
                  secretServerHash, keyClient, keyClientA, keyServer);
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test
      public void shouldCreateSpendableEscapeTransactionWithRevocationTransaction () {
  
          Script outputScript = ScriptTools.getEscapeOutputScript(revocationServerHash, keyServer, keyClient, 60 * 60 * 1000);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureClient = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyClient);
  
          Script inputScript = ScriptTools.getEscapeInputRevocationScript(revocationServerHash, keyServer, keyClient, 60 * 60 * 1000, signatureClient
                  .encodeToBitcoin(), revocationServer);
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test
      public void shouldCreateSpendableEscapeTransactionWithTimeoutTransaction () {
  
          Script outputScript = ScriptTools.getEscapeOutputScript(revocationServerHash, keyServer, keyClient, 60 * 60 * 1000);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureServer = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyServer);
  
          Script inputScript = ScriptTools.getEscapeInputTimeoutScript(revocationServerHash, keyServer, keyClient, 60 * 60 * 1000, signatureServer
                  .encodeToBitcoin());
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test
      public void shouldCreateSpendableFastEscapeTransactionWithSecretTransaction () {
  
          Script outputScript = ScriptTools.getFastEscapeOutputScript(secretClientHash, keyServer, keyClient, 60 * 60 * 1000);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureServer = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyServer);
  
          Script inputScript = ScriptTools.getFastEscapeInputSecretScript(secretClientHash, keyServer, keyClient, 60 * 60 * 1000, signatureServer
                  .encodeToBitcoin(), secretClient);
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test
      public void shouldCreateSpendableFastEscapeTransactionWithTimeoutTransaction () {
  
          Script outputScript = ScriptTools.getFastEscapeOutputScript(secretClientHash, keyServer, keyClient, 60 * 60 * 1000);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureClient = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyClient);
  
          Script inputScript = ScriptTools.getFastEscapeInputTimeoutScript(secretClientHash, keyServer, keyClient, 60 * 60 * 1000, signatureClient
                  .encodeToBitcoin());
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test(expected = ScriptException.class)
      public void shouldThrowExceptionBecauseOfWrongSecretWhenTryingToSpendEscapeTransaction () {
          Script outputScript = ScriptTools.getEscapeOutputScript(secretServerHash, keyServer, keyClient, 60 * 60 * 1000);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureClient = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyClient);
  
          byte[] b = new byte[]{0x00};
          System.arraycopy(b, 0, secretServer, 15, 1); //Copy a wrong byte into the secret, should not work anymore now
  
          Script inputScript = ScriptTools.getEscapeInputRevocationScript(secretServerHash, keyServer, keyClient, 60 * 60 * 1000, signatureClient
                  .encodeToBitcoin(), secretServer);
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test(expected = ScriptException.class)
      public void shouldThrowExceptionBecauseOfWrongSecretWhenTryingToSpendFastEscapeTransaction () {
          Script outputScript = ScriptTools.getFastEscapeOutputScript(secretClientHash, keyServer, keyClient, 60 * 60 * 1000);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureServer = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyServer);
  
          byte[] b = new byte[]{0x00};
          System.arraycopy(b, 0, secretClient, 15, 1); //Copy a wrong byte into the secret, should not work anymore now
  
          Script inputScript = ScriptTools.getFastEscapeInputSecretScript(secretClientHash, keyServer, keyClient, 60 * 60 * 1000, signatureServer
                  .encodeToBitcoin(), secretClient);
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test(expected = ScriptException.class)
      public void shouldThrowExceptionBecauseSignatureOrderIsNotCorrect () {
  
          Script outputScript = ScriptTools.getAnchorOutputScript(secretServerHash, keyClient, keyClientA, keyServer);
          Script outputScriptP2SH = ScriptBuilder.createP2SHOutputScript(outputScript);
  
          transactionInput.addInput(Sha256Hash.wrap("6d651fd23456606298348f7e750321cba2e3e752d433aa537ea289593645d2e4"), 0, Tools.getDummyScript());
          transactionInput.addOutput(Coin.valueOf(999000), Tools.getDummyScript());
  
          TransactionSignature signatureClientA = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyClientA);
          TransactionSignature signatureServer = Tools.getSignature(transactionInput, 0, outputScript.getProgram(), keyServer);
  
          Script inputScript = ScriptTools.getEscapeInputScript(signatureServer.encodeToBitcoin(), signatureClientA.encodeToBitcoin(), secretServer,
                  secretServerHash, keyClient, keyClientA, keyServer);
  
          transactionInput.getInput(0).setScriptSig(inputScript);
  
          inputScript.correctlySpends(transactionInput, 0, outputScriptP2SH);
      }
  
      @Test
      public void shouldProduceCorrectScript () throws Exception {
  
          byte[] p1 = Tools.hexStringToByteArray("aa bb cc dd ee");
          byte[] p2 = Tools.hexStringToByteArray("04 92 84 00 82 71 00 74 38 92 48 17");
          byte[] p3 = Tools.hexStringToByteArray("08 79 66 88");
          byte[] p4 = Tools.hexStringToByteArray("09 87 09 38 27 aa 98 00 83 a9 ff 89 11 39 47 89 28 11 99 02 83 99 04 28 40 66 78 09 65");
  
          Script script = ScriptTools.produceScript(ScriptTools.ANCHOR_OUTPUT_SCRIPT, p1, p2, p3, p4);
  
          assertTrue(Arrays.equals(script.getProgram(), Tools.hexStringToByteArray
                  ("A905AABBCCDDEE87630C04928400827100743892481767040879668868527C1D0987093827AA980083A9FF89113947892811990283990428406678096552AE")));
  
      }
  
      @Test
      public void testScriptShouldReturnTrue () throws Exception {
          byte[] script = Tools.hexStringToByteArray
                  ("A905AABBCCDDEE87630C04928400827100743892481767040879668868527C1D0987093827AA980083A9FF89113947892811990283990428406678096552AE");
  
          byte[] p1 = Tools.hexStringToByteArray("aa bb cc dd ee");
          byte[] p2 = Tools.hexStringToByteArray("04 92 84 00 82 71 00 74 38 92 48 17");
          byte[] p3 = Tools.hexStringToByteArray("08 79 66 88");
          byte[] p4 = Tools.hexStringToByteArray("09 87 09 38 27 aa 98 00 83 a9 ff 89 11 39 47 89 28 11 99 02 83 99 04 28 40 66 78 09 65");
  
          assertTrue(ScriptTools.testScript(script, ScriptTools.ANCHOR_OUTPUT_SCRIPT, p1, p2, p3, p4));
  
      }
  
      @Test
      public void testScriptShouldReturnFalse () throws Exception {
          //Changed one byte of the original sequence
          byte[] script = Tools.hexStringToByteArray
                  ("A905AABBCCDDEE87630C049284008271007438924817570408796688527C1D0987093827AA980083A9FF89113947892811990283990428406678096552AE");
  
          byte[] p1 = Tools.hexStringToByteArray("aa bb cc dd ee");
          byte[] p2 = Tools.hexStringToByteArray("04 92 84 00 82 71 00 74 38 92 48 17");
  