SECP256K1_API jobjectArray JNICALL Java_org_commercium_NativeSecp256k1_secp256k1_1privkey_1tweak_1add
  (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l)
{
  secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l;
  unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
  const unsigned char* tweak = (unsigned char*) (privkey + 32);

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

  int privkeylen = 32;

  int ret = secp256k1_ec_privkey_tweak_add(ctx, privkey, tweak);

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

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

  privArray = (*env)->NewByteArray(env, privkeylen);
  (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey);
  (*env)->SetObjectArrayElement(env, retArray, 0, privArray);

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

  (void)classObject;

  return retArray;
}
Ejemplo n.º 2
0
/* BOLT #3:
 *
 * The corresponding private keys can be similarly derived, if the basepoint
 * secrets are known (i.e. the private keys corresponding to `localpubkey`,
 * `local_htlcpubkey`, and `local_delayedpubkey` only):
 *
 *     privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)
 */
bool derive_simple_privkey(const struct secret *base_secret,
			const struct pubkey *basepoint,
			const struct pubkey *per_commitment_point,
			struct privkey *key)
{
	struct sha256 sha;
	unsigned char der_keys[PUBKEY_CMPR_LEN * 2];

	pubkey_to_der(der_keys, per_commitment_point);
	pubkey_to_der(der_keys + PUBKEY_CMPR_LEN, basepoint);
	sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
	printf("# SHA256(per_commitment_point || basepoint)\n");
	printf("# => SHA256(0x%s || 0x%s)\n",
	       tal_hexstr(tmpctx, der_keys, PUBKEY_CMPR_LEN),
	       tal_hexstr(tmpctx, der_keys + PUBKEY_CMPR_LEN, PUBKEY_CMPR_LEN));
	printf("# = 0x%s\n", tal_hexstr(tmpctx, &sha, sizeof(sha)));
#endif

	key->secret = *base_secret;
	if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret.data,
					   sha.u.u8) != 1)
		return false;
#ifdef SUPERVERBOSE
	printf("# + basepoint_secret (0x%s)\n",
	       tal_hexstr(tmpctx, base_secret, sizeof(*base_secret)));
	printf("# = 0x%s\n",
	       tal_hexstr(tmpctx, key, sizeof(*key)));
#endif
	return true;
}
Ejemplo n.º 3
0
bool bp_key_add_secret(struct bp_key *out,
		       const struct bp_key *key,
		       const uint8_t *tweak32)
{
	secp256k1_context *ctx = get_secp256k1_context();
	if (!ctx) {
		return false;
	}

	// If the secret is valid, tweak it and calculate the
	// resulting public key.  Otherwise tweak the public key (and
	// ensure the output private key is invalid).

	if (secp256k1_ec_seckey_verify(ctx, key->secret)) {

		memcpy(out->secret, key->secret, sizeof(key->secret));
		if (secp256k1_ec_privkey_tweak_add(ctx, out->secret, tweak32)) {
			return secp256k1_ec_pubkey_create(
				ctx, &out->pubkey, out->secret);
		}

		return false;
	}

	memset(out->secret, 0, sizeof(out->secret));
	memcpy(&out->pubkey, &key->pubkey, sizeof(secp256k1_pubkey));
	return secp256k1_ec_pubkey_tweak_add(ctx, &out->pubkey, tweak32);
}
Ejemplo n.º 4
0
PrivateKey & PrivateKey::operator += (const PrivateKey &privateKey)
{
    if(!secp256k1_ec_privkey_tweak_add(getContext().get(), data(), privateKey.data()))
    {
        throw std::runtime_error("private key operation failed");
    }
    return *this;
}
Ejemplo n.º 5
0
/* BOLT #3:
 *
 * The corresponding private key can be derived once the `per_commitment_secret`
 * is known:
 *
 *     revocationprivkey = revocation_basepoint_secret * SHA256(revocation_basepoint || per_commitment_point) + per_commitment_secret * SHA256(per_commitment_point || revocation_basepoint)
 */
bool derive_revocation_privkey(const struct secret *base_secret,
			       const struct secret *per_commitment_secret,
			       const struct pubkey *basepoint,
			       const struct pubkey *per_commitment_point,
			       struct privkey *key)
{
	struct sha256 sha;
	unsigned char der_keys[PUBKEY_CMPR_LEN * 2];
	struct secret part2;

	pubkey_to_der(der_keys, basepoint);
	pubkey_to_der(der_keys + PUBKEY_CMPR_LEN, per_commitment_point);
	sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
	printf("# SHA256(revocation_basepoint || per_commitment_point)\n");
	printf("# => SHA256(0x%s || 0x%s)\n",
	       tal_hexstr(tmpctx, der_keys, PUBKEY_CMPR_LEN),
	       tal_hexstr(tmpctx, der_keys + PUBKEY_CMPR_LEN, PUBKEY_CMPR_LEN));
	printf("# = 0x%s\n", tal_hexstr(tmpctx, sha.u.u8, sizeof(sha.u.u8))),
#endif

	key->secret = *base_secret;
	if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, key->secret.data,
					   sha.u.u8)
	    != 1)
		return false;
#ifdef SUPERVERBOSE
	printf("# * revocation_basepoint_secret (0x%s)",
	       tal_hexstr(tmpctx, base_secret, sizeof(*base_secret))),
	printf("# = 0x%s\n", tal_hexstr(tmpctx, key, sizeof(*key))),
#endif

	pubkey_to_der(der_keys, per_commitment_point);
	pubkey_to_der(der_keys + PUBKEY_CMPR_LEN, basepoint);
	sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
	printf("# SHA256(per_commitment_point || revocation_basepoint)\n");
	printf("# => SHA256(0x%s || 0x%s)\n",
	       tal_hexstr(tmpctx, der_keys, PUBKEY_CMPR_LEN),
	       tal_hexstr(tmpctx, der_keys + PUBKEY_CMPR_LEN, PUBKEY_CMPR_LEN));
	printf("# = 0x%s\n", tal_hexstr(tmpctx, sha.u.u8, sizeof(sha.u.u8))),
#endif

	part2 = *per_commitment_secret;
	if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, part2.data,
					   sha.u.u8) != 1)
		return false;
#ifdef SUPERVERBOSE
	printf("# * per_commitment_secret (0x%s)",
	       tal_hexstr(tmpctx, per_commitment_secret,
			  sizeof(*per_commitment_secret))),
		printf("# = 0x%s\n", tal_hexstr(tmpctx, &part2, sizeof(part2)));
#endif

	if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret.data,
					   part2.data) != 1)
		return false;

#ifdef SUPERVERBOSE
	printf("# => 0x%s\n", tal_hexstr(tmpctx, key, sizeof(*key)));
#endif
	return true;
}
Ejemplo n.º 6
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);

}
Ejemplo n.º 7
0
bool ec_add(ec_secret& a, const ec_secret& b)
{
    init.init();
    return secp256k1_ec_privkey_tweak_add(a.data(), b.data()) == 1;
}
Ejemplo n.º 8
0
bool ecc_private_key_tweak_add(uint8_t *private_key, const uint8_t *tweak)
{
    assert(secp256k1_ctx);
    return secp256k1_ec_privkey_tweak_add(secp256k1_ctx, (unsigned char *)private_key, (const unsigned char *)tweak);
}
Ejemplo n.º 9
0
bool ec_add(ec_secret& left, const ec_secret& right)
{
    const auto context = verification.context();
    return secp256k1_ec_privkey_tweak_add(context, left.data(),
        right.data()) == 1;
}