summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-04-09 00:06:18 -0400
committerJesse Luehrs <doy@tozt.net>2019-04-09 02:00:33 -0400
commitf1f522df90e4af23f442067e269463710193148d (patch)
treeb397d986d68623e79f12499da64f76f26cd30f99
parent6807601cb64e7b18b832cab2939cbb107e3727bb (diff)
downloadmatasano-f1f522df90e4af23f442067e269463710193148d.tar.gz
matasano-f1f522df90e4af23f442067e269463710193148d.zip
get this compiling again
-rw-r--r--.rustfmt.toml1
-rw-r--r--Cargo.lock278
-rw-r--r--Cargo.toml7
-rw-r--r--src/aes.rs97
-rw-r--r--src/base64.rs4
-rw-r--r--src/crack.rs402
-rw-r--r--src/data.rs29
-rw-r--r--src/http.rs43
-rw-r--r--src/lib.rs71
-rw-r--r--src/md4.rs130
-rw-r--r--src/primitives.rs54
-rw-r--r--src/random.rs170
-rw-r--r--src/sha1.rs109
-rw-r--r--tests/set1.rs33
-rw-r--r--tests/set2.rs124
-rw-r--r--tests/set3.rs98
-rw-r--r--tests/set4.rs112
-rw-r--r--tests/util.rs30
18 files changed, 1066 insertions, 726 deletions
diff --git a/.rustfmt.toml b/.rustfmt.toml
new file mode 100644
index 0000000..bcad605
--- /dev/null
+++ b/.rustfmt.toml
@@ -0,0 +1 @@
+max_width = 78
diff --git a/Cargo.lock b/Cargo.lock
index 4060adf..7c7f6da 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,103 +1,301 @@
-[root]
-name = "matasano"
-version = "0.0.1"
+[[package]]
+name = "autocfg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "bitflags"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cc"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cfg-if"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cloudabi"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "bitflags"
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "gcc"
-version = "0.3.5"
+name = "fuchsia-cprng"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
-version = "0.1.10"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
-version = "0.1.7"
+version = "0.2.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "libressl-pnacl-sys"
-version = "2.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+name = "matasano"
+version = "0.0.1"
dependencies = [
- "pnacl-build-helper 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl"
-version = "0.6.2"
+version = "0.10.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys"
-version = "0.6.2"
+version = "0.9.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "libressl-pnacl-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pkg-config"
-version = "0.3.4"
+version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "pnacl-build-helper"
-version = "1.4.0"
+name = "rand"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "rand"
-version = "0.3.8"
+name = "rand_chacha"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rand_hc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_isaac"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "rand_jitter"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_os"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_xorshift"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rdrand"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.1.54"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "rustc-serialize"
-version = "0.3.14"
+version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "tempdir"
-version = "0.3.4"
+name = "rustc_version"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "time"
-version = "0.1.25"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi"
+version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[metadata]
+"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
+"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
+"checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83"
+"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
+"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
+"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917"
+"checksum openssl 0.10.20 (registry+https://github.com/rust-lang/crates.io-index)" = "5a0d6b781aac4ac1bd6cafe2a2f0ad8c16ae8e1dd5184822a16c50139f8838d9"
+"checksum openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)" = "33c86834957dd5b915623e94f2f4ab2c70dd8f6b70679824155d5ae21dbd495d"
+"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
+"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
+"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
+"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
+"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832"
+"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
+"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
+"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"
+"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
+"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
+"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
+"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/Cargo.toml b/Cargo.toml
index f18ef09..9246928 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,6 +2,8 @@
name = "matasano"
version = "0.0.1"
authors = ["Jesse Luehrs <doy@tozt.net>"]
+edition = "2018"
+autotests = false
[[test]]
name = "set1"
@@ -21,6 +23,7 @@ path = "tests/set4.rs"
[dependencies]
rustc-serialize = "0.3"
-openssl = "0.6"
-rand = "0.3"
+openssl = "0.10"
+rand = "0.6"
+rand_core = "0.4"
time = "0.1"
diff --git a/src/aes.rs b/src/aes.rs
index ffd40d9..5dad753 100644
--- a/src/aes.rs
+++ b/src/aes.rs
@@ -1,24 +1,42 @@
-use primitives::{fixed_xor, pad_pkcs7, unpad_pkcs7};
+use crate::primitives::{fixed_xor, pad_pkcs7, unpad_pkcs7};
-pub fn decrypt_aes_128_ecb (bytes: &[u8], key: &[u8]) -> Option<Vec<u8>> {
- // openssl already doesn't return differentiable results for invalid
- // padding, so we can't either
- return Some(::openssl::crypto::symm::decrypt(
- ::openssl::crypto::symm::Type::AES_128_ECB,
+fn decrypt_aes_128_ecb_nopad(bytes: &[u8], key: &[u8]) -> Vec<u8> {
+ let t = openssl::symm::Cipher::aes_128_ecb();
+ let mut c = openssl::symm::Crypter::new(
+ t,
+ openssl::symm::Mode::Decrypt,
key,
- vec![],
- bytes
- ));
+ None,
+ )
+ .unwrap();
+ c.pad(false);
+ let mut out = vec![0; bytes.len() + t.block_size()];
+ let count = c.update(bytes, &mut out).unwrap();
+ let rest = c.finalize(&mut out[count..]).unwrap();
+ out.truncate(count + rest);
+ out
+}
+
+pub fn decrypt_aes_128_ecb(bytes: &[u8], key: &[u8]) -> Vec<u8> {
+ return openssl::symm::decrypt(
+ openssl::symm::Cipher::aes_128_ecb(),
+ key,
+ None,
+ bytes,
+ )
+ .unwrap();
}
-pub fn decrypt_aes_128_cbc (bytes: &[u8], key: &[u8], iv: &[u8]) -> Option<Vec<u8>> {
+pub fn decrypt_aes_128_cbc(
+ bytes: &[u8],
+ key: &[u8],
+ iv: &[u8],
+) -> Option<Vec<u8>> {
let mut prev = iv.clone();
let mut plaintext = vec![];
for block in bytes.chunks(16) {
- let plaintext_block = fixed_xor(
- &decrypt_aes_128_ecb(&pad_pkcs7(block, 16)[..], key).unwrap()[..],
- prev
- );
+ let plaintext_block =
+ fixed_xor(&decrypt_aes_128_ecb_nopad(&block, key)[..], prev);
for c in plaintext_block {
plaintext.push(c);
}
@@ -27,21 +45,23 @@ pub fn decrypt_aes_128_cbc (bytes: &[u8], key: &[u8], iv: &[u8]) -> Option<Vec<u
return unpad_pkcs7(&plaintext[..]).map(|v| v.to_vec());
}
-pub fn encrypt_aes_128_ecb (bytes: &[u8], key: &[u8]) -> Vec<u8> {
- return ::openssl::crypto::symm::encrypt(
- ::openssl::crypto::symm::Type::AES_128_ECB,
+pub fn encrypt_aes_128_ecb(bytes: &[u8], key: &[u8]) -> Vec<u8> {
+ return openssl::symm::encrypt(
+ openssl::symm::Cipher::aes_128_ecb(),
key,
- vec![],
- bytes
+ None,
+ bytes,
)
+ .unwrap();
}
-pub fn encrypt_aes_128_cbc (bytes: &[u8], key: &[u8], iv: &[u8]) -> Vec<u8> {
+pub fn encrypt_aes_128_cbc(bytes: &[u8], key: &[u8], iv: &[u8]) -> Vec<u8> {
let mut prev = iv.to_vec();
let mut ciphertext = vec![];
for block in pad_pkcs7(bytes, 16).chunks(16) {
let plaintext_block = fixed_xor(&block[..], &prev[..]);
- let mut ciphertext_block = encrypt_aes_128_ecb(&plaintext_block[..], key);
+ let mut ciphertext_block =
+ encrypt_aes_128_ecb(&plaintext_block[..], key);
ciphertext_block.truncate(16);
for &c in ciphertext_block.iter() {
ciphertext.push(c);
@@ -51,20 +71,22 @@ pub fn encrypt_aes_128_cbc (bytes: &[u8], key: &[u8], iv: &[u8]) -> Vec<u8> {
return ciphertext;
}
-pub fn aes_128_ctr (bytes: &[u8], key: &[u8], nonce: u64) -> Vec<u8> {
+pub fn aes_128_ctr(bytes: &[u8], key: &[u8], nonce: u64) -> Vec<u8> {
aes_128_ctr_with_counter(bytes, key, nonce, 0)
}
-pub fn aes_128_ctr_with_counter (bytes: &[u8], key: &[u8], nonce: u64, counter_start: u64) -> Vec<u8> {
- let nonce_array: [u8; 8] = unsafe {
- ::std::mem::transmute(nonce.to_le())
- };
+pub fn aes_128_ctr_with_counter(
+ bytes: &[u8],
+ key: &[u8],
+ nonce: u64,
+ counter_start: u64,
+) -> Vec<u8> {
+ let nonce_array: [u8; 8] = unsafe { std::mem::transmute(nonce.to_le()) };
let mut counter = counter_start;
let mut ret = vec![];
for block in bytes.chunks(16) {
- let counter_array: [u8; 8] = unsafe {
- ::std::mem::transmute(counter.to_le())
- };
+ let counter_array: [u8; 8] =
+ unsafe { std::mem::transmute(counter.to_le()) };
let keystream = encrypt_aes_128_ecb(
&pad_pkcs7(
&nonce_array
@@ -72,9 +94,9 @@ pub fn aes_128_ctr_with_counter (bytes: &[u8], key: &[u8], nonce: u64, counter_s
.chain(counter_array.iter())
.map(|x| *x)
.collect::<Vec<u8>>()[..],
- 16
+ 16,
)[..],
- key
+ key,
);
for c in fixed_xor(block, &keystream[..]) {
ret.push(c);
@@ -85,7 +107,7 @@ pub fn aes_128_ctr_with_counter (bytes: &[u8], key: &[u8], nonce: u64, counter_s
}
#[test]
-fn test_encrypt_decrypt () {
+fn test_encrypt_decrypt() {
let plaintext = b"Summertime and the wind is blowing outside in lower \
Chelsea and I don't know what I'm doing in the city, the \
sun is always in my eyes";
@@ -93,13 +115,16 @@ fn test_encrypt_decrypt () {
let iv = [0; 16];
let ciphertext_ecb = encrypt_aes_128_ecb(&plaintext[..], &key[..]);
- let ciphertext_cbc = encrypt_aes_128_cbc(&plaintext[..], &key[..], &iv[..]);
+ let ciphertext_cbc =
+ encrypt_aes_128_cbc(&plaintext[..], &key[..], &iv[..]);
- let plaintext2_ecb = decrypt_aes_128_ecb(&ciphertext_ecb[..], &key[..]).unwrap();
- let plaintext2_cbc = decrypt_aes_128_cbc(&ciphertext_cbc[..], &key[..], &iv[..]).unwrap();
+ let plaintext2_ecb = decrypt_aes_128_ecb(&ciphertext_ecb[..], &key[..]);
+ let plaintext2_cbc =
+ decrypt_aes_128_cbc(&ciphertext_cbc[..], &key[..], &iv[..]).unwrap();
let ciphertext2_ecb = encrypt_aes_128_ecb(&plaintext2_ecb[..], &key[..]);
- let ciphertext2_cbc = encrypt_aes_128_cbc(&plaintext2_cbc[..], &key[..], &iv[..]);
+ let ciphertext2_cbc =
+ encrypt_aes_128_cbc(&plaintext2_cbc[..], &key[..], &iv[..]);
assert_eq!(&plaintext[..], &plaintext2_ecb[..]);
assert_eq!(&plaintext[..], &plaintext2_cbc[..]);
diff --git a/src/base64.rs b/src/base64.rs
index cc0f787..9b01da8 100644
--- a/src/base64.rs
+++ b/src/base64.rs
@@ -1,5 +1,5 @@
-use serialize::base64::{ToBase64, STANDARD};
+use rustc_serialize::base64::{ToBase64, STANDARD};
-pub fn to_base64 (bytes: &[u8]) -> String {
+pub fn to_base64(bytes: &[u8]) -> String {
return bytes.to_base64(STANDARD);
}
diff --git a/src/crack.rs b/src/crack.rs
index acc059b..9d56980 100644
--- a/src/crack.rs
+++ b/src/crack.rs
@@ -1,20 +1,19 @@
-use std::ascii::AsciiExt;
+use rand::Rng;
use std::borrow::ToOwned;
use std::collections::{HashMap, HashSet};
-use rand::{Rng, SeedableRng};
-use aes::encrypt_aes_128_cbc;
-use data::ENGLISH_FREQUENCIES;
-use primitives::{fixed_xor, unpad_pkcs7, hamming, repeating_key_xor};
-use random::MersenneTwister;
+use crate::aes::encrypt_aes_128_cbc;
+use crate::data::ENGLISH_FREQUENCIES;
+use crate::primitives::{fixed_xor, hamming, repeating_key_xor, unpad_pkcs7};
+use crate::random::MersenneTwister;
-#[derive(PartialEq,Eq,Debug)]
+#[derive(PartialEq, Eq, Debug)]
pub enum BlockCipherMode {
ECB,
CBC,
}
-pub fn find_single_byte_xor_encrypted_string (inputs: &[Vec<u8>]) -> Vec<u8> {
+pub fn find_single_byte_xor_encrypted_string(inputs: &[Vec<u8>]) -> Vec<u8> {
let mut min_diff = 100.0;
let mut best_decrypted = vec![];
for input in inputs {
@@ -27,44 +26,40 @@ pub fn find_single_byte_xor_encrypted_string (inputs: &[Vec<u8>]) -> Vec<u8> {
return best_decrypted;
}
-pub fn crack_single_byte_xor (input: &[u8]) -> Vec<u8> {
+pub fn crack_single_byte_xor(input: &[u8]) -> Vec<u8> {
let (key, _) = crack_single_byte_xor_with_confidence(input);
return repeating_key_xor(input, &[key]);
}
-pub fn crack_repeating_key_xor (input: &[u8]) -> Vec<u8> {
+pub fn crack_repeating_key_xor(input: &[u8]) -> Vec<u8> {
let mut keysizes = vec![];
for keysize in 2..40 {
let distance1 = hamming(
&input[(keysize * 0)..(keysize * 1)],
- &input[(keysize * 1)..(keysize * 2)]
+ &input[(keysize * 1)..(keysize * 2)],
) as f64;
let distance2 = hamming(
&input[(keysize * 1)..(keysize * 2)],
- &input[(keysize * 2)..(keysize * 3)]
+ &input[(keysize * 2)..(keysize * 3)],
) as f64;
let distance3 = hamming(
&input[(keysize * 2)..(keysize * 3)],
- &input[(keysize * 3)..(keysize * 4)]
+ &input[(keysize * 3)..(keysize * 4)],
) as f64;
let distance = distance1 + distance2 + distance3 / 3.0;
let normal_distance = distance / (keysize as f64);
keysizes.push((keysize, normal_distance));
if keysizes.len() > 5 {
- let (idx, _) = keysizes
- .iter()
- .enumerate()
- .fold(
- (0, (0, 0.0)),
- |(accidx, (accsize, accdist)), (idx, &(size, dist))| {
- if dist > accdist {
- (idx, (size, dist))
- }
- else {
- (accidx, (accsize, accdist))
- }
+ let (idx, _) = keysizes.iter().enumerate().fold(
+ (0, (0, 0.0)),
+ |(accidx, (accsize, accdist)), (idx, &(size, dist))| {
+ if dist > accdist {
+ (idx, (size, dist))
+ } else {
+ (accidx, (accsize, accdist))
}
- );
+ },
+ );
keysizes.swap_remove(idx);
}
}
@@ -72,7 +67,8 @@ pub fn crack_repeating_key_xor (input: &[u8]) -> Vec<u8> {
let mut min_diff = 100.0;
let mut best_key = vec![];
for (keysize, _) in keysizes {
- let (key, diff) = crack_repeating_key_xor_with_keysize(input, keysize);
+ let (key, diff) =
+ crack_repeating_key_xor_with_keysize(input, keysize);
if diff < min_diff {
min_diff = diff;
best_key = key;
@@ -82,7 +78,7 @@ pub fn crack_repeating_key_xor (input: &[u8]) -> Vec<u8> {
return best_key;
}
-pub fn find_aes_128_ecb_encrypted_string (inputs: &[Vec<u8>]) -> Vec<u8> {
+pub fn find_aes_128_ecb_encrypted_string(inputs: &[Vec<u8>]) -> Vec<u8> {
let mut max_dups = 0;
let mut found = vec![];
for input in inputs {
@@ -95,27 +91,32 @@ pub fn find_aes_128_ecb_encrypted_string (inputs: &[Vec<u8>]) -> Vec<u8> {
return found;
}
-pub fn detect_ecb_cbc<F> (f: &F, block_size: usize) -> BlockCipherMode where F: Fn(&[u8]) -> Vec<u8> {
- if block_size >= ::std::u8::MAX as usize {
+pub fn detect_ecb_cbc<F>(f: &F, block_size: usize) -> BlockCipherMode
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
+ if block_size >= std::u8::MAX as usize {
panic!("invalid block size: {}", block_size);
}
let block_size_byte = block_size as u8;
let plaintext: Vec<u8> = (0..block_size_byte)
.cycle()
.take(block_size * 2)
- .flat_map(|n| ::std::iter::repeat(n).take(block_size + 1))
+ .flat_map(|n| std::iter::repeat(n).take(block_size + 1))
.collect();
let ciphertext = f(&plaintext[..]);
if count_duplicate_blocks(&ciphertext[..], block_size) >= block_size {
return BlockCipherMode::ECB;
- }
- else {
+ } else {
return BlockCipherMode::CBC;
}
}
-pub fn crack_padded_aes_128_ecb<F> (f: &F) -> Vec<u8> where F: Fn(&[u8]) -> Vec<u8> {
+pub fn crack_padded_aes_128_ecb<F>(f: &F) -> Vec<u8>
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let block_size = find_block_size(f);
if detect_ecb_cbc(f, block_size) != BlockCipherMode::ECB {
panic!("Can only crack ECB-encrypted data");
@@ -135,7 +136,7 @@ pub fn crack_padded_aes_128_ecb<F> (f: &F) -> Vec<u8> where F: Fn(&[u8]) -> Vec<
loop {
let mut map = HashMap::new();
- let prefix: Vec<u8> = ::std::iter::repeat(b'A')
+ let prefix: Vec<u8> = std::iter::repeat(b'A')
.take(block_size - ((i % block_size) + 1))
.collect();
for c in 0..256 {
@@ -150,22 +151,26 @@ pub fn crack_padded_aes_128_ecb<F> (f: &F) -> Vec<u8> where F: Fn(&[u8]) -> Vec<
let next_char = map.get(&get_block(&prefix[..], i));
if next_char.is_some() {
plaintext.push(*next_char.unwrap());
- }
- else {
+ } else {
break;
}
i += 1;
}
- return unpad_pkcs7(&plaintext[..]).expect("invalid padding").to_vec();
+ return unpad_pkcs7(&plaintext[..])
+ .expect("invalid padding")
+ .to_vec();
}
-pub fn crack_padded_aes_128_ecb_with_prefix<F> (f: &F) -> Vec<u8> where F: Fn(&[u8]) -> Vec<u8> {
+pub fn crack_padded_aes_128_ecb_with_prefix<F>(f: &F) -> Vec<u8>
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let (block_size, prefix_len) = find_block_size_and_fixed_prefix_len(f);
let wrapped_f = |input: &[u8]| {
let alignment_padding = block_size - (prefix_len % block_size);
- let padded_input: Vec<u8> = ::std::iter::repeat(b'A')
+ let padded_input: Vec<u8> = std::iter::repeat(b'A')
.take(alignment_padding)
.chain(input.iter().map(|x| *x))
.collect();
@@ -178,8 +183,13 @@ pub fn crack_padded_aes_128_ecb_with_prefix<F> (f: &F) -> Vec<u8> where F: Fn(&[
return crack_padded_aes_128_ecb(&wrapped_f);
}
-pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>) where F: Fn(&str) -> Vec<u8> {
- fn incr_map_element (map: &mut HashMap<Vec<u8>, usize>, key: Vec<u8>) {
+pub fn crack_querystring_aes_128_ecb<F>(
+ encrypter: &F,
+) -> (String, Vec<Vec<u8>>)
+where
+ F: Fn(&str) -> Vec<u8>,
+{
+ fn incr_map_element(map: &mut HashMap<Vec<u8>, usize>, key: Vec<u8>) {
if let Some(val) = map.get_mut(&key) {
*val += 1;
return;
@@ -191,8 +201,8 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
let find_uid_role_blocks = || {
let mut map = HashMap::new();
for c in 32..127 {
- let email_bytes: Vec<u8> = ::std::iter::repeat(c).take(9).collect();
- let email = ::std::str::from_utf8(&email_bytes[..]).unwrap();
+ let email_bytes: Vec<u8> = std::iter::repeat(c).take(9).collect();
+ let email = std::str::from_utf8(&email_bytes[..]).unwrap();
let ciphertext = encrypter(email);
incr_map_element(&mut map, ciphertext[..16].to_vec());
incr_map_element(&mut map, ciphertext[16..32].to_vec());
@@ -202,20 +212,16 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
for (k, v) in map {
most_common_blocks.push((k, v));
if most_common_blocks.len() > 2 {
- let (idx, _) = most_common_blocks
- .iter()
- .enumerate()
- .fold(
- (0, (vec![], 10000)),
- |(aidx, (ablock, acount)), (idx, &(ref block, count))| {
- if count < acount {
- (idx, (block.clone(), count))
- }
- else {
- (aidx, (ablock.clone(), acount))
- }
+ let (idx, _) = most_common_blocks.iter().enumerate().fold(
+ (0, (vec![], 10000)),
+ |(aidx, (ablock, acount)), (idx, &(ref block, count))| {
+ if count < acount {
+ (idx, (block.clone(), count))
+ } else {
+ (aidx, (ablock.clone(), acount))
}
- );
+ },
+ );
most_common_blocks.swap_remove(idx);
}
}
@@ -224,8 +230,7 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
let (ref block1, _) = most_common_blocks[0];
let (ref block2, _) = most_common_blocks[1];
return (block1.clone(), block2.clone());
- }
- else {
+ } else {
panic!("couldn't find most common blocks");
}
};
@@ -234,9 +239,12 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
// email=..........admin<pcks7 padding>...............&uid=10&role=user
let calculate_admin_block = |block1: Vec<u8>, block2: Vec<u8>| {
for _ in 0..1000 {
- let email = "blorg@bar.admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b...............";
+ let email =
+ "blorg@bar.admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b...............";
let ciphertext = encrypter(email);
- if &ciphertext[48..64] == &block1[..] || &ciphertext[48..64] == &block2[..] {
+ if &ciphertext[48..64] == &block1[..]
+ || &ciphertext[48..64] == &block2[..]
+ {
return ciphertext[16..32].to_vec();
}
}
@@ -256,7 +264,10 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
.chain(admin_block.iter())
.map(|x| *x)
.collect();
- if !possibles.iter().any(|possible| possible == &modified_ciphertext) {
+ if !possibles
+ .iter()
+ .any(|possible| possible == &modified_ciphertext)
+ {
possibles.push(modified_ciphertext);
}
}
@@ -268,7 +279,10 @@ pub fn crack_querystring_aes_128_ecb<F> (encrypter: &F) -> (String, Vec<Vec<u8>>
return calculate_possible_admin_ciphertexts(admin_block);
}
-pub fn crack_cbc_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8> {
+pub fn crack_cbc_bitflipping<F>(f: &F) -> Vec<u8>
+where
+ F: Fn(&str) -> Vec<u8>,
+{
let mut ciphertext = f("AAAAAAAAAAAAAAAA:admin<true:AAAA");
ciphertext[32] = ciphertext[32] ^ 0x01;
ciphertext[38] = ciphertext[38] ^ 0x01;
@@ -276,7 +290,14 @@ pub fn crack_cbc_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8>
return ciphertext;
}
-pub fn crack_cbc_padding_oracle<F> (iv: &[u8], ciphertext: &[u8], f: &F) -> Vec<u8> where F: Fn(&[u8], &[u8]) -> bool {
+pub fn crack_cbc_padding_oracle<F>(
+ iv: &[u8],
+ ciphertext: &[u8],
+ f: &F,
+) -> Vec<u8>
+where
+ F: Fn(&[u8], &[u8]) -> bool,
+{
let mut prev = iv;
let mut plaintext = vec![];
for block in ciphertext.chunks(16) {
@@ -285,14 +306,15 @@ pub fn crack_cbc_padding_oracle<F> (iv: &[u8], ciphertext: &[u8], f: &F) -> Vec<
for c_int in 0..256 {
let c = (255 - c_int) as u8;
let offset = (16 - byte - 1) as usize;
- let mut iv: Vec<u8> = prev
- .iter()
- .take(offset)
- .map(|x| *x)
- .collect();
+ let mut iv: Vec<u8> =
+ prev.iter().take(offset).map(|x| *x).collect();
iv.push(prev[offset] ^ c ^ (byte + 1));
for i in 0..(byte as usize) {
- iv.push(prev[offset + i + 1] ^ plaintext_block[i] ^ (byte + 1));
+ iv.push(
+ prev[offset + i + 1]
+ ^ plaintext_block[i]
+ ^ (byte + 1),
+ );
}
if f(&iv[..], block) {
plaintext_block.insert(0, c);
@@ -309,7 +331,9 @@ pub fn crack_cbc_padding_oracle<F> (iv: &[u8], ciphertext: &[u8], f: &F) -> Vec<
return unpad_pkcs7(&plaintext[..]).unwrap().to_vec();
}
-pub fn crack_fixed_nonce_ctr_statistically (input: Vec<Vec<u8>>) -> Vec<Vec<u8>> {
+pub fn crack_fixed_nonce_ctr_statistically(
+ input: Vec<Vec<u8>>,
+) -> Vec<Vec<u8>> {
let min_len = input.iter().map(|line| line.len()).min().unwrap();
let max_len = input.iter().map(|line| line.len()).max().unwrap();
@@ -328,8 +352,7 @@ pub fn crack_fixed_nonce_ctr_statistically (input: Vec<Vec<u8>>) -> Vec<Vec<u8>>
if line.len() >= len {
idxs.push(idx);
true
- }
- else {
+ } else {
false
}
})
@@ -337,10 +360,8 @@ pub fn crack_fixed_nonce_ctr_statistically (input: Vec<Vec<u8>>) -> Vec<Vec<u8>>
.map(|x| *x)
.collect();
- let (key, _) = crack_repeating_key_xor_with_keysize(
- &ciphertext[..],
- len
- );
+ let (key, _) =
+ crack_repeating_key_xor_with_keysize(&ciphertext[..], len);
for i in full_key.len()..key.len() {
full_key.push(key[i])
}
@@ -358,11 +379,11 @@ pub fn crack_fixed_nonce_ctr_statistically (input: Vec<Vec<u8>>) -> Vec<Vec<u8>>
return plaintext_lines;
}
-pub fn recover_mersenne_twister_seed_from_time (output: u32) -> Option<u32> {
- let now = ::time::now().to_timespec().sec as u32;
+pub fn recover_mersenne_twister_seed_from_time(output: u32) -> Option<u32> {
+ let now = time::now().to_timespec().sec as u32;
for i in -10000..10000i32 {
let seed = (now as i32).wrapping_add(i) as u32;
- let mut mt = MersenneTwister::from_seed(seed);
+ let mut mt = MersenneTwister::from_u32(seed);
let test_output: u32 = mt.gen();
if test_output == output {
return Some(seed);
@@ -371,9 +392,14 @@ pub fn recover_mersenne_twister_seed_from_time (output: u32) -> Option<u32> {
return None;
}
-pub fn clone_mersenne_twister_from_output (outputs: &[u32]) -> MersenneTwister {
- fn untemper (val: u32) -> u32 {
- fn unxorshift<F> (f: F, mut y: u32, n: usize, mask: u32) -> u32 where F: Fn(u32, usize) -> u32 {
+pub fn clone_mersenne_twister_from_output(
+ outputs: &[u32],
+) -> MersenneTwister {
+ fn untemper(val: u32) -> u32 {
+ fn unxorshift<F>(f: F, mut y: u32, n: usize, mask: u32) -> u32
+ where
+ F: Fn(u32, usize) -> u32,
+ {
let mut a = y;
for _ in 0..(32 / n) {
y = f(y, n) & mask;
@@ -384,10 +410,10 @@ pub fn clone_mersenne_twister_from_output (outputs: &[u32]) -> MersenneTwister {
let mut y = val;
- y = unxorshift(|a, n| {a >> n}, y, 18, 0xffffffff);
- y = unxorshift(|a, n| {a << n}, y, 15, 0xefc60000);
- y = unxorshift(|a, n| {a << n}, y, 7, 0x9d2c5680);
- y = unxorshift(|a, n| {a >> n}, y, 11, 0xffffffff);
+ y = unxorshift(|a, n| a >> n, y, 18, 0xffffffff);
+ y = unxorshift(|a, n| a << n, y, 15, 0xefc60000);
+ y = unxorshift(|a, n| a << n, y, 7, 0x9d2c5680);
+ y = unxorshift(|a, n| a >> n, y, 11, 0xffffffff);
y
}
@@ -397,16 +423,17 @@ pub fn clone_mersenne_twister_from_output (outputs: &[u32]) -> MersenneTwister {
state[i] = untemper(output);
}
- return MersenneTwister::from_seed((state, 0));
+ return MersenneTwister::from_state(state, 0);
}
-pub fn recover_16_bit_mt19937_key (ciphertext: &[u8], suffix: &[u8]) -> Option<u16> {
+pub fn recover_16_bit_mt19937_key(
+ ciphertext: &[u8],
+ suffix: &[u8],
+) -> Option<u16> {
for _key in 0..65536u32 {
let key = _key as u16;
- let plaintext = ::random::mt19937_stream_cipher(
- ciphertext,
- key as u32
- );
+ let plaintext =
+ crate::random::mt19937_stream_cipher(ciphertext, key as u32);
if &plaintext[(ciphertext.len() - suffix.len())..] == suffix {
return Some(key);
}
@@ -415,12 +442,15 @@ pub fn recover_16_bit_mt19937_key (ciphertext: &[u8], suffix: &[u8]) -> Option<u
return None;
}
-pub fn recover_mt19937_key_from_time (token: &[u8]) -> Option<u32> {
- let now = ::time::now().to_timespec().sec as u32;
+pub fn recover_mt19937_key_from_time(token: &[u8]) -> Option<u32> {
+ let now = time::now().to_timespec().sec as u32;
for i in -500..500i32 {
let seed = (now as i32).wrapping_add(i) as u32;
- let mut mt = MersenneTwister::from_seed(seed);
- let test_token: Vec<u8> = mt.gen_iter().take(16).collect();
+ let mut mt = MersenneTwister::from_u32(seed);
+ let test_token: Vec<u8> = mt
+ .sample_iter(&rand::distributions::Standard)
+ .take(16)
+ .collect();
if &test_token[..] == token {
return Some(seed);
}
@@ -428,15 +458,23 @@ pub fn recover_mt19937_key_from_time (token: &[u8]) -> Option<u32> {
return None;
}
-pub fn crack_aes_128_ctr_random_access<F> (ciphertext: &[u8], edit: F) -> Vec<u8> where F: Fn(&[u8], usize, &[u8]) -> Vec<u8> {
- let empty_plaintext: Vec<u8> = ::std::iter::repeat(b'\x00')
- .take(ciphertext.len())
- .collect();
+pub fn crack_aes_128_ctr_random_access<F>(
+ ciphertext: &[u8],
+ edit: F,
+) -> Vec<u8>
+where
+ F: Fn(&[u8], usize, &[u8]) -> Vec<u8>,
+{
+ let empty_plaintext: Vec<u8> =
+ std::iter::repeat(b'\x00').take(ciphertext.len()).collect();
let keystream = edit(ciphertext, 0, &empty_plaintext[..]);
return fixed_xor(&keystream[..], ciphertext);
}
-pub fn crack_ctr_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8> {
+pub fn crack_ctr_bitflipping<F>(f: &F) -> Vec<u8>
+where
+ F: Fn(&str) -> Vec<u8>,
+{
let ciphertext = f("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
let replacement = fixed_xor(&ciphertext[32..44], b";admin=true;");
return ciphertext[..32]
@@ -447,14 +485,18 @@ pub fn crack_ctr_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8>
.collect();
}
-pub fn crack_cbc_iv_key<F1, F2> (encrypt: &F1, verify: &F2) -> Vec<u8> where F1: Fn(&str) -> Vec<u8>, F2: Fn(&[u8]) -> Result<bool, Vec<u8>> {
+pub fn crack_cbc_iv_key<F1, F2>(encrypt: &F1, verify: &F2) -> Vec<u8>
+where
+ F1: Fn(&str) -> Vec<u8>,
+ F2: Fn(&[u8]) -> Result<bool, Vec<u8>>,
+{
loop {
- let plaintext_bytes: Vec<u8> = ::rand::thread_rng()
- .gen_iter()
+ let plaintext_bytes: Vec<u8> = rand::thread_rng()
+ .sample_iter(&rand::distributions::Standard)
.filter(|&c| c >= 32 && c < 127)
- .take(16*5)
+ .take(16 * 5)
.collect();
- let plaintext = ::std::str::from_utf8(&plaintext_bytes).unwrap();
+ let plaintext = std::str::from_utf8(&plaintext_bytes).unwrap();
let ciphertext = encrypt(plaintext);
let modified_ciphertext: Vec<u8> = ciphertext[..16]
.iter()
@@ -466,7 +508,7 @@ pub fn crack_cbc_iv_key<F1, F2> (encrypt: &F1, verify: &F2) -> Vec<u8> where F1:
if let Err(modified_plaintext) = verify(&modified_ciphertext[..]) {
let key = fixed_xor(
&modified_plaintext[..16],
- &modified_plaintext[32..48]
+ &modified_plaintext[32..48],
);
let desired_plaintext = b"comment1=cooking%20MCs;userdata=;admin=true;comment2=%20like%20a%20pound%20of%20bacon";
return encrypt_aes_128_cbc(desired_plaintext, &key[..], &key[..]);
@@ -474,51 +516,65 @@ pub fn crack_cbc_iv_key<F1, F2> (encrypt: &F1, verify: &F2) -> Vec<u8> where F1:
}
}
-pub fn crack_sha1_mac_length_extension (input: &[u8], mac: [u8; 20], extension: &[u8]) -> Vec<(Vec<u8>, [u8; 20])> {
- let mut sha1_state: [u32; 5] = unsafe { ::std::mem::transmute(mac) };
+pub fn crack_sha1_mac_length_extension(
+ input: &[u8],
+ mac: [u8; 20],
+ extension: &[u8],
+) -> Vec<(Vec<u8>, [u8; 20])> {
+ let mut sha1_state: [u32; 5] = unsafe { std::mem::transmute(mac) };
for word in sha1_state.iter_mut() {
*word = u32::from_be(*word);
}
- (0..100).map(|i| {
- let new_input: Vec<u8> = input
- .iter()
- .chain(::sha1::sha1_padding(i + input.len() as u64).iter())
- .chain(extension.iter())
- .map(|x| *x)
- .collect();
- let new_hash = ::sha1::sha1_with_state(
- extension,
- sha1_state,
- i + new_input.len() as u64
- );
- (new_input, new_hash)
- }).collect()
+ (0..100)
+ .map(|i| {
+ let new_input: Vec<u8> = input
+ .iter()
+ .chain(
+ crate::sha1::sha1_padding(i + input.len() as u64).iter(),
+ )
+ .chain(extension.iter())
+ .map(|x| *x)
+ .collect();
+ let new_hash = crate::sha1::sha1_with_state(
+ extension,
+ sha1_state,
+ i + new_input.len() as u64,
+ );
+ (new_input, new_hash)
+ })
+ .collect()
}
-pub fn crack_md4_mac_length_extension (input: &[u8], mac: [u8; 16], extension: &[u8]) -> Vec<(Vec<u8>, [u8; 16])> {
- let mut md4_state: [u32; 4] = unsafe { ::std::mem::transmute(mac) };
+pub fn crack_md4_mac_length_extension(
+ input: &[u8],
+ mac: [u8; 16],
+ extension: &[u8],
+) -> Vec<(Vec<u8>, [u8; 16])> {
+ let mut md4_state: [u32; 4] = unsafe { std::mem::transmute(mac) };
for word in md4_state.iter_mut() {
*word = u32::from_le(*word);
}
- (0..100).map(|i| {
- let new_input: Vec<u8> = input
- .iter()
- .chain(::md4::md4_padding(i + input.len() as u64).iter())
- .chain(extension.iter())
- .map(|x| *x)
- .collect();
- let new_hash = ::md4::md4_with_state(
- extension,
- md4_state,
- i + new_input.len() as u64
- );
- (new_input, new_hash)
- }).collect()
+ (0..100)
+ .map(|i| {
+ let new_input: Vec<u8> = input
+ .iter()
+ .chain(crate::md4::md4_padding(i + input.len() as u64).iter())
+ .chain(extension.iter())
+ .map(|x| *x)
+ .collect();
+ let new_hash = crate::md4::md4_with_state(
+ extension,
+ md4_state,
+ i + new_input.len() as u64,
+ );
+ (new_input, new_hash)
+ })
+ .collect()
}
-fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) {
+fn crack_single_byte_xor_with_confidence(input: &[u8]) -> (u8, f64) {
let mut min_diff = 100.0;
let mut best_key = 0;
for a in 0..256u16 {
@@ -526,12 +582,15 @@ fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) {
input,
&::std::iter::repeat(a as u8)
.take(input.len())
- .collect::<Vec<u8>>()[..]
+ .collect::<Vec<u8>>()[..],
);
if !decrypted.is_ascii() {
continue;
}
- if decrypted.iter().any(|&c| c != b'\n' && (c < 0x20 || c > 0x7E)) {
+ if decrypted
+ .iter()
+ .any(|&c| c != b'\n' && (c < 0x20 || c > 0x7E))
+ {
continue;
}
let lowercase = decrypted.to_ascii_lowercase();
@@ -542,15 +601,17 @@ fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) {
total_frequency += 1;
if c >= 0x61 && c <= 0x7A {
frequencies[(c - 0x61) as usize] += 1;
- }
- else {
+ } else {
extra_frequencies += 1;
}
}
let mut total_diff = 0.0;
- for (&english, &crypt) in ENGLISH_FREQUENCIES.iter().zip(frequencies.iter()) {
- let relative_frequency = (crypt as f64) / (total_frequency as f64);
+ for (&english, &crypt) in
+ ENGLISH_FREQUENCIES.iter().zip(frequencies.iter())
+ {
+ let relative_frequency =
+ (crypt as f64) / (total_frequency as f64);
total_diff += (english - relative_frequency).abs();
}
total_diff += (extra_frequencies as f64) / (total_frequency as f64);
@@ -564,7 +625,10 @@ fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) {
return (best_key, min_diff);
}
-fn crack_repeating_key_xor_with_keysize (input: &[u8], keysize: usize) -> (Vec<u8>, f64) {
+fn crack_repeating_key_xor_with_keysize(
+ input: &[u8],
+ keysize: usize,
+) -> (Vec<u8>, f64) {
let strides: Vec<Vec<u8>> = (0..keysize)
.map(|n| {
// XXX sigh ):
@@ -585,14 +649,11 @@ fn crack_repeating_key_xor_with_keysize (input: &[u8], keysize: usize) -> (Vec<u
.iter()
.map(|&(_, diff)| diff)
.fold(0.0, |acc, x| acc + x);
- let key = cracked
- .iter()
- .map(|&(c, _)| c)
- .collect();
+ let key = cracked.iter().map(|&(c, _)| c).collect();
return (key, diff / (keysize as f64));
}
-fn count_duplicate_blocks (input: &[u8], block_size: usize) -> usize {
+fn count_duplicate_blocks(input: &[u8], block_size: usize) -> usize {
let mut set = HashSet::new();
let mut dups = 0;
for block in input.chunks(block_size) {
@@ -603,26 +664,27 @@ fn count_duplicate_blocks (input: &[u8], block_size: usize) -> usize {
return dups;
}
-fn find_block_size<F> (f: &F) -> usize where F: Fn(&[u8]) -> Vec<u8> {
+fn find_block_size<F>(f: &F) -> usize
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let (block_size, _) = find_block_size_and_fixed_prefix_len(f);
return block_size;
}
-fn find_block_size_and_fixed_prefix_len<F> (f: &F) -> (usize, usize) where F: Fn(&[u8]) -> Vec<u8> {
+fn find_block_size_and_fixed_prefix_len<F>(f: &F) -> (usize, usize)
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let fixed_prefix_len = find_fixed_block_prefix_len(f);
let byte = b'A';
let mut prev = f(&[b'f']);
let mut len = 0;
loop {
- let prefix: Vec<u8> = ::std::iter::repeat(byte)
- .take(len)
- .collect();
+ let prefix: Vec<u8> = std::iter::repeat(byte).take(len).collect();
let next = f(&prefix[..]);
- let prefix_len = shared_prefix_len(
- prev.iter(),
- next.iter()
- );
+ let prefix_len = shared_prefix_len(prev.iter(), next.iter());
if prefix_len > fixed_prefix_len {
let block_size = prefix_len - fixed_prefix_len;
return (block_size, fixed_prefix_len + block_size - (len - 1));
@@ -633,15 +695,19 @@ fn find_block_size_and_fixed_prefix_len<F> (f: &F) -> (usize, usize) where F: Fn
}
}
-fn find_fixed_block_prefix_len<F> (f: &F) -> usize where F: Fn(&[u8]) -> Vec<u8> {
+fn find_fixed_block_prefix_len<F>(f: &F) -> usize
+where
+ F: Fn(&[u8]) -> Vec<u8>,
+{
let ciphertext1 = f(b"");
let ciphertext2 = f(b"A");
return shared_prefix_len(ciphertext1.iter(), ciphertext2.iter());
}
-fn shared_prefix_len<I> (i1: I, i2: I) -> usize where I: Iterator, <I as Iterator>::Item: PartialEq {
- return i1
- .zip(i2)
- .take_while(|&(ref c1, ref c2)| { c1 == c2 })
- .count();
+fn shared_prefix_len<I>(i1: I, i2: I) -> usize
+where
+ I: Iterator,
+ <I as Iterator>::Item: PartialEq,
+{
+ return i1.zip(i2).take_while(|&(ref c1, ref c2)| c1 == c2).count();
}
diff --git a/src/data.rs b/src/data.rs
index 6fb0272..0e8f9ae 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -1,28 +1,5 @@
pub const ENGLISH_FREQUENCIES: [f64; 26] = [
- 0.0804,
- 0.0148,
- 0.0334,
- 0.0382,
- 0.1249,
- 0.0240,
- 0.0187,
- 0.0505,
- 0.0757,
- 0.0016,
- 0.0054,
- 0.0407,
- 0.0251,
- 0.0723,
- 0.0764,
- 0.0214,
- 0.0012,
- 0.0628,
- 0.0651,
- 0.0928,
- 0.0273,
- 0.0105,
- 0.0168,
- 0.0023,
- 0.0166,
- 0.0009,
+ 0.0804, 0.0148, 0.0334, 0.0382, 0.1249, 0.0240, 0.0187, 0.0505, 0.0757,
+ 0.0016, 0.0054, 0.0407, 0.0251, 0.0723, 0.0764, 0.0214, 0.0012, 0.0628,
+ 0.0651, 0.0928, 0.0273, 0.0105, 0.0168, 0.0023, 0.0166, 0.0009,
];
diff --git a/src/http.rs b/src/http.rs
index 9096298..10b0eca 100644
--- a/src/http.rs
+++ b/src/http.rs
@@ -1,6 +1,6 @@
use std::collections::HashMap;
-pub fn parse_query_string (string: &str) -> Option<HashMap<&str, &str>> {
+pub fn parse_query_string(string: &str) -> Option<HashMap<&str, &str>> {
let mut map = HashMap::new();
let mut offset = 0;
let len = string.as_bytes().len();
@@ -10,14 +10,14 @@ pub fn parse_query_string (string: &str) -> Option<HashMap<&str, &str>> {
let key_end = key_start + found;
let key = &string[key_start..key_end];
let value_start = key_end + 1;
- let value_end = value_start + string[value_start..]
- .find('&')
- .unwrap_or_else(|| string[value_start..].as_bytes().len());
+ let value_end = value_start
+ + string[value_start..].find('&').unwrap_or_else(|| {
+ string[value_start..].as_bytes().len()
+ });
let value = &string[value_start..value_end];
map.insert(key, value);
offset = value_end + 1;
- }
- else {
+ } else {
return None;
}
}
@@ -25,9 +25,11 @@ pub fn parse_query_string (string: &str) -> Option<HashMap<&str, &str>> {
return Some(map);
}
-pub fn create_query_string (params: HashMap<&str, &str>) -> String {
- fn escape (s: &str) -> String {
- s.replace("%", "%25").replace("&", "%26").replace("=", "%3D")
+pub fn create_query_string(params: HashMap<&str, &str>) -> String {
+ fn escape(s: &str) -> String {
+ s.replace("%", "%25")
+ .replace("&", "%26")
+ .replace("=", "%3D")
}
let mut parts = vec![];
@@ -37,11 +39,11 @@ pub fn create_query_string (params: HashMap<&str, &str>) -> String {
part.push_str(&escape(v)[..]);
parts.push(part);
}
- return parts.connect("&");
+ return parts.join("&");
}
#[test]
-fn test_parse_query_string () {
+fn test_parse_query_string() {
let got = parse_query_string("foo=bar&baz=qux&zap=zazzle");
let mut expected = HashMap::new();
expected.insert("foo", "bar");
@@ -53,7 +55,7 @@ fn test_parse_query_string () {
}
#[test]
-fn test_create_query_string () {
+fn test_create_query_string() {
let mut params = HashMap::new();
params.insert("foo", "bar");
params.insert("baz", "qux");
@@ -66,18 +68,19 @@ fn test_create_query_string () {
let expected5 = "zap=zazzle&foo=bar&baz=qux";
let expected6 = "zap=zazzle&baz=qux&foo=bar";
assert!(
- got == expected1 ||
- got == expected2 ||
- got == expected3 ||
- got == expected4 ||
- got == expected5 ||
- got == expected6,
- "didn't parse query string correctly: {}", got
+ got == expected1
+ || got == expected2
+ || got == expected3
+ || got == expected4
+ || got == expected5
+ || got == expected6,
+ "didn't parse query string correctly: {}",
+ got
);
}
#[test]
-fn test_create_query_string_malicious () {
+fn test_create_query_string_malicious() {
let mut params = HashMap::new();
params.insert("email", "foo@bar.com&role=admin");
let got = create_query_string(params);
diff --git a/src/lib.rs b/src/lib.rs
index 151a323..51fc134 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,8 +1,3 @@
-extern crate rustc_serialize as serialize;
-extern crate openssl;
-extern crate rand;
-extern crate time;
-
mod aes;
mod base64;
mod crack;
@@ -13,50 +8,50 @@ mod primitives;
mod random;
mod sha1;
-pub use aes::decrypt_aes_128_ecb;
-pub use aes::decrypt_aes_128_cbc;
-pub use aes::encrypt_aes_128_ecb;
-pub use aes::encrypt_aes_128_cbc;
pub use aes::aes_128_ctr;
pub use aes::aes_128_ctr_with_counter;
+pub use aes::decrypt_aes_128_cbc;
+pub use aes::decrypt_aes_128_ecb;
+pub use aes::encrypt_aes_128_cbc;
+pub use aes::encrypt_aes_128_ecb;
pub use base64::to_base64;
-pub use http::parse_query_string;
+pub use crack::clone_mersenne_twister_from_output;
+pub use crack::crack_aes_128_ctr_random_access;
+pub use crack::crack_cbc_bitflipping;
+pub use crack::crack_cbc_iv_key;
+pub use crack::crack_cbc_padding_oracle;
+pub use crack::crack_ctr_bitflipping;
+pub use crack::crack_fixed_nonce_ctr_statistically;
+pub use crack::crack_md4_mac_length_extension;
+pub use crack::crack_padded_aes_128_ecb;
+pub use crack::crack_padded_aes_128_ecb_with_prefix;
+pub use crack::crack_querystring_aes_128_ecb;
+pub use crack::crack_repeating_key_xor;
+pub use crack::crack_sha1_mac_length_extension;
+pub use crack::crack_single_byte_xor;
+pub use crack::detect_ecb_cbc;
+pub use crack::find_aes_128_ecb_encrypted_string;
+pub use crack::find_single_byte_xor_encrypted_string;
+pub use crack::recover_16_bit_mt19937_key;
+pub use crack::recover_mersenne_twister_seed_from_time;
+pub use crack::recover_mt19937_key_from_time;
+pub use crack::BlockCipherMode;
pub use http::create_query_string;
+pub use http::parse_query_string;
pub use md4::md4;
-pub use md4::pad_md4;
+pub use md4::md4_mac;
pub use md4::md4_padding;
pub use md4::md4_with_state;
-pub use md4::md4_mac;
+pub use md4::pad_md4;
pub use primitives::fixed_xor;
pub use primitives::pad_pkcs7;
-pub use primitives::unpad_pkcs7;
pub use primitives::repeating_key_xor;
-pub use random::MersenneTwister;
+pub use primitives::unpad_pkcs7;
pub use random::mt19937_stream_cipher;
-pub use sha1::sha1;
+pub use random::MersenneTwister;
pub use sha1::pad_sha1;
+pub use sha1::sha1;
+pub use sha1::sha1_hmac;
+pub use sha1::sha1_mac;
pub use sha1::sha1_padding;
pub use sha1::sha1_with_state;
-pub use sha1::sha1_mac;
-pub use sha1::sha1_hmac;
-pub use crack::BlockCipherMode;
-pub use crack::find_aes_128_ecb_encrypted_string;
-pub use crack::detect_ecb_cbc;
-pub use crack::crack_padded_aes_128_ecb;
-pub use crack::crack_padded_aes_128_ecb_with_prefix;
-pub use crack::crack_querystring_aes_128_ecb;
-pub use crack::crack_cbc_bitflipping;
-pub use crack::crack_cbc_padding_oracle;
-pub use crack::find_single_byte_xor_encrypted_string;
-pub use crack::crack_single_byte_xor;
-pub use crack::crack_repeating_key_xor;
-pub use crack::crack_fixed_nonce_ctr_statistically;
-pub use crack::recover_mersenne_twister_seed_from_time;
-pub use crack::clone_mersenne_twister_from_output;
-pub use crack::recover_16_bit_mt19937_key;
-pub use crack::recover_mt19937_key_from_time;
-pub use crack::crack_aes_128_ctr_random_access;
-pub use crack::crack_ctr_bitflipping;
-pub use crack::crack_cbc_iv_key;
-pub use crack::crack_sha1_mac_length_extension;
-pub use crack::crack_md4_mac_length_extension;
diff --git a/src/md4.rs b/src/md4.rs
index 4fd9121..6495ee2 100644
--- a/src/md4.rs
+++ b/src/md4.rs
@@ -1,40 +1,30 @@
-#[cfg(test)] use serialize::hex::ToHex;
+#[cfg(test)]
+use rustc_serialize::hex::ToHex;
-pub fn md4 (bytes: &[u8]) -> [u8; 16] {
+pub fn md4(bytes: &[u8]) -> [u8; 16] {
md4_with_state(
bytes,
- [
- 0x67452301,
- 0xEFCDAB89,
- 0x98BADCFE,
- 0x10325476,
- ],
- bytes.len() as u64
+ [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476],
+ bytes.len() as u64,
)
}
-pub fn pad_md4 (bytes: &[u8], len: u64) -> Vec<u8> {
- return bytes
- .iter()
- .map(|x| *x)
- .chain(md4_padding(len))
- .collect();
+pub fn pad_md4(bytes: &[u8], len: u64) -> Vec<u8> {
+ return bytes.iter().map(|x| *x).chain(md4_padding(len)).collect();
}
-pub fn md4_padding (len: u64) -> Vec<u8> {
+pub fn md4_padding(len: u64) -> Vec<u8> {
let ml: u64 = len * 8;
- let ml_bytes: [u8; 8] = unsafe {
- ::std::mem::transmute(ml.to_le())
- };
+ let ml_bytes: [u8; 8] = unsafe { std::mem::transmute(ml.to_le()) };
return [0x80u8]
.iter()
.map(|x| *x)
- .chain(::std::iter::repeat(0x00).take((119 - (len % 64) as usize) % 64))
+ .chain(std::iter::repeat(0x00).take((119 - (len % 64) as usize) % 64))
.chain(ml_bytes.iter().map(|x| *x))
.collect();
}
-fn round1 (offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
+fn round1(offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
let a = (4 - offset as usize) % 4;
let b = (5 - offset as usize) % 4;
let c = (6 - offset as usize) % 4;
@@ -46,7 +36,7 @@ fn round1 (offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
.rotate_left(s)
}
-fn round2 (offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
+fn round2(offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
let a = (4 - offset as usize) % 4;
let b = (5 - offset as usize) % 4;
let c = (6 - offset as usize) % 4;
@@ -59,7 +49,7 @@ fn round2 (offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
.rotate_left(s)
}
-fn round3 (offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
+fn round3(offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
let a = (4 - offset as usize) % 4;
let b = (5 - offset as usize) % 4;
let c = (6 - offset as usize) % 4;
@@ -72,67 +62,66 @@ fn round3 (offset: u32, x: u32, s: u32, h: &mut [u32; 4]) {
.rotate_left(s)
}
-pub fn md4_with_state (bytes: &[u8], mut h: [u32; 4], len: u64) -> [u8; 16] {
+pub fn md4_with_state(bytes: &[u8], mut h: [u32; 4], len: u64) -> [u8; 16] {
for chunk in pad_md4(bytes, len).chunks(64) {
- let chunk_words: &[u32; 16] = unsafe {
- ::std::mem::transmute(chunk.as_ptr())
- };
- let mut x: [u32; 16] = unsafe { ::std::mem::uninitialized() };
+ let chunk_words: &[u32; 16] =
+ unsafe { std::mem::transmute(chunk.as_ptr()) };
+ let mut x: [u32; 16] = unsafe { std::mem::uninitialized() };
for i in 0..16 {
x[i] = u32::from_le(chunk_words[i]);
}
let mut hh = h;
- round1(0, x[ 0], 3, &mut hh);
- round1(1, x[ 1], 7, &mut hh);
- round1(2, x[ 2], 11, &mut hh);
- round1(3, x[ 3], 19, &mut hh);
- round1(0, x[ 4], 3, &mut hh);
- round1(1, x[ 5], 7, &mut hh);
- round1(2, x[ 6], 11, &mut hh);
- round1(3, x[ 7], 19, &mut hh);
- round1(0, x[ 8], 3, &mut hh);
- round1(1, x[ 9], 7, &mut hh);
+ round1(0, x[0], 3, &mut hh);
+ round1(1, x[1], 7, &mut hh);
+ round1(2, x[2], 11, &mut hh);
+ round1(3, x[3], 19, &mut hh);
+ round1(0, x[4], 3, &mut hh);
+ round1(1, x[5], 7, &mut hh);
+ round1(2, x[6], 11, &mut hh);
+ round1(3, x[7], 19, &mut hh);
+ round1(0, x[8], 3, &mut hh);
+ round1(1, x[9], 7, &mut hh);
round1(2, x[10], 11, &mut hh);
round1(3, x[11], 19, &mut hh);
- round1(0, x[12], 3, &mut hh);
- round1(1, x[13], 7, &mut hh);
+ round1(0, x[12], 3, &mut hh);
+ round1(1, x[13], 7, &mut hh);
round1(2, x[14], 11, &mut hh);
round1(3, x[15], 19, &mut hh);
- round2(0, x[ 0], 3, &mut hh);
- round2(1, x[ 4], 5, &mut hh);
- round2(2, x[ 8], 9, &mut hh);
+ round2(0, x[0], 3, &mut hh);
+ round2(1, x[4], 5, &mut hh);
+ round2(2, x[8], 9, &mut hh);
round2(3, x[12], 13, &mut hh);
- round2(0, x[ 1], 3, &mut hh);
- round2(1, x[ 5], 5, &mut hh);
- round2(2, x[ 9], 9, &mut hh);
+ round2(0, x[1], 3, &mut hh);
+ round2(1, x[5], 5, &mut hh);
+ round2(2, x[9], 9, &mut hh);
round2(3, x[13], 13, &mut hh);
- round2(0, x[ 2], 3, &mut hh);
- round2(1, x[ 6], 5, &mut hh);
- round2(2, x[10], 9, &mut hh);
+ round2(0, x[2], 3, &mut hh);
+ round2(1, x[6], 5, &mut hh);
+ round2(2, x[10], 9, &mut hh);
round2(3, x[14], 13, &mut hh);
- round2(0, x[ 3], 3, &mut hh);
- round2(1, x[ 7], 5, &mut hh);
- round2(2, x[11], 9, &mut hh);
+ round2(0, x[3], 3, &mut hh);
+ round2(1, x[7], 5, &mut hh);
+ round2(2, x[11], 9, &mut hh);
round2(3, x[15], 13, &mut hh);
- round3(0, x[ 0], 3, &mut hh);
- round3(1, x[ 8], 9, &mut hh);
- round3(2, x[ 4], 11, &mut hh);
+ round3(0, x[0], 3, &mut hh);
+ round3(1, x[8], 9, &mut hh);
+ round3(2, x[4], 11, &mut hh);
round3(3, x[12], 15, &mut hh);
- round3(0, x[ 2], 3, &mut hh);
- round3(1, x[10], 9, &mut hh);
- round3(2, x[ 6], 11, &mut hh);
+ round3(0, x[2], 3, &mut hh);
+ round3(1, x[10], 9, &mut hh);
+ round3(2, x[6], 11, &mut hh);
round3(3, x[14], 15, &mut hh);
- round3(0, x[ 1], 3, &mut hh);
- round3(1, x[ 9], 9, &mut hh);
- round3(2, x[ 5], 11, &mut hh);
+ round3(0, x[1], 3, &mut hh);
+ round3(1, x[9], 9, &mut hh);
+ round3(2, x[5], 11, &mut hh);
round3(3, x[13], 15, &mut hh);
- round3(0, x[ 3], 3, &mut hh);
- round3(1, x[11], 9, &mut hh);
- round3(2, x[ 7], 11, &mut hh);
+ round3(0, x[3], 3, &mut hh);
+ round3(1, x[11], 9, &mut hh);
+ round3(2, x[7], 11, &mut hh);
round3(3, x[15], 15, &mut hh);
h[0] = h[0].wrapping_add(hh[0]);
@@ -145,20 +134,17 @@ pub fn md4_with_state (bytes: &[u8], mut h: [u32; 4], len: u64) -> [u8; 16] {
*word = word.to_le();
}
- return unsafe { ::std::mem::transmute(h) };
+ return unsafe { std::mem::transmute(h) };
}
-pub fn md4_mac (bytes: &[u8], key: &[u8]) -> [u8; 16] {
- let full_bytes: Vec<u8> = key
- .iter()
- .chain(bytes.iter())
- .map(|x| *x)
- .collect();
+pub fn md4_mac(bytes: &[u8], key: &[u8]) -> [u8; 16] {
+ let full_bytes: Vec<u8> =
+ key.iter().chain(bytes.iter()).map(|x| *x).collect();
return md4(&full_bytes[..]);
}
#[test]
-fn test_md4 () {
+fn test_md4() {
let tests = [
(
&b""[..],
diff --git a/src/primitives.rs b/src/primitives.rs
index d537081..6f178cc 100644
--- a/src/primitives.rs
+++ b/src/primitives.rs
@@ -1,36 +1,36 @@
-pub fn fixed_xor (bytes1: &[u8], bytes2: &[u8]) -> Vec<u8> {
- return bytes1.iter()
+pub fn fixed_xor(bytes1: &[u8], bytes2: &[u8]) -> Vec<u8> {
+ return bytes1
+ .iter()
.zip(bytes2.iter())
- .map(|(&a, &b)| { a ^ b })
+ .map(|(&a, &b)| a ^ b)
.collect();
}
-pub fn repeating_key_xor (plaintext: &[u8], key: &[u8]) -> Vec<u8> {
+pub fn repeating_key_xor(plaintext: &[u8], key: &[u8]) -> Vec<u8> {
return fixed_xor(
plaintext,
- &key
- .iter()
+ &key.iter()
.cycle()
.take(plaintext.len())
- .map(|c| *c)
- .collect::<Vec<u8>>()[..]
+ .cloned()
+ .collect::<Vec<u8>>()[..],
);
}
-pub fn hamming (bytes1: &[u8], bytes2: &[u8]) -> u64 {
+pub fn hamming(bytes1: &[u8], bytes2: &[u8]) -> u64 {
count_bits(&fixed_xor(bytes1, bytes2)[..])
}
-pub fn pad_pkcs7 (block: &[u8], blocksize: u8) -> Vec<u8> {
+pub fn pad_pkcs7(block: &[u8], blocksize: u8) -> Vec<u8> {
let padding_bytes = blocksize - (block.len() % blocksize as usize) as u8;
return block
.iter()
- .map(|c| *c)
- .chain(::std::iter::repeat(padding_bytes).take(padding_bytes as usize))
+ .cloned()
+ .chain(std::iter::repeat(padding_bytes).take(padding_bytes as usize))
.collect();
}
-pub fn unpad_pkcs7 (block: &[u8]) -> Option<&[u8]> {
+pub fn unpad_pkcs7(block: &[u8]) -> Option<&[u8]> {
let padding_byte = block[block.len() - 1];
let padding_len = padding_byte as usize;
if padding_len > block.len() || padding_len == 0 {
@@ -40,28 +40,30 @@ pub fn unpad_pkcs7 (block: &[u8]) -> Option<&[u8]> {
let real_len = block.len() - padding_len;
if block[real_len..].iter().all(|&c| c == padding_byte) {
return Some(&block[..real_len]);
- }
- else {
+ } else {
return None;
}
}
-fn count_bits (bytes: &[u8]) -> u64 {
- bytes.iter().map(|&c| { count_bits_byte(c) }).fold(0, |acc, n| acc + n)
+fn count_bits(bytes: &[u8]) -> u64 {
+ bytes
+ .iter()
+ .map(|&c| count_bits_byte(c))
+ .fold(0, |acc, n| acc + n)
}
-fn count_bits_byte (byte: u8) -> u64 {
+fn count_bits_byte(byte: u8) -> u64 {
(((byte & (0x01 << 0)) >> 0)
- + ((byte & (0x01 << 1)) >> 1)
- + ((byte & (0x01 << 2)) >> 2)
- + ((byte & (0x01 << 3)) >> 3)
- + ((byte & (0x01 << 4)) >> 4)
- + ((byte & (0x01 << 5)) >> 5)
- + ((byte & (0x01 << 6)) >> 6)
- + ((byte & (0x01 << 7)) >> 7)) as u64
+ + ((byte & (0x01 << 1)) >> 1)
+ + ((byte & (0x01 << 2)) >> 2)
+ + ((byte & (0x01 << 3)) >> 3)
+ + ((byte & (0x01 << 4)) >> 4)
+ + ((byte & (0x01 << 5)) >> 5)
+ + ((byte & (0x01 << 6)) >> 6)
+ + ((byte & (0x01 << 7)) >> 7)) as u64
}
#[test]
-fn test_hamming () {
+fn test_hamming() {
assert_eq!(hamming(b"this is a test", b"wokka wokka!!!"), 37);
}
diff --git a/src/random.rs b/src/random.rs
index e248293..69bab3f 100644
--- a/src/random.rs
+++ b/src/random.rs
@@ -1,18 +1,91 @@
-use rand::{Rand, Rng, SeedableRng};
+use rand::{Rng, RngCore, SeedableRng};
pub struct MersenneTwister {
state: [u32; 624],
- index: usize,
+ index: u32,
+}
+
+pub struct MersenneTwisterSeed([u8; 2500]);
+
+impl Default for MersenneTwisterSeed {
+ fn default() -> MersenneTwisterSeed {
+ MersenneTwisterSeed([0; 2500])
+ }
+}
+
+impl AsMut<[u8]> for MersenneTwisterSeed {
+ fn as_mut(&mut self) -> &mut [u8] {
+ &mut self.0
+ }
+}
+
+fn mt_seed_to_state(seed: MersenneTwisterSeed) -> MersenneTwister {
+ let mut state = [0; 624];
+ for i in 0..624 {
+ let idx = i * 4;
+ state[i] = u32::from_ne_bytes([
+ seed.0[idx],
+ seed.0[idx + 1],
+ seed.0[idx + 2],
+ seed.0[idx + 3],
+ ]);
+ }
+ let index = u32::from_ne_bytes([
+ seed.0[2496],
+ seed.0[2497],
+ seed.0[2498],
+ seed.0[2499],
+ ]) % 624;
+ MersenneTwister { state, index }
+}
+
+fn mt_state_to_seed(state: [u32; 624], index: u32) -> MersenneTwisterSeed {
+ let mut seed = MersenneTwisterSeed([0; 2500]);
+ let mut idx = 0;
+ for i in &state[..] {
+ let bytes = u32::to_ne_bytes(*i);
+ seed.0[idx as usize] = bytes[0];
+ seed.0[(idx + 1) as usize] = bytes[1];
+ seed.0[(idx + 2) as usize] = bytes[2];
+ seed.0[(idx + 3) as usize] = bytes[3];
+ idx += 4;
+ }
+ let bytes = u32::to_ne_bytes(index);
+ seed.0[2496] = bytes[0];
+ seed.0[2497] = bytes[1];
+ seed.0[2498] = bytes[2];
+ seed.0[2499] = bytes[3];
+ seed
}
impl MersenneTwister {
- fn new_unseeded () -> MersenneTwister {
- MersenneTwister { state: [0; 624], index: 0 }
+ fn new_unseeded() -> MersenneTwister {
+ MersenneTwister {
+ state: [0; 624],
+ index: 0,
+ }
+ }
+
+ pub fn from_u32(seed: u32) -> MersenneTwister {
+ let mut state = [0; 624];
+ state[0] = seed;
+ for i in 1..624 {
+ let prev = state[i - 1];
+ state[i] = 1812433253u32
+ .wrapping_mul(prev ^ (prev >> 30))
+ .wrapping_add(i as u32);
+ }
+
+ MersenneTwister::from_seed(mt_state_to_seed(state, 0))
+ }
+
+ pub fn from_state(state: [u32; 624], index: u32) -> MersenneTwister {
+ MersenneTwister::from_seed(mt_state_to_seed(state, index))
}
}
-impl Rng for MersenneTwister {
- fn next_u32 (&mut self) -> u32 {
+impl RngCore for MersenneTwister {
+ fn next_u32(&mut self) -> u32 {
if self.index == 0 {
for i in 0..624 {
let y = (self.state[i] & 0x80000000)
@@ -24,7 +97,7 @@ impl Rng for MersenneTwister {
}
}
- let mut y = self.state[self.index];
+ let mut y = self.state[self.index as usize];
y = y ^ (y >> 11);
y = y ^ ((y << 7) & 0x9d2c5680);
y = y ^ ((y << 15) & 0xefc60000);
@@ -34,73 +107,68 @@ impl Rng for MersenneTwister {
return y;
}
-}
-impl SeedableRng<u32> for MersenneTwister {
- fn reseed (&mut self, seed: u32) {
- self.state[0] = seed;
- for i in 1..624 {
- let prev = self.state[i - 1];
- self.state[i] = 1812433253u32
- .wrapping_mul(prev ^ (prev >> 30))
- .wrapping_add(i as u32);
- }
+ fn next_u64(&mut self) -> u64 {
+ rand_core::impls::next_u64_via_u32(self)
}
- fn from_seed (seed: u32) -> MersenneTwister {
- let mut mt = MersenneTwister::new_unseeded();
- mt.reseed(seed);
- mt
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ rand_core::impls::fill_bytes_via_next(self, dest)
}
-}
-impl SeedableRng<([u32; 624], usize)> for MersenneTwister {
- fn reseed (&mut self, seed: ([u32; 624], usize)) {
- let (state, index) = seed;
- for i in 0..624 {
- self.state[i] = state[i];
- }
- self.index = index;
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
+ Ok(rand_core::impls::fill_bytes_via_next(self, dest))
}
+}
- fn from_seed (seed: ([u32; 624], usize)) -> MersenneTwister {
+impl SeedableRng for MersenneTwister {
+ type Seed = MersenneTwisterSeed;
+
+ fn from_seed(seed: MersenneTwisterSeed) -> MersenneTwister {
let mut mt = MersenneTwister::new_unseeded();
- mt.reseed(seed);
+ let MersenneTwister { state, index } = mt_seed_to_state(seed);
+ for i in 0..624 {
+ mt.state[i] = state[i];
+ }
+ mt.index = index;
mt
}
}
-impl Rand for MersenneTwister {
- fn rand<R: Rng> (other: &mut R) -> MersenneTwister {
- MersenneTwister::from_seed(other.next_u32())
- }
-}
-
impl Clone for MersenneTwister {
- fn clone (&self) -> MersenneTwister {
- MersenneTwister { state: self.state, index: self.index }
+ fn clone(&self) -> MersenneTwister {
+ MersenneTwister {
+ state: self.state,
+ index: self.index,
+ }
}
}
-impl ::std::fmt::Debug for MersenneTwister {
- fn fmt (&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
- try!(write!(f, "MersenneTwister {{ "));
- try!(::std::fmt::Debug::fmt(&&self.state[..], f));
- try!(write!(f, ", "));
- try!(::std::fmt::Debug::fmt(&self.index, f));
+impl std::fmt::Debug for MersenneTwister {
+ fn fmt(
+ &self,
+ f: &mut std::fmt::Formatter,
+ ) -> Result<(), std::fmt::Error> {
+ write!(f, "MersenneTwister {{ ")?;
+ std::fmt::Debug::fmt(&&self.state[..], f)?;
+ write!(f, ", ")?;
+ std::fmt::Debug::fmt(&self.index, f)?;
write!(f, " }}")
}
}
-pub fn mt19937_stream_cipher (ciphertext: &[u8], key: u32) -> Vec<u8> {
- let mut mt = MersenneTwister::from_seed(key);
- let keystream: Vec<u8> = mt.gen_iter().take(ciphertext.len()).collect();
- return ::primitives::fixed_xor(ciphertext, &keystream[..]);
+pub fn mt19937_stream_cipher(ciphertext: &[u8], key: u32) -> Vec<u8> {
+ let mut mt = MersenneTwister::from_u32(key);
+ let keystream: Vec<u8> = mt
+ .sample_iter(&rand::distributions::Standard)
+ .take(ciphertext.len())
+ .collect();
+ return crate::primitives::fixed_xor(ciphertext, &keystream[..]);
}
#[test]
-fn test_mt19937_stream_cipher () {
- let key = ::rand::thread_rng().gen();
+fn test_mt19937_stream_cipher() {
+ let key = rand::thread_rng().gen();
let plaintext = b"Summertime and the wind is blowing outside in lower \
Chelsea and I don't know what I'm doing in the city, the \
sun is always in my eyes";
diff --git a/src/sha1.rs b/src/sha1.rs
index 95270b0..7969b21 100644
--- a/src/sha1.rs
+++ b/src/sha1.rs
@@ -1,53 +1,42 @@
-#[cfg(test)] use serialize::hex::ToHex;
+#[cfg(test)]
+use rustc_serialize::hex::ToHex;
-use primitives::fixed_xor;
+use crate::primitives::fixed_xor;
-pub fn sha1 (bytes: &[u8]) -> [u8; 20] {
+pub fn sha1(bytes: &[u8]) -> [u8; 20] {
sha1_with_state(
bytes,
- [
- 0x67452301,
- 0xEFCDAB89,
- 0x98BADCFE,
- 0x10325476,
- 0xC3D2E1F0,
- ],
- bytes.len() as u64
+ [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0],
+ bytes.len() as u64,
)
}
-pub fn pad_sha1 (bytes: &[u8], len: u64) -> Vec<u8> {
- return bytes
- .iter()
- .map(|x| *x)
- .chain(sha1_padding(len))
- .collect();
+pub fn pad_sha1(bytes: &[u8], len: u64) -> Vec<u8> {
+ return bytes.iter().map(|x| *x).chain(sha1_padding(len)).collect();
}
-pub fn sha1_padding (len: u64) -> Vec<u8> {
+pub fn sha1_padding(len: u64) -> Vec<u8> {
let ml: u64 = len * 8;
- let ml_bytes: [u8; 8] = unsafe {
- ::std::mem::transmute(ml.to_be())
- };
+ let ml_bytes: [u8; 8] = unsafe { std::mem::transmute(ml.to_be()) };
return [0x80u8]
.iter()
.map(|x| *x)
- .chain(::std::iter::repeat(0x00).take((119 - (len % 64) as usize) % 64))
+ .chain(std::iter::repeat(0x00).take((119 - (len % 64) as usize) % 64))
.chain(ml_bytes.iter().map(|x| *x))
.collect();
}
-pub fn sha1_with_state (bytes: &[u8], mut h: [u32; 5], len: u64) -> [u8; 20] {
+pub fn sha1_with_state(bytes: &[u8], mut h: [u32; 5], len: u64) -> [u8; 20] {
for chunk in pad_sha1(bytes, len).chunks(64) {
- let chunk_words: &[u32; 16] = unsafe {
- ::std::mem::transmute(chunk.as_ptr())
- };
- let mut w: [u32; 80] = unsafe { ::std::mem::uninitialized() };
+ let chunk_words: &[u32; 16] =
+ unsafe { std::mem::transmute(chunk.as_ptr()) };
+ let mut w: [u32; 80] = unsafe { std::mem::uninitialized() };
for i in 0..16 {
w[i] = u32::from_be(chunk_words[i]);
}
for i in 16..80 {
- w[i] = (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]).rotate_left(1);
+ w[i] =
+ (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]).rotate_left(1);
}
let mut a = h[0];
@@ -58,14 +47,15 @@ pub fn sha1_with_state (bytes: &[u8], mut h: [u32; 5], len: u64) -> [u8; 20] {
for i in 0..80 {
let (f, k) = match i {
- 0...19 => ((b & c) | (!b & d), 0x5A827999),
- 20...39 => (b ^ c ^ d, 0x6ED9EBA1),
+ 0...19 => ((b & c) | (!b & d), 0x5A827999),
+ 20...39 => (b ^ c ^ d, 0x6ED9EBA1),
40...59 => ((b & c) | (b & d) | (c & d), 0x8F1BBCDC),
- 60...79 => (b ^ c ^ d, 0xCA62C1D6),
+ 60...79 => (b ^ c ^ d, 0xCA62C1D6),
_ => panic!(),
};
- let temp = a.rotate_left(5)
+ let temp = a
+ .rotate_left(5)
.wrapping_add(f)
.wrapping_add(e)
.wrapping_add(k)
@@ -89,60 +79,62 @@ pub fn sha1_with_state (bytes: &[u8], mut h: [u32; 5], len: u64) -> [u8; 20] {
*word = word.to_be();
}
- return unsafe { ::std::mem::transmute(h) };
+ return unsafe { std::mem::transmute(h) };
}
-pub fn sha1_mac (bytes: &[u8], key: &[u8]) -> [u8; 20] {
- let full_bytes: Vec<u8> = key
- .iter()
- .chain(bytes.iter())
- .map(|x| *x)
- .collect();
+pub fn sha1_mac(bytes: &[u8], key: &[u8]) -> [u8; 20] {
+ let full_bytes: Vec<u8> =
+ key.iter().chain(bytes.iter()).map(|x| *x).collect();
return sha1(&full_bytes[..]);
}
-pub fn sha1_hmac (bytes: &[u8], key: &[u8]) -> [u8; 20] {
+pub fn sha1_hmac(bytes: &[u8], key: &[u8]) -> [u8; 20] {
let blocksize = 64;
let fixed_key: Vec<u8> = if key.len() > blocksize {
- sha1(key).iter()
+ sha1(key)
+ .iter()
.map(|x| *x)
.chain(::std::iter::repeat(0x00u8).take(44))
.collect()
- }
- else {
+ } else {
key.iter()
.map(|x| *x)
.chain(::std::iter::repeat(0x00u8).take(blocksize - key.len()))
.collect()
};
- let ipad: Vec<u8> = ::std::iter::repeat(0x36u8).take(blocksize).collect();
- let opad: Vec<u8> = ::std::iter::repeat(0x5cu8).take(blocksize).collect();
+ let ipad: Vec<u8> = std::iter::repeat(0x36u8).take(blocksize).collect();
+ let opad: Vec<u8> = std::iter::repeat(0x5cu8).take(blocksize).collect();
let k_ipad = fixed_xor(&ipad[..], &fixed_key[..]);
let k_opad = fixed_xor(&opad[..], &fixed_key[..]);
let inner = sha1(
- &k_ipad.iter().chain(bytes.iter()).map(|x| *x).collect::<Vec<u8>>()[..]
+ &k_ipad
+ .iter()
+ .chain(bytes.iter())
+ .map(|x| *x)
+ .collect::<Vec<u8>>()[..],
);
return sha1(
- &k_opad.iter().chain(inner.iter()).map(|x| *x).collect::<Vec<u8>>()[..]
- )
+ &k_opad
+ .iter()
+ .chain(inner.iter())
+ .map(|x| *x)
+ .collect::<Vec<u8>>()[..],
+ );
}
#[test]
-fn test_sha1 () {
+fn test_sha1() {
let tests = [
- (
- &b""[..],
- "da39a3ee5e6b4b0d3255bfef95601890afd80709"
- ),
+ (&b""[..], "da39a3ee5e6b4b0d3255bfef95601890afd80709"),
(
&b"The quick brown fox jumps over the lazy dog"[..],
- "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"
+ "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
),
(
&b"The quick brown fox jumps over the lazy cog"[..],
- "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3"
+ "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3",
),
];
for &(input, expected) in tests.iter() {
@@ -152,7 +144,10 @@ fn test_sha1 () {
}
#[test]
-fn test_sha1_hmac () {
- assert_eq!(&sha1_hmac(b"", b"")[..].to_hex(), "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d");
+fn test_sha1_hmac() {
+ assert_eq!(
+ &sha1_hmac(b"", b"")[..].to_hex(),
+ "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d"
+ );
assert_eq!(&sha1_hmac(b"The quick brown fox jumps over the lazy dog", b"key")[..].to_hex(), "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9");
}
diff --git a/tests/set1.rs b/tests/set1.rs
index c9eece7..e1dacd1 100644
--- a/tests/set1.rs
+++ b/tests/set1.rs
@@ -6,10 +6,12 @@ use serialize::hex::FromHex;
mod util;
#[test]
-fn problem_1 () {
+fn problem_1() {
let hex = "49276d206b696c6c696e6720796f757220627261\
696e206c696b65206120706f69736f6e6f757320\
- 6d757368726f6f6d".from_hex().unwrap();
+ 6d757368726f6f6d"
+ .from_hex()
+ .unwrap();
let base64 = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEg\
cG9pc29ub3VzIG11c2hyb29t";
let got = matasano::to_base64(&hex[..]);
@@ -17,7 +19,7 @@ fn problem_1 () {
}
#[test]
-fn problem_2 () {
+fn problem_2() {
let bytes1 = "1c0111001f010100061a024b53535009181c".from_hex().unwrap();
let bytes2 = "686974207468652062756c6c277320657965".from_hex().unwrap();
let expected = "746865206b696420646f6e277420706c6179".from_hex().unwrap();
@@ -26,16 +28,18 @@ fn problem_2 () {
}
#[test]
-fn problem_3 () {
+fn problem_3() {
let ciphertext = "1b37373331363f78151b7f2b783431333d783978\
- 28372d363c78373e783a393b3736".from_hex().unwrap();
+ 28372d363c78373e783a393b3736"
+ .from_hex()
+ .unwrap();
let plaintext = b"Cooking MC's like a pound of bacon";
let got = matasano::crack_single_byte_xor(&ciphertext[..]);
assert_eq!(got, &plaintext[..]);
}
#[test]
-fn problem_4 () {
+fn problem_4() {
let possibles = util::read_as_hex_lines("data/4.txt");
let plaintext = b"Now that the party is jumping\n";
let got = matasano::find_single_byte_xor_encrypted_string(&possibles[..]);
@@ -43,20 +47,22 @@ fn problem_4 () {
}
#[test]
-fn problem_5 () {
+fn problem_5() {
let plaintext = b"Burning 'em, if you ain't quick and nimble\n\
I go crazy when I hear a cymbal";
let key = b"ICE";
let ciphertext = "0b3637272a2b2e63622c2e69692a23693a2a3c63\
24202d623d63343c2a26226324272765272a282b\
2f20430a652e2c652a3124333a653e2b2027630c\
- 692b20283165286326302e27282f".from_hex().unwrap();
+ 692b20283165286326302e27282f"
+ .from_hex()
+ .unwrap();
let got = matasano::repeating_key_xor(plaintext, key);
assert_eq!(got, ciphertext);
}
#[test]
-fn problem_6 () {
+fn problem_6() {
let ciphertext = util::read_as_base64("data/6.txt");
let plaintext = util::read("data/6.out.txt");
let key = matasano::crack_repeating_key_xor(&ciphertext[..]);
@@ -65,16 +71,16 @@ fn problem_6 () {
}
#[test]
-fn problem_7 () {
+fn problem_7() {
let ciphertext = util::read_as_base64("data/7.txt");
let key = b"YELLOW SUBMARINE";
let plaintext = util::read("data/7.out.txt");
let got = matasano::decrypt_aes_128_ecb(&ciphertext[..], key);
- assert_eq!(got, Some(plaintext));
+ assert_eq!(got, plaintext);
}
#[test]
-fn problem_8 () {
+fn problem_8() {
let possibles = util::read_as_hex_lines("data/8.txt");
let ciphertext = "d880619740a8a19b7840a8a31c810a3d08649af7\
0dc06f4fd5d2d69c744cd283e2dd052f6b641dbf\
@@ -84,7 +90,8 @@ fn problem_8 () {
8d6aecd566489154789a6b0308649af70dc06f4f\
d5d2d69c744cd283d403180c98c8f6db1f2a3f9c\
4040deb0ab51b29933f2c123c58386b06fba186a"
- .from_hex().unwrap();
+ .from_hex()
+ .unwrap();
let got = matasano::find_aes_128_ecb_encrypted_string(&possibles[..]);
assert_eq!(got, ciphertext);
}
diff --git a/tests/set2.rs b/tests/set2.rs
index 84f55b5..d5cc5d5 100644
--- a/tests/set2.rs
+++ b/tests/set2.rs
@@ -1,6 +1,6 @@
extern crate matasano;
-extern crate rustc_serialize as serialize;
extern crate rand;
+extern crate rustc_serialize as serialize;
use std::borrow::ToOwned;
use std::collections::HashMap;
@@ -11,14 +11,14 @@ use serialize::base64::FromBase64;
mod util;
#[test]
-fn problem_9 () {
+fn problem_9() {
let block = b"YELLOW SUBMARINE";
let got = matasano::pad_pkcs7(block, 20);
assert_eq!(got, b"YELLOW SUBMARINE\x04\x04\x04\x04");
}
#[test]
-fn problem_10 () {
+fn problem_10() {
let ciphertext = util::read_as_base64("data/10.txt");
let key = b"YELLOW SUBMARINE";
let plaintext = util::read("data/10.out.txt");
@@ -27,16 +27,17 @@ fn problem_10 () {
}
#[test]
-fn problem_11 () {
- static mut last_mode: matasano::BlockCipherMode = matasano::BlockCipherMode::ECB;
+fn problem_11() {
+ static mut LAST_MODE: matasano::BlockCipherMode =
+ matasano::BlockCipherMode::ECB;
- fn random_padding (input: &[u8]) -> Vec<u8> {
+ fn random_padding(input: &[u8]) -> Vec<u8> {
let front_padding: Vec<u8> = rand::thread_rng()
- .gen_iter()
+ .sample_iter(&rand::distributions::Standard)
.take(rand::thread_rng().gen_range(5, 10))
.collect();
let back_padding: Vec<u8> = rand::thread_rng()
- .gen_iter()
+ .sample_iter(&rand::distributions::Standard)
.take(rand::thread_rng().gen_range(5, 10))
.collect();
return front_padding
@@ -44,47 +45,48 @@ fn problem_11 () {
.chain(input.iter())
.chain(back_padding.iter())
.map(|x| *x)
- .collect()
+ .collect();
}
- fn random_encrypter (input: &[u8]) -> Vec<u8> {
+ fn random_encrypter(input: &[u8]) -> Vec<u8> {
let key = util::random_aes_128_key();
let padded_input = random_padding(input);
if util::coinflip() {
unsafe {
- last_mode = matasano::BlockCipherMode::ECB;
+ LAST_MODE = matasano::BlockCipherMode::ECB;
}
return matasano::encrypt_aes_128_ecb(&padded_input[..], &key[..]);
- }
- else {
+ } else {
unsafe {
- last_mode = matasano::BlockCipherMode::CBC;
+ LAST_MODE = matasano::BlockCipherMode::CBC;
}
let iv = util::random_aes_128_key();
- return matasano::encrypt_aes_128_cbc(&padded_input[..], &key[..], &iv[..]);
+ return matasano::encrypt_aes_128_cbc(
+ &padded_input[..],
+ &key[..],
+ &iv[..],
+ );
}
}
for _ in 0..100 {
let got = matasano::detect_ecb_cbc(&random_encrypter, 16);
- let expected = unsafe { &last_mode };
+ let expected = unsafe { &LAST_MODE };
assert_eq!(&got, expected);
}
}
#[test]
-fn problem_12 () {
+fn problem_12() {
let padding = b"Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWct\
dG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpU\
aGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq\
dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5v\
- LCBJIGp1c3QgZHJvdmUgYnkK".from_base64().unwrap();
+ LCBJIGp1c3QgZHJvdmUgYnkK"
+ .from_base64()
+ .unwrap();
let fixed_padding = |input: &[u8]| -> Vec<u8> {
- return input
- .iter()
- .chain(padding.iter())
- .map(|x| *x)
- .collect()
+ return input.iter().chain(padding.iter()).map(|x| *x).collect();
};
let key = util::random_aes_128_key();
@@ -98,8 +100,8 @@ fn problem_12 () {
}
#[test]
-fn problem_13 () {
- fn profile_for (email: &str) -> String {
+fn problem_13() {
+ fn profile_for(email: &str) -> String {
let mut params = HashMap::new();
params.insert("email", email);
params.insert("uid", "10");
@@ -112,40 +114,42 @@ fn problem_13 () {
matasano::encrypt_aes_128_ecb(profile_for(email).as_bytes(), &key[..])
};
let decrypter = |ciphertext: &[u8]| -> Option<HashMap<String, String>> {
- let plaintext = matasano::decrypt_aes_128_ecb(ciphertext, &key[..]).unwrap();
+ let plaintext = matasano::decrypt_aes_128_ecb(ciphertext, &key[..]);
let plaintext_str = std::str::from_utf8(&plaintext[..]).unwrap();
if let Some(params) = matasano::parse_query_string(plaintext_str) {
return Some(
params
- .into_iter()
- .map(|(k, v)| (k.to_owned(), v.to_owned()))
- .collect()
+ .into_iter()
+ .map(|(k, v)| (k.to_owned(), v.to_owned()))
+ .collect(),
);
- }
- else {
+ } else {
return None;
}
};
- let (email, ciphertexts) = matasano::crack_querystring_aes_128_ecb(&encrypter);
+ let (email, ciphertexts) =
+ matasano::crack_querystring_aes_128_ecb(&encrypter);
let mut expected = HashMap::new();
expected.insert("email".to_owned(), email);
expected.insert("uid".to_owned(), "10".to_owned());
expected.insert("role".to_owned(), "admin".to_owned());
- assert!(ciphertexts.iter().any(|ciphertext| {
- decrypter(ciphertext).map(|params| params == expected).unwrap_or(false)
- }));
+ assert!(ciphertexts.iter().any(|ciphertext| decrypter(ciphertext)
+ .map(|params| params == expected)
+ .unwrap_or(false)));
}
#[test]
-fn problem_14 () {
+fn problem_14() {
let padding = b"Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWct\
dG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpU\
aGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq\
dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5v\
- LCBJIGp1c3QgZHJvdmUgYnkK".from_base64().unwrap();
+ LCBJIGp1c3QgZHJvdmUgYnkK"
+ .from_base64()
+ .unwrap();
let front_padding: Vec<u8> = rand::thread_rng()
- .gen_iter()
+ .sample_iter(&rand::distributions::Standard)
.take(rand::thread_rng().gen_range(1, 100))
.collect();
let fixed_padding = |input: &[u8]| -> Vec<u8> {
@@ -154,7 +158,7 @@ fn problem_14 () {
.chain(input.iter())
.chain(padding.iter())
.map(|x| *x)
- .collect()
+ .collect();
};
let key = util::random_aes_128_key();
@@ -163,36 +167,25 @@ fn problem_14 () {
return matasano::encrypt_aes_128_ecb(&padded_input[..], &key[..]);
};
- let got = matasano::crack_padded_aes_128_ecb_with_prefix(&random_encrypter);
+ let got =
+ matasano::crack_padded_aes_128_ecb_with_prefix(&random_encrypter);
assert_eq!(got, padding);
}
#[test]
-fn problem_15 () {
+fn problem_15() {
assert_eq!(
matasano::unpad_pkcs7(b"ICE ICE BABY\x04\x04\x04\x04"),
Some(&b"ICE ICE BABY"[..])
);
- assert_eq!(
- matasano::unpad_pkcs7(b"ICE ICE BABY\x05\x05\x05\x05"),
- None
- );
- assert_eq!(
- matasano::unpad_pkcs7(b"ICE ICE BABY\x01\x02\x03\x04"),
- None
- );
- assert_eq!(
- matasano::unpad_pkcs7(b"ICE ICE BABY\x00"),
- None
- );
- assert_eq!(
- matasano::unpad_pkcs7(b"\x04\x04\x04\x04"),
- Some(&b""[..])
- );
+ assert_eq!(matasano::unpad_pkcs7(b"ICE ICE BABY\x05\x05\x05\x05"), None);
+ assert_eq!(matasano::unpad_pkcs7(b"ICE ICE BABY\x01\x02\x03\x04"), None);
+ assert_eq!(matasano::unpad_pkcs7(b"ICE ICE BABY\x00"), None);
+ assert_eq!(matasano::unpad_pkcs7(b"\x04\x04\x04\x04"), Some(&b""[..]));
}
#[test]
-fn problem_16 () {
+fn problem_16() {
let key = util::random_aes_128_key();
let iv = util::random_aes_128_key();
let prefix = "comment1=cooking%20MCs;userdata=";
@@ -200,7 +193,10 @@ fn problem_16 () {
let admin = ";admin=true;";
let escape = |input: &str| {
- input.replace("%", "%25").replace(";", "%3B").replace("=", "%3D")
+ input
+ .replace("%", "%25")
+ .replace(";", "%3B")
+ .replace("=", "%3D")
};
let encode = |input: &str| -> Vec<u8> {
@@ -211,11 +207,17 @@ fn problem_16 () {
.chain(suffix.as_bytes().iter())
.map(|x| *x)
.collect();
- return matasano::encrypt_aes_128_cbc(&plaintext[..], &key[..], &iv[..]);
+ return matasano::encrypt_aes_128_cbc(
+ &plaintext[..],
+ &key[..],
+ &iv[..],
+ );
};
let verify = |ciphertext: &[u8]| -> bool {
- let plaintext = matasano::decrypt_aes_128_cbc(ciphertext, &key[..], &iv[..]).unwrap();
+ let plaintext =
+ matasano::decrypt_aes_128_cbc(ciphertext, &key[..], &iv[..])
+ .unwrap();
return (0..(plaintext.len() - admin.len())).any(|i| {
plaintext
.iter()
diff --git a/tests/set3.rs b/tests/set3.rs
index 77b3371..4cbd9e2 100644
--- a/tests/set3.rs
+++ b/tests/set3.rs
@@ -1,16 +1,14 @@
extern crate matasano;
-extern crate rustc_serialize as serialize;
extern crate rand;
+extern crate rustc_serialize as serialize;
-use std::ascii::AsciiExt;
-
-use rand::{Rng, SeedableRng};
+use rand::{FromEntropy, Rng};
use serialize::base64::FromBase64;
mod util;
#[test]
-fn problem_17 () {
+fn problem_17() {
let strings = [
&b"MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc="[..],
&b"MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic="[..],
@@ -25,24 +23,21 @@ fn problem_17 () {
];
let key = util::random_aes_128_key();
- static mut chosen_plaintext_idx: usize = 0;
+ static mut CHOSEN_PLAINTEXT_IDX: usize = 0;
let encrypter = || {
let idx = rand::thread_rng().gen_range(0, strings.len());
let plaintext = strings[idx].from_base64().unwrap();
- unsafe { chosen_plaintext_idx = idx };
+ unsafe { CHOSEN_PLAINTEXT_IDX = idx };
let iv = util::random_aes_128_key();
return (
iv,
- matasano::encrypt_aes_128_cbc(&plaintext[..], &key[..], &iv[..])
+ matasano::encrypt_aes_128_cbc(&plaintext[..], &key[..], &iv[..]),
);
};
let validator = |iv: &[u8], ciphertext: &[u8]| {
- let plaintext = matasano::decrypt_aes_128_cbc(
- ciphertext,
- &key[..],
- &iv[..]
- );
+ let plaintext =
+ matasano::decrypt_aes_128_cbc(ciphertext, &key[..], &iv[..]);
return plaintext.is_some();
};
@@ -51,24 +46,23 @@ fn problem_17 () {
let plaintext = matasano::crack_cbc_padding_oracle(
&iv[..],
&ciphertext[..],
- &validator
+ &validator,
);
- let idx = unsafe { chosen_plaintext_idx.clone() };
+ let idx = unsafe { CHOSEN_PLAINTEXT_IDX.clone() };
let expected = strings[idx].from_base64().unwrap();
assert_eq!(plaintext, expected);
}
}
#[test]
-fn problem_18 () {
+fn problem_18() {
let ciphertext = b"L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syL\
- XzhPweyyMTJULu/6/kXX0KSvoOLSFQ==".from_base64().unwrap();
- let plaintext = &b"Yo, VIP Let's kick it Ice, Ice, baby Ice, Ice, baby "[..];
- let got = matasano::aes_128_ctr(
- &ciphertext[..],
- b"YELLOW SUBMARINE",
- 0
- );
+ XzhPweyyMTJULu/6/kXX0KSvoOLSFQ=="
+ .from_base64()
+ .unwrap();
+ let plaintext =
+ &b"Yo, VIP Let's kick it Ice, Ice, baby Ice, Ice, baby "[..];
+ let got = matasano::aes_128_ctr(&ciphertext[..], b"YELLOW SUBMARINE", 0);
assert_eq!(got, plaintext);
}
@@ -83,8 +77,8 @@ fn problem_18 () {
// }
#[test]
-fn problem_20 () {
- fn normalize (line_list: Vec<Vec<u8>>, len: usize) -> Vec<Vec<u8>> {
+fn problem_20() {
+ fn normalize(line_list: Vec<Vec<u8>>, len: usize) -> Vec<Vec<u8>> {
line_list
.iter()
.map(|line| line.to_ascii_lowercase())
@@ -99,20 +93,19 @@ fn problem_20 () {
.collect();
let expected = util::read_as_lines("data/20.out.txt");
- let plaintexts = matasano::crack_fixed_nonce_ctr_statistically(
- ciphertexts
- );
+ let plaintexts =
+ matasano::crack_fixed_nonce_ctr_statistically(ciphertexts);
- assert_eq!(
- normalize(plaintexts, 27),
- normalize(expected, 27)
- );
+ assert_eq!(normalize(plaintexts, 27), normalize(expected, 27));
}
#[test]
-fn problem_21 () {
- let mut mt = matasano::MersenneTwister::from_seed(0x12345678);
- let got: Vec<u32> = mt.gen_iter().take(10).collect();
+fn problem_21() {
+ let mut mt = matasano::MersenneTwister::from_u32(0x12345678);
+ let got: Vec<u32> = mt
+ .sample_iter(&rand::distributions::Standard)
+ .take(10)
+ .collect();
let expected: Vec<u32> = vec![
0xC6979343, 0x0962D2FA, 0xA73A24A4, 0xE118A180, 0xB5475ABB,
0x64613C7C, 0x6F32F4DB, 0xF27BF199, 0x464DD8DC, 0x95C1FED6,
@@ -121,20 +114,24 @@ fn problem_21 () {
}
#[test]
-fn problem_22 () {
+fn problem_22() {
// std::thread::sleep_ms(rand::thread_rng().gen_range(40, 1000) * 1000);
let seed = util::now();
- let mut mt = matasano::MersenneTwister::from_seed(seed);
+ let mut mt = matasano::MersenneTwister::from_u32(seed);
// std::thread::sleep_ms(rand::thread_rng().gen_range(40, 1000) * 1000);
let output: u32 = mt.gen();
- let got = matasano::recover_mersenne_twister_seed_from_time(output).unwrap();
+ let got =
+ matasano::recover_mersenne_twister_seed_from_time(output).unwrap();
assert_eq!(got, seed);
}
#[test]
-fn problem_23 () {
- let mut mt: matasano::MersenneTwister = rand::thread_rng().gen();
- let outputs: Vec<u32> = mt.gen_iter().take(624).collect();
+fn problem_23() {
+ let mut mt = matasano::MersenneTwister::from_entropy();
+ let outputs: Vec<u32> = mt
+ .sample_iter(&rand::distributions::Standard)
+ .take(624)
+ .collect();
let mut mt2 = matasano::clone_mersenne_twister_from_output(&outputs[..]);
for _ in 1..1000 {
assert_eq!(mt.gen::<u32>(), mt2.gen::<u32>());
@@ -142,27 +139,32 @@ fn problem_23 () {
}
#[test]
-fn problem_24 () {
+fn problem_24() {
let key: u16 = rand::thread_rng().gen();
let fixed_suffix = b"AAAAAAAAAAAAAA";
let plaintext: Vec<u8> = rand::thread_rng()
- .gen_iter()
+ .sample_iter(&rand::distributions::Standard)
.take(rand::thread_rng().gen_range(0, 32))
.chain(fixed_suffix.iter().map(|x| *x))
.collect();
- let ciphertext = matasano::mt19937_stream_cipher(&plaintext[..], key as u32);
+ let ciphertext =
+ matasano::mt19937_stream_cipher(&plaintext[..], key as u32);
let got = matasano::recover_16_bit_mt19937_key(
&ciphertext[..],
&fixed_suffix[..],
- ).unwrap();
+ )
+ .unwrap();
assert_eq!(got, key);
}
#[test]
-fn problem_24_part_2 () {
+fn problem_24_part_2() {
let seed = util::now();
- let mut mt = matasano::MersenneTwister::from_seed(seed);
- let token: Vec<u8> = mt.gen_iter().take(16).collect();
+ let mut mt = matasano::MersenneTwister::from_u32(seed);
+ let token: Vec<u8> = mt
+ .sample_iter(&rand::distributions::Standard)
+ .take(16)
+ .collect();
let got = matasano::recover_mt19937_key_from_time(&token[..]).unwrap();
assert_eq!(got, seed);
}
diff --git a/tests/set4.rs b/tests/set4.rs
index d6fbeb5..5f5916d 100644
--- a/tests/set4.rs
+++ b/tests/set4.rs
@@ -6,7 +6,7 @@ use rand::Rng;
mod util;
#[test]
-fn problem_25 () {
+fn problem_25() {
let key = util::random_aes_128_key();
let nonce: u64 = rand::thread_rng().gen();
let plaintext = util::read("data/25.txt");
@@ -16,15 +16,13 @@ fn problem_25 () {
let block_start_number = offset / 16;
let block_start = block_start_number * 16;
let block_end_number = (offset + newtext.len() - 1) / 16;
- let block_end = std::cmp::min(
- (block_end_number + 1) * 16,
- ciphertext.len()
- );
+ let block_end =
+ std::cmp::min((block_end_number + 1) * 16, ciphertext.len());
let mut plaintext = matasano::aes_128_ctr_with_counter(
&ciphertext[block_start..block_end],
&key[..],
nonce,
- (offset / 16) as u64
+ (offset / 16) as u64,
);
for i in 0..newtext.len() {
plaintext[offset - block_start + i] = newtext[i];
@@ -33,7 +31,7 @@ fn problem_25 () {
&plaintext[..],
&key[..],
nonce,
- (offset / 16) as u64
+ (offset / 16) as u64,
);
return ciphertext
@@ -45,12 +43,13 @@ fn problem_25 () {
.collect();
};
- let got = matasano::crack_aes_128_ctr_random_access(&ciphertext[..], edit);
+ let got =
+ matasano::crack_aes_128_ctr_random_access(&ciphertext[..], edit);
assert_eq!(&got[..], &plaintext[..]);
}
#[test]
-fn problem_26 () {
+fn problem_26() {
let key = util::random_aes_128_key();
let nonce = rand::thread_rng().gen();
let prefix = "comment1=cooking%20MCs;userdata=";
@@ -58,7 +57,10 @@ fn problem_26 () {
let admin = ";admin=true;";
let escape = |input: &str| {
- input.replace("%", "%25").replace(";", "%3B").replace("=", "%3D")
+ input
+ .replace("%", "%25")
+ .replace(";", "%3B")
+ .replace("=", "%3D")
};
let encode = |input: &str| -> Vec<u8> {
@@ -88,7 +90,7 @@ fn problem_26 () {
}
#[test]
-fn problem_27 () {
+fn problem_27() {
let key = util::random_aes_128_key();
let iv = key;
let prefix = "comment1=cooking%20MCs;userdata=";
@@ -96,7 +98,10 @@ fn problem_27 () {
let admin = ";admin=true;";
let escape = |input: &str| {
- input.replace("%", "%25").replace(";", "%3B").replace("=", "%3D")
+ input
+ .replace("%", "%25")
+ .replace(";", "%3B")
+ .replace("=", "%3D")
};
let encode = |input: &str| -> Vec<u8> {
@@ -107,24 +112,27 @@ fn problem_27 () {
.chain(suffix.as_bytes().iter())
.map(|x| *x)
.collect();
- return matasano::encrypt_aes_128_cbc(&plaintext[..], &key[..], &iv[..]);
+ return matasano::encrypt_aes_128_cbc(
+ &plaintext[..],
+ &key[..],
+ &iv[..],
+ );
};
let verify = |ciphertext: &[u8]| -> Result<bool, Vec<u8>> {
- let plaintext = matasano::decrypt_aes_128_cbc(ciphertext, &key[..], &iv[..]).unwrap();
+ let plaintext =
+ matasano::decrypt_aes_128_cbc(ciphertext, &key[..], &iv[..])
+ .unwrap();
if plaintext.iter().any(|&c| c < 32 || c > 126) {
return Err(plaintext);
- }
- else {
- return Ok(
- (0..(plaintext.len() - admin.len())).any(|i| {
- plaintext
- .iter()
- .skip(i)
- .zip(admin.as_bytes().iter())
- .all(|(&c1, &c2)| c1 == c2)
- })
- );
+ } else {
+ return Ok((0..(plaintext.len() - admin.len())).any(|i| {
+ plaintext
+ .iter()
+ .skip(i)
+ .zip(admin.as_bytes().iter())
+ .all(|(&c1, &c2)| c1 == c2)
+ }));
}
};
@@ -135,45 +143,47 @@ fn problem_27 () {
// problem 28 is just matasano::sha1_mac
#[test]
-fn problem_29 () {
- let key: Vec<u8> = ::rand::thread_rng()
- .gen_iter()
+fn problem_29() {
+ let key: Vec<u8> = rand::thread_rng()
+ .sample_iter(&rand::distributions::Standard)
.take(::rand::thread_rng().gen_range(5, 25))
.collect();
let valid_input = b"comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon";
let valid_mac = matasano::sha1_mac(valid_input, &key[..]);
- let possibles = matasano::crack_sha1_mac_length_extension(valid_input, valid_mac, b";admin=true");
- assert!(
- possibles.iter().all(|&(ref input, _)| {
- input.ends_with(b";admin=true")
- })
- );
- assert!(
- possibles.iter().any(|&(ref input, ref mac)| {
- &matasano::sha1_mac(&input[..], &key[..])[..] == &mac[..]
- })
+ let possibles = matasano::crack_sha1_mac_length_extension(
+ valid_input,
+ valid_mac,
+ b";admin=true",
);
+ assert!(possibles
+ .iter()
+ .all(|&(ref input, _)| input.ends_with(b";admin=true")));
+ assert!(possibles.iter().any(
+ |&(ref input, ref mac)| &matasano::sha1_mac(&input[..], &key[..])[..]
+ == &mac[..]
+ ));
}
#[test]
-fn problem_30 () {
- let key: Vec<u8> = ::rand::thread_rng()
- .gen_iter()
+fn problem_30() {
+ let key: Vec<u8> = rand::thread_rng()
+ .sample_iter(&rand::distributions::Standard)
.take(::rand::thread_rng().gen_range(5, 25))
.collect();
let valid_input = b"comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon";
let valid_mac = matasano::md4_mac(valid_input, &key[..]);
- let possibles = matasano::crack_md4_mac_length_extension(valid_input, valid_mac, b";admin=true");
- assert!(
- possibles.iter().all(|&(ref input, _)| {
- input.ends_with(b";admin=true")
- })
- );
- assert!(
- possibles.iter().any(|&(ref input, ref mac)| {
- &matasano::md4_mac(&input[..], &key[..])[..] == &mac[..]
- })
+ let possibles = matasano::crack_md4_mac_length_extension(
+ valid_input,
+ valid_mac,
+ b";admin=true",
);
+ assert!(possibles
+ .iter()
+ .all(|&(ref input, _)| input.ends_with(b";admin=true")));
+ assert!(possibles.iter().any(
+ |&(ref input, ref mac)| &matasano::md4_mac(&input[..], &key[..])[..]
+ == &mac[..]
+ ));
}
diff --git a/tests/util.rs b/tests/util.rs
index 6921eea..390559e 100644
--- a/tests/util.rs
+++ b/tests/util.rs
@@ -4,66 +4,66 @@ extern crate rand;
extern crate rustc_serialize as serialize;
extern crate time;
-use std::io::prelude::*;
use std::fs::File;
+use std::io::prelude::*;
-use self::rand::Rng;
+use self::rand::{Rng, RngCore};
use self::serialize::base64::FromBase64;
use self::serialize::hex::FromHex;
-pub fn read_as_hex_lines (filename: &str) -> Vec<Vec<u8>> {
+pub fn read_as_hex_lines(filename: &str) -> Vec<Vec<u8>> {
let fh = File::open(filename).unwrap();
- return ::std::io::BufReader::new(fh)
+ return std::io::BufReader::new(fh)
.lines()
.map(|line| line.unwrap().from_hex().unwrap())
.collect();
}
-pub fn read_as_base64_lines (filename: &str) -> Vec<Vec<u8>> {
+pub fn read_as_base64_lines(filename: &str) -> Vec<Vec<u8>> {
let fh = File::open(filename).unwrap();
- return ::std::io::BufReader::new(fh)
+ return std::io::BufReader::new(fh)
.lines()
.map(|line| line.unwrap().from_base64().unwrap())
.collect();
}
-pub fn read_as_lines (filename: &str) -> Vec<Vec<u8>> {
+pub fn read_as_lines(filename: &str) -> Vec<Vec<u8>> {
let fh = File::open(filename).unwrap();
- return ::std::io::BufReader::new(fh)
+ return std::io::BufReader::new(fh)
.lines()
.map(|line| line.unwrap().as_bytes().to_vec())
.collect();
}
-pub fn read_as_base64 (filename: &str) -> Vec<u8> {
+pub fn read_as_base64(filename: &str) -> Vec<u8> {
let fh = File::open(filename).unwrap();
- return ::std::io::BufReader::new(fh)
+ return std::io::BufReader::new(fh)
.lines()
.map(|line| line.unwrap().from_base64().unwrap())
.collect::<Vec<Vec<u8>>>()
.concat();
}
-pub fn read (filename: &str) -> Vec<u8> {
+pub fn read(filename: &str) -> Vec<u8> {
let outfh = File::open(filename).unwrap();
return outfh.bytes().map(|c| c.unwrap()).collect();
}
-pub fn write (filename: &str, data: &[u8]) {
+pub fn write(filename: &str, data: &[u8]) {
let mut outfh = File::create(filename).unwrap();
outfh.write(data).unwrap();
}
-pub fn random_aes_128_key () -> [u8; 16] {
+pub fn random_aes_128_key() -> [u8; 16] {
let mut key = [0; 16];
self::rand::thread_rng().fill_bytes(&mut key);
return key;
}
-pub fn coinflip () -> bool {
+pub fn coinflip() -> bool {
self::rand::thread_rng().gen()
}
-pub fn now () -> u32 {
+pub fn now() -> u32 {
return self::time::now().to_timespec().sec as u32;
}