View Source pqclean NIF

Build Status Hex.pm

Post-Quantum Cryptography NIF based on PQClean for Erlang and Elixir.

See documentation for the pqclean_nif module for the full list of types and functions provided.

installation

Installation

Add pqclean to your project's dependencies in mix.exs

defp deps do
  [
    {:pqclean, "~> 0.0.1"}
  ]
end

Add pqclean to your project's dependencies in your Makefile for erlang.mk or the following to your rebar.config

{deps, [
    {pqclean, "0.0.1"}
]}.

examples

Examples

key-encapsulation-mechanism-kem-algorithm-example

Key Encapsulation Mechanism (KEM) Algorithm Example

{PK, SK} = pqclean_nif:kyber768_keypair(),
{CT, SS} = pqclean_nif:kyber768_encapsulate(PK),
     SS  = pqclean_nif:kyber768_decapsulate(CT, SK).

KEM with Encryption Example

% Alice and Bob want to exchange an encrypted messages.
% Alice wants to send Bob the message "a2b".
% Bob wants to send Alice the message "b2a".

% Helper functions (encrypt/decrypt with AES-256-GCM):
Encrypt = fun(K, N, PTxt) ->
    crypto:crypto_one_time_aead(aes_256_gcm, K, <<N:96>>, PTxt, <<>>, true)
end,
Decrypt = fun(K, N, CTxt, CTag) ->
    crypto:crypto_one_time_aead(aes_256_gcm, K, <<N:96>>, CTxt, <<>>, CTag, false)
end.

% Alice generates a new ephemeral keypair using Kyber-768:
{PKa, SKa} = pqclean_nif:kyber768_keypair().

% Alice sends `PKa' to Bob.

% Bob generates a new ephemeral keypair using Kyber-768:
{PKb, SKb} = pqclean_nif:kyber768_keypair(),
% Bob encapsulates a shared-secret `SSb2a' against Alice's `PKa' with
% an ephemeral KEM cipher-text `CTb2a' using Kyber-768:
{CTb2a, SSb2a} = pqclean_nif:kyber768_encapsulate(PKa),
% Bob encrypts plain-text `PKb' with shared-secret `SSb2a' and nonce `0'
% into cipher-text `CTxt_PKb' and cipher-tag `CTag_PKb':
{CTxt_PKb, CTag_PKb} = Encrypt(SSb2a, 0, PKb),
% Bob encrypts plain-text "b2a" with shared-secret `SSb2a' and nonce `1'
% into cipher-text `CTxt_PKb' and cipher-tag `CTag_PKb':
{CTxt_Mb, CTag_Mb} = Encrypt(SSb2a, 1, <<"b2a">>).

% Bob sends `CTb2a', `CTxt_PKb', `CTag_PKb', `CTxt_Mb', and `CTag_Mb' to Alice.

% Alice decapsulates Bob's `CTb2a' using secret-key `SKa' which
% results in shared-secret `SSb2a' using Kyber-768:
SSb2a = pqclean_nif:kyber768_decapsulate(CTb2a, SKa),
% Alice decrypts `PKb' with shared-secret `SSb2a':
PKb = Decrypt(SSb2a, 0, CTxt_PKb, CTag_PKb),
% Alice decrypts Bob's message "b2a" using shared-secret `SSb2a':
<<"b2a">> = Decrypt(SSb2a, 1, CTxt_Mb, CTag_Mb),
% Alice encapsulates a shared-secret `SSa2b' against Bob's `PKb' with
% an ephemeral KEM cipher-text `CTa2b' using Kyber-768:
{CTa2b, SSa2b} = pqclean_nif:kyber768_encapsulate(PKb),
% Alice encrypts plain-text "a2b" with shared-secret `SSa2b' and nonce `0'
% into cipher-text `CTxt_Ma' and cipher-tag `CTag_Ma':
{CTxt_Ma, CTag_Ma} = Encrypt(SSa2b, 0, <<"a2b">>).

% Alice sends `CTa2b', `CTxt_Ma', and `CTag_Ma' to Bob.

