예제 #1
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;
}
예제 #2
0
파일: log.c 프로젝트: cdecker/lightning
static void log_to_file(const char *prefix,
			enum log_level level,
			bool continued,
			const struct timeabs *time,
			const char *str,
			const u8 *io,
			size_t io_len,
			FILE *logf)
{
	char iso8601_msec_fmt[sizeof("YYYY-mm-ddTHH:MM:SS.%03dZ")];
	strftime(iso8601_msec_fmt, sizeof(iso8601_msec_fmt), "%FT%T.%%03dZ", gmtime(&time->ts.tv_sec));
	char iso8601_s[sizeof("YYYY-mm-ddTHH:MM:SS.nnnZ")];
	snprintf(iso8601_s, sizeof(iso8601_s), iso8601_msec_fmt, (int) time->ts.tv_nsec / 1000000);

	if (level == LOG_IO_IN || level == LOG_IO_OUT) {
		const char *dir = level == LOG_IO_IN ? "[IN]" : "[OUT]";
		char *hex = tal_hexstr(NULL, io, io_len);
		fprintf(logf, "%s %s%s%s %s\n",
			iso8601_s, prefix, str, dir, hex);
		tal_free(hex);
	} else 	if (!continued) {
		fprintf(logf, "%s %s %s\n", iso8601_s, prefix, str);
	} else {
		fprintf(logf, "%s %s \t%s\n", iso8601_s, prefix, str);
	}
	fflush(logf);
}
예제 #3
0
static void hexeq(const void *p, size_t len, const char *hex)
{
	char *tmphex = tal_hexstr(NULL, p, len);

	if (strcmp(hex, tmphex)) {
		fprintf(stderr, "Expected '%s' got '%s'", hex, tmphex);
		abort();
	}
	tal_free(tmphex);
}
예제 #4
0
char *netaddr_to_hex(const tal_t *ctx, const struct netaddr *a)
{
	u8 *blob = tal_arr(ctx, u8, 0);
	char *hex;

	push_le32(a->type, push, &blob);
	push_le32(a->protocol, push, &blob);
	push_le32(a->addrlen, push, &blob);
	assert(a->addrlen <= sizeof(a->saddr));
	push(&a->saddr, a->addrlen, &blob);

	hex = tal_hexstr(ctx, blob, tal_count(blob));
	tal_free(blob);
	return hex;
}
예제 #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;
}
예제 #6
0
/* BOLT #3:
 *
 * The `revocationpubkey` is a blinded key: when the local node wishes to
 * create a new commitment for the remote node, it uses its own
 * `revocation_basepoint` and the remote node's `per_commitment_point` to
 * derive a new `revocationpubkey` for the commitment. After the remote node
 * reveals the `per_commitment_secret` used (thereby revoking that
 * commitment), the local node can then derive the `revocationprivkey`, as it
 * now knows the two secrets necessary to derive the key
 * (`revocation_basepoint_secret` and `per_commitment_secret`).
 *
 * The `per_commitment_point` is generated using elliptic-curve multiplication:
 *
 * 	per_commitment_point = per_commitment_secret * G
 *
 * And this is used to derive the revocation pubkey from the remote node's
 * `revocation_basepoint`:
 *
 * 	revocationpubkey = revocation_basepoint * SHA256(revocation_basepoint || per_commitment_point) + per_commitment_point * SHA256(per_commitment_point || revocation_basepoint)
 */
bool derive_revocation_key(const struct pubkey *basepoint,
			const struct pubkey *per_commitment_point,
			struct pubkey *key)
{
	struct sha256 sha;
	unsigned char der_keys[PUBKEY_CMPR_LEN * 2];
	secp256k1_pubkey add[2];
	const secp256k1_pubkey *args[2];

	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

	add[0] = basepoint->pubkey;
	if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, &add[0], sha.u.u8) != 1)
		return false;
#ifdef SUPERVERBOSE
	printf("# x revocation_basepoint = 0x%s\n",
	       type_to_string(tmpctx, secp256k1_pubkey, &add[0]));
#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

	add[1] = per_commitment_point->pubkey;
	if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, &add[1], sha.u.u8) != 1)
		return false;
#ifdef SUPERVERBOSE
	printf("# x per_commitment_point = 0x%s\n",
	       type_to_string(tmpctx, secp256k1_pubkey, &add[1]));
#endif

	args[0] = &add[0];
	args[1] = &add[1];
	if (secp256k1_ec_pubkey_combine(secp256k1_ctx, &key->pubkey, args, 2)
	    != 1)
		return false;

#ifdef SUPERVERBOSE
	printf("# 0x%s + 0x%s => 0x%s\n",
	       type_to_string(tmpctx, secp256k1_pubkey, args[0]),
	       type_to_string(tmpctx, secp256k1_pubkey, args[1]),
	       type_to_string(tmpctx, struct pubkey, key));
#endif
	return true;
}
예제 #7
0
파일: utils.c 프로젝트: cdecker/lightning
char *tal_hex(const tal_t *ctx, const tal_t *data)
{
	return tal_hexstr(ctx, data, tal_bytelen(data));
}
예제 #8
0
int main(void)
{
	setup_locale();

	struct privkey privkey;
	struct secret base_secret, per_commitment_secret;
	struct pubkey base_point, per_commitment_point, pubkey, pubkey2;

	setup_tmpctx();
	secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
						 | SECP256K1_CONTEXT_SIGN);

	base_secret = secret_from_hex("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
	per_commitment_secret = secret_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100");

	printf("base_secret: 0x%s\n",
	       tal_hexstr(tmpctx, &base_secret, sizeof(base_secret)));
	printf("per_commitment_secret: 0x%s\n",
	       tal_hexstr(tmpctx, &per_commitment_secret,
			  sizeof(per_commitment_secret)));
	if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
					&per_commitment_point.pubkey,
					per_commitment_secret.data))
		abort();
	if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
					&base_point.pubkey,
					base_secret.data))
		abort();
	printf("base_point: 0x%s\n",
	       type_to_string(tmpctx, struct pubkey, &base_point));
	printf("per_commitment_point: 0x%s\n",
	       type_to_string(tmpctx, struct pubkey, &per_commitment_point));

	/* FIXME: Annotate internal steps. */
	if (!derive_simple_key(&base_point, &per_commitment_point, &pubkey))
		abort();
	printf("localkey: 0x%s\n",
	       type_to_string(tmpctx, struct pubkey, &pubkey));
	if (!derive_simple_privkey(&base_secret, &base_point,
				   &per_commitment_point, &privkey))
		abort();
	printf("localprivkey: 0x%s\n",
	       tal_hexstr(tmpctx, &privkey, sizeof(privkey)));
	pubkey_from_privkey(&privkey, &pubkey2);
	assert(pubkey_eq(&pubkey, &pubkey2));

	/* FIXME: Annotate internal steps. */
	if (!derive_revocation_key(&base_point, &per_commitment_point, &pubkey))
		abort();
	printf("revocationkey: 0x%s\n",
	       type_to_string(tmpctx, struct pubkey, &pubkey));
	if (!derive_revocation_privkey(&base_secret, &per_commitment_secret,
				       &base_point, &per_commitment_point,
				       &privkey))
		abort();
	printf("revocationprivkey: 0x%s\n",
	       tal_hexstr(tmpctx, &privkey, sizeof(privkey)));
	pubkey_from_privkey(&privkey, &pubkey2);
	assert(pubkey_eq(&pubkey, &pubkey2));

	/* No memory leaks please */
	secp256k1_context_destroy(secp256k1_ctx);
	tal_free(tmpctx);
	return 0;
}