Example #1
0
int main(void) {
    int i;
    secp256k1_pubkey_t pubkey;
    secp256k1_ecdsa_signature_t sig;
    benchmark_verify_t data;

    data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);

    for (i = 0; i < 32; i++) {
        data.msg[i] = 1 + i;
    }
    for (i = 0; i < 32; i++) {
        data.key[i] = 33 + i;
    }
    data.siglen = 72;
    CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
    CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
    CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
    CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);

    run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);

    secp256k1_context_destroy(data.ctx);
    return 0;
}
Example #2
0
int main(void) {
    int i;
    secp256k1_pubkey pubkey;
    secp256k1_ecdsa_signature sig;
    benchmark_verify_t data;

    data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);

    for (i = 0; i < 32; i++) {
        data.msg[i] = 1 + i;
    }
    for (i = 0; i < 32; i++) {
        data.key[i] = 33 + i;
    }
    data.siglen = 72;
    CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
    CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
    CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
    data.pubkeylen = 33;
    CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);

    run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);
#ifdef ENABLE_OPENSSL_TESTS
    data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1);
    run_benchmark("ecdsa_verify_openssl", benchmark_verify_openssl, NULL, NULL, &data, 10, 20000);
    EC_GROUP_free(data.ec_group);
#endif

    secp256k1_context_destroy(data.ctx);
    return 0;
}
Example #3
0
bool sign(ec_signature& out, const ec_secret& secret, const hash_digest& hash)
{
    secp256k1_ecdsa_signature signature;
    const auto context = signing.context();

    if (secp256k1_ecdsa_sign(context, &signature, hash.data(), secret.data(),
        secp256k1_nonce_function_rfc6979, nullptr) != 1)
        return false;

    std::copy_n(std::begin(signature.data), out.size(), out.begin());
    return true;
}
Example #4
0
bool ecc_sign(const uint8_t *private_key, const uint8_t *hash, unsigned char *sigder, size_t *outlen)
{
    assert(secp256k1_ctx);

    secp256k1_ecdsa_signature sig;
    if (!secp256k1_ecdsa_sign(secp256k1_ctx, &sig, hash, private_key, secp256k1_nonce_function_rfc6979, NULL))
        return false;

    if (secp256k1_ecdsa_signature_serialize_der(secp256k1_ctx, sigder, outlen, &sig))
        return false;

    return true;
}
Example #5
0
endorsement sign(ec_secret secret, hash_digest hash, ec_secret nonce)
{
    init.init();

    int out_size = max_endorsement_size;
    endorsement signature(out_size);
    if (0 < secp256k1_ecdsa_sign(hash.data(), hash.size(), signature.data(),
        &out_size, secret.data(), nonce.data()))
    {
        signature.resize(out_size);
        return signature;
    }

    // Error case:
    return endorsement();
}
Example #6
0
data_chunk sign(ec_secret secret, hash_digest hash, ec_secret nonce)
{
    std::reverse(hash.begin(), hash.end());
    init.init();
    int out_size = 72;
    data_chunk signature(out_size);

    if (!verify_private_key(nonce)) // Needed because of upstream bug
        return data_chunk();
    bool valid = secp256k1_ecdsa_sign(hash.data(), hash.size(),
        signature.data(), &out_size, secret.data(), nonce.data()) == 1;
    if (!valid)
        return data_chunk();

    signature.resize(out_size);
    return signature;
}
Example #7
0
endorsement sign(ec_secret secret, hash_digest hash)
{
    init.init();

    int out_size = max_endorsement_size;
    endorsement signature(out_size);

    ec_secret nonce;
    unsigned index = 0;
    do {
        nonce = create_nonce(secret, hash, index++);
    } while (secp256k1_ecdsa_sign(hash.data(), hash.size(), signature.data(),
        &out_size, secret.data(), nonce.data()) <= 0);

    signature.resize(out_size);
    return signature;
}
void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) {
    int i, j, k;

    /* Loop */
    for (i = 1; i < order; i++) {  /* message */
        for (j = 1; j < order; j++) {  /* key */
            for (k = 1; k < order; k++) {  /* nonce */
                const int starting_k = k;
                secp256k1_ecdsa_signature sig;
                secp256k1_scalar sk, msg, r, s, expected_r;
                unsigned char sk32[32], msg32[32];
                secp256k1_scalar_set_int(&msg, i);
                secp256k1_scalar_set_int(&sk, j);
                secp256k1_scalar_get_b32(sk32, &sk);
                secp256k1_scalar_get_b32(msg32, &msg);

                secp256k1_ecdsa_sign(ctx, &sig, msg32, sk32, secp256k1_nonce_function_smallint, &k);

                secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig);
                /* Note that we compute expected_r *after* signing -- this is important
                 * because our nonce-computing function function might change k during
                 * signing. */
                r_from_k(&expected_r, group, k);
                CHECK(r == expected_r);
                CHECK((k * s) % order == (i + r * j) % order ||
                      (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order);

                /* Overflow means we've tried every possible nonce */
                if (k < starting_k) {
                    break;
                }
            }
        }
    }

    /* We would like to verify zero-knowledge here by counting how often every
     * possible (s, r) tuple appears, but because the group order is larger
     * than the field order, when coercing the x-values to scalar values, some
     * appear more often than others, so we are actually not zero-knowledge.
     * (This effect also appears in the real code, but the difference is on the
     * order of 1/2^128th the field order, so the deviation is not useful to a
     * computationally bounded attacker.)
     */
}
Example #9
0
void sign_hash(secp256k1_context *secpctx,
	       const struct privkey *privkey,
	       const struct sha256_double *h,
	       struct signature *s)
{
	bool ok;

#ifdef USE_SCHNORR
	ok = secp256k1_schnorr_sign(secpctx,
				    s->schnorr,
				    h->sha.u.u8,
				    privkey->secret, NULL, NULL);
#else
	ok = secp256k1_ecdsa_sign(secpctx,
				  &s->sig,
				  h->sha.u.u8,
				  privkey->secret, NULL, NULL);
#endif
	assert(ok);
}
SECP256K1_API jobjectArray JNICALL Java_org_commercium_NativeSecp256k1_secp256k1_1ecdsa_1sign
  (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l)
{
  secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
  unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
  unsigned char* secKey = (unsigned char*) (data + 32);

  jobjectArray retArray;
  jbyteArray sigArray, intsByteArray;
  unsigned char intsarray[2];

  secp256k1_ecdsa_signature sig[72];

  int ret = secp256k1_ecdsa_sign(ctx, sig, data, secKey, NULL, NULL );

  unsigned char outputSer[72];
  size_t outputLen = 72;

  if( ret ) {
    int ret2 = secp256k1_ecdsa_signature_serialize_der(ctx,outputSer, &outputLen, sig ); (void)ret2;
  }

  intsarray[0] = outputLen;
  intsarray[1] = ret;

  retArray = (*env)->NewObjectArray(env, 2,
    (*env)->FindClass(env, "[B"),
    (*env)->NewByteArray(env, 1));

  sigArray = (*env)->NewByteArray(env, outputLen);
  (*env)->SetByteArrayRegion(env, sigArray, 0, outputLen, (jbyte*)outputSer);
  (*env)->SetObjectArrayElement(env, retArray, 0, sigArray);

  intsByteArray = (*env)->NewByteArray(env, 2);
  (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray);
  (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray);

  (void)classObject;

  return retArray;
}
Example #11
0
bool bp_sign(const struct bp_key *key, const void *data, size_t data_len,
	     void **sig_, size_t *sig_len_)
{
	secp256k1_ecdsa_signature sig;

	if (32 != data_len) {
		return false;
	}

	secp256k1_context *ctx = get_secp256k1_context();
	if (!ctx) {
		return false;
	}

	if (!secp256k1_ec_seckey_verify(ctx, key->secret)) {
		return false;
	}

	if (!secp256k1_ecdsa_sign(ctx, &sig,
				  data,
				  key->secret,
				  secp256k1_nonce_function_rfc6979,
				  NULL)) {
		return false;
	}

	*sig_ = malloc(72);
	*sig_len_ = 72;

	if (!secp256k1_ecdsa_signature_serialize_der(ctx, *sig_, sig_len_, &sig)) {
		free(sig_);
		*sig_ = NULL;
		return false;
	}

	return true;
}
Example #12
0
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);

}
Example #13
0
bool serialize(const int devfd, struct bitcoin_storage *const st, bool serial_pad)
{
	static struct encoder_state s;
	static bool first_run = true;
	static int buf_left = 0; // Bytes left to send
	static int buf_i = 0; // Bytes position of next unsent byte

	if (first_run) {
		encoder_state_init(&s);
		first_run = false;
	}

	gint queued = heap_size(&st->send_queue);

	if (!buf_left && queued) {
		// Try to fill send buffer
		struct msg *m = bitcoin_dequeue(st);

		// Should not happen
		if (m == NULL) errx(6,"Send queue handling error");

		// Do not retransmit if it is already sent.
		if (m->sent) {
			printf("Already sent %s %s, skipping\n",
			       bitcoin_type_str(m),
			       hex256(bitcoin_inv_hash(m)));
			return true;
		}

		// Mark message as sent
		m->sent = true;

		// Calculate signature. FIXME: Include type in calculation!
		
		// Bitcoin message header in unidirectional
		// transfer. The signature is used to verify the
		// transmitter. Transactions have their own signature
		// inside message body, too.
		
		unsigned char sig[72];
		int siglen;
		secp256k1_ecdsa_sign(m->payload,m->length,sig,&siglen,NULL,NULL);

		encode_start(&s);
		encode(&s,&siglen,1); // FIXME doesn't work on big endian archs
		encode(&s,&sig,siglen);
		encode(&s,&m->type,1); // FIXME doesn't work on big endian archs
		encode(&s,m->payload,m->length);

		// Finishing encoding and updating send buffer
		buf_left = encode_end(&s);
		buf_i = 0;

		// Debugging
		char height_buf[20] = "";
		if (m->height != UNCONFIRMED) {
			snprintf(height_buf,sizeof(height_buf),
				 " @ %d",m->height);
		}
		printf("Sending %s %s%s, %d bytes, %d items left\n",
		       bitcoin_type_str(m),
		       hex256(bitcoin_inv_hash(m)),
		       height_buf,
		       m->length,
		       queued);
	}

	if (buf_left) {
		// Consume buffer as much as possible
		const int wrote = write(devfd, s.buf+buf_i, buf_left);
		if (wrote == 0) {
			errx(3,"Weird behaviour on serial port");
		} else if (wrote == -1) {
			err(4,"Unable to write to serial port");
		}
		buf_i += wrote;
		buf_left -= wrote;
	} else {
		if (!serial_pad) {
			// All is sent, do not come back until there
			// is more data availableq
			printf("Serial device idle\n");
			return false;
		}
		// Send padding and go back to waiting loop.
		guint8 buf[PAD_COUNT*5];
		int i = 0;
		while (i < sizeof(buf)) {
			// Z_SYNC_FLUSH is 5 bytes long:
			buf[i++] = 0x00;
			buf[i++] = 0x00;
			buf[i++] = 0x00;
			buf[i++] = 0xFF;
			buf[i++] = 0xFF;
		}

		const int ret = write(devfd,buf,sizeof(buf));
		if (ret < 1) err(4,"Unable to write to serial port");
		if (ret != sizeof(buf)) err(10,"Too large padding buffer or non-linuxy system");
		printf("Sending %d bytes of padding\n",ret);
	}
	return true;
}