qkd_key_rate.protocols.quantum.bb84 module

Classes to perform key error rate estimate for the BB84 QKD protocol.

This code is based on TNO’s BB84 key-rate paper (doi: 10.1007/s11128-021-03078-0):

Quantum Key Distribution (QKD) protocols rely on an entangled photon source that produces entangled photon pairs, which are distributed over two parties. Both parties randomly choose one of two predefined measurement bases. As the photons are entangled, non-random results will only be obtained for specific combinations of basis choices. Detection events are sifted, where only the detection events corresponding to events where both parties measured in an appropriate basis should be kept. Part of the resulting sifted key is made public which can be used to estimate the key error rate.

The famous BB84 protocol by Charles Bennett and Gilles Brassard for establishing a secure key between two parties, usually called Alice and Bob. Alice prepares a quantum state in one of four ways, and Bob measures the quantum state in one of two ways. Based on the way of measuring alone, both Alice and Bob can establish a key (assuming noiseless operations). Classical post-processing routines can correct potential errors still occurring and can detect eavesdroppers.

We consider three cases:

  • Fully Asymptotic Key Rate

    Both the number of pulses and the number of used decoy states is infinite. Because of the asymptotic number of pulses and decoy states, we can simplify the computations and instead work with a single intensity setting which we vary.

  • Asymptotic Key Rate

    Only the number of pulses is asymptotic, the number of decoy states is finite and chosen by the user. We have to optimize the probabilities for the X- and Z-basis for each intensity setting. So with two additional decoy states, we have three intensity settings to optimize and six probabilities in total. We use linear programs (LPs) for this.

  • Finite Key Rate:

    Both the number of pulses and the number of decoy states is finite and chosen by the user. The approach is similar to the asymptotic key rate module, however we have to take finite-key effects into account. We compute bounds on the effect of the finite key size and we use security parameters to impose a degree of certainty of these bounds.

Typical usage example:

from tno.quantum.communication.qkd_key_rate.protocols.quantum.bb84 import (
    BB84FullyAsymptoticKeyRateEstimate,
)
from tno.quantum.communication.qkd_key_rate.test.conftest import standard_detector

detector_Bob = standard_detector.customise(
    dark_count_rate=1e-8,
    polarization_drift=0,
    error_detector=0.1,
    efficiency_party=1,
)

fully_asymptotic_key_rate = BB84FullyAsymptoticKeyRateEstimate(detector=detector_Bob)
mu, rate = fully_asymptotic_key_rate.optimize_rate(attenuation=0.2)
class qkd_key_rate.protocols.quantum.bb84.BB84AsymptoticKeyRateEstimate(detector, number_of_decoy=2, **kwargs)[source]

Bases: AsymptoticKeyRateEstimate

The situation for an asymptotic number of pulses.

We consider a fixed number of intensities (number_of_decoy + 1)

__init__(detector, number_of_decoy=2, **kwargs)[source]
Parameters:
  • detector (Detector) – The detector used at Bob’s side

  • number_of_decoy (int) – Number of decoy intensities used

compute_last_positive_distance(x)[source]

Computes the last positive distance.

The optimization routine sometimes considers a parameter setting outside of the valid region. This function is used to push the parameters back to the valid regime.

Return type:

float

compute_rate(mu, attenuation)[source]

Computes the key-rate given intensity-settings and an attenuation

Parameters:
  • mu (ArrayLike) – Intensity

  • attenuation (float) – Attenuation

Return type:

float

Returns:

Key-rate

optimize_rate(*, attenuation, x_0=None, bounds=None)[source]

Function to optimize the key-rate

For certain input parameters it can happen that the resulting lp problem is unfeasible. In that case the attenuation is slightly modified (+1e-6) in an attempt to obtain a feasible lp problem that can be solved.

Parameters:
  • attenuation (float) – Loss in dB for the channel

  • x_0 (Optional[ArrayLike]) – Initial search value, default midpoint search bounds

  • bounds (Optional[List[ArrayLike]]) – Bounds on search range

Return type:

Tuple[ndarray[Any, dtype[float64]], float]

Returns:

Optimized intensity and key-rate

Raises:
  • ValueError – When x_0 or bounds are given with invalid dimensions.

  • ValueError – when the found key-rate is negative.

  • OptimizationError – When lp solver is unsuccessful due to infeasible problem. Multiple attempts are made with slightly modified attenuation before error is raised.

