Reconciliation Namespace

This namespace provides classes and functions for information reconciliation in Continuous Variable Quantum Key Distribution (CV-QKD) systems. The reconciliation process involves comparing correlated observations between two parties and correcting errors.

The reconciliation process consists of the following steps:

  1. Random Number Generation: The QRNG class is simulates the random number generation to be used as the raw key material.

  2. Multi-dimensional Reconciliation: The MDR class performs multi-dimensional reconciliation.

  3. Error Correction: The decoder class corrects the errors in key bits using the syndrome of the algorithm to correct the errors in the key bits.

  4. Cyclic Redundancy Check(CRC): The CRC class calculates the CRC of the key bits. Parties can verify key bit correctness by comparing CRCs.

The reconciliation functions are used as helpers in the process.

Reverse Reconciliation

The reconciliation::reconcile() function implements reverse reconciliation as in Fig. 1 , allowing the user to perform the reconciliation of correlated observations between parties directly.

_images/RR.png

Fig. 1 The reverse reconciliation algorithm employing multi-dimensional reconciliation (MDR). RNG, LLR and H stand for random number generator, log-likelihood ratio and parity check matrix of the code respectively. x and y are the correlated observations of the parties.

Classes

Decoder Class

The decoder class implements a mechanism for decoding key bits using their corresponding syndrome. The key features of the decoder class are as follows:

  • Forward Error Correction Code: Uses a rate-adaptive, protograph-based, raptor-like LDPC (Low-Density Parity-Check) code [CS24].

  • Decoding Algorithm: Utilizes the sum-product algorithm for efficient decoding.

  • Update Schedules: Supports both flooding and layered node update approaches.

  • Rate Range: Designed to accommodate coding rates between 0.01 and 0.2.

  • Performance: With the fast decoder option that uses look-up table in the decoding, the decoder achieves high performance with reduced decoding time.

class decoder

This class is used to decode LDPC codes using the sum-product algorithm (SPA).

Public Functions

decoder(size_t NoI = 500, bool layered_flag = true, bool fast_flag = true, const std::string &H_file_name = PCM_NAME, int lifting_factor = 5000, bool print_flag = false)

Construct a new decoder object.

Parameters:
  • NoI – Maximum number of iterations for the SPA decoder, default = 500

  • layered_flag – Flag to indicate whether to use layered decoding or not, default = true

  • fast_flag – Flag to indicate whether to use the fast decoder or not, default = true

  • H_file_name – Name of the file containing the LDPC code parity-check matrix, default is defined in CMakelists.txt file

  • lifting_factor – Lifting factor of the LDPC code, default = 5000

  • print_flag – Flag to indicate whether to print the statistics report or not, default = false

size_t get_N() const

Get the Blocklength of the codeword.

Returns:

size_t Blocklength of the codeword

size_t get_M() const

Get the number of check nodes in the LDPC code.

Returns:

size_t Number of check nodes

void set_rate(double rate)

Set the code rate.

Parameters:

rate – Code rate

double get_rate() const

Get the code rate.

Returns:

rate Code rate

template<typename T>
std::vector<uint8_t> get_syndrome(const T &word) const

Calculate the syndrome of a given word.

Parameters:

word – Codeword

Returns:

std::vector<uint8_t> Syndrome of the word

template<typename T1, typename T2>
std::tuple<std::vector<uint8_t>, int, bool> SPA_decoder(const T1 &llr_in, const T2 &syndrome) const

Decode the received LLRs using the SPA.

Parameters:
  • llr_in – Received LLRs

  • syndrome – Syndrome of the received codeword

Returns:

std::tuple<std::vector<uint8_t>, int, bool> Tuple containing the decoded codeword, the number of iterations taken to decode the codeword, and a flag indicating whether the decoder converged to a codeword or not

template<typename T1, typename T2>
int get_decoding_error_count(const T1 &decoded_message, const T2 &true_message) const

Calculate the number of bit errors between the decoded word and the true codeword.

Parameters:
  • decoded_message – Decoded word

  • true_message – True codeword

