Skip to content

Commit

Permalink
Version 0.3.0
Browse files Browse the repository at this point in the history
GitOrigin-RevId: 0efcfb965f99d4840cbb655e7d9748e811e67bd3
  • Loading branch information
Terra Quantum AG committed Nov 22, 2024
1 parent d90c851 commit c0ffee6
Show file tree
Hide file tree
Showing 229 changed files with 14,235 additions and 6,533 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
name: Build
runs-on: ${{ inputs.image }}

timeout-minutes: 60
timeout-minutes: 90

steps:
- name: Check architecture
Expand Down Expand Up @@ -142,8 +142,8 @@ jobs:
if: github.event_name == 'pull_request' && inputs.coverage == 'ON'
shell: bash
run: |
pip3 install gcovr
COVERAGE_REPORT=`gcovr -s -r ${{ github.workspace }} -e ${{ github.workspace }}/build ${{ github.workspace }}/build`
pip3 install gcovr==7.2
COVERAGE_REPORT=`gcovr -s -r ${{ github.workspace }} -e ${{ github.workspace }}/build ${{ github.workspace }}/build | grep -v '100%$'`
echo 'COVERAGE_REPORT<<EOF' >> ${GITHUB_ENV}
echo "${COVERAGE_REPORT}" >> ${GITHUB_ENV}
echo 'EOF' >> ${GITHUB_ENV}
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The library will expand to include support for additional languages (e.g., Pytho

# CAVP Certificates

The TQ42 Cryptography implementations of the Post-Quantum algorithms ML-KEM, ML-DSA, and SLH-DSA, comply with the latest NIST standards (FIPS 203, 204, and 205). These algorithms have also been validated through the NIST Cryptographic Algorithm Validation Program (CAVP). For further details, please visit the NIST CAVP [webpage](https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/details?product=18351).
The TQ42 Cryptography v0.2.2 implementations of the Post-Quantum algorithms ML-KEM, ML-DSA, and SLH-DSA, comply with the latest NIST standards (FIPS 203, 204, and 205). These algorithms have also been validated through the NIST Cryptographic Algorithm Validation Program (CAVP). For further details, please visit the NIST CAVP [webpage](https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/details?product=18351).

The validation process spans multiple operating systems and hardware configurations, including:

Expand Down Expand Up @@ -52,12 +52,12 @@ Symmetric Encryption:

Key Encapsulation Mechanism:

- [ML-KEM](https://terra-quantum-public.github.io/tq42-pqc-oss/post_quantum_algs/kem/ml-kem.html)
- [ML-KEM](https://terra-quantum-public.github.io/tq42-pqc-oss/post_quantum_algs/kem/ml-kem.html) (modes: ML-KEM-512, ML-KEM-768, ML-KEM-1024)
- [Classic McEliece 8192128f](https://terra-quantum-public.github.io/tq42-pqc-oss/post_quantum_algs/kem/mceliece.html)

Digital Signature:
- [SLH-DSA](https://terra-quantum-public.github.io/tq42-pqc-oss/post_quantum_algs/digital_signature/slh-dsa.html)
- [ML-DSA](https://terra-quantum-public.github.io/tq42-pqc-oss/post_quantum_algs/digital_signature/ml-dsa.html)
- [SLH-DSA](https://terra-quantum-public.github.io/tq42-pqc-oss/post_quantum_algs/digital_signature/slh-dsa.html) (modes: SLH-DSA-SHAKE-128s, SLH-DSA-SHAKE-128f, SLH-DSA-SHAKE-192s, SLH-DSA-SHAKE-192f, SLH-DSA-SHAKE-256s, SLH-DSA-SHAKE-256f)
- [ML-DSA](https://terra-quantum-public.github.io/tq42-pqc-oss/post_quantum_algs/digital_signature/ml-dsa.html) (modes: ML-DSA-44, ML-DSA-65, ML-DSA-87)
- [Falcon padded 1024](https://terra-quantum-public.github.io/tq42-pqc-oss/post_quantum_algs/digital_signature/falcon.html)

### Key Management
Expand Down
7 changes: 6 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ We support the following versions

| Version | Supported |
| ------- | ------------------ |
| [0.1](https://github.com/terra-quantum-public/tq42-pqc-oss/releases/tag/v0.1.0) | :white_check_mark: |
| [0.3](https://github.com/terra-quantum-public/tq42-pqc-oss/releases/tag/v0.3.0) | :white_check_mark: |
| [0.2.2](https://github.com/terra-quantum-public/tq42-pqc-oss/releases/tag/v0.2.2) | :white_check_mark: |
| [0.2.1](https://github.com/terra-quantum-public/tq42-pqc-oss/releases/tag/v0.2.1) | :x: |
| [0.2.0](https://github.com/terra-quantum-public/tq42-pqc-oss/releases/tag/v0.2.0) | :x: |
| [0.1.1](https://github.com/terra-quantum-public/tq42-pqc-oss/releases/tag/v0.1.1) | :x: |
| [0.1](https://github.com/terra-quantum-public/tq42-pqc-oss/releases/tag/v0.1.0) | :x: |

## Reporting a Vulnerability

Expand Down
17 changes: 14 additions & 3 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,23 @@ if(NOT benchmark_POPULATED)
endif()

add_executable(
pqc_benchmark
pqc_benchmark.cpp
benchmark_aes
benchmark_aes.cpp
)

target_link_libraries(
pqc_benchmark
benchmark_aes
benchmark::benchmark
pqc
)

add_executable(
benchmark_init
benchmark_init.cpp
)

target_link_libraries(
benchmark_init
benchmark::benchmark
pqc
)
25 changes: 13 additions & 12 deletions benchmark/pqc_benchmark.cpp → benchmark/benchmark_aes.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <benchmark/benchmark.h>
#include <iostream>
#include <vector>

#include <pqc/aes.h>

Expand All @@ -13,26 +14,26 @@ template <uint32_t mode> void aes_encrypt(benchmark::State & state)
'G', 'H', 'I', 'J', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'K', 'L'};

const int64_t data_len = state.range(0);
uint8_t * data = new uint8_t[data_len];
std::vector<uint8_t> data(data_len, 0);

context = PQC_init_context_iv(PQC_CIPHER_AES, key, PQC_AES_KEYLEN, iv, PQC_AES_IVLEN);
context = PQC_context_init_iv(PQC_CIPHER_AES, key, PQC_AES_KEYLEN, iv, PQC_AES_IVLEN);

size_t res = 0;
for (auto _ : state)
{
res = PQC_encrypt(context, mode, data, data_len);
res = PQC_symmetric_encrypt(context, mode, data.data(), data.size());
}

if (res != PQC_OK)
{
std::cerr << "PQC_encrypt failed" << std::endl;
std::cerr << "PQC_symmetric_encrypt failed" << std::endl;
abort();
}

PQC_context_close(context);

benchmark::DoNotOptimize(data);
state.SetBytesProcessed(state.iterations() * data_len);

delete[] data;
}


Expand All @@ -46,26 +47,26 @@ template <uint32_t mode> void aes_decrypt(benchmark::State & state)
'G', 'H', 'I', 'J', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'K', 'L'};

const int64_t data_len = state.range(0);
uint8_t * data = new uint8_t[data_len];
std::vector<uint8_t> data(data_len, 0);

context = PQC_init_context_iv(PQC_CIPHER_AES, key, PQC_AES_KEYLEN, iv, PQC_AES_IVLEN);
context = PQC_context_init_iv(PQC_CIPHER_AES, key, PQC_AES_KEYLEN, iv, PQC_AES_IVLEN);

size_t res = 0;
for (auto _ : state)
{
res = PQC_decrypt(context, mode, data, data_len);
res = PQC_symmetric_decrypt(context, mode, data.data(), data.size());
}

if (res != PQC_OK)
{
std::cerr << "PQC_decrypt failed" << std::endl;
std::cerr << "PQC_symmetric_decrypt failed" << std::endl;
abort();
}

PQC_context_close(context);

benchmark::DoNotOptimize(data);
state.SetBytesProcessed(state.iterations() * data_len);

delete[] data;
}


Expand Down
136 changes: 136 additions & 0 deletions benchmark/benchmark_init.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#include <benchmark/benchmark.h>
#include <iostream>
#include <pqc/aes.h>
#include <thread>
#include <vector>

template <uint32_t cipher> void init(benchmark::State & state)
{
std::vector<CIPHER_HANDLE> contexts;
contexts.reserve(state.max_iterations);

uint8_t iv[PQC_AES_IVLEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

uint8_t key[PQC_AES_KEYLEN] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'K', 'L'};

for (auto _ : state)
{
contexts.push_back(PQC_context_init_iv(PQC_CIPHER_AES, key, PQC_AES_KEYLEN, iv, PQC_AES_IVLEN));
}

for (CIPHER_HANDLE h : contexts)
{
PQC_context_close(h);
}

state.SetItemsProcessed(contexts.size());
}


template <uint32_t cipher> void remove(benchmark::State & state)
{
std::vector<CIPHER_HANDLE> contexts;
contexts.reserve(state.max_iterations);

uint8_t iv[PQC_AES_IVLEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

uint8_t key[PQC_AES_KEYLEN] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'K', 'L'};

for (int i = 0; i < state.max_iterations; ++i)
{
contexts.push_back(PQC_context_init_iv(PQC_CIPHER_AES, key, PQC_AES_KEYLEN, iv, PQC_AES_IVLEN));
}

int i = 0;
for (auto _ : state)
{
PQC_context_close(contexts[i++]);
}

state.SetItemsProcessed(contexts.size());
}

template <int open_context_count> void multi_context_operation(benchmark::State & state)
{
uint8_t iv[PQC_AES_IVLEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

uint8_t key[PQC_AES_KEYLEN] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'K', 'L'};

const int64_t data_len = PQC_AES_BLOCKLEN * 5;
std::vector<uint8_t> data(data_len, 0);

size_t res = 0;
for (auto _ : state)
{
CIPHER_HANDLE contexts[open_context_count];
for (int i = 0; i < open_context_count; ++i)
{
contexts[i] = PQC_context_init_iv(PQC_CIPHER_AES, key, PQC_AES_KEYLEN, iv, PQC_AES_IVLEN);
res = PQC_symmetric_encrypt(contexts[i], PQC_AES_M_OFB, data.data(), data.size());
if (res != PQC_OK)
{
std::cerr << "PQC_encrypt failed: " << res << std::endl;
abort();
}
}

for (CIPHER_HANDLE context : contexts)
{
PQC_context_close(context);
}
}

benchmark::DoNotOptimize(data);
state.SetBytesProcessed(state.iterations() * data_len);
state.SetItemsProcessed(state.iterations() * open_context_count);
}

void single_context_operation(benchmark::State & state)
{
uint8_t iv[PQC_AES_IVLEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

uint8_t key[PQC_AES_KEYLEN] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'K', 'L'};

const int64_t data_len = PQC_AES_BLOCKLEN * 5;
std::vector<uint8_t> data(data_len, 0);

size_t res = 0;
for (auto _ : state)
{
CIPHER_HANDLE context;
context = PQC_context_init_iv(PQC_CIPHER_AES, key, PQC_AES_KEYLEN, iv, PQC_AES_IVLEN);
res = PQC_symmetric_encrypt(context, PQC_AES_M_OFB, data.data(), data.size());
if (res != PQC_OK)
{
std::cerr << "PQC_encrypt failed: " << res << std::endl;
abort();
}
PQC_context_close(context);
}

benchmark::DoNotOptimize(data);
state.SetBytesProcessed(state.iterations() * data_len);
state.SetItemsProcessed(state.iterations());
}


BENCHMARK(init<PQC_CIPHER_AES>)->Arg(10000);
BENCHMARK(remove<PQC_CIPHER_AES>)->Arg(10000);
BENCHMARK(init<PQC_CIPHER_AES>)->Arg(1000000);
BENCHMARK(remove<PQC_CIPHER_AES>)->Arg(1000000);


BENCHMARK(init<PQC_CIPHER_AES>)->Arg(10000)->Threads(std::thread::hardware_concurrency());
BENCHMARK(remove<PQC_CIPHER_AES>)->Arg(10000)->Threads(std::thread::hardware_concurrency());

BENCHMARK(init<PQC_CIPHER_AES>)->Arg(1000000)->Threads(std::thread::hardware_concurrency());
BENCHMARK(remove<PQC_CIPHER_AES>)->Arg(1000000)->Threads(std::thread::hardware_concurrency());

BENCHMARK(single_context_operation)->Arg(1000000)->Threads(std::thread::hardware_concurrency())->MinTime(300);
BENCHMARK(multi_context_operation<20>)->Arg(1000000)->Threads(std::thread::hardware_concurrency())->MinTime(300);

BENCHMARK_MAIN();
61 changes: 34 additions & 27 deletions docs/api_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,51 @@ Below you may find the reference to the all API methods or examples that exist i

## Post-Quantum Algorithms
### KEM
- [`PQC_generate_key_pair`](post_quantum_algs/kem/api.html#pqc_generate_key_pair)
- [`PQC_init_context`](post_quantum_algs/kem/api.html#pqc_init_context)
- [`PQC_kem_encode`](post_quantum_algs/kem/api.html#pqc_kem_encode)
- [`PQC_kem_decode`](post_quantum_algs/kem/api.html#pqc_kem_decode)
- [`PQC_kem_encode_secret`](post_quantum_algs/kem/api.html#pqc_kem_encode_secret)
- [`PQC_kem_decode_secret`](post_quantum_algs/kem/api.html#pqc_kem_decode_secret)
- [`PQC_close_context`](post_quantum_algs/kem/api.html#pqc_close_context)
- [`PQC_context_init_asymmetric`](post_quantum_algs/kem/api.html#pqc_context_init_asymmetric)
- [`PQC_context_keypair_generate`](post_quantum_algs/kem/api.html#pqc_context_keypair_generate)
- [`PQC_keypair_generate`](post_quantum_algs/kem/api.html#pqc_keypair_generate)
- [`PQC_context_get_public_key`](post_quantum_algs/kem/api.html#pqc_context_get_public_key)
- [`PQC_context_get_keypair`](post_quantum_algs/kem/api.html#pqc_context_get_keypair)
- [`PQC_kem_encapsulate`](post_quantum_algs/kem/api.html#pqc_kem_encapsulate)
- [`PQC_kem_decapsulate`](post_quantum_algs/kem/api.html#pqc_kem_decapsulate)
- [`PQC_kem_encapsulate_secret`](post_quantum_algs/kem/api.html#pqc_kem_encapsulate_secret)
- [`PQC_kem_decapsulate_secret`](post_quantum_algs/kem/api.html#pqc_kem_decapsulate_secret)
- [`PQC_context_close`](post_quantum_algs/kem/api.html#pqc_context_close)
- [McEliece Example](post_quantum_algs/kem/mceliece.html#example)
- [ML-KEM Example](post_quantum_algs/kem/ml-kem.html#example)

### Digital Signature
- [`PQC_generate_key_pair`](post_quantum_algs/digital_signature/api.html#pqc_generate_key_pair)
- [`PQC_init_context`](post_quantum_algs/digital_signature/api.html#pqc_init_context)
- [`PQC_sign`](post_quantum_algs/digital_signature/api.html#pqc_sign)
- [`PQC_verify`](post_quantum_algs/digital_signature/api.html#pqc_verify)
- [`PQC_close_context`](post_quantum_algs/digital_signature/api.html#pqc_close_context)
- [`PQC_context_init_asymmetric`](post_quantum_algs/kem/api.html#pqc_context_init_asymmetric)
- [`PQC_context_keypair_generate`](post_quantum_algs/kem/api.html#pqc_context_keypair_generate)
- [`PQC_keypair_generate`](post_quantum_algs/kem/api.html#pqc_keypair_generate)
- [`PQC_context_get_public_key`](post_quantum_algs/kem/api.html#pqc_context_get_public_key)
- [`PQC_context_get_keypair`](post_quantum_algs/kem/api.html#pqc_context_get_keypair)
- [`PQC_signature_create`](post_quantum_algs/digital_signature/api.html#pqc_signature_create)
- [`PQC_signature_verify`](post_quantum_algs/digital_signature/api.html#pqc_signature_verify)
- [`PQC_context_close`](post_quantum_algs/digital_signature/api.html#pqc_context_close)
- [Falcon Example](post_quantum_algs/digital_signature/falcon.html#example)
- [ML-DSA Example](post_quantum_algs/digital_signature/ml-dsa.html#example)

## Classic Quantum-Resistant Algorithms

### AES-256
- [`PQC_init_context`](classic_quantum_resistant_algs/aes.html#pqc_init_context)
- [`PQC_init_context_iv`](classic_quantum_resistant_algs/aes.html#pqc_init_context_iv)
- [`PQC_set_iv`](classic_quantum_resistant_algs/aes.html#pqc_set_iv)
- [`PQC_encrypt`](classic_quantum_resistant_algs/aes.html#pqc_encrypt)
- [`PQC_decrypt`](classic_quantum_resistant_algs/aes.html#pqc_decrypt)
### AES-256s
- [`PQC_context_init`](classic_quantum_resistant_algs/aes.html#pqc_context_init)
- [`PQC_context_init_iv`](classic_quantum_resistant_algs/aes.html#pqc_context_init_iv)
- [`PQC_context_set_iv`](classic_quantum_resistant_algs/aes.html#pqc_context_set_iv)
- [`PQC_symmetric_encrypt`](classic_quantum_resistant_algs/aes.html#pqc_symmetric_encrypt)
- [`PQC_symmetric_decrypt`](classic_quantum_resistant_algs/aes.html#pqc_symmetric_decrypt)
- [`PQC_aead_encrypt`](classic_quantum_resistant_algs/aes.html#pqc_aead_encrypt)
- [`PQC_aead_check`](classic_quantum_resistant_algs/aes.html#pqc_aead_check)
- [`PQC_aead_decrypt`](classic_quantum_resistant_algs/aes.html#pqc_aead_decrypt)
- [`PQC_close_context`](classic_quantum_resistant_algs/aes.html#pqc_close_context)
- [`PQC_context_close`](classic_quantum_resistant_algs/aes.html#pqc_context_close)
- [AES Examples](classic_quantum_resistant_algs/aes.html#examples)

### SHA-3
- [`PQC_init_context_hash`](classic_quantum_resistant_algs/sha3.html#pqc_init_context_hash)
- [`PQC_add_data`](classic_quantum_resistant_algs/sha3.html#pqc_add_data)
- [`PQC_context_init_hash`](classic_quantum_resistant_algs/sha3.html#pqc_context_init_hash)
- [`PQC_hash_update`](classic_quantum_resistant_algs/sha3.html#pqc_hash_update)
- [`PQC_hash_size`](classic_quantum_resistant_algs/sha3.html#pqc_hash_size)
- [`PQC_get_hash`](classic_quantum_resistant_algs/sha3.html#pqc_get_hash)
- [`PQC_close_context`](classic_quantum_resistant_algs/sha3.html#pqc_close_context)
- [`PQC_hash_retrieve`](classic_quantum_resistant_algs/sha3.html#pqc_hash_retrieve)
- [`PQC_context_close`](classic_quantum_resistant_algs/sha3.html#pqc_context_close)
- [SHA-3 Example](classic_quantum_resistant_algs/aes.html#examples)

## Keys
Expand Down Expand Up @@ -95,9 +101,10 @@ Below you may find the reference to the all API methods or examples that exist i
- [Example](keys/keys_container.html#asymmetric-container-example)

### Randomness Source
- [`PQC_random_from_pq_17`](keys/PRNG.html#pqc_random_from_pq_17)
- [`PQC_random_from_external`](keys/PRNG.html#pqc_random_from_external)
- [`PQC_random_bytes`](keys/PRNG.html#pqc_random_bytes)
- [`PQC_context_random_set_pq_17`](keys/PRNG.html#pqc_context_random_set_pq_17)
- [`PQC_context_random_set_external`](keys/PRNG.html#pqc_context_random_set_external)
- [`PQC_context_init_randomsource`](keys/PRNG.html#pqc_context_init_randomsource)
- [`PQC_context_random_get_bytes`](keys/PRNG.html#pqc_context_random_get_bytes)
- [Example](keys/PRNG.html#example)

### Secure file removal (HDD & SSD)
Expand All @@ -109,6 +116,6 @@ Below you may find the reference to the all API methods or examples that exist i
- [Example](keys/pbkdf2.html#example)

## Common functions
- [`PQC_get_length`](common_functions.html#pqc_get_length)
- [`PQC_cipher_get_length`](common_functions.html#pqc_cipher_get_length)
- [`PQC_context_get_length`](common_functions.html#pqc_context_get_length)
- [Constants](common_functions.html#сonstants)
Loading

0 comments on commit c0ffee6

Please sign in to comment.