diff --git a/include/minisketch.h b/include/minisketch.h index f222f23..4f2dc99 100644 --- a/include/minisketch.h +++ b/include/minisketch.h @@ -60,16 +60,19 @@ MINISKETCH_API uint32_t minisketch_implementation_max(void); */ MINISKETCH_API int minisketch_implementation_supported(uint32_t bits, uint32_t implementation); -/** Construct a sketch for a given element size, implementation and capacity. +/** Construct a sketch for a given element size, implementation, capacity, and RNG seed. * * If the combination of `bits` and `implementation` is unavailable, or when * OOM occurs, NULL is returned. If minisketch_implementation_supported * returns 1 for the specified bits and implementation, this will always succeed * (except when allocation fails). * + * To protect against bad performance on maliciously-created sketches, it is + * to use strong randomness for the provided seed value. + * * If the result is not NULL, it must be destroyed using minisketch_destroy. */ -MINISKETCH_API minisketch* minisketch_create(uint32_t bits, uint32_t implementation, size_t capacity); +MINISKETCH_API minisketch* minisketch_create(uint32_t bits, uint32_t implementation, size_t capacity, uint64_t seed); /** Get the element size of a sketch in bits. */ MINISKETCH_API uint32_t minisketch_bits(const minisketch* sketch); @@ -82,14 +85,11 @@ MINISKETCH_API uint32_t minisketch_implementation(const minisketch* sketch); /** Set the seed for randomizing algorithm choices to a fixed value. * - * By default, sketches are initialized with a random seed. This is important - * to avoid scenarios where an attacker could force worst-case behavior. - * - * This function initializes the seed to a user-provided value (any 64-bit - * integer is acceptable, regardless of field size). + * This is equivalent to recreating the sketch with a different RNG seed. * * When seed is -1, a fixed internal value with predictable behavior is - * used. It is only intended for testing. + * used. It is only intended for testing. Note that minisketch_create does + * assign special meaning to seed = -1. */ MINISKETCH_API void minisketch_set_seed(minisketch* sketch, uint64_t seed); @@ -263,16 +263,16 @@ class Minisketch * ImplementationSupported(), or OOM occurs internally, an invalid Minisketch * object will be constructed. Use operator bool() to check that this isn't the * case before performing any other operations. */ - Minisketch(uint32_t bits, uint32_t implementation, size_t capacity) noexcept + Minisketch(uint32_t bits, uint32_t implementation, size_t capacity, uint64_t seed) noexcept { - m_minisketch = std::unique_ptr(minisketch_create(bits, implementation, capacity)); + m_minisketch = std::unique_ptr(minisketch_create(bits, implementation, capacity, seed)); } /** Create a Minisketch object sufficiently large for the specified number of elements at given fpbits. * It may construct an invalid object, which you may need to check for. */ - static Minisketch CreateFP(uint32_t bits, uint32_t implementation, size_t max_elements, uint32_t fpbits) noexcept + static Minisketch CreateFP(uint32_t bits, uint32_t implementation, size_t max_elements, uint32_t fpbits, uint64_t seed) noexcept { - return Minisketch(bits, implementation, ComputeCapacity(bits, max_elements, fpbits)); + return Minisketch(bits, implementation, ComputeCapacity(bits, max_elements, fpbits), seed); } /** Return the field size for a (valid) Minisketch object. */ diff --git a/src/bench.cpp b/src/bench.cpp index dc44379..541e801 100644 --- a/src/bench.cpp +++ b/src/bench.cpp @@ -18,6 +18,8 @@ int main(int argc, char** argv) { printf("Usage: %s [syndromes=150] [errors=syndromes] [iters=10]\n", argv[0]); return 1; } + std::random_device rng; + std::uniform_int_distribution dist; int syndromes = argc > 1 ? strtoul(argv[1], NULL, 10) : 150; int errors = argc > 2 ? strtoul(argv[2], NULL, 10) : syndromes; int iters = argc > 3 ? strtoul(argv[3], NULL, 10) : 10; @@ -47,7 +49,7 @@ int main(int argc, char** argv) { std::vector benches; benches.reserve(iters); for (int i = 0; i < iters; ++i) { - states[i] = minisketch_create(bits, impl, syndromes); + states[i] = minisketch_create(bits, impl, syndromes, dist(rng)); if (!states[i]) break; std::set done; for (int j = 0; j < errors; ++j) { @@ -80,15 +82,13 @@ int main(int argc, char** argv) { printf("create[ns]\t% 3i\t", bits); for (uint32_t impl = 0; impl <= max_impl; ++impl) { std::vector states; - std::random_device rng; - std::uniform_int_distribution dist; std::vector data; data.resize(errors * 10); states.resize(iters); std::vector benches; benches.reserve(iters); for (int i = 0; i < iters; ++i) { - states[i] = minisketch_create(bits, impl, syndromes); + states[i] = minisketch_create(bits, impl, syndromes, dist(rng)); } for (size_t i = 0; i < data.size(); ++i) { data[i] = dist(rng); diff --git a/src/fields/clmul_1byte.cpp b/src/fields/clmul_1byte.cpp index 8826af9..435d361 100644 --- a/src/fields/clmul_1byte.cpp +++ b/src/fields/clmul_1byte.cpp @@ -82,37 +82,37 @@ typedef Field(implementation, 5); + case 5: return new SketchImpl(implementation, 5, seed); #endif #ifdef ENABLE_FIELD_INT_8 - case 8: return new SketchImpl(implementation, 8); + case 8: return new SketchImpl(implementation, 8, seed); #endif } return nullptr; } -Sketch* ConstructClMulTri1Byte(int bits, int implementation) { +Sketch* ConstructClMulTri1Byte(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_2 - case 2: return new SketchImpl(implementation, 2); + case 2: return new SketchImpl(implementation, 2, seed); #endif #ifdef ENABLE_FIELD_INT_3 - case 3: return new SketchImpl(implementation, 3); + case 3: return new SketchImpl(implementation, 3, seed); #endif #ifdef ENABLE_FIELD_INT_4 - case 4: return new SketchImpl(implementation, 4); + case 4: return new SketchImpl(implementation, 4, seed); #endif #ifdef ENABLE_FIELD_INT_5 - case 5: return new SketchImpl(implementation, 5); + case 5: return new SketchImpl(implementation, 5, seed); #endif #ifdef ENABLE_FIELD_INT_6 - case 6: return new SketchImpl(implementation, 6); + case 6: return new SketchImpl(implementation, 6, seed); #endif #ifdef ENABLE_FIELD_INT_7 - case 7: return new SketchImpl(implementation, 7); + case 7: return new SketchImpl(implementation, 7, seed); #endif } return nullptr; diff --git a/src/fields/clmul_2bytes.cpp b/src/fields/clmul_2bytes.cpp index 4393025..c26bfd3 100644 --- a/src/fields/clmul_2bytes.cpp +++ b/src/fields/clmul_2bytes.cpp @@ -105,49 +105,49 @@ typedef Field(implementation, 10); + case 10: return new SketchImpl(implementation, 10, seed); #endif #ifdef ENABLE_FIELD_INT_11 - case 11: return new SketchImpl(implementation, 11); + case 11: return new SketchImpl(implementation, 11, seed); #endif #ifdef ENABLE_FIELD_INT_12 - case 12: return new SketchImpl(implementation, 12); + case 12: return new SketchImpl(implementation, 12, seed); #endif #ifdef ENABLE_FIELD_INT_13 - case 13: return new SketchImpl(implementation, 13); + case 13: return new SketchImpl(implementation, 13, seed); #endif #ifdef ENABLE_FIELD_INT_14 - case 14: return new SketchImpl(implementation, 14); + case 14: return new SketchImpl(implementation, 14, seed); #endif #ifdef ENABLE_FIELD_INT_16 - case 16: return new SketchImpl(implementation, 16); + case 16: return new SketchImpl(implementation, 16, seed); #endif } return nullptr; } -Sketch* ConstructClMulTri2Bytes(int bits, int implementation) { +Sketch* ConstructClMulTri2Bytes(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_9 - case 9: return new SketchImpl(implementation, 9); + case 9: return new SketchImpl(implementation, 9, seed); #endif #ifdef ENABLE_FIELD_INT_10 - case 10: return new SketchImpl(implementation, 10); + case 10: return new SketchImpl(implementation, 10, seed); #endif #ifdef ENABLE_FIELD_INT_11 - case 11: return new SketchImpl(implementation, 11); + case 11: return new SketchImpl(implementation, 11, seed); #endif #ifdef ENABLE_FIELD_INT_12 - case 12: return new SketchImpl(implementation, 12); + case 12: return new SketchImpl(implementation, 12, seed); #endif #ifdef ENABLE_FIELD_INT_14 - case 14: return new SketchImpl(implementation, 14); + case 14: return new SketchImpl(implementation, 14, seed); #endif #ifdef ENABLE_FIELD_INT_15 - case 15: return new SketchImpl(implementation, 15); + case 15: return new SketchImpl(implementation, 15, seed); #endif } return nullptr; diff --git a/src/fields/clmul_3bytes.cpp b/src/fields/clmul_3bytes.cpp index b473f66..e9ce4d5 100644 --- a/src/fields/clmul_3bytes.cpp +++ b/src/fields/clmul_3bytes.cpp @@ -114,52 +114,52 @@ typedef Field(implementation, 17); + case 17: return new SketchImpl(implementation, 17, seed); #endif #ifdef ENABLE_FIELD_INT_18 - case 18: return new SketchImpl(implementation, 18); + case 18: return new SketchImpl(implementation, 18, seed); #endif #ifdef ENABLE_FIELD_INT_19 - case 19: return new SketchImpl(implementation, 19); + case 19: return new SketchImpl(implementation, 19, seed); #endif #ifdef ENABLE_FIELD_INT_20 - case 20: return new SketchImpl(implementation, 20); + case 20: return new SketchImpl(implementation, 20, seed); #endif #ifdef ENABLE_FIELD_INT_21 - case 21: return new SketchImpl(implementation, 21); + case 21: return new SketchImpl(implementation, 21, seed); #endif #ifdef ENABLE_FIELD_INT_23 - case 23: return new SketchImpl(implementation, 23); + case 23: return new SketchImpl(implementation, 23, seed); #endif #ifdef ENABLE_FIELD_INT_24 - case 24: return new SketchImpl(implementation, 24); + case 24: return new SketchImpl(implementation, 24, seed); #endif } return nullptr; } -Sketch* ConstructClMulTri3Bytes(int bits, int implementation) { +Sketch* ConstructClMulTri3Bytes(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_17 - case 17: return new SketchImpl(implementation, 17); + case 17: return new SketchImpl(implementation, 17, seed); #endif #ifdef ENABLE_FIELD_INT_18 - case 18: return new SketchImpl(implementation, 18); + case 18: return new SketchImpl(implementation, 18, seed); #endif #ifdef ENABLE_FIELD_INT_20 - case 20: return new SketchImpl(implementation, 20); + case 20: return new SketchImpl(implementation, 20, seed); #endif #ifdef ENABLE_FIELD_INT_21 - case 21: return new SketchImpl(implementation, 21); + case 21: return new SketchImpl(implementation, 21, seed); #endif #ifdef ENABLE_FIELD_INT_22 - case 22: return new SketchImpl(implementation, 22); + case 22: return new SketchImpl(implementation, 22, seed); #endif #ifdef ENABLE_FIELD_INT_23 - case 23: return new SketchImpl(implementation, 23); + case 23: return new SketchImpl(implementation, 23, seed); #endif } return nullptr; diff --git a/src/fields/clmul_4bytes.cpp b/src/fields/clmul_4bytes.cpp index c659743..a01344e 100644 --- a/src/fields/clmul_4bytes.cpp +++ b/src/fields/clmul_4bytes.cpp @@ -112,46 +112,46 @@ typedef Field(implementation, 25); + case 25: return new SketchImpl(implementation, 25, seed); #endif #ifdef ENABLE_FIELD_INT_26 - case 26: return new SketchImpl(implementation, 26); + case 26: return new SketchImpl(implementation, 26, seed); #endif #ifdef ENABLE_FIELD_INT_27 - case 27: return new SketchImpl(implementation, 27); + case 27: return new SketchImpl(implementation, 27, seed); #endif #ifdef ENABLE_FIELD_INT_29 - case 29: return new SketchImpl(implementation, 29); + case 29: return new SketchImpl(implementation, 29, seed); #endif #ifdef ENABLE_FIELD_INT_31 - case 31: return new SketchImpl(implementation, 31); + case 31: return new SketchImpl(implementation, 31, seed); #endif #ifdef ENABLE_FIELD_INT_32 - case 32: return new SketchImpl(implementation, 32); + case 32: return new SketchImpl(implementation, 32, seed); #endif } return nullptr; } -Sketch* ConstructClMulTri4Bytes(int bits, int implementation) { +Sketch* ConstructClMulTri4Bytes(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_25 - case 25: return new SketchImpl(implementation, 25); + case 25: return new SketchImpl(implementation, 25, seed); #endif #ifdef ENABLE_FIELD_INT_28 - case 28: return new SketchImpl(implementation, 28); + case 28: return new SketchImpl(implementation, 28, seed); #endif #ifdef ENABLE_FIELD_INT_29 - case 29: return new SketchImpl(implementation, 29); + case 29: return new SketchImpl(implementation, 29, seed); #endif #ifdef ENABLE_FIELD_INT_30 - case 30: return new SketchImpl(implementation, 30); + case 30: return new SketchImpl(implementation, 30, seed); #endif #ifdef ENABLE_FIELD_INT_31 - case 31: return new SketchImpl(implementation, 31); + case 31: return new SketchImpl(implementation, 31, seed); #endif } return nullptr; diff --git a/src/fields/clmul_5bytes.cpp b/src/fields/clmul_5bytes.cpp index 29c3fb1..ad26862 100644 --- a/src/fields/clmul_5bytes.cpp +++ b/src/fields/clmul_5bytes.cpp @@ -122,52 +122,52 @@ typedef Field(implementation, 33); + case 33: return new SketchImpl(implementation, 33, seed); #endif #ifdef ENABLE_FIELD_INT_34 - case 34: return new SketchImpl(implementation, 34); + case 34: return new SketchImpl(implementation, 34, seed); #endif #ifdef ENABLE_FIELD_INT_35 - case 35: return new SketchImpl(implementation, 35); + case 35: return new SketchImpl(implementation, 35, seed); #endif #ifdef ENABLE_FIELD_INT_36 - case 36: return new SketchImpl(implementation, 36); + case 36: return new SketchImpl(implementation, 36, seed); #endif #ifdef ENABLE_FIELD_INT_37 - case 37: return new SketchImpl(implementation, 37); + case 37: return new SketchImpl(implementation, 37, seed); #endif #ifdef ENABLE_FIELD_INT_38 - case 38: return new SketchImpl(implementation, 38); + case 38: return new SketchImpl(implementation, 38, seed); #endif #ifdef ENABLE_FIELD_INT_39 - case 39: return new SketchImpl(implementation, 39); + case 39: return new SketchImpl(implementation, 39, seed); #endif #ifdef ENABLE_FIELD_INT_40 - case 40: return new SketchImpl(implementation, 40); + case 40: return new SketchImpl(implementation, 40, seed); #endif } return nullptr; } -Sketch* ConstructClMulTri5Bytes(int bits, int implementation) { +Sketch* ConstructClMulTri5Bytes(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_33 - case 33: return new SketchImpl(implementation, 33); + case 33: return new SketchImpl(implementation, 33, seed); #endif #ifdef ENABLE_FIELD_INT_34 - case 34: return new SketchImpl(implementation, 34); + case 34: return new SketchImpl(implementation, 34, seed); #endif #ifdef ENABLE_FIELD_INT_35 - case 35: return new SketchImpl(implementation, 35); + case 35: return new SketchImpl(implementation, 35, seed); #endif #ifdef ENABLE_FIELD_INT_36 - case 36: return new SketchImpl(implementation, 36); + case 36: return new SketchImpl(implementation, 36, seed); #endif #ifdef ENABLE_FIELD_INT_39 - case 39: return new SketchImpl(implementation, 39); + case 39: return new SketchImpl(implementation, 39, seed); #endif } return nullptr; diff --git a/src/fields/clmul_6bytes.cpp b/src/fields/clmul_6bytes.cpp index d0e7124..849ac6e 100644 --- a/src/fields/clmul_6bytes.cpp +++ b/src/fields/clmul_6bytes.cpp @@ -121,49 +121,49 @@ typedef Field(implementation, 41); + case 41: return new SketchImpl(implementation, 41, seed); #endif #ifdef ENABLE_FIELD_INT_42 - case 42: return new SketchImpl(implementation, 42); + case 42: return new SketchImpl(implementation, 42, seed); #endif #ifdef ENABLE_FIELD_INT_43 - case 43: return new SketchImpl(implementation, 43); + case 43: return new SketchImpl(implementation, 43, seed); #endif #ifdef ENABLE_FIELD_INT_44 - case 44: return new SketchImpl(implementation, 44); + case 44: return new SketchImpl(implementation, 44, seed); #endif #ifdef ENABLE_FIELD_INT_45 - case 45: return new SketchImpl(implementation, 45); + case 45: return new SketchImpl(implementation, 45, seed); #endif #ifdef ENABLE_FIELD_INT_47 - case 47: return new SketchImpl(implementation, 47); + case 47: return new SketchImpl(implementation, 47, seed); #endif #ifdef ENABLE_FIELD_INT_48 - case 48: return new SketchImpl(implementation, 48); + case 48: return new SketchImpl(implementation, 48, seed); #endif } return nullptr; } -Sketch* ConstructClMulTri6Bytes(int bits, int implementation) { +Sketch* ConstructClMulTri6Bytes(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_41 - case 41: return new SketchImpl(implementation, 41); + case 41: return new SketchImpl(implementation, 41, seed); #endif #ifdef ENABLE_FIELD_INT_42 - case 42: return new SketchImpl(implementation, 42); + case 42: return new SketchImpl(implementation, 42, seed); #endif #ifdef ENABLE_FIELD_INT_44 - case 44: return new SketchImpl(implementation, 44); + case 44: return new SketchImpl(implementation, 44, seed); #endif #ifdef ENABLE_FIELD_INT_46 - case 46: return new SketchImpl(implementation, 46); + case 46: return new SketchImpl(implementation, 46, seed); #endif #ifdef ENABLE_FIELD_INT_47 - case 47: return new SketchImpl(implementation, 47); + case 47: return new SketchImpl(implementation, 47, seed); #endif } return nullptr; diff --git a/src/fields/clmul_7bytes.cpp b/src/fields/clmul_7bytes.cpp index 2050dc3..c9e7081 100644 --- a/src/fields/clmul_7bytes.cpp +++ b/src/fields/clmul_7bytes.cpp @@ -121,49 +121,49 @@ typedef Field(implementation, 49); + case 49: return new SketchImpl(implementation, 49, seed); #endif #ifdef ENABLE_FIELD_INT_50 - case 50: return new SketchImpl(implementation, 50); + case 50: return new SketchImpl(implementation, 50, seed); #endif #ifdef ENABLE_FIELD_INT_51 - case 51: return new SketchImpl(implementation, 51); + case 51: return new SketchImpl(implementation, 51, seed); #endif #ifdef ENABLE_FIELD_INT_52 - case 52: return new SketchImpl(implementation, 52); + case 52: return new SketchImpl(implementation, 52, seed); #endif #ifdef ENABLE_FIELD_INT_53 - case 53: return new SketchImpl(implementation, 53); + case 53: return new SketchImpl(implementation, 53, seed); #endif #ifdef ENABLE_FIELD_INT_54 - case 54: return new SketchImpl(implementation, 54); + case 54: return new SketchImpl(implementation, 54, seed); #endif #ifdef ENABLE_FIELD_INT_55 - case 55: return new SketchImpl(implementation, 55); + case 55: return new SketchImpl(implementation, 55, seed); #endif #ifdef ENABLE_FIELD_INT_56 - case 56: return new SketchImpl(implementation, 56); + case 56: return new SketchImpl(implementation, 56, seed); #endif } return nullptr; } -Sketch* ConstructClMulTri7Bytes(int bits, int implementation) { +Sketch* ConstructClMulTri7Bytes(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_49 - case 49: return new SketchImpl(implementation, 49); + case 49: return new SketchImpl(implementation, 49, seed); #endif #ifdef ENABLE_FIELD_INT_52 - case 52: return new SketchImpl(implementation, 52); + case 52: return new SketchImpl(implementation, 52, seed); #endif #ifdef ENABLE_FIELD_INT_54 - case 54: return new SketchImpl(implementation, 54); + case 54: return new SketchImpl(implementation, 54, seed); #endif #ifdef ENABLE_FIELD_INT_55 - case 55: return new SketchImpl(implementation, 55); + case 55: return new SketchImpl(implementation, 55, seed); #endif } return nullptr; diff --git a/src/fields/clmul_8bytes.cpp b/src/fields/clmul_8bytes.cpp index 8dc1089..e4f9939 100644 --- a/src/fields/clmul_8bytes.cpp +++ b/src/fields/clmul_8bytes.cpp @@ -129,46 +129,46 @@ typedef Field(implementation, 57); + case 57: return new SketchImpl(implementation, 57, seed); #endif #ifdef ENABLE_FIELD_INT_58 - case 58: return new SketchImpl(implementation, 58); + case 58: return new SketchImpl(implementation, 58, seed); #endif #ifdef ENABLE_FIELD_INT_59 - case 59: return new SketchImpl(implementation, 59); + case 59: return new SketchImpl(implementation, 59, seed); #endif #ifdef ENABLE_FIELD_INT_61 - case 61: return new SketchImpl(implementation, 61); + case 61: return new SketchImpl(implementation, 61, seed); #endif #ifdef ENABLE_FIELD_INT_62 - case 62: return new SketchImpl(implementation, 62); + case 62: return new SketchImpl(implementation, 62, seed); #endif #ifdef ENABLE_FIELD_INT_64 - case 64: return new SketchImpl(implementation, 64); + case 64: return new SketchImpl(implementation, 64, seed); #endif } return nullptr; } -Sketch* ConstructClMulTri8Bytes(int bits, int implementation) { +Sketch* ConstructClMulTri8Bytes(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_57 - case 57: return new SketchImpl(implementation, 57); + case 57: return new SketchImpl(implementation, 57, seed); #endif #ifdef ENABLE_FIELD_INT_58 - case 58: return new SketchImpl(implementation, 58); + case 58: return new SketchImpl(implementation, 58, seed); #endif #ifdef ENABLE_FIELD_INT_60 - case 60: return new SketchImpl(implementation, 60); + case 60: return new SketchImpl(implementation, 60, seed); #endif #ifdef ENABLE_FIELD_INT_62 - case 62: return new SketchImpl(implementation, 62); + case 62: return new SketchImpl(implementation, 62, seed); #endif #ifdef ENABLE_FIELD_INT_63 - case 63: return new SketchImpl(implementation, 63); + case 63: return new SketchImpl(implementation, 63, seed); #endif } return nullptr; diff --git a/src/fields/generic_1byte.cpp b/src/fields/generic_1byte.cpp index 5ce42dc..a1ec7cf 100644 --- a/src/fields/generic_1byte.cpp +++ b/src/fields/generic_1byte.cpp @@ -83,29 +83,29 @@ typedef Field #endif } -Sketch* ConstructGeneric1Byte(int bits, int implementation) +Sketch* ConstructGeneric1Byte(int bits, int implementation, uint64_t seed) { switch (bits) { #ifdef ENABLE_FIELD_INT_2 - case 2: return new SketchImpl(implementation, 2); + case 2: return new SketchImpl(implementation, 2, seed); #endif #ifdef ENABLE_FIELD_INT_3 - case 3: return new SketchImpl(implementation, 3); + case 3: return new SketchImpl(implementation, 3, seed); #endif #ifdef ENABLE_FIELD_INT_4 - case 4: return new SketchImpl(implementation, 4); + case 4: return new SketchImpl(implementation, 4, seed); #endif #ifdef ENABLE_FIELD_INT_5 - case 5: return new SketchImpl(implementation, 5); + case 5: return new SketchImpl(implementation, 5, seed); #endif #ifdef ENABLE_FIELD_INT_6 - case 6: return new SketchImpl(implementation, 6); + case 6: return new SketchImpl(implementation, 6, seed); #endif #ifdef ENABLE_FIELD_INT_7 - case 7: return new SketchImpl(implementation, 7); + case 7: return new SketchImpl(implementation, 7, seed); #endif #ifdef ENABLE_FIELD_INT_8 - case 8: return new SketchImpl(implementation, 8); + case 8: return new SketchImpl(implementation, 8, seed); #endif default: return nullptr; } diff --git a/src/fields/generic_2bytes.cpp b/src/fields/generic_2bytes.cpp index 12bf311..ca91d7b 100644 --- a/src/fields/generic_2bytes.cpp +++ b/src/fields/generic_2bytes.cpp @@ -92,32 +92,32 @@ typedef Field(implementation, 9); + case 9: return new SketchImpl(implementation, 9, seed); #endif #ifdef ENABLE_FIELD_INT_10 - case 10: return new SketchImpl(implementation, 10); + case 10: return new SketchImpl(implementation, 10, seed); #endif #ifdef ENABLE_FIELD_INT_11 - case 11: return new SketchImpl(implementation, 11); + case 11: return new SketchImpl(implementation, 11, seed); #endif #ifdef ENABLE_FIELD_INT_12 - case 12: return new SketchImpl(implementation, 12); + case 12: return new SketchImpl(implementation, 12, seed); #endif #ifdef ENABLE_FIELD_INT_13 - case 13: return new SketchImpl(implementation, 13); + case 13: return new SketchImpl(implementation, 13, seed); #endif #ifdef ENABLE_FIELD_INT_14 - case 14: return new SketchImpl(implementation, 14); + case 14: return new SketchImpl(implementation, 14, seed); #endif #ifdef ENABLE_FIELD_INT_15 - case 15: return new SketchImpl(implementation, 15); + case 15: return new SketchImpl(implementation, 15, seed); #endif #ifdef ENABLE_FIELD_INT_16 - case 16: return new SketchImpl(implementation, 16); + case 16: return new SketchImpl(implementation, 16, seed); #endif default: return nullptr; } diff --git a/src/fields/generic_3bytes.cpp b/src/fields/generic_3bytes.cpp index 13e85bd..48852ee 100644 --- a/src/fields/generic_3bytes.cpp +++ b/src/fields/generic_3bytes.cpp @@ -92,32 +92,32 @@ typedef Field(implementation, 17); + case 17: return new SketchImpl(implementation, 17, seed); #endif #ifdef ENABLE_FIELD_INT_18 - case 18: return new SketchImpl(implementation, 18); + case 18: return new SketchImpl(implementation, 18, seed); #endif #ifdef ENABLE_FIELD_INT_19 - case 19: return new SketchImpl(implementation, 19); + case 19: return new SketchImpl(implementation, 19, seed); #endif #ifdef ENABLE_FIELD_INT_20 - case 20: return new SketchImpl(implementation, 20); + case 20: return new SketchImpl(implementation, 20, seed); #endif #ifdef ENABLE_FIELD_INT_21 - case 21: return new SketchImpl(implementation, 21); + case 21: return new SketchImpl(implementation, 21, seed); #endif #ifdef ENABLE_FIELD_INT_22 - case 22: return new SketchImpl(implementation, 22); + case 22: return new SketchImpl(implementation, 22, seed); #endif #ifdef ENABLE_FIELD_INT_23 - case 23: return new SketchImpl(implementation, 23); + case 23: return new SketchImpl(implementation, 23, seed); #endif #ifdef ENABLE_FIELD_INT_24 - case 24: return new SketchImpl(implementation, 24); + case 24: return new SketchImpl(implementation, 24, seed); #endif default: return nullptr; } diff --git a/src/fields/generic_4bytes.cpp b/src/fields/generic_4bytes.cpp index 2a26b90..7beb858 100644 --- a/src/fields/generic_4bytes.cpp +++ b/src/fields/generic_4bytes.cpp @@ -92,32 +92,32 @@ typedef Field(implementation, 25); + case 25: return new SketchImpl(implementation, 25, seed); #endif #ifdef ENABLE_FIELD_INT_26 - case 26: return new SketchImpl(implementation, 26); + case 26: return new SketchImpl(implementation, 26, seed); #endif #ifdef ENABLE_FIELD_INT_27 - case 27: return new SketchImpl(implementation, 27); + case 27: return new SketchImpl(implementation, 27, seed); #endif #ifdef ENABLE_FIELD_INT_28 - case 28: return new SketchImpl(implementation, 28); + case 28: return new SketchImpl(implementation, 28, seed); #endif #ifdef ENABLE_FIELD_INT_29 - case 29: return new SketchImpl(implementation, 29); + case 29: return new SketchImpl(implementation, 29, seed); #endif #ifdef ENABLE_FIELD_INT_30 - case 30: return new SketchImpl(implementation, 30); + case 30: return new SketchImpl(implementation, 30, seed); #endif #ifdef ENABLE_FIELD_INT_31 - case 31: return new SketchImpl(implementation, 31); + case 31: return new SketchImpl(implementation, 31, seed); #endif #ifdef ENABLE_FIELD_INT_32 - case 32: return new SketchImpl(implementation, 32); + case 32: return new SketchImpl(implementation, 32, seed); #endif default: return nullptr; } diff --git a/src/fields/generic_5bytes.cpp b/src/fields/generic_5bytes.cpp index b064181..01d7028 100644 --- a/src/fields/generic_5bytes.cpp +++ b/src/fields/generic_5bytes.cpp @@ -92,32 +92,32 @@ typedef Field(implementation, 33); + case 33: return new SketchImpl(implementation, 33, seed); #endif #ifdef ENABLE_FIELD_INT_34 - case 34: return new SketchImpl(implementation, 34); + case 34: return new SketchImpl(implementation, 34, seed); #endif #ifdef ENABLE_FIELD_INT_35 - case 35: return new SketchImpl(implementation, 35); + case 35: return new SketchImpl(implementation, 35, seed); #endif #ifdef ENABLE_FIELD_INT_36 - case 36: return new SketchImpl(implementation, 36); + case 36: return new SketchImpl(implementation, 36, seed); #endif #ifdef ENABLE_FIELD_INT_37 - case 37: return new SketchImpl(implementation, 37); + case 37: return new SketchImpl(implementation, 37, seed); #endif #ifdef ENABLE_FIELD_INT_38 - case 38: return new SketchImpl(implementation, 38); + case 38: return new SketchImpl(implementation, 38, seed); #endif #ifdef ENABLE_FIELD_INT_39 - case 39: return new SketchImpl(implementation, 39); + case 39: return new SketchImpl(implementation, 39, seed); #endif #ifdef ENABLE_FIELD_INT_40 - case 40: return new SketchImpl(implementation, 40); + case 40: return new SketchImpl(implementation, 40, seed); #endif default: return nullptr; } diff --git a/src/fields/generic_6bytes.cpp b/src/fields/generic_6bytes.cpp index becb26e..63b9383 100644 --- a/src/fields/generic_6bytes.cpp +++ b/src/fields/generic_6bytes.cpp @@ -92,32 +92,32 @@ typedef Field(implementation, 41); + case 41: return new SketchImpl(implementation, 41, seed); #endif #ifdef ENABLE_FIELD_INT_42 - case 42: return new SketchImpl(implementation, 42); + case 42: return new SketchImpl(implementation, 42, seed); #endif #ifdef ENABLE_FIELD_INT_43 - case 43: return new SketchImpl(implementation, 43); + case 43: return new SketchImpl(implementation, 43, seed); #endif #ifdef ENABLE_FIELD_INT_44 - case 44: return new SketchImpl(implementation, 44); + case 44: return new SketchImpl(implementation, 44, seed); #endif #ifdef ENABLE_FIELD_INT_45 - case 45: return new SketchImpl(implementation, 45); + case 45: return new SketchImpl(implementation, 45, seed); #endif #ifdef ENABLE_FIELD_INT_46 - case 46: return new SketchImpl(implementation, 46); + case 46: return new SketchImpl(implementation, 46, seed); #endif #ifdef ENABLE_FIELD_INT_47 - case 47: return new SketchImpl(implementation, 47); + case 47: return new SketchImpl(implementation, 47, seed); #endif #ifdef ENABLE_FIELD_INT_48 - case 48: return new SketchImpl(implementation, 48); + case 48: return new SketchImpl(implementation, 48, seed); #endif default: return nullptr; } diff --git a/src/fields/generic_7bytes.cpp b/src/fields/generic_7bytes.cpp index 8222f37..fa8ef61 100644 --- a/src/fields/generic_7bytes.cpp +++ b/src/fields/generic_7bytes.cpp @@ -92,32 +92,32 @@ typedef Field(implementation, 49); + case 49: return new SketchImpl(implementation, 49, seed); #endif #ifdef ENABLE_FIELD_INT_50 - case 50: return new SketchImpl(implementation, 50); + case 50: return new SketchImpl(implementation, 50, seed); #endif #ifdef ENABLE_FIELD_INT_51 - case 51: return new SketchImpl(implementation, 51); + case 51: return new SketchImpl(implementation, 51, seed); #endif #ifdef ENABLE_FIELD_INT_52 - case 52: return new SketchImpl(implementation, 52); + case 52: return new SketchImpl(implementation, 52, seed); #endif #ifdef ENABLE_FIELD_INT_53 - case 53: return new SketchImpl(implementation, 53); + case 53: return new SketchImpl(implementation, 53, seed); #endif #ifdef ENABLE_FIELD_INT_54 - case 54: return new SketchImpl(implementation, 54); + case 54: return new SketchImpl(implementation, 54, seed); #endif #ifdef ENABLE_FIELD_INT_55 - case 55: return new SketchImpl(implementation, 55); + case 55: return new SketchImpl(implementation, 55, seed); #endif #ifdef ENABLE_FIELD_INT_56 - case 56: return new SketchImpl(implementation, 56); + case 56: return new SketchImpl(implementation, 56, seed); #endif default: return nullptr; } diff --git a/src/fields/generic_8bytes.cpp b/src/fields/generic_8bytes.cpp index 8bb63e8..51cb46a 100644 --- a/src/fields/generic_8bytes.cpp +++ b/src/fields/generic_8bytes.cpp @@ -92,32 +92,32 @@ typedef Field(implementation, 57); + case 57: return new SketchImpl(implementation, 57, seed); #endif #ifdef ENABLE_FIELD_INT_58 - case 58: return new SketchImpl(implementation, 58); + case 58: return new SketchImpl(implementation, 58, seed); #endif #ifdef ENABLE_FIELD_INT_59 - case 59: return new SketchImpl(implementation, 59); + case 59: return new SketchImpl(implementation, 59, seed); #endif #ifdef ENABLE_FIELD_INT_60 - case 60: return new SketchImpl(implementation, 60); + case 60: return new SketchImpl(implementation, 60, seed); #endif #ifdef ENABLE_FIELD_INT_61 - case 61: return new SketchImpl(implementation, 61); + case 61: return new SketchImpl(implementation, 61, seed); #endif #ifdef ENABLE_FIELD_INT_62 - case 62: return new SketchImpl(implementation, 62); + case 62: return new SketchImpl(implementation, 62, seed); #endif #ifdef ENABLE_FIELD_INT_63 - case 63: return new SketchImpl(implementation, 63); + case 63: return new SketchImpl(implementation, 63, seed); #endif #ifdef ENABLE_FIELD_INT_64 - case 64: return new SketchImpl(implementation, 64); + case 64: return new SketchImpl(implementation, 64, seed); #endif default: return nullptr; } diff --git a/src/minisketch.cpp b/src/minisketch.cpp index 2e45409..4b212b0 100644 --- a/src/minisketch.cpp +++ b/src/minisketch.cpp @@ -25,32 +25,32 @@ # endif #endif -Sketch* ConstructGeneric1Byte(int bits, int implementation); -Sketch* ConstructGeneric2Bytes(int bits, int implementation); -Sketch* ConstructGeneric3Bytes(int bits, int implementation); -Sketch* ConstructGeneric4Bytes(int bits, int implementation); -Sketch* ConstructGeneric5Bytes(int bits, int implementation); -Sketch* ConstructGeneric6Bytes(int bits, int implementation); -Sketch* ConstructGeneric7Bytes(int bits, int implementation); -Sketch* ConstructGeneric8Bytes(int bits, int implementation); +Sketch* ConstructGeneric1Byte(int bits, int implementation, uint64_t seed); +Sketch* ConstructGeneric2Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructGeneric3Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructGeneric4Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructGeneric5Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructGeneric6Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructGeneric7Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructGeneric8Bytes(int bits, int implementation, uint64_t seed); #ifdef HAVE_CLMUL -Sketch* ConstructClMul1Byte(int bits, int implementation); -Sketch* ConstructClMul2Bytes(int bits, int implementation); -Sketch* ConstructClMul3Bytes(int bits, int implementation); -Sketch* ConstructClMul4Bytes(int bits, int implementation); -Sketch* ConstructClMul5Bytes(int bits, int implementation); -Sketch* ConstructClMul6Bytes(int bits, int implementation); -Sketch* ConstructClMul7Bytes(int bits, int implementation); -Sketch* ConstructClMul8Bytes(int bits, int implementation); -Sketch* ConstructClMulTri1Byte(int bits, int implementation); -Sketch* ConstructClMulTri2Bytes(int bits, int implementation); -Sketch* ConstructClMulTri3Bytes(int bits, int implementation); -Sketch* ConstructClMulTri4Bytes(int bits, int implementation); -Sketch* ConstructClMulTri5Bytes(int bits, int implementation); -Sketch* ConstructClMulTri6Bytes(int bits, int implementation); -Sketch* ConstructClMulTri7Bytes(int bits, int implementation); -Sketch* ConstructClMulTri8Bytes(int bits, int implementation); +Sketch* ConstructClMul1Byte(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMul2Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMul3Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMul4Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMul5Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMul6Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMul7Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMul8Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMulTri1Byte(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMulTri2Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMulTri3Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMulTri4Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMulTri5Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMulTri6Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMulTri7Bytes(int bits, int implementation, uint64_t seed); +Sketch* ConstructClMulTri8Bytes(int bits, int implementation, uint64_t seed); #endif namespace { @@ -77,27 +77,27 @@ static inline bool EnableClmul() } #endif -Sketch* Construct(int bits, int impl) +Sketch* Construct(int bits, int impl, uint64_t seed) { switch (FieldImpl(impl)) { case FieldImpl::GENERIC: switch ((bits + 7) / 8) { case 1: - return ConstructGeneric1Byte(bits, impl); + return ConstructGeneric1Byte(bits, impl, seed); case 2: - return ConstructGeneric2Bytes(bits, impl); + return ConstructGeneric2Bytes(bits, impl, seed); case 3: - return ConstructGeneric3Bytes(bits, impl); + return ConstructGeneric3Bytes(bits, impl, seed); case 4: - return ConstructGeneric4Bytes(bits, impl); + return ConstructGeneric4Bytes(bits, impl, seed); case 5: - return ConstructGeneric5Bytes(bits, impl); + return ConstructGeneric5Bytes(bits, impl, seed); case 6: - return ConstructGeneric6Bytes(bits, impl); + return ConstructGeneric6Bytes(bits, impl, seed); case 7: - return ConstructGeneric7Bytes(bits, impl); + return ConstructGeneric7Bytes(bits, impl, seed); case 8: - return ConstructGeneric8Bytes(bits, impl); + return ConstructGeneric8Bytes(bits, impl, seed); default: return nullptr; } @@ -107,21 +107,21 @@ Sketch* Construct(int bits, int impl) if (EnableClmul()) { switch ((bits + 7) / 8) { case 1: - return ConstructClMul1Byte(bits, impl); + return ConstructClMul1Byte(bits, impl, seed); case 2: - return ConstructClMul2Bytes(bits, impl); + return ConstructClMul2Bytes(bits, impl, seed); case 3: - return ConstructClMul3Bytes(bits, impl); + return ConstructClMul3Bytes(bits, impl, seed); case 4: - return ConstructClMul4Bytes(bits, impl); + return ConstructClMul4Bytes(bits, impl, seed); case 5: - return ConstructClMul5Bytes(bits, impl); + return ConstructClMul5Bytes(bits, impl, seed); case 6: - return ConstructClMul6Bytes(bits, impl); + return ConstructClMul6Bytes(bits, impl, seed); case 7: - return ConstructClMul7Bytes(bits, impl); + return ConstructClMul7Bytes(bits, impl, seed); case 8: - return ConstructClMul8Bytes(bits, impl); + return ConstructClMul8Bytes(bits, impl, seed); default: return nullptr; } @@ -131,21 +131,21 @@ Sketch* Construct(int bits, int impl) if (EnableClmul()) { switch ((bits + 7) / 8) { case 1: - return ConstructClMulTri1Byte(bits, impl); + return ConstructClMulTri1Byte(bits, impl, seed); case 2: - return ConstructClMulTri2Bytes(bits, impl); + return ConstructClMulTri2Bytes(bits, impl, seed); case 3: - return ConstructClMulTri3Bytes(bits, impl); + return ConstructClMulTri3Bytes(bits, impl, seed); case 4: - return ConstructClMulTri4Bytes(bits, impl); + return ConstructClMulTri4Bytes(bits, impl, seed); case 5: - return ConstructClMulTri5Bytes(bits, impl); + return ConstructClMulTri5Bytes(bits, impl, seed); case 6: - return ConstructClMulTri6Bytes(bits, impl); + return ConstructClMulTri6Bytes(bits, impl, seed); case 7: - return ConstructClMulTri7Bytes(bits, impl); + return ConstructClMulTri7Bytes(bits, impl, seed); case 8: - return ConstructClMulTri8Bytes(bits, impl); + return ConstructClMulTri8Bytes(bits, impl, seed); default: return nullptr; } @@ -366,7 +366,7 @@ int minisketch_implementation_supported(uint32_t bits, uint32_t implementation) return 0; } try { - Sketch* sketch = Construct(bits, implementation); + Sketch* sketch = Construct(bits, implementation, 0); if (sketch) { delete sketch; return 1; @@ -375,9 +375,9 @@ int minisketch_implementation_supported(uint32_t bits, uint32_t implementation) return 0; } -minisketch* minisketch_create(uint32_t bits, uint32_t implementation, size_t capacity) { +minisketch* minisketch_create(uint32_t bits, uint32_t implementation, size_t capacity, uint64_t seed) { try { - Sketch* sketch = Construct(bits, implementation); + Sketch* sketch = Construct(bits, implementation, seed); if (sketch) { try { sketch->Init(capacity); @@ -414,9 +414,9 @@ uint32_t minisketch_implementation(const minisketch* sketch) { minisketch* minisketch_clone(const minisketch* sketch) { const Sketch* s = (const Sketch*)sketch; s->Check(); - Sketch* r = (Sketch*) minisketch_create(s->Bits(), s->Implementation(), s->Syndromes()); + Sketch* r = s->Clone(); if (r) { - r->Merge(s); + r->Check(); } return (minisketch*) r; } diff --git a/src/sketch.h b/src/sketch.h index 662b4e9..41900b7 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -35,6 +35,7 @@ class Sketch virtual void Deserialize(const unsigned char*) = 0; virtual size_t Merge(const Sketch* other_sketch) = 0; virtual void SetSeed(uint64_t seed) = 0; + virtual Sketch* Clone() const = 0; virtual int Decode(int max_count, uint64_t* roots) const = 0; }; diff --git a/src/sketch_impl.h b/src/sketch_impl.h index c357f0e..82048ae 100644 --- a/src/sketch_impl.h +++ b/src/sketch_impl.h @@ -360,12 +360,12 @@ class SketchImpl final : public Sketch public: template - SketchImpl(int implementation, int bits, const Args&... args) : Sketch(implementation, bits), m_field(args...) { - std::random_device rng; - std::uniform_int_distribution dist; - m_basis = m_field.FromSeed(dist(rng)); + SketchImpl(int implementation, int bits, uint64_t seed, const Args&... args) : Sketch(implementation, bits), m_field(args...) { + m_basis = m_field.FromSeed(seed); } + SketchImpl(const SketchImpl& other) = default; + size_t Syndromes() const override { return m_syndromes.size(); } void Init(size_t count) override { m_syndromes.assign(count, 0); } @@ -429,6 +429,11 @@ class SketchImpl final : public Sketch m_basis = m_field.FromSeed(seed); } } + + Sketch* Clone() const override + { + return new SketchImpl(*this); + } }; #endif diff --git a/src/test.cpp b/src/test.cpp index 85b9e9e..922cf06 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -28,13 +28,13 @@ uint64_t Combination(uint64_t n, uint64_t k) { } /** Create a vector with Minisketch objects, one for each implementation. */ -std::vector CreateSketches(uint32_t bits, size_t capacity) { +std::vector CreateSketches(uint32_t bits, size_t capacity, uint64_t seed) { if (!Minisketch::BitsSupported(bits)) return {}; std::vector ret; for (uint32_t impl = 0; impl <= Minisketch::MaxImplementation(); ++impl) { if (Minisketch::ImplementationSupported(bits, impl)) { CHECK(Minisketch::BitsSupported(bits)); - ret.push_back(Minisketch(bits, impl, capacity)); + ret.push_back(Minisketch(bits, impl, capacity, seed)); CHECK((bool)ret.back()); } else { // implementation 0 must always work unless field size is disabled @@ -46,10 +46,10 @@ std::vector CreateSketches(uint32_t bits, size_t capacity) { /** Test properties by exhaustively decoding all 2**(bits*capacity) sketches * with specified capacity and bits. */ -void TestExhaustive(uint32_t bits, size_t capacity) { - auto sketches = CreateSketches(bits, capacity); +void TestExhaustive(uint32_t bits, size_t capacity, uint64_t seed) { + auto sketches = CreateSketches(bits, capacity, seed); if (sketches.empty()) return; - auto sketches_rebuild = CreateSketches(bits, capacity); + auto sketches_rebuild = CreateSketches(bits, capacity, seed + 1); std::vector serialized; std::vector serialized_empty; @@ -125,6 +125,7 @@ void TestExhaustive(uint32_t bits, size_t capacity) { /** Test properties of sketches with random elements put in. */ void TestRandomized(uint32_t bits, size_t max_capacity, size_t iter) { std::random_device rnd; + std::uniform_int_distribution seed_dist; std::uniform_int_distribution capacity_dist(0, std::min(std::numeric_limits::max() >> (64 - bits), max_capacity)); std::uniform_int_distribution element_dist(1, std::numeric_limits::max() >> (64 - bits)); std::uniform_int_distribution rand64(0, std::numeric_limits::max()); @@ -138,7 +139,7 @@ void TestRandomized(uint32_t bits, size_t max_capacity, size_t iter) { for (size_t i = 0; i < iter; ++i) { // Determine capacity, and construct Minisketch objects for all implementations. uint64_t capacity = capacity_dist(rnd); - auto sketches = CreateSketches(bits, capacity); + auto sketches = CreateSketches(bits, capacity, seed_dist(rnd)); // Sanity checks if (sketches.empty()) return; for (size_t impl = 0; impl < sketches.size(); ++impl) { @@ -268,6 +269,8 @@ void TestComputeFunctions() { } // namespace int main(int argc, char** argv) { + std::random_device rnd; + std::uniform_int_distribution seed_dist; uint64_t test_complexity = 4; if (argc > 1) { size_t len = 0; @@ -307,7 +310,7 @@ int main(int argc, char** argv) { for (int bits = 2; weight == 0 ? bits <= 64 : (bits <= 32 && bits <= weight); ++bits) { int capacity = weight / bits; if (capacity * bits != weight) continue; - TestExhaustive(bits, capacity); + TestExhaustive(bits, capacity, seed_dist(rnd)); } if (weight >= 16 && test_complexity >> (weight - 16) == 0) break; }