compact_signature private_key::sign_compact( const fc::sha256& digest, bool require_canonical )const { FC_ASSERT( my->_key != empty_priv ); compact_signature result; int recid; unsigned int counter = 0; do { FC_ASSERT( secp256k1_ecdsa_sign_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) result.begin() + 1, (unsigned char*) my->_key.data(), extended_nonce_function, &counter, &recid )); } while( require_canonical && !public_key::is_canonical( result ) ); result.begin()[0] = 27 + 4 + recid; return result; }
static void bench_sign(void* arg) { int i; bench_sign_t *data = (bench_sign_t*)arg; unsigned char sig[64]; for (i = 0; i < 20000; i++) { int j; int recid = 0; check(secp256k1_ecdsa_sign_compact(data->ctx, data->msg, sig, data->key, null, null, &recid)); for (j = 0; j < 32; j++) { data->msg[j] = sig[j]; /* move former r to message. */ data->key[j] = sig[j + 32]; /* move former s to key. */ } } }
static void bench_sign(void* arg) { int i; bench_sign_t *data = (bench_sign_t*)arg; unsigned char sig[64]; for (i = 0; i < 20000; i++) { int j; int recid = 0; CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, NULL, NULL, &recid)); for (j = 0; j < 32; j++) { data->msg[j] = sig[j]; /* Move former R to message. */ data->key[j] = sig[j + 32]; /* Move former S to key. */ } } }
compact_signature sign_compact(ec_secret secret, hash_digest hash, ec_secret nonce) { init.init(); compact_signature out; if (0 < secp256k1_ecdsa_sign_compact(hash.data(), hash.size(), out.signature.data(), secret.data(), nonce.data(), &out.recid)) { return out; } // Error case: return compact_signature{{{0}}, 0}; }
compact_signature sign_compact(ec_secret secret, hash_digest hash) { init.init(); compact_signature out; ec_secret nonce; unsigned index = 0; do { nonce = create_nonce(secret, hash, index++); } while (secp256k1_ecdsa_sign_compact(hash.data(), hash.size(), out.signature.data(), secret.data(), nonce.data(), &out.recid) <= 0); return out; }
void test_ecdsa_end_to_end(void) { unsigned char privkey[32]; unsigned char message[32]; /* Generate a random key and message. */ { secp256k1_scalar_t msg, key; random_scalar_order_test(&msg); random_scalar_order_test(&key); secp256k1_scalar_get_b32(privkey, &key); secp256k1_scalar_get_b32(message, &msg); } /* Construct and verify corresponding public key. */ CHECK(secp256k1_ec_seckey_verify(privkey) == 1); unsigned char pubkey[65]; int pubkeylen = 65; CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, secp256k1_rand32() % 2) == 1); CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen)); /* Verify private key import and export. */ unsigned char seckey[300]; int seckeylen = 300; CHECK(secp256k1_ec_privkey_export(privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1); unsigned char privkey2[32]; CHECK(secp256k1_ec_privkey_import(privkey2, seckey, seckeylen) == 1); CHECK(memcmp(privkey, privkey2, 32) == 0); /* Optionally tweak the keys using addition. */ if (secp256k1_rand32() % 3 == 0) { unsigned char rnd[32]; secp256k1_rand256_test(rnd); int ret1 = secp256k1_ec_privkey_tweak_add(privkey, rnd); int ret2 = secp256k1_ec_pubkey_tweak_add(pubkey, pubkeylen, rnd); CHECK(ret1 == ret2); if (ret1 == 0) return; unsigned char pubkey2[65]; int pubkeylen2 = 65; CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); } /* Optionally tweak the keys using multiplication. */ if (secp256k1_rand32() % 3 == 0) { unsigned char rnd[32]; secp256k1_rand256_test(rnd); int ret1 = secp256k1_ec_privkey_tweak_mul(privkey, rnd); int ret2 = secp256k1_ec_pubkey_tweak_mul(pubkey, pubkeylen, rnd); CHECK(ret1 == ret2); if (ret1 == 0) return; unsigned char pubkey2[65]; int pubkeylen2 = 65; CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); } /* Sign. */ unsigned char signature[72]; int signaturelen = 72; while(1) { unsigned char rnd[32]; secp256k1_rand256_test(rnd); if (secp256k1_ecdsa_sign(message, 32, signature, &signaturelen, privkey, rnd) == 1) { break; } } /* Verify. */ CHECK(secp256k1_ecdsa_verify(message, 32, signature, signaturelen, pubkey, pubkeylen) == 1); /* Destroy signature and verify again. */ signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255); CHECK(secp256k1_ecdsa_verify(message, 32, signature, signaturelen, pubkey, pubkeylen) != 1); /* Compact sign. */ unsigned char csignature[64]; int recid = 0; while(1) { unsigned char rnd[32]; secp256k1_rand256_test(rnd); if (secp256k1_ecdsa_sign_compact(message, 32, csignature, privkey, rnd, &recid) == 1) { break; } } /* Recover. */ unsigned char recpubkey[65]; int recpubkeylen = 0; CHECK(secp256k1_ecdsa_recover_compact(message, 32, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1); CHECK(recpubkeylen == pubkeylen); CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0); /* Destroy signature and verify again. */ csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255); CHECK(secp256k1_ecdsa_recover_compact(message, 32, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 || memcmp(pubkey, recpubkey, pubkeylen) != 0); CHECK(recpubkeylen == pubkeylen); }