crypto-calcul is a cryptographic library that provides various functionalities in C with a GUI.
- C compiler, e.g.
gccorclang CMake≥ 3.20 andNinjaGMPpython3cffi(installed fromrequirements.txt)PyQt
# macOS
brew install cmake ninja gmp
# Debian/Ubuntu
sudo apt install cmake ninja-build libgmp-devIt's recommended to install the toolchain with MSYS2 and run every command below in the MSYS2 MinGW64 terminal.
pacman -S make \
mingw-w64-x86_64-gcc \
mingw-w64-x86_64-cmake \
mingw-w64-x86_64-ninja \
mingw-w64-x86_64-gmp \
mingw-w64-x86_64-python \
mingw-w64-x86_64-python-pipThe build is defined with CMake (CMakeLists.txt, src/backend/CMakeLists.txt) and runs on Ninja, which builds in parallel and only rebuilds what changed (including after header edits). The Makefile provides short aliases for it.
make setupThis creates the Python virtual environment in .venv, installs the dependencies, compiles the C library and the tests, and builds the Python package cryptocalc used by the GUI.
-
Set up the Python virtual environment and install the dependencies:
python3 -m venv .venv source .venv/bin/activate # Windows (MSYS2): source .venv/bin/activate or .venv/Scripts/activate pip install -r requirements.txt
-
Build everything (C library, test executables, Python package):
make
Or build only the Python package with
make python.
Outputs go to build/: test executables in build/tests/<module>/, the shared library in build/lib/, and the importable Python package in build/python/ (PYTHONPATH=build/python).
| Option | Values | Default |
|---|---|---|
BUILD_TYPE |
Release, Debug, RelWithDebInfo |
Release |
SANITIZE |
ON, OFF |
OFF |
SANITIZER |
address, leak, thread, undefined |
address |
PYTHON_PKG |
ON, OFF (skip the Python package) |
ON |
make test SANITIZE=ON SANITIZER=undefinedWith SANITIZE=ON, the Python tests run too: CMake finds the sanitizer runtime and preloads it into Python. src/frontend/debug.sh runs the whole suite under AddressSanitizer and UndefinedBehaviorSanitizer in build-asan/.
Each module is a static library that declares only its direct dependencies, so building a target builds exactly what it needs:
cmake --build build --target rsa # librsa.a and its dependencies
cmake --build build --target test_rsa_enc # one test executable
cmake --build build --target cryptocalc # the shared libraryCreate src/backend/<module>/ with its sources and *.test.c files, then add one line to src/backend/CMakeLists.txt:
cc_module(<module> DEPS <direct dependencies>)To expose it to applications and Python, add cc_* functions to cryptocalc.h and implement them in src/backend/api/: the Python bindings pick up the header automatically, and a class in src/python/cryptocalc/ can wrap them.
make also builds build/lib/libcryptocalc (.so, .dylib or .dll), a shared library whose only exported symbols are the cc_* functions declared in src/backend/include/cryptocalc.h. It is the stable interface for programs (and future bindings) that use the library: internal headers, GMP types and module structures are not part of it.
#include "cryptocalc.h"
cc_rsa_t *rsa;
uint8_t ct[512];
size_t ct_len = sizeof(ct);
cc_status_t status = cc_rsa_new(&rsa, CC_SEC_128, CC_RSA_OAEP_PSS);
if (status == CC_OK)
status = cc_rsa_keygen(rsa);
if (status == CC_OK)
status = cc_rsa_encrypt(rsa, msg, msg_len, ct, &ct_len);
if (status != CC_OK)
fprintf(stderr, "RSA failed: %s\n", cc_strerror(status));
cc_rsa_free(rsa);- Every function returns a
cc_status_t; the library never prints or exits. - Data is passed as bytes; big integers are big-endian.
- Outputs take a buffer and a capacity (
*out_len): if the buffer is too small, the call returnsCC_ERR_BUFFER_TOO_SMALLand the required size. - Verification functions return
CC_OKorCC_ERR_VERIFY.
cmake --install build --prefix <dir> installs the library and its header.
The GUI uses cryptocalc, a Python package in src/python/. Its bindings are generated by cffi from cryptocalc.h itself, so they always match the C API; a thin layer of classes makes them convenient:
from cryptocalc import RSA, RSAVariant, SecurityLevel, CryptoError
rsa = RSA(SecurityLevel.L1, RSAVariant.SECURE)
rsa.keygen()
ciphertext = rsa.encrypt(b"Hello")
try:
rsa.decrypt(ciphertext[::-1])
except CryptoError as e:
print(e, e.status) # "Decryption failed", the cc_status_t code- In this repository,
makebuilds it intobuild/python/;make guiruns the GUI with it. pip install .builds and installs it (with the C library inside) into the current environment, andpip install -e .installs it in editable mode.
-
Run the tests of the C library:
# All tests make test # Tests of one module (builds only that module and its dependencies) make test_<module_name>
Tests are registered with CTest, so
ctest --test-dir build -j8andctest --test-dir build -R rsaalso work.make test_apiruns the public API test, which links only againstlibcryptocalc. -
Test the Python library used by the UI:
make test_python
make guior, for a single page:
make gui_<page_name>The interface has light and dark themes, switched from the bottom of the sidebar and remembered between runs. Its look is defined in src/frontend/theme.py: color tokens for each theme and the Qt stylesheet built from them. The page forms are Qt Designer files in src/frontend/wireframes/ and carry no styling of their own.
make clean # remove build outputs
make distclean # remove the whole build directory, including the CMake cache