package com.itranswarp.bitcoin.util;

import static org.junit.Assert.*;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;

import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.junit.Test;

public class Secp256k1UtilsTest {

	static final Provider BC = new BouncyCastleProvider();

	PublicKey getPublicKeyFromBytes(BigInteger[] pubKey) throws Exception {
		ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
		KeyFactory kf = KeyFactory.getInstance("ECDSA", BC);
		ECPoint point = Secp256k1Utils.getCurve().createPoint(pubKey[0], pubKey[1]);
		ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, spec);
		return kf.generatePublic(pubKeySpec);
	}

	PrivateKey getPrivateKeyFromBytes(BigInteger priKey) throws Exception {
		ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
		KeyFactory kf = KeyFactory.getInstance("ECDSA", BC);
		ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec(priKey, spec);
		return kf.generatePrivate(priKeySpec);
	}

	public byte[] sign(PrivateKey priKey, byte[] message) throws Exception {
		Signature sign = Signature.getInstance("SHA256withECDSA", BC);
		sign.initSign(priKey, new SecureRandom());
		sign.update(message);
		return sign.sign();
	}

	public boolean verifySignature(PublicKey pubKey, byte[] message, byte[] signature) throws Exception {
		Signature sign = Signature.getInstance("SHA256withECDSA", new BouncyCastleProvider());
		sign.initVerify(pubKey);
		sign.update(message);
		return sign.verify(signature);
	}

	@Test
	public void testGetN() throws Exception {
		// ECDSAKeyPair keyPair = ECDSAKeyPair.createNewKeyPair();
		// BigInteger priKey = keyPair.getPrivateKey();
		// BigInteger[] pubKey = keyPair.getPublicKey();
		// byte[] message = HashUtils.toBytes(
		// "54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29");
		// byte[] signature = sign(getPrivateKeyFromBytes(priKey), message);
		// System.out.println(HashUtils.toHexString(signature));
		// System.out.println(verifySignature(getPublicKeyFromBytes(pubKey),
		// message, signature));

		// ECDSASigner signer = new ECDSASigner();
		// ByteArrayOutputStream buffer = new ByteArrayOutputStream ();
		// DERSequenceGenerator g=new DERSequenceGenerator(buffer);
		// g.addObject(null);
		// g.close();
	}

	@Test
	public void testSignAndVerify() throws Exception {
		BigInteger privateKey = new BigInteger("18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725", 16);
		byte[] message = "Bitcoin: A Peer-to-Peer Electronic Cash System".getBytes();
		byte[] signature = Secp256k1Utils.sign(message, privateKey);
		System.out.println(signature.length + ": " + HashUtils.toHexString(signature));
		// verify:
		byte[] publicKey = Secp256k1Utils.toPublicKey(privateKey);
		Secp256k1Utils.verify(message, signature, publicKey);
	}
}

@@ -77,3282 +77,58 @@
 ort 
-java.math.BigInteger;%0Aimport java.security.KeyFactory;%0Aimport java.security.PrivateKey;%0Aimport java.security.Provider;%0Aimport java.security.PublicKey;%0Aimport java.security.SecureRandom;%0Aimport java.security.Signature;%0A%0Aimport org.bouncycastle.jce.ECNamedCurveTable;%0Aimport org.bouncycastle.jce.provider.BouncyCastleProvider;%0Aimport org.bouncycastle.jce.spec.ECParameterSpec;%0Aimport org.bouncycastle.jce.spec.ECPrivateKeySpec;%0Aimport org.bouncycastle.jce.spec.ECPublicKeySpec;%0Aimport org.bouncycastle.math.ec.ECPoint;%0Aimport org.junit.Test;%0A%0Apublic class Secp256k1UtilsTest %7B%0A%0A%09static final Provider BC = new BouncyCastleProvider();%0A%0A%09PublicKey getPublicKeyFromBytes(BigInteger%5B%5D pubKey) throws Exception %7B%0A%09%09ECParameterSpec spec = ECNamedCurveTable.getParameterSpec(%22secp256k1%22);%0A%09%09KeyFactory kf = KeyFactory.getInstance(%22ECDSA%22, BC);%0A%09%09ECPoint point = Secp256k1Utils.getCurve().createPoint(pubKey%5B0%5D, pubKey%5B1%5D);%0A%09%09ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, spec);%0A%09%09return kf.generatePublic(pubKeySpec);%0A%09%7D%0A%0A%09PrivateKey getPrivateKeyFromBytes(BigInteger priKey) throws Exception %7B%0A%09%09ECParameterSpec spec = ECNamedCurveTable.getParameterSpec(%22secp256k1%22);%0A%09%09KeyFactory kf = KeyFactory.getInstance(%22ECDSA%22, BC);%0A%09%09ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec(priKey, spec);%0A%09%09return kf.generatePrivate(priKeySpec);%0A%09%7D%0A%0A%09public byte%5B%5D sign(PrivateKey priKey, byte%5B%5D message) throws Exception %7B%0A%09%09Signature sign = Signature.getInstance(%22SHA256withECDSA%22, BC);%0A%09%09sign.initSign(priKey, new SecureRandom());%0A%09%09sign.update(message);%0A%09%09return sign.sign();%0A%09%7D%0A%0A%09public boolean verifySignature(PublicKey pubKey, byte%5B%5D message, byte%5B%5D signature) throws Exception %7B%0A%09%09Signature sign = Signature.getInstance(%22SHA256withECDSA%22, new BouncyCastleProvider());%0A%09%09sign.initVerify(pubKey);%0A%09%09sign.update(message);%0A%09%09return sign.verify(signature);%0A%09%7D%0A%0A%09@Test%0A%09public void testGetN() throws Exception %7B%0A%09%09// ECDSAKeyPair keyPair = ECDSAKeyPair.createNewKeyPair();%0A%09%09// BigInteger priKey = keyPair.getPrivateKey();%0A%09%09// BigInteger%5B%5D pubKey = keyPair.getPublicKey();%0A%09%09// byte%5B%5D message = HashUtils.toBytes(%0A%09%09// %2254686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29%22);%0A%09%09// byte%5B%5D signature = sign(getPrivateKeyFromBytes(priKey), message);%0A%09%09// System.out.println(HashUtils.toHexString(signature));%0A%09%09// System.out.println(verifySignature(getPublicKeyFromBytes(pubKey),%0A%09%09// message, signature));%0A%0A%09%09// ECDSASigner signer = new ECDSASigner();%0A%09%09// ByteArrayOutputStream buffer = new ByteArrayOutputStream ();%0A%09%09// DERSequenceGenerator g=new DERSequenceGenerator(buffer);%0A%09%09// g.addObject(null);%0A%09%09// g.close();%0A%09%7D%0A%0A%09@Test%0A%09public void testSignAndVerify() throws Exception %7B%0A%09%09BigInteger privateKey = new BigInteger(%2218e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725%22, 16);%0A%09%09byte%5B%5D message = %22Bitcoin: A Peer-to-Peer Electronic Cash System%22.getBytes();%0A%09%09byte%5B%5D signature = Secp256k1Utils.sign(message, privateKey);%0A%09%09System.out.println(signature.length + %22: %22 + HashUtils.toHexString(signature));%0A%09%09// verify:%0A%09%09byte%5B%5D publicKey = Secp256k1Utils.toPublicKey(privateKey);%0A%09%09Secp256k1Utils.verify(message, signature, publicKey);%0A%09%7D
+org.junit.Test;%0A%0Apublic class Secp256k1UtilsTest %7B%0A
 %0A%7D%0A

update test