2 #define BOOST_TEST_MODULE utilTest
3 #include <boost/test/included/unit_test.hpp>
5 #include "libzerocash/utils/util.h"
6 #include "libzerocash/utils/sha256.h"
8 #define SHA256_PREIMAGE_BYTES 3
9 const unsigned char sha256_preimage[SHA256_PREIMAGE_BYTES] = { 'a', 'b', 'c' };
10 /* This is the SHA256 hash of "abc" according to the modified implementation of
11 * SHA256 included in libzerocash. */
12 const unsigned char sha256_hash[32] = { 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae,
13 0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f,
14 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b,
15 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab,
16 0x5b, 0xe0, 0xcd, 0x19 };
18 BOOST_AUTO_TEST_CASE( testGetRandBytes ) {
19 unsigned char bytes1[32];
20 unsigned char bytes2[32];
22 memset(bytes1, 0, 32);
23 memset(bytes2, 0, 32);
25 libzerocash::getRandBytes(bytes1, 32);
26 libzerocash::getRandBytes(bytes2, 32);
28 BOOST_CHECK( memcmp(bytes1, bytes2, 32) != 0 );
29 BOOST_CHECK( memcmp(bytes1, bytes1+16, 16) != 0 );
32 BOOST_AUTO_TEST_CASE( testConvertVectorToInt ) {
33 BOOST_CHECK(libzerocash::convertVectorToInt({0}) == 0);
34 BOOST_CHECK(libzerocash::convertVectorToInt({1}) == 1);
35 BOOST_CHECK(libzerocash::convertVectorToInt({0,1}) == 1);
36 BOOST_CHECK(libzerocash::convertVectorToInt({1,0}) == 2);
37 BOOST_CHECK(libzerocash::convertVectorToInt({1,1}) == 3);
38 BOOST_CHECK(libzerocash::convertVectorToInt({1,0,0}) == 4);
39 BOOST_CHECK(libzerocash::convertVectorToInt({1,0,1}) == 5);
40 BOOST_CHECK(libzerocash::convertVectorToInt({1,1,0}) == 6);
42 BOOST_CHECK_THROW(libzerocash::convertVectorToInt(std::vector<bool>(100)), std::length_error);
45 std::vector<bool> v(63, 1);
46 BOOST_CHECK(libzerocash::convertVectorToInt(v) == 0x7fffffffffffffff);
50 std::vector<bool> v(64, 1);
51 BOOST_CHECK(libzerocash::convertVectorToInt(v) == 0xffffffffffffffff);
55 BOOST_AUTO_TEST_CASE( testConvertBytesToVector ) {
56 unsigned char bytes[5] = {0x00, 0x01, 0x03, 0x12, 0xFF};
57 std::vector<bool> v1(5*8);
58 libzerocash::convertBytesToVector(bytes, v1);
60 std::vector<bool> v2 = {
62 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 1,
66 0, 0, 0, 0, 0, 0, 1, 1,
68 0, 0, 0, 1, 0, 0, 1, 0,
70 1, 1, 1, 1, 1, 1, 1, 1
73 BOOST_CHECK(v1 == v2);
75 std::vector<bool> unevensize(4);
76 unsigned char abyte[1] = { 0x55 };
77 libzerocash::convertBytesToVector(abyte, unevensize);
79 /* This may not be what we would expect, but this test will alert us if the
80 * behavior changes. */
82 BOOST_CHECK(unevensize == v2);
85 BOOST_AUTO_TEST_CASE( testConvertVectorToBytes) {
86 unsigned char bytes[5] = {0x00, 0x01, 0x03, 0x12, 0xFF};
87 std::vector<bool> v = {
89 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 1,
93 0, 0, 0, 0, 0, 0, 1, 1,
95 0, 0, 0, 1, 0, 0, 1, 0,
97 1, 1, 1, 1, 1, 1, 1, 1
99 unsigned char output[5];
100 libzerocash::convertVectorToBytes(v, output);
101 BOOST_CHECK( memcmp(bytes, output, sizeof(bytes)) == 0 );
103 /* This is not necessarily the behavior one would expect, but this test will
104 * notify us if it changes. */
105 unsigned char onebyte[1];
106 std::vector<bool> unevensize { 1, 1, 1, 1, 1, 1, 1 };
107 libzerocash::convertVectorToBytes(unevensize, onebyte);
108 BOOST_CHECK(onebyte[0] == 0);
111 BOOST_AUTO_TEST_CASE( testConvertBytesToBytesVector ) {
112 unsigned char bytes[16];
113 for (int i = 0; i < 16; i++) {
116 std::vector<unsigned char> v(16);
117 libzerocash::convertBytesToBytesVector(bytes, v);
118 for (int i = 0; i < 16; i++) {
119 BOOST_CHECK(v.at(i) == bytes[i]);
123 BOOST_AUTO_TEST_CASE( testConvertBytesVectorToBytes ) {
124 std::vector<unsigned char>v(16);
125 for (int i = 0; i < 16; i++) {
128 unsigned char bytes[16];
129 memset(bytes, 0, 16);
130 libzerocash::convertBytesVectorToBytes(v, bytes);
131 for (int i = 0; i < 16; i++) {
132 BOOST_CHECK(bytes[i] == v.at(i));
136 BOOST_AUTO_TEST_CASE( testConvertBytesVectorToVector ) {
137 std::vector<unsigned char> bytes = {0x00, 0x01, 0x03, 0x12, 0xFF};
138 std::vector<bool> expected_bits = {
140 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 1,
144 0, 0, 0, 0, 0, 0, 1, 1,
146 0, 0, 0, 1, 0, 0, 1, 0,
148 1, 1, 1, 1, 1, 1, 1, 1
150 std::vector<bool> actual_bits;
151 libzerocash::convertBytesVectorToVector(bytes, actual_bits);
152 BOOST_CHECK(actual_bits == expected_bits);
155 BOOST_AUTO_TEST_CASE( testConvertVectorToBytesVector ) {
156 std::vector<unsigned char> expected_bytes = {0x00, 0x01, 0x03, 0x12, 0xFF};
157 std::vector<bool> bits = {
159 0, 0, 0, 0, 0, 0, 0, 0,
161 0, 0, 0, 0, 0, 0, 0, 1,
163 0, 0, 0, 0, 0, 0, 1, 1,
165 0, 0, 0, 1, 0, 0, 1, 0,
167 1, 1, 1, 1, 1, 1, 1, 1
169 // TODO: evaluate whether initializing with 5 should be necessary.
170 std::vector<unsigned char> actual_bytes(5);
171 libzerocash::convertVectorToBytesVector(bits, actual_bytes);
172 BOOST_CHECK(actual_bytes == expected_bytes);
175 BOOST_AUTO_TEST_CASE( testConvertIntToBytesVector ) {
177 std::vector<unsigned char> expected;
178 std::vector<unsigned char> bytes(8);
181 expected = { 0, 0, 0, 0, 0, 0, 0, 0 };
182 libzerocash::convertIntToBytesVector(val, bytes);
183 BOOST_CHECK( expected == bytes );
186 expected = { 0, 0, 0, 0, 0, 0, 0, 1 };
187 libzerocash::convertIntToBytesVector(val, bytes);
188 BOOST_CHECK( expected == bytes );
190 val = 0xffffffffffffffffULL;
191 expected = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
192 libzerocash::convertIntToBytesVector(val, bytes);
193 BOOST_CHECK( expected == bytes );
195 val = 0x8000000080000001ULL; // sign extension
196 expected = { 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01 };
197 libzerocash::convertIntToBytesVector(val, bytes);
198 BOOST_CHECK( expected == bytes );
200 // The following two tests aren't necessarily desired results. They merely
201 // document the behavior so that we'll be alerted if it changes in the
204 val = 0xffffffffdeadbeefULL; // truncation
205 expected = { 0xde, 0xad, 0xbe, 0xef };
206 std::vector<unsigned char> small_bytes(4);
207 libzerocash::convertIntToBytesVector(val, small_bytes);
208 BOOST_CHECK( expected == small_bytes );
210 val = 0xf1f2f3f401020304ULL; // bytes buffer is too big
211 // The first byte is 4 because `>> 64` is undefined, and that's the result
212 // it has on my system (note that it's the same as the original LSB).
213 expected = { 0x04, 0xf1, 0xf2, 0xf3, 0xf4, 0x01, 0x02, 0x03, 0x04 };
214 std::vector<unsigned char> big_bytes(9);
215 libzerocash::convertIntToBytesVector(val, big_bytes);
216 BOOST_CHECK( expected == big_bytes);
219 BOOST_AUTO_TEST_CASE( testConvertBytesVectorToInt ) {
222 std::vector<unsigned char> bytes;
224 bytes = { 0, 0, 0, 0, 0, 0, 0, 0 };
226 val = libzerocash::convertBytesVectorToInt(bytes);
227 BOOST_CHECK( expected == val );
229 bytes = { 0, 0, 0, 0, 0, 0, 0, 1 };
231 val = libzerocash::convertBytesVectorToInt(bytes);
232 BOOST_CHECK( expected == val );
234 bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
235 expected = 0xffffffffffffffffULL;
236 val = libzerocash::convertBytesVectorToInt(bytes);
237 BOOST_CHECK( expected == val );
239 bytes = { 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01 };
240 expected = 0x8000000080000001ULL;
241 val = libzerocash::convertBytesVectorToInt(bytes);
242 BOOST_CHECK( expected == val );
244 bytes = { 0xde, 0xad, 0xbe, 0xef }; // opposite of truncation
245 expected = 0xdeadbeefULL;
246 val = libzerocash::convertBytesVectorToInt(bytes);
247 BOOST_CHECK( expected == val );
250 BOOST_AUTO_TEST_CASE( testConvertIntToVector ) {
252 std::vector<bool> expected;
253 std::vector<bool> vector;
256 expected = { 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0,
259 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0,
263 0, 0, 0, 0, 0, 0, 0, 0 };
264 libzerocash::convertIntToVector(val, vector);
265 BOOST_CHECK( expected == vector );
268 expected = { 0, 0, 0, 0, 0, 0, 0, 0,
269 0, 0, 0, 0, 0, 0, 0, 0,
270 0, 0, 0, 0, 0, 0, 0, 0,
271 0, 0, 0, 0, 0, 0, 0, 0,
272 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 0, 0,
275 0, 0, 0, 0, 0, 0, 0, 1 };
276 libzerocash::convertIntToVector(val, vector);
277 BOOST_CHECK( expected == vector );
279 val = 0xffffffffffffffffULL;
280 expected = { 1, 1, 1, 1, 1, 1, 1, 1,
281 1, 1, 1, 1, 1, 1, 1, 1,
282 1, 1, 1, 1, 1, 1, 1, 1,
283 1, 1, 1, 1, 1, 1, 1, 1,
284 1, 1, 1, 1, 1, 1, 1, 1,
285 1, 1, 1, 1, 1, 1, 1, 1,
286 1, 1, 1, 1, 1, 1, 1, 1,
287 1, 1, 1, 1, 1, 1, 1, 1 };
288 libzerocash::convertIntToVector(val, vector);
289 BOOST_CHECK( expected == vector );
291 val = 0x8000000080000001ULL; // sign extension
292 expected = { 1, 0, 0, 0, 0, 0, 0, 0,
293 0, 0, 0, 0, 0, 0, 0, 0,
294 0, 0, 0, 0, 0, 0, 0, 0,
295 0, 0, 0, 0, 0, 0, 0, 0,
296 1, 0, 0, 0, 0, 0, 0, 0,
297 0, 0, 0, 0, 0, 0, 0, 0,
298 0, 0, 0, 0, 0, 0, 0, 0,
299 0, 0, 0, 0, 0, 0, 0, 1 };
300 libzerocash::convertIntToVector(val, vector);
301 BOOST_CHECK( expected == vector );
303 std::vector<bool> too_big(100);
304 libzerocash::convertIntToVector(0, too_big);
305 BOOST_CHECK(too_big.size() == 64);
307 std::vector<bool> too_small(10);
308 libzerocash::convertIntToVector(0, too_small);
309 BOOST_CHECK(too_big.size() == 64);
312 BOOST_AUTO_TEST_CASE( testConcatenateTwoBoolVectors ) {
313 std::vector<bool> front = { 0, 1, 0 };
314 std::vector<bool> back = { 1, 0, 1 };
315 std::vector<bool> expected = { 0, 1, 0, 1, 0, 1 };
316 std::vector<bool> actual;
317 libzerocash::concatenateVectors(front, back, actual);
318 BOOST_CHECK( expected == actual );
321 BOOST_AUTO_TEST_CASE( testConcatenateTwoByteVectors ) {
322 std::vector<unsigned char> front = { 0, 1, 2 };
323 std::vector<unsigned char> back = { 3, 4, 5 };
324 std::vector<unsigned char> expected = { 0, 1, 2, 3, 4, 5 };
325 std::vector<unsigned char> actual;
326 libzerocash::concatenateVectors(front, back, actual);
327 BOOST_CHECK( expected == actual );
330 BOOST_AUTO_TEST_CASE( testConcatenateThreeBoolVectors ) {
331 std::vector<bool> front = { 0, 1, 0 };
332 std::vector<bool> middle { 1, 1, 1 };
333 std::vector<bool> back = { 1, 0, 1 };
334 std::vector<bool> expected = { 0, 1, 0, 1, 1, 1, 1, 0, 1 };
335 std::vector<bool> actual;
336 libzerocash::concatenateVectors(front, middle, back, actual);
337 BOOST_CHECK( expected == actual );
340 BOOST_AUTO_TEST_CASE( testConcatenateThreeByteVectors ) {
341 std::vector<unsigned char> front = { 0, 1, 0 };
342 std::vector<unsigned char> middle { 1, 1, 1 };
343 std::vector<unsigned char> back = { 1, 0, 1 };
344 std::vector<unsigned char> expected = { 0, 1, 0, 1, 1, 1, 1, 0, 1 };
345 std::vector<unsigned char> actual;
346 libzerocash::concatenateVectors(front, middle, back, actual);
347 BOOST_CHECK( expected == actual );
350 BOOST_AUTO_TEST_CASE( testSHA256ModifiedTestVectors ) {
351 unsigned char actual_hash[32];
352 libzerocash::sha256(sha256_preimage, actual_hash, 3);
353 BOOST_CHECK( memcmp(sha256_hash, actual_hash, 32) == 0 );
356 BOOST_AUTO_TEST_CASE( testSHA256ModifiedTestVectorsCTX ) {
357 unsigned char actual_hash[32];
358 SHA256_CTX_mod ctx256;
359 libzerocash::sha256(&ctx256, sha256_preimage, actual_hash, 3);
360 BOOST_CHECK( memcmp(sha256_hash, actual_hash, 32) == 0 );
363 BOOST_AUTO_TEST_CASE( testSHA256TestVectors ) {
364 /* Tests an actual SHA256 test vector (with length padding) to make sure
365 * libzerocash's implementation is actually the same as SHA256 with the
366 * length padding removed. */
367 unsigned char preimage[3] = { 'a', 'b', 'c' };
368 unsigned char expected_hash[32] = { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01,
369 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
370 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03,
371 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
372 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00,
374 unsigned char actual_hash[32];
375 SHA256_CTX_mod ctx256;
376 sha256_init(&ctx256);
377 sha256_update(&ctx256, preimage, 3);
378 sha256_length_padding(&ctx256);
379 sha256_final_no_padding(&ctx256, actual_hash);
381 BOOST_CHECK( memcmp(expected_hash, actual_hash, 32) == 0 );
384 BOOST_AUTO_TEST_CASE( testHashBoolVectorToBoolVectorCTX ) {
385 SHA256_CTX_mod ctx256;
387 std::vector<bool> preimage(SHA256_PREIMAGE_BYTES * 8);
388 libzerocash::convertBytesToVector(sha256_preimage, preimage);
390 std::vector<bool> expected(32*8);
391 libzerocash::convertBytesToVector(sha256_hash, expected);
393 // TODO: evaluate whether this should be a necessary precondition.
394 std::vector<bool> actual(32*8);
395 libzerocash::hashVector(&ctx256, preimage, actual);
397 BOOST_CHECK( expected == actual );
400 BOOST_AUTO_TEST_CASE( testHashByteVectorToByteVectorCTX ) {
401 SHA256_CTX_mod ctx256;
403 std::vector<unsigned char> preimage(SHA256_PREIMAGE_BYTES);
404 libzerocash::convertBytesToBytesVector(sha256_preimage, preimage);
406 std::vector<unsigned char> expected(32);
407 libzerocash::convertBytesToBytesVector(sha256_hash, expected);
409 // TODO: evaluate whether this should be a necessary precondition.
410 std::vector<unsigned char> actual(32);
411 libzerocash::hashVector(&ctx256, preimage, actual);
413 BOOST_CHECK( expected == actual );
417 BOOST_AUTO_TEST_CASE( testHashBoolVectorToBoolVector ) {
418 std::vector<bool> preimage(SHA256_PREIMAGE_BYTES * 8);
419 libzerocash::convertBytesToVector(sha256_preimage, preimage);
421 std::vector<bool> expected(32*8);
422 libzerocash::convertBytesToVector(sha256_hash, expected);
424 // TODO: evaluate whether this should be a necessary precondition.
425 std::vector<bool> actual(32*8);
426 libzerocash::hashVector(preimage, actual);
428 BOOST_CHECK( expected == actual );
431 BOOST_AUTO_TEST_CASE( testHashByteVectorToByteVector ) {
432 std::vector<unsigned char> preimage(SHA256_PREIMAGE_BYTES);
433 libzerocash::convertBytesToBytesVector(sha256_preimage, preimage);
435 std::vector<unsigned char> expected(32);
436 libzerocash::convertBytesToBytesVector(sha256_hash, expected);
438 // TODO: evaluate whether this should be a necessary precondition.
439 std::vector<unsigned char> actual(32);
440 libzerocash::hashVector(preimage, actual);
442 BOOST_CHECK( expected == actual );
445 BOOST_AUTO_TEST_CASE( testHashBoolVectorsCTX ) {
446 SHA256_CTX_mod ctx256;
448 std::vector<bool> preimage1(8);
449 libzerocash::convertBytesToVector(sha256_preimage, preimage1);
451 std::vector<bool> preimage2((SHA256_PREIMAGE_BYTES - 1) * 8);
452 libzerocash::convertBytesToVector(sha256_preimage + 1, preimage2);
454 std::vector<bool> expected(32*8);
455 libzerocash::convertBytesToVector(sha256_hash, expected);
457 // TODO: evaluate whether this should be a necessary precondition.
458 std::vector<bool> actual(32 * 8);
459 libzerocash::hashVectors(&ctx256, preimage1, preimage2, actual);
461 BOOST_CHECK( expected == actual );
464 BOOST_AUTO_TEST_CASE( testHashByteVectorsCTX ) {
465 SHA256_CTX_mod ctx256;
467 std::vector<unsigned char> preimage1(1);
468 libzerocash::convertBytesToBytesVector(sha256_preimage, preimage1);
470 std::vector<unsigned char> preimage2(SHA256_PREIMAGE_BYTES - 1);
471 libzerocash::convertBytesToBytesVector(sha256_preimage + 1, preimage2);
473 std::vector<unsigned char> expected(32);
474 libzerocash::convertBytesToBytesVector(sha256_hash, expected);
476 // TODO: evaluate whether this should be a necessary precondition.
477 std::vector<unsigned char> actual(32);
478 libzerocash::hashVectors(&ctx256, preimage1, preimage2, actual);
480 BOOST_CHECK( expected == actual );
484 BOOST_AUTO_TEST_CASE( testHashBoolVectors ) {
485 std::vector<bool> preimage1(8);
486 libzerocash::convertBytesToVector(sha256_preimage, preimage1);
488 std::vector<bool> preimage2((SHA256_PREIMAGE_BYTES - 1) * 8);
489 libzerocash::convertBytesToVector(sha256_preimage + 1, preimage2);
491 std::vector<bool> expected(32*8);
492 libzerocash::convertBytesToVector(sha256_hash, expected);
494 // TODO: evaluate whether this should be a necessary precondition.
495 std::vector<bool> actual(32 * 8);
496 libzerocash::hashVectors(preimage1, preimage2, actual);
498 BOOST_CHECK( expected == actual );
501 BOOST_AUTO_TEST_CASE( testHashByteVectors ) {
502 std::vector<unsigned char> preimage1(1);
503 libzerocash::convertBytesToBytesVector(sha256_preimage, preimage1);
505 std::vector<unsigned char> preimage2(SHA256_PREIMAGE_BYTES - 1);
506 libzerocash::convertBytesToBytesVector(sha256_preimage + 1, preimage2);
508 std::vector<unsigned char> expected(32);
509 libzerocash::convertBytesToBytesVector(sha256_hash, expected);
511 // TODO: evaluate whether this should be a necessary precondition.
512 std::vector<unsigned char> actual(32);
513 libzerocash::hashVectors(preimage1, preimage2, actual);
515 BOOST_CHECK( expected == actual );
518 BOOST_AUTO_TEST_CASE( testVectorIsZero ) {
519 std::vector<bool> bits;
520 BOOST_CHECK( libzerocash::VectorIsZero(bits) );
523 BOOST_CHECK( libzerocash::VectorIsZero(bits) );
526 BOOST_CHECK( libzerocash::VectorIsZero(bits) );
529 BOOST_CHECK( !libzerocash::VectorIsZero(bits) );
532 BOOST_CHECK( !libzerocash::VectorIsZero(bits) );