Returns:

int Number of bit errors

Private Functions

double tanh_lookup(double a) const

Lookup table implementation of the hyperbolic tangent function.

Parameters:

a – Input to the hyperbolic tangent function

Returns:

double Output of the hyperbolic tangent function

double atanh_lookup(double a) const

Lookup table implementation of the inverse hyperbolic tangent function.

Parameters:

a – Input to the inverse hyperbolic tangent function

Returns:

double Output of the inverse hyperbolic tangent function

void read_H(const std::string &H_file_name)

Read the LDPC code parity-check matrix from a file.

Parameters:

H_file_name – Name of the file containing the LDPC code parity-check matrix

Private Members

std::vector<size_t> CN_degrees

Vector of the degrees of each check node

std::vector<size_t> Connected_VNs

Vector of the variable node indices connected to each check node

size_t max_CN_degree

Maximum degree of the check nodes in the LDPC code

size_t number_of_VNs

Number of variable nodes in the LDPC code

std::vector<double> tanh_table

Lookup table for the hyperbolic tangent function

std::vector<double> atanh_table

Lookup table for the inverse hyperbolic tangent function

size_t N

Blocklength of the codeword

size_t M

Number of check nodes in the LDPC code

size_t max_iter

Maximum number of iterations for the SPA decoder

double rate

Code rate. It must be between 0.2 and 0.01.

int lifting_factor

Lifting factor of the LDPC code

double inverse_stepsize_tanh

Inverse of the step size used for the tanh lookup table

double inverse_stepsize_atanh

Inverse of the step size used for the atanh lookup table

bool fast_decoder

Flag to indicate whether to use the LUT for the decoding or not

bool print_flag

Flag to indicate whether to print the decoding results or not

bool layered_flag

Flag to indicate whether to use the layered decoding or not

MDR Class

The MDR class implements multi-dimensional reconciliation as described in [LAB08]. The key features of the MDR class are as follows:

  • Dimensionality: Supports multi-dimensional reconciliation with dimensions ranging from 1 to 8.

  • Implementation: Uses Cayley-Dickson construction for rotations in higher dimensions.

class MDR

This class is used to perform multi-dimensional reconciliation (MDR).

Public Functions

MDR(int dim = 8, bool print_flag = false)

Construct a new MDR object.

Parameters:
  • dim – Dimension of the MDR, default = 8

  • print_flag – Flag to indicate whether to print the statistics report or not, default = false

std::vector<double> normalize(std::vector<double> &x) const

Normalize the input vector.

Parameters:

x – Input vector

Returns:

std::vector<double> Normalization vector

template<typename T1, typename T2>
std::vector<double> multiplication_Alice(const T1 &channel_message, const T2 &q_states) const

Perform the MDR multiplication at Alice’s side.

Parameters:
  • channel_message – Channel message

  • q_states – Quantum states

Returns:

std::vector<double> MDR output at Alice’s side

template<typename T1, typename T2>
std::vector<double> multiplication_Bob(const T1 &received_quantum_states, const T2 &QRNG_output_bipolar) const

Perform the MDR multiplication at Bob’s side.

Parameters:
  • received_quantum_states – Received quantum states

  • QRNG_output_bipolar – QRNG output in bipolar form

Returns:

std::vector<double> MDR output at Bob’s side

Private Functions

template<typename T>
std::vector<double> compute_higher_dimension_conjugate(const T &x) const

Compute the higher dimension conjugate of a vector.

Parameters:

x – Input vector

Returns:

std::vector<double> Higher dimension conjugate of the input vector

std::vector<double> compute_cayley_dickson_construction(const std::vector<double> &x, const std::vector<double> &y) const

Compute the Cayley-Dickson construction of two vectors.

Parameters:
  • x – First input vector

  • y – Second input vector

Returns:

std::vector<double> Cayley-Dickson construction of the two input vectors

Private Members

size_t dimension

Dimension of the MDR

bool print_flag

Flag to indicate whether to print the statistics report or not

CRC Class