% Bob decapsulates Alice's `CTa2b' using secret-key `SKb' which
% results in shared-secret `SSa2b' using Kyber-768:
SSa2b = pqclean_nif:kyber768_decapsulate(CTa2b, SKb),
% Bob decrypts Alice's message "a2b" using shared-secret `SSa2b':
<<"a2b">> = Decrypt(SSa2b, 0, CTxt_Ma, CTag_Ma).

% Alice sends Bob a total of 2,291-bytes.
% Bob sends Alice a total of 2,307-bytes.

See PQNoise for more in-depth examples.

signature-algorithm-example

Signature Algorithm Example

{PK, SK} = pqclean_nif:falcon512_keypair(),
Msg = <<"message">>,
Sig = pqclean_nif:falcon512_sign(Msg, SK),
true = pqclean_nif:falcon512_verify(Sig, Msg, PK).

kem-algorithm-support

KEM Algorithm Support

KEM AlgorithmNIST LevelPublic KeySecret KeyCipher TextShared Secret
HQC-RMRS-12812,2492,2894,48164
HQC-RMRS-19234,5224,5629,02664
HQC-RMRS-25657,2457,28514,46964
Kyber51218001,63276832
Kyber512-90s18001,63276832
Kyber76831,1842,4001,08832
Kyber768-90s31,1842,4001,08832
Kyber102451,5683,1681,56832
Kyber1024-90s51,5683,1681,56832

signature-algorithm-support

Signature Algorithm Support

Signature AlgorithmNIST LevelPublic KeySecret KeySignatureSeed
Dilithium221,3122,5282,420&mdash;
Dilithium2-AES21,3122,5282,420&mdash;
Dilithium331,9524,0003,293&mdash;
Dilithium3-AES31,9524,0003,293&mdash;
Dilithium552,5924,8644,595&mdash;
Dilithium5-AES52,5924,8644,595&mdash;
Falcon-51218971,281666&mdash;
Falcon-102451,7932,3051,280&mdash;
SPHINCS+-haraka-128f-robust1326417,08848
SPHINCS+-haraka-128f-simple1326417,08848
SPHINCS+-haraka-128s-robust132647,85648
SPHINCS+-haraka-128s-simple132647,85648
SPHINCS+-haraka-192f-robust2489635,66472
SPHINCS+-haraka-192f-simple2489635,66472
SPHINCS+-haraka-192s-robust2489616,22472
SPHINCS+-haraka-192s-simple2489616,22472
SPHINCS+-haraka-256f-robust26412849,85696
SPHINCS+-haraka-256f-simple26412849,85696
SPHINCS+-haraka-256s-robust26412829,79296
SPHINCS+-haraka-256s-simple26412829,79296
SPHINCS+-sha2-128f-robust1326417,08848
SPHINCS+-sha2-128f-simple1326417,08848
SPHINCS+-sha2-128s-robust132647,85648
SPHINCS+-sha2-128s-simple132647,85648
SPHINCS+-sha2-192f-robust3489635,66472
SPHINCS+-sha2-192f-simple3489635,66472
SPHINCS+-sha2-192s-robust3489616,22472
SPHINCS+-sha2-192s-simple3489616,22472
SPHINCS+-sha2-256f-robust56412849,85696
SPHINCS+-sha2-256f-simple56412849,85696
SPHINCS+-sha2-256s-robust56412829,79296
SPHINCS+-sha2-256s-simple56412829,79296
SPHINCS+-shake-128f-robust1326417,08848
SPHINCS+-shake-128f-simple1326417,08848
SPHINCS+-shake-128s-robust132647,85648
SPHINCS+-shake-128s-simple132647,85648
SPHINCS+-shake-192f-robust3489635,66472
SPHINCS+-shake-192f-simple3489635,66472
SPHINCS+-shake-192s-robust3489616,22472
SPHINCS+-shake-192s-simple3489616,22472
SPHINCS+-shake-256f-robust56412849,85696
SPHINCS+-shake-256f-simple56412849,85696
SPHINCS+-shake-256s-robust56412829,79296
SPHINCS+-shake-256s-simple56412829,79296