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:
Random Number Generation: The QRNG class is simulates the random number generation to be used as the raw key material.
Multi-dimensional Reconciliation: The MDR class performs multi-dimensional reconciliation.
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.
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.
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
-
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)
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
-
MDR(int dim = 8, bool print_flag = false)
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
Private Members
-
uint32_t poly
Generator polynomial of the CRC
-
explicit CRC(uint32_t polynomial = 0xEDB88320)
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
-
QRNG(size_t seq_length, size_t NoF, bool print_flag = false)
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.
-
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)
References
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.
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.
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.