The CRC class calculates the CRC of the key bits. The key features of the CRC class are as follows:

  • Verification: Parties can verify the correctness of key bits by comparing CRCs.

  • Implementation: Uses the CRC-32 algorithm for error detection [MFZ18].

class CRC

This class is used to calculate the cyclic redundancy check (CRC) of a message.

Public Functions

explicit CRC(uint32_t polynomial = 0xEDB88320)

Construct a new CRC object.

Parameters:

polynomial – Generator polynomial of the CRC, default = 0xEDB88320

template<typename T>
std::vector<int> get_CRC_checksum(const T &data)

Calculate the CRC checksum of a message.

Parameters:

data – Message

Returns:

std::vector<int> CRC checksum of the message

Private Members

uint32_t poly

Generator polynomial of the CRC

QRNG Class

class QRNG

This class is used to simulate quantum random number generator (QRNG) output.

Public Functions

QRNG(size_t seq_length, size_t NoF, bool print_flag = false)

Construct a new QRNG object.

Parameters:
  • seq_length – Length of the QRNG sequence

  • NoF – Number of frames

  • print_flag – Flag to indicate whether to print the statistics report or not, default = false

std::vector<std::vector<int8_t>> generate_random_sequence()

Generate a random sequence of bits using the QRNG.

Returns:

std::vector<std::vector<int8_t>> QRNG output

Public Members

size_t sequence_length

Length of the QRNG sequence

size_t num_of_frames

Number of frames

bool print_flag

Flag to indicate whether to print the statistics report or not

Private Functions

std::mt19937 generate_randomly_seeded_engine()

Generate a randomly seeded Mersenne Twister engine.

Returns:

std::mt19937 Randomly seeded Mersenne Twister engine

Functions

namespace reconciliation

Functions

std::vector<double> binary_to_bipolar(const std::vector<std::vector<int8_t>> &QRNG_output, const size_t N, const size_t num_of_decoding_frames, const int MDR_dim = 8)

Convert a binary vector to a bipolar vector.

Parameters:
  • QRNG_output – Binary vector

  • N – Blocklength of the codeword

  • num_of_decoding_frames – Number of frames

  • MDR_dim – Dimension of the MDR, default = 8

Returns:

std::vector<double> Bipolar vector

std::vector<std::vector<double>> get_LLR(std::vector<double> synthetic_channel_output, const std::vector<double> &alice_normalization_vector, const std::vector<double> &bob_normalization_vector, double noise_variance, int MDR_dim, size_t num_of_decoding_frames, int N, bool print_flag = false)

Calculate the log-likelihood ratio (LLR) values from the synthetic channel output.

Parameters:
  • synthetic_channel_output – Synthetic channel output

  • alice_normalization_vector – Normalization vector at Alice’s side

  • bob_normalization_vector – Normalization vector at Bob’s side

  • noise_variance – Noise variance of the channel

  • MDR_dim – Dimension of the MDR

  • num_of_decoding_frames – Number of frames

  • N – Blocklength of the codeword

  • print_flag – Flag to indicate whether to print the statistics report or not, default = false

Returns:

std::vector<std::vector<double>> LLR values

template<typename T>
std::vector<std::vector<uint8_t>> get_CRC_values(const std::vector<std::vector<T>> &decoded_frame, CRC &crc, size_t num_of_decoding_frames)

Calculate the CRC values of the decoded frames.

Parameters:
  • decoded_frame – Decoded frames

  • crc – CRC object

  • num_of_decoding_frames – Number of frames

Returns:

std::vector<std::vector<uint8_t>> CRC values of the decoded frames

std::tuple<double, int> check_CRC(const std::vector<std::vector<uint8_t>> &CRC_decoded, const std::vector<std::vector<uint8_t>> &CRC_QRNG, const std::vector<int> &syndrome_flags, utilities::statistics &stats, size_t num_of_decoding_frames, bool print_flag = false)

Check the CRC values of the decoded frames against the CRC values of the QRNG output.

