Usage#
The typical workflow with randextract
is the following:
Decide what randomness extractor you want to use
Calculate the optimal parameters based on the weak randomness source and the acceptable error
Pick one particular family of extractor with fixed input and output lengths
Process the weak randomness, or
Verify a different implementation
The first step is something you have to decide before starting to write any code. The theory section can
help you make an informed decision. Once you know what extractor you want to use, the second step can be done with the
help of randextract
by using the calculate_length()
method of any RandomnessExtractor
class. Third
step is done by using the class method create()
of RandomnessExtractor
or by calling directly the
constructor of the implementation class (e.g. ToeplitzHashing
). The actual randomness extraction is always done
by calling the extract()
method of a RandomnessExtractor
. And finally, testing and validating other
implementations using the class Validator
. In the next section we show some practical examples using our package
to validate high-performance implementations used in current QKD experiments.
First example#
First of all, if you haven’t install randextract
,
You can use randextract
in your own Python script. The recommended way to create a
randomness extractor object is to use the method create()
of our factory
class RandomnessExtractor
.
The first thing you need to decide is the type of extractor you want to use. Currently, we offer these three types:
toeplitz
, modified_toeplitz
, and trevisan
. For a summary of these implementations you can read
their docstrings in the API Reference page. For a more detailed explanation, as well as some examples, check
the theory section.
import randextract
from randextract import RandomnessExtractor
ext = RandomnessExtractor.create(extractor_type="YOUR TYPE CHOICE", ...)
Once you know what extractor you want to use, you should read the required parameters from its implementation class.
For example, if you want to use a Toeplitz hashing extractor, check ToeplitzHashing
. For a Trevisan’s
construction, check TrevisanExtractor
.
The simplest extractor requires, at least, that you specify
the length of the bit string from the weak random source,
a lower bound on the weak random source entropy,
and the tolerable error.
For example, the following code creates a Toeplitz hashing extractor that expects an input of 1 MiB from a weak random and outputs around 512 KiB (up to an error \(10^{-6}\)).
from galois import GF2
import randextract
from randextract import RandomnessExtractor, ToeplitzHashing
MiB = 8 * 2**20
optimal_output_length = ToeplitzHashing.calculate_length(
extractor_type="quantum",
input_length=MiB,
relative_source_entropy=0.5,
error_bound=1e-6,
)
ext = RandomnessExtractor.create(
extractor_type="toeplitz", input_length=MiB, output_length=optimal_output_length
)
input_ext = GF2.Random(MiB)
seed_ext = GF2.Random(ext.seed_length)
extracted = ext.extract(input_ext, seed_ext)
The Trevisan’s construction requires a weak design and a one-bit extractor, each of which accepts a set of parameters. For example, the following code creates a Trevisan’s construction using the polynomial one-bit extractor and the finite field polynomial weak design.
import randextract
from randextract import RandomnessExtractor
from galois import GF2
ext = RandomnessExtractor.create(
extractor_type="trevisan",
weak_design_type="finite_field",
one_bit_extractor_type="polynomial",
one_bit_extractor_seed_length=1024,
input_length=2**20,
output_length=2**10,
)
input_ext = GF2.Random(ext.input_length)
seed_ext = GF2.Random(ext.seed_length)
extracted = ext.extract(input_ext, seed_ext)