Complete Set of Test-Vectors for ECDSA secp256k1 Although there are several implementations of ECDSA secp256k1 public available over the internet (the most popular being OpenSSL), it seems that there are no complete set of test-vectors available.  

The few test vectors I could find always miss some important information:  


do not provide the hash integer or the secure random integer k.
do not provide the (r,s) signature pair, instead only provides some hash of it according to bitcoin protocol format.


A complete set of test-vectors would require the following information:  


private key
public key x-coordinate
public key y-coordinate
hash
secure random integer k (see note bellow)
r signature
s signature


Example:  

1. private key: D30519BCAE8D180DBFCC94FE0B8383DC310185B0BE97B4365083EBCECCD75759  
2. public key x-coordinate: 3AF1E1EFA4D1E1AD5CB9E3967E98E901DAFCD37C44CF0BFB6C216997F5EE51DF  
3. public key y-coordinate: E4ACAC3E6F139E0C7DB2BD736824F51392BDA176965A1C59EB9C3C5FF9E85D7A  
4. hash: 3F891FDA3704F0368DAB65FA81EBE616F4AA2A0854995DA4DC0B59D2CADBD64F  
5. secure random integer k: CF554F5F4224223D52DC9CA784478FAC3C1A0D0419FDEEF27849A81846C71BA3  
6. r signature: A5C7B7756D34D8AAF6AA68F0B71644F0BEF90D8BFD126CE951B6060498345089  
7. s signature: BC9644F1625AF13841E589FD00653AE8C763309184EA0DE481E8F06709E5D1CB




Note that a set o test-vectors without the random integer k might also be helpful for validation purposes:  


first validate the signature verification code
than use the validated signature verification code to validate the signature generation code


The reason I consider important to include the random integer k is because with it you can validate different parts of the code independently of each other, therefore reducing the risks of hidden bugs. 



Question
Is there any public available test-vector with the aforementioned set of information?
OK, so I quickly found out that there is a test in Bouncy Castle called:

org.bouncycastle.crypto.test.ECTest.testECDSASecP224k1sha256()


which tests exactly what you are trying to do (with a message the same size of a SHA-256 hash).

So I decided to create a new test that duplicates this test, but for SecP256k1 and SHA-256.

I've generated the following test vectors (I'll use hexadecimals):

 d = ebb2c082fd7727890a28ac82f6bdf97bad8de9f5d7c9028692de1a255cad3e0f
 k = 49a0d7b786ec9cde0d0721d72804befd06571c974b191efb42ecf322ba9ddd9a
 M = 4b688df40bcedbe641ddb16ff0a1842d9c67ea1c3bf63f3e0471baa664531d1a


resulting in:

 r = 241097efbf8b63bf145c8961dbdf10c310efbb3b2676bbc0f8b08505c9e2f795
 s = 021006b7838609339e8b415a7f9acb1b661828131aef1ecbc7955dfb01f3ca0e


note that $s$ starts with 6 zero bits, which should be fine.

Finally, you'd want to verify the signature as well of course, so here is the public key:

 q = 04779dd197a5df977ed2cf6cb31d82d43328b790dc6b3b7d4437a427bd5847dfcde94b724a555b6d017bb7607c3e3281daf5b1699d6ef4124975c9237b917d426f


where $q$ is an uncompressed point, consisting of the following coordinates:

x = 779dd197a5df977ed2cf6cb31d82d43328b790dc6b3b7d4437a427bd5847dfcd
y = e94b724a555b6d017bb7607c3e3281daf5b1699d6ef4124975c9237b917d426f




Method of generating the parameters:

private static final void createAndPrintRequiredParameters()
{
    // code used to generate the random key pair (public point converted to uncompressed point encoding manually)
    ECKeyPairGenerator gen = new ECKeyPairGenerator();
    X9ECParameters p = SECNamedCurves.getByName("secp256k1");
    ECDomainParameters params = new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH());
    SecureRandom kpr = new SecureRandom();
    ECKeyGenerationParameters genParams = new ECKeyGenerationParameters(params, kpr);
    gen.init(genParams);
    AsymmetricCipherKeyPair ecKeyPair = gen.generateKeyPair();
    ECPrivateKeyParameters ecPrivate = (ECPrivateKeyParameters) ecKeyPair.getPrivate();
    ECPublicKeyParameters ecPublic = (ECPublicKeyParameters) ecKeyPair.getPublic();
    System.out.println(ecPrivate.getD().toString(16));
    System.out.println(ecPublic.getQ().toString());

    // code used to generate the message (hash) M
    byte[] mesg = "Maarten Bodewes generated this test vector on 2016-11-08".getBytes(StandardCharsets.UTF_8);
    SHA256Digest dig = new SHA256Digest();
    dig.update(mesg, 0, mesg.length);
    byte[] M = new byte[dig.getDigestSize()];
    dig.doFinal(M, 0);
    System.out.printf("M = %s%n", Hex.toHexString(M));

    // code used to generate the random k
    SecureRandom krng = new SecureRandom();
    BigInteger k;
    do {
        k = new BigInteger(256, krng);
    } while (k.compareTo(params.getN()) &gt;= 1);        
    System.out.printf("K = %s%n", k.toString(16));
}


To make sure that the value of $k$ is used directly within the algorithm I did some tests. A $k$ consisting of all FF bytes and a shorter $k$ both failed as expected . A $k$ consisting of 7F byte followed by all FF bytes does work. So the value $k$ within the FixedSecureRandom constructor is indeed directly used.



And finally the method of testing the deterministic result:

private static void testECDSASecP256k1sha256()
{
    X9ECParameters p = SECNamedCurves.getByName("secp256k1");
    ECDomainParameters params = new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH());
    ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(
        new BigInteger("ebb2c082fd7727890a28ac82f6bdf97bad8de9f5d7c9028692de1a255cad3e0f", 16), // d
        params);
    SecureRandom    k = new FixedSecureRandom(Hex.decode("49a0d7b786ec9cde0d0721d72804befd06571c974b191efb42ecf322ba9ddd9a"));        

    byte[] M = Hex.decode("4b688df40bcedbe641ddb16ff0a1842d9c67ea1c3bf63f3e0471baa664531d1a");

    ECDSASigner dsa = new ECDSASigner();

    dsa.init(true, new ParametersWithRandom(priKey, k));

    BigInteger[] sig = dsa.generateSignature(M);

    BigInteger r = new BigInteger("241097efbf8b63bf145c8961dbdf10c310efbb3b2676bbc0f8b08505c9e2f795", 16);
    BigInteger s = new BigInteger("21006b7838609339e8b415a7f9acb1b661828131aef1ecbc7955dfb01f3ca0e", 16);

    if (!r.equals(sig[0]))
    {
        fail("r component wrong." + Strings.lineSeparator()
            + " expecting: " + r + Strings.lineSeparator()
            + " got      : " + sig[0]);
    }

    if (!s.equals(sig[1]))
    {
        fail("s component wrong." + Strings.lineSeparator()
            + " expecting: " + s + Strings.lineSeparator()
            + " got      : " + sig[1]);
    }

            // Verify the signature
    ECPublicKeyParameters pubKey = new ECPublicKeyParameters(
        params.getCurve().decodePoint(Hex.decode("04779dd197a5df977ed2cf6cb31d82d43328b790dc6b3b7d4437a427bd5847dfcde94b724a555b6d017bb7607c3e3281daf5b1699d6ef4124975c9237b917d426f")), // Q
        params);

    dsa.init(false, pubKey);
    if (!dsa.verifySignature(M, sig[0], sig[1]))
    {
        fail("signature fails");
    }
}


which is a direct copy of the test for SecP224k1 and SHA256, but of course with the different parameters.