rangeproof: expose sidechannel message field in the signing API
Including a fix by Jonas Nick.
This commit is contained in:
parent
9f21e1b518
commit
9722b11506
@ -199,7 +199,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign(
|
|||||||
const unsigned char *nonce,
|
const unsigned char *nonce,
|
||||||
int exp,
|
int exp,
|
||||||
int min_bits,
|
int min_bits,
|
||||||
uint64_t value
|
uint64_t value,
|
||||||
|
const unsigned char *message,
|
||||||
|
size_t msg_len
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7);
|
||||||
|
|
||||||
/** Extract some basic information from a range-proof.
|
/** Extract some basic information from a range-proof.
|
||||||
|
@ -30,7 +30,7 @@ static void bench_rangeproof_setup(void* arg) {
|
|||||||
for (i = 0; i < 32; i++) data->blind[i] = i + 1;
|
for (i = 0; i < 32; i++) data->blind[i] = i + 1;
|
||||||
CHECK(secp256k1_pedersen_commit(data->ctx, &data->commit, data->blind, data->v));
|
CHECK(secp256k1_pedersen_commit(data->ctx, &data->commit, data->blind, data->v));
|
||||||
data->len = 5134;
|
data->len = 5134;
|
||||||
CHECK(secp256k1_rangeproof_sign(data->ctx, data->proof, &data->len, 0, &data->commit, data->blind, (const unsigned char*)&data->commit, 0, data->min_bits, data->v));
|
CHECK(secp256k1_rangeproof_sign(data->ctx, data->proof, &data->len, 0, &data->commit, data->blind, (const unsigned char*)&data->commit, 0, data->min_bits, data->v, NULL, 0));
|
||||||
CHECK(secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, &data->commit, data->proof, data->len));
|
CHECK(secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, &data->commit, data->proof, data->len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,8 @@ int secp256k1_rangeproof_verify(const secp256k1_context* ctx, uint64_t *min_valu
|
|||||||
}
|
}
|
||||||
|
|
||||||
int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof, size_t *plen, uint64_t min_value,
|
int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof, size_t *plen, uint64_t min_value,
|
||||||
const secp256k1_pedersen_commitment *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){
|
const secp256k1_pedersen_commitment *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value,
|
||||||
|
const unsigned char *message, size_t msg_len){
|
||||||
secp256k1_ge commitp;
|
secp256k1_ge commitp;
|
||||||
ARG_CHECK(ctx != NULL);
|
ARG_CHECK(ctx != NULL);
|
||||||
ARG_CHECK(proof != NULL);
|
ARG_CHECK(proof != NULL);
|
||||||
@ -187,7 +188,7 @@ int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof
|
|||||||
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
||||||
secp256k1_pedersen_commitment_load(&commitp, commit);
|
secp256k1_pedersen_commitment_load(&commitp, commit);
|
||||||
return secp256k1_rangeproof_sign_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx,
|
return secp256k1_rangeproof_sign_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx,
|
||||||
proof, plen, min_value, &commitp, blind, nonce, exp, min_bits, value);
|
proof, plen, min_value, &commitp, blind, nonce, exp, min_bits, value, message, msg_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -191,7 +191,8 @@ SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, size_t *rin
|
|||||||
SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmult_context* ecmult_ctx,
|
SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmult_context* ecmult_ctx,
|
||||||
const secp256k1_ecmult_gen_context* ecmult_gen_ctx,
|
const secp256k1_ecmult_gen_context* ecmult_gen_ctx,
|
||||||
unsigned char *proof, size_t *plen, uint64_t min_value,
|
unsigned char *proof, size_t *plen, uint64_t min_value,
|
||||||
const secp256k1_ge *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){
|
const secp256k1_ge *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value,
|
||||||
|
const unsigned char *message, size_t msg_len){
|
||||||
secp256k1_gej pubs[128]; /* Candidate digits for our proof, most inferred. */
|
secp256k1_gej pubs[128]; /* Candidate digits for our proof, most inferred. */
|
||||||
secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */
|
secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */
|
||||||
secp256k1_scalar sec[32]; /* Blinding factors for the correct digits. */
|
secp256k1_scalar sec[32]; /* Blinding factors for the correct digits. */
|
||||||
@ -231,6 +232,13 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
|
|||||||
}
|
}
|
||||||
len += 8;
|
len += 8;
|
||||||
}
|
}
|
||||||
|
/* Do we have enough room in the proof for the message? Each ring gives us 128 bytes, but the
|
||||||
|
* final ring is used to encode the blinding factor and the value, so we can't use that. (Well,
|
||||||
|
* technically there are 64 bytes available if we avoided the other data, but this is difficult
|
||||||
|
* because it's not always in the same place. */
|
||||||
|
if (msg_len > 0 && msg_len > 128 * (rings - 1)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/* Do we have enough room for the proof? */
|
/* Do we have enough room for the proof? */
|
||||||
if (*plen - len < 32 * (npub + rings - 1) + 32 + ((rings+6) >> 3)) {
|
if (*plen - len < 32 * (npub + rings - 1) + 32 + ((rings+6) >> 3)) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -241,6 +249,9 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
|
|||||||
secp256k1_sha256_write(&sha256_m, proof, len);
|
secp256k1_sha256_write(&sha256_m, proof, len);
|
||||||
|
|
||||||
memset(prep, 0, 4096);
|
memset(prep, 0, 4096);
|
||||||
|
if (message != NULL) {
|
||||||
|
memcpy(prep, message, msg_len);
|
||||||
|
}
|
||||||
/* Note, the data corresponding to the blinding factors must be zero. */
|
/* Note, the data corresponding to the blinding factors must be zero. */
|
||||||
if (rsizes[rings - 1] > 1) {
|
if (rsizes[rings - 1] > 1) {
|
||||||
size_t idx;
|
size_t idx;
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef SECP256K1_MODULE_RANGEPROOF_TESTS
|
#ifndef SECP256K1_MODULE_RANGEPROOF_TESTS
|
||||||
#define SECP256K1_MODULE_RANGEPROOF_TESTS
|
#define SECP256K1_MODULE_RANGEPROOF_TESTS
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "scalar.h"
|
#include "scalar.h"
|
||||||
#include "testrand.h"
|
#include "testrand.h"
|
||||||
@ -166,17 +168,42 @@ void test_rangeproof(void) {
|
|||||||
size_t i;
|
size_t i;
|
||||||
size_t j;
|
size_t j;
|
||||||
size_t k;
|
size_t k;
|
||||||
|
/* Short message is a Simone de Beauvoir quote */
|
||||||
|
const unsigned char message_short[120] = "When I see my own likeness in the depths of someone else's consciousness, I always experience a moment of panic.";
|
||||||
|
/* Long message is 0xA5 with a bunch of this quote in the middle */
|
||||||
|
unsigned char message_long[3968];
|
||||||
|
memset(message_long, 0xa5, sizeof(message_long));
|
||||||
|
for (i = 1200; i < 3600; i += 120) {
|
||||||
|
memcpy(&message_long[i], message_short, sizeof(message_short));
|
||||||
|
}
|
||||||
|
|
||||||
secp256k1_rand256(blind);
|
secp256k1_rand256(blind);
|
||||||
for (i = 0; i < 11; i++) {
|
for (i = 0; i < 11; i++) {
|
||||||
v = testvs[i];
|
v = testvs[i];
|
||||||
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
||||||
for (vmin = 0; vmin < (i<9 && i > 0 ? 2 : 1); vmin++) {
|
for (vmin = 0; vmin < (i<9 && i > 0 ? 2 : 1); vmin++) {
|
||||||
|
const unsigned char *input_message = NULL;
|
||||||
|
size_t input_message_len = 0;
|
||||||
|
/* vmin is always either 0 or 1; if it is 1, then we have no room for a message.
|
||||||
|
* If it's 0, we use "minimum encoding" and only have room for a small message when
|
||||||
|
* `testvs[i]` is >= 4; for a large message when it's >= 2^32. */
|
||||||
|
if (vmin == 0 && i > 2) {
|
||||||
|
input_message = message_short;
|
||||||
|
input_message_len = sizeof(message_short);
|
||||||
|
}
|
||||||
|
if (vmin == 0 && i > 7) {
|
||||||
|
input_message = message_long;
|
||||||
|
input_message_len = sizeof(message_long);
|
||||||
|
}
|
||||||
len = 5134;
|
len = 5134;
|
||||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, 0, 0, v));
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, 0, 0, v, input_message, input_message_len));
|
||||||
CHECK(len <= 5134);
|
CHECK(len <= 5134);
|
||||||
mlen = 4096;
|
mlen = 4096;
|
||||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len));
|
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len));
|
||||||
for (j = 0; j < mlen; j++) {
|
if (input_message != NULL) {
|
||||||
|
CHECK(memcmp(message, input_message, input_message_len) == 0);
|
||||||
|
}
|
||||||
|
for (j = input_message_len; j < mlen; j++) {
|
||||||
CHECK(message[j] == 0);
|
CHECK(message[j] == 0);
|
||||||
}
|
}
|
||||||
CHECK(mlen <= 4096);
|
CHECK(mlen <= 4096);
|
||||||
@ -185,7 +212,7 @@ void test_rangeproof(void) {
|
|||||||
CHECK(minv <= v);
|
CHECK(minv <= v);
|
||||||
CHECK(maxv >= v);
|
CHECK(maxv >= v);
|
||||||
len = 5134;
|
len = 5134;
|
||||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v));
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v, NULL, 0));
|
||||||
CHECK(len <= 73);
|
CHECK(len <= 73);
|
||||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len));
|
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len));
|
||||||
CHECK(memcmp(blindout, blind, 32) == 0);
|
CHECK(memcmp(blindout, blind, 32) == 0);
|
||||||
@ -199,7 +226,7 @@ void test_rangeproof(void) {
|
|||||||
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
||||||
for (i = 0; i < 19; i++) {
|
for (i = 0; i < 19; i++) {
|
||||||
len = 5134;
|
len = 5134;
|
||||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, i, 0, v));
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, i, 0, v, NULL, 0));
|
||||||
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len));
|
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len));
|
||||||
CHECK(len <= 5134);
|
CHECK(len <= 5134);
|
||||||
CHECK(minv <= v);
|
CHECK(minv <= v);
|
||||||
@ -211,7 +238,7 @@ void test_rangeproof(void) {
|
|||||||
v = secp256k1_rands64(0, 255);
|
v = secp256k1_rands64(0, 255);
|
||||||
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
||||||
len = 5134;
|
len = 5134;
|
||||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, 0, 3, v));
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, 0, 3, v, NULL, 0));
|
||||||
CHECK(len <= 5134);
|
CHECK(len <= 5134);
|
||||||
for (i = 0; i < len*8; i++) {
|
for (i = 0; i < len*8; i++) {
|
||||||
proof[i >> 3] ^= 1 << (i & 7);
|
proof[i >> 3] ^= 1 << (i & 7);
|
||||||
@ -242,7 +269,7 @@ void test_rangeproof(void) {
|
|||||||
if (min_bits < 0) {
|
if (min_bits < 0) {
|
||||||
min_bits = -min_bits;
|
min_bits = -min_bits;
|
||||||
}
|
}
|
||||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, exp, min_bits, v));
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, exp, min_bits, v, NULL, 0));
|
||||||
CHECK(len <= 5134);
|
CHECK(len <= 5134);
|
||||||
mlen = 4096;
|
mlen = 4096;
|
||||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len));
|
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user