Parameters:
  • CRC_decoded – CRC values of the decoded frames

  • CRC_QRNG – CRC values of the QRNG output

  • syndrome_flags – Flags indicating whether the decoder converged to a codeword or not

  • stats – Statistics object

  • num_of_decoding_frames – Number of frames

  • print_flag – Flag to indicate whether to print the statistics report or not, default = false

Returns:

std::tuple<double, int> Number of CRC mismatches and the number of undetected errors

std::vector<std::vector<uint8_t>> calculate_syndrome(const decoder LDPC_decoder, const std::vector<std::vector<int8_t>> &QRNG_output, const size_t num_of_decoding_frames, bool print_flag = false)

Calculate the syndromes of the QRNG output.

Parameters:
  • LDPC_decoder – LDPC decoder object

  • QRNG_output – QRNG output

  • num_of_decoding_frames – Number of frames

  • print_flag – Flag to indicate whether to print the statistics report or not, default = false

Returns:

auto Syndromes of the QRNG output

utilities::statistics reconcile(const std::vector<double> &alice_states_input, const std::vector<double> &bob_states_input, const double rate, const double noise_variance, const size_t NoI = 500, const int MDR_dim = 8, bool layered_flag = true, bool fast_flag = true, bool print_flag = false, const std::string H_file_name = PCM_NAME, int lifting_factor = 5000)

Sample uniform numbers to be used as raw key material, perform multi-dimensional reconciliation (MDR) and error correction, and check the CRC values of the decoded frames.

Parameters:
  • alice_states_input – Alice’s quantum states

  • bob_states_input – Bob’s quantum states

  • rate – Code rate

  • noise_variance – Noise variance of the channel

  • NoI – Maximum number of iterations for the SPA decoder, default = 500

  • MDR_dim – Dimension of the MDR, default = 8

  • layered_flag – Flag to indicate whether to use layered decoding or not, default = true

  • fast_flag – Flag to indicate whether to use the fast decoder or not, default = true

  • print_flag – Flag to indicate whether to print the statistics report or not, default = false

  • H_file_name – Name of the file containing the LDPC code parity-check matrix, default is defined in CMakelists.txt file

  • lifting_factor – Lifting factor of the LDPC code, default = 5000

Returns:

utilities::statistics Statistics object containing the simulation results

template std::vector< uint8_t > decoder::get_syndrome< std::vector< uint8_t > > (const std::vector< uint8_t > &) const
template std::vector< double > MDR::compute_higher_dimension_conjugate< std::vector< double > > (const std::vector< double > &) const
template std::vector< int > CRC::get_CRC_checksum< std::vector< uint8_t > > (const std::vector< uint8_t > &)
template std::vector< std::vector< uint8_t > > get_CRC_values< uint8_t > (const std::vector< std::vector< uint8_t >> &, CRC &, size_t)
class CRC
#include <CRC.hpp>

This class is used to calculate the cyclic redundancy check (CRC) of a message.

class decoder
#include <decoder.hpp>

This class is used to decode LDPC codes using the sum-product algorithm (SPA).

class MDR
#include <MDR.hpp>

This class is used to perform multi-dimensional reconciliation (MDR).

class QRNG
#include <QRNG.hpp>

This class is used to simulate quantum random number generator (QRNG) output.

References

[LAB08]
  1. Leverrier, R. Alléaume, J. Boutros, G. Zémor, and P. Grangier, “Multidimensional reconciliation for a continuous-variable quantum key distribution,” Phys. Rev. Lett., vol. 77, no. 4, Apr. 2008.

[CS24]
    1. Cil and L. Schmalen, “Rate-adaptive protograph-based raptor-like LDPC code for continuous-variable quantum key distribution,” in Proc. Advanced Photonic Congress: Signal Processing in Photonic Communications (SPPCom), Quebec City, Canada, Jul. 2024.

[MFZ18]
  1. Milicevic, C. Feng, L. M. Zhang, and P. G. Gulak, “Quasi-cyclic multi-edge LDPC codes for long-distance quantum cryptography,” npj Quantum Information, vol. 4, no. 1, Apr. 2018.