class qkd_key_rate.protocols.quantum.bb84.BB84FiniteKeyRateEstimate(detector, number_of_pulses=1000000000000.0, number_of_decoy=2, **kwargs)[source]

Bases: FiniteKeyRateEstimate

The situation for a finite number of pulses

A fixed number of intensities is considered. The probabilities for both bases might vary.

__init__(detector, number_of_pulses=1000000000000.0, number_of_decoy=2, **kwargs)[source]
Parameters:
  • detector (Detector) – The detector used at Bob’s side

  • number_of_pulses (Optional[int]) – Number of pulses sent

  • number_of_decoy (Optional[int]) – Number of decoy intensities used

compute_last_positive_distance(x)[source]

Computes the last positive distance.

The optimization routine sometimes considers a parameter setting outside of the valid region. This function is used to push the parameters back to the valid regime.

Return type:

float

compute_rate(mu, attenuation, probability_basis_X, probability_basis_Z, n_X=None)[source]

Compute the key-rate for a specific set of parameters

Parameters:
  • mu (ArrayLike) – Used intensities

  • attenuation (float) – Attenuation of the channel

  • probability_basis_X (ArrayLike) – Probabilities for each intensity in the X-basis

  • probability_basis_Z (ArrayLike) – Probabilities for each intensity in the Z-basis

  • n_X (Optional[int]) – Number of pulses in the X-basis.

Return type:

float

Returns:

key-rate

optimize_rate(*, attenuation, x_0=None, bounds=None)[source]

Function to optimize the key-rate

The laser intensities should be ordered and the probabilities should sum to one. Probabilities for both X and Z-basis are considered simultaneously. We consider the Z-basis for error estimation and the X-basis for key-rate estimation, so no sifting rate is considered.

For certain input parameters it can happen that the resulting lp problem is unfeasible. In that case the attenuation is slightly modified (+1e-6) in an attempt to obtain a feasible lp problem that can be solved.

Parameters:
  • attenuation (float) – Loss in dB for the channel

  • x_0 (Optional[ArrayLike]) – Initial search value

  • bounds (Optional[List[ArrayLike]]) – Bounds on search range

  • args – Other variables to be optimized, for instance the attenuation

Return type:

Tuple[ndarray[Any, dtype[float64]], float]

Returns:

Optimized x=[intensity, probability_basis_X, probability_basis_Z] and found optimal key-rate

Raises:
  • ValueError – When x_0 or bounds are given with invalid dimensions.

  • ValueError – when the found key-rate is negative.

  • OptimizationError – When lp solver is unsuccessful due to infeasible problem. Multiple attempts are made with slightly modified attenuation before error is raised.

class qkd_key_rate.protocols.quantum.bb84.BB84FullyAsymptoticKeyRateEstimate(detector, **kwargs)[source]

Bases: AsymptoticKeyRateEstimate

The situation for an asymptotic number of intensity settings and pulses.

In the fully asymptotic case we only have to consider a single intensity

__init__(detector, **kwargs)[source]
Parameters:
  • detector (Detector) – The detector used at Bob’s side

  • kwargs – Protocol specific input

compute_rate(mu, attenuation)[source]

Computes the key-rate given an intensity and an attenuation.

Only the vacuum states and single photon states can be safely used. The error rate for vacuum states is 0.5. For single photon states we must upper bound it.

Parameters:
  • mu (ArrayLike) – Intensity

  • attenuation (float) – Attenuation

Return type:

float

Returns:

Key-rate

optimize_rate(*, attenuation, x_0=None, bounds=None)[source]

Function to optimize the key-rate

Parameters:
  • attenuation (float) – Loss in dB for the channel

  • x_0 (Optional[ArrayLike]) – Initial search value, default value [0.5] is chosen.

  • bounds (Optional[List[ArrayLike]]) – Bounds on search range, default [(0.1, 0.9)]

Raises:
  • ValueError – When x_0 or bounds are given with invalid dimensions.

  • ValueError – when the found key-rate is negative.

Return type:

Tuple[ndarray[Any, dtype[float64]], float]

Returns:

Optimized intensity and key-rate

exception qkd_key_rate.protocols.quantum.bb84.OptimizationError[source]

Bases: ValueError

Raised when optimization is unsuccessful. This error typically thrown when the lp problem is infeasible.

qkd_key_rate.protocols.quantum.bb84.bound_f(number_of_pulses, probability, epsilon)[source]

