C 810: HQC (Hamming Quasi-Cyclic) Encryption (10 pts extra)

What You Need

A Debian Linux machine. I used Debian 12.

Purpose

To practice using the HQC encryption algorithm,which was just approved by NIST.

Background

On March 11, 2025, NIST selected HQC, as explained here:
NIST Selects HQC as Fifth Algorithm for Post-Quantum Encryption
Here are the main points from that announcement: While the ML-KEM algorithm is built around a mathematical idea called structured lattices, the HQC algorithm is built around another concept called error-correcting codes, which have been used in information security for decades. HQC is a lengthier algorithm than ML-KEM and therefore demands more computing resources. However its clean and secure operation makes it a worthy backup choice.

Security Levels

Here are the current encryption security levels specified in NIST Special Publication 800-57 Part 1: Revision 5 -- Recommendation for Key Management.

"Security Strength" refers to the number of bits of security, meaning that a brute force attack would need to search through that many bits to find the key.

Post-Quantum Security Levels

Here are the security levels for post-quantum encryption, from this page:

HQC Algorithms

Here are the HQC algorithms and their security levels, from Open Quantum Safe: HQC:
AlgorithmClaimed NIST Level Public key size (bytes)Secret key size (bytes)
HQC-128122492305
HQC-192345224586
HQC-256572457317

Configure, Build and Install liboqs from C Source Code

Execute these commands:
sudo apt update
sudo apt install cmake 

git clone --depth=1 https://github.com/open-quantum-safe/liboqs
cmake -S liboqs -B liboqs/build -DBUILD_SHARED_LIBS=ON
cmake --build liboqs/build --parallel 8
sudo cmake --build liboqs/build --target install

Install and Activate a Python Virtual Environment

Execute these commands:
python3 -m venv hqc
source hqc/bin/activate
python3 -m ensurepip --upgrade

Configure and Install the Python Wrapper

Execute these commands:
git clone --depth=1 https://github.com/open-quantum-safe/liboqs-python
cd liboqs-python
pip install .
pip install pycryptodome

Generate a Shared Secret

Execute these commands, as shown below:
python3

import oqs
kemalg = 'HQC-128'
with oqs.KeyEncapsulation(kemalg) as client:
    with oqs.KeyEncapsulation(kemalg) as server:
        public_key_client = client.generate_keypair()
        ciphertext, shared_secret_server = server.encap_secret(public_key_client)
        shared_secret_client = client.decap_secret(ciphertext)
        secret_key_client = client.export_secret_key()

print("Client Public Key: length=", len(public_key_client), 
      "Value:", public_key_client.hex()[:20], "...")

print("Client Secret Key: length=", len(secret_key_client), 
      "Value:", secret_key_client.hex()[:20], "...")

print("Client Shared Secret: length=", len(shared_secret_client), 
      "Value:", shared_secret_client.hex()[:20], "...")

print("Server Shared Secret: length=", len(shared_secret_server), 
      "Value:", shared_secret_server.hex()[:20], "...")
Notice these things:

Generating an AES Key from the Shared Secret

Execute these commands, as shown below:
import hashlib
from Crypto.Cipher import AES

aes_key = hashlib.pbkdf2_hmac('sha256', shared_secret_server, b"", 1024, 16)
print("AES Key: length=", len(aes_key), aes_key.hex())
You see a key that is 16 bytes long, as shown below.

Encrypting Text

Execute these commands, as shown below:
cleartext = b'Using Post-Quantum Cryptography!'
iv = b"0000111122223333"
cipher = AES.new(aes_key, AES.MODE_GCM, nonce=iv)
ciphertext = cipher.encrypt(cleartext)
print("Ciphertext: ", ciphertext.hex())
THe ciphetext is random-appearing hex bytes, as shown below.

Decrypting Text

Execute these commands, as shown below:
iv = b"0000111122223333"
cipher = AES.new(aes_key, AES.MODE_GCM, nonce=iv)
decrtext = cipher.decrypt(ciphertext)
print("Decrypted text: ", decrtext)
The cleartext message is recovered, as shown below.

C 810.1: Server Details (10 pts)

Execute this command:
print(server.details)
The flag is covered by a green rectangle in the image below.

Sources

liboqs-python: Python 3 bindings for liboqs
Code-Based Post-Quantum Cryptography
NIST: Post-Quantum Cryptography Selected Algorithms
Open Quantum Safe: HQC
NIST Selects HQC as Fifth Algorithm for Post-Quantum Encryption

Posted and video added 4-9-25