diff --git a/Cargo.lock b/Cargo.lock index e497b82..a042fda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + [[package]] name = "anyhow" version = "1.0.79" @@ -642,6 +654,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.0.83" @@ -657,6 +675,58 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + [[package]] name = "config" version = "0.13.4" @@ -720,6 +790,42 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + [[package]] name = "crossbeam-channel" version = "0.5.11" @@ -729,6 +835,16 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + [[package]] name = "crossbeam-epoch" version = "0.9.18" @@ -744,6 +860,12 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -1224,6 +1346,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1440,6 +1572,26 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is-terminal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -1698,6 +1850,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "openssl" version = "0.10.63" @@ -1900,6 +2058,34 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + [[package]] name = "postgres-protocol" version = "0.6.6" @@ -2043,6 +2229,26 @@ dependencies = [ "bitflags 2.4.2", ] +[[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -2667,6 +2873,7 @@ dependencies = [ "base64 0.21.7", "cargo_metadata 0.15.4", "config", + "criterion", "diesel", "diesel-async", "digest 0.9.0", @@ -2772,6 +2979,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index bfd7399..dede700 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,7 @@ argh = "0.1.12" [dev-dependencies] rand = "0.8.5" +criterion = "0.5.1" axum-test = "14.2.2" [build-dependencies] @@ -83,3 +84,11 @@ name = "utils" strip = true lto = true codegen-units = 1 + +[[bench]] +name = "luhn-test" +harness = false + +[[bench]] +name = "encryption" +harness = false diff --git a/benches/bench-private-key.pem b/benches/bench-private-key.pem new file mode 100644 index 0000000..69c3a82 --- /dev/null +++ b/benches/bench-private-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAuZu3oeOJ+KWJfzoTjwPncxKJqKOUmuVbDmFHHBK5l8e8drr7 +6QH+Zt2PS477Vl0wIEH246TXUp1VzSCRiAkP/ecNx+29UpOoKTbI+GHfGMJgG7H/ +g6epjqpYvAz2BeX1KNptzSh4a5qaggYuQdsWAaZZcxfsBuvv0TvvFbJpsoshOdYY +QzhCpRBVWZlXB83fusAdYS8/lV4diC7vT+erwSaI2tN/GNHFCU+9zXuuJl/NoDUY +xur8HS/2FJf0K83Vq/mFMRNLyYhxpUlrvJHTv3sXwMYAW8fynURH00Ykgw3DFAac +vO+FDZXrzyTTRwBIpMBJ4J1sdPDuqNW07NURwwIDAQABAoIBAHbt0S9ZRgndwAmW +o/uqi75PLYeyMUFDHyJKsK7LTMJ1iEwnqcx2q5Ur+Gp41pFTKsgwnErnT9Uu3VCP +wtCAxg9x4oGt0va7iC/IW+PTiokp2z1Dw66PWvUAL9VnFKlY3Mrtkxe3C9oe+UvB +PBiUkjhCZ+R4epNA0KyoE506ccGljy5DZhGO8doyquQ91m5ohJ5bTh3wJkNV2ruv +sq+wiDsaSHKnza6L4gIYdSt0Rq92zIjj/UpsU4KI+xtvCUTU0NY66shpj5YcDoLj +9YQra3o0Td+w83Yg5loVAbJQCwuSxSby38w+nrZ7Ujlvbi9K5ZHWgFAC1OcfuS0o ++7AuNzkCgYEA2p1i4lRyCTze4qsEaKUGHzcblzim6CLFN90D3jDSArN1YaI2yYkH +suUy959Wy2M7YtGYTqTt8DmjWjUyH3p1Q2DW0D1EMopuYw5hDWhfT70RiSAjFDog +LlFA7YtmUiIOePzROyN0fxt2smZtjIYn/rgE4IOSN1YNMIGBLokNF7UCgYEA2Vlb +c5i5wUFLvyXYLMRvvX9SJgmGgWF9jhYnpQUxRuGyw+6MFrpNGbHHyN6GN71Sz0mV +ORgiFnLLyVqxko+38Xrp1bYuCqwfjuEe4PJKuE4ti44UmrpKiKnZvbC/76rqWbeS +ANCOw14zxsnsPKKc8UyL5X4EfW24+cmz81dNfpcCgYAUcrg3F1L7TjhC12A4MYdb +EBqCkIf8GpR73y5ncAWUvxhxo2ygeTLBJvMXek3yBDwfyB8I7CBdYebHn0Yq75dc +UAiHvdNNLumYVlX5nROdL8AeJWVilPVBn9QE5A8UC59y7aLcdzqEURtPIImKpVnE +V44NOgFJL8FYEiT1J1iUKQKBgGZpVE4DiIMm4SoQCuwNIxmHBI4nrtkHtsFcbxGy +gKWFc1Ye8KNE5U9WFWzwbQ2Wh45kfYuJc4ZgUOVvdnw4e9OstsGcNdWRhM0uBf64 +K7zsGUnIiKzfWn9KiO54effT8NiVRpZbrukfWgYw3r8zX//SsZhQ6IyxRpdsEv52 +BG3BAoGAdVQXTdsyrNCV+ks2/9DGoOHnBZa74d9ILZ0X0eaYsO+UwbzzuU6Fnq7s +MP6KhQXbP1It/PziPcbHCici7zshDyOEGRCyuNbr9MH31e2BRCv7knXgtpTZB/12 +OPZJMkrMfuqgGLW5xToKgcZW53G4IwUMcaI805f1sXlHRLosQ84= +-----END RSA PRIVATE KEY----- diff --git a/benches/bench-public-key.pem b/benches/bench-public-key.pem new file mode 100644 index 0000000..0795f7e --- /dev/null +++ b/benches/bench-public-key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuZu3oeOJ+KWJfzoTjwPn +cxKJqKOUmuVbDmFHHBK5l8e8drr76QH+Zt2PS477Vl0wIEH246TXUp1VzSCRiAkP +/ecNx+29UpOoKTbI+GHfGMJgG7H/g6epjqpYvAz2BeX1KNptzSh4a5qaggYuQdsW +AaZZcxfsBuvv0TvvFbJpsoshOdYYQzhCpRBVWZlXB83fusAdYS8/lV4diC7vT+er +wSaI2tN/GNHFCU+9zXuuJl/NoDUYxur8HS/2FJf0K83Vq/mFMRNLyYhxpUlrvJHT +v3sXwMYAW8fynURH00Ykgw3DFAacvO+FDZXrzyTTRwBIpMBJ4J1sdPDuqNW07NUR +wwIDAQAB +-----END PUBLIC KEY----- diff --git a/benches/encryption.rs b/benches/encryption.rs new file mode 100644 index 0000000..f41d6ac --- /dev/null +++ b/benches/encryption.rs @@ -0,0 +1,129 @@ +#![allow(clippy::expect_used)] +#![allow(clippy::missing_panics_doc)] + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use josekit::jwe; +use tartarus::crypto::{aes, jw, Encryption}; + +const ITERATION: u32 = 14; +const JWE_PRIVATE_KEY: &str = include_str!("bench-private-key.pem"); +const JWE_PUBLIC_KEY: &str = include_str!("bench-public-key.pem"); + +criterion_main!(benches); +criterion_group!(benches, criterion_aes, criterion_jwe_jws); + +pub fn criterion_aes(c: &mut Criterion) { + let key = aes::generate_aes256_key(); + let algo = aes::GcmAes256::new(key.to_vec()); + + { + let mut group = c.benchmark_group("aes-encryption"); + (1..ITERATION).for_each(|po| { + let max: u64 = (2_u64).pow(po); + let value = (0..max).map(|_| rand::random::()).collect::>(); + let encrypted_value = algo + .encrypt(value.clone()) + .expect("Failed while aes encrypting"); + group.throughput(criterion::Throughput::Bytes(max)); + group.bench_with_input( + criterion::BenchmarkId::from_parameter(max), + &(value, encrypted_value), + |b, (value, encrypted_value)| { + b.iter(|| { + black_box( + &algo + .encrypt(black_box(value.clone())) + .expect("Failed while aes encrypting") + == encrypted_value, + ) + }) + }, + ); + }); + } + + let mut group_2 = c.benchmark_group("aes-decryption"); + (1..ITERATION).for_each(|po| { + let max: u64 = (2_u64).pow(po); + let value = (0..max).map(|_| rand::random::()).collect::>(); + let encrypted_value = algo + .encrypt(value.clone()) + .expect("Failed while aes decrypting"); + group_2.throughput(criterion::Throughput::Bytes(max)); + group_2.bench_with_input( + criterion::BenchmarkId::from_parameter(max), + &(value, encrypted_value), + |b, (value, encrypted_value)| { + b.iter(|| { + black_box( + &algo + .decrypt(black_box(encrypted_value.clone())) + .expect("Failed while aes decrypting") + == value, + ) + }) + }, + ); + }); +} + +pub fn criterion_jwe_jws(c: &mut Criterion) { + let algo = jw::JWEncryption::new( + JWE_PRIVATE_KEY.to_string(), + JWE_PUBLIC_KEY.to_string(), + jwe::RSA_OAEP, + jwe::RSA_OAEP, + ); + + { + let mut group = c.benchmark_group("jw-encryption"); + (1..ITERATION).for_each(|po| { + let max: u64 = (2_u64).pow(po); + let value = (0..max).map(|_| rand::random::()).collect::(); + let value = value.as_bytes().to_vec(); + let encrypted_value = algo + .encrypt(value.clone()) + .expect("Failed while jw encrypting"); + group.throughput(criterion::Throughput::Bytes(max)); + group.bench_with_input( + criterion::BenchmarkId::from_parameter(max), + &(value, encrypted_value), + |b, (value, encrypted_value)| { + b.iter(|| { + black_box( + &algo + .encrypt(black_box(value.clone())) + .expect("Failed while jw encrypting") + == encrypted_value, + ) + }) + }, + ); + }); + } + + let mut group_2 = c.benchmark_group("jw-decryption"); + (1..ITERATION).for_each(|po| { + let max: u64 = (2_u64).pow(po); + let value = (0..max).map(|_| rand::random::()).collect::(); + let value = value.as_bytes().to_vec(); + let encrypted_value = algo + .encrypt(value.clone()) + .expect("Failed while jw decrypting"); + group_2.throughput(criterion::Throughput::Bytes(max)); + group_2.bench_with_input( + criterion::BenchmarkId::from_parameter(max), + &(value, encrypted_value), + |b, (value, encrypted_value)| { + b.iter(|| { + black_box( + &algo + .decrypt(black_box(encrypted_value.clone())) + .expect("Failed while jw decrypting") + == value, + ) + }) + }, + ); + }); +} diff --git a/benches/luhn-test.rs b/benches/luhn-test.rs new file mode 100644 index 0000000..2ab816d --- /dev/null +++ b/benches/luhn-test.rs @@ -0,0 +1,28 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use std::fmt::Write; +use tartarus::validations::luhn_on_string; + +#[allow(clippy::expect_used)] +fn card_number_generator() -> String { + (0..16).fold(String::new(), |mut acc, _| { + write!(&mut acc, "{}", rand::random::() % 10) + .expect("Failed to write to string buffer"); + acc + }) +} + +pub fn criterion_luhn(c: &mut Criterion) { + c.bench_function("card-number-generator", |b| { + b.iter(|| black_box(card_number_generator())) + }); + c.bench_function("luhn-validation", |b| { + b.iter(|| black_box(luhn_on_string(&black_box(card_number_generator())))) + }); + let card_number = card_number_generator(); + c.bench_function("luhn", |b| { + b.iter(|| black_box(luhn_on_string(black_box(&card_number)))) + }); +} + +criterion_group!(benches, criterion_luhn); +criterion_main!(benches); diff --git a/src/crypto/jw.rs b/src/crypto/jw.rs index b2509a4..ab2e392 100644 --- a/src/crypto/jw.rs +++ b/src/crypto/jw.rs @@ -53,7 +53,7 @@ impl JwsBody { } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct JweBody { pub header: String, @@ -139,7 +139,6 @@ pub fn encrypt_jwe( public_key: impl AsRef<[u8]>, alg: jwe::alg::rsaes::RsaesJweAlgorithm, ) -> Result { - // let alg = jwe::RSA_OAEP; let enc = "A256GCM"; let mut src_header = jwe::JweHeader::new(); src_header.set_content_encryption(enc);