Bitcoin ABC  0.28.12
P2P Digital Currency
tests_impl.h
Go to the documentation of this file.
1 /***********************************************************************
2  * Copyright (c) 2017 Tomas van der Wansem *
3  * Distributed under the MIT software license, see the accompanying *
4  * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5  ***********************************************************************/
6 
7 #ifndef SECP256K1_MODULE_MULTISET_TESTS_H
8 #define SECP256K1_MODULE_MULTISET_TESTS_H
9 
10 
11 #include "include/secp256k1.h"
13 #include "util.h"
14 #include "testrand.h"
15 
16 #define DATALEN 64*3
17 #define DATACOUNT 100
18 
19 
20 #define CHECK_EQUAL(a,b) { \
21  unsigned char hash1[32]; \
22  unsigned char hash2[32]; \
23  secp256k1_multiset_finalize(ctx, hash1, (a)); \
24  secp256k1_multiset_finalize(ctx, hash2, (b)); \
25  CHECK(memcmp(hash1,hash2,sizeof(hash1))==0); \
26 }
27 
28 #define CHECK_NOTEQUAL(a,b) { \
29  unsigned char hash1[32]; \
30  unsigned char hash2[32]; \
31  secp256k1_multiset_finalize(ctx, hash1, (a)); \
32  secp256k1_multiset_finalize(ctx, hash2, (b)); \
33  CHECK(memcmp(hash1,hash2,sizeof(hash1))!=0); \
34 }
35 
36 static unsigned char elements[DATACOUNT][DATALEN];
37 
38 /* Create random data */
39 static void initdata(void) {
40  int n,m;
41  for(n=0; n < DATACOUNT; n++) {
42  for(m=0; m < DATALEN/4; m++) {
43  uint32_t x = secp256k1_testrand32();
44  memcpy(&elements[n][m], &x, sizeof(x));
45  }
46 
47  }
48 }
49 
50 void test_unordered(void) {
51 
52  /* Check if multisets are uneffected by order */
53 
54  secp256k1_multiset empty, r1,r2,r3;
55 
60 
63 
64  CHECK_NOTEQUAL(&r1,&r2); /* M(0,1)!=M() */
65 
68  CHECK_EQUAL(&r1,&r2); /* M(0,1)==M(1,0) */
69 
73 
74  CHECK_EQUAL(&r1,&r2); /* M()==M() */
75 
79 
83 
87 
88  CHECK_EQUAL(&r1,&r2); /* M(0,1,2)==M(2,0,1) */
89  CHECK_EQUAL(&r1,&r3); /* M(0,1,2)==M(1,0,2) */
90 
91 
92  secp256k1_multiset_combine(ctx, &r3, &empty);
93  CHECK_EQUAL(&r1,&r3); /* M(1,0,2)+M()=M(0,1,2) */
94 
96  CHECK_NOTEQUAL(&r1,&r3); /* M(1,0,2)+M(0,1,2)!=M(0,1,2) */
97 
98 }
99 
100 void test_combine(void) {
101 
102  /* Testing if combining is effectively the same as adding the elements */
103 
104  secp256k1_multiset empty, r1,r2,r3;
105  secp256k1_gej gej_pos, gej_neg;
106 
107  secp256k1_multiset_init(ctx, &empty);
111 
114  CHECK_NOTEQUAL(&r1,&r2); /* M(0) != M(1) */
115 
118  CHECK_EQUAL(&r1,&r2); /* M(1,0) == M(0,1) */
119 
123 
124  CHECK_EQUAL(&r1,&r2); /* M() == M() */
125 
129 
133  secp256k1_multiset_combine(ctx, &r2, &r3);
134  CHECK_EQUAL(&r1,&r2); /* M(0,1,2) == M(2)+M(0,1) */
135 
141  secp256k1_multiset_combine(ctx, &r2, &r3);
142  CHECK_EQUAL(&r1,&r2); /* M(0,1,2) == M(2,0)+M(1) */
143 
144  secp256k1_multiset_combine(ctx, &r2, &empty);
145  CHECK_EQUAL(&r1,&r2); /* M(0,1,2)+M() == M(0,1,2) */
146  secp256k1_multiset_combine(ctx, &r2, &r1);
147  CHECK_NOTEQUAL(&r1,&r2); /* M(0,1,2)+M(0,1,2) != M(0,1,2) */
148 
149  /* Combine multisets so that the combination representation is infinity */
152  CHECK_EQUAL(&r1, &r2); /* M() == M() */
153 
155 
156  gej_from_multiset_var(&gej_pos, &r1);
157  secp256k1_gej_neg(&gej_neg, &gej_pos);
158  secp256k1_fe_normalize(&gej_neg.x);
159  secp256k1_fe_normalize(&gej_neg.y);
160  secp256k1_fe_normalize(&gej_neg.z);
161 
162  multiset_from_gej_var(&r2, &gej_neg);
163 
164  /* This is equivalent to a removal due to multisets being associative */
165  secp256k1_multiset_combine(ctx, &r1, &r2);
166  CHECK_EQUAL(&empty, &r1); /* M() == M(X)+M(-X) == M(X)-M(X) */
167 }
168 
169 
170 void test_remove(void) {
171 
172  /* Testing removal of elements */
173  secp256k1_multiset empty, r1,r2,r3;
174 
175  secp256k1_multiset_init(ctx, &empty);
179 
180  CHECK_EQUAL(&r1,&r2); /* M()==M() */
181 
187 
197 
209 
210  CHECK_EQUAL(&r1,&r2); /* M(0,1,3,9,8)==M(1,9,11,10,9,3,8)-M(10,11) */
211  CHECK_EQUAL(&r1,&r3); /* M(0,1,3,9,8)==M(9,15,15,1,9,0,3,8)-M(15,15,9) */
212  CHECK_NOTEQUAL(&r1,&empty); /* M(0,1,3,9,8)!=M() */
213 
215  CHECK_NOTEQUAL(&r1,&r3); /* M(0,1,3,9,8)-M(8)!=M(0,1,3,9,8) */
216 
222 
223  CHECK_EQUAL(&r2,&empty); /* M(0,1,3,9,8)-M(0,1,3,9,8)==M() */
224 }
225 
226 void test_duplicate(void) {
227 
228  /* Test if the multiset properly handles duplicates */
229  secp256k1_multiset empty, r1,r2,r3;
230 
231  secp256k1_multiset_init(ctx, &empty);
235 
240 
243 
244  CHECK_NOTEQUAL(&r1, &r2); /* M(0,0,1,1)!=M(0,1) */
245 
248  CHECK_EQUAL(&r1, &r2); /* M(0,0,1,1)!=M(0,0,1,1) */
249 
254 
255  secp256k1_multiset_combine(ctx, &r2, &r3);
256  CHECK_EQUAL(&r1, &r2); /* M(0,0,0,1,1,1)!=M(0,0,1,1)+M(0,1) */
257 }
258 
259 void test_empty(void) {
260 
261  /* Test if empty set properties hold */
262 
263  secp256k1_multiset empty, r1,r2;
264 
265  secp256k1_multiset_init(ctx, &empty);
268 
269  CHECK_EQUAL(&empty,&r1); /* M()==M() */
270 
271  /* empty + empty = empty */
272  secp256k1_multiset_combine(ctx, &r1, &r2);
273  CHECK_EQUAL(&empty, &r1); /* M()+M()==M() */
274 }
275 
276 void test_testvector(void) {
277  /* Tests known values from the specification */
278 
279  const unsigned char d1[113] = {
280  0x98,0x20,0x51,0xfd,0x1e,0x4b,0xa7,0x44,0xbb,0xbe,0x68,0x0e,0x1f,0xee,0x14,0x67,0x7b,0xa1,0xa3,0xc3,0x54,0x0b,0xf7,0xb1,0xcd,0xb6,0x06,0xe8,0x57,0x23,0x3e,0x0e,
281  0x00,0x00,0x00,0x00,0x03,0x00,0xf2,0x05,0x2a,0x01,0x00,0x00,0x00,0x43,0x41,0x04,0x96,0xb5,0x38,0xe8,0x53,0x51,0x9c,0x72,0x6a,0x2c,0x91,0xe6,0x1e,0xc1,0x16,0x00,
282  0xae,0x13,0x90,0x81,0x3a,0x62,0x7c,0x66,0xfb,0x8b,0xe7,0x94,0x7b,0xe6,0x3c,0x52,0xda,0x75,0x89,0x37,0x95,0x15,0xd4,0xe0,0xa6,0x04,0xf8,0x14,0x17,0x81,0xe6,0x22,
283  0x94,0x72,0x11,0x66,0xbf,0x62,0x1e,0x73,0xa8,0x2c,0xbf,0x23,0x42,0xc8,0x58,0xee,0xac };
284 
285  const unsigned char d2[113] = {
286  0xd5,0xfd,0xcc,0x54,0x1e,0x25,0xde,0x1c,0x7a,0x5a,0xdd,0xed,0xf2,0x48,0x58,0xb8,0xbb,0x66,0x5c,0x9f,0x36,0xef,0x74,0x4e,0xe4,0x2c,0x31,0x60,0x22,0xc9,0x0f,0x9b,
287  0x00,0x00,0x00,0x00,0x05,0x00,0xf2,0x05,0x2a,0x01,0x00,0x00,0x00,0x43,0x41,0x04,0x72,0x11,0xa8,0x24,0xf5,0x5b,0x50,0x52,0x28,0xe4,0xc3,0xd5,0x19,0x4c,0x1f,0xcf,
288  0xaa,0x15,0xa4,0x56,0xab,0xdf,0x37,0xf9,0xb9,0xd9,0x7a,0x40,0x40,0xaf,0xc0,0x73,0xde,0xe6,0xc8,0x90,0x64,0x98,0x4f,0x03,0x38,0x52,0x37,0xd9,0x21,0x67,0xc1,0x3e,
289  0x23,0x64,0x46,0xb4,0x17,0xab,0x79,0xa0,0xfc,0xae,0x41,0x2a,0xe3,0x31,0x6b,0x77,0xac };
290 
291  const unsigned char d3[113] = {
292  0x44,0xf6,0x72,0x22,0x60,0x90,0xd8,0x5d,0xb9,0xa9,0xf2,0xfb,0xfe,0x5f,0x0f,0x96,0x09,0xb3,0x87,0xaf,0x7b,0xe5,0xb7,0xfb,0xb7,0xa1,0x76,0x7c,0x83,0x1c,0x9e,0x99,
293  0x00,0x00,0x00,0x00,0x07,0x00,0xf2,0x05,0x2a,0x01,0x00,0x00,0x00,0x43,0x41,0x04,0x94,0xb9,0xd3,0xe7,0x6c,0x5b,0x16,0x29,0xec,0xf9,0x7f,0xff,0x95,0xd7,0xa4,0xbb,
294  0xda,0xc8,0x7c,0xc2,0x60,0x99,0xad,0xa2,0x80,0x66,0xc6,0xff,0x1e,0xb9,0x19,0x12,0x23,0xcd,0x89,0x71,0x94,0xa0,0x8d,0x0c,0x27,0x26,0xc5,0x74,0x7f,0x1d,0xb4,0x9e,
295  0x8c,0xf9,0x0e,0x75,0xdc,0x3e,0x35,0x50,0xae,0x9b,0x30,0x08,0x6f,0x3c,0xd5,0xaa,0xac };
296 
297  /* Expected resulting multisets */
298  const unsigned char exp_empty[32] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
299  const unsigned char exp_m1[32] = { 0x5e,0x29,0x49,0x84,0xc0,0xb6,0xff,0x1c,0x89,0x7b,0xdb,0xb6,0xf7,0xcf,0x3e,0xf8,0x01,0xe2,0xf1,0x3b,0xc7,0x34,0x28,0xaa,0xcd,0xf8,0xcb,0x8d,0x3b,0xd2,0xf0,0xe5 };
300  const unsigned char exp_m2[32] = { 0x93,0x70,0x80,0xb6,0x6c,0x2b,0x37,0x2d,0x35,0x39,0x88,0xd6,0xc0,0x92,0x22,0x78,0x8f,0x88,0xa5,0x13,0x0a,0x13,0x32,0xeb,0xc1,0x49,0x5a,0xa3,0xa7,0xfa,0xb4,0xfb };
301  const unsigned char exp_m3[32] = { 0xdd,0xbf,0x2f,0x18,0xaf,0xe0,0xaf,0xa8,0x87,0x28,0x57,0x93,0xa4,0x82,0xa0,0x7f,0xc2,0x2a,0x46,0x28,0x48,0x36,0x78,0x73,0xd7,0x9d,0x72,0xa7,0x33,0x0a,0x96,0x15 };
302  const unsigned char exp_m1m2[32] = { 0x48,0x09,0x8f,0x4c,0xa9,0xbb,0x5d,0xac,0x27,0x3e,0x56,0x31,0x6d,0xb6,0x41,0x23,0x69,0xed,0x1f,0xa8,0xbe,0xb5,0x79,0x57,0x05,0x32,0xd1,0x63,0x47,0xfe,0xfc,0xcc };
303  const unsigned char exp_m1m2m3[32] = { 0x47,0xfb,0xdf,0xf4,0x76,0x7c,0x32,0xa4,0xea,0x74,0xca,0x43,0x86,0x59,0x0f,0x62,0x22,0xee,0x83,0x96,0xb8,0xb4,0xf0,0x0e,0xf5,0x6e,0x9b,0x49,0x43,0xf4,0x24,0x93 };
304 
305  unsigned char m0[32],m1[32],m2[32],m3[32],m1m2[32],m1m2m3[32];
306  secp256k1_multiset r0,r1,r2,r3;
307 
312 
313  secp256k1_multiset_add (ctx, &r1, d1, sizeof(d1));
314  secp256k1_multiset_add (ctx, &r2, d2, sizeof(d2));
315  secp256k1_multiset_add (ctx, &r3, d3, sizeof(d3));
316 
321 
322  secp256k1_multiset_combine(ctx, &r1, &r2);
323  secp256k1_multiset_finalize(ctx, m1m2, &r1);
324 
325  secp256k1_multiset_combine(ctx, &r1, &r3);
326  secp256k1_multiset_finalize(ctx, m1m2m3, &r1);
327 
328  CHECK(memcmp(m0,exp_empty,32)==0);
329  CHECK(memcmp(m1,exp_m1,32)==0);
330  CHECK(memcmp(m2,exp_m2,32)==0);
331  CHECK(memcmp(m3,exp_m3,32)==0);
332  CHECK(memcmp(m1m2,exp_m1m2,32)==0);
333  CHECK(memcmp(m1m2m3,exp_m1m2m3,32)==0);
334 }
335 
336 void run_multiset_tests(void) {
337 
338  initdata();
339  test_unordered();
340  test_combine();
341  test_remove();
342  test_empty();
343  test_duplicate();
344  test_testvector();
345 }
346 
347 #endif /* SECP256K1_MODULE_MULTISET_TESTS_H */
secp256k1_context * ctx
static void secp256k1_fe_normalize(secp256k1_fe *r)
Field element module.
static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a)
Set r equal to the inverse of a (i.e., mirrored around the X axis)
static void gej_from_multiset_var(secp256k1_gej *target, const secp256k1_multiset *input)
Converts a multiset to group element (Jacobian) Infinite uses special value, z = 0.
Definition: main_impl.h:34
static void multiset_from_gej_var(secp256k1_multiset *target, const secp256k1_gej *input)
Converts a group element (Jacobian) to a multiset.
Definition: main_impl.h:21
#define DATACOUNT
Definition: tests_impl.h:17
void run_multiset_tests(void)
Definition: tests_impl.h:336
void test_empty(void)
Definition: tests_impl.h:259
static void initdata(void)
Definition: tests_impl.h:39
#define CHECK_NOTEQUAL(a, b)
Definition: tests_impl.h:28
void test_duplicate(void)
Definition: tests_impl.h:226
void test_combine(void)
Definition: tests_impl.h:100
void test_remove(void)
Definition: tests_impl.h:170
#define DATALEN
Definition: tests_impl.h:16
void test_testvector(void)
Definition: tests_impl.h:276
void test_unordered(void)
Definition: tests_impl.h:50
static unsigned char elements[DATACOUNT][DATALEN]
Definition: tests_impl.h:36
#define CHECK_EQUAL(a, b)
Definition: tests_impl.h:20
#define CHECK(cond)
Definition: util.h:53
SECP256K1_API int secp256k1_multiset_init(const secp256k1_context *ctx, secp256k1_multiset *multiset) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Initialize a multiset The resulting multiset the multiset for no data elements.
Definition: main_impl.h:200
SECP256K1_API int secp256k1_multiset_finalize(const secp256k1_context *ctx, unsigned char *resultHash, const secp256k1_multiset *multiset) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Converts a multiset to a hash.
Definition: main_impl.h:165
SECP256K1_API int secp256k1_multiset_add(const secp256k1_context *ctx, secp256k1_multiset *multiset, const unsigned char *input, size_t inputLen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Adds an element to a multiset from single data element.
Definition: main_impl.h:127
SECP256K1_API int secp256k1_multiset_remove(const secp256k1_context *ctx, secp256k1_multiset *multiset, const unsigned char *input, size_t inputLen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Removes an element from a multiset.
Definition: main_impl.h:132
SECP256K1_API int secp256k1_multiset_combine(const secp256k1_context *ctx, secp256k1_multiset *multiset, const secp256k1_multiset *input) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Combines two multisets.
Definition: main_impl.h:137
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:23
secp256k1_fe y
Definition: group.h:25
secp256k1_fe x
Definition: group.h:24
secp256k1_fe z
Definition: group.h:26
Opaque multiset; this is actually a group element.
static uint32_t secp256k1_testrand32(void)
Generate a pseudorandom number in the range [0..2**32-1].