Skip to content

Commit 24c60e2

Browse files
committed
Add test vector for ECDSA secp256k1
1 parent 15e1a74 commit 24c60e2

File tree

2 files changed

+143
-3
lines changed

2 files changed

+143
-3
lines changed

test/ecdsa_test_vectors.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/* Copyright 2020, Kenneth MacKay. Licensed under the BSD 2-clause license. */
2+
3+
#include "uECC.h"
4+
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <string.h>
8+
9+
typedef struct {
10+
const char* private_key;
11+
const char* public_key;
12+
const char* k;
13+
const char* hash;
14+
const char* r;
15+
const char* s;
16+
} Test;
17+
18+
Test secp256k1_tests[] = {
19+
{
20+
"ebb2c082fd7727890a28ac82f6bdf97bad8de9f5d7c9028692de1a255cad3e0f",
21+
"779dd197a5df977ed2cf6cb31d82d43328b790dc6b3b7d4437a427bd5847dfcde94b724a555b6d017bb7607c3e3281daf5b1699d6ef4124975c9237b917d426f",
22+
"49a0d7b786ec9cde0d0721d72804befd06571c974b191efb42ecf322ba9ddd9a",
23+
"4b688df40bcedbe641ddb16ff0a1842d9c67ea1c3bf63f3e0471baa664531d1a",
24+
"241097efbf8b63bf145c8961dbdf10c310efbb3b2676bbc0f8b08505c9e2f795",
25+
"021006b7838609339e8b415a7f9acb1b661828131aef1ecbc7955dfb01f3ca0e"
26+
},
27+
};
28+
29+
extern int uECC_sign_with_k(const uint8_t *private_key,
30+
const uint8_t *message_hash,
31+
unsigned hash_size,
32+
const uint8_t *k,
33+
uint8_t *signature,
34+
uECC_Curve curve);
35+
36+
37+
void vli_print(uint8_t *vli, unsigned int size) {
38+
for(unsigned i=0; i<size; ++i) {
39+
printf("%02X ", (unsigned)vli[i]);
40+
}
41+
printf("\n");
42+
}
43+
44+
void strtobytes(const char* str, uint8_t* bytes, int count) {
45+
for (int c = 0; c < count; ++c) {
46+
if (sscanf(str, "%2hhx", &bytes[c]) != 1) {
47+
printf("Failed to read string to bytes");
48+
exit(1);
49+
}
50+
str += 2;
51+
}
52+
}
53+
54+
int run(Test* tests, int num_tests, uECC_Curve curve) {
55+
uint8_t private[32] = {0};
56+
uint8_t public[64] = {0};
57+
uint8_t k[32] = {0};
58+
uint8_t hash[32] = {0};
59+
uint8_t r[32] = {0};
60+
uint8_t s[32] = {0};
61+
62+
uint8_t signature[64] = {0};
63+
64+
int result;
65+
int i;
66+
int private_key_size;
67+
int public_key_size;
68+
int all_success = 1;
69+
70+
private_key_size = uECC_curve_private_key_size(curve);
71+
public_key_size = uECC_curve_public_key_size(curve);
72+
73+
for (i = 0; i < num_tests; ++i) {
74+
strtobytes(tests[i].private_key, private, private_key_size);
75+
strtobytes(tests[i].public_key, public, public_key_size);
76+
strtobytes(tests[i].k, k, private_key_size);
77+
strtobytes(tests[i].hash, hash, private_key_size);
78+
strtobytes(tests[i].r, r, private_key_size);
79+
strtobytes(tests[i].s, s, private_key_size);
80+
81+
result = uECC_sign_with_k(private, hash, private_key_size, k, signature, curve);
82+
if (!result) {
83+
all_success = 0;
84+
printf(" Sign failed for test %d\n", i);
85+
}
86+
if (result) {
87+
if (memcmp(signature, r, private_key_size) != 0) {
88+
all_success = 0;
89+
printf(" Got incorrect r for test %d\n", i);
90+
printf(" Expected: ");
91+
vli_print(r, private_key_size);
92+
printf(" Calculated: ");
93+
vli_print(signature, private_key_size);
94+
}
95+
if (memcmp(signature + private_key_size, s, private_key_size) != 0) {
96+
all_success = 0;
97+
printf(" Got incorrect s for test %d\n", i);
98+
printf(" Expected: ");
99+
vli_print(s, private_key_size);
100+
printf(" Calculated: ");
101+
vli_print(signature + private_key_size, private_key_size);
102+
}
103+
104+
result = uECC_verify(public, hash, private_key_size, signature, curve);
105+
if (!result) {
106+
printf(" Verify failed for test %d\n", i);
107+
}
108+
}
109+
}
110+
111+
return all_success;
112+
}
113+
114+
#define RUN_TESTS(curve) \
115+
printf(#curve ":\n"); \
116+
if (run(curve##_tests, sizeof(curve##_tests) / sizeof(curve##_tests[0]), uECC_##curve()) ) { \
117+
printf(" All passed\n"); \
118+
} else { \
119+
printf(" Failed\n"); \
120+
}
121+
122+
int main() {
123+
#if uECC_SUPPORTS_secp256k1
124+
RUN_TESTS(secp256k1)
125+
#endif
126+
127+
return 0;
128+
}

uECC.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ static void bits2int(uECC_word_t *native,
12431243
}
12441244
}
12451245

1246-
static int uECC_sign_with_k(const uint8_t *private_key,
1246+
static int uECC_sign_with_k_internal(const uint8_t *private_key,
12471247
const uint8_t *message_hash,
12481248
unsigned hash_size,
12491249
uECC_word_t *k,
@@ -1326,6 +1326,18 @@ static int uECC_sign_with_k(const uint8_t *private_key,
13261326
return 1;
13271327
}
13281328

1329+
/* For testing - sign with an explicitly specified k value */
1330+
int uECC_sign_with_k(const uint8_t *private_key,
1331+
const uint8_t *message_hash,
1332+
unsigned hash_size,
1333+
const uint8_t *k,
1334+
uint8_t *signature,
1335+
uECC_Curve curve) {
1336+
uECC_word_t k2[uECC_MAX_WORDS];
1337+
bits2int(k2, k, BITS_TO_BYTES(curve->num_n_bits), curve);
1338+
return uECC_sign_with_k_internal(private_key, message_hash, hash_size, k2, signature, curve);
1339+
}
1340+
13291341
int uECC_sign(const uint8_t *private_key,
13301342
const uint8_t *message_hash,
13311343
unsigned hash_size,
@@ -1339,7 +1351,7 @@ int uECC_sign(const uint8_t *private_key,
13391351
return 0;
13401352
}
13411353

1342-
if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature, curve)) {
1354+
if (uECC_sign_with_k_internal(private_key, message_hash, hash_size, k, signature, curve)) {
13431355
return 1;
13441356
}
13451357
}
@@ -1455,7 +1467,7 @@ int uECC_sign_deterministic(const uint8_t *private_key,
14551467
mask >> ((bitcount_t)(num_n_words * uECC_WORD_SIZE * 8 - num_n_bits));
14561468
}
14571469

1458-
if (uECC_sign_with_k(private_key, message_hash, hash_size, T, signature, curve)) {
1470+
if (uECC_sign_with_k_internal(private_key, message_hash, hash_size, T, signature, curve)) {
14591471
return 1;
14601472
}
14611473

0 commit comments

Comments
 (0)