Source code for qkdsec.proofs.decoy_state
import math
from dataclasses import dataclass
[docs]
@dataclass
class DecoyBounds:
Y_0: float
Y_1_lower: float
Q_1_lower: float
e_1_upper: float
[docs]
def two_decoy_bounds(
mu_signal: float,
mu_decoy: float,
gain_signal: float,
gain_decoy: float,
gain_vacuum: float,
qber_decoy: float,
e_0: float = 0.5,
) -> DecoyBounds:
if not (mu_signal > mu_decoy > 0.0):
raise ValueError("require mu_signal > mu_decoy > 0")
mu = mu_signal
nu = mu_decoy
Y_0 = max(0.0, gain_vacuum)
Y_1_lower = (mu / (mu * nu - nu ** 2)) * (
gain_decoy * math.exp(nu)
- gain_signal * math.exp(mu) * (nu ** 2 / mu ** 2)
- ((mu ** 2 - nu ** 2) / mu ** 2) * Y_0
)
Y_1_lower = max(0.0, Y_1_lower)
Q_1_lower = mu * math.exp(-mu) * Y_1_lower
if Y_1_lower > 0.0:
e_1_upper = (
qber_decoy * gain_decoy * math.exp(nu) - e_0 * Y_0
) / (Y_1_lower * nu)
e_1_upper = max(0.0, min(0.5, e_1_upper))
else:
e_1_upper = 0.5
return DecoyBounds(
Y_0=Y_0,
Y_1_lower=Y_1_lower,
Q_1_lower=Q_1_lower,
e_1_upper=e_1_upper,
)