Source code for qkd_key_rate.utils.required_linktime

"""
Util functions for calculating the efficiency and communication of the
two error correction protocols Winnow and Cascade.
"""
# pylint: disable=invalid-name

from typing import Optional

import numpy as np

from tno.quantum.communication.qkd_key_rate.base.parity_strategy import (
    ERROR_RATES_TO_BLOCK_SIZES,
)
from tno.quantum.communication.qkd_key_rate.base.schedule import ERROR_RATES_TO_SCHEDULE

EFFICIENCY = {
    "winnow": {
        0.010: 0.90,
        0.020: 0.83,
        0.030: 0.80,
        0.040: 0.71,
        0.050: 0.65,
        0.060: 0.59,
        0.070: 0.54,
        0.080: 0.49,
        0.090: 0.44,
        0.100: 0.40,
        0.110: 0.34,
        0.120: 0.29,
        0.130: 0.27,
        0.140: 0.22,
        0.150: 0.19,
    },
    "cascade": {
        0.010: 0.83,
        0.020: 0.78,
        0.030: 0.73,
        0.040: 0.67,
        0.050: 0.63,
        0.060: 0.58,
        0.070: 0.55,
        0.080: 0.51,
        0.090: 0.47,
        0.100: 0.44,
        0.110: 0.39,
        0.120: 0.35,
        0.130: 0.32,
        0.140: 0.30,
        0.150: 0.27,
    },
}


[docs]def get_efficiency(method: str, error_rate: float) -> float: """Calculate the efficiency of the error correction protocol. Args: method: the error correction protocol (``'Winnow'`` or ``'Cascade'``) error_rate: estimated error rate Returns: Efficiency of the error correction protocol """ try: efficiency_dict = EFFICIENCY[method.lower()] except KeyError as exc: raise NameError("Unknown passed corrector-method.") from exc error_keys = efficiency_dict.keys() try: er = min(x for x in error_keys if x >= error_rate) except ValueError: # If the error-rate is above the maximum defined error rate, # set the efficiency to 0.20 return 0.20 return EFFICIENCY.get(er, 0.20)
[docs]def get_estimate_on_communication( method: str, error_rate: float, message_length: Optional[int] = None ) -> int: """Estimate on the number of communication rounds. Args: method: the error correction protocol (``'Winnow'`` or ``'Cascade'``) error_rate: the error rate message_length: Length of the message, only required for cascade protocol Returns: number of communication rounds. For the Cascade only a rough upper bound can be provided. """ if method.lower() == "winnow": error_keys = ERROR_RATES_TO_SCHEDULE.keys() try: er = min(x for x in error_keys if x >= error_rate) except ValueError as exc: raise ValueError("Error rate too high for secure protocol") from exc return 1 + 2 * sum(ERROR_RATES_TO_SCHEDULE[er]) if method.lower() == "cascade": # Only a loose estimate on the number of communications can be given. if message_length is None: raise ValueError("Message length needs to be provided for Cascade protocol") error_keys = ERROR_RATES_TO_BLOCK_SIZES.keys() try: er = min(x for x in error_keys if x >= error_rate) except ValueError as exc: raise ValueError("Error rate too high for secure protocol") from exc start_block_size = ERROR_RATES_TO_BLOCK_SIZES[er] number_of_passes = 8 block_sizes = [start_block_size * 2**i for i in range(number_of_passes)] max_sizes = np.repeat([message_length // 2], number_of_passes) block_sizes = np.vstack([block_sizes, max_sizes]).min(axis=0) max_number_of_communication_rounds = 1 + 2 * np.sum( [ np.sum(np.ceil(np.log2(block_sizes[: i + 1]))) for i in range(number_of_passes) ], dtype=int, ) return max_number_of_communication_rounds raise NameError("Unknown passed corrector-method.")