# Post Quantum Cryptography (PQC) with Bouncy Castle and C#

Like it or not, we will have to ween ourselves off our existing public key methods and move towards quantum robust techniques. But how to migrate? Well, the Bouncy Castle library supports both Java and .NET integration, and can thus be supported on many systems. So, let’s have a look at the implementation of these methods with .NET/C#.

# Key exchange and public key encryption

NIST have approved the Kyber key encapsulation method as a standard, along with HQC, Bike and Classic Mceliece progressing to the next round of standardization:

**Kyber with Bouncy Castle and C#**

CRYSTALS (Cryptographic Suite for Algebraic Lattices) supports two quantum robust mechanisms: Kyber for key-encapsulation mechanism (KEM) and key exchange; and Dilithium for a digital signature algorithm. CRYSTALS-Kyber uses LWE (Learning with Errors) with lattice methods. A new lattice attack was discovered within the period of the assessment [1], but it is hoped that an updated version of Kyber can be produced for the final assessment. NIST have some worries about its side-channel robustness, but is a strong contender for KEM.

Overall a KEM allows a symmetric key to be passed using public key methods. In this case, Alice will generate her key pair of a public key (pk) and a private key (sk). She then passes her public key to Bob, and then Bob creates a cipher text (ct) with Alice’s public key. He passes the ciphertext to Alice, and who decrypts with her private key. This will reveal the key that Bob wants Alice to use. Kyber512 has a security level of AES-128, Kyber738 maps to AES-192, and Keyber1024 to AES-256.

Implementation: Kyber.

**HQC with Bouncy Castle and C#**

HQC is a code-based key encapsulation mechanism and is based on Hamming Quasi-Cyclic. It has three security levels: HQC-128, HQC-192 and HQC-256. While Kyber-512 has a public key of 800 bytes, HQC128 uses a 2,249-byte public key. With the private key, Kyber512 has a key size of 1,632 bytes, and Bike128 has a public key of 2,289 bytes. The ciphertext for Kyber512 is 768 bytes, and in HQC128 it is 4,497 bytes.

Implementation: HQC

**Bike with Bouncy Castle and C#**

In the 3rd round of the NIST PQC competition, Kyber was selected for standardization for a key encapsulation method and thus looks likely to replace ECDH as a key exchange method. In the 4th round, NIST is now assessing BIKE, Classic McEliece, HQC and SIKE. BIKE is a code-based key encapsulation mechanism and is based on QC-MDPC (Quasi-Cyclic Moderate Density Parity-Check). It has three security levels: Bike-128, Bike-192 and Bike-256. While Kyber-512 has a public key of 800 bytes, Bike128 uses a 1,541-byte public key. With the public key, Kyber512 has a key size of 1,632 bytes, and Bike128 has a public key of 3,114 bytes. The ciphertext for Kyber512 is 768 bytes, and in Bike128 it is 1,573 bytes

Implementation: Bike

**Classic Mceliece with Bouncy Castle and C#**

In the 3rd round of the NIST PQC competition, Kyber was selected for standardization for a key encapsulation method and thus looks to replace ECDH as a key exchange method.. In the 4th round, NIST are now assessing BIKE, Classic McEliece, HQC and SIKE. Classic Mceliece has five main modes: McEliece348864. McEliece460896 524. McEliece6688128, McEliece6960119 and McEliece8192128. With this, we have large public keys, and relatively large private keys, but a small ciphertext size. Unfortunately, it is slow for key generation, but gives acceptable levels of encapsulation and decapsulation performance.

Implementation: Mceliece

**NTRU Prime with Bouncy Castle and C#**

The NTRU (Nth degree TRUncated polynomial ring) public key method is a lattice-based method which is quantum robust. It uses the shortest vector problem in a lattice and has an underpinning related to the difficulty of factorizing certain polynomials. NTRUhps2048509 has a security level of AES-128, NTRUhps2048677 maps to AES-192, and NTRUhps4096821 to AES-256.

Implementation: NTRU Prime

# Digital Signatures

NIST approved three methods for standardization for digital signatures: Dilithium, Falcon and SPHINCS+.

**Dilithium with Bouncy Castle and C#**

At present, CRYSTALS (Cryptographic Suite for Algebraic Lattices) supports two quantum robust mechanisms: Kyber for key-encapsulation mechanism (KEM) and key exchange; and Dilithium for a digital signature algorithm. CRYSTALS Dilithium uses lattice-based Fiat-Shamir schemes, and produces one of the smallest signatures of all the post-quantum methods, and with relatively small public and private key sizes. The three main implements for the parameters used are: Dilithium 2, Dilithium 3 and Dilithium 5. Overall, Dilithium 3 is equivalent to a 128-bit signature and is perhaps the starting point for an implementation.

Implementation: Dilithium.

**Falcon with Bouncy Castle and C#**

Falcon was one of the finalists for the NIST standard for PQC (Post Quantum Cryptography), along with NTRU (Nth degree‐truncated polynomial ring units) and CRYSTALS-DILITHIUM, and is now approved by NIST as a standard for digital signatures (alongside Kyber and SPHINCS+). It is derived from NTRU and is a lattice-based methods for quantum robust digital signing. Falcon is based on the Gentry, Peikert and Vaikuntanathan method for generating lattice-based signature schemes, along with a trapdoor sampler — Fast Fourier sampling. We select three parameters: *N*, *p* and *q*. To generate the key pair, we select two polynomials: **f** and **g**. From these, we compute: *F*=**f***q*=**f**−1(mod*q*) and where **f** and **f***q* are the private keys. The public key is **h**=*p*⋅**f***q*.**f**(mod*q*)

With Falcon-512 (which has an equivalent security to RSA-2048), we generate a public key of 897 bytes, a private key size of 1,281 bytes and a signature size of 690 bytes, while FALCON-1024 gives a public key of 1,793 bytes and a signature size of 1,280 bytes.

Implementation: Falcon

**SPHINCS+ with Bouncy Castle and C#**

SPHINCS+ was one of the finalists for the NIST standard for PQC (Post Quantum Cryptography), along with NTRU (Nth degree‐truncated polynomial ring units) and CRYSTALS-DILITHIUM, and is now approved by NIST as a standard for digital signatures. It is a stateless hash-based signature scheme, which is quantum robust. It was proposed by Bernstein et al. in 2015. SPHINCS+ 256 128-bit has a public key size of 32 bytes, a private key size of 64 bytes, and a signature of 17KB. It has been shown to operate at speeds of hundreds of hashes per second on a 4-core 3.5GHz processor. In this case we will implement using SHA-256. Other hashing methods are Haraka and SHAKE-256, for 128-bit, 192-bit and 256-bit versions.

Implementation: SPHINCS+