Bitcoin ABC 0.30.5
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
36static unsigned char elements[DATACOUNT][DATALEN];
37
38/* Create random data */
39static 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
50void 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
100void 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
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
134 CHECK_EQUAL(&r1,&r2); /* M(0,1,2) == M(2)+M(0,1) */
135
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) */
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 */
166 CHECK_EQUAL(&empty, &r1); /* M() == M(X)+M(-X) == M(X)-M(X) */
167}
168
169
170void test_remove(void) {
171
172 /* Testing removal of elements */
173 secp256k1_multiset empty, r1,r2,r3;
174
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
226void test_duplicate(void) {
227
228 /* Test if the multiset properly handles duplicates */
229 secp256k1_multiset empty, r1,r2,r3;
230
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
256 CHECK_EQUAL(&r1, &r2); /* M(0,0,0,1,1,1)!=M(0,0,1,1)+M(0,1) */
257}
258
259void test_empty(void) {
260
261 /* Test if empty set properties hold */
262
263 secp256k1_multiset empty, r1,r2;
264
268
269 CHECK_EQUAL(&empty,&r1); /* M()==M() */
270
271 /* empty + empty = empty */
273 CHECK_EQUAL(&empty, &r1); /* M()+M()==M() */
274}
275
276void 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
324
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
337
338 initdata();
340 test_combine();
341 test_remove();
342 test_empty();
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].