diff --git a/cryptomite/circulant.py b/cryptomite/circulant.py index ff1cb7a..204e1d0 100644 --- a/cryptomite/circulant.py +++ b/cryptomite/circulant.py @@ -22,7 +22,7 @@ def __init__(self, n: int, m: int): ---------- n : int The length of the input bits. - *** n + 1 should be prime. *** + ** n + 1 should be prime. ** m : int The length of the output bits. """ diff --git a/cryptomite/dodis.py b/cryptomite/dodis.py index 454b5a6..d26a0b6 100644 --- a/cryptomite/dodis.py +++ b/cryptomite/dodis.py @@ -21,7 +21,7 @@ def __init__(self, n: int, m: int): ---------- n : int The length of the two input bits. - *** This should be prime with primitive root 2. *** + ** This should be prime with primitive root 2. ** m : int The length of the output bits. """ diff --git a/cryptomite/toeplitz.py b/cryptomite/toeplitz.py index 49fb329..9ce4e9b 100644 --- a/cryptomite/toeplitz.py +++ b/cryptomite/toeplitz.py @@ -78,7 +78,7 @@ def from_params( min_entropy2 : float The min-entropy of input source 2, the '(weak) seed'. log2_error : float - The acceptable maximum extractor error, in the + The maximum acceptable extractor error, in the form error = b where extractor error = :math:`2 ^ b`. input_length1 : int The initial length of input source. diff --git a/cryptomite/trevisan.py b/cryptomite/trevisan.py index 91e2a9b..999af79 100644 --- a/cryptomite/trevisan.py +++ b/cryptomite/trevisan.py @@ -1,41 +1,34 @@ """ -This is a module. +Trevisan is a seeded extractor that takes two differing length, +independent, strings of bits to produce some error-perfect random bits. """ from __future__ import annotations __all__ = ['Trevisan'] -from math import ceil, exp, floor, log, log2 - from cryptomite import _cryptomite class Trevisan: """Trevisan extractor based on [Trev2001]_ and [Mauer2012]_. """ - def __init__(self, n: int, k: float, max_eps: float): + def __init__(self, n: int, k: float, error: float): """Create a Trevisan Extractor. - The extractor accepts `n` input bits of min-entropy `k` and `d` - seed bits and outputs `m` bits with total worst case error of - `max_eps`. The parameters for the weak designs and 1-bit - extractors are computed from `n`, `k`, and `max_eps`. To use - the Trevisan extractor, provide `n`, `k` and `max_eps`. - Parameters ---------- - n : int - The number of input bits. - k : float - The amount of min-entropy in the input bits. - max_eps : float - The total worst case error. + n : int + The length of the input bits. + k : float + The total min-entropy of the input bits. + error : float + The maximum acceptable extractor error. """ - self.config = _cryptomite.TrevisanConfig(n, k, max_eps) + self.config = _cryptomite.TrevisanConfig(n, k, error) self.ext = _cryptomite.Trevisan(self.config) def extract(self, input1: list[bool], input2: list[bool]) -> list[bool]: """ - Load the source and the seed. + Extract randomness. Parameters ---------- @@ -57,83 +50,3 @@ def extract(self, input1: list[bool], input2: list[bool]) -> list[bool]: bit = self.ext.extract_bit(i) bits.append(bit) return bits - - @staticmethod - def from_params( - min_entropy1: float, - min_entropy2: float, - log2_error: float, - input_length1: int, - input_length2: int, - markov_q_proof: bool, - verbose: bool = True) -> Trevisan: - """ - Calculate a valid input and output size for this extractor, - given the initial lengths and min-entropies of the input sources - and generate the associated extractor. - - *** Note: at present, this function (for Trevisan) only supports - when input_length2 = min_entropy2, i.e. when the seed is - uniform. *** - The min entropy inputs are a lower bound on the - :term:`min-entropy` of the related input string. - - Parameters - ---------- - min_entropy1 : float - The min-entropy of input source 1, the 'input'. - min_entropy2 : float - The min-entropy of input source 2, the '(weak) seed'. - log_error : float - The acceptable maximum extractor error, in the - form error = b where extractor error = :math:`2 ^ b`. - input_length1 : int - The initial length of input source. - input_length2 : int - The initial length of the (weak) seed. - markov_q_proof : bool - Boolean indicator of whether the extractor parameters - should be calculated to account for being quantum-proof - in the Markov model or not. - - Returns - ------- - Trevisan - The Trevisan extractor. - """ - if log2_error > 0: - raise Exception("""Cannot extract with these parameters. - log2_error must be < 0.""") - if min_entropy2 != input_length2: - raise Exception("""Cannot calcuate with these parameters. - Set min_entropy2 = input_length2.""") - r = 2 * exp(1) - m = min_entropy1 + 4 * log2_error - 6 - output_length = floor(min_entropy1 + 4 * log2_error - - 4 * log2(m) - 6) - t = 2 * ceil(log2(input_length1) + 1 - - 2 * log2_error + 2 * log2(2 * output_length)) - a = max(1, ceil((log(output_length - r) - log(t - r)) - / (log(r) - log(r-1)))) - if markov_q_proof: - m = (1/7) * (min_entropy1 + 6 - 6 * log2(3) - + 12 * log2_error) - output_length = floor((1/7) * (min_entropy1 + 6 - 6 * log2(3) - + 12 * log2_error - 12 * log2(m))) - t = 2 * ceil(log2(input_length1) + 1 - - 2 * log2_error + 2 * log2(2 * output_length)) - a = max(1, ceil((log(output_length - r) - log(t - r)) - / (log(r) - log(r-1)))) - if input_length2 < 4 * a * t**2: - raise Exception("""Cannot extract with these parameters. - Increase input_length2.""") - input_length2 = 4 * a * t**2 - if verbose: - print('Min entropy1: ', min_entropy1, - 'Min entropy2: ', min_entropy2, - 'Log error: ', log2_error, - 'Input length1: ', input_length1, - 'Input length2: ', input_length2, - 'Output length: ', output_length) - print('Adjust length of the input and seed accordingly') - return Trevisan(n=input_length1, m=output_length) diff --git a/docs/bibliography.rst b/docs/bibliography.rst index 7edd9a9..4f8a8d8 100644 --- a/docs/bibliography.rst +++ b/docs/bibliography.rst @@ -16,3 +16,5 @@ Bibliography .. [Mauer2012] W. Mauerer, C. Portmann, and V. B. Scholz, `A modular framework for randomness extraction based on Trevisan’s construction `_, Pre-print (2012) .. [Dodis2004] Y. Dodis, A. Elbaz, R. Oliveira, and R. Raz, `Improved randomness extraction from two independent sources `_ in Proceedings RANDOM, vol. 3122, pp. 334–344 (2004) + +.. [For2024] C. Foreman, R. Yeung, A. Edgington et al. `Cryptomite: A versatile and user-friendly library of randomness extractors`_, Pre-print (2024) \ No newline at end of file diff --git a/docs/figures/Table.png b/docs/figures/Table.png new file mode 100644 index 0000000..0504107 Binary files /dev/null and b/docs/figures/Table.png differ diff --git a/docs/figures/extractor_flow_chart.png b/docs/figures/extractor_flow_chart.png new file mode 100644 index 0000000..9d1abcc Binary files /dev/null and b/docs/figures/extractor_flow_chart.png differ diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst index 1fe95cc..fe6d35a 100644 --- a/docs/gettingstarted.rst +++ b/docs/gettingstarted.rst @@ -1,62 +1,16 @@ Selecting a Randomness Extractor ================================ -In the following, we use the notation :math:`n_1, n_2` to denote the length and :math:`k_1, k_2` to denote the :term:`min-entropy` of -any first or second input string respectively. Additionally, :math:`m` denotes the length of an output string, :math:`\epsilon` -the extractor error and :math:`O(.)` denotes the asymptotic behaviour of a function. +In general, the choice of randomness extractor depends on the scenario in which it is to be used and, it is not always clear which extractor is best suited to a given scenario. +In this section, we (informally) help solve this problem, based on the section 'Overview of Extractor Library' from Cryptomite's accompanying paper (see :ref:`For2024`). +We use the notation :math:`n_1, n_2` to denote the length and :math:`k_1, k_2` to denote the :term:`min-entropy` of any first or second input string respectively. +Additionally, :math:`m` denotes the length of an output string, :math:`\epsilon` the extractor error and :math:`O(.)` denotes asymptotic quantities. -:py:class:`.Circulant` ------------------- -The Circulant extractor is a :term:`seeded randomness extractor`, meaning that it requires two independent bit -strings of randomness, where one is already (near-)perfectly random (called a seed). -It requires the weak input to be of length :math:`n_1 = n_2 - 1`, where the length of the seed :math:`n_2` is prime -and outputs approximately :math:`m \approx k_1 + k_2 - n_1` when considering classical side information or in the quantum product-source model -and :math:`m \approx \frac{1}{5}(k_1 + k_2 - n_1)`. -Our implementation of this extractor has near-linear computational complexity. +.. image:: figures/extractor_flow_chart.png + :width: 600 -This extractor is best suited to scenarios where a seeded extractor is required in both the classical and quantum side information setting. +Note: there may be a small gain to be made by analysing the extractors individually if sufficiently motivated, but this flow-chart gives a good, general, approach to follow. +The individual extractor parameters are given in the following table: -:py:class:`.Dodis` ------------------- -The Dodis extractor is a :term:`2-source randomness extractor`, meaning that it requires two independent bit -strings of randomness that only 'contain' entropy (as opposed to one or both being fully entropic). -It requires equal length inputs (:math:`n_1 = n_2`) that are prime with 2 as a primitive root (see :py:func:`.na_set` in glossary) -and outputs approximately :math:`m \approx k_1 + k_2 - n_1` when considering classical side information and :math:`m \approx \frac{1}{5}(k_1 + k_2 - n_1)`. -Our implementation of this extractor has near-linear computational complexity. - -This extractor is best suited to scenarios where a two-source extractor is required, -or a computationally efficient extractor considering classical side information only (then Dodis can be -used as a seeded extractor, giving approximately the same output length as Toeplitz, whilst reducing required seed size.) - -:py:class:`.Toeplitz` ---------------------- -The Toeplitz extractor is a :term:`seeded randomness extractor`, meaning that it requires two independent bit -strings of randomness, where one is already (near-)perfectly random (called a seed). -It requires a seed length of :math:`n_2 = n_1 + m - 1` -and outputs approximately :math:`m \approx k_1` when considering classical or quantum side information. -Our implementation of this extractor has near-linear computational complexity. -We also offer a two-source extension of this extractor, whereby the error scales with :math:`\epsilon \rightarrow 2^{n_2 - k_2} \epsilon`, -where :math:`n_2-k_2` is the difference between the seed length and the seed min-entropy. - -This extractor is best suited to scenarios where a computationally efficient seeded extractor is needed and security -against quantum side information. - -:py:class:`.Trevisan` ---------------------- -The Trevisan extractor is a :term:`seeded randomness extractor`, meaning that it requires two independent bit -strings of randomness, where one is already (near-)perfectly random (called a seed). -It requires a seed length of :math:`n_2 = O(\log_2 (n_1))` and outputs approximately :math:`m \approx k_1` when considering classical or quantum side information. -Our implementation of this extractor has :math:`O(n_1^2)` computational complexity. -We also offer a two-source extension of this extractor, whereby the error scales with :math:`\epsilon \rightarrow 2^{n_2 - k_2} \epsilon`, -where :math:`n_2-k_2` is the difference between the seed length and the seed min-entropy. - -This extractor is best suited to scenarios where only a seeded extractor is needed, but only a -small (in terms of length) seed is available as a resource. - -:py:func:`.von_neumann` ------------------------ -The Von-Neumann extractor is a :term:`deterministic randomness extractor`, meaning that it requires a -single input string of randomness that has some known (and specific) structure. -Our implementation of this extractor has linear computational complexity. - -This extractor is best suited to scenarios where a fast extractor is needed and the input has more structure than simply min-entropy. +.. image:: figures/Table.png + :width: 600 diff --git a/docs/index.rst b/docs/index.rst index a07a863..f8f3969 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,10 +1,9 @@ ========== -cryptomite +Cryptomite ========== -:py:mod:`cryptomite` is a modular, extensible high-level Python library -for randomness extractions, created by Quantinuum's Quantum Cryptography team. -At a high level, the library offers state-of-the-art randomness extractors that are easy to use, optimized and numerically precise +:py:mod:`Cryptomite` is a Python library of randomness extractors, created by Quantinuum's Quantum Cryptography team. +At a high level, the library offers state-of-the-art randomness extractors that are easy to use, optimized and numerically precise -- providing a trade-off of features that suits numerous practical use cases today. The performance critical parts of the library (e.g. NTT) are implemented in C++, but the rest of the @@ -20,13 +19,13 @@ To see the example notebooks, go to Examples. User Support ============ -If you need help with :py:mod:`cryptomite` or you think you have found a bug, please email +If you need help with :py:mod:`Cryptomite` or think you have found a bug, please email qcrypto@quantinuum.com. Licence ======= See `license `_ here. -In summary, you are free to use, modify and distribute to :py:mod:`cryptomite` +In summary, you are free to use, modify and distribute to :py:mod:`Cryptomite` for academic purposes. If you wish to use it for commercial use, contact qcrypto@quantinuum.com diff --git a/docs/intro.rst b/docs/intro.rst index 8708220..73ca86a 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -15,6 +15,6 @@ Recent years have seen major advances in theoretical and experimental quantum cr demonstrations and even commercialized products. All of these require a suitable randomness extractor with the appropriate implementation complexity, loss/error and security. -To facilitate these advances, we have developed :code:`cryptomite`, a software library with multiple randomness extractor implementations. +To facilitate these advances, we have developed :code:`Cryptomite`, a software library with multiple randomness extractor implementations. This software library offers state-of-the-art randomness extractors that are easy to use, optimized and numerically precise providing a trade-off of features that suits numerous practical use cases today. \ No newline at end of file diff --git a/docs/notebooks.rst b/docs/notebooks.rst index 2b412e8..7128931 100644 --- a/docs/notebooks.rst +++ b/docs/notebooks.rst @@ -3,7 +3,7 @@ Examples ======== -Here we give examples using ``cryptomite`` for the randomness extraction step in recent experimental quantum cryptography demonstrations, specifically, the tasks of +Here we give examples using ``Cryptomite`` for the randomness extraction step in recent experimental quantum cryptography demonstrations, specifically, the tasks of quantum key distribution and quantum random number generation. We also highlight some extensions in these examples, whereby the results of these previous works could be improved by some combination of (i) relaxing assumptions and (ii) speeding-up implementation. diff --git a/docs/performance.rst b/docs/performance.rst index dd3e5ad..e655404 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -1,8 +1,9 @@ Performance ========== -To demonstrate the capabilities of :py:mod:`cryptomite`, we perform some benchmarking on a MacBook Pro personal laptop (with 2 GHz quad-core Intel i5 processor with 16GB RAM). -The varying degrees of computational efficiency for the extractors of :py:mod:`cryptomite` are evidenced in the following Figure. +To demonstrate the capabilities of :py:mod:`Cryptomite`, we perform some bench-marking on a MacBook Pro personal laptop (with 2 GHz quad-core Intel i5 processor with 16GB RAM). +The speed (throughput) for the standard versions of :py:mod:`Cryptomite` extractors are evidenced in the following figure. +This testing is performed assuming that the min-entropy of the weak input is :math:`k_1 = n_1 / 2`. .. image:: figures/performance.png :width: 600 @@ -10,6 +11,6 @@ The varying degrees of computational efficiency for the extractors of :py:mod:`c Some observations performance observations are: * The :py:func:`.von_neumann` extractor is able to output at speeds above 7Mbit/s. -* The :py:class:`.Circulant`, :py:class:`.Dodis` and :py:class:`.Toeplitz` extractors are able to output at speeds of up to 1Mbit/s. The generation speed is faster for shorter input lengths. +* The :py:class:`.Circulant`, :py:class:`.Dodis` and :py:class:`.Toeplitz` extractors are able to output at speeds of up to 0.5Mbit/s. The generation speed is faster for shorter input lengths. * The :py:class:`.Trevisan` extractor can generate output at speeds comparable to the :py:class:`.Toeplitz` and :py:class:`.Dodis` extractors only when the input size is extremely short. * The :py:class:`.Trevisan` extractor unable to generate a non-vanishing bits/second rate for input lengths greater than approximately 30,000.