diff --git a/ecdsa.c b/ecdsa.c index 92b9a95d01..65aef7d5c9 100644 --- a/ecdsa.c +++ b/ecdsa.c @@ -533,28 +533,37 @@ int ecdsa_verify_digest(const uint8_t *pub_key, const uint8_t *sig, const uint8_ int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der) { - int p1, p2; - p1 = sig[0] >= 0x80; - p2 = sig[32] >= 0x80; - der[0] = 0x30; // sequence - der[1] = (1 + 1 + p1 + 32) + (1 + 1 + p2 + 32); // total len - der[2] = 0x02; // int - if (p1) { - der[3] = 33; - der[4] = 0x00; - memcpy(der + 5, sig, 32); - } else { - der[3] = 32; - memcpy(der + 4, sig, 32); + int i; + uint8_t *p = der, *len, *len1, *len2; + *p = 0x30; p++; // sequence + *p = 0x00; len = p; p++; // len(sequence) + + *p = 0x02; p++; // integer + *p = 0x00; len1 = p; p++; // len(integer) + + // process R + i = 0; + while (sig[i] == 0 && i < 32) { i++; } // skip leading zeroes + if (sig[i] >= 0x80) { // put zero in output if MSB set + *p = 0x00; p++; *len1 = *len1 + 1; } - der[36 + p1] = 0x02; // int - if (p2) { - der[37 + p1] = 33; - der[38 + p1] = 0x00; - memcpy(der + 39 + p1, sig + 32, 32); - } else { - der[37 + p1] = 32; - memcpy(der + 38 + p1, sig + 32, 32); + while (i < 32) { // copy bytes to output + *p = sig[i]; p++; *len1 = *len1 + 1; i++; } - return der[1] + 2; + + *p = 0x02; p++; // integer + *p = 0x00; len2 = p; p++; // len(integer) + + // process S + i = 32; + while (sig[i] == 0 && i < 64) { i++; } // skip leading zeroes + if (sig[i] >= 0x80) { // put zero in output if MSB set + *p = 0x00; p++; *len2 = *len2 + 1; + } + while (i < 64) { // copy bytes to output + *p = sig[i]; p++; *len2 = *len2 + 1; i++; + } + + *len = *len1 + *len2 + 4; + return *len + 2; } diff --git a/tests.c b/tests.c index 2140978b76..c1f972ba80 100644 --- a/tests.c +++ b/tests.c @@ -573,6 +573,30 @@ START_TEST(test_ecdsa_der) res = ecdsa_sig_to_der(sig, der); ck_assert_int_eq(res, 72); ck_assert_mem_eq(der, fromhex("3046022100eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee022100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), 72); + + memcpy(sig, fromhex("0000000000000000000000000000000000000000000000000000000000000066"), 32); + memcpy(sig + 32, fromhex("0000000000000000000000000000000000000000000000000000000000000077"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 8); + ck_assert_mem_eq(der, fromhex("3006020166020177"), 8); + + memcpy(sig, fromhex("0000000000000000000000000000000000000000000000000000000000000066"), 32); + memcpy(sig + 32, fromhex("00000000000000000000000000000000000000000000000000000000000000ee"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 9); + ck_assert_mem_eq(der, fromhex("3007020166020200ee"), 9); + + memcpy(sig, fromhex("00000000000000000000000000000000000000000000000000000000000000ee"), 32); + memcpy(sig + 32, fromhex("0000000000000000000000000000000000000000000000000000000000000077"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 9); + ck_assert_mem_eq(der, fromhex("3007020200ee020177"), 9); + + memcpy(sig, fromhex("00000000000000000000000000000000000000000000000000000000000000ee"), 32); + memcpy(sig + 32, fromhex("00000000000000000000000000000000000000000000000000000000000000ff"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 10); + ck_assert_mem_eq(der, fromhex("3008020200ee020200ff"), 10); } END_TEST