Giter Club home page Giter Club logo

classic-mceliece-rust's Introduction

classic-mceliece-rust

A safe pure-rust implementation of the Classic McEliece post-quantum scheme.

  • Classic McEliece is a lattice-based key encapsulation mechanism (KEM)
  • The implementation is based on the Classic McEliece reference implementation of NIST round 3
  • The implementation does not utilize any concurrency techniques (SIMD/threading/…, except maybe auto-vectorization on your CPU)
  • It depends on sha3 as SHA-3 implementation and aes as AES block cipher (used as RNG) implementation
  • It passes the 100 testcases of the C reference implementation
  • It implements all 10 variants of the Classic McEliece KEM
  • The implementation takes between 100 milliseconds (mceliece348864) and 500 milliseconds (mceliece8192128f) to run on a modern computer
  • The implementation is constant-time on software instruction level
  • The random number generator is based on AES256 in counter mode
  • First described in 1978, the cryptographic scheme has a rich history in security analysis. Its large public key size, however, often limits adoption.

The 10 variants have the following designated identifiers:

  • mceliece348864
  • mceliece348864f
  • mceliece460896
  • mceliece460896f
  • mceliece6688128
  • mceliece6688128f
  • mceliece6960119
  • mceliece6960119f
  • mceliece8192128
  • mceliece8192128f

Who should use it?

Anyone, how wants to use Classic McEliece to negotiate a key between two parties.

How does one use it?

Add this to your Cargo.toml:

[dependencies]
classic-mceliece-rust = "1.0"

To use a specific Classic McEliece variant, you need to import it with the corresponding feature flag:

[dependencies]
classic-mceliece-rust = { version = "1.0", features = ["mceliece6960119"] }

The simple example illustrates the API:

use classic_mceliece_rust::AesState;
use classic_mceliece_rust::{crypto_kem_dec, crypto_kem_enc, crypto_kem_keypair};
use classic_mceliece_rust::{CRYPTO_BYTES, CRYPTO_CIPHERTEXTBYTES, CRYPTO_PUBLICKEYBYTES, CRYPTO_SECRETKEYBYTES};

fn main() -> Result<(), Box<dyn error::Error>> {
  let mut rng = AesState::new();
  let mut pk = [0u8; CRYPTO_PUBLICKEYBYTES];
  let mut sk = [0u8; CRYPTO_SECRETKEYBYTES];
  let mut ct = [0u8; CRYPTO_CIPHERTEXTBYTES];
  let mut ss_alice = [0u8; CRYPTO_BYTES];
  let mut ss_bob = [0u8; CRYPTO_BYTES];

  crypto_kem_keypair(&mut pk, &mut sk, &mut rng)?;
  crypto_kem_enc(&mut ct, &mut ss_bob, &pk, &mut rng)?;
  crypto_kem_dec(&mut ss_alice, &ct, &sk)?;

  assert_eq!(ss_bob, ss_alice);
}

How does one run it?

This library comes with two examples:

$ cargo run --example basic

The output annotates messages with Alice/Bob to illustrate which data is processed by which party. The katkem example implements the classic request/response file structure which is part of the NIST PQC framework.

$ cargo run --example katkem PQCkemKAT_935.req PQCkemKAT_935.rsp
$ cargo run --example katkem PQCkemKAT_935.rsp

The different variants can be enabled through feature flags:

$ cargo run --example katkem --features mceliece6960119 -- PQCkemKAT_1450.req PQCkemKAT_1450.rsp

mceliece348864 is the default variant. You cannot enable two variants simultaneously.

How fast is it?

All data uses clock cycles as unit (the smaller the better). The rust implementation yielded the following runtime results:

complete KEMkeypairencdec
mceliece348864439,132,283418,968,068268,72243,444,716
mceliece348864f265,775,807222,549,540269,55543,245,009
mceliece4608961,231,610,7381,211,071,786461,924107,828,642
mceliece460896f723,224,611650,813,812435,803104,153,026
mceliece66881282,559,092,0962,231,201,954947,605198,260,095
mceliece6688128f1,166,028,7761,210,393,7991,210,453200,919,923
mceliece69601192,684,515,1492,194,168,2533,135,087194,131,917
mceliece6960119f1,146,146,9831,038,560,4693,101,435194,415,995
mceliece81921283,044,572,0962,873,255,5421,068,166249,912,972
mceliece8192128f1,362,327,6262,009,006,6531,790,924272,566,816

The C reference implementation yielded the following runtime results:

complete KEMkeypairencdec
mceliece348864434,103,000437,187,000187,55773,801,300
mceliece348864f252,423,000180,235,000189,52273,668,000
mceliece460896760,993,000894,497,000298,041154,507,000
mceliece460896f606,225,00044,906,000297,743154,013,000
mceliece66881281,568,900,0001,780,660,000425,50429,575,000
mceliece6688128f109,471,000760,298,000414,358298,173,000
mceliece69601193,405,730,0001,694,410,000840,598287,154,000
mceliece6960119f1,311,130,000942,987,000984,660303,543,000
mceliece81921281,635,550,000760,619,000428,112361,999,000
mceliece8192128f1,772,530,0001,222,720,000534,503392,729,000

The tests were done on a Lenovo Thinkpad x260 (Intel Core i5-6200U CPU @ 2.30GHz). In the case of rust, criterion 0.3.5 has been used as given in benches/ and in case of C, Google's benchmark with PFM support and disabled CPU frequency scaling. You can run the benchmark suite yourself with the bench subcommand and optionally some variant feature flag:

$ cargo bench --features mceliece348864

Is it correct?

Yes, besides passing unittests (derived from the C implementation), the generated KAT KEM test files have equivalent MD5 hashes. Namely …

variantexpected MD5 hash
mceliece348864d2def196fde89e938d3d45b2c6f806aa
mceliece348864f84b5357d8dd656bed9297e28beb15057
mceliece4608968aac2122916b901172e49e009efeede6
mceliece460896fd84d3b179e303b9f3fc32ccb6befb886
mceliece6688128b86987d56c45da2e326556864e66bda7
mceliece6688128fae1e42cac2a885a87a2c241e05391481
mceliece69601199d9b3c9e8d7595503248131c584394be
mceliece6960119fc79b1bd28fd307f8d157bd566374bfb3
mceliece8192128b233e2585359a1133a1135c66fa48282
mceliece8192128fd21bcb80dde24826e2c14254da917df3

Where is the source code?

On github.

What is the content's license?

MIT License

Changelog

  • 2022-04-01 version 1.0.0: public release (no April fools though)

Where can I ask you to fix a bug?

On github.

classic-mceliece-rust's People

Contributors

colfenor avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.