Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
/**********************************************************************
|
|
|
|
* Copyright (c) 2015 Gregory Maxwell *
|
|
|
|
* Distributed under the MIT software license, see the accompanying *
|
|
|
|
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#ifndef SECP256K1_MODULE_RANGEPROOF_TESTS
|
|
|
|
#define SECP256K1_MODULE_RANGEPROOF_TESTS
|
|
|
|
|
2016-07-04 13:04:57 +00:00
|
|
|
#include "group.h"
|
|
|
|
#include "scalar.h"
|
|
|
|
#include "testrand.h"
|
|
|
|
#include "util.h"
|
|
|
|
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
#include "include/secp256k1_rangeproof.h"
|
|
|
|
|
|
|
|
void test_pedersen(void) {
|
2016-07-04 13:04:57 +00:00
|
|
|
secp256k1_pedersen_commitment commits[19];
|
|
|
|
const secp256k1_pedersen_commitment *cptr[19];
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
unsigned char blinds[32*19];
|
|
|
|
const unsigned char *bptr[19];
|
|
|
|
secp256k1_scalar s;
|
|
|
|
uint64_t values[19];
|
|
|
|
int64_t totalv;
|
|
|
|
int i;
|
|
|
|
int inputs;
|
|
|
|
int outputs;
|
|
|
|
int total;
|
|
|
|
inputs = (secp256k1_rand32() & 7) + 1;
|
|
|
|
outputs = (secp256k1_rand32() & 7) + 2;
|
|
|
|
total = inputs + outputs;
|
|
|
|
for (i = 0; i < 19; i++) {
|
2016-07-04 13:04:57 +00:00
|
|
|
cptr[i] = &commits[i];
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
bptr[i] = &blinds[i * 32];
|
|
|
|
}
|
|
|
|
totalv = 0;
|
|
|
|
for (i = 0; i < inputs; i++) {
|
|
|
|
values[i] = secp256k1_rands64(0, INT64_MAX - totalv);
|
|
|
|
totalv += values[i];
|
|
|
|
}
|
|
|
|
if (secp256k1_rand32() & 1) {
|
|
|
|
for (i = 0; i < outputs; i++) {
|
|
|
|
int64_t max = INT64_MAX;
|
|
|
|
if (totalv < 0) {
|
|
|
|
max += totalv;
|
|
|
|
}
|
|
|
|
values[i + inputs] = secp256k1_rands64(0, max);
|
|
|
|
totalv -= values[i + inputs];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < outputs - 1; i++) {
|
|
|
|
values[i + inputs] = secp256k1_rands64(0, totalv);
|
|
|
|
totalv -= values[i + inputs];
|
|
|
|
}
|
|
|
|
values[total - 1] = totalv >> (secp256k1_rand32() & 1);
|
|
|
|
totalv -= values[total - 1];
|
|
|
|
}
|
|
|
|
for (i = 0; i < total - 1; i++) {
|
|
|
|
random_scalar_order(&s);
|
|
|
|
secp256k1_scalar_get_b32(&blinds[i * 32], &s);
|
|
|
|
}
|
|
|
|
CHECK(secp256k1_pedersen_blind_sum(ctx, &blinds[(total - 1) * 32], bptr, total - 1, inputs));
|
|
|
|
for (i = 0; i < total; i++) {
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i]));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
}
|
|
|
|
CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv));
|
|
|
|
CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv + 1));
|
|
|
|
random_scalar_order(&s);
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
secp256k1_scalar_get_b32(&blinds[i * 32], &s);
|
|
|
|
}
|
|
|
|
values[0] = INT64_MAX;
|
|
|
|
values[1] = 0;
|
|
|
|
values[2] = 1;
|
|
|
|
for (i = 0; i < 3; i++) {
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i]));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
}
|
|
|
|
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[2], 1, -1));
|
|
|
|
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[2], 1, &cptr[1], 1, 1));
|
|
|
|
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[0], 1, 0));
|
|
|
|
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[1], 1, INT64_MAX));
|
|
|
|
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[1], 1, 0));
|
|
|
|
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[0], 1, -INT64_MAX));
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_borromean(void) {
|
|
|
|
unsigned char e0[32];
|
|
|
|
secp256k1_scalar s[64];
|
|
|
|
secp256k1_gej pubs[64];
|
|
|
|
secp256k1_scalar k[8];
|
|
|
|
secp256k1_scalar sec[8];
|
|
|
|
secp256k1_ge ge;
|
|
|
|
secp256k1_scalar one;
|
|
|
|
unsigned char m[32];
|
2016-07-04 13:04:57 +00:00
|
|
|
size_t rsizes[8];
|
|
|
|
size_t secidx[8];
|
|
|
|
size_t nrings;
|
|
|
|
size_t i;
|
|
|
|
size_t j;
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
int c;
|
|
|
|
secp256k1_rand256_test(m);
|
|
|
|
nrings = 1 + (secp256k1_rand32()&7);
|
|
|
|
c = 0;
|
|
|
|
secp256k1_scalar_set_int(&one, 1);
|
|
|
|
if (secp256k1_rand32()&1) {
|
|
|
|
secp256k1_scalar_negate(&one, &one);
|
|
|
|
}
|
|
|
|
for (i = 0; i < nrings; i++) {
|
|
|
|
rsizes[i] = 1 + (secp256k1_rand32()&7);
|
|
|
|
secidx[i] = secp256k1_rand32() % rsizes[i];
|
|
|
|
random_scalar_order(&sec[i]);
|
|
|
|
random_scalar_order(&k[i]);
|
|
|
|
if(secp256k1_rand32()&7) {
|
|
|
|
sec[i] = one;
|
|
|
|
}
|
|
|
|
if(secp256k1_rand32()&7) {
|
|
|
|
k[i] = one;
|
|
|
|
}
|
|
|
|
for (j = 0; j < rsizes[i]; j++) {
|
|
|
|
random_scalar_order(&s[c + j]);
|
|
|
|
if(secp256k1_rand32()&7) {
|
|
|
|
s[i] = one;
|
|
|
|
}
|
|
|
|
if (j == secidx[i]) {
|
|
|
|
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubs[c + j], &sec[i]);
|
|
|
|
} else {
|
|
|
|
random_group_element_test(&ge);
|
|
|
|
random_group_element_jacobian_test(&pubs[c + j],&ge);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c += rsizes[i];
|
|
|
|
}
|
|
|
|
CHECK(secp256k1_borromean_sign(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, e0, s, pubs, k, sec, rsizes, secidx, nrings, m, 32));
|
|
|
|
CHECK(secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, e0, s, pubs, rsizes, nrings, m, 32));
|
|
|
|
i = secp256k1_rand32() % c;
|
|
|
|
secp256k1_scalar_negate(&s[i],&s[i]);
|
|
|
|
CHECK(!secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, e0, s, pubs, rsizes, nrings, m, 32));
|
|
|
|
secp256k1_scalar_negate(&s[i],&s[i]);
|
|
|
|
secp256k1_scalar_set_int(&one, 1);
|
|
|
|
for(j = 0; j < 4; j++) {
|
|
|
|
i = secp256k1_rand32() % c;
|
|
|
|
if (secp256k1_rand32() & 1) {
|
|
|
|
secp256k1_gej_double_var(&pubs[i],&pubs[i], NULL);
|
|
|
|
} else {
|
|
|
|
secp256k1_scalar_add(&s[i],&s[i],&one);
|
|
|
|
}
|
|
|
|
CHECK(!secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, e0, s, pubs, rsizes, nrings, m, 32));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_rangeproof(void) {
|
|
|
|
const uint64_t testvs[11] = {0, 1, 5, 11, 65535, 65537, INT32_MAX, UINT32_MAX, INT64_MAX - 1, INT64_MAX, UINT64_MAX};
|
2016-07-04 13:04:57 +00:00
|
|
|
secp256k1_pedersen_commitment commit;
|
|
|
|
secp256k1_pedersen_commitment commit2;
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
unsigned char proof[5134];
|
|
|
|
unsigned char blind[32];
|
|
|
|
unsigned char blindout[32];
|
|
|
|
unsigned char message[4096];
|
2016-07-04 13:04:57 +00:00
|
|
|
size_t mlen;
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
uint64_t v;
|
|
|
|
uint64_t vout;
|
|
|
|
uint64_t vmin;
|
|
|
|
uint64_t minv;
|
|
|
|
uint64_t maxv;
|
2016-07-04 13:04:57 +00:00
|
|
|
size_t len;
|
|
|
|
size_t i;
|
|
|
|
size_t j;
|
|
|
|
size_t k;
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
secp256k1_rand256(blind);
|
|
|
|
for (i = 0; i < 11; i++) {
|
|
|
|
v = testvs[i];
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
for (vmin = 0; vmin < (i<9 && i > 0 ? 2 : 1); vmin++) {
|
|
|
|
len = 5134;
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, 0, 0, v));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
CHECK(len <= 5134);
|
|
|
|
mlen = 4096;
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
for (j = 0; j < mlen; j++) {
|
|
|
|
CHECK(message[j] == 0);
|
|
|
|
}
|
|
|
|
CHECK(mlen <= 4096);
|
|
|
|
CHECK(memcmp(blindout, blind, 32) == 0);
|
|
|
|
CHECK(vout == v);
|
|
|
|
CHECK(minv <= v);
|
|
|
|
CHECK(maxv >= v);
|
|
|
|
len = 5134;
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
CHECK(len <= 73);
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
CHECK(memcmp(blindout, blind, 32) == 0);
|
|
|
|
CHECK(vout == v);
|
|
|
|
CHECK(minv == v);
|
|
|
|
CHECK(maxv == v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
secp256k1_rand256(blind);
|
|
|
|
v = INT64_MAX - 1;
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
for (i = 0; i < 19; i++) {
|
|
|
|
len = 5134;
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, i, 0, v));
|
|
|
|
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
CHECK(len <= 5134);
|
|
|
|
CHECK(minv <= v);
|
|
|
|
CHECK(maxv >= v);
|
|
|
|
}
|
|
|
|
secp256k1_rand256(blind);
|
|
|
|
{
|
|
|
|
/*Malleability test.*/
|
|
|
|
v = secp256k1_rands64(0, 255);
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
len = 5134;
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, 0, 3, v));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
CHECK(len <= 5134);
|
|
|
|
for (i = 0; i < len*8; i++) {
|
|
|
|
proof[i >> 3] ^= 1 << (i & 7);
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
proof[i >> 3] ^= 1 << (i & 7);
|
|
|
|
}
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
CHECK(minv <= v);
|
|
|
|
CHECK(maxv >= v);
|
|
|
|
}
|
2016-07-04 13:04:57 +00:00
|
|
|
memcpy(&commit2, &commit, sizeof(commit));
|
|
|
|
for (i = 0; i < 10 * (size_t) count; i++) {
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
int exp;
|
|
|
|
int min_bits;
|
|
|
|
v = secp256k1_rands64(0, UINT64_MAX >> (secp256k1_rand32()&63));
|
|
|
|
vmin = 0;
|
|
|
|
if ((v < INT64_MAX) && (secp256k1_rand32()&1)) {
|
|
|
|
vmin = secp256k1_rands64(0, v);
|
|
|
|
}
|
|
|
|
secp256k1_rand256(blind);
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
len = 5134;
|
|
|
|
exp = (int)secp256k1_rands64(0,18)-(int)secp256k1_rands64(0,18);
|
|
|
|
if (exp < 0) {
|
|
|
|
exp = -exp;
|
|
|
|
}
|
|
|
|
min_bits = (int)secp256k1_rands64(0,64)-(int)secp256k1_rands64(0,64);
|
|
|
|
if (min_bits < 0) {
|
|
|
|
min_bits = -min_bits;
|
|
|
|
}
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, exp, min_bits, v));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
CHECK(len <= 5134);
|
|
|
|
mlen = 4096;
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
for (j = 0; j < mlen; j++) {
|
|
|
|
CHECK(message[j] == 0);
|
|
|
|
}
|
|
|
|
CHECK(mlen <= 4096);
|
|
|
|
CHECK(memcmp(blindout, blind, 32) == 0);
|
|
|
|
CHECK(vout == v);
|
|
|
|
CHECK(minv <= v);
|
|
|
|
CHECK(maxv >= v);
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len));
|
|
|
|
memcpy(&commit2, &commit, sizeof(commit));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
}
|
|
|
|
for (j = 0; j < 10; j++) {
|
|
|
|
for (i = 0; i < 96; i++) {
|
|
|
|
secp256k1_rand256(&proof[i * 32]);
|
|
|
|
}
|
|
|
|
for (k = 0; k < 128; k++) {
|
|
|
|
len = k;
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
}
|
|
|
|
len = secp256k1_rands64(0, 3072);
|
2016-07-04 13:04:57 +00:00
|
|
|
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len));
|
Pedersen commitments, borromean ring signatures, and ZK range proofs.
This commit adds three new cryptosystems to libsecp256k1:
Pedersen commitments are a system for making blinded commitments
to a value. Functionally they work like:
commit_b,v = H(blind_b || value_v),
except they are additively homorphic, e.g.
C(b1, v1) - C(b2, v2) = C(b1 - b2, v1 - v2) and
C(b1, v1) - C(b1, v1) = 0, etc.
The commitments themselves are EC points, serialized as 33 bytes.
In addition to the commit function this implementation includes
utility functions for verifying that a set of commitments sums
to zero, and for picking blinding factors that sum to zero.
If the blinding factors are uniformly random, pedersen commitments
have information theoretic privacy.
Borromean ring signatures are a novel efficient ring signature
construction for AND/OR admissions policies (the code here implements
an AND of ORs, each of any size). This construction requires
32 bytes of signature per pubkey used plus 32 bytes of constant
overhead. With these you can construct signatures like "Given pubkeys
A B C D E F G, the signer knows the discrete logs
satisifying (A || B) & (C || D || E) & (F || G)".
ZK range proofs allow someone to prove a pedersen commitment is in
a particular range (e.g. [0..2^64)) without revealing the specific
value. The construction here is based on the above borromean
ring signature and uses a radix-4 encoding and other optimizations
to maximize efficiency. It also supports encoding proofs with a
non-private base-10 exponent and minimum-value to allow trading
off secrecy for size and speed (or just avoiding wasting space
keeping data private that was already public due to external
constraints).
A proof for a 32-bit mantissa takes 2564 bytes, but 2048 bytes of
this can be used to communicate a private message to a receiver
who shares a secret random seed with the prover.
2015-08-05 19:04:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void run_rangeproof_tests(void) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 10*count; i++) {
|
|
|
|
test_pedersen();
|
|
|
|
}
|
|
|
|
for (i = 0; i < 10*count; i++) {
|
|
|
|
test_borromean();
|
|
|
|
}
|
|
|
|
test_rangeproof();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|