int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) { secp256k1_num_t sec, non, msg; secp256k1_num_init(&sec); secp256k1_num_init(&non); secp256k1_num_init(&msg); secp256k1_num_set_bin(&sec, seckey, 32); secp256k1_num_set_bin(&non, nonce, 32); secp256k1_num_set_bin(&msg, message, messagelen); int ret = !secp256k1_num_is_zero(&non) && (secp256k1_num_cmp(&non, &secp256k1_ge_consts->order) < 0); secp256k1_ecdsa_sig_t sig; secp256k1_ecdsa_sig_init(&sig); if (ret) { ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL); } if (ret) { secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig); } secp256k1_ecdsa_sig_free(&sig); secp256k1_num_clear(&msg); secp256k1_num_clear(&non); secp256k1_num_clear(&sec); secp256k1_num_free(&msg); secp256k1_num_free(&non); secp256k1_num_free(&sec); return ret; }
int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) { secp256k1_num_t sec, non, msg; secp256k1_num_init(&sec); secp256k1_num_init(&non); secp256k1_num_init(&msg); secp256k1_num_set_bin(&sec, seckey, 32); secp256k1_num_set_bin(&non, nonce, 32); secp256k1_num_set_bin(&msg, message, messagelen); int ret = !secp256k1_num_is_zero(&non) && (secp256k1_num_cmp(&non, &secp256k1_ge_consts->order) < 0); secp256k1_ecdsa_sig_t sig; secp256k1_ecdsa_sig_init(&sig); if (ret) { ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid); } if (ret) { secp256k1_num_get_bin(sig64, 32, &sig.r); secp256k1_num_get_bin(sig64 + 32, 32, &sig.s); } secp256k1_ecdsa_sig_free(&sig); secp256k1_num_clear(&msg); secp256k1_num_clear(&non); secp256k1_num_clear(&sec); secp256k1_num_free(&msg); secp256k1_num_free(&non); secp256k1_num_free(&sec); return ret; }
int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { int ret = -3; secp256k1_num_t m; secp256k1_num_init(&m); secp256k1_ecdsa_sig_t s; secp256k1_ecdsa_sig_init(&s); secp256k1_ge_t q; secp256k1_num_set_bin(&m, msg, msglen); if (!secp256k1_ecdsa_pubkey_parse(&q, pubkey, pubkeylen)) { ret = -1; goto end; } if (!secp256k1_ecdsa_sig_parse(&s, sig, siglen)) { ret = -2; goto end; } if (!secp256k1_ecdsa_sig_verify(&s, &q, &m)) { ret = 0; goto end; } ret = 1; end: secp256k1_ecdsa_sig_free(&s); secp256k1_num_free(&m); return ret; }
int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { DEBUG_CHECK(secp256k1_ecmult_consts != NULL); DEBUG_CHECK(msg != NULL); DEBUG_CHECK(msglen <= 32); DEBUG_CHECK(sig64 != NULL); DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(pubkeylen != NULL); DEBUG_CHECK(recid >= 0 && recid <= 3); int ret = 0; secp256k1_num_t m; secp256k1_num_init(&m); secp256k1_ecdsa_sig_t sig; secp256k1_ecdsa_sig_init(&sig); secp256k1_num_set_bin(&sig.r, sig64, 32); secp256k1_num_set_bin(&sig.s, sig64 + 32, 32); secp256k1_num_set_bin(&m, msg, msglen); secp256k1_ge_t q; if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) { secp256k1_ecdsa_pubkey_serialize(&q, pubkey, pubkeylen, compressed); ret = 1; } secp256k1_ecdsa_sig_free(&sig); secp256k1_num_free(&m); return ret; }
void test_ecdsa_openssl() { const secp256k1_ge_consts_t *c = secp256k1_ge_consts; secp256k1_num_t key, msg; secp256k1_num_init(&msg); unsigned char message[32]; secp256k1_rand256_test(message); secp256k1_num_set_bin(&msg, message, 32); secp256k1_num_init(&key); random_num_order_test(&key); secp256k1_gej_t qj; secp256k1_ecmult_gen(&qj, &key); secp256k1_ge_t q; secp256k1_ge_set_gej(&q, &qj); EC_KEY *ec_key = get_openssl_key(&key); assert(ec_key); unsigned char signature[80]; int sigsize = 80; assert(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); secp256k1_ecdsa_sig_t sig; secp256k1_ecdsa_sig_init(&sig); assert(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize)); assert(secp256k1_ecdsa_sig_verify(&sig, &q, &msg)); secp256k1_num_inc(&sig.r); assert(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg)); random_sign(&sig, &key, &msg, NULL); sigsize = 80; assert(secp256k1_ecdsa_sig_serialize(signature, &sigsize, &sig)); assert(ECDSA_verify(0, message, sizeof(message), signature, sigsize, ec_key) == 1); secp256k1_ecdsa_sig_free(&sig); EC_KEY_free(ec_key); secp256k1_num_free(&key); secp256k1_num_free(&msg); }
int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { int ret = 0; secp256k1_num_t m; secp256k1_num_init(&m); secp256k1_ecdsa_sig_t sig; secp256k1_ecdsa_sig_init(&sig); secp256k1_num_set_bin(&sig.r, sig64, 32); secp256k1_num_set_bin(&sig.s, sig64 + 32, 32); secp256k1_num_set_bin(&m, msg, msglen); secp256k1_ge_t q; if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) { secp256k1_ecdsa_pubkey_serialize(&q, pubkey, pubkeylen, compressed); ret = 1; } secp256k1_ecdsa_sig_free(&sig); secp256k1_num_free(&m); return ret; }
void test_ecdsa_sign_verify() { const secp256k1_ge_consts_t *c = secp256k1_ge_consts; secp256k1_num_t msg, key; secp256k1_num_init(&msg); random_num_order_test(&msg); secp256k1_num_init(&key); random_num_order_test(&key); secp256k1_gej_t pubj; secp256k1_ecmult_gen(&pubj, &key); secp256k1_ge_t pub; secp256k1_ge_set_gej(&pub, &pubj); secp256k1_ecdsa_sig_t sig; secp256k1_ecdsa_sig_init(&sig); random_sign(&sig, &key, &msg, NULL); assert(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); secp256k1_num_inc(&msg); assert(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); secp256k1_ecdsa_sig_free(&sig); secp256k1_num_free(&msg); secp256k1_num_free(&key); }
int main() { secp256k1_fe_start(); secp256k1_ge_start(); secp256k1_ecmult_start(); secp256k1_fe_t x; const secp256k1_num_t *order = &secp256k1_ge_consts->order; secp256k1_num_t r, s, m; secp256k1_num_init(&r); secp256k1_num_init(&s); secp256k1_num_init(&m); secp256k1_ecdsa_sig_t sig; secp256k1_ecdsa_sig_init(&sig); secp256k1_fe_set_hex(&x, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64); int cnt = 0; int good = 0; for (int i=0; i<1000000; i++) { random_num_order(&r); random_num_order(&s); random_num_order(&m); secp256k1_ecdsa_sig_set_rs(&sig, &r, &s); secp256k1_ge_t pubkey; secp256k1_ge_set_xo(&pubkey, &x, 1); if (secp256k1_ge_is_valid(&pubkey)) { cnt++; good += secp256k1_ecdsa_sig_verify(&sig, &pubkey, &m); } } printf("%i/%i\n", good, cnt); secp256k1_num_free(&r); secp256k1_num_free(&s); secp256k1_num_free(&m); secp256k1_ecdsa_sig_free(&sig); secp256k1_ecmult_stop(); secp256k1_ge_stop(); secp256k1_fe_stop(); return 0; }