How to use pQCee TEE API Server¶
The server handles Web APIs i.e. POST and GET requests for the various cryptographic operations.
Request Method is GET when no parameters are needed, and POST when parameters are needed.
Server Initialisation¶
The server needs a Transport Key to encrypt all private keys before returning. “Initialisation” of the server refers to the process of loading a Transport Key into the server.
There are two ways to initialise the server.
Loading the Transport Key through an API call.
The Initialise Server operation returns an encapsulation key that derives a symmetric key. The administrator encrypts the Transport Key with this key before loading it into the server.
Typing the Transport Key on server start.
The administrator types the Transport Key into the terminal when the server starts. In this case, the administrator does not call the initialise server operation.
Overview of APIs¶
pQCee’s Trusted Execution Environment (TEE) API server consist of:
2 functions that achieves a quantum-safe Transport Key Setup process,
3 functions that achieves the ML-KEM cryptographic functions, and
3 functions that achieves the SPP-ECDSA cryptographic functions.
3 functions that achieves the ML-DSA cryptographic functions.
Transport Key Setup using API¶
Call the GET /init_server API to receive an ML-KEM-768 Encapsulation Key.
On your own server, encapsulate this key, and use the resulting “shared secret” to encrypt the Transport Key.
Pass the encrypted transport key and ML-KEM-768 ciphertext to the POST /load_tk API to transfer the Transport Key into the API server.
ML-KEM Cryptographic Functions¶
To obtain a new ML-KEM-768 keypair, call the GET /mlkem_keygen API to receive an Encapsulation Key and an encrypted Decapsulation Key. The Decapsulation Key is encrypted with an Ephemeral Key derived from the Transport Key.
On your own server, encapsulate the Encapsulation Key, and use the resulting “shared secret” to encrypt the data.
Pass the encrypted data, encrypted Decapsulation Key and ML-KEM-768 ciphertext to the POST /mlkem_decrypt API to receive the decrypted data.
Pass the data, encrypted Decapsulation Key and ML-KEM-768 ciphertext to the POST /tofrontdecrypt API to receive the encrypted data.
SPP-ECDSA Cryptographic Functions¶
To obtain a new SPP-ECDSA keypair, call the GET /keygen API to receive an encrypted SPP secret key and its ECDSA public key. The SPP secret key is encrypted with an Ephemeral Key derived from the Transport Key.
Hash the data you wish to sign using SHA256, resulting in a “digest”.
Call the POST /sign API with the encrypted SPP secret key and this “digest” to receive an SPP-ECDSA signature and its zero-knowledge proof.
Call the POST /verify API with the “digest”, the signature, the ECDSA public key and the zero-knowledge proof to verify the authenticity of the signature.
ML-DSA Cryptographic Functions¶
To obtain a new ML-DSA keypair, call the GET /mldsa_keygen API to receive an encrypted ML-DSA private key and its public key. The ML-DSA private key is encrypted with an Ephemeral Key derived from the Transport Key.
Call the POST /mldsa_sign API with the encrypted SPP secret key, context and the “message” to receive a detached ML-DSA signature.
Call the POST /mldsa_verify API with the “message”, the signature, the ML-DSA public key and the context to verify the authenticity of the signature.
Example Usage¶
The following script provides an example usage of the API server.
The linux
curl
program is used to make GET and POST requests to the server.curl
commands without any parameters are GET requests, whilecurl
commands with--header
and--data-binary
are POST requests.Parameters to the POST requests are JSON objects, here processed by the JSON processing tool
jq
.
set -e
ADDR="http://localhost:8443"
echo "------------init_server()------------"
curl -v ${ADDR}/init_server | tee mlkem_encap_key | jq
echo "----------loadTK(E_SS(TK), CT)----------"
cat ciphertext encrypted_tk | jq -sc add >to_loadtk
curl -v ${ADDR}/load_tk --header "Content-Type: application/json" --data-binary @to_loadtk
echo "------------mlkem_keygen()------------"
curl -v ${ADDR}/mlkem_keygen >mlkem_keys
echo "Split into encrypted_mlkem_decap_key and mlkem_encap_key"
jq '{encrypted_mlkem_decap_key: .encrypted_mlkem_decap_key}' mlkem_keys >encrypted_mlkem_decap_key
jq '{mlkem_encap_key: .mlkem_encap_key}' mlkem_keys >mlkem_encap_key
echo "------------mlkem_decrypt(E_SS2(data), E_EK(mlkem_decap_key), CT)------------"
cat encrypted_mlkem_decap_key ciphertext encrypted_data | jq -sc add >to_mlkemdecrypt
echo "Running ML-KEM Decrypt"
curl -v ${ADDR}/mlkem_decrypt --header "Content-Type: application/json" --data-binary @to_mlkemdecrypt | tee data | jq
echo "------------keygen()------------"
curl -v ${ADDR}/keygen >keys
echo "Split into encrypted_secret_key and public_key"
jq '{encrypted_secret_key: .encrypted_secret_key}' keys >encrypted_secret_key
jq '{public_key: .public_key}' keys >public_key
echo "Create input params to sign"
cat encrypted_secret_key public_key digest | jq -s add >to_sign
echo "------------sign(digest, E_EK(secretkey), publickey)------------"
curl -v ${ADDR}/sign --header "Content-Type: application/json" --data-binary @to_sign | jq >signed
echo "Create input params to verify"
cat public_key digest signed | jq -s add >to_verify
echo "------------verify(digest, signature, proof, publickey)------------"
curl -v ${ADDR}/verify --header "Content-Type: application/json" --data-binary @to_verify
echo "------------mldsa_keygen()------------"
curl -v ${ADDR}/mldsa_keygen >mldsa_keys
echo "Split into encrypted_mldsa_private_key and mldsa_public_key"
jq '{encrypted_mldsa_private_key: .encrypted_mldsa_private_key}' mldsa_keys >encrypted_mldsa_private_key
jq '{mldsa_public_key: .mldsa_public_key}' mldsa_keys >mldsa_public_key
echo "Create input params to mldsa_sign"
cat encrypted_mldsa_private_key message context | jq -s add >to_mldsa_sign
echo "------------mldsa_sign(message, E_EK(privatekey), context)------------"
curl -v ${ADDR}/mldsa_sign --header "Content-Type: application/json" --data-binary @to_mldsa_sign | jq >mldsa_signed
echo "Create input params to mldsa_verify"
cat mldsa_public_key message mldsa_signed context | jq -s add >to_mldsa_verify
echo "------------mldsa_verify(message, mlsignature, mldsa_public_key, context)------------"
curl -v ${ADDR}/mldsa_verify --header "Content-Type: application/json" --data-binary @to_mldsa_verify