Unit tests Toeplitz hashing#
TestToeplitzMatrixAlmostSquare#
This is the first relevant unit test to be documented. Previous tests check for correct initialization and use of the correct types for each of the parameters.
The first step is to compute the output length. Given the lower bound on the min-entropy, we compute the largest output length to achieve a distance from uniform lower than the error bound. This is guaranteed by the leftover hash lemma.
>>> import math
>>> math.floor(0.99*5 - 2*math.log2(1/0.99))
4
Our code does not compute and store the Toeplitz matrix to use the extract()
method because we use the
Fast Fourier Transform and work directly with the input and seed
vectors. However, the method to_matrix()
allows us to obtain this Toeplitz matrix. The default arrangement of the
seed to form the Toeplitz matrix is the same as described in the theory section, i.e.,
In this particular test we have
The seed was chosen to emphasize the differences between the available options for seed_mode
and seed_order
.
For seed_mode="col-first"
we obtain
And for seed_mode="row-first"
With seed_mode="custom"
, the permutation array seed_order
determines how the bits from the seed are used to
construct the matrix. Three permutations are tested, here we show the first one which swaps the first and second
bit.
Finally, the output of the extract()
method matches the matrix-vector multiplication between the Toeplitz matrix
and the input from the weak source. In this particular test we have
TestToeplitzMatrixWide#
>>> import math
>>> math.floor(0.7*8 - 2*math.log2(1/0.5))
3
TestToeplitzMatrixOneDimensionalWide#
>>> import math
>>> math.floor(0.5*10 - 2*math.log2(1/0.25))
1
This is an extreme scenario where the Toeplitz matrix only has one row, but the “matrix” is still computed in the same way, so it looks reversed except for the first bit.
Unit tests Modified Toeplitz hashing#
TestModifiedToeplitzMatrixAlmostSquare#
>>> import math
>>> math.floor(0.75*9 - 2*math.log2(1/0.5))
4
Remember that the modified Toeplitz hashing appends an identity matrix to reduce the
required seed. Because of this, instead of a seed of length \(\text{input_length}+\text{output_length}-1\), we only
need \(\text{input_length}-1\) bits. The order of these bits to form the matrix is exactly the same as in the normal
Toeplitz hashing, and seed_mode
and seed_order
kwargs can also be used to modify it.
TestModifiedToeplitzMatrixNarrow#
>>> import math
>>> math.floor(0.99*11 - 2*math.log2(1/0.5))
8
TestModifiedToeplitzMatrixWide#
>>> import math
>>> math.floor(0.5*11 - 2*math.log2(1/0.5))
3
TestModifiedToeplitzMatrixOneDimensionalNarrow#
>>> import math
>>> math.floor(0.99*11 - 2*math.log2(1/0.99))
10
TestModifiedToeplitzMatrixOneDimensionalWide#
>>> import math
>>> math.floor(0.5*11 - 2*math.log2(1/0.25))
1