Skip to content

Commit 9eea081

Browse files
committed
rangeproof: add a bunch more testing
Add two new fixed rangeproof vectors; check that various extracted values are correct; add a test for creating and verifying single-value proofs.
1 parent 71a206f commit 9eea081

File tree

1 file changed

+261
-8
lines changed

1 file changed

+261
-8
lines changed

src/modules/rangeproof/tests_impl.h

+261-8
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,95 @@ static void test_rangeproof(void) {
547547
}
548548
}
549549

550+
static void test_single_value_proof(uint64_t val) {
551+
unsigned char proof[5000];
552+
secp256k1_pedersen_commitment commit;
553+
unsigned char blind[32];
554+
unsigned char blind_out[32];
555+
unsigned char nonce[32];
556+
const unsigned char message[1] = " "; /* no message will fit into a single-value proof */
557+
unsigned char message_out[sizeof(proof)] = { 0 };
558+
size_t plen = sizeof(proof);
559+
uint64_t min_val_out = 0;
560+
uint64_t max_val_out = 0;
561+
uint64_t val_out = 0;
562+
size_t m_len_out = 0;
563+
564+
secp256k1_testrand256(blind);
565+
secp256k1_testrand256(nonce);
566+
CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, val, secp256k1_generator_h));
567+
568+
CHECK(secp256k1_rangeproof_sign(
569+
ctx,
570+
proof, &plen,
571+
val, /* min_val */
572+
&commit, blind, nonce,
573+
-1, /* exp: -1 is magic value to indicate a single-value proof */
574+
0, /* min_bits */
575+
val, /* val */
576+
message, sizeof(message), /* Will cause this to fail */
577+
NULL, 0,
578+
secp256k1_generator_h
579+
) == 0);
580+
581+
plen = sizeof(proof);
582+
CHECK(secp256k1_rangeproof_sign(
583+
ctx,
584+
proof, &plen,
585+
val, /* min_val */
586+
&commit, blind, nonce,
587+
-1, /* exp: -1 is magic value to indicate a single-value proof */
588+
0, /* min_bits */
589+
val, /* val */
590+
NULL, 0,
591+
NULL, 0,
592+
secp256k1_generator_h
593+
) == 1);
594+
595+
/* Different proof sizes are unfortunate but is caused by `min_value` of
596+
* zero being special-cased and encoded more efficiently. */
597+
if (val == 0) {
598+
CHECK(plen == 65);
599+
} else {
600+
CHECK(plen == 73);
601+
}
602+
603+
CHECK(secp256k1_rangeproof_verify(
604+
ctx,
605+
&min_val_out, &max_val_out,
606+
&commit,
607+
proof, plen,
608+
NULL, 0,
609+
secp256k1_generator_h
610+
) == 1);
611+
CHECK(min_val_out == val);
612+
CHECK(max_val_out == val);
613+
614+
memset(message_out, 0, sizeof(message_out));
615+
m_len_out = sizeof(message_out);
616+
CHECK(secp256k1_rangeproof_rewind(
617+
ctx,
618+
blind_out, &val_out,
619+
message_out, &m_len_out,
620+
nonce,
621+
&min_val_out, &max_val_out,
622+
&commit,
623+
proof, plen,
624+
NULL, 0,
625+
secp256k1_generator_h
626+
));
627+
CHECK(val_out == val);
628+
CHECK(min_val_out == val);
629+
CHECK(max_val_out == val);
630+
CHECK(m_len_out == 0);
631+
CHECK(memcmp(blind, blind_out, 32) == 0);
632+
for (m_len_out = 0; m_len_out < sizeof(message_out); m_len_out++) {
633+
CHECK(message_out[m_len_out] == 0);
634+
}
635+
}
636+
550637
#define MAX_N_GENS 30
551-
void test_multiple_generators(void) {
638+
static void test_multiple_generators(void) {
552639
const size_t n_inputs = (secp256k1_testrand32() % (MAX_N_GENS / 2)) + 1;
553640
const size_t n_outputs = (secp256k1_testrand32() % (MAX_N_GENS / 2)) + 1;
554641
const size_t n_generators = n_inputs + n_outputs;
@@ -610,7 +697,18 @@ void test_multiple_generators(void) {
610697
}
611698

612699
void test_rangeproof_fixed_vectors(void) {
613-
const unsigned char vector_1[] = {
700+
size_t i;
701+
unsigned char blind[32];
702+
uint64_t value;
703+
uint64_t min_value;
704+
uint64_t max_value;
705+
secp256k1_pedersen_commitment pc;
706+
unsigned char message[4000] = {0};
707+
size_t m_len = sizeof(message);
708+
709+
/* Vector 1: no message */
710+
{
711+
static const unsigned char vector_1[] = {
614712
0x62, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x02, 0x2a, 0x5c, 0x42, 0x0e, 0x1d,
615713
0x51, 0xe1, 0xb7, 0xf3, 0x69, 0x04, 0xb5, 0xbb, 0x9b, 0x41, 0x66, 0x14, 0xf3, 0x64, 0x42, 0x26,
616714
0xe3, 0xa7, 0x6a, 0x06, 0xbb, 0xa8, 0x5a, 0x49, 0x6f, 0x19, 0x76, 0xfb, 0xe5, 0x75, 0x77, 0x88,
@@ -653,25 +751,175 @@ void test_rangeproof_fixed_vectors(void) {
653751
0xa6, 0x45, 0xf6, 0xce, 0xcf, 0x48, 0xf6, 0x1e, 0x3d, 0xd2, 0xcf, 0xcb, 0x3a, 0xcd, 0xbb, 0x92,
654752
0x29, 0x24, 0x16, 0x7f, 0x8a, 0xa8, 0x5c, 0x0c, 0x45, 0x71, 0x33
655753
};
656-
const unsigned char commit_1[] = {
754+
static const unsigned char commit_1[] = {
657755
0x08,
658756
0xf5, 0x1e, 0x0d, 0xc5, 0x86, 0x78, 0x51, 0xa9, 0x00, 0x00, 0xef, 0x4d, 0xe2, 0x94, 0x60, 0x89,
659757
0x83, 0x04, 0xb4, 0x0e, 0x90, 0x10, 0x05, 0x1c, 0x7f, 0xd7, 0x33, 0x92, 0x1f, 0xe7, 0x74, 0x59
660758
};
661-
uint64_t min_value_1;
662-
uint64_t max_value_1;
663-
secp256k1_pedersen_commitment pc;
759+
static const unsigned char blind_1[] = {
760+
0x98, 0x44, 0xfc, 0x7a, 0x64, 0xa9, 0xca, 0xdf, 0xf3, 0x2f, 0x9f, 0x02, 0xba, 0x46, 0xc7, 0xd9,
761+
0x77, 0x47, 0xa4, 0xd3, 0x53, 0x17, 0xc6, 0x44, 0x30, 0x73, 0x84, 0xeb, 0x1f, 0xbe, 0xa1, 0xfb
762+
};
664763

665764
CHECK(secp256k1_pedersen_commitment_parse(ctx, &pc, commit_1));
666-
667765
CHECK(secp256k1_rangeproof_verify(
668766
ctx,
669-
&min_value_1, &max_value_1,
767+
&min_value, &max_value,
670768
&pc,
671769
vector_1, sizeof(vector_1),
672770
NULL, 0,
673771
secp256k1_generator_h
674772
));
773+
CHECK(min_value == 86);
774+
CHECK(max_value == 25586);
775+
776+
CHECK(secp256k1_rangeproof_rewind(
777+
ctx,
778+
blind, &value,
779+
message, &m_len,
780+
pc.data,
781+
&min_value, &max_value,
782+
&pc,
783+
vector_1, sizeof(vector_1),
784+
NULL, 0,
785+
secp256k1_generator_h
786+
));
787+
788+
CHECK(memcmp(blind, blind_1, 32) == 0);
789+
CHECK(value == 86);
790+
CHECK(min_value == 86);
791+
CHECK(max_value == 25586);
792+
CHECK(m_len == 448); /* length of the sidechannel in the proof */
793+
for (i = 0; i < m_len; i++) {
794+
/* No message encoded in this vector */
795+
CHECK(message[i] == 0);
796+
}
797+
}
798+
799+
/* Vector 2: embedded message */
800+
{
801+
static const unsigned char vector_2[] = {
802+
0x40, 0x03, 0x00, 0x90, 0x1a, 0x61, 0x64, 0xbb, 0x85, 0x1a, 0x78, 0x35, 0x1e, 0xe0, 0xd5, 0x96,
803+
0x71, 0x0f, 0x18, 0x8e, 0xf3, 0x33, 0xf0, 0x75, 0xfe, 0xd6, 0xc6, 0x11, 0x6b, 0x42, 0x89, 0xea,
804+
0xa2, 0x0c, 0x89, 0x25, 0x37, 0x81, 0x10, 0xf9, 0xf0, 0x9b, 0xda, 0x68, 0x2a, 0xd9, 0x2e, 0x0c,
805+
0x45, 0x17, 0x54, 0x6d, 0x02, 0xd2, 0x21, 0x5d, 0xbc, 0x10, 0xf8, 0x8f, 0xf1, 0x92, 0x40, 0xa9,
806+
0xc7, 0x24, 0x00, 0x1b, 0xc8, 0x75, 0x0f, 0xf6, 0x8f, 0x93, 0x8b, 0x78, 0x62, 0x73, 0x3c, 0x86,
807+
0x4b, 0x61, 0x7c, 0x0f, 0xc6, 0x41, 0xc9, 0xb3, 0xc1, 0x30, 0x7f, 0xd4, 0xee, 0x9f, 0x37, 0x08,
808+
0x9b, 0x64, 0x23, 0xd5, 0xe6, 0x1a, 0x03, 0x54, 0x74, 0x9b, 0x0b, 0xae, 0x6f, 0x2b, 0x1e, 0xf5,
809+
0x40, 0x44, 0xaa, 0x12, 0xe8, 0xbd, 0xe0, 0xa6, 0x85, 0x89, 0xf1, 0xa9, 0xd0, 0x3f, 0x2e, 0xc6,
810+
0x1f, 0x11, 0xf5, 0x44, 0x69, 0x99, 0x31, 0x10, 0x2e, 0x64, 0xc6, 0x44, 0xdb, 0x47, 0x06, 0x6d,
811+
0xd5, 0xf2, 0x8d, 0x19, 0x00, 0x39, 0xb8, 0xca, 0xda, 0x5c, 0x1d, 0x83, 0xbd, 0xa3, 0x6d, 0xbf,
812+
0x97, 0xdd, 0x83, 0x86, 0xc9, 0x56, 0xe2, 0xbb, 0x37, 0x4b, 0x2d, 0xb5, 0x9d, 0xf2, 0x7a, 0x6a,
813+
0x25, 0x47, 0xfa, 0x03, 0x05, 0xc5, 0xda, 0x73, 0xe1, 0x96, 0x15, 0x21, 0x23, 0xe5, 0xef, 0x55,
814+
0x36, 0xdd, 0xf1, 0xb1, 0x3f, 0x33, 0x1a, 0x91, 0x6c, 0x73, 0x64, 0xd3, 0x88, 0xe7, 0xc6, 0xc9,
815+
0x04, 0x29, 0xae, 0x55, 0x27, 0xa0, 0x80, 0x60, 0xaf, 0x0c, 0x09, 0x2f, 0xc8, 0x1b, 0xe6, 0x16,
816+
0x9e, 0xed, 0x29, 0xc7, 0x93, 0xce, 0xc7, 0x0d, 0xdf, 0x1f, 0x28, 0xba, 0xf3, 0x38, 0xc3, 0xaa,
817+
0x99, 0xd9, 0x21, 0x41, 0xb8, 0x10, 0xa5, 0x48, 0x37, 0xec, 0x60, 0xda, 0x64, 0x5a, 0x73, 0x55,
818+
0xd7, 0xff, 0x23, 0xfa, 0xf6, 0xc6, 0xf4, 0xe2, 0xca, 0x99, 0x2f, 0x30, 0x36, 0x48, 0x73, 0x8b,
819+
0x57, 0xa6, 0x62, 0x12, 0xa3, 0xe7, 0x5c, 0xa8, 0xd1, 0xe6, 0x85, 0x05, 0x59, 0xfe, 0x2b, 0x44,
820+
0xe4, 0x73, 0x1c, 0xc3, 0x56, 0x32, 0x07, 0x65, 0x4a, 0x58, 0xaf, 0x2b, 0x3f, 0x36, 0xca, 0xb4,
821+
0x1d, 0x5c, 0x2a, 0x46, 0x1f, 0xf7, 0x63, 0x59, 0x4f, 0x2b, 0xd0, 0xf6, 0xfc, 0xcf, 0x04, 0x09,
822+
0xb7, 0x65, 0x1b
823+
};
824+
static const unsigned char commit_2[] = {
825+
0x09,
826+
0x25, 0xa4, 0xbd, 0xc4, 0x57, 0x69, 0xeb, 0x4f, 0x34, 0x0f, 0xea, 0xb8, 0xe4, 0x72, 0x04, 0x54,
827+
0x06, 0xe5, 0xd6, 0x85, 0x15, 0x42, 0xea, 0x6e, 0x1d, 0x11, 0x11, 0x9c, 0x56, 0xf8, 0x10, 0x45
828+
};
829+
static const unsigned char blind_2[] = {
830+
0xdc, 0x79, 0x07, 0x89, 0x2d, 0xc4, 0xe3, 0x76, 0xf9, 0x13, 0x38, 0xd6, 0x4b, 0x46, 0xed, 0x9d,
831+
0x9b, 0xf6, 0x70, 0x3d, 0x04, 0xcf, 0x96, 0x8c, 0xfd, 0xb5, 0xff, 0x0a, 0x06, 0xc7, 0x08, 0x8b
832+
};
833+
static const unsigned char message_2[] = "When I see my own likeness in the depths of someone else's consciousness, I always experience a moment of panic.";
834+
835+
CHECK(secp256k1_pedersen_commitment_parse(ctx, &pc, commit_2));
836+
CHECK(secp256k1_rangeproof_verify(
837+
ctx,
838+
&min_value, &max_value,
839+
&pc,
840+
vector_2, sizeof(vector_2),
841+
NULL, 0,
842+
secp256k1_generator_h
843+
));
844+
CHECK(min_value == 0);
845+
CHECK(max_value == 15);
846+
847+
CHECK(secp256k1_rangeproof_rewind(
848+
ctx,
849+
blind, &value,
850+
message, &m_len,
851+
pc.data,
852+
&min_value, &max_value,
853+
&pc,
854+
vector_2, sizeof(vector_2),
855+
NULL, 0,
856+
secp256k1_generator_h
857+
));
858+
859+
CHECK(memcmp(blind, blind_2, 32) == 0);
860+
CHECK(value == 11);
861+
CHECK(min_value == 0);
862+
CHECK(max_value == 15);
863+
CHECK(m_len == 192); /* length of the sidechannel in the proof */
864+
CHECK(memcmp(message, message_2, sizeof(message_2)) == 0);
865+
for (i = sizeof(message_2); i < m_len; i++) {
866+
/* No message encoded in this vector */
867+
CHECK(message[i] == 0);
868+
}
869+
}
870+
871+
/* Vector 3: single-value proof of UINT64_MAX */
872+
{
873+
static const unsigned char vector_3[] = {
874+
0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdc, 0x7d, 0x0b, 0x79, 0x0e, 0xaf, 0x41,
875+
0xa5, 0x8e, 0x9b, 0x0c, 0x5b, 0xa3, 0xee, 0x7d, 0xfd, 0x3d, 0x6b, 0xf3, 0xac, 0x04, 0x8a, 0x43,
876+
0x75, 0xb0, 0xb7, 0x0e, 0x92, 0xd7, 0xdf, 0xf0, 0x76, 0xc4, 0xa5, 0xb6, 0x2f, 0xf1, 0xb5, 0xfb,
877+
0xb4, 0xb6, 0x29, 0xea, 0x34, 0x9b, 0x16, 0x30, 0x0d, 0x06, 0xf1, 0xb4, 0x3f, 0x0d, 0x73, 0x59,
878+
0x75, 0xbf, 0x5d, 0x19, 0x59, 0xef, 0x11, 0xf0, 0xbf
879+
};
880+
static const unsigned char commit_3[] = {
881+
0x08,
882+
0xc7, 0xea, 0x40, 0x7d, 0x26, 0x38, 0xa2, 0x99, 0xb9, 0x40, 0x22, 0x78, 0x17, 0x57, 0x65, 0xb3,
883+
0x36, 0x82, 0x18, 0x42, 0xc5, 0x57, 0x04, 0x5e, 0x58, 0x5e, 0xf6, 0x40, 0x8b, 0x24, 0x73, 0x10
884+
};
885+
static const unsigned char nonce_3[] = {
886+
0x84, 0x50, 0x94, 0x69, 0xa3, 0x4b, 0x6c, 0x62, 0x1a, 0xc7, 0xe2, 0x0e, 0x07, 0x9a, 0x6f, 0x85,
887+
0x5f, 0x26, 0x50, 0xcd, 0x88, 0x5a, 0x9f, 0xaa, 0x23, 0x5e, 0x0a, 0xe0, 0x7e, 0xc5, 0xe9, 0xf1
888+
};
889+
static const unsigned char blind_3[] = {
890+
0x68, 0x89, 0x47, 0x8c, 0x77, 0xec, 0xcc, 0x2b, 0x65, 0x01, 0x78, 0x6b, 0x06, 0x8b, 0x38, 0x94,
891+
0xc0, 0x6b, 0x9b, 0x4c, 0x02, 0xa6, 0xc8, 0xf6, 0xc0, 0x34, 0xea, 0x35, 0x57, 0xf4, 0xe1, 0x37
892+
};
893+
894+
CHECK(secp256k1_pedersen_commitment_parse(ctx, &pc, commit_3));
895+
CHECK(secp256k1_rangeproof_verify(
896+
ctx,
897+
&min_value, &max_value,
898+
&pc,
899+
vector_3, sizeof(vector_3),
900+
NULL, 0,
901+
secp256k1_generator_h
902+
));
903+
CHECK(min_value == UINT64_MAX);
904+
CHECK(max_value == UINT64_MAX);
905+
906+
CHECK(secp256k1_rangeproof_rewind(
907+
ctx,
908+
blind, &value,
909+
message, &m_len,
910+
nonce_3,
911+
&min_value, &max_value,
912+
&pc,
913+
vector_3, sizeof(vector_3),
914+
NULL, 0,
915+
secp256k1_generator_h
916+
));
917+
CHECK(memcmp(blind, blind_3, 32) == 0);
918+
CHECK(value == UINT64_MAX);
919+
CHECK(min_value == UINT64_MAX);
920+
CHECK(max_value == UINT64_MAX);
921+
CHECK(m_len == 0);
922+
}
675923
}
676924

677925
void test_pedersen_commitment_fixed_vector(void) {
@@ -696,6 +944,11 @@ void test_pedersen_commitment_fixed_vector(void) {
696944
void run_rangeproof_tests(void) {
697945
int i;
698946
test_api();
947+
948+
test_single_value_proof(0);
949+
test_single_value_proof(12345678);
950+
test_single_value_proof(UINT64_MAX);
951+
699952
test_rangeproof_fixed_vectors();
700953
test_pedersen_commitment_fixed_vector();
701954
for (i = 0; i < count / 2 + 1; i++) {

0 commit comments

Comments
 (0)