Skip to content

Commit

Permalink
Improve docs (#7)
Browse files Browse the repository at this point in the history
* add figures and update docs

* update code annotation
  • Loading branch information
cforeman-cqc authored Jan 15, 2024
1 parent 39f9069 commit e0f0013
Show file tree
Hide file tree
Showing 12 changed files with 37 additions and 168 deletions.
2 changes: 1 addition & 1 deletion cryptomite/circulant.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""
Expand Down
2 changes: 1 addition & 1 deletion cryptomite/dodis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""
Expand Down
2 changes: 1 addition & 1 deletion cryptomite/toeplitz.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
109 changes: 11 additions & 98 deletions cryptomite/trevisan.py
Original file line number Diff line number Diff line change
@@ -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
----------
Expand All @@ -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)
2 changes: 2 additions & 0 deletions docs/bibliography.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://arxiv.org/pdf/1212.0520.pdf>`_, Pre-print (2012)
.. [Dodis2004] Y. Dodis, A. Elbaz, R. Oliveira, and R. Raz, `Improved randomness extraction from two independent sources <https://link.springer.com/chapter/10.1007/978-3-540-27821-4_30>`_ 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)
Binary file added docs/figures/Table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/extractor_flow_chart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 10 additions & 56 deletions docs/gettingstarted.rst
Original file line number Diff line number Diff line change
@@ -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

11 changes: 5 additions & 6 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 <https://github.com/CQCL/cryptomite/blob/main/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

Expand Down
2 changes: 1 addition & 1 deletion docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
2 changes: 1 addition & 1 deletion docs/notebooks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 4 additions & 3 deletions docs/performance.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
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

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.

0 comments on commit e0f0013

Please sign in to comment.