Computes a bound used in the finite key-rate computations.

Parameters:
  • number_of_pulses (int) – Number of pulses considered

  • probability (float) – Probability of the event for which the bound-term is computed

  • epsilon (float) – Security-parameter

Return type:

float

qkd_key_rate.protocols.quantum.bb84.compute_gain_and_error_rate(detector, mu, attenuation)[source]

Computes the total gain and error rate of the channel

Parameters:
  • detector (Detector) – The used detector on Bob’s side

  • mu (ArrayLike) – Intensities of the laser

  • attenuation (float) – Loss of the channel

Return type:

Tuple[ndarray[Any, dtype[float64]], ndarray[Any, dtype[float64]]]

Returns:

  • The gain per intensity. The probability of an event, given a pulse.

  • The error rate per intensity.

qkd_key_rate.protocols.quantum.bb84.delta(n_x, n_z, e1)[source]

Computes a bound based on the number of pulses sent in both bases and an epsilon-security value.

Parameters:
  • n_x (int) – Number of pulses in the X-basis

  • n_z (int) – Number of pulses in the Z-basis

  • e1 (float) – Epsilon-security parameter

Return type:

float

qkd_key_rate.protocols.quantum.bb84.delta_ec(p_abort, n_x)[source]

Computes a bound on the losses due to error correction.

Parameters:
  • p_abort (float) – Abort probability, used if there are too many errors

  • n_x (int) – Number of pulses in the X-basis

Return type:

float

qkd_key_rate.protocols.quantum.bb84.ensure_probability(p)[source]

Ensure that we have a probability between zero and one. Other functions will otherwise throw an error.

Parameters:

p (float) – Probability to be mapped to range \([0, 1]\).

Return type:

float

Returns:

Probability

qkd_key_rate.protocols.quantum.bb84.lower_bound_matrix_gain(max_num_photons, mus)[source]

Computes a lower bound on the likeliness of the number of photons per intensity

Parameters:
  • max_num_photons (int) – Maximum on the number of photons per pulse to consider

  • mus (Union[List, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) – All used intensities

Return type:

float

qkd_key_rate.protocols.quantum.bb84.solve_finite_lp(target_vacuum, target_single, probabilities_intensity_j, mu, max_num_photons, number_of_pulses, observed_count, epsilon_mu_j, epsilon_num_photons_M, epsilon_num_photons_M_in_basis_B)[source]

Solves the linear program (LP) for the finite case.

Parameters:
  • target_vacuum (float) – Coefficient for the vacuum state term

  • target_single (float) – Coefficient for the single photon state terms

  • probabilities_intensity_j (Union[List[float], _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) – Probability for each decoy state

  • mu (Union[List[float], _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) – The used intensity

  • max_num_photons (int) – The number of photons at which the sums are cut

  • number_of_pulses (int) – Number of pulses sent in specific basis

  • observed_count (ArrayLike) – Number of pulses observed in specific basis per intensity

  • epsilon_mu_j (Union[List[float], _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) – Epsilon terms for the intensities

  • epsilon_num_photons_M (Union[List[float], _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) – Epsilon terms for the number of photons

  • epsilon_num_photons_M_in_basis_B (Union[List[float], _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) – Epsilon terms for the number of photons in basis B

Return type:

OptimizeResult

Returns:

Number of usable pulses

The variables in the LP are
  • \(n_0\): Number of vacuum pulses

  • \(n_1\): Number of single photon pulses

  • \(\ldots\)

  • \(n_M\): Number of pulses with M pulses

  • \(\delta_{j,1}\): Deviation for intensity 1

  • \(\delta_{j,2}\): Deviation for intensity 2

  • \(\ldots\)

  • \(\delta_{j,m}\): Deviation for intensity m

qkd_key_rate.protocols.quantum.bb84.solve_lp(target_vacuum, target_single, mu, program_coefficients, max_num_photons)[source]

Solves the linear program (LP) for the asymptotic case.

Parameters:
  • target_vacuum (float) – Coefficient for the vacuum state term

  • target_single (float) – Coefficient for the single photon state terms

  • mu (Union[List, ndarray[Any, dtype[float64]]]) – The used intensity

  • program_coefficients (Union[List, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) – The coefficients in the LP, e.g., gain, error-rate or their product

  • max_num_photons (int) – The number of photons at which the sums are cut

Raises:

OptimizationError in case no solution was found for the LP.

Return type:

OptimizeResult