Protocol coverage
What runs, through which component, on which analysis. Grades: Validation. Refusals: Status and roadmap. Finite key per family: Security.
Three levels of reach
An engine is reached through a component tree (q.Link, q.Swap, q.PairLink), through a module taking its arguments by name (q.rates, q.security, q.dps, qkd.fock), or from qkd._core alone. Per engine: Architecture. q.ThresholdArray, q.PnrDetector and q.TransmittedLO construct and are refused by q.Link (refusals).
The two families
Balanced receivers (quadratures, covariance matrices, Devetak–Winter) and threshold detectors (clicks, collision probabilities, GLLP [GLLP04], phase-error bounds) share the RNG, the Wiener phase walk and the thermal-loss channel, never the accounting. Link refuses a mismatched modulation/security pair (Architecture, Security).
The matrix
| Protocol | Encoding | Detection | Security implemented | Reachable from |
|---|---|---|---|---|
| Gaussian modulation of coherent states | Gaussian in | homodyne or heterodyne | Devetak–Winter, asymptotic and Leverrier finite-size, trusted or untrusted | q.Link |
| Discrete modulation, | heterodyne | [DBL21] analytic bound, untrusted only; the relative-entropy proof, trusted or untrusted. Asymptotic, collective attacks | q.Link via q.PhaseShiftKeying, with q.Asymptotic or q.CertifiedBound | |
| Differential phase shift | phase between adjacent pulses | delay interferometer + two threshold detectors | Waks–Takesue–Yamamoto individual attacks | q.Link. Three-pulse blocks on photon-number-resolving detectors are a different protocol: q.dps |
| Round-robin differential phase shift | phase between a randomly chosen pair in a packet of | variable-delay interferometer + two threshold detectors | [SYK14]: privacy amplification from | q.rates.keyrate("rrdps", …) — no component tree |
| BB84 with weak coherent pulses | basis and bit, two intensities of decoy; carrier unnamed or polarisation | basis analyser + threshold detectors | GLLP with decoy-state | q.Link, closed form or sampled |
| Six-state | the same bits keyed into three mutually unbiased bases | the same | [S09] App. A: a tomographically complete Bell-diagonal estimate, asymptotic | q.Link via q.BasisKeying(bases=3) |
| SARG04 | the same four BB84 states, a non-orthogonal pair announced instead of a basis | the same | [FTL06] unconditional rate, paying privacy amplification on one- and two-photon signals — though the decoy layer bounds only | q.Link via q.BasisKeying(announce="pair") |
| Two-state keying (B92) | two non-orthogonal coherent states, one per bit | nulling receiver + one threshold gate | [TL04] on the plain branch, phase error derived; [K04] on the strong-reference branch, supplied. [TLKB09] derive it on a photon-number-resolving receiver: _core.b92_strong, no q. path | q.Link via q.TwoStateKeying |
| Coherent one way | intensity keying, data line plus monitoring tap, optional finite extinction | threshold detectors on both lines | phase-error form, with the bound supplied rather than derived | q.Link |
| COW′, the vacuum-decoy variant | the same, with the four-sequence monitoring record read exactly | the same | the exact worst case over every measurement consistent with the record, by semidefinite programme | q.rates.keyrate("cow-vacuum", …) — no component tree |
| Continuous-variable relay | two Gaussian senders into an untrusted relay | relay Bell measurement | Holevo bound on the conditioned two-sender state | q.Swap |
| Basis-keyed relay (MDI-BB84) | two decoy weak-coherent senders into an untrusted relay, key basis and test basis | relay Bell-state measurement, four threshold detectors | joint two-sender decoy | q.Swap with q.Relay(bell=q.BellAnalyser(…)) — below |
| Mode-pairing / asynchronous MDI | two independent weak-coherent senders, the two clicks that make a bit chosen after the announcement | single-photon interference at an untrusted station | [ZZWM22] asymptotic rate on a pairing rate and a sifted share | q.rates.keyrate("pairing", …) — no component tree |
| Entanglement-based basis keying | a photon-pair source, both parties measuring in two conjugate bases | threshold detectors at both ends, coincidence-counted | Shor–Preskill through basis symmetry, on the [MFL07] pair model | q.PairLink with q.SymmetryBound |
| CHSH-priced entanglement (E91) | the same pairs, a third analyser setting spent on a Bell test | the same | [A07]'s | q.PairLink with q.ViolationBound |
| Loss-tolerant source flaws | not a protocol — a reading of BB84's own data with a known modulator flaw | the same | [TCKLA14] exact phase-error inversion, beside the quantum-coin worst case it replaces | q.Link via q.FlawedKeying with q.FlawBound — below |
| Truncated-Fock states | not a protocol — the non-Gaussian state layer | — | not a security layer | qkd.fock |
Relay rows: Relay topologies. Fock row: Non-Gaussian states. Components are named for what the hardware does to the light; the acronyms live here.
| Component | Known in the literature as |
|---|---|
GaussianModulation | GG02, after Grosshans–Grangier 2002 |
PhaseShiftKeying | |
DifferentialPhase | DPS |
BasisKeying with a Decoy set | BB84-WCP |
BasisKeying(bases=3) | the six-state protocol |
BasisKeying(announce="pair") | SARG04 |
PolarisationKeying | BB84-WCP with its carrier named |
IntensityKeying | COW |
TwoStateKeying | B92; with reference=True, Koashi's strong-reference variant |
q.Swap | CV-MDI |
q.BellAnalyser with basis- or polarisation-keyed senders | MDI-QKD, MDI-BB84 |
q.TestBasisBound | the |
q.PairSource with q.SymmetryBound | BBM92, the entanglement-based BB84 |
q.PairSource with q.ViolationBound | E91, priced by the CHSH violation |
q.rates.keyrate("rrdps", …) | RRDPS |
q.rates.keyrate("pairing", …) | mode-pairing QKD, also published as asynchronous MDI-QKD |
q.SourceFlaw, q.FlawedKeying | loss-tolerant QKD with state-preparation flaws |
q.rates.keyrate("cow-vacuum", …) | COW′, the two-pulse vacuum-decoy variant |
Gaussian modulation
Devetak–Winter with reverse reconciliation, q.FiniteSize is accepted on this family alone.
Discrete modulation
dm_holevo takes
| Argument | Plane / units | Default | Description |
|---|---|---|---|
z | channel output, SNU | required | Off-diagonal block of the Alice–Bob matrix; carries its factor of cv_rate at |
bits | bits | required | Entropy of Alice's alphabet. No default: a covariance matrix carries no alphabet. |
| Quantity | Clamped? | Because |
|---|---|---|
| at zero, on output | ||
dm_holevo's key | no, as cv_rate | a negative value means no key |
| Property | What holds |
|---|---|
| Ordering in | the rate is |
| Mutual information | Gauss–Hermite quadrature over the real constellation, not dm_rate therefore returns slightly less than the papers it is checked against, whose own combination is the checked quantity |
The quadrature, and the order it is verified to
The node count tracks the modulation amplitude
| Nodes | Verified | |
|---|---|---|
| 16 | every constellation to | |
| 64 | at |
Operating points sit at dm_holevo, which never calls this quadrature.
Newton starts from Numerical Recipes' gauher guesses, which fail at high order:
| Order | Second root, against an independent bisection finder |
|---|---|
| 192 | wrong by |
| 194 | wrong by |
| 196 | wrong by |
| 200 | lands in the first root's basin; the positive half of the rule collapses onto a single point |
| 384 | first visible symptom — mutual() returns |
| Guard | |
|---|---|
| a sum-of-weights check | blind to this: the zeroth moment matched |
| root acceptance | Newton must converge and land in a bracket proven to hold one root; otherwise bisection. Bit-identical below order 188 |
| order cap | 370, checked at compile time against both node counts. Orders 2 to 370 agree with the independent finder to |
import qkd as q
res = q.Link(
modulation=q.PhaseShiftKeying(states=4, alpha=0.4),
channel=q.Channel(T=0.5, xi=0.01, ref="input"),
bob=q.Bob(detector=q.Heterodyne(eta=0.6, v_el=0.1, trusted=False)),
security=q.Asymptotic(beta=0.95),
).run()
res.explain["v_a"] # {'value': 0.32, 'label': 'derived'} 2 alpha^2
res.explain["bits"] # {'value': 2.0, 'label': 'derived'} log2 m
res.explain["z_star"] # the certified correlation
res.explain["z_gauss"] # what a Gaussian modulation would have certified
res.explain["i_ab_gauss"] # the log2(1 + SNR) substitute, kept beside i_abdm_rate coincides with the linear-objective SDP, falls short of the best known QPSK result where a nonlinear objective buys more, and tightens with q.CertifiedBound. Refused on this family — a trusted receiver on the analytic bound, homodyne, FiniteSize: roadmap.
Phase keying
A train of coherent pulses with random
A Mach–Zehnder has two 50:50 couplers, so the ports of slot
so the interferometric error is
The QBER is derived from DelayInterferometer.visibility, the Wiener walk over ClickDetector.dark (Architecture); worked link: Protocol layer.
Timing jitter is two things, and only one of them is a loss
| Symbol | Meaning |
|---|---|
| the arrival-time law | |
| symbol period, and the centred acceptance window | |
| the share of one slot's light collected by the window | |
| Window loss | detections in no window. A pure loss, indistinguishable from a smaller |
| Bin leak | detections in the wrong slot's window. The differential bit there is independent of this slot's, so half are errors |
Jitter convolves the port intensities along the slot train,
and
Gaussian, or tailed?
The prompt response — avalanche build-up, discriminator walk, clock distribution, optical pulse width — is Gaussian. A thick silicon SPAD also detects carriers photogenerated outside the high-field region, which diffuse in and arrive late by an exponential time, never early. The mixture is
with
A purely Gaussian jitter model produces window loss and no bin error: a core narrow enough for a realistic window loss puts the neighbouring slot tens of standard deviations away. Diamanti et al.'s two published window statements exclude it from the data side (Validation).
| Core FWHM, 1 GHz train | Neighbour offset | Bin leak |
|---|---|---|
0.0 as shipped | ||
| below | — | 0.0 by arithmetic, not a modelling cut |
| — |
jitter_split choice | Reason |
|---|---|
| the Gaussian core is integrated to | its density there is below 0.0 is the model, not an underflow (f64's smallest subnormal is |
eight-point Gauss–Legendre panels, not a rational erf | that erf's |
link = q.Link(
modulation=q.DifferentialPhase(mu=0.2),
channel=q.Fiber(length=100.0, alpha=0.2074),
bob=q.Bob(
detector=q.ClickDetector(
eta=0.004, # PRE-window: the gate's cost is derived
dark=3.5e-8,
jitter=79.3e-12, # Gaussian core, FWHM
window=100e-12, # acceptance window inside the 1 ns period
tail_frac=0.579, # weight of the diffusion tail
tail_time=295e-12, # its time constant
),
receiver=q.DelayInterferometer(delay=1, visibility=0.98),
),
alice=q.Alice(laser=q.Laser(linewidth=0.0), symbol_rate=1e9),
security=q.IndividualAttack(f=1.16),
)
res = link.run(symbols=1_000_000, seed=1)
res.explain["window_loss"] # {'value': 0.539783, 'label': 'derived'}
res.explain["bin_leak"] # {'value': 0.014951, 'label': 'derived'}eta is the efficiency before the gate; the window's cost is derived from the response. The two explain rows appear only when a response is described.
Jitter reaches the convolved slot train alone, as dead_time and afterpulse do, so it is refused beside a pinned IndividualAttack(qber=…) and on the decoy families. A window wider than the symbol period is refused.
Double clicks are a bit, not a discard
A slot where both detectors fire is kept and given a uniformly random bit (squashing), the coin drawn from the run's own Threefry stream so the result stays reproducible. Discarding it would let an adversary who provokes double clicks shape the sifted set. The coin is wrong half the time, worth roughly a factor of two on the DPS rate here.
The rate is the Waks–Takesue–Yamamoto individual-attack bound (Security).
Round-robin differential phase shift
Alice sends
The privacy amplification reads no observable. rrdps_leak(l, nu_th) is a function of the packet length and a photon-number threshold alone (against DPS and COW).
The price is sifting: a packet yields at most one bit, so every rate is divided by rrdps_optimum sweeps l_max and L_MAX is 4096, a train being
Three published assemblies of the same cost ship; they differ, and the literature quotes all three.
| Function | Assembly | Source |
|---|---|---|
rrdps_phase fed to | entropy form, the one the [SYK14] proof is printed in | [T15] Eqs. (3) and (4) |
rrdps_tag | GLLP tagging | [Z17] Eq. (12); the same expression is [Y18] Methods |
rrdps_gllp | per-photon-number tagging | [Z17] Eq. (13) |
rrdps_gllp rrdps_tag rrdps_phase
rrdps_collective is [Y18] Eq. (1): rrdps_leak's
Cut validity is the theorem; cut placement is a heuristic. Eq. (1) maximises a concave, positively homogeneous objective, so for any interior
The ascent picking bound - witness gap, never wrong. src/lp.rs certifies the same quantity from the same planes; a programme above the one-plane cap is refused as unresolved.
Field of rrdps_simplex | What it is |
|---|---|
bound | the certified upper bound on Eve's information — the number rrdps_collective returns |
witness | Eq. (1)'s objective where the ascent stopped. The maximum is at least this; it proves nothing and brackets from below |
tangent | the same bound from one plane, no solver |
steps, iters | ascent iterations and barrier Newton steps |
It refuses when the ascent does not close its bracket, when the programme fails to match the tangent cap, when the certified value fails to beat rrdps_leak, and when the bracket is wider than reltol. At rrdps_simplex(l, 1) reproduces the bisection to
q.rates.keyrate("rrdps", …) selects the assembly by cost: "entropy", "tagged" and "resolved" are the three above, "collective" is rrdps_collective. [MSK19]'s refined bound is the shape taking p_src, q and e_bit in place of the receiver model. rrdps_counts gives rrdps_rate assembles the rate in bits per pulse.
Basis keying with weak coherent pulses
BB84 on an attenuated laser. Poissonian pulses carry two or more photons at some rate, which a photon-number-splitting adversary takes for free. The GLLP rate concedes them, pays privacy amplification on single-photon detections only, and charges error correction against the whole sifted gain:
The decoy layer
Alice varies the intensity between a signal
The inversion is protocol-blind: BB84-WCP, six-state and SARG04 consume the same
The sampled pulse train
The bound consumes gains and error rates, produced two ways. decoy_gain, the default, integrates the Poisson photon-number distribution against the detector yields in closed form. alice=q.Alice() on a basis-keyed link samples instead: pulses at one of three intensities reach two threshold detectors behind the basis analyser, are sifted, and the gains and error rates are divided out of integer counts. Both feed decoy_bounds and bb84_rate.
res = q.Link(
modulation=q.BasisKeying(
decoy=q.Decoy(intensities=(0.48, 0.1, 0.0), probs=(0.8, 0.15, 0.05)),
),
channel=q.Fiber(length=25.0, alpha=0.21),
bob=q.Bob(
detector=q.ClickDetector(eta=0.045, dark=8.5e-7),
receiver=q.BasisAnalyser(misalign=0.033),
),
security=q.SplittingAttack(f=1.22),
alice=q.Alice(),
).run(symbols=2_000_000, seed=5)
res.explain["stages"] # 'pulse train + sifting'
res.qber # counted, not integrated
res.sifted, res.doubles # exact integers| Quantity | Closed form | Sampled |
|---|---|---|
| Background | ClickDetector.dark | one dark gate per detector, |
| Gain | clicks / pulses sent, per intensity | |
| Error rate | errors / sifted, per intensity | |
| Double clicks | not represented | counted, kept, and given a uniformly random bit |
| Sifting | a factor | a Bernoulli thinning of the clicks, checked by sift_rate |
The sampled path is BB84's alone (Protocol layer).
ClickDetector.dark is Link derives dark. [MQZL05]'s q.Link reproduces their
The two paths agree at
the double-count correction decoy_gain keeps and [MQZL05] drop. test_dark_convention in test/discrete.py asserts both directions.
| Case, at | QBER |
|---|---|
| closed form, | |
| sampled, | |
| closed form handed | |
| GYS hardware, | the gap is eleven orders below the gain |
A finite sample's numbers are kept as measured: a vacuum arm with no click reports a gain of zero, which decoy_bounds reads as a smaller single-photon yield. Decoy.probs exists because the weakest arm's count sets the bound's precision.
Six-state keying
q.BasisKeying(bases=3) keys the bits into three mutually unbiased qubit bases [B98]. Bob flips his bit when he measured
Three bases make the channel estimate tomographically complete; that is the advantage. A Bell-diagonal state has four weights. BB84 measures two error rates and leaves Eve one free parameter; six-state measures three and fixes all four. sixstate_bell is that inversion —
Eve's Holevo information is bb84_rate and sixstate_rate differ in one factor. The Bell-diagonal parametrisation is [RGK05] Eq. (10); unconditional security is [L01].
Eq. (A4) runs, not Eq. (A5). Same quantity, but (A5) divides by
sixstate_eve(e_x, e_y, e_z) is not symmetric: the key basis is Z, the third slot, and only sixstate_holevo(Q) is the depolarising case decoy_bounds returning one
res = q.Link(
modulation=q.BasisKeying(
decoy=q.Decoy(intensities=(0.48, 0.1, 0.0)), bases=3
),
channel=q.Fiber(length=25.0, alpha=0.21),
bob=q.Bob(
detector=q.ClickDetector(eta=0.045, dark=8.5e-7),
receiver=q.BasisAnalyser(misalign=0.033),
),
security=q.SplittingAttack(f=1.22),
).run()
res.key_rate # 5.221e-04, against BB84's 6.670e-04 on the same span
res.explain["sift"] # {'value': 0.3333..., 'label': 'pinned'}
res.explain["chi_e1"] # {'value': 0.1712, 'label': 'derived'} Eve, at e1test_third_basis_pays in test/protocols.py asserts both directions: at an equal sifting factor six-state gives strictly more key on the same decoy bounds; at the uniform factors, sift towards 1; q.BasisKeying(bases=3, sift=0.81) pins one. Refused on this branch: Protocol layer, roadmap.
SARG04
q.BasisKeying(announce="pair") sends the four BB84 states and changes only the classical post-processing [SARG04]. Alice announces one of four non-orthogonal pairs containing the state she sent; Bob keeps the round only when his outcome is orthogonal to one member, excluding it and naming the other. A BB84 rig runs SARG04 unchanged.
Sifting is
The unconditional rate is [FTL06] Eq. (39), on the Bell-diagonal relations of their Theorems 1 and 2 (Eqs. (9) and (10)), after [TL06]. The detector model, yields and gains are their Eqs. (40)–(43).
Both privacy-amplification terms have a domain neither equation states. Past it,
| Cutoff | Why there |
|---|---|
| two-photon, | the stationarity condition of Eq. (10)'s minimisation puts the root of |
| single-photon, | three independent statements: $H(Z_1 |
Neither cutoff refuses its argument, so a distance sweep runs through both (Validation); each returns the value that credits zero. Uncut, the single-photon term returns
res = q.Link(
modulation=q.BasisKeying(
decoy=q.Decoy(intensities=(0.16, 0.1, 0.0)), announce="pair"
),
channel=q.Fiber(length=25.0, alpha=0.21),
bob=q.Bob(
detector=q.ClickDetector(eta=0.045, dark=8.5e-7),
receiver=q.BasisAnalyser(misalign=0.033),
),
security=q.SplittingAttack(f=1.22),
).run()
res.key_rate # 4.275e-05
res.qber # 0.06256, the error rate on CONCLUSIVE rounds
res.explain["sift"] # {'value': 0.2665, 'label': 'derived'} -- 0.25 + e_det/2
res.explain["q2"] # {'value': 0.0, 'label': 'absent'}q2 is reported absent: nothing in the decoy layer bounds test_two_photon_absent in test/protocols.py asserts that the infinite-decoy sarg_yield computes that limit, which [FTL06] take explicitly; no finite-decoy
sarg_ceiling is not a security bound: [BGKS05] Eq. (106), an upper bound over a restricted class of incoherent attacks, with no decoy states, no dark counts, no limiting distance, and three corrections its authors name dropped. It scales as test/sarg.py.
Two-state keying
q.TwoStateKeying sends q.NullingReceiver (Protocol layer).
| Branch | Phase error | Source |
|---|---|---|
reference=False, the default | derived from the loss, the overlap and the observed bit error | [TL04], extending the loss-free proof of [TKI03] |
reference=True | supplied, on q.DiscriminationBound(e_phase=…), and labelled pinned as cow_rate's is | [K04], implicit over a virtual entanglement picture, as is [TLKB09] Eq. (15) over experimental bounds; neither collapses to a closed form in |
The unambiguous-discrimination boundary is where the rate dies
USD breaks the protocol only past the loss at which Eve can run it and still meet Bob's expected count, test_usd_boundary in test/b92.py and test/protocols.py pins that nothing raises.
b92_limit(L, f_ec) returns the largest depolarising rate at which plain B92 distils key, and the overlap attaining it.
| Depolarising limit at | Overlap | [TL04] Fig. 2 | |
|---|---|---|---|
| " | |||
| " | |||
| " |
Their Fig. 2(b) plots the square
The one seam, stated plainly
[TL04] is a single-photon proof; b92_detect is a coherent-state receiver. b92_point's plain branch takes the overlap from b92_plain has no seam: single-photon source, their channel, bound and rate.
b92_ceiling charges the multiphoton pulses the proof does not model: Eve takes the b92_point returns b92_optimum crossing follows the ceiling down to zero.
The reference branch's p_fil is test/b92.py's receiver (
res = q.Link(
modulation=q.TwoStateKeying(mu=0.23), # Koashi's optimum, overlap 0.6313
channel=q.Channel(T=0.8),
bob=q.Bob(
detector=q.ClickDetector(eta=1.0, dark=1e-8),
receiver=q.NullingReceiver(visibility=0.995),
),
security=q.DiscriminationBound(f=1.16),
).run()
res.key_rate # 0.1016
res.qber # 0.003522
res.explain["overlap"] # 0.6313, derived
res.explain["e_phase"] # 0.1352, DERIVED on the plain branch
res.explain["discrimination"] # 0.3687 -- the transmittance USD takes over at
res.explain["ceiling"] # the beam-splitting capA supplied e_phase on the plain branch is a floor under the derived bound (test_supplied_floor); explain()["e_phase_floor"] reads absent or pinned. Refused: Protocol layer.
Polarisation encoding
BasisKeying leaves the carrier open and takes the analyser's misalignment as given. PolarisationKeying names the carrier: fibre birefringence rotates the polarisation, which Bob reads as basis misalignment.
Both bases are linear and turn by the same angle under a rotation of the linear axes, so one angle serves the protocol. A Jones rotation by
Three contrasts multiply. Adding error rates would double-count events where both flip and push the total past
| Contrast | Form | Notes |
|---|---|---|
| analyser optics | BasisAnalyser.misalign, a property of the receiver | |
| frame drift | ||
| PMD | normalised field overlap of the two principal states for a Gaussian envelope of intensity rms width mode_overlap at equal widths, as a first-order fringe contrast must be. Evaluated at the worst input polarisation |
The reference-frame tracking model
The two models take disjoint parameters.
tracking | Reads | Contrast | |
|---|---|---|---|
"tracked" | drift | ||
"free" | rate interval |
The free-running form is the time average of tracking has no permissive default.
q.Link(
modulation=q.PolarisationKeying(
decoy=q.Decoy(intensities=(0.48, 0.1, 0.0)),
frame=q.ReferenceFrame(drift=0.05),
),
channel=q.Fiber(length=25.0, alpha=0.21),
bob=q.Bob(
detector=q.ClickDetector(eta=0.045, dark=8.5e-7),
receiver=q.BasisAnalyser(misalign=0.033),
),
security=q.SplittingAttack(f=1.22),
).run()
# qber 0.0354 against 0.0330, and 89.8% of the key rate| Reported | Label |
|---|---|
misalign_optics | pinned, at the analyser's value |
pol_contrast, misalign | derived |
tracking, drift (or drift_rate and drift_interval), dispersion, pulse_width, dgd | the inputs that produced them |
The rotation is of the linear axes. A fibre's birefringence is an arbitrary bases and announce are not fields here: six-state and SARG04 run through q.BasisKeying.
Intensity keying
Coherent one way encodes the bit in which slot of a pair is empty.
| Slot pair | Meaning |
|---|---|
| (empty, pulse) | logical 0 |
| (pulse, empty) | logical 1 |
| (pulse, pulse), a small fraction | decoy sequence, sent to a monitoring interferometer measuring coherence between adjacent non-empty pulses |
No active basis choice and no phase modulator on the data line. Its security analysis was revised:
| Original (Stucki et al.; Branciard, Gisin and Scarani) | After the sequential zero-error attack | |
|---|---|---|
| Eve bounded through | monitoring-line coherence | the phase error, supplied rather than derived |
| Rate scaling | linear in | |
| Reach | hundreds of kilometres | below decoy BB84 at range |
| Due to | — | [GTWC20]; [TC21] |
COW's signal states are linearly independent and its vacuum slots break coherence across the sequence, so Eve discriminates blocks unambiguously and resends them separated by vacuum, holding both the data-line error rate and the monitoring visibility at their unattacked values while knowing the key. qkd implements the [G22] phase-error form,
so e_phase is an input on q.Link.
| Function | What it is |
|---|---|
cow_rate | the phase-error form above; reads e_phase and never a visibility |
cow_visibility | from the two monitoring detectors; not wired into cow_rate, a visibility of 1 being consistent with a full zero-error attack. A hardware diagnostic |
cow_ceiling | the model-independent limit |
The sequential-attack bound's cap on e_phase.
Finite modulator extinction
Intensity modulators reach IntensityKeying.extinction is the dB figure, None by default. The on slot keeps
The data line
The empty slot clicks with
| Outcome | Probability | Error |
|---|---|---|
| signal slot alone clicks | ||
| empty slot alone clicks | always | |
| both slots click |
giving
Ambiguous slots get a random bit, as on the phase-keyed path.
The coherence check
The fringe does not move. A coherence check sits where both sides carry signal pulses, so the measured visibility, cow_visibility, is what a perfect modulator gives. What changes is the light it covers: a monitoring sequence emits
cow_monitor returns the pair. e_phase stays supplied.
The residual raises the gain, to which a key rate is proportional, so counting only the extra clicks would report more key for a worse modulator.
extinction | gain | monitored | rate vs ideal | ||
|---|---|---|---|---|---|
None | |||||
Parameterisation, from test/discrete.py: data line at
COW′ and the semidefinite programme
src/sdp.rs solves
every block dense, symmetric and single-digit. Method, refusals and the other two solvers: roadmap, Security.
What it buys COW′
COW′ is the two-pulse vacuum-decoy variant. Its four sequences have overlaps fixed by sdp_phase. The problem is [SP26] Sec. VI D, replacing the analytic estimator of [G22] Eqs. (7) and (12), shipped as sdp_analytic.
The SDP cannot be looser than Cauchy–Schwarz, which maximises over a superset of the measurements the record allows; test_below_analytic in test/sdp.py would catch a sign or index slip in the assembly.
Reach against the source is a declared miss.
The relative-entropy proof for discrete modulation
dm_secure in src/dmcs.rs, on the complex-Hermitian numerics of src/herm.rs, implements both steps of [WLC18] for protocol 2 — heterodyne, reverse reconciliation — of [LUL19].
| Field | What it is |
|---|---|
upper | step 1, Frank–Wolfe over |
bound | step 2, Theorem 3 linearised at the step-1 state and dualised; the proof |
key | bound - p_pass * delta_ec, unclamped — a negative value is how far past the working distance the point sits |
viol, zeta | Theorem 3's |
The dual point is certified by its spectrum, not by the Cholesky that accepted it: the least eigenvalue is measured and the point shifted down until positive. Limits and reach: roadmap.
q.CertifiedBound(cutoff=…) stands for q.Asymptotic on a q.PhaseShiftKeying link, or is called directly. certify(modulation, eta, xi) is untrusted: eta is the total transmittance from Alice's output to Bob's measurement, xi the input-plane excess noise in the closed form's folding, certify_trusted(modulation, eta, xi, eta_d, v_el) is [LL20]: eta the channel alone, the receiver's eta_d and v_el apart. Both misuses are the referring-plane error: a bare span transmittance in certify() overstates the rate; a folded one in certify_trusted() counts the loss twice.
The linear programme
src/lp.rs solves _core.lp_dual and reached by nothing in qkd/. Error side and assembly trap: roadmap.
| Consumer | What it bounds |
|---|---|
mdi_program, mdi_disturb | MDI-BB84's |
rrdps_simplex, rrdps_collective | [Y18] Eq. (1) past one photon, certifying the tangent planes an ascent placed |
| mode pairing | nothing. src/pairing.rs does not import it |
The postselection technique
The lift from an IID-collective proof to a coherent-attack one, for permutation-invariant protocols on finite-dimensional systems, wired to nothing (roadmap). [CKR09] Theorem 1 is the original; what runs is [NTZLT24] Corollary 3.1.
ps_lift returns two costs as separate fields.
| Cost | What it does |
|---|---|
| the factor | multiplies a failure probability, upward. It does not scale a key rate |
| subtracts from the key length in bits |
It errs toward the larger epsilon, the larger ps_secrecy implements [NTZLT24]'s sum with the square root, never [CKR09]'s max, which is strictly smaller at every admissible allocation and so under-reports the failure probability; no argument produces it.
The epsilon the lift demands is usually not representable in f64, so the budget side is in logarithms. At [NTZLT24]'s worked point — 0.0 reads as unconditional security. ps_budget returns ps_thirds allocates in ps_epsilon, the one function forming a probability, refuses a lifted epsilon at or above 1.
| Condition | |
|---|---|
| C1 permutation invariance | enforceable by prepending a public random permutation of the rounds, at about |
| C2 finite dimension | failed by every optical protocol, on both sides (roadmap) |
| C3 a fixed marginal | built from the source description, extending the technique to prepare-and-measure protocols; [CKR09]'s results are entanglement-based only |
| C4 an IID proof of the right shape | a proof already stated against general attacks has no such decomposition; its epsilon fed here bounds nothing while looking conservative |
ps_family refuses every shipped family, naming the condition each fails (per family). The lift removes one assumption and adds device assumptions on the way in, so it is no step toward device independence.
The entropic uncertainty relation
Nothing in qkd/ reaches it: eur_family refuses every shipped protocol, naming the condition each fails.
Three statements, one chain, three different quantities.
| Statement | Scope | Here |
|---|---|---|
| [MU88] — | a memoryless adversary | eur_quality, eur_conjugate, eur_misalign compute |
| [B10] — | collective attacks, in their words | eur_memory, and eur_asymptotic for the two-adversary form through Devetak–Winter. Not a coherent-attack number |
| [TR11] Theorem 1 — | coherent attacks | eur_smooth. Reaches them with no de Finetti reduction, no postselection technique and no asymptotic equipartition step |
The key length is [TLGR12] Eq. (2) — the smooth relation for eur_length is that formula and eur_secret is it behind the family gate.
Which side it errs on. eur_quality takes an upper bound on eur_smooth and eur_length refuse a result not below eur_length saturates at
The continuous-variable branch. [F14] give the overlap of position and momentum bins of widths eur_binned ships
that at
Two conventions. [F14] prints the constant twice, inconsistently — Results as eur_binned(1, 1) is
Entanglement-based basis keying
A photon-pair source sends one photon of each pair to each party; both measure in two conjugate bases, and the key rides on the coincidences. Nothing is modulated or prepared. The source may sit anywhere between the labs and is never trusted: Alice and Bob certify the state by measuring in both bases.
| Component | q.PairSource(brightness=…, rate=…, pumping="pulsed"), run through q.PairLink |
| Source model | two independent two-mode squeezers, one per encoding mode pair: negative-binomial pair number, mean q.gaussian.Epr(r)'s |
| Rate | |
| derived from hardware, their Eqs. (9) and (10), not dialled | |
| Security | q.SymmetryBound, or q.ViolationBound. Asymptotic only |
Where the source lives is the result
channels=(alice's arm, bob's arm) states the position. There is no site= field, which could disagree with it.
At constant total fibre on [MFL07] Table 1 hardware (
| Source at | Zero-key crossing |
|---|---|
| the midpoint | 308.1 km |
| the quarter point | 241.5 km |
| a party's lab | 183.0 km |
The gain depends on the product of the two arms, so this is no
A midpoint source is not the relay. A relay moves the detectors to the middle and buys detector side-channel immunity; a pair source moves the source and buys source-trust immunity, its detectors staying in the threat model.
E91: pricing Eve by the violation
E91 [E91] is the protocol above with a third setting spent on a CHSH test. q.ViolationBound puts the observed violation where q.SymmetryBound puts a phase error; that substitution is the difference.
q.SymmetryBound (BBM92) | q.ViolationBound (E91) | |
|---|---|---|
| Eve priced by | the phase error, under a characterised-qubit assumption | the observed CHSH magnitude, with no assumption about the source state |
| Bound | [MFL07], basis symmetry | [A07]: |
| Zero-key error rate, | ||
| Defaults | e_phase=None, taking the bit error; f=1.22; sift=0.5 | s and source required; f=1.22; sift=2/9 — Ekert's six settings drawn uniformly, two of the nine pairs coinciding and carrying the key |
The violation is never the cheaper price, and the test_price_is_worse in test/protocols.py asserts the ordering on the same coincidences.
With trusted, characterised analysers E91's key rate is pair_rate [BBM92], and ekert_point returns both numbers (Architecture).
[E91]'s Eq. (3) sign convention makes ekert_rate takes the magnitude. His Eq. (7),
source= is how the engine says this is not device independence
q.ViolationBound.source has no default: it decides whether the number is a bound.
source | What happens |
|---|---|
"measured" | the rate is returned, and it is a collective-attack bound given that estimate |
"modelled" | refused. An ekert_chsh, pair_chsh, a visibility — prices one assumed state and bounds no unknown one. That model is the device-dependent assumption the CHSH bound avoids, so reading it as security is circular. ekert_point computes that number under its own label |
"device-independent" | refused, naming three missing pieces — the tight bound beyond CHSH, entropy accumulation for coherent attacks, and an q.ClickDetector's default |
| anything else | refused, listing the three read |
res = q.PairLink(
source=q.PairSource(brightness=0.01),
detectors=(q.ClickDetector(eta=0.2, dark=1e-6),
q.ClickDetector(eta=0.2, dark=1e-6)),
channels=(q.Fiber(length=10.0), q.Fiber(length=10.0)),
security=q.ViolationBound(s=2.7, source="measured"),
).run()
res.key_rate # 3.093e-05
res.e_phase # None -- the violation stands where one would
res.explain["e_phase"] # {'value': None, 'label': 'absent'}
res.explain["chsh"] # 2.5965, labelled 'diagnostic'
res.explain["key_symmetry"] # what basis symmetry would have paid
res.explain["device_independent"] # False, labelled 'structural'qkd.pairs.chsh(v) models source="modelled" refuses. A violation past Tsirelson's bound is refused; one at or below 2 buys no key,
Published device-independent demonstrations: [N22] over 2 m of trapped-ion separation; [L26], 624 hours for 1.2 million heralded pairs at 11 km.
Basis keying into an untrusted midpoint
MDI-BB84. Alice and Bob send decoy weak coherent pulses, a bit in one of two conjugate bases. An untrusted station interferes the arrivals on a balanced coupler, splits each output on a polarising beamsplitter, reads four threshold detectors and announces which pair fired together: a Bell-state projection, revealing neither bit. Detector side channels leave the threat model; the proof never assumes the station behaved.
| State | asymptotic, or a finite-key length under q.TestBasisBound(block=q.RelayBlock(…)). q.BellDetector on the relay gives the continuous-variable midpoint, q.BellAnalyser this one. Composes inside q.Network |
| Reached from | q.Swap(alice=…, bob=…, relay=q.Relay(bell=q.BellAnalyser(…)), channels=…, security=q.TestBasisBound(f=…)), with q.BasisKeying(decoy=…, sift=1.0) on both senders (why) |
| Defaults | q.TestBasisBound(f=1.16, block=None); block=None is the asymptotic rate |
| Exams | MDI · Forward, MDI · Decoy, MDI · Anchors, MDI · Parts, MDI · Guards |
The rate
[XCQL13] Eq. (1):
| Symbol | What it is |
|---|---|
gain of rounds where each sender emitted one photon, both in the key basis, and the station announced: mdi_gain | |
| that pair's error rate in the test basis, standing in for the key basis's phase error | |
| key-basis gain and QBER at the signal intensities, observed | |
| error-correction inefficiency, |
| Three ways to get this wrong | |
|---|---|
| Per pulse pair, not per pulse | |
| No sifting prefactor | bb84_rate's explicit |
| The two error rates are in different bases | privacy amplification pays on bb84_rate is not reused: its signature cannot say which basis each argument came from |
[MR12]'s single-photon-source rate, test_single_photon asserts the reduction.
The two bases are different physics
Only the test basis needs indistinguishable arrivals. The polarising beamsplitters separate rectilinear signals, which never interfere, so interference enters the key basis only through dark counts.
| Key basis (rectilinear) | Test basis (diagonal) | |
|---|---|---|
| Forward model | mdi_rect, [MR12] Eqs. (51)–(54) | mdi_diag, their Eqs. (35) and (39) |
| Hong–Ou–Mandel indistinguishability | not needed | required |
| QBER with no dark counts | exactly | |
| Announcement rate | — | twice the key basis's in the weak-signal limit: it accepts the multiphoton coincidences the polarising beamsplitters reject |
A test-basis QBER near 25% is the protocol working: two independent coherent sources have uncorrelated multiphoton content, and [T14] measure about 26% beside a key-basis QBER under 0.5%. The decoy layer recovers q.BellAnalyser carries two misalignments, misalign and misalign_test; one number for both overstates a midpoint rate. The four- and seven-intensity protocols give the two bases different intensities for this reason.
The decoy layer is two-dimensional
Both senders vary intensity independently, so the unknown is a matrix decoy_bounds cannot reach it.
mdi_y11 implements [XCQL13]'s three-intensity analytic bound over a
Two of the nine cells are unread by mdi_y11 | the closed form uses the vacuum row and column, the decoy block and the signal-signal cell, not (signal_a, decoy_b) or (decoy_a, signal_b). mdi_program reads all nine as a linear programme over the truncated src/lp.rs and bounds tighter; mdi_disturb is its twin over q. path |
| Infeasible data |
A numerical trap, and where it bites
[MR12]'s Eq. (35) bracket,
each bracket summed from its series with the leading terms removed before they form, as relay.rs's h_ent and std.rs's g_ent are. The limit then holds to
The repeaterless bound has the same trap: 0.0 by 176 dB. Use -log1p(-eta)/ln 2. Mode pairing's source paper prints the literal form.
What it refuses
| Refused | Why |
|---|---|
| An intensity ladder that does not decrease strictly | equal settings put a zero in the bound's denominator |
| A gain grid that is not nine cells | it is row-major with Alice's intensity as the row, and is never reshaped |
| an inverted decoy bound, not rescaled | |
A decoy setting at or below its own vacuum, in mdi_e11 | the same denominator |
A trusted= flag anywhere on q.BellAnalyser | structural: an untrusted midpoint has no trusted variant |
An e_phase on q.TestBasisBound | nothing to supply: unlike q.PhaseBound, the test basis measures it |
Finite-size security from q.Swap | runs. q.TestBasisBound(block=q.RelayBlock(…)) reaches _core.mdi_length — [C14], with the analytical two-decoy estimation, Serfling's sampling transfer and Claim 3 across all six branches. It reads the q.Decoy weights, the basis bias from q.BasisKeying(bias=…), and the code-string share from q.RelayBlock(code=…). Refused instead: a block with no bias=, and a bias= with no block |
Mode pairing
Two weak-coherent senders into one untrusted single-photon-interference station; the two clicks forming a key bit are chosen after the announcement. [ZZWM22]: Eq. (4) the pairing rate, Eq. (7) the key rate, Eqs. (90)–(104) the forward model. Also published as asynchronous MDI-QKD; the phase-drift model behind the pairing window is [X21] Sec. III.
Not twin-field QKD, and not covered by that exclusion: it shares the
Why the scaling changes. Alice and Bob emit independently; the station announces which rounds clicked; only then are two clicked rounds paired into a bit. A round succeeds on its own, not jointly with a partner fixed in advance, so a pair arrives at span, the maximal pairing interval, buys this: at span = 1 the scheme is time-bin MDI-QKD and the exponent returns to 1. On [X21] Table 1 hardware (span span
| Quantity | What it is | Trap |
|---|---|---|
pairing_pairs, | pairs per round | carries the whole transmittance scaling |
pairing_sift, | fraction of those pairs that are usable Z-pairs | |
pairing_single, | fraction of sifted signal pairs whose two non-empty slots each held one photon | a fraction, not a gain: mdi_gain's Poisson prefactor is already taken, and applying it again charges the source twice |
pairing_rate; swapped, the result is wrong by the channel loss and still looks like a key rate.
The phase error is not computed here: [ZZWM22] Eq. (104) takes mdi_yield's second return at mdi_yield follows [MR12].
pairing_length implements [X21]'s key-length equation and fluctuation appendix, and pairing_yield the one decoy step that transfers. Two links of the chain are absent and no linear programme retires either: pairing_bases has no setting for. The programme's own constraint row is upstream too: its equalities are pairing-resolved gains pairing_click takes one intensity with the four patterns at a quarter apiece. On pairing_yield the closed form is the vertex: lp_dual climbs to it from below, relative
Loss-tolerant source flaws
A reading of BB84's data when Alice's phase modulator applies
flaw_tolerant reads the phase error exactly; flaw_standard bounds it through a quantum coin and returns the coin imbalance in that slot (Security). At
flaw_triangle is the spanning condition as a number:
flaw_direct measures the two virtual states, which Alice never sends: not a protocol step but the arbiter flaw_phase is checked against. [TCKLA14]'s theorem is that the two agree; test_theorem_exact in test/flaws.py pins them to
Scope, the refusal to compose with qkd.attacks and the unreconciled line of [TCKLA14] Appendix C: Security, roadmap.
[TCKLA14] Appendix C prints
Detector attacks
Mechanisms and sources: Security; module: Impairments. Mismatch is also Makarov, Anisimov & Skaar, Phys. Rev. A 74, 022313 (2006). mismatch_rate is Fung, Tamaki, Qi, Lo & Ma, QIC 9, 131 (2009), arXiv:0802.3788, Eq. (33) with the data-discarding argument and Eq. (34) as their general estimate.
Post-processing
Three quantities kept apart, bridge(), pick()'s refusal and tabulated Cascade efficiency: Architecture, Usage. Not modelled: slice reconciliation, BICONF, polar and rateless codes, and ETSI key-delivery accounting.
Settled exclusions
Four settled exclusions: Status and roadmap.
What is not implemented
Refused capabilities: roadmap. Not implemented and stated nowhere else:
| Not implemented | |
|---|---|
| A composable CV proof against general attacks | the Gaussian de Finetti arithmetic ships (roadmap). On test/keyrate.py's link it moves the minimum viable block from about |
| Four- and seven-intensity MDI protocols | Zhou, Yu & Wang, PRA 93, 042324 (2016); Wang, Xu & Lo, PRX 9, 041012 (2019). The three-intensity bound ships |
| Entanglement-based CV-QKD as a protocol | the EPR picture only derives the prepare-and-measure bound; q.PairLink shares none of that machinery |
| Source-side flaws beyond a modulator angle | correlated pulses and intensity-setting errors. probe_rate refuses a Trojan-horse key rate naming four missing pieces, the first being that q.Decoy sets its intensities with a modulator behind the very isolators the bound prices, spending one isolation budget twice |
| Field-level simulation of the basis-keyed train | the sampled path reduces each pulse to a detection probability: no interferometer, no phase walk, no detector memory |
| Squashing / basis-independent detector models | the click family works from click probabilities directly |
Where these live
Link refuses a security model that does not belong to the modulation:
q.Link(
modulation=q.BasisKeying(decoy=q.Decoy(intensities=(0.5, 0.1, 0.0))),
channel=q.Fiber(length=50.0),
bob=q.Bob(detector=q.ClickDetector(), receiver=q.BasisAnalyser()),
security=q.Asymptotic(),
).run()
# NotImplementedError: BasisKeying takes SplittingAttack securityEntry point per engine: Architecture.
See the component reference for what each component takes.
References
| [A07] | Acín, Brunner, Gisin, Massar, Pironio & Scarani, Phys. Rev. Lett. 98, 230501 (2007) |
| [B92] | Bennett, Phys. Rev. Lett. 68, 3121 (1992) |
| [B98] | Bruß, Phys. Rev. Lett. 81, 3018 (1998) |
| [B10] | Berta, Christandl, Colbeck, Renes & Renner, Nature Physics 6, 659 (2010), arXiv:0909.0950 |
| [BBM92] | Bennett, Brassard & Mermin, Phys. Rev. Lett. 68, 557 (1992) |
| [BGKS05] | Branciard, Gisin, Kraus & Scarani, Phys. Rev. A 72, 032301 (2005) |
| [C14] | Curty, Xu, Cui, Lim, Tamaki & Lo, Nat. Commun. 5, 3732 (2014) |
| [CKR09] | Christandl, König & Renner, Post-selection technique for quantum channels with applications to quantum cryptography, Phys. Rev. Lett. 102, 020504 (2009), arXiv:0809.3019 |
| [DBL21] | Denys, Brown & Leverrier, Quantum 5, 540 (2021) |
| [E91] | Ekert, Phys. Rev. Lett. 67, 661 (1991) |
| [F14] | Furrer, Berta, Tomamichel, Scholz & Christandl, J. Math. Phys. 55, 122205 (2014), arXiv:1308.4527 |
| [FTL06] | Fung, Tamaki & Lo, Phys. Rev. A 73, 012337 (2006), arXiv:quant-ph/0510025 |
| [G22] | Gao et al., Opt. Express 30, 23783 (2022), arXiv:2107.09329 |
| [GLLP04] | Gottesman, Lo, Lütkenhaus & Preskill, QIC 5, 325 (2004) |
| [GTWC20] | González-Payo, Trényi, Wang and Curty, PRL 125, 260510 (2020) |
| [K04] | Koashi, Phys. Rev. Lett. 93, 120501 (2004), arXiv:quant-ph/0403131 |
| [L01] | Lo, Quant. Inf. Comput. 1, 81 (2001) |
| [L15] | Leverrier, Phys. Rev. Lett. 114, 070501 (2015), arXiv:1408.5689 |
| [L17] | Leverrier, Phys. Rev. Lett. 118, 200501 (2017), arXiv:1701.03393 |
| [L26] | Lu et al., Science (2026), 10.1126/science.aec6243 |
| [LL20] | Lin & Lütkenhaus, Phys. Rev. Applied 14, 064030 (2020), arXiv:2006.06166 |
| [LUL19] | Lin, Upadhyaya & Lütkenhaus, PRX 9, 041064 (2019), arXiv:1905.10896 |
| [LWLC24] | Lu, Wang, Li & Cao, arXiv:2401.01727 |
| [MFL07] | Ma, Fung & Lo, Phys. Rev. A 76, 012307 (2007) |
| [MQZL05] | Ma, Qi, Zhao and Lo |
| [MR12] | Ma & Razavi |
| [MSK19] | Matsuura, Sasaki & Koashi, Phys. Rev. A 99, 042303 (2019), arXiv:1812.10916 |
| [MU88] | Maassen & Uffink, Phys. Rev. Lett. 60, 1103 (1988) |
| [N22] | Nadlinger et al., Nature 607, 682 (2022) |
| [NTZLT24] | Nahar, Tupkary, Zhao, Lütkenhaus & Tan, Postselection technique for optical Quantum Key Distribution with improved de Finetti reductions, PRX Quantum 5, 040315 (2024), arXiv:2403.11851 |
| [P09] | Pironio, Acín, Brunner, Gisin, Massar & Scarani, New J. Phys. 11, 045021 (2009) |
| [PCT19] | Pereira, Curty & Tamaki, npj Quantum Information 5, 62 (2019), arXiv:1902.02126 |
| [RGK05] | Renner, Gisin & Kraus, Phys. Rev. A 72, 012332 (2005) |
| [S09] | Scarani, Bechmann-Pasquinucci, Cerf, Dušek, Lütkenhaus & Peev, Rev. Mod. Phys. 81, 1301 (2009) |
| [SARG04] | Scarani, Acín, Ribordy & Gisin, Phys. Rev. Lett. 92, 057901 (2004) |
| [SP26] | Seksaria & Prabhakar, Short reach by theorem: the certifiable key rate of COW QKD (2026) |
| [SYK14] | Sasaki, Yamamoto & Koashi, Nature 509, 475 (2014) |
| [T14] | Tang et al., Phys. Rev. Lett. 113, 190501 (2014) |
| [T15] | Takesue, Sasaki, Tamaki & Koashi, Nature Photonics 9, 827 (2015), arXiv:1505.07914 |
| [TC21] | Trényi and Curty, NJP 23, 093005 (2021) |
| [TCKLA14] | Tamaki, Curty, Kato, Lo & Azuma, Phys. Rev. A 90, 052314 (2014), arXiv:1312.3514 |
| [TKI03] | Tamaki, Koashi & Imoto, Phys. Rev. Lett. 90, 167904 (2003) |
| [TL04] | Tamaki & Lütkenhaus, Phys. Rev. A 69, 032316 (2004), arXiv:quant-ph/0308048 |
| [TL06] | Tamaki & Lo, Phys. Rev. A 73, 010302(R) (2006) |
| [TLGR12] | Tomamichel, Lim, Gisin & Renner, Nature Communications 3, 634 (2012), arXiv:1103.4130 |
| [TLKB09] | Tamaki, Lütkenhaus, Koashi & Batuwantudawe, Phys. Rev. A 80, 032302 (2009) |
| [TR11] | Tomamichel & Renner, Phys. Rev. Lett. 106, 110506 (2011), arXiv:1009.2015 |
| [UvHLL21] | Upadhyaya, van Himbeeck, Lin & Lütkenhaus, PRX Quantum 2, 020325 (2021), arXiv:2101.05799 |
| [WLC18] | Winick, Lütkenhaus & Coles, Quantum 2, 77 (2018), arXiv:1710.05511 |
| [X21] | Xie, Lu, Weng, Zhang et al., Breaking the rate-loss bound of quantum key distribution with asynchronous two-photon interference, arXiv:2112.11635 |
| [XCQL13] | Xu, Curty, Qi and Lo, New J. Phys. 15, 113007 (2013) |
| [Y18] | Yin, Wang, Chen, Han, Wang, Guo & Han, Nature Communications 9, 457 (2018) |
| [Z17] | Zhang, Yuan, Cao & Ma, New J. Phys. 19, 033013 (2017), arXiv:1505.02481 |
| [ZZWM22] | Zeng, Zhou, Wu & Ma, Mode-pairing quantum key distribution, Nat. Commun. 13, 3903 (2022), arXiv:2201.04300 |