diff --git a/.github/workflows/aes.yml b/.github/workflows/aes.yml index f7542d3a..f9edc7cb 100644 --- a/.github/workflows/aes.yml +++ b/.github/workflows/aes.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.72.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -73,7 +73,7 @@ jobs: include: # 32-bit Linux - target: i686-unknown-linux-gnu - rust: 1.56.0 # MSRV + rust: 1.72.0 # MSRV deps: sudo apt update && sudo apt install gcc-multilib - target: i686-unknown-linux-gnu rust: stable @@ -81,7 +81,7 @@ jobs: # 64-bit Linux - target: x86_64-unknown-linux-gnu - rust: 1.56.0 # MSRV + rust: 1.72.0 # MSRV - target: x86_64-unknown-linux-gnu rust: stable steps: @@ -104,7 +104,7 @@ jobs: include: # 32-bit Linux - target: i686-unknown-linux-gnu - rust: 1.56.0 # MSRV + rust: 1.72.0 # MSRV deps: sudo apt update && sudo apt install gcc-multilib - target: i686-unknown-linux-gnu rust: stable @@ -112,7 +112,7 @@ jobs: # 64-bit Linux - target: x86_64-unknown-linux-gnu - rust: 1.56.0 # MSRV + rust: 1.72.0 # MSRV - target: x86_64-unknown-linux-gnu rust: stable steps: @@ -137,7 +137,7 @@ jobs: include: # 32-bit Linux - target: i686-unknown-linux-gnu - rust: 1.56.0 # MSRV + rust: 1.72.0 # MSRV deps: sudo apt update && sudo apt install gcc-multilib - target: i686-unknown-linux-gnu rust: stable @@ -145,7 +145,7 @@ jobs: # 64-bit Linux - target: x86_64-unknown-linux-gnu - rust: 1.56.0 # MSRV + rust: 1.72.0 # MSRV - target: x86_64-unknown-linux-gnu rust: stable steps: @@ -167,13 +167,13 @@ jobs: include: # ARM64 - target: aarch64-unknown-linux-gnu - rust: 1.56.0 # MSRV + rust: 1.72.0 # MSRV - target: aarch64-unknown-linux-gnu rust: stable # PPC32 - target: powerpc-unknown-linux-gnu - rust: 1.56.0 # MSRV + rust: 1.72.0 # MSRV - target: powerpc-unknown-linux-gnu rust: stable runs-on: ubuntu-latest @@ -211,13 +211,11 @@ jobs: # ARMv8 cross-compiled tests for AES intrinsics armv8: - env: - RUSTFLAGS: "-Dwarnings --cfg aes_armv8" strategy: matrix: include: - target: aarch64-unknown-linux-gnu - rust: 1.61.0 # MSRV for `aes_armv8` + rust: 1.72.0 # MSRV runs-on: ubuntu-latest # Cross mounts only current package, i.e. by default it ignores workspace's Cargo.toml defaults: @@ -245,6 +243,6 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.56.0 # MSRV + toolchain: 1.72.0 # MSRV components: clippy - run: cargo clippy --features hazmat -- -D warnings diff --git a/.github/workflows/aria.yml b/.github/workflows/aria.yml index fdea9063..b11b21fa 100644 --- a/.github/workflows/aria.yml +++ b/.github/workflows/aria.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/belt-block.yml b/.github/workflows/belt-block.yml index 366e7d99..e4f29256 100644 --- a/.github/workflows/belt-block.yml +++ b/.github/workflows/belt-block.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/blowfish.yml b/.github/workflows/blowfish.yml index d1f05903..cce03698 100644 --- a/.github/workflows/blowfish.yml +++ b/.github/workflows/blowfish.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/camellia.yml b/.github/workflows/camellia.yml index cf8accfc..dffd85e0 100644 --- a/.github/workflows/camellia.yml +++ b/.github/workflows/camellia.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/cast5.yml b/.github/workflows/cast5.yml index 8b4b9891..b71c1034 100644 --- a/.github/workflows/cast5.yml +++ b/.github/workflows/cast5.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/cast6.yml b/.github/workflows/cast6.yml new file mode 100644 index 00000000..60615c5d --- /dev/null +++ b/.github/workflows/cast6.yml @@ -0,0 +1,60 @@ +name: cast6 + +on: + pull_request: + paths: + - "cast6/**" + - "Cargo.*" + push: + branches: master + +defaults: + run: + working-directory: cast6 + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.65.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v3 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + targets: ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} + + minimal-versions: + uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + with: + working-directory: ${{ github.workflow }} + + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.65.0 # MSRV + - stable + steps: + - uses: actions/checkout@v3 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + - run: cargo check --all-features + - run: cargo test --no-default-features + - run: cargo test + - run: cargo test --all-features diff --git a/.github/workflows/des.yml b/.github/workflows/des.yml index 2091f64e..2cd01816 100644 --- a/.github/workflows/des.yml +++ b/.github/workflows/des.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/idea.yml b/.github/workflows/idea.yml index 1898df4b..9f53c8c4 100644 --- a/.github/workflows/idea.yml +++ b/.github/workflows/idea.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/kuznyechik.yml b/.github/workflows/kuznyechik.yml index d8bd04f0..a77983ec 100644 --- a/.github/workflows/kuznyechik.yml +++ b/.github/workflows/kuznyechik.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -45,12 +45,44 @@ jobs: with: working-directory: ${{ github.workflow }} + sse2: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.65.0 # MSRV + - stable + target: + - i686-unknown-linux-gnu + - x86_64-unknown-linux-gnu + include: + - target: i686-unknown-linux-gnu + deps: sudo apt update && sudo apt install gcc-multilib + steps: + - uses: actions/checkout@v3 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + targets: ${{ matrix.target }} + - run: ${{ matrix.deps }} + - env: + RUSTFLAGS: "-Dwarnings -C target-feature=+sse2" + run: | + cargo test --target ${{ matrix.target }} + cargo test --target ${{ matrix.target }} --all-features + - env: + RUSTFLAGS: "-Dwarnings -C target-feature=+sse2 --cfg kuznyechik_force_soft" + run: | + cargo test --target ${{ matrix.target }} + cargo test --target ${{ matrix.target }} --all-features + test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/magma.yml b/.github/workflows/magma.yml index 7d3146ae..4bb3b454 100644 --- a/.github/workflows/magma.yml +++ b/.github/workflows/magma.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/rc2.yml b/.github/workflows/rc2.yml index 7fbc3f8b..e5a01cbb 100644 --- a/.github/workflows/rc2.yml +++ b/.github/workflows/rc2.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/rc5.yml b/.github/workflows/rc5.yml index 15e554fe..95fd41a1 100644 --- a/.github/workflows/rc5.yml +++ b/.github/workflows/rc5.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -45,7 +45,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/serpent.yml b/.github/workflows/serpent.yml index b3c65a56..450a8833 100644 --- a/.github/workflows/serpent.yml +++ b/.github/workflows/serpent.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/sm4.yml b/.github/workflows/sm4.yml index 1977d45c..06a32a4c 100644 --- a/.github/workflows/sm4.yml +++ b/.github/workflows/sm4.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/speck.yml b/.github/workflows/speck.yml index b7698281..40a6ea59 100644 --- a/.github/workflows/speck.yml +++ b/.github/workflows/speck.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -36,6 +36,7 @@ jobs: - run: cargo build --no-default-features --release --target ${{ matrix.target }} minimal-versions: + if: false # TODO: temp disabled due to unpublished prerelease dependencies runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -52,7 +53,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/threefish.yml b/.github/workflows/threefish.yml index 2f195fde..a6a80e13 100644 --- a/.github/workflows/threefish.yml +++ b/.github/workflows/threefish.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/twofish.yml b/.github/workflows/twofish.yml index 19a9e337..9ffafac6 100644 --- a/.github/workflows/twofish.yml +++ b/.github/workflows/twofish.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index ceffe101..816bb875 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -17,7 +17,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.63.0 + toolchain: 1.71.0 components: clippy - run: cargo clippy --all --exclude aes --all-features -- -D warnings diff --git a/.github/workflows/xtea.yml b/.github/workflows/xtea.yml new file mode 100644 index 00000000..a6875806 --- /dev/null +++ b/.github/workflows/xtea.yml @@ -0,0 +1,60 @@ +name: xtea + +on: + pull_request: + paths: + - "xtea/**" + - "Cargo.*" + push: + branches: master + +defaults: + run: + working-directory: xtea + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.65.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v3 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + targets: ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} + + minimal-versions: + uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + with: + working-directory: ${{ github.workflow }} + + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.65.0 # MSRV + - stable + steps: + - uses: actions/checkout@v3 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + - run: cargo check --all-features + - run: cargo test --no-default-features + - run: cargo test + - run: cargo test --all-features diff --git a/Cargo.lock b/Cargo.lock index c3e4e96b..ef813462 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,31 +4,63 @@ version = 3 [[package]] name = "aes" -version = "0.8.3" +version = "0.9.0-pre.1" dependencies = [ "cfg-if", - "cipher 0.4.4", + "cipher 0.5.0-pre.6", "cpufeatures", - "hex-literal", + "hex-literal 0.3.4", "zeroize", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "aria" -version = "0.1.0" +version = "0.2.0-pre" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", ] +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + [[package]] name = "belt-block" -version = "0.1.2" +version = "0.2.0-pre.1" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "blobby" version = "0.3.1" @@ -37,12 +69,18 @@ checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" [[package]] name = "blowfish" -version = "0.9.1" +version = "0.10.0-pre.1" dependencies = [ "byteorder", - "cipher 0.4.4", + "cipher 0.5.0-pre.6", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byteorder" version = "1.4.3" @@ -51,18 +89,32 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "camellia" -version = "0.1.0" +version = "0.2.0-pre" dependencies = [ "byteorder", - "cipher 0.4.4", + "cipher 0.5.0-pre.6", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cast5" -version = "0.11.1" +version = "0.12.0-pre" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", +] + +[[package]] +name = "cast6" +version = "0.2.0-pre" +dependencies = [ + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", ] [[package]] @@ -95,15 +147,96 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] +[[package]] +name = "criterion" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-cycles-per-byte" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07175eab62c9054f8828955f9a84ddd3f732f796ee99fb4898453d60be4bcbdc" +dependencies = [ + "criterion", +] + +[[package]] +name = "criterion-plot" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crypto-common" version = "0.1.6" @@ -123,13 +256,40 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "des" -version = "0.8.1" +version = "0.9.0-pre.1" dependencies = [ - "cipher 0.4.4", + "cipher 0.5.0-pre.6", ] +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "generic-array" version = "0.14.7" @@ -142,21 +302,51 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", "wasi", ] +[[package]] +name = "gift-cipher" +version = "0.0.0" +dependencies = [ + "cipher 0.5.0-pre.6", + "criterion", + "criterion-cycles-per-byte", +] + +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hex-literal" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "hybrid-array" version = "0.2.0-rc.9" @@ -168,9 +358,9 @@ dependencies = [ [[package]] name = "idea" -version = "0.5.1" +version = "0.6.0-pre" dependencies = [ - "cipher 0.4.4", + "cipher 0.5.0-pre.6", ] [[package]] @@ -191,26 +381,117 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "kuznyechik" -version = "0.8.1" +version = "0.9.0-pre.1" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" -version = "0.2.146" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "magma" -version = "0.8.1" +version = "0.10.0-pre.1" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + +[[package]] +name = "plotters" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" + +[[package]] +name = "plotters-svg" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +dependencies = [ + "plotters-backend", ] [[package]] @@ -219,6 +500,24 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rand" version = "0.8.5" @@ -249,16 +548,36 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rc2" -version = "0.8.1" +version = "0.9.0-pre" dependencies = [ - "cipher 0.4.4", + "cipher 0.5.0-pre.6", ] [[package]] name = "rc5" -version = "0.0.1" +version = "0.1.0-pre" dependencies = [ "cipher 0.5.0-pre.6", "rand", @@ -272,45 +591,161 @@ dependencies = [ "rand", ] +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.121" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "serpent" -version = "0.5.1" +version = "0.6.0-pre" dependencies = [ "byteorder", - "cipher 0.4.4", + "cipher 0.5.0-pre.6", ] [[package]] name = "sm4" -version = "0.5.1" +version = "0.6.0-pre" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", ] [[package]] -name = "speck" -version = "0.0.1" +name = "speck-cipher" +version = "0.0.0" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", +] + +[[package]] +name = "syn" +version = "2.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", ] [[package]] name = "threefish" -version = "0.5.2" +version = "0.6.0-pre" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", "zeroize", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "twofish" -version = "0.7.1" +version = "0.8.0-pre" dependencies = [ - "cipher 0.4.4", - "hex-literal", + "cipher 0.5.0-pre.6", + "hex-literal 0.4.1", ] [[package]] @@ -319,11 +754,33 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-width" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] [[package]] name = "wasi" @@ -331,8 +788,183 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "xtea" +version = "0.0.0" +dependencies = [ + "cipher 0.5.0-pre.6", +] + [[package]] name = "zeroize" -version = "1.8.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index 53e84ba7..7585a409 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "aes", "aria", @@ -6,7 +7,9 @@ members = [ "blowfish", "camellia", "cast5", + "cast6", "des", + "gift", "idea", "kuznyechik", "magma", @@ -18,6 +21,7 @@ members = [ "speck", "twofish", "threefish", + "xtea", ] [profile.dev] diff --git a/README.md b/README.md index 88f34fd0..27980166 100644 --- a/README.md +++ b/README.md @@ -36,23 +36,25 @@ It's generally recommended not to use other cipher implementations in this repos | Name | Crate name | crates.io | Docs | MSRV | |------|------------|-----------|------|------| -| [AES] (Rijndael) | [`aes`] | [![crates.io](https://img.shields.io/crates/v/aes.svg)](https://crates.io/crates/aes) | [![Documentation](https://docs.rs/aes/badge.svg)](https://docs.rs/aes) | ![MSRV 1.56][msrv-1.56] | -| [ARIA] | [`aria`] | [![crates.io](https://img.shields.io/crates/v/aria.svg)](https://crates.io/crates/aria) | [![Documentation](https://docs.rs/aria/badge.svg)](https://docs.rs/aria) | ![MSRV 1.56][msrv-1.56] | -| [BelT] block cipher | [`belt-block`] | [![crates.io](https://img.shields.io/crates/v/belt-block.svg)](https://crates.io/crates/belt-block) | [![Documentation](https://docs.rs/belt-block/badge.svg)](https://docs.rs/belt-block) | ![MSRV 1.56][msrv-1.56] | -| [Blowfish] | [`blowfish`] | [![crates.io](https://img.shields.io/crates/v/blowfish.svg)](https://crates.io/crates/blowfish) | [![Documentation](https://docs.rs/blowfish/badge.svg)](https://docs.rs/blowfish) | ![MSRV 1.56][msrv-1.56] | -| [Camellia] | [`camellia`] | [![crates.io](https://img.shields.io/crates/v/camellia.svg)](https://crates.io/crates/camellia) | [![Documentation](https://docs.rs/camellia/badge.svg)](https://docs.rs/camellia) | ![MSRV 1.56][msrv-1.56] | -| [CAST5] (CAST-128) | [`cast5`] | [![crates.io](https://img.shields.io/crates/v/cast5.svg)](https://crates.io/crates/cast5) | [![Documentation](https://docs.rs/cast5/badge.svg)](https://docs.rs/cast5) | ![MSRV 1.56][msrv-1.56] | -| [DES] + [3DES] (DEA, 3DEA) | [`des`] | [![crates.io](https://img.shields.io/crates/v/des.svg)](https://crates.io/crates/des) | [![Documentation](https://docs.rs/des/badge.svg)](https://docs.rs/des) | ![MSRV 1.56][msrv-1.56] | -| [IDEA] | [`idea`] | [![crates.io](https://img.shields.io/crates/v/idea.svg)](https://crates.io/crates/idea) | [![Documentation](https://docs.rs/idea/badge.svg)](https://docs.rs/idea) | ![MSRV 1.56][msrv-1.56] | -| [Kuznyechik] (GOST R 34.12-2015) | [`kuznyechik`] | [![crates.io](https://img.shields.io/crates/v/kuznyechik.svg)](https://crates.io/crates/kuznyechik) | [![Documentation](https://docs.rs/kuznyechik/badge.svg)](https://docs.rs/kuznyechik) | ![MSRV 1.56][msrv-1.56] | -| [Magma] (GOST R 34.12-2015) | [`magma`] | [![crates.io](https://img.shields.io/crates/v/magma.svg)](https://crates.io/crates/magma) | [![Documentation](https://docs.rs/magma/badge.svg)](https://docs.rs/magma) | ![MSRV 1.56][msrv-1.56] | -| [RC2] (ARC2) | [`rc2`] | [![crates.io](https://img.shields.io/crates/v/rc2.svg)](https://crates.io/crates/rc2) | [![Documentation](https://docs.rs/rc2/badge.svg)](https://docs.rs/rc2) | ![MSRV 1.56][msrv-1.56] | -| [RC5] | [`rc5`] | [![crates.io](https://img.shields.io/crates/v/rc5.svg)](https://crates.io/crates/rc5) | [![Documentation](https://docs.rs/rc5/badge.svg)](https://docs.rs/rc5) | ![MSRV 1.56][msrv-1.56] | -| [Serpent] | [`serpent`] | [![crates.io](https://img.shields.io/crates/v/serpent.svg)](https://crates.io/crates/serpent) | [![Documentation](https://docs.rs/serpent/badge.svg)](https://docs.rs/serpent) | ![MSRV 1.56][msrv-1.56] | -| [SM4] | [`sm4`] | [![crates.io](https://img.shields.io/crates/v/sm4.svg)](https://crates.io/crates/sm4) | [![Documentation](https://docs.rs/sm4/badge.svg)](https://docs.rs/sm4) | ![MSRV 1.56][msrv-1.56] | -| [Speck] | `speck` | [![crates.io](https://img.shields.io/crates/v/speck.svg)](https://crates.io/crates/speck) | [![Documentation](https://docs.rs/speck/badge.svg)](https://docs.rs/speck) | ![MSRV 1.56][msrv-1.56] | -| [Threefish] | [`threefish`] | [![crates.io](https://img.shields.io/crates/v/threefish.svg)](https://crates.io/crates/threefish) | [![Documentation](https://docs.rs/threefish/badge.svg)](https://docs.rs/threefish) | ![MSRV 1.56][msrv-1.56] | -| [Twofish] | [`twofish`] | [![crates.io](https://img.shields.io/crates/v/twofish.svg)](https://crates.io/crates/twofish) | [![Documentation](https://docs.rs/twofish/badge.svg)](https://docs.rs/twofish) | ![MSRV 1.56][msrv-1.56] | +| [AES] (Rijndael) | [`aes`] | [![crates.io](https://img.shields.io/crates/v/aes.svg)](https://crates.io/crates/aes) | [![Documentation](https://docs.rs/aes/badge.svg)](https://docs.rs/aes) | ![MSRV 1.65][msrv-1.65] | +| [ARIA] | [`aria`] | [![crates.io](https://img.shields.io/crates/v/aria.svg)](https://crates.io/crates/aria) | [![Documentation](https://docs.rs/aria/badge.svg)](https://docs.rs/aria) | ![MSRV 1.65][msrv-1.65] | +| [BelT] block cipher | [`belt-block`] | [![crates.io](https://img.shields.io/crates/v/belt-block.svg)](https://crates.io/crates/belt-block) | [![Documentation](https://docs.rs/belt-block/badge.svg)](https://docs.rs/belt-block) | ![MSRV 1.65][msrv-1.65] | +| [Blowfish] | [`blowfish`] | [![crates.io](https://img.shields.io/crates/v/blowfish.svg)](https://crates.io/crates/blowfish) | [![Documentation](https://docs.rs/blowfish/badge.svg)](https://docs.rs/blowfish) | ![MSRV 1.65][msrv-1.65] | +| [Camellia] | [`camellia`] | [![crates.io](https://img.shields.io/crates/v/camellia.svg)](https://crates.io/crates/camellia) | [![Documentation](https://docs.rs/camellia/badge.svg)](https://docs.rs/camellia) | ![MSRV 1.65][msrv-1.65] | +| [CAST5] (CAST-128) | [`cast5`] | [![crates.io](https://img.shields.io/crates/v/cast5.svg)](https://crates.io/crates/cast5) | [![Documentation](https://docs.rs/cast5/badge.svg)](https://docs.rs/cast5) | ![MSRV 1.65][msrv-1.65] | +| [CAST6] (CAST-256) | [`cast6`] | [![crates.io](https://img.shields.io/crates/v/cast6.svg)](https://crates.io/crates/cast6) | [![Documentation](https://docs.rs/cast6/badge.svg)](https://docs.rs/cast6) | ![MSRV 1.65][msrv-1.65] | +| [DES] + [3DES] (DEA, 3DEA) | [`des`] | [![crates.io](https://img.shields.io/crates/v/des.svg)](https://crates.io/crates/des) | [![Documentation](https://docs.rs/des/badge.svg)](https://docs.rs/des) | ![MSRV 1.65][msrv-1.65] | +| [IDEA] | [`idea`] | [![crates.io](https://img.shields.io/crates/v/idea.svg)](https://crates.io/crates/idea) | [![Documentation](https://docs.rs/idea/badge.svg)](https://docs.rs/idea) | ![MSRV 1.65][msrv-1.65] | +| [Kuznyechik] (GOST R 34.12-2015) | [`kuznyechik`] | [![crates.io](https://img.shields.io/crates/v/kuznyechik.svg)](https://crates.io/crates/kuznyechik) | [![Documentation](https://docs.rs/kuznyechik/badge.svg)](https://docs.rs/kuznyechik) | ![MSRV 1.65][msrv-1.65] | +| [Magma] (GOST R 34.12-2015) | [`magma`] | [![crates.io](https://img.shields.io/crates/v/magma.svg)](https://crates.io/crates/magma) | [![Documentation](https://docs.rs/magma/badge.svg)](https://docs.rs/magma) | ![MSRV 1.65][msrv-1.65] | +| [RC2] (ARC2) | [`rc2`] | [![crates.io](https://img.shields.io/crates/v/rc2.svg)](https://crates.io/crates/rc2) | [![Documentation](https://docs.rs/rc2/badge.svg)](https://docs.rs/rc2) | ![MSRV 1.65][msrv-1.65] | +| [RC5] | [`rc5`] | [![crates.io](https://img.shields.io/crates/v/rc5.svg)](https://crates.io/crates/rc5) | [![Documentation](https://docs.rs/rc5/badge.svg)](https://docs.rs/rc5) | ![MSRV 1.65][msrv-1.65] | +| [Serpent] | [`serpent`] | [![crates.io](https://img.shields.io/crates/v/serpent.svg)](https://crates.io/crates/serpent) | [![Documentation](https://docs.rs/serpent/badge.svg)](https://docs.rs/serpent) | ![MSRV 1.65][msrv-1.65] | +| [SM4] | [`sm4`] | [![crates.io](https://img.shields.io/crates/v/sm4.svg)](https://crates.io/crates/sm4) | [![Documentation](https://docs.rs/sm4/badge.svg)](https://docs.rs/sm4) | ![MSRV 1.65][msrv-1.65] | +| [Speck] | [`speck-cipher`] | [![crates.io](https://img.shields.io/crates/v/speck-cipher.svg)](https://crates.io/crates/speck-cipher) | [![Documentation](https://docs.rs/speck-cipher/badge.svg)](https://docs.rs/speck-cipher) | ![MSRV 1.65][msrv-1.65] | +| [Threefish] | [`threefish`] | [![crates.io](https://img.shields.io/crates/v/threefish.svg)](https://crates.io/crates/threefish) | [![Documentation](https://docs.rs/threefish/badge.svg)](https://docs.rs/threefish) | ![MSRV 1.65][msrv-1.65] | +| [Twofish] | [`twofish`] | [![crates.io](https://img.shields.io/crates/v/twofish.svg)](https://crates.io/crates/twofish) | [![Documentation](https://docs.rs/twofish/badge.svg)](https://docs.rs/twofish) | ![MSRV 1.65][msrv-1.65] | +| [XTEA] | [`xtea`] | [![crates.io](https://img.shields.io/crates/v/xtea.svg)](https://crates.io/crates/xtea) | [![Documentation](https://docs.rs/xtea/badge.svg)](https://docs.rs/xtea) | ![MSRV 1.65][msrv-1.65] | ### Minimum Supported Rust Version (MSRV) Policy @@ -82,7 +84,7 @@ dual licensed as above, without any additional terms or conditions. [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md -[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.65]: https://img.shields.io/badge/rustc-1.65.0+-blue.svg [//]: # (crates) @@ -92,6 +94,7 @@ dual licensed as above, without any additional terms or conditions. [`blowfish`]: ./blowfish [`camellia`]: ./camellia [`cast5`]: ./cast5 +[`cast6`]: ./cast6 [`des`]: ./des [`idea`]: ./idea [`kuznyechik`]: ./kuznyechik @@ -100,8 +103,10 @@ dual licensed as above, without any additional terms or conditions. [`rc5`]: ./rc5 [`serpent`]: ./serpent [`sm4`]: ./sm4 +[`speck-cipher`]: ./speck [`threefish`]: ./threefish [`twofish`]: ./twofish +[`xtea`]: ./xtea [//]: # (links) @@ -115,6 +120,7 @@ dual licensed as above, without any additional terms or conditions. [Blowfish]: https://en.wikipedia.org/wiki/Blowfish_(cipher) [Camellia]: https://en.wikipedia.org/wiki/Camellia_(cipher) [CAST5]: https://en.wikipedia.org/wiki/CAST-128 +[CAST6]: https://en.wikipedia.org/wiki/CAST-256 [DES]: https://en.wikipedia.org/wiki/Data_Encryption_Standard [3DES]: https://en.wikipedia.org/wiki/Triple_DES [IDEA]: https://simple.wikipedia.org/wiki/International_Data_Encryption_Algorithm @@ -127,3 +133,4 @@ dual licensed as above, without any additional terms or conditions. [Speck]: https://en.wikipedia.org/wiki/Speck_(cipher) [Threefish]: https://en.wikipedia.org/wiki/Threefish [Twofish]: https://en.wikipedia.org/wiki/Twofish +[XTEA]: https://en.wikipedia.org/wiki/XTEA diff --git a/aes/CHANGELOG.md b/aes/CHANGELOG.md index 37970b24..7e8ab114 100644 --- a/aes/CHANGELOG.md +++ b/aes/CHANGELOG.md @@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Added +- add #[inline] attributes for KeyInit::new impls ([#386]) + +### Changed +- Bump `cipher` to v0.5.0-pre.1; MSRV 1.65 ([#394]) +- replace inline ASM with ARMv8 intrinsics ([#380]) +- enable ARMv8 backend by default; MSRV 1.72 ([#395]) +- Bump `cipher` dependency to v0.5.0-pre.2 ([#398]) +- Use `BlockCipherEncrypt`/`BlockCipherDecrypt` trait names ([#400]) +- Assert precondition required for soundness ([#407]) +- use const preconditions assert ([#408]) +- bump `cipher` dependency to `0.5.0-pre.4` ([#413]) + +[#386]: https://github.com/RustCrypto/block-ciphers/pull/386 +[#394]: https://github.com/RustCrypto/block-ciphers/pull/394 +[#380]: https://github.com/RustCrypto/block-ciphers/pull/380 +[#395]: https://github.com/RustCrypto/block-ciphers/pull/395 +[#398]: https://github.com/RustCrypto/block-ciphers/pull/398 +[#400]: https://github.com/RustCrypto/block-ciphers/pull/400 +[#407]: https://github.com/RustCrypto/block-ciphers/pull/407 +[#408]: https://github.com/RustCrypto/block-ciphers/pull/408 +[#413]: https://github.com/RustCrypto/block-ciphers/pull/413 + +## 0.8.4 (2024-02-13) +### Changed +- Assert soundness preconditions for ARMv8 key expansion ([#407], [#408]) + +[#407]: https://github.com/RustCrypto/block-ciphers/pull/407 +[#408]: https://github.com/RustCrypto/block-ciphers/pull/408 + ## 0.8.3 (2023-06-17) ### Added - Support `aes_armv8` on Rust 1.61+ using `asm!` ([#365]) diff --git a/aes/Cargo.toml b/aes/Cargo.toml index 9aedfa8c..6065cbe9 100644 --- a/aes/Cargo.toml +++ b/aes/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "aes" -version = "0.8.3" +version = "0.9.0-pre.1" description = "Pure Rust implementation of the Advanced Encryption Standard (a.k.a. Rijndael)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.72" readme = "README.md" documentation = "https://docs.rs/aes" repository = "https://github.com/RustCrypto/block-ciphers" @@ -14,25 +14,23 @@ categories = ["cryptography", "no-std"] [dependencies] cfg-if = "1" -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" +zeroize = { version = "1.5.6", optional = true, default-features = false, features = ["aarch64"] } [target.'cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "x86"))'.dependencies] cpufeatures = "0.2" -[target.'cfg(not(all(aes_armv8, target_arch = "aarch64")))'.dependencies] -zeroize = { version = "1.6.0", optional = true, default_features = false } - -# TODO(tarcieri): unconditionally enable `aarch64` feature when MSRV is 1.59 -[target.'cfg(all(aes_armv8, target_arch = "aarch64"))'.dependencies] -zeroize = { version = "1.5.6", optional = true, default_features = false, features = ["aarch64"] } - [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } hex-literal = "0.3" [features] hazmat = [] # Expose cryptographically hazardous APIs +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ["cfg(aes_compact)", "cfg(aes_force_soft)"] + [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/aes/README.md b/aes/README.md index ce95a3a1..1783fe1a 100644 --- a/aes/README.md +++ b/aes/README.md @@ -43,7 +43,7 @@ using a portable implementation based on bitslicing. ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.72** or higher. Minimum supported Rust version can be changed in future releases, but it will be done with a minor version bump. @@ -75,7 +75,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/aes/badge.svg [docs-link]: https://docs.rs/aes/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.72+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260039-block-ciphers [build-image]: https://github.com/RustCrypto/block-ciphers/workflows/aes/badge.svg?branch=master&event=push diff --git a/aes/src/armv8.rs b/aes/src/armv8.rs index 3ece1b44..4ac12959 100644 --- a/aes/src/armv8.rs +++ b/aes/src/armv8.rs @@ -14,7 +14,6 @@ pub(crate) mod hazmat; mod encdec; mod expand; -mod intrinsics; #[cfg(test)] mod test_expand; @@ -26,7 +25,7 @@ use crate::{Block, Block8}; use cipher::{ consts::{U16, U24, U32, U8}, inout::InOut, - AlgorithmName, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt, BlockEncrypt, + AlgorithmName, BlockBackend, BlockCipher, BlockCipherDecrypt, BlockCipherEncrypt, BlockClosure, BlockSizeUser, Key, KeyInit, KeySizeUser, ParBlocksSizeUser, }; use core::arch::aarch64::*; @@ -99,13 +98,13 @@ macro_rules! define_aes_impl { type BlockSize = U16; } - impl BlockEncrypt for $name { + impl BlockCipherEncrypt for $name { fn encrypt_with_backend(&self, f: impl BlockClosure) { self.encrypt.encrypt_with_backend(f) } } - impl BlockDecrypt for $name { + impl BlockCipherDecrypt for $name { fn decrypt_with_backend(&self, f: impl BlockClosure) { self.decrypt.decrypt_with_backend(f) } @@ -147,6 +146,7 @@ macro_rules! define_aes_impl { } impl KeyInit for $name_enc { + #[inline] fn new(key: &Key) -> Self { Self { round_keys: unsafe { expand_key(key.as_ref()) }, @@ -158,7 +158,7 @@ macro_rules! define_aes_impl { type BlockSize = U16; } - impl BlockEncrypt for $name_enc { + impl BlockCipherEncrypt for $name_enc { fn encrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut self.get_enc_backend()) } @@ -208,6 +208,7 @@ macro_rules! define_aes_impl { } impl KeyInit for $name_dec { + #[inline] fn new(key: &Key) -> Self { $name_enc::new(key).into() } @@ -232,7 +233,7 @@ macro_rules! define_aes_impl { type BlockSize = U16; } - impl BlockDecrypt for $name_dec { + impl BlockCipherDecrypt for $name_dec { fn decrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut self.get_dec_backend()); } diff --git a/aes/src/armv8/encdec.rs b/aes/src/armv8/encdec.rs index 09c59cee..7f462564 100644 --- a/aes/src/armv8/encdec.rs +++ b/aes/src/armv8/encdec.rs @@ -4,12 +4,6 @@ use crate::{Block, Block8}; use cipher::inout::InOut; use core::arch::aarch64::*; -// Stable "polyfills" for unstable core::arch::aarch64 intrinsics -// TODO(tarcieri): remove when these intrinsics have been stabilized -use super::intrinsics::{ - vaesdq_u8, vaesdq_u8_and_vaesimcq_u8, vaeseq_u8, vaeseq_u8_and_vaesmcq_u8, -}; - /// Perform AES encryption using the given expanded keys. #[target_feature(enable = "aes")] #[target_feature(enable = "neon")] @@ -25,8 +19,11 @@ pub(super) unsafe fn encrypt1( let mut state = vld1q_u8(in_ptr as *const u8); for k in expanded_keys.iter().take(rounds - 1) { - // AES single round encryption and mix columns - state = vaeseq_u8_and_vaesmcq_u8(state, *k); + // AES single round encryption + state = vaeseq_u8(state, *k); + + // Mix columns + state = vaesmcq_u8(state); } // AES single round encryption @@ -65,8 +62,11 @@ pub(super) unsafe fn encrypt8( for k in expanded_keys.iter().take(rounds - 1) { for i in 0..8 { - // AES single round encryption and mix columns - state[i] = vaeseq_u8_and_vaesmcq_u8(state[i], *k); + // AES single round encryption + state[i] = vaeseq_u8(state[i], *k); + + // Mix columns + state[i] = vaesmcq_u8(state[i]); } } @@ -95,8 +95,11 @@ pub(super) unsafe fn decrypt1( let mut state = vld1q_u8(in_ptr as *const u8); for k in expanded_keys.iter().take(rounds - 1) { - // AES single round decryption and inverse mix columns - state = vaesdq_u8_and_vaesimcq_u8(state, *k); + // AES single round decryption + state = vaesdq_u8(state, *k); + + // Inverse mix columns + state = vaesimcq_u8(state); } // AES single round decryption @@ -135,8 +138,11 @@ pub(super) unsafe fn decrypt8( for k in expanded_keys.iter().take(rounds - 1) { for i in 0..8 { - // AES single round decryption and inverse mix columns - state[i] = vaesdq_u8_and_vaesimcq_u8(state[i], *k); + // AES single round decryption + state[i] = vaesdq_u8(state[i], *k); + + // Inverse mix columns + state[i] = vaesimcq_u8(state[i]); } } diff --git a/aes/src/armv8/expand.rs b/aes/src/armv8/expand.rs index 0cfc52d1..e932c7ca 100644 --- a/aes/src/armv8/expand.rs +++ b/aes/src/armv8/expand.rs @@ -2,10 +2,6 @@ use core::{arch::aarch64::*, mem, slice}; -// Stable "polyfills" for unstable core::arch::aarch64 intrinsics -// TODO(tarcieri): remove when these intrinsics have been stabilized -use super::intrinsics::{vaeseq_u8, vaesimcq_u8}; - /// There are 4 AES words in a block. const BLOCK_WORDS: usize = 4; @@ -22,8 +18,10 @@ pub unsafe fn expand_key(key: &[u8; L]) -> [uint let mut expanded_keys: [uint8x16_t; N] = mem::zeroed(); - let columns = - slice::from_raw_parts_mut(expanded_keys.as_mut_ptr() as *mut u32, N * BLOCK_WORDS); + // Sanity check, as this is required in order for the subsequent conversion to be sound. + const _: () = assert!(mem::align_of::() >= mem::align_of::()); + let keys_ptr: *mut u32 = expanded_keys.as_mut_ptr().cast(); + let columns = slice::from_raw_parts_mut(keys_ptr, N * BLOCK_WORDS); for (i, chunk) in key.chunks_exact(WORD_SIZE).enumerate() { columns[i] = u32::from_ne_bytes(chunk.try_into().unwrap()); diff --git a/aes/src/armv8/hazmat.rs b/aes/src/armv8/hazmat.rs index 3e078cfe..f094243c 100644 --- a/aes/src/armv8/hazmat.rs +++ b/aes/src/armv8/hazmat.rs @@ -7,9 +7,6 @@ use crate::{Block, Block8}; use core::arch::aarch64::*; -// Stable "polyfills" for unstable core::arch::aarch64 intrinsics -use super::intrinsics::{vaesdq_u8, vaeseq_u8, vaesimcq_u8, vaesmcq_u8}; - /// AES cipher (encrypt) round function. #[allow(clippy::cast_ptr_alignment)] #[target_feature(enable = "aes")] diff --git a/aes/src/armv8/intrinsics.rs b/aes/src/armv8/intrinsics.rs deleted file mode 100644 index 752af492..00000000 --- a/aes/src/armv8/intrinsics.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! Stable "polyfills" for unstable `core::arch::aarch64` intrinsics which use -//! `asm!` internally to allow use on stable Rust. -// TODO(tarcieri): remove when these intrinsics have been stabilized - -use core::arch::{aarch64::uint8x16_t, asm}; - -/// AES single round encryption. -#[inline] -#[target_feature(enable = "aes")] -pub(super) unsafe fn vaeseq_u8(mut data: uint8x16_t, key: uint8x16_t) -> uint8x16_t { - asm!( - "AESE {d:v}.16B, {k:v}.16B", - d = inout(vreg) data, - k = in(vreg) key, - options(pure, nomem, nostack, preserves_flags) - ); - data -} - -/// AES single round decryption. -#[inline] -#[target_feature(enable = "aes")] -pub(super) unsafe fn vaesdq_u8(mut data: uint8x16_t, key: uint8x16_t) -> uint8x16_t { - asm!( - "AESD {d:v}.16B, {k:v}.16B", - d = inout(vreg) data, - k = in(vreg) key, - options(pure, nomem, nostack, preserves_flags) - ); - data -} - -/// AES mix columns. -#[cfg(feature = "hazmat")] -#[inline] -#[target_feature(enable = "aes")] -pub(super) unsafe fn vaesmcq_u8(mut data: uint8x16_t) -> uint8x16_t { - asm!( - "AESMC {d:v}.16B, {d:v}.16B", - d = inout(vreg) data, - options(pure, nomem, nostack, preserves_flags) - ); - data -} - -/// AES inverse mix columns. -#[inline] -#[target_feature(enable = "aes")] -pub(super) unsafe fn vaesimcq_u8(mut data: uint8x16_t) -> uint8x16_t { - asm!( - "AESIMC {d:v}.16B, {d:v}.16B", - d = inout(vreg) data, - options(pure, nomem, nostack, preserves_flags) - ); - data -} - -/// AES single round encryption combined with mix columns. -/// -/// These two instructions are combined into a single assembly block to ensure -/// that instructions fuse properly. -#[inline] -#[target_feature(enable = "aes")] -pub(super) unsafe fn vaeseq_u8_and_vaesmcq_u8(mut data: uint8x16_t, key: uint8x16_t) -> uint8x16_t { - asm!( - "AESE {d:v}.16B, {k:v}.16B", - "AESMC {d:v}.16B, {d:v}.16B", - d = inout(vreg) data, - k = in(vreg) key, - options(pure, nomem, nostack, preserves_flags) - ); - data -} - -/// AES single round decryption combined with mix columns. -/// -/// These two instructions are combined into a single assembly block to ensure -/// that instructions fuse properly. -#[inline] -#[target_feature(enable = "aes")] -pub(super) unsafe fn vaesdq_u8_and_vaesimcq_u8( - mut data: uint8x16_t, - key: uint8x16_t, -) -> uint8x16_t { - asm!( - "AESD {d:v}.16B, {k:v}.16B", - "AESIMC {d:v}.16B, {d:v}.16B", - d = inout(vreg) data, - k = in(vreg) key, - options(pure, nomem, nostack, preserves_flags) - ); - data -} diff --git a/aes/src/autodetect.rs b/aes/src/autodetect.rs index ac471fab..3cf17fc4 100644 --- a/aes/src/autodetect.rs +++ b/aes/src/autodetect.rs @@ -4,13 +4,13 @@ use crate::soft; use cipher::{ consts::{U16, U24, U32}, - AlgorithmName, BlockCipher, BlockClosure, BlockDecrypt, BlockEncrypt, BlockSizeUser, Key, - KeyInit, KeySizeUser, + AlgorithmName, BlockCipher, BlockCipherDecrypt, BlockCipherEncrypt, BlockClosure, + BlockSizeUser, Key, KeyInit, KeySizeUser, }; use core::fmt; use core::mem::ManuallyDrop; -#[cfg(all(target_arch = "aarch64", aes_armv8))] +#[cfg(target_arch = "aarch64")] use crate::armv8 as intrinsics; #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] @@ -130,7 +130,7 @@ macro_rules! define_aes_impl { impl BlockCipher for $name {} - impl BlockEncrypt for $name { + impl BlockCipherEncrypt for $name { fn encrypt_with_backend(&self, f: impl BlockClosure) { unsafe { if self.token.get() { @@ -149,7 +149,7 @@ macro_rules! define_aes_impl { } } - impl BlockDecrypt for $name { + impl BlockCipherDecrypt for $name { fn decrypt_with_backend(&self, f: impl BlockClosure) { unsafe { if self.token.get() { @@ -249,7 +249,7 @@ macro_rules! define_aes_impl { impl BlockCipher for $name_enc {} - impl BlockEncrypt for $name_enc { + impl BlockCipherEncrypt for $name_enc { fn encrypt_with_backend(&self, f: impl BlockClosure) { unsafe { if self.token.get() { @@ -378,7 +378,7 @@ macro_rules! define_aes_impl { impl BlockCipher for $name_dec {} - impl BlockDecrypt for $name_dec { + impl BlockCipherDecrypt for $name_dec { fn decrypt_with_backend(&self, f: impl BlockClosure) { unsafe { if self.token.get() { diff --git a/aes/src/hazmat.rs b/aes/src/hazmat.rs index 4776bb4e..3d4def91 100644 --- a/aes/src/hazmat.rs +++ b/aes/src/hazmat.rs @@ -13,18 +13,14 @@ use crate::{soft::fixslice::hazmat as soft, Block, Block8}; -#[cfg(all(target_arch = "aarch64", aes_armv8, not(aes_force_soft)))] +#[cfg(all(target_arch = "aarch64", not(aes_force_soft)))] use crate::armv8::hazmat as intrinsics; #[cfg(all(any(target_arch = "x86_64", target_arch = "x86"), not(aes_force_soft)))] use crate::ni::hazmat as intrinsics; #[cfg(all( - any( - target_arch = "x86", - target_arch = "x86_64", - all(target_arch = "aarch64", aes_armv8) - ), + any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64"), not(aes_force_soft) ))] cpufeatures::new!(aes_intrinsics, "aes"); @@ -34,11 +30,7 @@ cpufeatures::new!(aes_intrinsics, "aes"); macro_rules! if_intrinsics_available { ($body:expr) => {{ #[cfg(all( - any( - target_arch = "x86", - target_arch = "x86_64", - all(target_arch = "aarch64", aes_armv8) - ), + any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64"), not(aes_force_soft) ))] if aes_intrinsics::get() { diff --git a/aes/src/lib.rs b/aes/src/lib.rs index 1df43ea6..0f8bab50 100644 --- a/aes/src/lib.rs +++ b/aes/src/lib.rs @@ -29,13 +29,11 @@ //! ## ARMv8 intrinsics (Rust 1.61+) //! On `aarch64` targets including `aarch64-apple-darwin` (Apple M1) and Linux //! targets such as `aarch64-unknown-linux-gnu` and `aarch64-unknown-linux-musl`, -//! support for using AES intrinsics provided by the ARMv8 Cryptography Extensions -//! is available when using Rust 1.61 or above, and can be enabled using the -//! `aes_armv8` configuration flag. +//! support for using AES intrinsics provided by the ARMv8 Cryptography Extensions. //! -//! On Linux and macOS, when the `aes_armv8` flag is enabled support for AES -//! intrinsics is autodetected at runtime. On other platforms the `aes` -//! target feature must be enabled via RUSTFLAGS. +//! On Linux and macOS, support for ARMv8 AES intrinsics is autodetected at +//! runtime. On other platforms the `aes` target feature must be enabled via +//! RUSTFLAGS. //! //! ## `x86`/`x86_64` intrinsics (AES-NI) //! By default this crate uses runtime detection on `i686`/`x86_64` targets @@ -54,12 +52,12 @@ //! ``` //! use aes::Aes128; //! use aes::cipher::{ -//! BlockCipher, BlockEncrypt, BlockDecrypt, KeyInit, -//! generic_array::GenericArray, +//! BlockCipher, BlockCipherEncrypt, BlockCipherDecrypt, KeyInit, +//! array::Array, //! }; //! -//! let key = GenericArray::from([0u8; 16]); -//! let mut block = GenericArray::from([42u8; 16]); +//! let key = Array::from([0u8; 16]); +//! let mut block = Array::from([42u8; 16]); //! //! // Initialize cipher //! let cipher = Aes128::new(&key); @@ -101,7 +99,6 @@ //! //! You can modify crate using the following configuration flags: //! -//! - `aes_armv8`: enable ARMv8 AES intrinsics (Rust 1.61+). //! - `aes_force_soft`: force software implementation. //! - `aes_compact`: reduce code size at the cost of slower performance //! (affects only software backend). @@ -131,7 +128,7 @@ mod soft; use cfg_if::cfg_if; cfg_if! { - if #[cfg(all(target_arch = "aarch64", aes_armv8, not(aes_force_soft)))] { + if #[cfg(all(target_arch = "aarch64", not(aes_force_soft)))] { mod armv8; mod autodetect; pub use autodetect::*; @@ -149,14 +146,14 @@ cfg_if! { pub use cipher; use cipher::{ + array::Array, consts::{U16, U8}, - generic_array::GenericArray, }; /// 128-bit AES block -pub type Block = GenericArray; +pub type Block = Array; /// Eight 128-bit AES blocks -pub type Block8 = GenericArray; +pub type Block8 = Array; #[cfg(test)] mod tests { @@ -212,7 +209,7 @@ mod tests { } } - #[cfg(all(target_arch = "aarch64", aes_armv8, not(aes_force_soft)))] + #[cfg(all(target_arch = "aarch64", not(aes_force_soft)))] { use super::armv8; diff --git a/aes/src/ni.rs b/aes/src/ni.rs index 15b49ef5..95117aad 100644 --- a/aes/src/ni.rs +++ b/aes/src/ni.rs @@ -37,7 +37,7 @@ use crate::{Block, Block8}; use cipher::{ consts::{U16, U24, U32, U8}, inout::InOut, - AlgorithmName, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt, BlockEncrypt, + AlgorithmName, BlockBackend, BlockCipher, BlockCipherDecrypt, BlockCipherEncrypt, BlockClosure, BlockSizeUser, Key, KeyInit, KeySizeUser, ParBlocksSizeUser, }; use core::fmt; @@ -109,13 +109,13 @@ macro_rules! define_aes_impl { type BlockSize = U16; } - impl BlockEncrypt for $name { + impl BlockCipherEncrypt for $name { fn encrypt_with_backend(&self, f: impl BlockClosure) { self.encrypt.encrypt_with_backend(f) } } - impl BlockDecrypt for $name { + impl BlockCipherDecrypt for $name { fn decrypt_with_backend(&self, f: impl BlockClosure) { self.decrypt.decrypt_with_backend(f) } @@ -157,6 +157,7 @@ macro_rules! define_aes_impl { } impl KeyInit for $name_enc { + #[inline] fn new(key: &Key) -> Self { // SAFETY: we enforce that this code is called only when // target features required by `expand` were properly checked. @@ -170,7 +171,7 @@ macro_rules! define_aes_impl { type BlockSize = U16; } - impl BlockEncrypt for $name_enc { + impl BlockCipherEncrypt for $name_enc { fn encrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut self.get_enc_backend()) } @@ -220,6 +221,7 @@ macro_rules! define_aes_impl { } impl KeyInit for $name_dec { + #[inline] fn new(key: &Key) -> Self { $name_enc::new(key).into() } @@ -244,7 +246,7 @@ macro_rules! define_aes_impl { type BlockSize = U16; } - impl BlockDecrypt for $name_dec { + impl BlockCipherDecrypt for $name_dec { fn decrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut self.get_dec_backend()); } diff --git a/aes/src/ni/aes256.rs b/aes/src/ni/aes256.rs index bea090ab..b42e2e65 100644 --- a/aes/src/ni/aes256.rs +++ b/aes/src/ni/aes256.rs @@ -3,7 +3,7 @@ use crate::{Block, Block8}; use cipher::inout::InOut; use core::mem; -/// AES-192 round keys +/// AES-256 round keys pub(super) type RoundKeys = [__m128i; 15]; #[inline] diff --git a/aes/src/soft.rs b/aes/src/soft.rs index 5f90b1e2..50daf7df 100644 --- a/aes/src/soft.rs +++ b/aes/src/soft.rs @@ -16,7 +16,7 @@ use crate::Block; use cipher::{ consts::{U16, U24, U32}, inout::InOut, - AlgorithmName, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt, BlockEncrypt, + AlgorithmName, BlockBackend, BlockCipher, BlockCipherDecrypt, BlockCipherEncrypt, BlockClosure, BlockSizeUser, Key, KeyInit, KeySizeUser, ParBlocksSizeUser, }; use core::fmt; @@ -63,7 +63,7 @@ macro_rules! define_aes_impl { #[inline] fn new(key: &Key) -> Self { Self { - keys: $fixslice_key_schedule(key.as_ref()), + keys: $fixslice_key_schedule(key.into()), } } } @@ -74,13 +74,13 @@ macro_rules! define_aes_impl { impl BlockCipher for $name {} - impl BlockEncrypt for $name { + impl BlockCipherEncrypt for $name { fn encrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut self.get_enc_backend()) } } - impl BlockDecrypt for $name { + impl BlockCipherDecrypt for $name { fn decrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut self.get_dec_backend()) } @@ -155,7 +155,7 @@ macro_rules! define_aes_impl { type BlockSize = U16; } - impl BlockEncrypt for $name_enc { + impl BlockCipherEncrypt for $name_enc { fn encrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut self.get_enc_backend()) } @@ -224,7 +224,7 @@ macro_rules! define_aes_impl { type BlockSize = U16; } - impl BlockDecrypt for $name_dec { + impl BlockCipherDecrypt for $name_dec { fn decrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut self.get_dec_backend()); } diff --git a/aes/src/soft/fixslice32.rs b/aes/src/soft/fixslice32.rs index 45b674d6..c0c9627c 100644 --- a/aes/src/soft/fixslice32.rs +++ b/aes/src/soft/fixslice32.rs @@ -16,12 +16,12 @@ #![allow(clippy::unreadable_literal)] use crate::Block; -use cipher::{consts::U2, generic_array::GenericArray}; +use cipher::{array::Array, consts::U2}; /// AES block batch size for this implementation pub(crate) type FixsliceBlocks = U2; -pub(crate) type BatchBlocks = GenericArray; +pub(crate) type BatchBlocks = Array; /// AES-128 round keys pub(crate) type FixsliceKeys128 = [u32; 88]; diff --git a/aes/src/soft/fixslice64.rs b/aes/src/soft/fixslice64.rs index 09dbcbe9..6dcd88f9 100644 --- a/aes/src/soft/fixslice64.rs +++ b/aes/src/soft/fixslice64.rs @@ -16,12 +16,12 @@ #![allow(clippy::unreadable_literal)] use crate::Block; -use cipher::{consts::U4, generic_array::GenericArray}; +use cipher::{array::Array, consts::U4}; /// AES block batch size for this implementation pub(crate) type FixsliceBlocks = U4; -pub(crate) type BatchBlocks = GenericArray; +pub(crate) type BatchBlocks = Array; /// AES-128 round keys pub(crate) type FixsliceKeys128 = [u64; 88]; diff --git a/aria/Cargo.toml b/aria/Cargo.toml index 4ccbfcc3..2485e7a3 100644 --- a/aria/Cargo.toml +++ b/aria/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "aria" -version = "0.1.0" +version = "0.2.0-pre" description = "Pure Rust implementation of the ARIA Encryption Algorithm" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/aria" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,11 +13,11 @@ keywords = ["crypto", "aria", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } -hex-literal = "0.3" +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" [features] zeroize = ["cipher/zeroize"] diff --git a/aria/README.md b/aria/README.md index 01e0cde4..075db478 100644 --- a/aria/README.md +++ b/aria/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/aria/badge.svg [docs-link]: https://docs.rs/aria/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/aria/src/lib.rs b/aria/src/lib.rs index 7eac2dfc..ff2ad66a 100644 --- a/aria/src/lib.rs +++ b/aria/src/lib.rs @@ -10,12 +10,12 @@ //! //! # Examples //! ``` -//! use aria::cipher::generic_array::GenericArray; -//! use aria::cipher::{Key, Block, BlockEncrypt, BlockDecrypt, KeyInit}; +//! use aria::cipher::array::Array; +//! use aria::cipher::{Key, Block, BlockCipherEncrypt, BlockCipherDecrypt, KeyInit}; //! use aria::Aria128; //! -//! let key = GenericArray::from([0u8; 16]); -//! let mut block = GenericArray::from([0u8; 16]); +//! let key = Array::from([0u8; 16]); +//! let mut block = Array::from([0u8; 16]); //! // Initialize cipher //! let cipher = Aria128::new(&key); //! diff --git a/aria/tests/mod.rs b/aria/tests/mod.rs index 498d83c7..f9dcdb8f 100644 --- a/aria/tests/mod.rs +++ b/aria/tests/mod.rs @@ -1,5 +1,5 @@ use aria::{Aria128, Aria192, Aria256}; -use cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt, KeyInit}; +use cipher::{array::Array, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; use hex_literal::hex; /// Test vector from RFC 5794, Appendix A.1 @@ -11,11 +11,11 @@ fn test_rfc5794_a1() { let c = Aria128::new_from_slice(&key).unwrap(); - let mut buf = GenericArray::from(pt); + let mut buf = Array::from(pt); c.encrypt_block(&mut buf); - assert_eq!(buf.as_ref(), ct); + assert_eq!(&buf, &ct); c.decrypt_block(&mut buf); - assert_eq!(buf.as_ref(), pt); + assert_eq!(&buf, &pt); } /// Test vector from RFC 5794, Appendix A.2 @@ -27,11 +27,11 @@ fn test_rfc5794_a2() { let c = Aria192::new_from_slice(&key).unwrap(); - let mut buf = GenericArray::from(pt); + let mut buf = Array::from(pt); c.encrypt_block(&mut buf); - assert_eq!(buf.as_ref(), ct); + assert_eq!(&buf, &ct); c.decrypt_block(&mut buf); - assert_eq!(buf.as_ref(), pt); + assert_eq!(&buf, &pt); } /// Test vector from RFC 5794, Appendix A.3 @@ -43,9 +43,9 @@ fn test_rfc5794_a3() { let c = Aria256::new_from_slice(&key).unwrap(); - let mut buf = GenericArray::from(pt); + let mut buf = Array::from(pt); c.encrypt_block(&mut buf); - assert_eq!(buf.as_ref(), ct); + assert_eq!(&buf, &ct); c.decrypt_block(&mut buf); - assert_eq!(buf.as_ref(), pt); + assert_eq!(&buf, &pt); } diff --git a/belt-block/CHANGELOG.md b/belt-block/CHANGELOG.md index 56bf092e..aa8ffa14 100644 --- a/belt-block/CHANGELOG.md +++ b/belt-block/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Changed +- Bump `cipher` to v0.5.0-pre.1; MSRV 1.65 ([#394]) +- Bump `cipher` dependency to v0.5.0-pre.2 ([#398]) +- Use `BlockCipherEncrypt`/`BlockCipherDecrypt` trait names ([#400]) +- mark `to_u32` function as private ([#402]) +- bump `cipher` dependency to `0.5.0-pre.4` ([#413]) + +[#394]: https://github.com/RustCrypto/block-ciphers/pull/394 +[#398]: https://github.com/RustCrypto/block-ciphers/pull/398 +[#400]: https://github.com/RustCrypto/block-ciphers/pull/400 +[#402]: https://github.com/RustCrypto/block-ciphers/pull/402 +[#413]: https://github.com/RustCrypto/block-ciphers/pull/413 + ## 0.1.2 (2023-04-15) ### Added - `belt_wblock_enc`, `belt_wblock_dec`, and `to_u32` functions ([#362]) diff --git a/belt-block/Cargo.toml b/belt-block/Cargo.toml index 36f8d91b..6b401bdf 100644 --- a/belt-block/Cargo.toml +++ b/belt-block/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "belt-block" -version = "0.1.2" +version = "0.2.0-pre.1" description = "belt-block block cipher implementation" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" -rust-version = "1.56" +rust-version = "1.65" edition = "2021" readme = "README.md" documentation = "https://docs.rs/belt-block" @@ -12,11 +12,11 @@ repository = "https://github.com/RustCrypto/block-ciphers" keywords = ["crypto", "belt-block", "belt", "stb"] [dependencies] -cipher = { version = "0.4.3", optional = true } +cipher = { version = "=0.5.0-pre.6", optional = true } [dev-dependencies] -cipher = { version = "0.4.3", features = ["dev"] } -hex-literal = "0.3.4" +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" [features] default = ["cipher"] diff --git a/belt-block/README.md b/belt-block/README.md index febfeb1f..40c7bd2e 100644 --- a/belt-block/README.md +++ b/belt-block/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/belt-block/badge.svg [docs-link]: https://docs.rs/belt-block/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/belt-block/src/lib.rs b/belt-block/src/lib.rs index 3baf0679..321bfc44 100644 --- a/belt-block/src/lib.rs +++ b/belt-block/src/lib.rs @@ -170,7 +170,7 @@ pub struct InvalidLengthError; /// # Panics /// If length of `src` is not equal to `4 * N`. #[inline(always)] -pub fn to_u32(src: &[u8]) -> [u32; N] { +fn to_u32(src: &[u8]) -> [u32; N] { assert_eq!(src.len(), 4 * N); let mut res = [0u32; N]; res.iter_mut() diff --git a/belt-block/tests/mod.rs b/belt-block/tests/mod.rs index d0135e05..ff649dc7 100644 --- a/belt-block/tests/mod.rs +++ b/belt-block/tests/mod.rs @@ -1,9 +1,9 @@ //! Example vectors from STB 34.101.31 (2020): //! http://apmi.bsu.by/assets/files/std/belt-spec371.pdf -use belt_block::{belt_block_raw, belt_wblock_dec, belt_wblock_enc, to_u32}; +use belt_block::{belt_block_raw, belt_wblock_dec, belt_wblock_enc}; #[cfg(feature = "cipher")] use belt_block::{ - cipher::{BlockDecrypt, BlockEncrypt, KeyInit}, + cipher::{BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}, BeltBlock, }; use hex_literal::hex; @@ -34,9 +34,9 @@ fn belt_block() { let cipher = BeltBlock::new(&key.into()); let mut block = pt.into(); cipher.encrypt_block(&mut block); - assert_eq!(block, ct.into()); + assert_eq!(block, ct); cipher.decrypt_block(&mut block); - assert_eq!(block, pt.into()); + assert_eq!(block, pt); } } } @@ -124,3 +124,12 @@ fn belt_wblock() { assert_eq!(t, x[..i]); } } + +fn to_u32(src: &[u8]) -> [u32; N] { + assert_eq!(src.len(), 4 * N); + let mut res = [0u32; N]; + res.iter_mut() + .zip(src.chunks_exact(4)) + .for_each(|(dst, src)| *dst = u32::from_le_bytes(src.try_into().unwrap())); + res +} diff --git a/blowfish/Cargo.toml b/blowfish/Cargo.toml index f7e795e8..3eb9a598 100644 --- a/blowfish/Cargo.toml +++ b/blowfish/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "blowfish" -version = "0.9.1" +version = "0.10.0-pre.1" description = "Blowfish block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/blowfish" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,11 +13,11 @@ keywords = ["crypto", "blowfish", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" byteorder = { version = "1.1", default-features = false } [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } [features] bcrypt = [] diff --git a/blowfish/README.md b/blowfish/README.md index 00a1f2d1..0e92ae4f 100644 --- a/blowfish/README.md +++ b/blowfish/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/blowfish/badge.svg [docs-link]: https://docs.rs/blowfish/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/blowfish/tests/data/blowfish_le.blb b/blowfish/tests/data/blowfish_le.blb new file mode 100644 index 00000000..eea65bd6 Binary files /dev/null and b/blowfish/tests/data/blowfish_le.blb differ diff --git a/blowfish/tests/mod.rs b/blowfish/tests/mod.rs index df20dbe0..79ad18f0 100644 --- a/blowfish/tests/mod.rs +++ b/blowfish/tests/mod.rs @@ -1 +1,3 @@ cipher::block_cipher_test!(blowfish_test, "blowfish", blowfish::Blowfish); +// Tests for BlowfishLE were randomly generated using implementation in this crate +cipher::block_cipher_test!(blowfish_le_test, "blowfish_le", blowfish::BlowfishLE); diff --git a/camellia/Cargo.toml b/camellia/Cargo.toml index 770256bc..23acdedc 100644 --- a/camellia/Cargo.toml +++ b/camellia/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "camellia" -version = "0.1.0" +version = "0.2.0-pre" description = "Camellia block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/camellia" repository = "https://github.com/RustCrypto/block-ciphers" @@ -14,10 +14,10 @@ categories = ["cryptography", "no-std"] [dependencies] byteorder = { version = "1.1", default-features = false } -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } [features] zeroize = ["cipher/zeroize"] diff --git a/camellia/README.md b/camellia/README.md index 2eeb6885..bb9fe26e 100644 --- a/camellia/README.md +++ b/camellia/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/camellia/badge.svg [docs-link]: https://docs.rs/camellia/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/camellia/src/lib.rs b/camellia/src/lib.rs index 9d5f20f4..83bec0f5 100644 --- a/camellia/src/lib.rs +++ b/camellia/src/lib.rs @@ -10,12 +10,12 @@ //! //! # Examples //! ``` -//! use camellia::cipher::generic_array::GenericArray; -//! use camellia::cipher::{BlockDecrypt, BlockEncrypt, KeyInit}; +//! use camellia::cipher::array::Array; +//! use camellia::cipher::{BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; //! use camellia::Camellia128; //! -//! let key = GenericArray::from([0_u8; 16]); -//! let mut block = GenericArray::from([0_u8; 16]); +//! let key = Array::from([0_u8; 16]); +//! let mut block = Array::from([0_u8; 16]); //! //! // Initialize cipher //! let cipher = Camellia128::new(&key); diff --git a/cast5/Cargo.toml b/cast5/Cargo.toml index d2884a7e..85c83308 100644 --- a/cast5/Cargo.toml +++ b/cast5/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "cast5" -version = "0.11.1" +version = "0.12.0-pre" description = "CAST5 block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/cast5" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,11 +13,11 @@ keywords = ["crypto", "cast5", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } -hex-literal = "0.3" +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" [features] zeroize = ["cipher/zeroize"] diff --git a/cast5/README.md b/cast5/README.md index 1a0665f6..621405ec 100644 --- a/cast5/README.md +++ b/cast5/README.md @@ -28,7 +28,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -60,7 +60,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/cast5/badge.svg [docs-link]: https://docs.rs/cast5/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/cast5/src/lib.rs b/cast5/src/lib.rs index 40bbbd13..575f0d33 100644 --- a/cast5/src/lib.rs +++ b/cast5/src/lib.rs @@ -10,12 +10,12 @@ //! //! # Examples //! ``` -//! use cast5::cipher::generic_array::GenericArray; -//! use cast5::cipher::{Key, Block, BlockEncrypt, BlockDecrypt, KeyInit}; +//! use cast5::cipher::array::Array; +//! use cast5::cipher::{Key, Block, BlockCipherEncrypt, BlockCipherDecrypt, KeyInit}; //! use cast5::Cast5; //! -//! let key = GenericArray::from([0u8; 16]); -//! let mut block = GenericArray::from([0u8; 8]); +//! let key = Array::from([0u8; 16]); +//! let mut block = Array::from([0u8; 8]); //! // Initialize cipher //! let cipher = Cast5::new(&key); //! diff --git a/cast5/tests/mod.rs b/cast5/tests/mod.rs index 8d0a2500..9da6622d 100644 --- a/cast5/tests/mod.rs +++ b/cast5/tests/mod.rs @@ -1,5 +1,5 @@ use cast5::Cast5; -use cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt, KeyInit}; +use cipher::{array::Array, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; use hex_literal::hex; /// Test vectors from RFC 2144 Appendix B.1 @@ -9,12 +9,12 @@ fn rfc2144_b1() { let key128 = hex!("0123456712345678234567893456789A"); let key80 = hex!("01234567123456782345"); let key40 = hex!("0123456712"); - let ct128 = GenericArray::from(hex!("238B4FE5847E44B2")); - let ct80 = GenericArray::from(hex!("EB6A711A2C02271B")); - let ct40 = GenericArray::from(hex!("7AC816D16E9B302E")); - let pt = GenericArray::from(hex!("0123456789ABCDEF")); + let ct128 = Array::from(hex!("238B4FE5847E44B2")); + let ct80 = Array::from(hex!("EB6A711A2C02271B")); + let ct40 = Array::from(hex!("7AC816D16E9B302E")); + let pt = Array::from(hex!("0123456789ABCDEF")); - let mut buf = pt.clone(); + let mut buf = pt; let c = Cast5::new_from_slice(&key128).unwrap(); c.encrypt_block(&mut buf); @@ -39,33 +39,33 @@ fn rfc2144_b1() { /// https://tools.ietf.org/html/rfc2144#appendix-B.1 #[test] fn full_maintance_test() { - let mut a = hex!("0123456712345678234567893456789A"); - let mut b = hex!("0123456712345678234567893456789A"); + let a = hex!("0123456712345678234567893456789A"); + let b = hex!("0123456712345678234567893456789A"); let verify_a = hex!("EEA9D0A249FD3BA6B3436FB89D6DCA92"); let verify_b = hex!("B2C95EB00C31AD7180AC05B8E83D696E"); let count = 1_000_000; - let (al, ar) = a.split_at_mut(8); - let (bl, br) = b.split_at_mut(8); + let (al, ar) = a.split_at(8); + let (bl, br) = b.split_at(8); - let mut al = GenericArray::from_mut_slice(al); - let mut ar = GenericArray::from_mut_slice(ar); + let mut al = Array::try_from(al).unwrap(); + let mut ar = Array::try_from(ar).unwrap(); - let mut bl = GenericArray::from_mut_slice(bl); - let mut br = GenericArray::from_mut_slice(br); + let mut bl = Array::try_from(bl).unwrap(); + let mut br = Array::try_from(br).unwrap(); for _ in 0..count { - let mut k = GenericArray::from([0u8; 16]); - k[..8].copy_from_slice(bl); - k[8..].copy_from_slice(br); + let mut k = Array::from([0u8; 16]); + k[..8].copy_from_slice(&bl); + k[8..].copy_from_slice(&br); let c = Cast5::new(&k); c.encrypt_block(&mut al); c.encrypt_block(&mut ar); - k[..8].copy_from_slice(al); - k[8..].copy_from_slice(ar); + k[..8].copy_from_slice(&al); + k[8..].copy_from_slice(&ar); let c = Cast5::new(&k); c.encrypt_block(&mut bl); c.encrypt_block(&mut br); diff --git a/cast6/CHANGELOG.md b/cast6/CHANGELOG.md new file mode 100644 index 00000000..d193d6da --- /dev/null +++ b/cast6/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.0 (2023-11-22) +- Initial release diff --git a/cast6/Cargo.toml b/cast6/Cargo.toml new file mode 100644 index 00000000..66818705 --- /dev/null +++ b/cast6/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "cast6" +version = "0.2.0-pre" +description = "CAST6 block cipher" +authors = ["RustCrypto Developers"] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version = "1.65" +readme = "README.md" +documentation = "https://docs.rs/cast6" +repository = "https://github.com/RustCrypto/block-ciphers" +keywords = ["crypto", "cast6", "block-cipher"] +categories = ["cryptography", "no-std"] + +[dependencies] +cipher = "=0.5.0-pre.6" + +[dev-dependencies] +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" + +[features] +zeroize = ["cipher/zeroize"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/cast6/LICENSE-APACHE b/cast6/LICENSE-APACHE new file mode 100644 index 00000000..78173fa2 --- /dev/null +++ b/cast6/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/cast6/LICENSE-MIT b/cast6/LICENSE-MIT new file mode 100644 index 00000000..50c61807 --- /dev/null +++ b/cast6/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2023 The RustCrypto Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/cast6/README.md b/cast6/README.md new file mode 100644 index 00000000..5e45c3bc --- /dev/null +++ b/cast6/README.md @@ -0,0 +1,71 @@ +# RustCrypto: CAST6 Cipher + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] +[![Build Status][build-image]][build-link] +[![HAZMAT][hazmat-image]][hazmat-link] + +Pure Rust implementation of the [CAST6 block cipher][1]. + +[Documentation][docs-link] + +## ⚠️ Security Warning: [Hazmat!][hazmat-link] + +This crate does not ensure ciphertexts are authentic (i.e. by using a MAC to +verify ciphertext integrity), which can lead to serious vulnerabilities +if used incorrectly! + +No security audits of this crate have ever been performed, and it has not been +thoroughly assessed to ensure its operation is constant-time on common CPU +architectures. + +USE AT YOUR OWN RISK! + +## Minimum Supported Rust Version + +Rust **1.65** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/cast6.svg +[crate-link]: https://crates.io/crates/cast6 +[docs-image]: https://docs.rs/cast6/badge.svg +[docs-link]: https://docs.rs/cast6/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg +[hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260039-block-ciphers +[build-image]: https://github.com/RustCrypto/block-ciphers/workflows/cast6/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/block-ciphers/actions?query=workflow%3Acast6 + +[//]: # (general links) + +[1]: https://en.wikipedia.org/wiki/CAST-256 diff --git a/cast6/benches/mod.rs b/cast6/benches/mod.rs new file mode 100644 index 00000000..d3f66f70 --- /dev/null +++ b/cast6/benches/mod.rs @@ -0,0 +1,8 @@ +#![feature(test)] +extern crate test; + +use cast6::Cast6; +use cipher::{block_decryptor_bench, block_encryptor_bench}; + +block_encryptor_bench!(Key: Cast6, cast6_encrypt_block, cast6_encrypt_blocks); +block_decryptor_bench!(Key: Cast6, cast6_decrypt_block, cast6_decrypt_blocks); diff --git a/cast6/src/consts.rs b/cast6/src/consts.rs new file mode 100644 index 00000000..bbcbc082 --- /dev/null +++ b/cast6/src/consts.rs @@ -0,0 +1,173 @@ +#![allow(clippy::unreadable_literal)] + +pub const S1: [u32; 256] = [ + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf, +]; + +pub const S2: [u32; 256] = [ + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1, +]; + +pub const S3: [u32; 256] = [ + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783, +]; + +pub const S4: [u32; 256] = [ + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2, +]; + +pub const TM: [u32; 192] = [ + 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d, 0x84c413be, 0xf39dff5f, 0x6277eb00, + 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525, 0xfb9370c6, 0x6a6d5c67, 0xd9474808, + 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d, 0x7262cdce, 0xe13cb96f, 0x5016a510, + 0xbef090b1, 0x2dca7c52, 0x9ca467f3, 0x0b7e5394, 0x7a583f35, 0xe9322ad6, 0x580c1677, 0xc6e60218, + 0x35bfedb9, 0xa499d95a, 0x1373c4fb, 0x824db09c, 0xf1279c3d, 0x600187de, 0xcedb737f, 0x3db55f20, + 0xac8f4ac1, 0x1b693662, 0x8a432203, 0xf91d0da4, 0x67f6f945, 0xd6d0e4e6, 0x45aad087, 0xb484bc28, + 0x235ea7c9, 0x9238936a, 0x01127f0b, 0x6fec6aac, 0xdec6564d, 0x4da041ee, 0xbc7a2d8f, 0x2b541930, + 0x9a2e04d1, 0x0907f072, 0x77e1dc13, 0xe6bbc7b4, 0x5595b355, 0xc46f9ef6, 0x33498a97, 0xa2237638, + 0x10fd61d9, 0x7fd74d7a, 0xeeb1391b, 0x5d8b24bc, 0xcc65105d, 0x3b3efbfe, 0xaa18e79f, 0x18f2d340, + 0x87ccbee1, 0xf6a6aa82, 0x65809623, 0xd45a81c4, 0x43346d65, 0xb20e5906, 0x20e844a7, 0x8fc23048, + 0xfe9c1be9, 0x6d76078a, 0xdc4ff32b, 0x4b29decc, 0xba03ca6d, 0x28ddb60e, 0x97b7a1af, 0x06918d50, + 0x756b78f1, 0xe4456492, 0x531f5033, 0xc1f93bd4, 0x30d32775, 0x9fad1316, 0x0e86feb7, 0x7d60ea58, + 0xec3ad5f9, 0x5b14c19a, 0xc9eead3b, 0x38c898dc, 0xa7a2847d, 0x167c701e, 0x85565bbf, 0xf4304760, + 0x630a3301, 0xd1e41ea2, 0x40be0a43, 0xaf97f5e4, 0x1e71e185, 0x8d4bcd26, 0xfc25b8c7, 0x6affa468, + 0xd9d99009, 0x48b37baa, 0xb78d674b, 0x266752ec, 0x95413e8d, 0x041b2a2e, 0x72f515cf, 0xe1cf0170, + 0x50a8ed11, 0xbf82d8b2, 0x2e5cc453, 0x9d36aff4, 0x0c109b95, 0x7aea8736, 0xe9c472d7, 0x589e5e78, + 0xc7784a19, 0x365235ba, 0xa52c215b, 0x14060cfc, 0x82dff89d, 0xf1b9e43e, 0x6093cfdf, 0xcf6dbb80, + 0x3e47a721, 0xad2192c2, 0x1bfb7e63, 0x8ad56a04, 0xf9af55a5, 0x68894146, 0xd7632ce7, 0x463d1888, + 0xb5170429, 0x23f0efca, 0x92cadb6b, 0x01a4c70c, 0x707eb2ad, 0xdf589e4e, 0x4e3289ef, 0xbd0c7590, + 0x2be66131, 0x9ac04cd2, 0x099a3873, 0x78742414, 0xe74e0fb5, 0x5627fb56, 0xc501e6f7, 0x33dbd298, + 0xa2b5be39, 0x118fa9da, 0x8069957b, 0xef43811c, 0x5e1d6cbd, 0xccf7585e, 0x3bd143ff, 0xaaab2fa0, + 0x19851b41, 0x885f06e2, 0xf738f283, 0x6612de24, 0xd4ecc9c5, 0x43c6b566, 0xb2a0a107, 0x217a8ca8, + 0x90547849, 0xff2e63ea, 0x6e084f8b, 0xdce23b2c, 0x4bbc26cd, 0xba96126e, 0x296ffe0f, 0x9849e9b0, + 0x0723d551, 0x75fdc0f2, 0xe4d7ac93, 0x53b19834, 0xc28b83d5, 0x31656f76, 0xa03f5b17, 0x0f1946b8, +]; + +pub const TR: [u8; 32] = [ + 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0a, 0x1b, 0x0c, 0x1d, 0x0e, 0x1f, 0x10, 0x01, 0x12, + 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1a, 0x0b, 0x1c, 0x0d, 0x1e, 0x0f, 0x00, 0x11, 0x02, +]; diff --git a/cast6/src/lib.rs b/cast6/src/lib.rs new file mode 100644 index 00000000..e6d2c89a --- /dev/null +++ b/cast6/src/lib.rs @@ -0,0 +1,301 @@ +//! Pure Rust implementation of the [CAST6] block cipher ([RFC 2612]). +//! +//! # ⚠️ Security Warning: Hazmat! +//! +//! This crate implements only the low-level block cipher function, and is intended +//! for use for implementing higher-level constructions *only*. It is NOT +//! intended for direct use in applications. +//! +//! USE AT YOUR OWN RISK! +//! +//! # Examples +//! ``` +//! use cast6::cipher::array::Array; +//! use cast6::cipher::{Key, Block, BlockCipherEncrypt, BlockCipherDecrypt, KeyInit}; +//! use cast6::Cast6; +//! +//! let key = Array::from([0u8; 32]); +//! let mut block = Array::from([0u8; 16]); +//! // Initialize cipher +//! let cipher = Cast6::new(&key); +//! +//! let block_copy = block.clone(); +//! // Encrypt block in-place +//! cipher.encrypt_block(&mut block); +//! // And decrypt it back +//! cipher.decrypt_block(&mut block); +//! assert_eq!(block, block_copy); +//! ``` +//! +//! [CAST6]: https://en.wikipedia.org/wiki/CAST-256 +//! [RFC 2612]: https://tools.ietf.org/html/rfc2612 + +#![no_std] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" +)] +#![deny(unsafe_code)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![warn(missing_docs, rust_2018_idioms)] + +pub use cipher; + +mod consts; + +use cipher::{ + consts::{U16, U32}, + AlgorithmName, BlockCipher, InvalidLength, Key, KeyInit, KeySizeUser, +}; +use core::fmt; + +#[cfg(feature = "zeroize")] +use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; + +use consts::{S1, S2, S3, S4, TM, TR}; + +/// The CAST6 block cipher. +#[derive(Clone)] +pub struct Cast6 { + masking: [[u32; 4]; 12], + rotate: [[u8; 4]; 12], +} + +impl Cast6 { + /// Implements the key schedule according to RFC 2612 2.4. + /// https://tools.ietf.org/html/rfc2612#section-2.4 + fn key_schedule(&mut self, key: &[u8; 32]) { + let mut kappa = to_u32s(key); + for i in 0..12 { + let m_idx = 16 * i; + let r_idx = 16 * (i % 2); + + let m = &TM[m_idx..][..8]; + let r = &TR[r_idx..][..8]; + forward_octave(&mut kappa, m, r); + + let m = &TM[m_idx + 8..][..8]; + let r = &TR[r_idx + 8..][..8]; + forward_octave(&mut kappa, m, r); + + let [a, b, c, d, e, f, g, h] = kappa; + self.masking[i] = [h, f, d, b]; + + self.rotate[i][0] = (a & 0x1f) as u8; + self.rotate[i][1] = (c & 0x1f) as u8; + self.rotate[i][2] = (e & 0x1f) as u8; + self.rotate[i][3] = (g & 0x1f) as u8; + } + } +} + +macro_rules! f1 { + ($D:expr, $m:expr, $r:expr) => {{ + let i = ($m.wrapping_add($D)).rotate_left(u32::from($r)); + (S1[(i >> 24) as usize] ^ S2[((i >> 16) & 0xff) as usize]) + .wrapping_sub(S3[((i >> 8) & 0xff) as usize]) + .wrapping_add(S4[(i & 0xff) as usize]) + }}; +} + +macro_rules! f2 { + ($D:expr, $m:expr, $r:expr) => {{ + let i = ($m ^ $D).rotate_left(u32::from($r)); + S1[(i >> 24) as usize] + .wrapping_sub(S2[((i >> 16) & 0xff) as usize]) + .wrapping_add(S3[((i >> 8) & 0xff) as usize]) + ^ S4[(i & 0xff) as usize] + }}; +} + +macro_rules! f3 { + ($D:expr, $m:expr, $r:expr) => {{ + let i = ($m.wrapping_sub($D)).rotate_left(u32::from($r)); + (S1[(i >> 24) as usize].wrapping_add(S2[((i >> 16) & 0xff) as usize]) + ^ S3[((i >> 8) & 0xff) as usize]) + .wrapping_sub(S4[(i & 0xff) as usize]) + }}; +} + +#[inline] +fn forward_quad(beta: &mut [u32; 4], m: &[u32; 4], r: &[u8; 4]) { + // Let "BETA <- Qi(BETA)" be short-hand notation for the following: + // C = C ^ f1(D, Kr0_(i), Km0_(i)) + // B = B ^ f2(C, Kr1_(i), Km1_(i)) + // A = A ^ f3(B, Kr2_(i), Km2_(i)) + // D = D ^ f1(A, Kr3_(i), Km3_(i)) + + let [a, b, c, d] = beta; + *c ^= f1!(*d, m[0], r[0]); + *b ^= f2!(*c, m[1], r[1]); + *a ^= f3!(*b, m[2], r[2]); + *d ^= f1!(*a, m[3], r[3]); +} + +#[inline] +fn reverse_quad(beta: &mut [u32; 4], m: &[u32; 4], r: &[u8; 4]) { + // Let "BETA <- QBARi(BETA)" be short-hand notation for the + // following: + // D = D ^ f1(A, Kr3_(i), Km3_(i)) + // A = A ^ f3(B, Kr2_(i), Km2_(i)) + // B = B ^ f2(C, Kr1_(i), Km1_(i)) + // C = C ^ f1(D, Kr0_(i), Km0_(i)) + + let [a, b, c, d] = beta; + *d ^= f1!(*a, m[3], r[3]); + *a ^= f3!(*b, m[2], r[2]); + *b ^= f2!(*c, m[1], r[1]); + *c ^= f1!(*d, m[0], r[0]); +} + +#[inline] +fn forward_octave(kappa: &mut [u32; 8], m: &[u32], r: &[u8]) { + // Let "KAPPA <- Wi(KAPPA)" be short-hand notation for the + // following: + // G = G ^ f1(H, Tr0_(i), Tm0_(i)) + // F = F ^ f2(G, Tr1_(i), Tm1_(i)) + // E = E ^ f3(F, Tr2_(i), Tm2_(i)) + // D = D ^ f1(E, Tr3_(i), Tm3_(i)) + // C = C ^ f2(D, Tr4_(i), Tm4_(i)) + // B = B ^ f3(C, Tr5_(i), Tm5_(i)) + // A = A ^ f1(B, Tr6_(i), Tm6_(i)) + // H = H ^ f2(A, Tr7_(i), Tm7_(i)) + + let [a, b, c, d, e, f, g, h] = kappa; + *g ^= f1!(*h, m[0], r[0]); + *f ^= f2!(*g, m[1], r[1]); + *e ^= f3!(*f, m[2], r[2]); + *d ^= f1!(*e, m[3], r[3]); + *c ^= f2!(*d, m[4], r[4]); + *b ^= f3!(*c, m[5], r[5]); + *a ^= f1!(*b, m[6], r[6]); + *h ^= f2!(*a, m[7], r[7]); +} + +impl BlockCipher for Cast6 {} + +impl KeySizeUser for Cast6 { + type KeySize = U32; +} + +impl KeyInit for Cast6 { + fn new(key: &Key) -> Self { + Self::new_from_slice(key).unwrap() + } + + fn new_from_slice(key: &[u8]) -> Result { + // Available key sizes are 128, 160, 192, 224, and 256 bits. + if ![16, 20, 24, 28, 32].contains(&key.len()) { + return Err(InvalidLength); + } + let mut cast6 = Self { + masking: [[0u32; 4]; 12], + rotate: [[0u8; 4]; 12], + }; + + // Pad keys that are less than 256 bits long. + let mut padded_key = [0u8; 32]; + padded_key[..key.len()].copy_from_slice(key); + cast6.key_schedule(&padded_key); + Ok(cast6) + } +} + +impl fmt::Debug for Cast6 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Cast6 { ... }") + } +} + +impl AlgorithmName for Cast6 { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Cast6") + } +} + +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl Drop for Cast6 { + fn drop(&mut self) { + self.masking.zeroize(); + self.rotate.zeroize(); + } +} + +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl ZeroizeOnDrop for Cast6 {} + +cipher::impl_simple_block_encdec!( + Cast6, U16, cipher, block, + encrypt: { + let masking = &cipher.masking; + let rotate = &cipher.rotate; + + // Let BETA = (ABCD) be a 128-bit block where A, B, C and D are each + // 32 bits in length. + // BETA = 128bits of plaintext. + let mut beta = to_u32s(block.get_in()); + + // for (i=0; i<6; i++) + // BETA <- Qi(BETA) + forward_quad(&mut beta, &masking[0], &rotate[0]); + forward_quad(&mut beta, &masking[1], &rotate[1]); + forward_quad(&mut beta, &masking[2], &rotate[2]); + forward_quad(&mut beta, &masking[3], &rotate[3]); + forward_quad(&mut beta, &masking[4], &rotate[4]); + forward_quad(&mut beta, &masking[5], &rotate[5]); + + // for (i=6; i<12; i++) + // BETA <- QBARi(BETA) + reverse_quad(&mut beta, &masking[6], &rotate[6]); + reverse_quad(&mut beta, &masking[7], &rotate[7]); + reverse_quad(&mut beta, &masking[8], &rotate[8]); + reverse_quad(&mut beta, &masking[9], &rotate[9]); + reverse_quad(&mut beta, &masking[10], &rotate[10]); + reverse_quad(&mut beta, &masking[11], &rotate[11]); + + // 128bits of ciphertext = BETA + *block.get_out() = to_u8s::<16>(&beta).into(); + } + decrypt: { + let masking = &cipher.masking; + let rotate = &cipher.rotate; + + let mut beta = to_u32s(block.get_in()); + + forward_quad(&mut beta, &masking[11], &rotate[11]); + forward_quad(&mut beta, &masking[10], &rotate[10]); + forward_quad(&mut beta, &masking[9], &rotate[9]); + forward_quad(&mut beta, &masking[8], &rotate[8]); + forward_quad(&mut beta, &masking[7], &rotate[7]); + forward_quad(&mut beta, &masking[6], &rotate[6]); + + reverse_quad(&mut beta, &masking[5], &rotate[5]); + reverse_quad(&mut beta, &masking[4], &rotate[4]); + reverse_quad(&mut beta, &masking[3], &rotate[3]); + reverse_quad(&mut beta, &masking[2], &rotate[2]); + reverse_quad(&mut beta, &masking[1], &rotate[1]); + reverse_quad(&mut beta, &masking[0], &rotate[0]); + + *block.get_out() = to_u8s::<16>(&beta).into(); + } +); + +fn to_u32s(src: &[u8]) -> [u32; N] { + assert_eq!(src.len(), 4 * N); + let mut res = [0u32; N]; + for (chunk, dst) in src.chunks_exact(4).zip(res.iter_mut()) { + *dst = u32::from_be_bytes(chunk.try_into().unwrap()); + } + res +} + +fn to_u8s(src: &[u32]) -> [u8; N] { + assert_eq!(4 * src.len(), N); + let mut res = [0u8; N]; + for (dst_chunk, src) in res.chunks_exact_mut(4).zip(src.iter()) { + dst_chunk.copy_from_slice(&src.to_be_bytes()); + } + res +} diff --git a/cast6/tests/mod.rs b/cast6/tests/mod.rs new file mode 100644 index 00000000..6f7bf4d8 --- /dev/null +++ b/cast6/tests/mod.rs @@ -0,0 +1,36 @@ +use cast6::Cast6; +use cipher::{Block, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; +use hex_literal::hex; + +/// Test vectors from RFC 2612 Appendix A +/// https://tools.ietf.org/html/rfc2612#page-10 +#[test] +fn rfc2144_a() { + let key128 = hex!("2342bb9efa38542c0af75647f29f615d"); + let key192 = hex!("2342bb9efa38542cbed0ac83940ac298bac77a7717942863"); + let key256 = hex!("2342bb9efa38542cbed0ac83940ac2988d7c47ce264908461cc1b5137ae6b604"); + let ct128 = hex!("c842a08972b43d20836c91d1b7530f6b"); + let ct192 = hex!("1b386c0210dcadcbdd0e41aa08a7a7e8"); + let ct256 = hex!("4f6a2038286897b9c9870136553317fa"); + let pt = Block::::default(); + + let mut buf = pt; + + let c = Cast6::new_from_slice(&key128).unwrap(); + c.encrypt_block(&mut buf); + assert_eq!(buf, ct128); + c.decrypt_block(&mut buf); + assert_eq!(buf, pt); + + let c = Cast6::new_from_slice(&key192).unwrap(); + c.encrypt_block(&mut buf); + assert_eq!(buf, ct192); + c.decrypt_block(&mut buf); + assert_eq!(buf, pt); + + let c = Cast6::new_from_slice(&key256).unwrap(); + c.encrypt_block(&mut buf); + assert_eq!(buf, ct256); + c.decrypt_block(&mut buf); + assert_eq!(buf, pt); +} diff --git a/des/CHANGELOG.md b/des/CHANGELOG.md index 6320ad6b..8586338d 100644 --- a/des/CHANGELOG.md +++ b/des/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Changed +- Remove `html_root_url` ([#344]) +- Update Clippy and fix lints ([#378]) +- Bump `cipher` to v0.5.0-pre.1; MSRV 1.65 ([#394]) +- Bump `cipher` dependency to v0.5.0-pre.2 ([#398]) +- bump `cipher` dependency to `0.5.0-pre.4` ([#413]) + +[#344]: https://github.com/RustCrypto/block-ciphers/pull/344 +[#378]: https://github.com/RustCrypto/block-ciphers/pull/378 +[#394]: https://github.com/RustCrypto/block-ciphers/pull/394 +[#398]: https://github.com/RustCrypto/block-ciphers/pull/398 +[#413]: https://github.com/RustCrypto/block-ciphers/pull/413 + ## 0.8.1 (2022-02-17) ### Fixed - Minimal versions build ([#303]) diff --git a/des/Cargo.toml b/des/Cargo.toml index 17238d12..d8a327bf 100644 --- a/des/Cargo.toml +++ b/des/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "des" -version = "0.8.1" +version = "0.9.0-pre.1" description = "DES and Triple DES (3DES, TDES) block ciphers implementation" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/des" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,10 +13,10 @@ keywords = ["crypto", "des", "tdes", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } [features] zeroize = ["cipher/zeroize"] diff --git a/des/README.md b/des/README.md index 732c7f64..53f399cb 100644 --- a/des/README.md +++ b/des/README.md @@ -28,7 +28,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -60,7 +60,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/des/badge.svg [docs-link]: https://docs.rs/des/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/des/src/des.rs b/des/src/des.rs index f4e1c933..0f6c628b 100644 --- a/des/src/des.rs +++ b/des/src/des.rs @@ -149,7 +149,7 @@ fn round(input: u64, key: u64) -> u64 { } fn f(input: u64, key: u64) -> u64 { - let mut val = e(input as u64); + let mut val = e(input); val ^= key; val = apply_sboxes(val); p(val) diff --git a/gift/.gitignore b/gift/.gitignore new file mode 100644 index 00000000..5a50b7f9 --- /dev/null +++ b/gift/.gitignore @@ -0,0 +1 @@ +/target/* diff --git a/gift/CHANGELOG.md b/gift/CHANGELOG.md new file mode 100644 index 00000000..16e3f8e1 --- /dev/null +++ b/gift/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.0 (2022-08-16) +- Initial release diff --git a/gift/Cargo.toml b/gift/Cargo.toml new file mode 100644 index 00000000..1e3c6c90 --- /dev/null +++ b/gift/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "gift-cipher" +version = "0.0.0" +description = "Gift block cipher" +authors = ["RustCrypto Developers", "Schmid7k"] +license = "MIT OR Apache-2.0" +rust-version = "1.56" +edition = "2021" +readme = "README.md" +documentation = "https://docs.rs/gift-cipher" +repository = "https://github.com/RustCrypto/block-ciphers" +keywords = ["crypto", "gift", "block-cipher"] +categories = ["cryptography", "no-std"] + +[dependencies] +cipher = "=0.5.0-pre.6" + +[dev-dependencies] +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +criterion = "0.3.5" + +[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dev-dependencies] +criterion-cycles-per-byte = "0.1.2" + +[features] +zeroize = ["cipher/zeroize"] + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] + +[[bench]] +name = "gift128enc" +path = "benches/gift128enc.rs" +harness = false diff --git a/gift/LICENSE-APACHE b/gift/LICENSE-APACHE new file mode 100644 index 00000000..78173fa2 --- /dev/null +++ b/gift/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/gift/LICENSE-MIT b/gift/LICENSE-MIT new file mode 100644 index 00000000..f8eccd8c --- /dev/null +++ b/gift/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2021 Shun Sakai + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/gift/README.md b/gift/README.md new file mode 100644 index 00000000..6a9dae6a --- /dev/null +++ b/gift/README.md @@ -0,0 +1,71 @@ +# RustCrypto: Gift Cipher + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] +[![Build Status][build-image]][build-link] +[![HAZMAT][hazmat-image]][hazmat-link] + +Pure Rust implementation of the [Gift block cipher][1]. + +[Documentation][docs-link] + +## ⚠️ Security Warning: [Hazmat!][hazmat-link] + +This crate does not ensure ciphertexts are authentic (i.e. by using a MAC to +verify ciphertext integrity), which can lead to serious vulnerabilities +if used incorrectly! + +No security audits of this crate have ever been performed, and it has not been +thoroughly assessed to ensure its operation is constant-time on common CPU +architectures. + +USE AT YOUR OWN RISK! + +## Minimum Supported Rust Version + +Rust **1.56** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/gift_cipher.svg +[crate-link]: https://crates.io/crates/gift_cipher +[docs-image]: https://docs.rs/gift_cipher/badge.svg +[docs-link]: https://docs.rs/gift_cipher/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg +[hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260039-block-ciphers +[build-image]: https://github.com/RustCrypto/block-ciphers/workflows/gift_cipher/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/block-ciphers/actions?query=workflow%3Agift_cipher + +[//]: # (general links) + +[1]: https://eprint.iacr.org/2017/622.pdf diff --git a/gift/benches/gift128enc.rs b/gift/benches/gift128enc.rs new file mode 100644 index 00000000..9df2f03b --- /dev/null +++ b/gift/benches/gift128enc.rs @@ -0,0 +1,32 @@ +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use criterion_cycles_per_byte::CyclesPerByte; +use gift_cipher::cipher::{BlockEncrypt, KeyInit}; +use gift_cipher::Gift128; + +const KB: usize = 1024; + +fn bench(c: &mut Criterion) { + let mut group = c.benchmark_group("gift128enc"); + + let cipher128 = Gift128::new(&Default::default()); + + for size in &[KB, 2 * KB, 4 * KB, 8 * KB, 16 * KB] { + let mut buf = vec![Default::default(); *size / 16]; + + group.throughput(Throughput::Bytes(*size as u64)); + + group.bench_function(BenchmarkId::new("encrypt-128", size), |b| { + b.iter(|| cipher128.encrypt_blocks(&mut buf)); + }); + } + + group.finish(); +} + +criterion_group!( + name = benches; + config = Criterion::default().with_measurement(CyclesPerByte); + targets = bench +); + +criterion_main!(benches); diff --git a/gift/src/consts.rs b/gift/src/consts.rs new file mode 100644 index 00000000..f5ad22bf --- /dev/null +++ b/gift/src/consts.rs @@ -0,0 +1,8 @@ +/// Gift round constants according to the fixsliced representation +pub(crate) const GIFT_RC: [u32; 40] = [ + 0x10000008, 0x80018000, 0x54000002, 0x01010181, 0x8000001f, 0x10888880, 0x6001e000, 0x51500002, + 0x03030180, 0x8000002f, 0x10088880, 0x60016000, 0x41500002, 0x03030080, 0x80000027, 0x10008880, + 0x4001e000, 0x11500002, 0x03020180, 0x8000002b, 0x10080880, 0x60014000, 0x01400002, 0x02020080, + 0x80000021, 0x10000080, 0x0001c000, 0x51000002, 0x03010180, 0x8000002e, 0x10088800, 0x60012000, + 0x40500002, 0x01030080, 0x80000006, 0x10008808, 0xc001a000, 0x14500002, 0x01020181, 0x8000001a, +]; diff --git a/gift/src/gift.rs b/gift/src/gift.rs new file mode 100644 index 00000000..9e6d829d --- /dev/null +++ b/gift/src/gift.rs @@ -0,0 +1,134 @@ +// This implementation is based on the +// 32-bit word oriented C implementation https://github.com/aadomn/gift/tree/master/crypto_bc/gift128/opt32 from https://github.com/aadomn/gift + +use cipher::{consts::U16, BlockCipher, Key, KeyInit, KeySizeUser}; +use core::fmt; + +#[cfg(feature = "zeroize")] +use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; + +use crate::{ + consts::GIFT_RC, + key_schedule::{ + key_double_update_1, key_double_update_2, key_double_update_3, key_double_update_4, + key_triple_update_0, key_triple_update_1, key_triple_update_2, key_triple_update_3, + key_triple_update_4, key_update, rearrange_rkey_0, rearrange_rkey_1, rearrange_rkey_2, + rearrange_rkey_3, + }, + primitives::{ + inv_quintuple_round, packing, quintuple_round, swapmovesingle, u32big, unpacking, + }, +}; + +impl Gift128 { + #[inline] + fn precompute_rkeys(key: &[u8]) -> Self { + let mut rkey = [0u32; 80]; + rkey[0] = u32big(&(key[12..16])); + rkey[1] = u32big(&(key[4..8])); + rkey[2] = u32big(&(key[8..12])); + rkey[3] = u32big(&(key[0..4])); + + for i in (0..16).step_by(2) { + rkey[i + 4] = rkey[i + 1]; + rkey[i + 5] = key_update(&rkey[i]); + } + + for i in (0..20).step_by(10) { + rkey[i] = rearrange_rkey_0(&rkey[i]); + rkey[i + 1] = rearrange_rkey_0(&rkey[i + 1]); + rkey[i + 2] = rearrange_rkey_1(&rkey[i + 2]); + rkey[i + 3] = rearrange_rkey_1(&rkey[i + 3]); + rkey[i + 4] = rearrange_rkey_2(&rkey[i + 4]); + rkey[i + 5] = rearrange_rkey_2(&rkey[i + 5]); + rkey[i + 6] = rearrange_rkey_3(&rkey[i + 6]); + rkey[i + 7] = rearrange_rkey_3(&rkey[i + 7]); + } + + for i in (20..80).step_by(10) { + rkey[i] = rkey[i - 19]; + rkey[i + 1] = key_triple_update_0(&rkey[i - 20]); + rkey[i + 2] = key_double_update_1(&rkey[i - 17]); + rkey[i + 3] = key_triple_update_1(&rkey[i - 18]); + rkey[i + 4] = key_double_update_2(&rkey[i - 15]); + rkey[i + 5] = key_triple_update_2(&rkey[i - 16]); + rkey[i + 6] = key_double_update_3(&rkey[i - 13]); + rkey[i + 7] = key_triple_update_3(&rkey[i - 14]); + rkey[i + 8] = key_double_update_4(&rkey[i - 11]); + rkey[i + 9] = key_triple_update_4(&rkey[i - 12]); + swapmovesingle(&mut rkey[i], 0x00003333, 16); + swapmovesingle(&mut rkey[i], 0x55554444, 1); + swapmovesingle(&mut rkey[i + 1], 0x55551100, 1); + } + + Self { k: rkey } + } +} + +impl KeyInit for Gift128 { + fn new(key: &Key) -> Self { + Self::precompute_rkeys(key[0..16].try_into().unwrap()) + } +} + +macro_rules! impl_gift { + ($name:ident, $subkey_size:literal, $key_size:ty, $doc:literal) => { + #[doc = $doc] + #[derive(Clone)] + pub struct $name { + /// Subkeys + k: [u32; $subkey_size], + } + + impl BlockCipher for $name {} + + impl KeySizeUser for $name { + type KeySize = $key_size; + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + #[cfg(feature = "zeroize")] + #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] + impl Drop for $name { + fn drop(&mut self) { + self.k.zeroize(); + } + } + + #[cfg(feature = "zeroize")] + #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] + impl ZeroizeOnDrop for $name {} + + cipher::impl_simple_block_encdec!( + $name, U16, cipher, block, + encrypt: { + let b = block.get_in(); + let mut state = [0u32; 4]; + packing(&mut state, b); + for i in (0..40).step_by(5) { + quintuple_round(&mut state, &cipher.k[i*2..], &GIFT_RC[i..]); + } + unpacking(&state, block.get_out()); + } + decrypt: { + let b = block.get_in(); + let mut state = [0u32; 4]; + packing(&mut state, b); + let mut i: usize = 35; + while i > 0 { + inv_quintuple_round(&mut state, &cipher.k[i*2..], &GIFT_RC[i..]); + i -= 5; + } + inv_quintuple_round(&mut state, &cipher.k[i*2..], &GIFT_RC[i..]); + unpacking(&state, block.get_out()); + } + ); + }; +} + +impl_gift!(Gift128, 80, U16, "Gift-128 block cipher instance."); diff --git a/gift/src/key_schedule.rs b/gift/src/key_schedule.rs new file mode 100644 index 00000000..58801b49 --- /dev/null +++ b/gift/src/key_schedule.rs @@ -0,0 +1,114 @@ +use crate::primitives::{ror, swapmovesingle}; + +#[inline] +pub(crate) fn rearrange_rkey_0(x: &u32) -> u32 { + let mut tmp = *x; + swapmovesingle(&mut tmp, 0x00550055, 9); + swapmovesingle(&mut tmp, 0x000f000f, 12); + swapmovesingle(&mut tmp, 0x00003333, 18); + swapmovesingle(&mut tmp, 0x000000ff, 24); + tmp +} + +#[inline] +pub(crate) fn rearrange_rkey_1(x: &u32) -> u32 { + let mut tmp = *x; + swapmovesingle(&mut tmp, 0x11111111, 3); + swapmovesingle(&mut tmp, 0x03030303, 6); + swapmovesingle(&mut tmp, 0x000f000f, 12); + swapmovesingle(&mut tmp, 0x000000ff, 24); + tmp +} + +#[inline] +pub(crate) fn rearrange_rkey_2(x: &u32) -> u32 { + let mut tmp = *x; + swapmovesingle(&mut tmp, 0x0000aaaa, 15); + swapmovesingle(&mut tmp, 0x00003333, 18); + swapmovesingle(&mut tmp, 0x0000f0f0, 12); + swapmovesingle(&mut tmp, 0x000000ff, 24); + tmp +} + +#[inline] +pub(crate) fn rearrange_rkey_3(x: &u32) -> u32 { + let mut tmp = *x; + swapmovesingle(&mut tmp, 0x0a0a0a0a, 3); + swapmovesingle(&mut tmp, 0x00cc00cc, 6); + swapmovesingle(&mut tmp, 0x0000f0f0, 12); + swapmovesingle(&mut tmp, 0x000000ff, 24); + tmp +} + +#[inline] +pub(crate) fn key_update(x: &u32) -> u32 { + (((*x) >> 12) & 0x0000000f) + | (((*x) & 0x00000fff) << 4) + | (((*x) >> 2) & 0x3fff0000) + | (((*x) & 0x00030000) << 14) +} + +#[inline] +pub(crate) fn key_triple_update_0(x: &u32) -> u32 { + ror(&(*x & 0x33333333), &24) | ror(&(*x & 0xcccccccc), &16) +} + +#[inline] +pub(crate) fn key_double_update_1(x: &u32) -> u32 { + (((x) >> 4) & 0x0f000f00) + | (((x) & 0x0f000f00) << 4) + | (((x) >> 6) & 0x00030003) + | (((x) & 0x003f003f) << 2) +} + +#[inline] +pub(crate) fn key_triple_update_1(x: &u32) -> u32 { + (((x) >> 6) & 0x03000300) + | (((x) & 0x3f003f00) << 2) + | (((x) >> 5) & 0x00070007) + | (((x) & 0x001f001f) << 3) +} + +#[inline] +pub(crate) fn key_double_update_2(x: &u32) -> u32 { + ror(&(*x & 0xaaaaaaaa), &24) | ror(&(*x & 0x55555555), &16) +} + +#[inline] +pub(crate) fn key_triple_update_2(x: &u32) -> u32 { + ror(&(*x & 0x55555555), &24) | ror(&(*x & 0xaaaaaaaa), &20) +} + +#[inline] +pub(crate) fn key_double_update_3(x: &u32) -> u32 { + (((x) >> 2) & 0x03030303) + | (((x) & 0x03030303) << 2) + | (((x) >> 1) & 0x70707070) + | (((x) & 0x10101010) << 3) +} + +#[inline] +pub(crate) fn key_triple_update_3(x: &u32) -> u32 { + (((x) >> 18) & 0x00003030) + | (((x) & 0x01010101) << 3) + | (((x) >> 14) & 0x0000c0c0) + | (((x) & 0x0000e0e0) << 15) + | (((x) >> 1) & 0x07070707) + | (((x) & 0x00001010) << 19) +} + +#[inline] +pub(crate) fn key_double_update_4(x: &u32) -> u32 { + (((x) >> 4) & 0x0fff0000) + | (((x) & 0x000f0000) << 12) + | (((x) >> 8) & 0x000000ff) + | (((x) & 0x000000ff) << 8) +} + +#[inline] +pub(crate) fn key_triple_update_4(x: &u32) -> u32 { + (((x) >> 6) & 0x03ff0000) + | (((x) & 0x003f0000) << 10) + | (((x) >> 4) & 0x00000fff) + | (((x) & 0x0000000f) << 12) +} diff --git a/gift/src/lib.rs b/gift/src/lib.rs new file mode 100644 index 00000000..f0cd1f44 --- /dev/null +++ b/gift/src/lib.rs @@ -0,0 +1,53 @@ +//! Pure Rust implementation of the [Gift][1] block cipher. +//! +//! # ⚠️ Security Warning: Hazmat! +//! +//! This crate implements only the low-level block cipher function, and is intended +//! for use for implementing higher-level constructions *only*. It is NOT +//! intended for direct use in applications. +//! +//! USE AT YOUR OWN RISK! +//! +//! # Examples +//! ``` +//! use gift_cipher::cipher::array::Array; +//! use gift_cipher::cipher::{BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; +//! use gift_cipher::Gift128; +//! +//! let key = Array::from([0u8; 16]); +//! let mut block = Array::from([0u8; 16]); +//! +//! // Initialize cipher +//! let cipher = Gift128::new(&key); +//! +//! let block_copy = block; +//! +//! // Encrypt block in-place +//! cipher.encrypt_block(&mut block); +//! +//! // And decrypt it back +//! cipher.decrypt_block(&mut block); +//! +//! assert_eq!(block, block_copy); +//! ``` +//! +//! [1]: https://eprint.iacr.org/2017/622.pdf + +#![no_std] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", + html_root_url = "https://docs.rs/gift-cipher/0.0.1" +)] +#![deny(unsafe_code)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![warn(missing_docs, rust_2018_idioms)] + +pub use cipher; + +mod consts; +mod gift; +mod key_schedule; +mod primitives; + +pub use crate::gift::Gift128; diff --git a/gift/src/primitives.rs b/gift/src/primitives.rs new file mode 100644 index 00000000..1bb90d91 --- /dev/null +++ b/gift/src/primitives.rs @@ -0,0 +1,264 @@ +#[inline] +pub(crate) fn u32big(x: &[u8]) -> u32 { + ((x[0] as u32) << 24) | ((x[1] as u32) << 16) | ((x[2] as u32) << 8) | (x[3] as u32) +} + +#[inline] +pub(crate) fn ror(x: &u32, y: &u32) -> u32 { + ((*x) >> (*y)) | (*x << (32 - (*y))) +} + +#[inline] +pub(crate) fn byte_ror_2(x: &u32) -> u32 { + (((x) >> 2) & 0x3f3f3f3f) | (((x) & 0x03030303) << 6) +} + +#[inline] +pub(crate) fn byte_ror_4(x: &u32) -> u32 { + (((x) >> 4) & 0x0f0f0f0f) | (((x) & 0x0f0f0f0f) << 4) +} + +#[inline] +pub(crate) fn byte_ror_6(x: &u32) -> u32 { + (((x) >> 6) & 0x03030303) | (((x) & 0x3f3f3f3f) << 2) +} + +#[inline] +pub(crate) fn half_ror_4(&x: &u32) -> u32 { + (((x) >> 4) & 0x0fff0fff) | (((x) & 0x000f000f) << 12) +} + +#[inline] +pub(crate) fn half_ror_8(x: &u32) -> u32 { + (((x) >> 8) & 0x00ff00ff) | (((x) & 0x00ff00ff) << 8) +} + +#[inline] +pub(crate) fn half_ror_12(&x: &u32) -> u32 { + (((x) >> 12) & 0x000f000f) | (((x) & 0x0fff0fff) << 4) +} + +#[inline] +pub(crate) fn nibble_ror_1(x: &u32) -> u32 { + (((x) >> 1) & 0x77777777) | (((x) & 0x11111111) << 3) +} + +#[inline] +pub(crate) fn nibble_ror_2(x: &u32) -> u32 { + (((x) >> 2) & 0x33333333) | (((x) & 0x33333333) << 2) +} + +#[inline] +pub(crate) fn nibble_ror_3(&x: &u32) -> u32 { + (((x) >> 3) & 0x11111111) | (((x) & 0x77777777) << 1) +} + +#[inline] +pub(crate) fn swapmove(a: &mut u32, b: &mut u32, mask: u32, n: u8) { + let tmp = (*b ^ (*a >> n)) & mask; + *b ^= tmp; + *a ^= tmp << n; +} + +#[inline] +pub(crate) fn swapmovesingle(a: &mut u32, mask: u32, n: u8) { + let tmp = (*a ^ (*a >> n)) & mask; + *a ^= tmp; + *a ^= tmp << n; +} + +#[inline] +pub(crate) fn sbox(s0: &mut u32, s1: &mut u32, s2: &mut u32, s3: &mut u32) { + *s1 ^= *s0 & *s2; + *s0 ^= *s1 & *s3; + *s2 ^= *s0 | *s1; + *s3 ^= *s2; + *s1 ^= *s3; + *s3 ^= 0xffffffff; + *s2 ^= *s0 & *s1; +} + +#[inline] +pub(crate) fn inv_sbox(s0: &mut u32, s1: &mut u32, s2: &mut u32, s3: &mut u32) { + *s2 ^= *s3 & *s1; + *s0 ^= 0xffffffff; + *s1 ^= *s0; + *s0 ^= *s2; + *s2 ^= *s3 | *s1; + *s3 ^= *s1 & *s0; + *s1 ^= *s3 & *s2; +} + +#[inline] +pub(crate) fn packing(state: &mut [u32], input: &[u8]) { + let mut s0 = ((input[6] as u32) << 24) + | ((input[7] as u32) << 16) + | ((input[14] as u32) << 8) + | input[15] as u32; + let mut s1 = ((input[4] as u32) << 24) + | ((input[5] as u32) << 16) + | ((input[12] as u32) << 8) + | input[13] as u32; + let mut s2 = ((input[2] as u32) << 24) + | ((input[3] as u32) << 16) + | ((input[10] as u32) << 8) + | input[11] as u32; + let mut s3 = ((input[0] as u32) << 24) + | ((input[1] as u32) << 16) + | ((input[8] as u32) << 8) + | input[9] as u32; + swapmovesingle(&mut s0, 0x0a0a0a0a, 3); + swapmovesingle(&mut s0, 0x00cc00cc, 6); + swapmovesingle(&mut s1, 0x0a0a0a0a, 3); + swapmovesingle(&mut s1, 0x00cc00cc, 6); + swapmovesingle(&mut s2, 0x0a0a0a0a, 3); + swapmovesingle(&mut s2, 0x00cc00cc, 6); + swapmovesingle(&mut s3, 0x0a0a0a0a, 3); + swapmovesingle(&mut s3, 0x00cc00cc, 6); + swapmove(&mut s0, &mut s1, 0x000f000f, 4); + swapmove(&mut s0, &mut s2, 0x000f000f, 8); + swapmove(&mut s0, &mut s3, 0x000f000f, 12); + swapmove(&mut s1, &mut s2, 0x00f000f0, 4); + swapmove(&mut s1, &mut s3, 0x00f000f0, 8); + swapmove(&mut s2, &mut s3, 0x0f000f00, 4); + state[0] = s0; + state[1] = s1; + state[2] = s2; + state[3] = s3; +} + +#[inline] +pub(crate) fn unpacking(state: &[u32], output: &mut [u8]) { + let (mut s0, mut s1, mut s2, mut s3) = (state[0], state[1], state[2], state[3]); + + swapmove(&mut s2, &mut s3, 0x0f000f00, 4); + swapmove(&mut s1, &mut s3, 0x00f000f0, 8); + swapmove(&mut s1, &mut s2, 0x00f000f0, 4); + swapmove(&mut s0, &mut s3, 0x000f000f, 12); + swapmove(&mut s0, &mut s2, 0x000f000f, 8); + swapmove(&mut s0, &mut s1, 0x000f000f, 4); + swapmovesingle(&mut s3, 0x00cc00cc, 6); + swapmovesingle(&mut s3, 0x0a0a0a0a, 3); + swapmovesingle(&mut s2, 0x00cc00cc, 6); + swapmovesingle(&mut s2, 0x0a0a0a0a, 3); + swapmovesingle(&mut s1, 0x00cc00cc, 6); + swapmovesingle(&mut s1, 0x0a0a0a0a, 3); + swapmovesingle(&mut s0, 0x00cc00cc, 6); + swapmovesingle(&mut s0, 0x0a0a0a0a, 3); + output[0] = (s3 >> 24) as u8; + output[1] = ((s3 >> 16) & 0xff) as u8; + output[2] = (s2 >> 24) as u8; + output[3] = ((s2 >> 16) & 0xff) as u8; + output[4] = (s1 >> 24) as u8; + output[5] = ((s1 >> 16) & 0xff) as u8; + output[6] = (s0 >> 24) as u8; + output[7] = ((s0 >> 16) & 0xff) as u8; + output[8] = ((s3 >> 8) & 0xff) as u8; + output[9] = (s3 & 0xff) as u8; + output[10] = ((s2 >> 8) & 0xff) as u8; + output[11] = (s2 & 0xff) as u8; + output[12] = ((s1 >> 8) & 0xff) as u8; + output[13] = (s1 & 0xff) as u8; + output[14] = ((s0 >> 8) & 0xff) as u8; + output[15] = (s0 & 0xff) as u8; +} + +#[inline] +pub(crate) fn quintuple_round(state: &mut [u32; 4], rkey: &[u32], rconst: &[u32]) { + let mut s0 = state[0]; + let mut s1 = state[1]; + let mut s2 = state[2]; + let mut s3 = state[3]; + sbox(&mut s0, &mut s1, &mut s2, &mut s3); + s3 = nibble_ror_1(&s3); + s1 = nibble_ror_2(&s1); + s2 = nibble_ror_3(&s2); + s1 ^= rkey[0]; + s2 ^= rkey[1]; + s0 ^= rconst[0]; + sbox(&mut s3, &mut s1, &mut s2, &mut s0); + s0 = half_ror_4(&s0); + s1 = half_ror_8(&s1); + s2 = half_ror_12(&s2); + s1 ^= rkey[2]; + s2 ^= rkey[3]; + s3 ^= rconst[1]; + sbox(&mut s0, &mut s1, &mut s2, &mut s3); + s3 = ror(&s3, &16); + s2 = ror(&s2, &16); + swapmovesingle(&mut s1, 0x55555555, 1); + swapmovesingle(&mut s2, 0x00005555, 1); + swapmovesingle(&mut s3, 0x55550000, 1); + s1 ^= rkey[4]; + s2 ^= rkey[5]; + s0 ^= rconst[2]; + sbox(&mut s3, &mut s1, &mut s2, &mut s0); + s0 = byte_ror_6(&s0); + s1 = byte_ror_4(&s1); + s2 = byte_ror_2(&s2); + s1 ^= rkey[6]; + s2 ^= rkey[7]; + s3 ^= rconst[3]; + sbox(&mut s0, &mut s1, &mut s2, &mut s3); + s3 = ror(&s3, &24); + s1 = ror(&s1, &16); + s2 = ror(&s2, &8); + s1 ^= rkey[8]; + s2 ^= rkey[9]; + s0 ^= rconst[4]; + core::mem::swap(&mut s0, &mut s3); + state[0] = s0; + state[1] = s1; + state[2] = s2; + state[3] = s3; +} + +#[inline] +pub(crate) fn inv_quintuple_round(state: &mut [u32; 4], rkey: &[u32], rconst: &[u32]) { + let mut s0 = state[0]; + let mut s1 = state[1]; + let mut s2 = state[2]; + let mut s3 = state[3]; + core::mem::swap(&mut s0, &mut s3); + s1 ^= rkey[8]; + s2 ^= rkey[9]; + s0 ^= rconst[4]; + s3 = ror(&s3, &8); + s1 = ror(&s1, &16); + s2 = ror(&s2, &24); + inv_sbox(&mut s3, &mut s1, &mut s2, &mut s0); + s1 ^= rkey[6]; + s2 ^= rkey[7]; + s3 ^= rconst[3]; + s0 = byte_ror_2(&s0); + s1 = byte_ror_4(&s1); + s2 = byte_ror_6(&s2); + inv_sbox(&mut s0, &mut s1, &mut s2, &mut s3); + s1 ^= rkey[4]; + s2 ^= rkey[5]; + s0 ^= rconst[2]; + swapmovesingle(&mut s3, 0x55550000, 1); + swapmovesingle(&mut s1, 0x55555555, 1); + swapmovesingle(&mut s2, 0x00005555, 1); + s3 = ror(&s3, &16); + s2 = ror(&s2, &16); + inv_sbox(&mut s3, &mut s1, &mut s2, &mut s0); + s1 ^= rkey[2]; + s2 ^= rkey[3]; + s3 ^= rconst[1]; + s0 = half_ror_12(&s0); + s1 = half_ror_8(&s1); + s2 = half_ror_4(&s2); + inv_sbox(&mut s0, &mut s1, &mut s2, &mut s3); + s1 ^= rkey[0]; + s2 ^= rkey[1]; + s0 ^= rconst[0]; + s3 = nibble_ror_3(&s3); + s1 = nibble_ror_2(&s1); + s2 = nibble_ror_1(&s2); + inv_sbox(&mut s3, &mut s1, &mut s2, &mut s0); + state[0] = s0; + state[1] = s1; + state[2] = s2; + state[3] = s3; +} diff --git a/gift/tests/test.rs b/gift/tests/test.rs new file mode 100644 index 00000000..22cb3df4 --- /dev/null +++ b/gift/tests/test.rs @@ -0,0 +1,67 @@ +use cipher::{array::Array, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; +use gift_cipher::Gift128; + +const KEYS: [[u8; 16]; 3] = [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1st key + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + [ + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, // 2nd key + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + ], + [ + 0xd0, 0xf5, 0xc5, 0x9a, 0x77, 0x00, 0xd3, 0xe7, // 3rd key + 0x99, 0x02, 0x8f, 0xa9, 0xf9, 0x0a, 0xd8, 0x37, + ], +]; + +const PTEXT: [[u8; 16]; 3] = [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1st key + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + [ + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, // 2nd plaintext + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + ], + [ + 0xe3, 0x9c, 0x14, 0x1f, 0xa5, 0x7d, 0xba, 0x43, // 3rd plaintext + 0xf0, 0x8a, 0x85, 0xb6, 0xa9, 0x1f, 0x86, 0xc1, + ], +]; + +const CTEXT: [[u8; 16]; 3] = [ + [ + 0xcd, 0x0b, 0xd7, 0x38, 0x38, 0x8a, 0xd3, 0xf6, // 1st ciphertext + 0x68, 0xb1, 0x5a, 0x36, 0xce, 0xb6, 0xff, 0x92, + ], + [ + 0x84, 0x22, 0x24, 0x1a, 0x6d, 0xbf, 0x5a, 0x93, // 2nd ciphertext + 0x46, 0xaf, 0x46, 0x84, 0x09, 0xee, 0x01, 0x52, + ], + [ + 0x13, 0xed, 0xe6, 0x7c, 0xbd, 0xcc, 0x3d, 0xbf, // 3rd ciphertext + 0x40, 0x0a, 0x62, 0xd6, 0x97, 0x72, 0x65, 0xea, + ], +]; + +#[test] +fn test_vectors() { + for i in 0..3 { + let cipher = Gift128::new(&KEYS[i].into()); + let mut pt = Array::from(PTEXT[i]); + + cipher.encrypt_block(&mut pt); + + //println!("Ciphertext: {:#02x}", pt.as_slice()); + + assert_eq!(pt, Array::from(CTEXT[i])); + + cipher.decrypt_block(&mut pt); + + //println!("Plaintext: {:#02x}", pt.as_slice()); + + assert_eq!(pt, Array::from(PTEXT[i])); + } +} diff --git a/idea/Cargo.toml b/idea/Cargo.toml index 39575264..a05af49a 100644 --- a/idea/Cargo.toml +++ b/idea/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "idea" -version = "0.5.1" +version = "0.6.0-pre" description = "IDEA block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/idea" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,10 +13,10 @@ keywords = ["crypto", "idea", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } [features] zeroize = ["cipher/zeroize"] diff --git a/idea/README.md b/idea/README.md index c6e0385c..590f115c 100644 --- a/idea/README.md +++ b/idea/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/idea/badge.svg [docs-link]: https://docs.rs/idea/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/kuznyechik/CHANGELOG.md b/kuznyechik/CHANGELOG.md index 0ee35f5f..f8bad935 100644 --- a/kuznyechik/CHANGELOG.md +++ b/kuznyechik/CHANGELOG.md @@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Changed +- Update Clippy and fix lints ([#378]) +- Bump `cipher` to v0.5.0-pre.1; MSRV 1.65 ([#394]) +- Bump `cipher` dependency to v0.5.0-pre.2 ([#398]) +- Use `BlockCipherEncrypt`/`BlockCipherDecrypt` trait names ([#400]) +- bump `cipher` dependency to `0.5.0-pre.4` ([#413]) + +### Fixed +- Fix kuznyechik 32bit build ([#406]) + + +[#378]: https://github.com/RustCrypto/block-ciphers/pull/378 +[#394]: https://github.com/RustCrypto/block-ciphers/pull/394 +[#398]: https://github.com/RustCrypto/block-ciphers/pull/398 +[#400]: https://github.com/RustCrypto/block-ciphers/pull/400 +[#406]: https://github.com/RustCrypto/block-ciphers/pull/406 +[#413]: https://github.com/RustCrypto/block-ciphers/pull/413 + + +## 0.8.2 (2023-08-06) +### Fixed +- `Drop` implementations in the software backend with enabled `zeroize` feature ([#311]) + +[#311]: https://github.com/RustCrypto/block-ciphers/pull/311 + ## 0.8.1 (2022-02-17) ### Fixed - Minimal versions build ([#303]) diff --git a/kuznyechik/Cargo.toml b/kuznyechik/Cargo.toml index 1905098b..5517fbc7 100644 --- a/kuznyechik/Cargo.toml +++ b/kuznyechik/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "kuznyechik" -version = "0.8.1" +version = "0.9.0-pre.1" description = "Kuznyechik (GOST R 34.12-2015) block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/kuznyechik" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,15 +13,19 @@ keywords = ["crypto", "kuznyechik", "gost", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } -hex-literal = "0.3.3" +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" [features] zeroize = ["cipher/zeroize"] +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ["cfg(kuznyechik_force_soft)"] + [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/kuznyechik/README.md b/kuznyechik/README.md index 3ea1036a..49914033 100644 --- a/kuznyechik/README.md +++ b/kuznyechik/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/kuznyechik/badge.svg [docs-link]: https://docs.rs/kuznyechik/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/kuznyechik/src/lib.rs b/kuznyechik/src/lib.rs index af86f80e..d94ef04d 100644 --- a/kuznyechik/src/lib.rs +++ b/kuznyechik/src/lib.rs @@ -31,8 +31,8 @@ pub use cipher; use cipher::{ + array::Array, consts::{U16, U32}, - generic_array::GenericArray, }; mod consts; @@ -59,6 +59,6 @@ type BlockSize = U16; type KeySize = U32; /// 128-bit Kuznyechik block -pub type Block = GenericArray; +pub type Block = Array; /// 256-bit Kuznyechik key -pub type Key = GenericArray; +pub type Key = Array; diff --git a/kuznyechik/src/soft/mod.rs b/kuznyechik/src/soft/mod.rs index c972cbab..8cb35ef1 100644 --- a/kuznyechik/src/soft/mod.rs +++ b/kuznyechik/src/soft/mod.rs @@ -1,7 +1,7 @@ use crate::{BlockSize, Key, KeySize}; use cipher::{ - AlgorithmName, BlockCipher, BlockClosure, BlockDecrypt, BlockEncrypt, BlockSizeUser, KeyInit, - KeySizeUser, + AlgorithmName, BlockCipher, BlockCipherDecrypt, BlockCipherEncrypt, BlockClosure, + BlockSizeUser, KeyInit, KeySizeUser, }; use core::fmt; @@ -47,19 +47,17 @@ impl From for Kuznyechik { impl From<&KuznyechikEnc> for Kuznyechik { #[inline] fn from(enc: &KuznyechikEnc) -> Kuznyechik { - Self { - keys: enc.keys.clone(), - } + Self { keys: enc.keys } } } -impl BlockEncrypt for Kuznyechik { +impl BlockCipherEncrypt for Kuznyechik { fn encrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut EncBackend(&self.keys)); } } -impl BlockDecrypt for Kuznyechik { +impl BlockCipherDecrypt for Kuznyechik { fn decrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut DecBackend(&self.keys)); } @@ -113,7 +111,7 @@ impl KeyInit for KuznyechikEnc { } } -impl BlockEncrypt for KuznyechikEnc { +impl BlockCipherEncrypt for KuznyechikEnc { fn encrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut EncBackend(&self.keys)); } @@ -177,13 +175,11 @@ impl From for KuznyechikDec { impl From<&KuznyechikEnc> for KuznyechikDec { #[inline] fn from(enc: &KuznyechikEnc) -> KuznyechikDec { - Self { - keys: enc.keys.clone(), - } + Self { keys: enc.keys } } } -impl BlockDecrypt for KuznyechikDec { +impl BlockCipherDecrypt for KuznyechikDec { fn decrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut DecBackend(&self.keys)); } diff --git a/kuznyechik/src/sse2/backends.rs b/kuznyechik/src/sse2/backends.rs index 541fdece..091c3691 100644 --- a/kuznyechik/src/sse2/backends.rs +++ b/kuznyechik/src/sse2/backends.rs @@ -9,6 +9,10 @@ use cipher::{ typenum::Unsigned, BlockBackend, BlockSizeUser, ParBlocks, ParBlocksSizeUser, }; + +#[cfg(target_arch = "x86")] +use core::arch::x86::*; +#[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; pub(super) type RoundKeys = [__m128i; 10]; diff --git a/kuznyechik/src/sse2/mod.rs b/kuznyechik/src/sse2/mod.rs index 3ba16862..812ef08d 100644 --- a/kuznyechik/src/sse2/mod.rs +++ b/kuznyechik/src/sse2/mod.rs @@ -2,8 +2,8 @@ use crate::{BlockSize, Key, KeySize}; use cipher::{ - AlgorithmName, BlockCipher, BlockClosure, BlockDecrypt, BlockEncrypt, BlockSizeUser, KeyInit, - KeySizeUser, + AlgorithmName, BlockCipher, BlockCipherDecrypt, BlockCipherEncrypt, BlockClosure, + BlockSizeUser, KeyInit, KeySizeUser, }; use core::fmt; @@ -60,13 +60,13 @@ impl From<&KuznyechikEnc> for Kuznyechik { } } -impl BlockEncrypt for Kuznyechik { +impl BlockCipherEncrypt for Kuznyechik { fn encrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut EncBackend(&self.enc_keys)); } } -impl BlockDecrypt for Kuznyechik { +impl BlockCipherDecrypt for Kuznyechik { fn decrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut DecBackend(&self.dec_keys)); } @@ -121,7 +121,7 @@ impl KeyInit for KuznyechikEnc { } } -impl BlockEncrypt for KuznyechikEnc { +impl BlockCipherEncrypt for KuznyechikEnc { fn encrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut EncBackend(&self.keys)); } @@ -194,7 +194,7 @@ impl From<&KuznyechikEnc> for KuznyechikDec { } } -impl BlockDecrypt for KuznyechikDec { +impl BlockCipherDecrypt for KuznyechikDec { fn decrypt_with_backend(&self, f: impl BlockClosure) { f.call(&mut DecBackend(&self.keys)); } diff --git a/kuznyechik/tests/mod.rs b/kuznyechik/tests/mod.rs index d23f144b..bd080b31 100644 --- a/kuznyechik/tests/mod.rs +++ b/kuznyechik/tests/mod.rs @@ -1,4 +1,4 @@ -use cipher::{Block, BlockDecrypt, BlockEncrypt, KeyInit}; +use cipher::{Block, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; use hex_literal::hex; use kuznyechik::{Kuznyechik, KuznyechikDec, KuznyechikEnc}; @@ -37,8 +37,8 @@ fn kuznyechik() { }); } - let mut blocks2 = blocks.clone(); - let blocks_cpy = blocks.clone(); + let mut blocks2 = blocks; + let blocks_cpy = blocks; cipher.encrypt_blocks(&mut blocks); assert!(blocks[..] != blocks_cpy[..]); diff --git a/magma/CHANGELOG.md b/magma/CHANGELOG.md index 5c0adf1b..c5242d8d 100644 --- a/magma/CHANGELOG.md +++ b/magma/CHANGELOG.md @@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Changed +- Bump `cipher` to v0.5.0-pre.1; MSRV 1.65 ([#394]) +- Bump `cipher` dependency to v0.5.0-pre.2 ([#398]) +- Use `BlockCipherEncrypt`/`BlockCipherDecrypt` trait names ([#400]) +- bump `cipher` dependency to `0.5.0-pre.4` ([#413]) + +[#394]: https://github.com/RustCrypto/block-ciphers/pull/394 +[#398]: https://github.com/RustCrypto/block-ciphers/pull/398 +[#400]: https://github.com/RustCrypto/block-ciphers/pull/400 +[#413]: https://github.com/RustCrypto/block-ciphers/pull/413 + +## 0.9.0 (2023-08-06) +### Breaking changes +- API of the `Sbox` trait is changed, S-Box expansion is now performed +internally, helper methods are removed. Most users of the crate should not be +affected by this change. ([#376]) + +[#376]: https://github.com/RustCrypto/block-ciphers/pull/376 + ## 0.8.1 (2022-02-17) ### Fixed - Minimal versions build ([#303]) diff --git a/magma/Cargo.toml b/magma/Cargo.toml index b5b851b6..b63d4e0e 100644 --- a/magma/Cargo.toml +++ b/magma/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "magma" -version = "0.8.1" +version = "0.10.0-pre.1" description = "Magma (GOST R 34.12-2015) block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/magma" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,11 +13,11 @@ keywords = ["crypto", "magma", "gost", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } -hex-literal = "0.3.3" +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" [features] zeroize = ["cipher/zeroize"] diff --git a/magma/README.md b/magma/README.md index f6d07632..2b358cf1 100644 --- a/magma/README.md +++ b/magma/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/magma/badge.svg [docs-link]: https://docs.rs/magma/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/magma/src/lib.rs b/magma/src/lib.rs index 8b95acc9..e0bccc1a 100644 --- a/magma/src/lib.rs +++ b/magma/src/lib.rs @@ -13,8 +13,8 @@ //! ``` //! use magma::Magma; //! use magma::cipher::{ -//! generic_array::GenericArray, -//! BlockEncrypt, BlockDecrypt, KeyInit, +//! array::Array, +//! BlockCipherEncrypt, BlockCipherDecrypt, KeyInit, //! }; //! use hex_literal::hex; //! @@ -28,7 +28,7 @@ //! //! let cipher = Magma::new(&key.into()); //! -//! let mut block = GenericArray::clone_from_slice(&plaintext); +//! let mut block = Array::clone_from_slice(&plaintext); //! cipher.encrypt_block(&mut block); //! assert_eq!(&ciphertext, block.as_slice()); //! @@ -62,8 +62,9 @@ mod sboxes; pub use sboxes::Sbox; +use sboxes::SboxExt; + /// Block cipher defined in GOST 28147-89 generic over S-box -#[derive(Clone)] pub struct Gost89 { key: [u32; 8], _p: PhantomData, @@ -88,19 +89,36 @@ impl KeyInit for Gost89 { } } +impl Clone for Gost89 { + fn clone(&self) -> Self { + Self { + key: self.key, + _p: PhantomData, + } + } +} + impl fmt::Debug for Gost89 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("Gost89<")?; - f.write_str(S::NAME)?; - f.write_str("> { ... }") + if S::NAME == "Tc26" { + f.write_str("Magma { ... }") + } else { + f.write_str("Gost89<")?; + f.write_str(S::NAME)?; + f.write_str("> { ... }") + } } } impl AlgorithmName for Gost89 { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("Gost89<")?; - f.write_str(S::NAME)?; - f.write_str("> { ... }") + if S::NAME == "Tc26" { + f.write_str("Magma { ... }") + } else { + f.write_str("Gost89<")?; + f.write_str(S::NAME)?; + f.write_str("> { ... }") + } } } diff --git a/magma/src/sboxes.rs b/magma/src/sboxes.rs index 380e2483..a5e7ed07 100644 --- a/magma/src/sboxes.rs +++ b/magma/src/sboxes.rs @@ -3,34 +3,41 @@ type ExpSbox = [[u8; 256]; 4]; type SmallSbox = [[u8; 16]; 8]; -/// Trait implemented for the GOST 28147-89 cipher S-boxes. -pub trait Sbox { - /// Expanded S-box - const EXP_SBOX: ExpSbox; - - /// Unexpanded S-box - const SBOX: SmallSbox; +const fn gen_exp_sbox(sbox: &SmallSbox) -> ExpSbox { + let mut out = [[0u8; 256]; 4]; + let mut i = 0; + while i < 4 { + let mut j = 0; + while j < 16 { + let mut k = 0; + while k < 16 { + let v: u8 = sbox[2 * i][j] + (sbox[2 * i + 1][k] << 4); + let c: usize = j + (k << 4); + out[i][c] = v; + k += 1; + } + j += 1; + } + i += 1; + } + out +} +/// Trait for GOST 28147-89 cipher S-boxes +pub trait Sbox { /// S-Box name const NAME: &'static str; + /// Unexpanded S-box + const SBOX: SmallSbox; +} - /// Generate expanded version of S-box. - #[allow(clippy::needless_range_loop)] - fn gen_exp_sbox() -> ExpSbox { - let mut out = [[0u8; 256]; 4]; - for i in 0..4 { - for j in 0..16 { - for k in 0..16 { - let v: u8 = Self::SBOX[2 * i][j] + (Self::SBOX[2 * i + 1][k] << 4); - let c: usize = j + (k << 4); - out[i][c] = v; - } - } - } - out - } +/// Extension of the `Sbox` trait which provides expanded S-Box +/// and helper methods +pub(crate) trait SboxExt: Sbox { + /// Expanded S-box + const EXP_SBOX: ExpSbox = gen_exp_sbox(&Self::SBOX); - /// Apply S-box and return result. + /// Apply S-box and return result fn apply_sbox(a: u32) -> u32 { let mut v = 0; for i in 0..4 { @@ -41,84 +48,18 @@ pub trait Sbox { v } - /// Function `g` based on the S-box. + /// Function `g` based on the S-box fn g(a: u32, k: u32) -> u32 { Self::apply_sbox(a.wrapping_add(k)).rotate_left(11) } } -#[derive(Clone)] +impl SboxExt for T {} + pub enum Tc26 {} impl Sbox for Tc26 { const NAME: &'static str = "Tc26"; - const EXP_SBOX: ExpSbox = [ - [ - 108, 100, 102, 98, 106, 101, 107, 105, 110, 104, 109, 103, 96, 99, 111, 97, 140, 132, - 134, 130, 138, 133, 139, 137, 142, 136, 141, 135, 128, 131, 143, 129, 44, 36, 38, 34, - 42, 37, 43, 41, 46, 40, 45, 39, 32, 35, 47, 33, 60, 52, 54, 50, 58, 53, 59, 57, 62, 56, - 61, 55, 48, 51, 63, 49, 156, 148, 150, 146, 154, 149, 155, 153, 158, 152, 157, 151, - 144, 147, 159, 145, 172, 164, 166, 162, 170, 165, 171, 169, 174, 168, 173, 167, 160, - 163, 175, 161, 92, 84, 86, 82, 90, 85, 91, 89, 94, 88, 93, 87, 80, 83, 95, 81, 204, - 196, 198, 194, 202, 197, 203, 201, 206, 200, 205, 199, 192, 195, 207, 193, 28, 20, 22, - 18, 26, 21, 27, 25, 30, 24, 29, 23, 16, 19, 31, 17, 236, 228, 230, 226, 234, 229, 235, - 233, 238, 232, 237, 231, 224, 227, 239, 225, 76, 68, 70, 66, 74, 69, 75, 73, 78, 72, - 77, 71, 64, 67, 79, 65, 124, 116, 118, 114, 122, 117, 123, 121, 126, 120, 125, 119, - 112, 115, 127, 113, 188, 180, 182, 178, 186, 181, 187, 185, 190, 184, 189, 183, 176, - 179, 191, 177, 220, 212, 214, 210, 218, 213, 219, 217, 222, 216, 221, 215, 208, 211, - 223, 209, 12, 4, 6, 2, 10, 5, 11, 9, 14, 8, 13, 7, 0, 3, 15, 1, 252, 244, 246, 242, - 250, 245, 251, 249, 254, 248, 253, 247, 240, 243, 255, 241, - ], - [ - 203, 195, 197, 200, 194, 207, 202, 205, 206, 193, 199, 196, 204, 201, 198, 192, 139, - 131, 133, 136, 130, 143, 138, 141, 142, 129, 135, 132, 140, 137, 134, 128, 43, 35, 37, - 40, 34, 47, 42, 45, 46, 33, 39, 36, 44, 41, 38, 32, 27, 19, 21, 24, 18, 31, 26, 29, 30, - 17, 23, 20, 28, 25, 22, 16, 219, 211, 213, 216, 210, 223, 218, 221, 222, 209, 215, 212, - 220, 217, 214, 208, 75, 67, 69, 72, 66, 79, 74, 77, 78, 65, 71, 68, 76, 73, 70, 64, - 251, 243, 245, 248, 242, 255, 250, 253, 254, 241, 247, 244, 252, 249, 246, 240, 107, - 99, 101, 104, 98, 111, 106, 109, 110, 97, 103, 100, 108, 105, 102, 96, 123, 115, 117, - 120, 114, 127, 122, 125, 126, 113, 119, 116, 124, 121, 118, 112, 11, 3, 5, 8, 2, 15, - 10, 13, 14, 1, 7, 4, 12, 9, 6, 0, 171, 163, 165, 168, 162, 175, 170, 173, 174, 161, - 167, 164, 172, 169, 166, 160, 91, 83, 85, 88, 82, 95, 90, 93, 94, 81, 87, 84, 92, 89, - 86, 80, 59, 51, 53, 56, 50, 63, 58, 61, 62, 49, 55, 52, 60, 57, 54, 48, 235, 227, 229, - 232, 226, 239, 234, 237, 238, 225, 231, 228, 236, 233, 230, 224, 155, 147, 149, 152, - 146, 159, 154, 157, 158, 145, 151, 148, 156, 153, 150, 144, 187, 179, 181, 184, 178, - 191, 186, 189, 190, 177, 183, 180, 188, 185, 182, 176, - ], - [ - 87, 95, 85, 90, 88, 81, 86, 93, 80, 89, 83, 94, 91, 84, 82, 92, 215, 223, 213, 218, - 216, 209, 214, 221, 208, 217, 211, 222, 219, 212, 210, 220, 247, 255, 245, 250, 248, - 241, 246, 253, 240, 249, 243, 254, 251, 244, 242, 252, 103, 111, 101, 106, 104, 97, - 102, 109, 96, 105, 99, 110, 107, 100, 98, 108, 151, 159, 149, 154, 152, 145, 150, 157, - 144, 153, 147, 158, 155, 148, 146, 156, 39, 47, 37, 42, 40, 33, 38, 45, 32, 41, 35, 46, - 43, 36, 34, 44, 199, 207, 197, 202, 200, 193, 198, 205, 192, 201, 195, 206, 203, 196, - 194, 204, 167, 175, 165, 170, 168, 161, 166, 173, 160, 169, 163, 174, 171, 164, 162, - 172, 183, 191, 181, 186, 184, 177, 182, 189, 176, 185, 179, 190, 187, 180, 178, 188, - 119, 127, 117, 122, 120, 113, 118, 125, 112, 121, 115, 126, 123, 116, 114, 124, 135, - 143, 133, 138, 136, 129, 134, 141, 128, 137, 131, 142, 139, 132, 130, 140, 23, 31, 21, - 26, 24, 17, 22, 29, 16, 25, 19, 30, 27, 20, 18, 28, 71, 79, 69, 74, 72, 65, 70, 77, 64, - 73, 67, 78, 75, 68, 66, 76, 55, 63, 53, 58, 56, 49, 54, 61, 48, 57, 51, 62, 59, 52, 50, - 60, 231, 239, 229, 234, 232, 225, 230, 237, 224, 233, 227, 238, 235, 228, 226, 236, 7, - 15, 5, 10, 8, 1, 6, 13, 0, 9, 3, 14, 11, 4, 2, 12, - ], - [ - 24, 30, 18, 21, 22, 25, 17, 28, 31, 20, 27, 16, 29, 26, 19, 23, 120, 126, 114, 117, - 118, 121, 113, 124, 127, 116, 123, 112, 125, 122, 115, 119, 232, 238, 226, 229, 230, - 233, 225, 236, 239, 228, 235, 224, 237, 234, 227, 231, 216, 222, 210, 213, 214, 217, - 209, 220, 223, 212, 219, 208, 221, 218, 211, 215, 8, 14, 2, 5, 6, 9, 1, 12, 15, 4, 11, - 0, 13, 10, 3, 7, 88, 94, 82, 85, 86, 89, 81, 92, 95, 84, 91, 80, 93, 90, 83, 87, 136, - 142, 130, 133, 134, 137, 129, 140, 143, 132, 139, 128, 141, 138, 131, 135, 56, 62, 50, - 53, 54, 57, 49, 60, 63, 52, 59, 48, 61, 58, 51, 55, 72, 78, 66, 69, 70, 73, 65, 76, 79, - 68, 75, 64, 77, 74, 67, 71, 248, 254, 242, 245, 246, 249, 241, 252, 255, 244, 251, 240, - 253, 250, 243, 247, 168, 174, 162, 165, 166, 169, 161, 172, 175, 164, 171, 160, 173, - 170, 163, 167, 104, 110, 98, 101, 102, 105, 97, 108, 111, 100, 107, 96, 109, 106, 99, - 103, 152, 158, 146, 149, 150, 153, 145, 156, 159, 148, 155, 144, 157, 154, 147, 151, - 200, 206, 194, 197, 198, 201, 193, 204, 207, 196, 203, 192, 205, 202, 195, 199, 184, - 190, 178, 181, 182, 185, 177, 188, 191, 180, 187, 176, 189, 186, 179, 183, 40, 46, 34, - 37, 38, 41, 33, 44, 47, 36, 43, 32, 45, 42, 35, 39, - ], - ]; - const SBOX: SmallSbox = [ [12, 4, 6, 2, 10, 5, 11, 9, 14, 8, 13, 7, 0, 3, 15, 1], [6, 8, 2, 3, 9, 10, 5, 12, 1, 14, 4, 7, 11, 13, 0, 15], @@ -131,78 +72,10 @@ impl Sbox for Tc26 { ]; } -#[derive(Clone)] pub enum TestSbox {} impl Sbox for TestSbox { const NAME: &'static str = "TestSbox"; - const EXP_SBOX: ExpSbox = [ - [ - 228, 234, 233, 226, 237, 232, 224, 238, 230, 235, 225, 236, 231, 239, 229, 227, 180, - 186, 185, 178, 189, 184, 176, 190, 182, 187, 177, 188, 183, 191, 181, 179, 68, 74, 73, - 66, 77, 72, 64, 78, 70, 75, 65, 76, 71, 79, 69, 67, 196, 202, 201, 194, 205, 200, 192, - 206, 198, 203, 193, 204, 199, 207, 197, 195, 100, 106, 105, 98, 109, 104, 96, 110, 102, - 107, 97, 108, 103, 111, 101, 99, 212, 218, 217, 210, 221, 216, 208, 222, 214, 219, 209, - 220, 215, 223, 213, 211, 244, 250, 249, 242, 253, 248, 240, 254, 246, 251, 241, 252, - 247, 255, 245, 243, 164, 170, 169, 162, 173, 168, 160, 174, 166, 171, 161, 172, 167, - 175, 165, 163, 36, 42, 41, 34, 45, 40, 32, 46, 38, 43, 33, 44, 39, 47, 37, 35, 52, 58, - 57, 50, 61, 56, 48, 62, 54, 59, 49, 60, 55, 63, 53, 51, 132, 138, 137, 130, 141, 136, - 128, 142, 134, 139, 129, 140, 135, 143, 133, 131, 20, 26, 25, 18, 29, 24, 16, 30, 22, - 27, 17, 28, 23, 31, 21, 19, 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3, 116, - 122, 121, 114, 125, 120, 112, 126, 118, 123, 113, 124, 119, 127, 117, 115, 84, 90, 89, - 82, 93, 88, 80, 94, 86, 91, 81, 92, 87, 95, 85, 83, 148, 154, 153, 146, 157, 152, 144, - 158, 150, 155, 145, 156, 151, 159, 149, 147, - ], - [ - 117, 120, 113, 125, 122, 115, 116, 114, 126, 127, 124, 119, 118, 112, 121, 123, 213, - 216, 209, 221, 218, 211, 212, 210, 222, 223, 220, 215, 214, 208, 217, 219, 165, 168, - 161, 173, 170, 163, 164, 162, 174, 175, 172, 167, 166, 160, 169, 171, 21, 24, 17, 29, - 26, 19, 20, 18, 30, 31, 28, 23, 22, 16, 25, 27, 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, - 7, 6, 0, 9, 11, 133, 136, 129, 141, 138, 131, 132, 130, 142, 143, 140, 135, 134, 128, - 137, 139, 149, 152, 145, 157, 154, 147, 148, 146, 158, 159, 156, 151, 150, 144, 153, - 155, 245, 248, 241, 253, 250, 243, 244, 242, 254, 255, 252, 247, 246, 240, 249, 251, - 229, 232, 225, 237, 234, 227, 228, 226, 238, 239, 236, 231, 230, 224, 233, 235, 69, 72, - 65, 77, 74, 67, 68, 66, 78, 79, 76, 71, 70, 64, 73, 75, 101, 104, 97, 109, 106, 99, - 100, 98, 110, 111, 108, 103, 102, 96, 105, 107, 197, 200, 193, 205, 202, 195, 196, 194, - 206, 207, 204, 199, 198, 192, 201, 203, 181, 184, 177, 189, 186, 179, 180, 178, 190, - 191, 188, 183, 182, 176, 185, 187, 37, 40, 33, 45, 42, 35, 36, 34, 46, 47, 44, 39, 38, - 32, 41, 43, 85, 88, 81, 93, 90, 83, 84, 82, 94, 95, 92, 87, 86, 80, 89, 91, 53, 56, 49, - 61, 58, 51, 52, 50, 62, 63, 60, 55, 54, 48, 57, 59, - ], - [ - 70, 76, 71, 65, 69, 79, 77, 72, 68, 74, 73, 78, 64, 67, 75, 66, 182, 188, 183, 177, - 181, 191, 189, 184, 180, 186, 185, 190, 176, 179, 187, 178, 166, 172, 167, 161, 165, - 175, 173, 168, 164, 170, 169, 174, 160, 163, 171, 162, 6, 12, 7, 1, 5, 15, 13, 8, 4, - 10, 9, 14, 0, 3, 11, 2, 118, 124, 119, 113, 117, 127, 125, 120, 116, 122, 121, 126, - 112, 115, 123, 114, 38, 44, 39, 33, 37, 47, 45, 40, 36, 42, 41, 46, 32, 35, 43, 34, 22, - 28, 23, 17, 21, 31, 29, 24, 20, 26, 25, 30, 16, 19, 27, 18, 214, 220, 215, 209, 213, - 223, 221, 216, 212, 218, 217, 222, 208, 211, 219, 210, 54, 60, 55, 49, 53, 63, 61, 56, - 52, 58, 57, 62, 48, 51, 59, 50, 102, 108, 103, 97, 101, 111, 109, 104, 100, 106, 105, - 110, 96, 99, 107, 98, 134, 140, 135, 129, 133, 143, 141, 136, 132, 138, 137, 142, 128, - 131, 139, 130, 86, 92, 87, 81, 85, 95, 93, 88, 84, 90, 89, 94, 80, 83, 91, 82, 150, - 156, 151, 145, 149, 159, 157, 152, 148, 154, 153, 158, 144, 147, 155, 146, 198, 204, - 199, 193, 197, 207, 205, 200, 196, 202, 201, 206, 192, 195, 203, 194, 246, 252, 247, - 241, 245, 255, 253, 248, 244, 250, 249, 254, 240, 243, 251, 242, 230, 236, 231, 225, - 229, 239, 237, 232, 228, 234, 233, 238, 224, 227, 235, 226, - ], - [ - 29, 27, 20, 17, 19, 31, 21, 25, 16, 26, 30, 23, 22, 24, 18, 28, 253, 251, 244, 241, - 243, 255, 245, 249, 240, 250, 254, 247, 246, 248, 242, 252, 221, 219, 212, 209, 211, - 223, 213, 217, 208, 218, 222, 215, 214, 216, 210, 220, 13, 11, 4, 1, 3, 15, 5, 9, 0, - 10, 14, 7, 6, 8, 2, 12, 93, 91, 84, 81, 83, 95, 85, 89, 80, 90, 94, 87, 86, 88, 82, 92, - 125, 123, 116, 113, 115, 127, 117, 121, 112, 122, 126, 119, 118, 120, 114, 124, 173, - 171, 164, 161, 163, 175, 165, 169, 160, 170, 174, 167, 166, 168, 162, 172, 77, 75, 68, - 65, 67, 79, 69, 73, 64, 74, 78, 71, 70, 72, 66, 76, 157, 155, 148, 145, 147, 159, 149, - 153, 144, 154, 158, 151, 150, 152, 146, 156, 45, 43, 36, 33, 35, 47, 37, 41, 32, 42, - 46, 39, 38, 40, 34, 44, 61, 59, 52, 49, 51, 63, 53, 57, 48, 58, 62, 55, 54, 56, 50, 60, - 237, 235, 228, 225, 227, 239, 229, 233, 224, 234, 238, 231, 230, 232, 226, 236, 109, - 107, 100, 97, 99, 111, 101, 105, 96, 106, 110, 103, 102, 104, 98, 108, 189, 187, 180, - 177, 179, 191, 181, 185, 176, 186, 190, 183, 182, 184, 178, 188, 141, 139, 132, 129, - 131, 143, 133, 137, 128, 138, 142, 135, 134, 136, 130, 140, 205, 203, 196, 193, 195, - 207, 197, 201, 192, 202, 206, 199, 198, 200, 194, 204, - ], - ]; - const SBOX: SmallSbox = [ [4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3], [14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9], @@ -215,78 +88,10 @@ impl Sbox for TestSbox { ]; } -#[derive(Clone)] pub enum CryptoProA {} impl Sbox for CryptoProA { const NAME: &'static str = "CryptoProA"; - const EXP_SBOX: ExpSbox = [ - [ - 57, 54, 51, 50, 56, 59, 49, 55, 58, 52, 62, 63, 60, 48, 61, 53, 121, 118, 115, 114, - 120, 123, 113, 119, 122, 116, 126, 127, 124, 112, 125, 117, 233, 230, 227, 226, 232, - 235, 225, 231, 234, 228, 238, 239, 236, 224, 237, 229, 153, 150, 147, 146, 152, 155, - 145, 151, 154, 148, 158, 159, 156, 144, 157, 149, 137, 134, 131, 130, 136, 139, 129, - 135, 138, 132, 142, 143, 140, 128, 141, 133, 169, 166, 163, 162, 168, 171, 161, 167, - 170, 164, 174, 175, 172, 160, 173, 165, 249, 246, 243, 242, 248, 251, 241, 247, 250, - 244, 254, 255, 252, 240, 253, 245, 9, 6, 3, 2, 8, 11, 1, 7, 10, 4, 14, 15, 12, 0, 13, - 5, 89, 86, 83, 82, 88, 91, 81, 87, 90, 84, 94, 95, 92, 80, 93, 85, 41, 38, 35, 34, 40, - 43, 33, 39, 42, 36, 46, 47, 44, 32, 45, 37, 105, 102, 99, 98, 104, 107, 97, 103, 106, - 100, 110, 111, 108, 96, 109, 101, 201, 198, 195, 194, 200, 203, 193, 199, 202, 196, - 206, 207, 204, 192, 205, 197, 185, 182, 179, 178, 184, 187, 177, 183, 186, 180, 190, - 191, 188, 176, 189, 181, 73, 70, 67, 66, 72, 75, 65, 71, 74, 68, 78, 79, 76, 64, 77, - 69, 217, 214, 211, 210, 216, 219, 209, 215, 218, 212, 222, 223, 220, 208, 221, 213, 25, - 22, 19, 18, 24, 27, 17, 23, 26, 20, 30, 31, 28, 16, 29, 21, - ], - [ - 238, 228, 230, 226, 235, 227, 237, 232, 236, 239, 229, 234, 224, 231, 225, 233, 126, - 116, 118, 114, 123, 115, 125, 120, 124, 127, 117, 122, 112, 119, 113, 121, 174, 164, - 166, 162, 171, 163, 173, 168, 172, 175, 165, 170, 160, 167, 161, 169, 206, 196, 198, - 194, 203, 195, 205, 200, 204, 207, 197, 202, 192, 199, 193, 201, 222, 212, 214, 210, - 219, 211, 221, 216, 220, 223, 213, 218, 208, 215, 209, 217, 30, 20, 22, 18, 27, 19, 29, - 24, 28, 31, 21, 26, 16, 23, 17, 25, 62, 52, 54, 50, 59, 51, 61, 56, 60, 63, 53, 58, 48, - 55, 49, 57, 158, 148, 150, 146, 155, 147, 157, 152, 156, 159, 149, 154, 144, 151, 145, - 153, 14, 4, 6, 2, 11, 3, 13, 8, 12, 15, 5, 10, 0, 7, 1, 9, 46, 36, 38, 34, 43, 35, 45, - 40, 44, 47, 37, 42, 32, 39, 33, 41, 190, 180, 182, 178, 187, 179, 189, 184, 188, 191, - 181, 186, 176, 183, 177, 185, 78, 68, 70, 66, 75, 67, 77, 72, 76, 79, 69, 74, 64, 71, - 65, 73, 254, 244, 246, 242, 251, 243, 253, 248, 252, 255, 245, 250, 240, 247, 241, 249, - 142, 132, 134, 130, 139, 131, 141, 136, 140, 143, 133, 138, 128, 135, 129, 137, 94, 84, - 86, 82, 91, 83, 93, 88, 92, 95, 85, 90, 80, 87, 81, 89, 110, 100, 102, 98, 107, 99, - 109, 104, 108, 111, 101, 106, 96, 103, 97, 105, - ], - [ - 59, 53, 49, 57, 56, 61, 63, 48, 62, 52, 50, 51, 60, 55, 58, 54, 171, 165, 161, 169, - 168, 173, 175, 160, 174, 164, 162, 163, 172, 167, 170, 166, 219, 213, 209, 217, 216, - 221, 223, 208, 222, 212, 210, 211, 220, 215, 218, 214, 203, 197, 193, 201, 200, 205, - 207, 192, 206, 196, 194, 195, 204, 199, 202, 198, 27, 21, 17, 25, 24, 29, 31, 16, 30, - 20, 18, 19, 28, 23, 26, 22, 43, 37, 33, 41, 40, 45, 47, 32, 46, 36, 34, 35, 44, 39, 42, - 38, 11, 5, 1, 9, 8, 13, 15, 0, 14, 4, 2, 3, 12, 7, 10, 6, 187, 181, 177, 185, 184, 189, - 191, 176, 190, 180, 178, 179, 188, 183, 186, 182, 123, 117, 113, 121, 120, 125, 127, - 112, 126, 116, 114, 115, 124, 119, 122, 118, 91, 85, 81, 89, 88, 93, 95, 80, 94, 84, - 82, 83, 92, 87, 90, 86, 155, 149, 145, 153, 152, 157, 159, 144, 158, 148, 146, 147, - 156, 151, 154, 150, 75, 69, 65, 73, 72, 77, 79, 64, 78, 68, 66, 67, 76, 71, 74, 70, - 139, 133, 129, 137, 136, 141, 143, 128, 142, 132, 130, 131, 140, 135, 138, 134, 251, - 245, 241, 249, 248, 253, 255, 240, 254, 244, 242, 243, 252, 247, 250, 246, 235, 229, - 225, 233, 232, 237, 239, 224, 238, 228, 226, 227, 236, 231, 234, 230, 107, 101, 97, - 105, 104, 109, 111, 96, 110, 100, 98, 99, 108, 103, 106, 102, - ], - [ - 177, 189, 178, 185, 183, 186, 182, 176, 184, 188, 180, 181, 191, 179, 187, 190, 161, - 173, 162, 169, 167, 170, 166, 160, 168, 172, 164, 165, 175, 163, 171, 174, 241, 253, - 242, 249, 247, 250, 246, 240, 248, 252, 244, 245, 255, 243, 251, 254, 81, 93, 82, 89, - 87, 90, 86, 80, 88, 92, 84, 85, 95, 83, 91, 94, 1, 13, 2, 9, 7, 10, 6, 0, 8, 12, 4, 5, - 15, 3, 11, 14, 193, 205, 194, 201, 199, 202, 198, 192, 200, 204, 196, 197, 207, 195, - 203, 206, 225, 237, 226, 233, 231, 234, 230, 224, 232, 236, 228, 229, 239, 227, 235, - 238, 129, 141, 130, 137, 135, 138, 134, 128, 136, 140, 132, 133, 143, 131, 139, 142, - 97, 109, 98, 105, 103, 106, 102, 96, 104, 108, 100, 101, 111, 99, 107, 110, 33, 45, 34, - 41, 39, 42, 38, 32, 40, 44, 36, 37, 47, 35, 43, 46, 49, 61, 50, 57, 55, 58, 54, 48, 56, - 60, 52, 53, 63, 51, 59, 62, 145, 157, 146, 153, 151, 154, 150, 144, 152, 156, 148, 149, - 159, 147, 155, 158, 17, 29, 18, 25, 23, 26, 22, 16, 24, 28, 20, 21, 31, 19, 27, 30, - 113, 125, 114, 121, 119, 122, 118, 112, 120, 124, 116, 117, 127, 115, 123, 126, 209, - 221, 210, 217, 215, 218, 214, 208, 216, 220, 212, 213, 223, 211, 219, 222, 65, 77, 66, - 73, 71, 74, 70, 64, 72, 76, 68, 69, 79, 67, 75, 78, - ], - ]; - const SBOX: SmallSbox = [ [9, 6, 3, 2, 8, 11, 1, 7, 10, 4, 14, 15, 12, 0, 13, 5], [3, 7, 14, 9, 8, 10, 15, 0, 5, 2, 6, 12, 11, 4, 13, 1], @@ -299,78 +104,10 @@ impl Sbox for CryptoProA { ]; } -#[derive(Clone)] pub enum CryptoProB {} impl Sbox for CryptoProB { const NAME: &'static str = "CryptoProB"; - const EXP_SBOX: ExpSbox = [ - [ - 8, 4, 11, 1, 3, 5, 0, 9, 2, 14, 10, 12, 13, 6, 7, 15, 24, 20, 27, 17, 19, 21, 16, 25, - 18, 30, 26, 28, 29, 22, 23, 31, 40, 36, 43, 33, 35, 37, 32, 41, 34, 46, 42, 44, 45, 38, - 39, 47, 168, 164, 171, 161, 163, 165, 160, 169, 162, 174, 170, 172, 173, 166, 167, 175, - 72, 68, 75, 65, 67, 69, 64, 73, 66, 78, 74, 76, 77, 70, 71, 79, 216, 212, 219, 209, - 211, 213, 208, 217, 210, 222, 218, 220, 221, 214, 215, 223, 88, 84, 91, 81, 83, 85, 80, - 89, 82, 94, 90, 92, 93, 86, 87, 95, 200, 196, 203, 193, 195, 197, 192, 201, 194, 206, - 202, 204, 205, 198, 199, 207, 152, 148, 155, 145, 147, 149, 144, 153, 146, 158, 154, - 156, 157, 150, 151, 159, 120, 116, 123, 113, 115, 117, 112, 121, 114, 126, 122, 124, - 125, 118, 119, 127, 56, 52, 59, 49, 51, 53, 48, 57, 50, 62, 58, 60, 61, 54, 55, 63, - 248, 244, 251, 241, 243, 245, 240, 249, 242, 254, 250, 252, 253, 246, 247, 255, 184, - 180, 187, 177, 179, 181, 176, 185, 178, 190, 186, 188, 189, 182, 183, 191, 136, 132, - 139, 129, 131, 133, 128, 137, 130, 142, 138, 140, 141, 134, 135, 143, 104, 100, 107, - 97, 99, 101, 96, 105, 98, 110, 106, 108, 109, 102, 103, 111, 232, 228, 235, 225, 227, - 229, 224, 233, 226, 238, 234, 236, 237, 230, 231, 239, - ], - [ - 126, 124, 112, 122, 121, 114, 125, 123, 119, 117, 120, 127, 115, 118, 113, 116, 94, 92, - 80, 90, 89, 82, 93, 91, 87, 85, 88, 95, 83, 86, 81, 84, 14, 12, 0, 10, 9, 2, 13, 11, 7, - 5, 8, 15, 3, 6, 1, 4, 222, 220, 208, 218, 217, 210, 221, 219, 215, 213, 216, 223, 211, - 214, 209, 212, 190, 188, 176, 186, 185, 178, 189, 187, 183, 181, 184, 191, 179, 182, - 177, 180, 110, 108, 96, 106, 105, 98, 109, 107, 103, 101, 104, 111, 99, 102, 97, 100, - 30, 28, 16, 26, 25, 18, 29, 27, 23, 21, 24, 31, 19, 22, 17, 20, 46, 44, 32, 42, 41, 34, - 45, 43, 39, 37, 40, 47, 35, 38, 33, 36, 62, 60, 48, 58, 57, 50, 61, 59, 55, 53, 56, 63, - 51, 54, 49, 52, 174, 172, 160, 170, 169, 162, 173, 171, 167, 165, 168, 175, 163, 166, - 161, 164, 206, 204, 192, 202, 201, 194, 205, 203, 199, 197, 200, 207, 195, 198, 193, - 196, 254, 252, 240, 250, 249, 242, 253, 251, 247, 245, 248, 255, 243, 246, 241, 244, - 78, 76, 64, 74, 73, 66, 77, 75, 71, 69, 72, 79, 67, 70, 65, 68, 238, 236, 224, 234, - 233, 226, 237, 235, 231, 229, 232, 239, 227, 230, 225, 228, 158, 156, 144, 154, 153, - 146, 157, 155, 151, 149, 152, 159, 147, 150, 145, 148, 142, 140, 128, 138, 137, 130, - 141, 139, 135, 133, 136, 143, 131, 134, 129, 132, - ], - [ - 130, 135, 140, 143, 137, 133, 138, 139, 129, 132, 128, 141, 134, 136, 142, 131, 50, 55, - 60, 63, 57, 53, 58, 59, 49, 52, 48, 61, 54, 56, 62, 51, 34, 39, 44, 47, 41, 37, 42, 43, - 33, 36, 32, 45, 38, 40, 46, 35, 98, 103, 108, 111, 105, 101, 106, 107, 97, 100, 96, - 109, 102, 104, 110, 99, 66, 71, 76, 79, 73, 69, 74, 75, 65, 68, 64, 77, 70, 72, 78, 67, - 210, 215, 220, 223, 217, 213, 218, 219, 209, 212, 208, 221, 214, 216, 222, 211, 226, - 231, 236, 239, 233, 229, 234, 235, 225, 228, 224, 237, 230, 232, 238, 227, 178, 183, - 188, 191, 185, 181, 186, 187, 177, 180, 176, 189, 182, 184, 190, 179, 194, 199, 204, - 207, 201, 197, 202, 203, 193, 196, 192, 205, 198, 200, 206, 195, 18, 23, 28, 31, 25, - 21, 26, 27, 17, 20, 16, 29, 22, 24, 30, 19, 114, 119, 124, 127, 121, 117, 122, 123, - 113, 116, 112, 125, 118, 120, 126, 115, 242, 247, 252, 255, 249, 245, 250, 251, 241, - 244, 240, 253, 246, 248, 254, 243, 162, 167, 172, 175, 169, 165, 170, 171, 161, 164, - 160, 173, 166, 168, 174, 163, 2, 7, 12, 15, 9, 5, 10, 11, 1, 4, 0, 13, 6, 8, 14, 3, - 146, 151, 156, 159, 153, 149, 154, 155, 145, 148, 144, 157, 150, 152, 158, 147, 82, 87, - 92, 95, 89, 85, 90, 91, 81, 84, 80, 93, 86, 88, 94, 83, - ], - [ - 5, 2, 10, 11, 9, 1, 12, 3, 7, 4, 13, 0, 6, 15, 8, 14, 69, 66, 74, 75, 73, 65, 76, 67, - 71, 68, 77, 64, 70, 79, 72, 78, 181, 178, 186, 187, 185, 177, 188, 179, 183, 180, 189, - 176, 182, 191, 184, 190, 229, 226, 234, 235, 233, 225, 236, 227, 231, 228, 237, 224, - 230, 239, 232, 238, 133, 130, 138, 139, 137, 129, 140, 131, 135, 132, 141, 128, 134, - 143, 136, 142, 53, 50, 58, 59, 57, 49, 60, 51, 55, 52, 61, 48, 54, 63, 56, 62, 117, - 114, 122, 123, 121, 113, 124, 115, 119, 116, 125, 112, 118, 127, 120, 126, 21, 18, 26, - 27, 25, 17, 28, 19, 23, 20, 29, 16, 22, 31, 24, 30, 165, 162, 170, 171, 169, 161, 172, - 163, 167, 164, 173, 160, 166, 175, 168, 174, 37, 34, 42, 43, 41, 33, 44, 35, 39, 36, - 45, 32, 38, 47, 40, 46, 149, 146, 154, 155, 153, 145, 156, 147, 151, 148, 157, 144, - 150, 159, 152, 158, 101, 98, 106, 107, 105, 97, 108, 99, 103, 100, 109, 96, 102, 111, - 104, 110, 245, 242, 250, 251, 249, 241, 252, 243, 247, 244, 253, 240, 246, 255, 248, - 254, 213, 210, 218, 219, 217, 209, 220, 211, 215, 212, 221, 208, 214, 223, 216, 222, - 85, 82, 90, 91, 89, 81, 92, 83, 87, 84, 93, 80, 86, 95, 88, 94, 197, 194, 202, 203, - 201, 193, 204, 195, 199, 196, 205, 192, 198, 207, 200, 206, - ], - ]; - const SBOX: SmallSbox = [ [8, 4, 11, 1, 3, 5, 0, 9, 2, 14, 10, 12, 13, 6, 7, 15], [0, 1, 2, 10, 4, 13, 5, 12, 9, 7, 3, 15, 11, 8, 6, 14], @@ -383,78 +120,10 @@ impl Sbox for CryptoProB { ]; } -#[derive(Clone)] pub enum CryptoProC {} impl Sbox for CryptoProC { const NAME: &'static str = "CryptoProC"; - const EXP_SBOX: ExpSbox = [ - [ - 1, 11, 12, 2, 9, 13, 0, 15, 4, 5, 8, 14, 10, 7, 6, 3, 17, 27, 28, 18, 25, 29, 16, 31, - 20, 21, 24, 30, 26, 23, 22, 19, 113, 123, 124, 114, 121, 125, 112, 127, 116, 117, 120, - 126, 122, 119, 118, 115, 209, 219, 220, 210, 217, 221, 208, 223, 212, 213, 216, 222, - 218, 215, 214, 211, 177, 187, 188, 178, 185, 189, 176, 191, 180, 181, 184, 190, 186, - 183, 182, 179, 65, 75, 76, 66, 73, 77, 64, 79, 68, 69, 72, 78, 74, 71, 70, 67, 81, 91, - 92, 82, 89, 93, 80, 95, 84, 85, 88, 94, 90, 87, 86, 83, 33, 43, 44, 34, 41, 45, 32, 47, - 36, 37, 40, 46, 42, 39, 38, 35, 129, 139, 140, 130, 137, 141, 128, 143, 132, 133, 136, - 142, 138, 135, 134, 131, 225, 235, 236, 226, 233, 237, 224, 239, 228, 229, 232, 238, - 234, 231, 230, 227, 241, 251, 252, 242, 249, 253, 240, 255, 244, 245, 248, 254, 250, - 247, 246, 243, 193, 203, 204, 194, 201, 205, 192, 207, 196, 197, 200, 206, 202, 199, - 198, 195, 145, 155, 156, 146, 153, 157, 144, 159, 148, 149, 152, 158, 154, 151, 150, - 147, 161, 171, 172, 162, 169, 173, 160, 175, 164, 165, 168, 174, 170, 167, 166, 163, - 97, 107, 108, 98, 105, 109, 96, 111, 100, 101, 104, 110, 106, 103, 102, 99, 49, 59, 60, - 50, 57, 61, 48, 63, 52, 53, 56, 62, 58, 55, 54, 51, - ], - [ - 56, 50, 53, 48, 52, 57, 63, 58, 51, 55, 60, 61, 54, 62, 49, 59, 104, 98, 101, 96, 100, - 105, 111, 106, 99, 103, 108, 109, 102, 110, 97, 107, 8, 2, 5, 0, 4, 9, 15, 10, 3, 7, - 12, 13, 6, 14, 1, 11, 24, 18, 21, 16, 20, 25, 31, 26, 19, 23, 28, 29, 22, 30, 17, 27, - 88, 82, 85, 80, 84, 89, 95, 90, 83, 87, 92, 93, 86, 94, 81, 91, 216, 210, 213, 208, - 212, 217, 223, 218, 211, 215, 220, 221, 214, 222, 209, 219, 168, 162, 165, 160, 164, - 169, 175, 170, 163, 167, 172, 173, 166, 174, 161, 171, 136, 130, 133, 128, 132, 137, - 143, 138, 131, 135, 140, 141, 134, 142, 129, 139, 184, 178, 181, 176, 180, 185, 191, - 186, 179, 183, 188, 189, 182, 190, 177, 187, 40, 34, 37, 32, 36, 41, 47, 42, 35, 39, - 44, 45, 38, 46, 33, 43, 152, 146, 149, 144, 148, 153, 159, 154, 147, 151, 156, 157, - 150, 158, 145, 155, 120, 114, 117, 112, 116, 121, 127, 122, 115, 119, 124, 125, 118, - 126, 113, 123, 232, 226, 229, 224, 228, 233, 239, 234, 227, 231, 236, 237, 230, 238, - 225, 235, 248, 242, 245, 240, 244, 249, 255, 250, 243, 247, 252, 253, 246, 254, 241, - 251, 200, 194, 197, 192, 196, 201, 207, 202, 195, 199, 204, 205, 198, 206, 193, 203, - 72, 66, 69, 64, 68, 73, 79, 74, 67, 71, 76, 77, 70, 78, 65, 75, - ], - [ - 200, 205, 203, 192, 196, 197, 193, 194, 201, 195, 204, 206, 198, 207, 202, 199, 152, - 157, 155, 144, 148, 149, 145, 146, 153, 147, 156, 158, 150, 159, 154, 151, 184, 189, - 187, 176, 180, 181, 177, 178, 185, 179, 188, 190, 182, 191, 186, 183, 24, 29, 27, 16, - 20, 21, 17, 18, 25, 19, 28, 30, 22, 31, 26, 23, 136, 141, 139, 128, 132, 133, 129, 130, - 137, 131, 140, 142, 134, 143, 138, 135, 232, 237, 235, 224, 228, 229, 225, 226, 233, - 227, 236, 238, 230, 239, 234, 231, 40, 45, 43, 32, 36, 37, 33, 34, 41, 35, 44, 46, 38, - 47, 42, 39, 72, 77, 75, 64, 68, 69, 65, 66, 73, 67, 76, 78, 70, 79, 74, 71, 120, 125, - 123, 112, 116, 117, 113, 114, 121, 115, 124, 126, 118, 127, 122, 119, 56, 61, 59, 48, - 52, 53, 49, 50, 57, 51, 60, 62, 54, 63, 58, 55, 104, 109, 107, 96, 100, 101, 97, 98, - 105, 99, 108, 110, 102, 111, 106, 103, 88, 93, 91, 80, 84, 85, 81, 82, 89, 83, 92, 94, - 86, 95, 90, 87, 168, 173, 171, 160, 164, 165, 161, 162, 169, 163, 172, 174, 166, 175, - 170, 167, 8, 13, 11, 0, 4, 5, 1, 2, 9, 3, 12, 14, 6, 15, 10, 7, 248, 253, 251, 240, - 244, 245, 241, 242, 249, 243, 252, 254, 246, 255, 250, 247, 216, 221, 219, 208, 212, - 213, 209, 210, 217, 211, 220, 222, 214, 223, 218, 215, - ], - [ - 122, 121, 118, 120, 125, 126, 114, 112, 127, 115, 117, 123, 116, 113, 124, 119, 74, 73, - 70, 72, 77, 78, 66, 64, 79, 67, 69, 75, 68, 65, 76, 71, 10, 9, 6, 8, 13, 14, 2, 0, 15, - 3, 5, 11, 4, 1, 12, 7, 90, 89, 86, 88, 93, 94, 82, 80, 95, 83, 85, 91, 84, 81, 92, 87, - 170, 169, 166, 168, 173, 174, 162, 160, 175, 163, 165, 171, 164, 161, 172, 167, 42, 41, - 38, 40, 45, 46, 34, 32, 47, 35, 37, 43, 36, 33, 44, 39, 250, 249, 246, 248, 253, 254, - 242, 240, 255, 243, 245, 251, 244, 241, 252, 247, 234, 233, 230, 232, 237, 238, 226, - 224, 239, 227, 229, 235, 228, 225, 236, 231, 202, 201, 198, 200, 205, 206, 194, 192, - 207, 195, 197, 203, 196, 193, 204, 199, 106, 105, 102, 104, 109, 110, 98, 96, 111, 99, - 101, 107, 100, 97, 108, 103, 26, 25, 22, 24, 29, 30, 18, 16, 31, 19, 21, 27, 20, 17, - 28, 23, 186, 185, 182, 184, 189, 190, 178, 176, 191, 179, 181, 187, 180, 177, 188, 183, - 218, 217, 214, 216, 221, 222, 210, 208, 223, 211, 213, 219, 212, 209, 220, 215, 154, - 153, 150, 152, 157, 158, 146, 144, 159, 147, 149, 155, 148, 145, 156, 151, 58, 57, 54, - 56, 61, 62, 50, 48, 63, 51, 53, 59, 52, 49, 60, 55, 138, 137, 134, 136, 141, 142, 130, - 128, 143, 131, 133, 139, 132, 129, 140, 135, - ], - ]; - const SBOX: SmallSbox = [ [1, 11, 12, 2, 9, 13, 0, 15, 4, 5, 8, 14, 10, 7, 6, 3], [0, 1, 7, 13, 11, 4, 5, 2, 8, 14, 15, 12, 9, 10, 6, 3], @@ -467,78 +136,10 @@ impl Sbox for CryptoProC { ]; } -#[derive(Clone)] pub enum CryptoProD {} impl Sbox for CryptoProD { const NAME: &'static str = "CryptoProD"; - const EXP_SBOX: ExpSbox = [ - [ - 90, 84, 85, 86, 88, 81, 83, 87, 93, 92, 94, 80, 89, 82, 91, 95, 250, 244, 245, 246, - 248, 241, 243, 247, 253, 252, 254, 240, 249, 242, 251, 255, 74, 68, 69, 70, 72, 65, 67, - 71, 77, 76, 78, 64, 73, 66, 75, 79, 10, 4, 5, 6, 8, 1, 3, 7, 13, 12, 14, 0, 9, 2, 11, - 15, 42, 36, 37, 38, 40, 33, 35, 39, 45, 44, 46, 32, 41, 34, 43, 47, 218, 212, 213, 214, - 216, 209, 211, 215, 221, 220, 222, 208, 217, 210, 219, 223, 186, 180, 181, 182, 184, - 177, 179, 183, 189, 188, 190, 176, 185, 178, 187, 191, 154, 148, 149, 150, 152, 145, - 147, 151, 157, 156, 158, 144, 153, 146, 155, 159, 26, 20, 21, 22, 24, 17, 19, 23, 29, - 28, 30, 16, 25, 18, 27, 31, 122, 116, 117, 118, 120, 113, 115, 119, 125, 124, 126, 112, - 121, 114, 123, 127, 106, 100, 101, 102, 104, 97, 99, 103, 109, 108, 110, 96, 105, 98, - 107, 111, 58, 52, 53, 54, 56, 49, 51, 55, 61, 60, 62, 48, 57, 50, 59, 63, 202, 196, - 197, 198, 200, 193, 195, 199, 205, 204, 206, 192, 201, 194, 203, 207, 234, 228, 229, - 230, 232, 225, 227, 231, 237, 236, 238, 224, 233, 226, 235, 239, 170, 164, 165, 166, - 168, 161, 163, 167, 173, 172, 174, 160, 169, 162, 171, 175, 138, 132, 133, 134, 136, - 129, 131, 135, 141, 140, 142, 128, 137, 130, 139, 143, - ], - [ - 71, 79, 76, 78, 73, 68, 65, 64, 67, 75, 69, 66, 70, 74, 72, 77, 167, 175, 172, 174, - 169, 164, 161, 160, 163, 171, 165, 162, 166, 170, 168, 173, 119, 127, 124, 126, 121, - 116, 113, 112, 115, 123, 117, 114, 118, 122, 120, 125, 199, 207, 204, 206, 201, 196, - 193, 192, 195, 203, 197, 194, 198, 202, 200, 205, 7, 15, 12, 14, 9, 4, 1, 0, 3, 11, 5, - 2, 6, 10, 8, 13, 247, 255, 252, 254, 249, 244, 241, 240, 243, 251, 245, 242, 246, 250, - 248, 253, 39, 47, 44, 46, 41, 36, 33, 32, 35, 43, 37, 34, 38, 42, 40, 45, 135, 143, - 140, 142, 137, 132, 129, 128, 131, 139, 133, 130, 134, 138, 136, 141, 231, 239, 236, - 238, 233, 228, 225, 224, 227, 235, 229, 226, 230, 234, 232, 237, 23, 31, 28, 30, 25, - 20, 17, 16, 19, 27, 21, 18, 22, 26, 24, 29, 103, 111, 108, 110, 105, 100, 97, 96, 99, - 107, 101, 98, 102, 106, 104, 109, 87, 95, 92, 94, 89, 84, 81, 80, 83, 91, 85, 82, 86, - 90, 88, 93, 215, 223, 220, 222, 217, 212, 209, 208, 211, 219, 213, 210, 214, 218, 216, - 221, 183, 191, 188, 190, 185, 180, 177, 176, 179, 187, 181, 178, 182, 186, 184, 189, - 151, 159, 156, 158, 153, 148, 145, 144, 147, 155, 149, 146, 150, 154, 152, 157, 55, 63, - 60, 62, 57, 52, 49, 48, 51, 59, 53, 50, 54, 58, 56, 61, - ], - [ - 119, 118, 116, 123, 121, 124, 114, 122, 113, 120, 112, 126, 127, 125, 115, 117, 103, - 102, 100, 107, 105, 108, 98, 106, 97, 104, 96, 110, 111, 109, 99, 101, 39, 38, 36, 43, - 41, 44, 34, 42, 33, 40, 32, 46, 47, 45, 35, 37, 71, 70, 68, 75, 73, 76, 66, 74, 65, 72, - 64, 78, 79, 77, 67, 69, 215, 214, 212, 219, 217, 220, 210, 218, 209, 216, 208, 222, - 223, 221, 211, 213, 151, 150, 148, 155, 153, 156, 146, 154, 145, 152, 144, 158, 159, - 157, 147, 149, 247, 246, 244, 251, 249, 252, 242, 250, 241, 248, 240, 254, 255, 253, - 243, 245, 7, 6, 4, 11, 9, 12, 2, 10, 1, 8, 0, 14, 15, 13, 3, 5, 167, 166, 164, 171, - 169, 172, 162, 170, 161, 168, 160, 174, 175, 173, 163, 165, 23, 22, 20, 27, 25, 28, 18, - 26, 17, 24, 16, 30, 31, 29, 19, 21, 87, 86, 84, 91, 89, 92, 82, 90, 81, 88, 80, 94, 95, - 93, 83, 85, 183, 182, 180, 187, 185, 188, 178, 186, 177, 184, 176, 190, 191, 189, 179, - 181, 135, 134, 132, 139, 137, 140, 130, 138, 129, 136, 128, 142, 143, 141, 131, 133, - 231, 230, 228, 235, 233, 236, 226, 234, 225, 232, 224, 238, 239, 237, 227, 229, 199, - 198, 196, 203, 201, 204, 194, 202, 193, 200, 192, 206, 207, 205, 195, 197, 55, 54, 52, - 59, 57, 60, 50, 58, 49, 56, 48, 62, 63, 61, 51, 53, - ], - [ - 29, 30, 20, 17, 23, 16, 21, 26, 19, 28, 24, 31, 22, 18, 25, 27, 61, 62, 52, 49, 55, 48, - 53, 58, 51, 60, 56, 63, 54, 50, 57, 59, 173, 174, 164, 161, 167, 160, 165, 170, 163, - 172, 168, 175, 166, 162, 169, 171, 157, 158, 148, 145, 151, 144, 149, 154, 147, 156, - 152, 159, 150, 146, 153, 155, 93, 94, 84, 81, 87, 80, 85, 90, 83, 92, 88, 95, 86, 82, - 89, 91, 189, 190, 180, 177, 183, 176, 181, 186, 179, 188, 184, 191, 182, 178, 185, 187, - 77, 78, 68, 65, 71, 64, 69, 74, 67, 76, 72, 79, 70, 66, 73, 75, 253, 254, 244, 241, - 247, 240, 245, 250, 243, 252, 248, 255, 246, 242, 249, 251, 141, 142, 132, 129, 135, - 128, 133, 138, 131, 140, 136, 143, 134, 130, 137, 139, 109, 110, 100, 97, 103, 96, 101, - 106, 99, 108, 104, 111, 102, 98, 105, 107, 125, 126, 116, 113, 119, 112, 117, 122, 115, - 124, 120, 127, 118, 114, 121, 123, 237, 238, 228, 225, 231, 224, 229, 234, 227, 236, - 232, 239, 230, 226, 233, 235, 221, 222, 212, 209, 215, 208, 213, 218, 211, 220, 216, - 223, 214, 210, 217, 219, 13, 14, 4, 1, 7, 0, 5, 10, 3, 12, 8, 15, 6, 2, 9, 11, 45, 46, - 36, 33, 39, 32, 37, 42, 35, 44, 40, 47, 38, 34, 41, 43, 205, 206, 196, 193, 199, 192, - 197, 202, 195, 204, 200, 207, 198, 194, 201, 203, - ], - ]; - const SBOX: SmallSbox = [ [10, 4, 5, 6, 8, 1, 3, 7, 13, 12, 14, 0, 9, 2, 11, 15], [5, 15, 4, 0, 2, 13, 11, 9, 1, 7, 6, 3, 12, 14, 10, 8], @@ -550,27 +151,3 @@ impl Sbox for CryptoProD { [1, 3, 10, 9, 5, 11, 4, 15, 8, 6, 7, 14, 13, 0, 2, 12], ]; } - -#[cfg(test)] -mod tests { - use super::*; - - fn test_sbox() { - let gen_sbox = S::gen_exp_sbox(); - for i in 0..4 { - for j in 0..256 { - assert_eq!(gen_sbox[i][j], S::EXP_SBOX[i][j]); - } - } - } - - #[test] - fn test_sboxes() { - test_sbox::(); - test_sbox::(); - test_sbox::(); - test_sbox::(); - test_sbox::(); - test_sbox::(); - } -} diff --git a/rc2/Cargo.toml b/rc2/Cargo.toml index e035bb77..c126af72 100644 --- a/rc2/Cargo.toml +++ b/rc2/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "rc2" -version = "0.8.1" +version = "0.9.0-pre" description = "RC2 block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/rc2" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,10 +13,10 @@ keywords = ["crypto", "rc2", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } [features] zeroize = ["cipher/zeroize"] diff --git a/rc2/LICENSE-APACHE b/rc2/LICENSE-APACHE index 652489d7..7de5cca3 100644 --- a/rc2/LICENSE-APACHE +++ b/rc2/LICENSE-APACHE @@ -1,13 +1,202 @@ -Copyright 2017 Damian Czaja -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ - http://www.apache.org/licenses/LICENSE-2.0 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Damian Czaja + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/rc2/README.md b/rc2/README.md index 89186b28..108d3935 100644 --- a/rc2/README.md +++ b/rc2/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/rc2/badge.svg [docs-link]: https://docs.rs/rc2/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/rc2/src/lib.rs b/rc2/src/lib.rs index 0756866c..21652e50 100644 --- a/rc2/src/lib.rs +++ b/rc2/src/lib.rs @@ -48,7 +48,7 @@ impl Rc2 { } fn expand_key(key: &[u8], t1: usize) -> [u16; 64] { - let key_len = key.len() as usize; + let key_len = key.len(); let t8: usize = (t1 + 7) >> 3; diff --git a/rc2/tests/mod.rs b/rc2/tests/mod.rs index 626be1c5..5f8844dd 100644 --- a/rc2/tests/mod.rs +++ b/rc2/tests/mod.rs @@ -1,5 +1,5 @@ -use cipher::generic_array::GenericArray; -use cipher::{BlockDecrypt, BlockEncrypt, KeyInit}; +use cipher::array::Array; +use cipher::{BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; struct Test { key: &'static [u8], @@ -21,48 +21,51 @@ macro_rules! new_tests { } #[test] +#[allow(deprecated)] // uses `clone_from_slice` fn rc2() { let tests = new_tests!("1", "2", "3", "7"); for test in &tests { - let cipher = rc2::Rc2::new_from_slice(&test.key).unwrap(); + let cipher = rc2::Rc2::new_from_slice(test.key).unwrap(); - let mut buf = GenericArray::clone_from_slice(test.input); + let mut buf = Array::clone_from_slice(test.input); cipher.encrypt_block(&mut buf); assert_eq!(test.output, &buf[..]); - let mut buf = GenericArray::clone_from_slice(test.output); + let mut buf = Array::clone_from_slice(test.output); cipher.decrypt_block(&mut buf); assert_eq!(test.input, &buf[..]); } } #[test] +#[allow(deprecated)] // uses `clone_from_slice` fn rc2_effective_key_64() { let tests = new_tests!("4", "5", "6"); for test in &tests { let cipher = rc2::Rc2::new_with_eff_key_len(test.key, 64); - let mut buf = GenericArray::clone_from_slice(test.input); + let mut buf = Array::clone_from_slice(test.input); cipher.encrypt_block(&mut buf); assert_eq!(test.output, &buf[..]); - let mut buf = GenericArray::clone_from_slice(test.output); + let mut buf = Array::clone_from_slice(test.output); cipher.decrypt_block(&mut buf); assert_eq!(test.input, &buf[..]); } } #[test] +#[allow(deprecated)] // uses `clone_from_slice` fn rc2_effective_key_129() { let tests = new_tests!("8"); for test in &tests { let cipher = rc2::Rc2::new_with_eff_key_len(test.key, 129); - let mut buf = GenericArray::clone_from_slice(test.input); + let mut buf = Array::clone_from_slice(test.input); cipher.encrypt_block(&mut buf); assert_eq!(test.output, &buf[..]); - let mut buf = GenericArray::clone_from_slice(test.output); + let mut buf = Array::clone_from_slice(test.output); cipher.decrypt_block(&mut buf); assert_eq!(test.input, &buf[..]); } diff --git a/rc5/CHANGELOG.md b/rc5/CHANGELOG.md index 53a89336..59c600b5 100644 --- a/rc5/CHANGELOG.md +++ b/rc5/CHANGELOG.md @@ -5,5 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +- Added u8 and u128 word size support. +- Enabled custom word size, key size, and round count values. +- Deprecated old predefined RC5 cipher types. + ## 0.0.1 (2023-02-10) -- Initial release +- Initial release \ No newline at end of file diff --git a/rc5/Cargo.toml b/rc5/Cargo.toml index 98f0786f..70bc79c0 100644 --- a/rc5/Cargo.toml +++ b/rc5/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "rc5" -version = "0.0.1" +version = "0.1.0-pre" description = "RC5 block cipher" authors = ["RustCrypto Developers"] edition = "2021" license = "MIT OR Apache-2.0" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" repository = "https://github.com/RustCrypto/block-ciphers" keywords = ["crypto", "rc5", "block-cipher"] diff --git a/rc5/LICENSE-APACHE b/rc5/LICENSE-APACHE index cf59c06d..257ba9ac 100644 --- a/rc5/LICENSE-APACHE +++ b/rc5/LICENSE-APACHE @@ -1,13 +1,202 @@ -Copyright 2022 Antonio Dropulic -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ - http://www.apache.org/licenses/LICENSE-2.0 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 Antonio Dropulic + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/rc5/README.md b/rc5/README.md index de626d62..667eb0ad 100644 --- a/rc5/README.md +++ b/rc5/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -60,7 +60,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/block-ciphers/actions/workflows/rc5.yml/badge.svg [build-link]: https://github.com/RustCrypto/block-ciphers/actions/workflows/rc5.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/rc5/benches/mod.rs b/rc5/benches/mod.rs index 538db60b..bf87b3bc 100644 --- a/rc5/benches/mod.rs +++ b/rc5/benches/mod.rs @@ -1,27 +1,28 @@ #![feature(test)] extern crate test; +use cipher::consts::*; use cipher::{block_decryptor_bench, block_encryptor_bench}; -use rc5::{RC5_32_12_16, RC5_32_16_16}; +use rc5::RC5; block_encryptor_bench!( - Key: RC5_32_12_16, + Key: RC5, rc5_32_12_16_encrypt_block, rc5_32_12_16_encrypt_blocks, ); block_decryptor_bench!( - Key: RC5_32_12_16, + Key: RC5, rc5_32_12_16_decrypt_block, rc5_32_12_16_decrypt_blocks, ); block_encryptor_bench!( - Key: RC5_32_16_16, + Key: RC5, rc5_32_16_16_encrypt_block, rc5_32_16_16_encrypt_blocks, ); block_decryptor_bench!( - Key: RC5_32_16_16, + Key: RC5, rc5_32_16_16_decrypt_block, rc5_32_16_16_decrypt_blocks, ); diff --git a/rc5/src/block_cipher.rs b/rc5/src/block_cipher.rs index 6bde8f40..56c6b88a 100644 --- a/rc5/src/block_cipher.rs +++ b/rc5/src/block_cipher.rs @@ -1,11 +1,13 @@ use core::ops::{Add, Div, Mul, Sub}; use cipher::{ - generic_array::ArrayLength, + array::ArraySize, + consts::*, + crypto_common::BlockSizes, inout::InOut, - typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U12, U16, U2, U24, U256, U8}, - AlgorithmName, Block, BlockBackend, BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser, - KeyInit, KeySizeUser, ParBlocksSizeUser, + typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U2, U256}, + AlgorithmName, Block, BlockBackend, BlockCipher, BlockCipherDecrypt, BlockCipherEncrypt, + BlockSizeUser, KeyInit, KeySizeUser, ParBlocksSizeUser, }; use crate::core::{BlockSize, ExpandedKeyTableSize, KeyAsWordsSize, Word, RC5}; @@ -15,7 +17,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -23,16 +25,16 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, // Key range - B: ArrayLength, + B: ArraySize, B: IsLess, Le: NonZero, // KeyAsWordsSize B: Add, Sum: Sub, Diff, U1>: Div, - KeyAsWordsSize: ArrayLength, + KeyAsWordsSize: ArraySize, { fn new(key: &cipher::Key) -> Self { Self::new(key) @@ -44,7 +46,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -52,8 +54,8 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, - B: ArrayLength, + ExpandedKeyTableSize: ArraySize, + B: ArraySize, { type KeySize = B; } @@ -63,7 +65,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -71,7 +73,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { } @@ -80,7 +82,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -88,17 +90,17 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { type BlockSize = BlockSize; } -impl BlockEncrypt for RC5 +impl BlockCipherEncrypt for RC5 where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -106,16 +108,16 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, // Key range - B: ArrayLength, + B: ArraySize, B: IsLess, Le: NonZero, // KeyAsWordsSize B: Add, Sum: Sub, Diff, U1>: Div, - KeyAsWordsSize: ArrayLength, + KeyAsWordsSize: ArraySize, { fn encrypt_with_backend(&self, f: impl cipher::BlockClosure) { f.call(&mut RC5EncryptBackend { enc_dec: self }) @@ -127,7 +129,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -135,7 +137,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { enc_dec: &'a RC5, } @@ -144,7 +146,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -152,7 +154,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { type BlockSize = BlockSize; } @@ -162,7 +164,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -170,7 +172,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { type ParBlocksSize = U1; } @@ -180,7 +182,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -188,16 +190,16 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, // Key range - B: ArrayLength, + B: ArraySize, B: IsLess, Le: NonZero, // KeyAsWordsSize B: Add, Sum: Sub, Diff, U1>: Div, - KeyAsWordsSize: ArrayLength, + KeyAsWordsSize: ArraySize, { #[inline(always)] fn proc_block(&mut self, block: InOut<'_, '_, Block>) { @@ -206,12 +208,12 @@ where } } -impl BlockDecrypt for RC5 +impl BlockCipherDecrypt for RC5 where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -219,16 +221,16 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, // Key range - B: ArrayLength, + B: ArraySize, B: IsLess, Le: NonZero, // KeyAsWordsSize B: Add, Sum: Sub, Diff, U1>: Div, - KeyAsWordsSize: ArrayLength, + KeyAsWordsSize: ArraySize, { fn decrypt_with_backend(&self, f: impl cipher::BlockClosure) { f.call(&mut RC5DecryptBackend { enc_dec: self }) @@ -240,7 +242,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -248,7 +250,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { enc_dec: &'a RC5, } @@ -257,7 +259,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -265,7 +267,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { type BlockSize = BlockSize; } @@ -275,7 +277,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -283,7 +285,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { type ParBlocksSize = U1; } @@ -293,7 +295,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -301,16 +303,16 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, // Key range - B: ArrayLength, + B: ArraySize, B: IsLess, Le: NonZero, // KeyAsWordsSize B: Add, Sum: Sub, Diff, U1>: Div, - KeyAsWordsSize: ArrayLength, + KeyAsWordsSize: ArraySize, { #[inline(always)] fn proc_block(&mut self, block: InOut<'_, '_, Block>) { @@ -324,7 +326,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -332,7 +334,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( @@ -345,7 +347,15 @@ where } } +#[allow(dead_code)] +#[deprecated(since = "0.1.0", note = "use RC5 instead.")] +pub type RC5_16_16_8 = RC5; +#[allow(dead_code)] +#[deprecated(since = "0.1.0", note = "use RC5 instead.")] pub type RC5_32_12_16 = RC5; +#[allow(dead_code)] +#[deprecated(since = "0.1.0", note = "use RC5 instead.")] pub type RC5_32_16_16 = RC5; -pub type RC5_16_16_8 = RC5; +#[allow(dead_code)] +#[deprecated(since = "0.1.0", note = "use RC5 instead.")] pub type RC5_64_24_24 = RC5; diff --git a/rc5/src/core/backend.rs b/rc5/src/core/backend.rs index 23908f9f..b7fbdc78 100644 --- a/rc5/src/core/backend.rs +++ b/rc5/src/core/backend.rs @@ -5,7 +5,8 @@ use core::{ }; use cipher::{ - generic_array::{sequence::GenericSequence, ArrayLength, GenericArray}, + array::{Array, ArraySize}, + crypto_common::BlockSizes, inout::InOut, typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U2, U256}, }; @@ -19,7 +20,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -27,7 +28,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { key_table: ExpandedKeyTable, _key_size: PhantomData, @@ -38,7 +39,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -46,16 +47,16 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, // Key range - B: ArrayLength, + B: ArraySize, B: IsLess, Le: NonZero, // KeyAsWordsSize B: Add, Sum: Sub, Diff, U1>: Div, - KeyAsWordsSize: ArrayLength, + KeyAsWordsSize: ArraySize, { pub fn new(key: &Key) -> RC5 { Self { @@ -73,7 +74,7 @@ where fn key_into_words(key: &Key) -> KeyAsWords { // can be uninitialized - let mut key_as_words: GenericArray> = GenericArray::default(); + let mut key_as_words: Array> = Array::default(); for i in (0..B::USIZE).rev() { key_as_words[i / W::Bytes::USIZE] = @@ -86,8 +87,7 @@ where fn initialize_expanded_key_table() -> ExpandedKeyTable { // must be zero initialized - let mut expanded_key_table: GenericArray> = - GenericArray::generate(|_| W::ZERO); + let mut expanded_key_table: Array> = Array::from_fn(|_| W::ZERO); expanded_key_table[0] = W::P; for i in 1..expanded_key_table.len() { @@ -132,7 +132,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -140,7 +140,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { pub fn encrypt(&self, mut block: InOut<'_, '_, Block>) { let (mut a, mut b) = Self::words_from_block(block.get_in()); @@ -194,7 +194,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -202,7 +202,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { } @@ -212,7 +212,7 @@ where W: Word, // Block size W::Bytes: Mul, - BlockSize: ArrayLength, + BlockSize: BlockSizes, // Rounds range R: Unsigned, R: IsLess, @@ -220,7 +220,7 @@ where // ExpandedKeyTableSize R: Add, Sum: Mul, - ExpandedKeyTableSize: ArrayLength, + ExpandedKeyTableSize: ArraySize, { fn drop(&mut self) { cipher::zeroize::Zeroize::zeroize(&mut *self.key_table) diff --git a/rc5/src/core/primitives.rs b/rc5/src/core/primitives.rs index 1a72e96d..1e17da0b 100644 --- a/rc5/src/core/primitives.rs +++ b/rc5/src/core/primitives.rs @@ -1,26 +1,26 @@ use core::ops::{Add, BitXor}; use cipher::{ - generic_array::{ArrayLength, GenericArray}, - typenum::{Diff, Prod, Quot, Sum, U1, U2, U4, U8}, + array::{Array, ArraySize}, + typenum::{Diff, Prod, Quot, Sum, U1, U16, U2, U4, U8}, zeroize::DefaultIsZeroes, }; pub type BlockSize = Prod<::Bytes, U2>; -pub type Block = GenericArray>; +pub type Block = Array>; -pub type Key = GenericArray; +pub type Key = Array; -pub type ExpandedKeyTable = GenericArray>; +pub type ExpandedKeyTable = Array>; pub type ExpandedKeyTableSize = Prod, U2>; -pub type KeyAsWords = GenericArray>; +pub type KeyAsWords = Array>; pub type KeyAsWordsSize = Quot::Bytes>, U1>, ::Bytes>; pub trait Word: Default + Copy + From + Add + DefaultIsZeroes + private::Sealed { - type Bytes: ArrayLength; + type Bytes: ArraySize; const ZERO: Self; const THREE: Self; @@ -35,62 +35,63 @@ pub trait Word: fn rotate_left(self, n: Self) -> Self; fn rotate_right(self, n: Self) -> Self; - fn from_le_bytes(bytes: &GenericArray) -> Self; - fn to_le_bytes(self) -> GenericArray; + fn from_le_bytes(bytes: &Array) -> Self; + fn to_le_bytes(self) -> Array; fn bitxor(self, other: Self) -> Self; } mod private { pub trait Sealed {} - - impl Sealed for u32 {} + impl Sealed for u8 {} impl Sealed for u16 {} + impl Sealed for u32 {} impl Sealed for u64 {} + impl Sealed for u128 {} } -impl Word for u32 { - type Bytes = U4; +impl Word for u8 { + type Bytes = U1; const ZERO: Self = 0; const THREE: Self = 3; const EIGHT: Self = 8; - const P: Self = 0xb7e15163; - const Q: Self = 0x9e3779b9; + const P: Self = 0xb7; + const Q: Self = 0x9f; #[inline(always)] fn wrapping_add(self, rhs: Self) -> Self { - u32::wrapping_add(self, rhs) + u8::wrapping_add(self, rhs) } #[inline(always)] fn wrapping_sub(self, rhs: Self) -> Self { - u32::wrapping_sub(self, rhs) + u8::wrapping_sub(self, rhs) } #[inline(always)] fn rotate_left(self, n: Self) -> Self { - u32::rotate_left(self, n) + u8::rotate_left(self, n as u32) } #[inline(always)] fn rotate_right(self, n: Self) -> Self { - u32::rotate_right(self, n) + u8::rotate_right(self, n as u32) } #[inline(always)] - fn from_le_bytes(bytes: &GenericArray) -> Self { - u32::from_le_bytes(bytes.as_slice().try_into().unwrap()) + fn from_le_bytes(bytes: &Array) -> Self { + u8::from_le_bytes(bytes.as_slice().try_into().unwrap()) } #[inline(always)] - fn to_le_bytes(self) -> GenericArray { - u32::to_le_bytes(self).into() + fn to_le_bytes(self) -> Array { + u8::to_le_bytes(self).into() } #[inline(always)] fn bitxor(self, other: Self) -> Self { - ::bitxor(self, other) + ::bitxor(self, other) } } @@ -124,12 +125,12 @@ impl Word for u16 { } #[inline(always)] - fn from_le_bytes(bytes: &GenericArray) -> Self { + fn from_le_bytes(bytes: &Array) -> Self { u16::from_le_bytes(bytes.as_slice().try_into().unwrap()) } #[inline(always)] - fn to_le_bytes(self) -> GenericArray { + fn to_le_bytes(self) -> Array { u16::to_le_bytes(self).into() } @@ -139,6 +140,51 @@ impl Word for u16 { } } +impl Word for u32 { + type Bytes = U4; + + const ZERO: Self = 0; + const THREE: Self = 3; + const EIGHT: Self = 8; + + const P: Self = 0xb7e15163; + const Q: Self = 0x9e3779b9; + + #[inline(always)] + fn wrapping_add(self, rhs: Self) -> Self { + u32::wrapping_add(self, rhs) + } + #[inline(always)] + fn wrapping_sub(self, rhs: Self) -> Self { + u32::wrapping_sub(self, rhs) + } + + #[inline(always)] + fn rotate_left(self, n: Self) -> Self { + u32::rotate_left(self, n) + } + + #[inline(always)] + fn rotate_right(self, n: Self) -> Self { + u32::rotate_right(self, n) + } + + #[inline(always)] + fn from_le_bytes(bytes: &Array) -> Self { + u32::from_le_bytes(bytes.as_slice().try_into().unwrap()) + } + + #[inline(always)] + fn to_le_bytes(self) -> Array { + u32::to_le_bytes(self).into() + } + + #[inline(always)] + fn bitxor(self, other: Self) -> Self { + ::bitxor(self, other) + } +} + impl Word for u64 { type Bytes = U8; @@ -171,12 +217,12 @@ impl Word for u64 { } #[inline(always)] - fn from_le_bytes(bytes: &GenericArray) -> Self { + fn from_le_bytes(bytes: &Array) -> Self { u64::from_le_bytes(bytes.as_slice().try_into().unwrap()) } #[inline(always)] - fn to_le_bytes(self) -> GenericArray { + fn to_le_bytes(self) -> Array { u64::to_le_bytes(self).into() } @@ -185,3 +231,50 @@ impl Word for u64 { ::bitxor(self, other) } } + +impl Word for u128 { + type Bytes = U16; + + const ZERO: Self = 0; + const THREE: Self = 3; + const EIGHT: Self = 8; + + const P: Self = 0xb7e151628aed2a6abf7158809cf4f3c7; + const Q: Self = 0x9e3779b97f4a7c15f39cc0605cedc835; + + #[inline(always)] + fn wrapping_add(self, rhs: Self) -> Self { + u128::wrapping_add(self, rhs) + } + #[inline(always)] + fn wrapping_sub(self, rhs: Self) -> Self { + u128::wrapping_sub(self, rhs) + } + + #[inline(always)] + fn rotate_left(self, n: Self) -> Self { + let size = Self::BITS; + u128::rotate_left(self, (n % size as u128) as u32) + } + + #[inline(always)] + fn rotate_right(self, n: Self) -> Self { + let size = Self::BITS; + u128::rotate_right(self, (n % size as u128) as u32) + } + + #[inline(always)] + fn from_le_bytes(bytes: &Array) -> Self { + u128::from_le_bytes(bytes.as_slice().try_into().unwrap()) + } + + #[inline(always)] + fn to_le_bytes(self) -> Array { + u128::to_le_bytes(self).into() + } + + #[inline(always)] + fn bitxor(self, other: Self) -> Self { + ::bitxor(self, other) + } +} diff --git a/rc5/src/lib.rs b/rc5/src/lib.rs index b2d584b0..6ddf5f99 100644 --- a/rc5/src/lib.rs +++ b/rc5/src/lib.rs @@ -3,4 +3,5 @@ mod block_cipher; mod core; +pub use crate::core::RC5; pub use block_cipher::*; diff --git a/rc5/tests/mod.rs b/rc5/tests/mod.rs index 77fe3554..f17416ed 100644 --- a/rc5/tests/mod.rs +++ b/rc5/tests/mod.rs @@ -1,8 +1,28 @@ /// generated using the code in: https://www.ietf.org/archive/id/draft-krovetz-rc6-rc5-vectors-00.txt #[cfg(test)] +#[allow(deprecated)] // uses `clone_from_slice` mod tests { - use cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt, KeyInit}; - use rc5::{RC5_16_16_8, RC5_32_12_16, RC5_32_16_16, RC5_64_24_24}; + use cipher::consts::*; + use cipher::{array::Array, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; + use rc5::RC5; + + #[test] + fn enc_dec_8_12_4() { + let key = [0x00, 0x01, 0x02, 0x03]; + + let pt = [0x00, 0x01]; + let ct = [0x21, 0x2A]; + + let rc5 = as KeyInit>::new_from_slice(&key).unwrap(); + + let mut block = Array::clone_from_slice(&pt); + rc5.encrypt_block(&mut block); + + assert_eq!(ct, block[..]); + + rc5.decrypt_block(&mut block); + assert_eq!(pt, block[..]); + } #[test] fn enc_dec_16_16_8() { @@ -11,9 +31,9 @@ mod tests { let pt = [0x00, 0x01, 0x02, 0x03]; let ct = [0x23, 0xA8, 0xD7, 0x2E]; - let rc5 = ::new_from_slice(&key).unwrap(); + let rc5 = as KeyInit>::new_from_slice(&key).unwrap(); - let mut block = GenericArray::clone_from_slice(&pt); + let mut block = Array::clone_from_slice(&pt); rc5.encrypt_block(&mut block); assert_eq!(ct, block[..]); @@ -32,9 +52,9 @@ mod tests { let pt = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]; let ct = [0xC8, 0xD3, 0xB3, 0xC4, 0x86, 0x70, 0x0C, 0xFA]; - let rc5 = ::new_from_slice(&key).unwrap(); + let rc5 = as KeyInit>::new_from_slice(&key).unwrap(); - let mut block = GenericArray::clone_from_slice(&pt); + let mut block = Array::clone_from_slice(&pt); rc5.encrypt_block(&mut block); assert_eq!(ct, block[..]); @@ -53,9 +73,9 @@ mod tests { let pt = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]; let ct = [0x3E, 0x2E, 0x95, 0x35, 0x70, 0x27, 0xD8, 0x96]; - let rc5 = ::new_from_slice(&key).unwrap(); + let rc5 = as KeyInit>::new_from_slice(&key).unwrap(); - let mut block = GenericArray::clone_from_slice(&pt); + let mut block = Array::clone_from_slice(&pt); rc5.encrypt_block(&mut block); assert_eq!(ct, block[..]); @@ -80,9 +100,39 @@ mod tests { 0x78, 0xDA, ]; - let rc5 = ::new_from_slice(&key).unwrap(); + let rc5 = as KeyInit>::new_from_slice(&key).unwrap(); + + let mut block = Array::clone_from_slice(&pt); + rc5.encrypt_block(&mut block); + + assert_eq!(ct, block[..]); + + rc5.decrypt_block(&mut block); + assert_eq!(pt, block[..]); + } + + #[test] + fn enc_dec_128_28_32() { + let key = [ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, + ]; + + let pt = [ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, + ]; + let ct = [ + 0xEC, 0xA5, 0x91, 0x09, 0x21, 0xA4, 0xF4, 0xCF, 0xDD, 0x7A, 0xD7, 0xAD, 0x20, 0xA1, + 0xFC, 0xBA, 0x06, 0x8E, 0xC7, 0xA7, 0xCD, 0x75, 0x2D, 0x68, 0xFE, 0x91, 0x4B, 0x7F, + 0xE1, 0x80, 0xB4, 0x40, + ]; + + let rc5 = as KeyInit>::new_from_slice(&key).unwrap(); - let mut block = GenericArray::clone_from_slice(&pt); + let mut block = Array::clone_from_slice(&pt); rc5.encrypt_block(&mut block); assert_eq!(ct, block[..]); diff --git a/serpent/Cargo.toml b/serpent/Cargo.toml index b9ced5c3..8536fa98 100644 --- a/serpent/Cargo.toml +++ b/serpent/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "serpent" -version = "0.5.1" +version = "0.6.0-pre" description = "Serpent block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/serpent" repository = "https://github.com/RustCrypto/block-ciphers" @@ -14,10 +14,10 @@ categories = ["cryptography", "no-std"] [dependencies] byteorder = { version = "1.1", default-features = false } -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } [features] zeroize = ["cipher/zeroize"] diff --git a/serpent/README.md b/serpent/README.md index 1902e143..69464f33 100644 --- a/serpent/README.md +++ b/serpent/README.md @@ -28,7 +28,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -60,7 +60,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/serpent/badge.svg [docs-link]: https://docs.rs/serpent/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/serpent/src/lib.rs b/serpent/src/lib.rs index ad1c7e63..e806f632 100644 --- a/serpent/src/lib.rs +++ b/serpent/src/lib.rs @@ -211,19 +211,16 @@ impl Serpent { let mut k = [0u32; 132]; for i in 0..r { let sbox_index = (ROUNDS + 3 - i) % ROUNDS; - let a = words[(4 * i) as usize]; - let b = words[(4 * i + 1) as usize]; - let c = words[(4 * i + 2) as usize]; - let d = words[(4 * i + 3) as usize]; + let [a, b, c, d]: [u32; 4] = words[4 * i..][..4].try_into().unwrap(); // calculate keys in bitslicing mode for j in 0..32 { let input = get_bit(a as usize, j) | get_bit(b as usize, j) << 1 | get_bit(c as usize, j) << 2 | get_bit(d as usize, j) << 3; - let output = apply_s(sbox_index, input as u8); + let output = apply_s(sbox_index, input); for l in 0..4 { - k[(4 * i + l) as usize] |= u32::from(get_bit(output as usize, l)) << j; + k[4 * i + l] |= u32::from(get_bit(output as usize, l)) << j; } } } diff --git a/sm4/Cargo.toml b/sm4/Cargo.toml index 08e8c6b4..136ecc9e 100644 --- a/sm4/Cargo.toml +++ b/sm4/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "sm4" -version = "0.5.1" +version = "0.6.0-pre" description = "SM4 block cipher algorithm" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/sm4" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,11 +13,11 @@ keywords = ["crypto", "sm4", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } -hex-literal = "0.3" +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" [features] zeroize = ["cipher/zeroize"] diff --git a/sm4/README.md b/sm4/README.md index 10f285ba..2e36277f 100644 --- a/sm4/README.md +++ b/sm4/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/sm4/badge.svg [docs-link]: https://docs.rs/sm4/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/sm4/tests/mod.rs b/sm4/tests/mod.rs index c7d55737..036d7181 100644 --- a/sm4/tests/mod.rs +++ b/sm4/tests/mod.rs @@ -1,17 +1,17 @@ //! Test vectors are from GM/T 0002-2012 -use cipher::{BlockDecrypt, BlockEncrypt, KeyInit}; +use cipher::{BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; use hex_literal::hex; use sm4::Sm4; #[test] fn sm4_example_1() { let key = hex!("0123456789abcdeffedcba9876543210"); - let plaintext = key.clone(); + let plaintext = key; let ciphertext = hex!("681EDF34D206965E86B3E94F536E4246"); let cipher = Sm4::new(&key.into()); - let mut block = plaintext.clone().into(); + let mut block = plaintext.into(); cipher.encrypt_block(&mut block); assert_eq!(&ciphertext, block.as_slice()); @@ -23,12 +23,12 @@ fn sm4_example_1() { #[test] fn sm4_example_2() { let key = hex!("0123456789abcdeffedcba9876543210"); - let plaintext = key.clone(); + let plaintext = key; let ciphertext = hex!("595298c7c6fd271f0402f804c33d3f66"); let cipher = Sm4::new(&key.into()); - let mut block = plaintext.clone().into(); + let mut block = plaintext.into(); for _ in 0..1_000_000 { cipher.encrypt_block(&mut block); } diff --git a/speck/CHANGELOG.md b/speck/CHANGELOG.md new file mode 100644 index 00000000..ea14bbf1 --- /dev/null +++ b/speck/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.0.1 (2024-05-17) +- Initial release diff --git a/speck/Cargo.toml b/speck/Cargo.toml index 8b59688a..90229a6f 100644 --- a/speck/Cargo.toml +++ b/speck/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "speck" -version = "0.0.1" # Also update html_root_url in lib.rs when bumping this +name = "speck-cipher" +version = "0.0.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Speck block cipher algorithm" @@ -8,13 +8,13 @@ documentation = "https://docs.rs/speck" repository = "https://github.com/RustCrypto/block-ciphers/tree/master/speck" readme = "README.md" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" keywords = ["crypto", "speck", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } -hex-literal = "0.3" +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" diff --git a/speck/README.md b/speck/README.md index 796e6e0a..4898cbcf 100644 --- a/speck/README.md +++ b/speck/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -53,12 +53,12 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/speck.svg -[crate-link]: https://crates.io/crates/speck -[docs-image]: https://docs.rs/speck/badge.svg -[docs-link]: https://docs.rs/speck/ +[crate-image]: https://img.shields.io/crates/v/speck-cipher.svg +[crate-link]: https://crates.io/crates/speck-cipher +[docs-image]: https://docs.rs/speck-cipher/badge.svg +[docs-link]: https://docs.rs/speck-cipher/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/speck/tests/mod.rs b/speck/tests/mod.rs index eb30eeae..0f1e1450 100644 --- a/speck/tests/mod.rs +++ b/speck/tests/mod.rs @@ -1,8 +1,8 @@ //! Test vectors are from The Simon and Speck Families of Lightweight Block Ciphers (Appendix C) -use cipher::{BlockDecrypt, BlockEncrypt, KeyInit}; +use cipher::{BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; use hex_literal::hex; -use speck::{ +use speck_cipher::{ Speck128_128, Speck128_192, Speck128_256, Speck32_64, Speck48_72, Speck48_96, Speck64_128, Speck64_96, Speck96_144, Speck96_96, }; diff --git a/threefish/Cargo.toml b/threefish/Cargo.toml index f8545b2f..653ea214 100644 --- a/threefish/Cargo.toml +++ b/threefish/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "threefish" -version = "0.5.2" +version = "0.6.0-pre" description = "Threefish block cipher" authors = ["The Rust-Crypto Project Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/threefish" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,12 +13,12 @@ keywords = ["crypto", "threefish", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = { version = "0.4.2", optional = true } +cipher = { version = "=0.5.0-pre.6", optional = true } zeroize = { version = "1.6", optional = true, default-features = false } [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"]} -hex-literal = "0.3.3" +cipher = { version = "=0.5.0-pre.6", features = ["dev"]} +hex-literal = "0.4" [features] default = ["cipher"] diff --git a/threefish/README.md b/threefish/README.md index 8734b486..bb68ff2d 100644 --- a/threefish/README.md +++ b/threefish/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/threefish/badge.svg [docs-link]: https://docs.rs/threefish/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/threefish/tests/mod.rs b/threefish/tests/mod.rs index 4436ecc4..7238e1e4 100644 --- a/threefish/tests/mod.rs +++ b/threefish/tests/mod.rs @@ -1,7 +1,7 @@ //! Test vectors from: //! https://github.com/weidai11/cryptopp/blob/master/TestVectors/threefish.txt -#![cfg(featue = "cipher")] -use cipher::{Block, BlockDecrypt, BlockEncrypt, KeyInit}; +#![cfg(feature = "cipher")] +use cipher::{Block, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; use hex_literal::hex; use threefish::{Threefish1024, Threefish256, Threefish512}; @@ -15,6 +15,7 @@ struct Vector { macro_rules! impl_test { {$name:ident, $cipher:ty, $tests:expr,} => { #[test] + #[allow(deprecated)] // uses `clone_from_slice` fn $name() { let vectors = $tests; for &Vector { key, tweak, pt, ct } in vectors.iter() { diff --git a/twofish/Cargo.toml b/twofish/Cargo.toml index 38419285..885c69cb 100644 --- a/twofish/Cargo.toml +++ b/twofish/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "twofish" -version = "0.7.1" +version = "0.8.0-pre" description = "Twofish block cipher" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/twofish" repository = "https://github.com/RustCrypto/block-ciphers" @@ -13,11 +13,11 @@ keywords = ["crypto", "twofish", "block-cipher"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "0.4.2" +cipher = "=0.5.0-pre.6" [dev-dependencies] -cipher = { version = "0.4.2", features = ["dev"] } -hex-literal = "0.3" +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +hex-literal = "0.4" [features] zeroize = ["cipher/zeroize"] diff --git a/twofish/README.md b/twofish/README.md index 73c29af4..a493e595 100644 --- a/twofish/README.md +++ b/twofish/README.md @@ -26,7 +26,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/twofish/badge.svg [docs-link]: https://docs.rs/twofish/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg [hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/twofish/tests/mod.rs b/twofish/tests/mod.rs index 86df62a4..7d8f2039 100644 --- a/twofish/tests/mod.rs +++ b/twofish/tests/mod.rs @@ -1,4 +1,4 @@ -use cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt, KeyInit}; +use cipher::{array::Array, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; use hex_literal::hex; use twofish::Twofish; @@ -11,7 +11,7 @@ macro_rules! new_test { #[test] fn $name() { let mut key = [0u8; $key_len]; - let mut plain = GenericArray::default(); + let mut plain = Array::default(); let mut cipher; for i in 1..50 { diff --git a/xtea/CHANGELOG.md b/xtea/CHANGELOG.md new file mode 100644 index 00000000..f14e3560 --- /dev/null +++ b/xtea/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.0 (2024-05-11) +- Initial release diff --git a/xtea/Cargo.toml b/xtea/Cargo.toml new file mode 100644 index 00000000..6905348a --- /dev/null +++ b/xtea/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "xtea" +version = "0.0.0" +description = "XTEA block cipher" +authors = ["RustCrypto Developers"] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version = "1.65" +readme = "README.md" +documentation = "https://docs.rs/xtea" +repository = "https://github.com/RustCrypto/block-ciphers" +keywords = ["crypto", "xtea", "block-cipher"] +categories = ["cryptography", "no-std"] + +[dependencies] +cipher = "=0.5.0-pre.6" + +[dev-dependencies] +cipher = { version = "=0.5.0-pre.6", features = ["dev"] } + +[features] +zeroize = ["cipher/zeroize"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/xtea/LICENSE-APACHE b/xtea/LICENSE-APACHE new file mode 100644 index 00000000..0de24dde --- /dev/null +++ b/xtea/LICENSE-APACHE @@ -0,0 +1,13 @@ +Copyright 2024 Kevin Ludwig + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/xtea/LICENSE-MIT b/xtea/LICENSE-MIT new file mode 100644 index 00000000..95e7d3c6 --- /dev/null +++ b/xtea/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2024 Kevin Ludwig + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/xtea/README.md b/xtea/README.md new file mode 100644 index 00000000..54839dfc --- /dev/null +++ b/xtea/README.md @@ -0,0 +1,71 @@ +# RustCrypto: XTEA Cipher + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] +[![Build Status][build-image]][build-link] +[![HAZMAT][hazmat-image]][hazmat-link] + +Pure Rust implementation of the [XTEA block cipher][1]. + +[Documentation][docs-link] + +## ⚠️ Security Warning: [Hazmat!][hazmat-link] + +This crate does not ensure ciphertexts are authentic (i.e. by using a MAC to +verify ciphertext integrity), which can lead to serious vulnerabilities +if used incorrectly! + +No security audits of this crate have ever been performed, and it has not been +thoroughly assessed to ensure its operation is constant-time on common CPU +architectures. + +USE AT YOUR OWN RISK! + +## Minimum Supported Rust Version + +Rust **1.65** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/xtea.svg +[crate-link]: https://crates.io/crates/xtea +[docs-image]: https://docs.rs/xtea/badge.svg +[docs-link]: https://docs.rs/xtea/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg +[hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260039-block-ciphers +[build-image]: https://github.com/RustCrypto/block-ciphers/workflows/xtea/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/block-ciphers/actions?query=workflow%3Axtea + +[//]: # (general links) + +[1]: https://en.wikipedia.org/wiki/XTEA diff --git a/xtea/benches/mod.rs b/xtea/benches/mod.rs new file mode 100644 index 00000000..1105734d --- /dev/null +++ b/xtea/benches/mod.rs @@ -0,0 +1,8 @@ +#![feature(test)] +extern crate test; + +use cipher::{block_decryptor_bench, block_encryptor_bench}; +use xtea::Xtea; + +block_encryptor_bench!(Key: Xtea, xtea_encrypt_block, xtea_encrypt_blocks); +block_decryptor_bench!(Key: Xtea, xtea_decrypt_block, xtea_decrypt_blocks); diff --git a/xtea/src/consts.rs b/xtea/src/consts.rs new file mode 100644 index 00000000..d5bba793 --- /dev/null +++ b/xtea/src/consts.rs @@ -0,0 +1,2 @@ +pub const DELTA: u32 = 0x9e3779b9; +pub const ROUNDS: usize = 32; diff --git a/xtea/src/lib.rs b/xtea/src/lib.rs new file mode 100644 index 00000000..1e83dc39 --- /dev/null +++ b/xtea/src/lib.rs @@ -0,0 +1,156 @@ +//! Pure Rust implementation of the [Extended Tiny Encryption Algorithm][XTEA]. +//! +//! # ⚠️ Security Warning: Hazmat! +//! +//! This crate implements only the low-level block cipher function, and is intended +//! for use for implementing higher-level constructions *only*. It is NOT +//! intended for direct use in applications. +//! +//! USE AT YOUR OWN RISK! +//! +//! [XTEA]: https://en.wikipedia.org/wiki/XTEA + +#![no_std] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg" +)] +#![deny(unsafe_code)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![warn(missing_docs, rust_2018_idioms)] + +pub use cipher; + +use cipher::{ + consts::{U16, U8}, + AlgorithmName, BlockCipher, InvalidLength, Key, KeyInit, KeySizeUser, +}; +use core::fmt; + +#[cfg(feature = "zeroize")] +use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; + +mod consts; +use consts::{DELTA, ROUNDS}; + +/// XTEA block cipher. +pub struct Xtea { + k: [u32; 4], +} + +impl BlockCipher for Xtea {} + +impl KeySizeUser for Xtea { + type KeySize = U16; +} + +impl KeyInit for Xtea { + fn new(key: &Key) -> Self { + Self::new_from_slice(key).unwrap() + } + + fn new_from_slice(key: &[u8]) -> Result { + if key.len() != 16 { + return Err(InvalidLength); + } + let key = [ + u32::from_le_bytes(key[0..4].try_into().unwrap()), + u32::from_le_bytes(key[4..8].try_into().unwrap()), + u32::from_le_bytes(key[8..12].try_into().unwrap()), + u32::from_le_bytes(key[12..16].try_into().unwrap()), + ]; + Ok(Xtea { k: key }) + } +} + +impl fmt::Debug for Xtea { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("XTEA { ... }") + } +} + +impl AlgorithmName for Xtea { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("XTEA") + } +} + +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl Drop for Xtea { + fn drop(&mut self) { + self.k.zeroize(); + } +} + +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl ZeroizeOnDrop for Xtea {} + +cipher::impl_simple_block_encdec!( + Xtea, U8, cipher, block, + encrypt: { + let v = block.get_in(); + let mut v0 = u32::from_le_bytes(v[0..4].try_into().unwrap()); + let mut v1 = u32::from_le_bytes(v[4..8].try_into().unwrap()); + let mut sum = 0u32; + + // Use 4 loops as otherwise unrolling will not be performed by default + for _ in 0..8 { + v0 = v0.wrapping_add((((v1 << 4) ^ (v1 >> 5)).wrapping_add(v1)) ^ sum.wrapping_add(cipher.k[(sum & 3) as usize])); + sum = sum.wrapping_add(DELTA); + v1 = v1.wrapping_add((((v0 << 4) ^ (v0 >> 5)).wrapping_add(v0)) ^ sum.wrapping_add(cipher.k[((sum >> 11) & 3) as usize])); + } + for _ in 0..8 { + v0 = v0.wrapping_add((((v1 << 4) ^ (v1 >> 5)).wrapping_add(v1)) ^ sum.wrapping_add(cipher.k[(sum & 3) as usize])); + sum = sum.wrapping_add(DELTA); + v1 = v1.wrapping_add((((v0 << 4) ^ (v0 >> 5)).wrapping_add(v0)) ^ sum.wrapping_add(cipher.k[((sum >> 11) & 3) as usize])); + } + for _ in 0..8 { + v0 = v0.wrapping_add((((v1 << 4) ^ (v1 >> 5)).wrapping_add(v1)) ^ sum.wrapping_add(cipher.k[(sum & 3) as usize])); + sum = sum.wrapping_add(DELTA); + v1 = v1.wrapping_add((((v0 << 4) ^ (v0 >> 5)).wrapping_add(v0)) ^ sum.wrapping_add(cipher.k[((sum >> 11) & 3) as usize])); + } + for _ in 0..8 { + v0 = v0.wrapping_add((((v1 << 4) ^ (v1 >> 5)).wrapping_add(v1)) ^ sum.wrapping_add(cipher.k[(sum & 3) as usize])); + sum = sum.wrapping_add(DELTA); + v1 = v1.wrapping_add((((v0 << 4) ^ (v0 >> 5)).wrapping_add(v0)) ^ sum.wrapping_add(cipher.k[((sum >> 11) & 3) as usize])); + } + + let v = block.get_out(); + v[0..4].copy_from_slice(&v0.to_le_bytes()); + v[4..8].copy_from_slice(&v1.to_le_bytes()); + } + decrypt: { + let v = block.get_in(); + let mut v0 = u32::from_le_bytes(v[0..4].try_into().unwrap()); + let mut v1 = u32::from_le_bytes(v[4..8].try_into().unwrap()); + let mut sum = DELTA.wrapping_mul(ROUNDS as u32); + + // Same as encrypt, just in reverse + for _ in 0..8 { + v1 = v1.wrapping_sub((((v0 << 4) ^ (v0 >> 5)).wrapping_add(v0)) ^ sum.wrapping_add(cipher.k[((sum >> 11) & 3) as usize])); + sum = sum.wrapping_sub(DELTA); + v0 = v0.wrapping_sub((((v1 << 4) ^ (v1 >> 5)).wrapping_add(v1)) ^ sum.wrapping_add(cipher.k[(sum & 3) as usize])); + } + for _ in 0..8 { + v1 = v1.wrapping_sub((((v0 << 4) ^ (v0 >> 5)).wrapping_add(v0)) ^ sum.wrapping_add(cipher.k[((sum >> 11) & 3) as usize])); + sum = sum.wrapping_sub(DELTA); + v0 = v0.wrapping_sub((((v1 << 4) ^ (v1 >> 5)).wrapping_add(v1)) ^ sum.wrapping_add(cipher.k[(sum & 3) as usize])); + } + for _ in 0..8 { + v1 = v1.wrapping_sub((((v0 << 4) ^ (v0 >> 5)).wrapping_add(v0)) ^ sum.wrapping_add(cipher.k[((sum >> 11) & 3) as usize])); + sum = sum.wrapping_sub(DELTA); + v0 = v0.wrapping_sub((((v1 << 4) ^ (v1 >> 5)).wrapping_add(v1)) ^ sum.wrapping_add(cipher.k[(sum & 3) as usize])); + } + for _ in 0..8 { + v1 = v1.wrapping_sub((((v0 << 4) ^ (v0 >> 5)).wrapping_add(v0)) ^ sum.wrapping_add(cipher.k[((sum >> 11) & 3) as usize])); + sum = sum.wrapping_sub(DELTA); + v0 = v0.wrapping_sub((((v1 << 4) ^ (v1 >> 5)).wrapping_add(v1)) ^ sum.wrapping_add(cipher.k[(sum & 3) as usize])); + } + + let v = block.get_out(); + v[0..4].copy_from_slice(&v0.to_le_bytes()); + v[4..8].copy_from_slice(&v1.to_le_bytes()); + } +); diff --git a/xtea/tests/mod.rs b/xtea/tests/mod.rs new file mode 100644 index 00000000..85922ab4 --- /dev/null +++ b/xtea/tests/mod.rs @@ -0,0 +1,18 @@ +use cipher::{array::Array, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; +use xtea::Xtea; + +#[test] +fn xtea() { + // https://web.archive.org/web/20231115163347/https://asecuritysite.com/encryption/xtea + let key = b"0123456789012345"; + let plaintext = b"ABCDEFGH"; + let ciphertext = [0xea, 0x0c, 0x3d, 0x7c, 0x1c, 0x22, 0x55, 0x7f]; + let cipher = Xtea::new_from_slice(key).unwrap(); + + let mut block = Array(*plaintext); + cipher.encrypt_block(&mut block); + assert_eq!(ciphertext, block.as_slice()); + + cipher.decrypt_block(&mut block); + assert_eq!(plaintext, block.as_slice()); +}