From bcf969825cdb0ff6857b084cbdfd41e438331717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Tue, 23 Nov 2021 20:33:25 +0300 Subject: [PATCH] update crates to digest v0.10 --- .github/workflows/fsb.yml | 5 +- .../workflows/{ripemd160.yml => ripemd.yml} | 6 +- .github/workflows/ripemd256.yml | 58 - .github/workflows/ripemd320.yml | 57 - .github/workflows/sha2.yml | 15 +- Cargo.lock | 154 +- Cargo.toml | 10 +- README.md | 209 +- blake2/CHANGELOG.md | 6 + blake2/Cargo.toml | 13 +- blake2/examples/blake2b_sum.rs | 47 - blake2/examples/blake2s_sum.rs | 47 - blake2/src/blake2.rs | 414 -- blake2/src/blake2b.rs | 18 - blake2/src/blake2s.rs | 18 - blake2/src/lib.rs | 146 +- blake2/src/macros.rs | 371 ++ blake2/tests/data/blake2b/fixed.blb | Bin 182 -> 178 bytes blake2/tests/data/blake2b/mac.blb | Bin 66318 -> 50313 bytes blake2/tests/data/blake2b/variable.blb | Bin 53 -> 47 bytes blake2/tests/data/blake2s/mac.blb | Bin 49870 -> 41833 bytes blake2/tests/data/blake2s/variable.blb | Bin 40 -> 34 bytes blake2/tests/lib.rs | 15 +- blake2/tests/mac.rs | 8 +- blake2/tests/persona.rs | 41 +- fsb/CHANGELOG.md | 6 + fsb/Cargo.toml | 14 +- {ripemd160 => fsb}/LICENSE-APACHE | 0 {ripemd160 => fsb}/LICENSE-MIT | 4 +- fsb/README.md | 2 +- fsb/benches/fsb160.rs | 4 + fsb/benches/fsb224.rs | 4 + fsb/benches/fsb256.rs | 4 + fsb/benches/fsb384.rs | 4 + fsb/benches/fsb512.rs | 4 + fsb/src/lib.rs | 49 +- fsb/src/macros.rs | 207 +- fsb/tests/data/fsb160.blb | Bin 147 -> 141 bytes fsb/tests/data/fsb224.blb | Bin 171 -> 165 bytes fsb/tests/data/fsb256.blb | Bin 183 -> 177 bytes fsb/tests/data/fsb384.blb | Bin 231 -> 225 bytes fsb/tests/data/fsb512.blb | Bin 279 -> 276 bytes gost94/CHANGELOG.md | 6 + gost94/Cargo.toml | 8 +- gost94/examples/gost94_cryptopro_sum.rs | 47 - gost94/examples/gost94_test_sum.rs | 47 - gost94/src/cryptopro.rs | 12 - gost94/src/{gost94.rs => gost94_core.rs} | 152 +- gost94/src/lib.rs | 38 +- gost94/src/macros.rs | 48 - gost94/src/params.rs | 70 + gost94/src/s2015.rs | 12 - gost94/src/test_param.rs | 12 - gost94/tests/data/cryptopro.blb | Bin 627 -> 622 bytes gost94/tests/data/test.blb | Bin 627 -> 622 bytes groestl/CHANGELOG.md | 6 + groestl/Cargo.toml | 8 +- groestl/LICENSE-MIT | 2 +- groestl/src/compress1024.rs | 99 + groestl/src/compress512.rs | 83 + groestl/src/consts.rs | 55 - groestl/src/groestl.rs | 76 - groestl/src/lib.rs | 228 +- groestl/src/macros.rs | 95 - groestl/src/matrix.rs | 87 - groestl/src/state.rs | 293 -- groestl/src/table.rs | 11 + groestl/tests/data/groestl224.blb | Bin 40327 -> 40513 bytes groestl/tests/data/groestl256.blb | Bin 41351 -> 41537 bytes groestl/tests/data/groestl384.blb | Bin 45447 -> 45633 bytes groestl/tests/data/groestl512.blb | Bin 49543 -> 49985 bytes k12/CHANGELOG.md | 6 + k12/Cargo.toml | 6 +- k12/src/lib.rs | 26 +- k12/tests/lib.rs | 20 +- md2/CHANGELOG.md | 6 + md2/Cargo.toml | 8 +- md2/examples/md2sum.rs | 39 - md2/src/lib.rs | 128 +- md2/tests/data/md2.blb | Bin 147 -> 141 bytes md4/CHANGELOG.md | 6 + md4/Cargo.toml | 8 +- md4/examples/md4sum.rs | 47 - md4/src/lib.rs | 247 +- md4/tests/data/md4.blb | Bin 441 -> 436 bytes md5/CHANGELOG.md | 6 + md5/Cargo.toml | 10 +- md5/examples/md5sum.rs | 47 - md5/src/{utils.rs => compress.rs} | 27 +- md5/src/consts.rs | 21 - md5/src/lib.rs | 141 +- md5/tests/data/md5.blb | Bin 3286 -> 3271 bytes ripemd/CHANGELOG.md | 12 + {ripemd320 => ripemd}/Cargo.toml | 16 +- {ripemd256 => ripemd}/LICENSE-APACHE | 0 {ripemd256 => ripemd}/LICENSE-MIT | 4 +- {ripemd160 => ripemd}/README.md | 6 +- ripemd/benches/ripemd160.rs | 4 + ripemd/benches/ripemd320.rs | 4 + ripemd160/src/block.rs => ripemd/src/c160.rs | 7 +- ripemd256/src/block.rs => ripemd/src/c256.rs | 7 +- ripemd320/src/block.rs => ripemd/src/c320.rs | 7 +- ripemd/src/lib.rs | 299 ++ ripemd/tests/data/ripemd160.blb | Bin 0 -> 234 bytes ripemd/tests/data/ripemd256.blb | Bin 0 -> 516 bytes ripemd/tests/data/ripemd320.blb | Bin 0 -> 502 bytes ripemd/tests/lib.rs | 32 + ripemd160/CHANGELOG.md | 50 - ripemd160/Cargo.toml | 25 - ripemd160/benches/lib.rs | 4 - ripemd160/examples/ripemd160sum.rs | 47 - ripemd160/src/lib.rs | 101 - ripemd160/tests/data/one_million_a.bin | 1 - ripemd160/tests/data/ripemd160.blb | 1 - ripemd160/tests/lib.rs | 18 - ripemd256/.gitignore | 2 - ripemd256/Cargo.toml | 25 - ripemd256/README.md | 31 - ripemd256/examples/ripemd256sum.rs | 47 - ripemd256/src/lib.rs | 96 - ripemd256/tests/lib.rs | 53 - ripemd320/CHANGELOG.md | 25 - ripemd320/LICENSE-APACHE | 201 - ripemd320/LICENSE-MIT | 27 - ripemd320/README.md | 56 - ripemd320/benches/lib.rs | 4 - ripemd320/examples/ripemd320sum.rs | 47 - ripemd320/src/lib.rs | 102 - ripemd320/tests/data/one_million_a.bin | 1 - ripemd320/tests/data/ripemd320.blb | Bin 508 -> 0 bytes ripemd320/tests/lib.rs | 19 - sha1/CHANGELOG.md | 6 + sha1/Cargo.toml | 11 +- sha1/examples/sha1sum.rs | 47 - sha1/src/compress.rs | 15 +- sha1/src/compress/soft.rs | 21 +- sha1/src/consts.rs | 12 - sha1/src/lib.rs | 120 +- sha1/tests/data/sha1.blb | Bin 240 -> 234 bytes sha2/CHANGELOG.md | 6 + sha2/Cargo.toml | 8 +- sha2/examples/sha256sum.rs | 47 - sha2/examples/sha512sum.rs | 47 - sha2/src/lib.rs | 178 +- sha2/src/sha256.rs | 148 +- sha2/src/sha512.rs | 235 +- sha2/tests/data/sha224.blb | Bin 184 -> 178 bytes sha2/tests/data/sha256.blb | Bin 196 -> 190 bytes sha2/tests/data/sha384.blb | Bin 244 -> 238 bytes sha2/tests/data/sha512.blb | Bin 292 -> 289 bytes sha2/tests/data/sha512_224.blb | Bin 184 -> 178 bytes sha2/tests/data/sha512_256.blb | Bin 196 -> 190 bytes sha2/tests/lib.rs | 2 +- sha3/CHANGELOG.md | 5 + sha3/Cargo.toml | 8 +- sha3/examples/sha3_256sum.rs | 47 - sha3/examples/sha3_512sum.rs | 47 - sha3/src/lib.rs | 120 +- sha3/src/macros.rs | 214 +- sha3/src/paddings.rs | 33 - sha3/src/reader.rs | 66 - sha3/tests/data/keccak_224.blb | Bin 37 -> 31 bytes sha3/tests/data/keccak_256.blb | Bin 174 -> 169 bytes sha3/tests/data/keccak_256_full.blb | Bin 3395 -> 3403 bytes sha3/tests/data/keccak_384.blb | Bin 57 -> 51 bytes sha3/tests/data/keccak_512.blb | Bin 73 -> 68 bytes sha3/tests/data/sha3_224.blb | Bin 40327 -> 40513 bytes sha3/tests/data/sha3_256.blb | Bin 41351 -> 41537 bytes sha3/tests/data/sha3_384.blb | Bin 45397 -> 45583 bytes sha3/tests/data/sha3_512.blb | Bin 49477 -> 49918 bytes sha3/tests/data/shake128.blb | Bin 164743 -> 164673 bytes sha3/tests/data/shake256.blb | Bin 164743 -> 164673 bytes shabal/CHANGELOG.md | 6 + shabal/Cargo.toml | 8 +- shabal/examples/shabal256sum.rs | 47 - shabal/examples/shabal512sum.rs | 47 - shabal/src/consts.rs | 360 +- shabal/src/lib.rs | 113 +- shabal/src/shabal.rs | 513 -- shabal/src/state.rs | 226 + shabal/tests/data/shabal192.blb | Bin 2048 -> 2050 bytes shabal/tests/data/shabal224.blb | Bin 2168 -> 2170 bytes shabal/tests/data/shabal256.blb | Bin 2288 -> 2290 bytes shabal/tests/data/shabal384.blb | Bin 2768 -> 2770 bytes shabal/tests/data/shabal512.blb | Bin 3248 -> 3280 bytes sm3/CHANGELOG.md | 6 + sm3/Cargo.toml | 10 +- sm3/LICENSE-MIT | 2 +- sm3/examples/sm3sum.rs | 47 - sm3/src/{sm3.rs => compress.rs} | 74 +- sm3/src/consts.rs | 4 +- sm3/src/lib.rs | 99 +- sm3/tests/data/sm3.blb | Bin 253 -> 308 bytes sm3/tests/data/sm3_one_million_a.bin | 2 - sm3/tests/lib.rs | 30 +- streebog/CHANGELOG.md | 6 + streebog/Cargo.toml | 8 +- streebog/examples/streebog256sum.rs | 47 - streebog/examples/streebog512sum.rs | 47 - streebog/src/lib.rs | 43 +- streebog/src/streebog.rs | 170 +- streebog/src/streebog256.rs | 87 + streebog/src/streebog512.rs | 82 + streebog/tests/data/streebog256.blb | Bin 828 -> 827 bytes streebog/tests/data/streebog512.blb | Bin 1052 -> 1058 bytes tiger/CHANGELOG.md | 9 + tiger/Cargo.toml | 10 +- tiger/LICENSE-MIT | 1 + tiger/src/compress.rs | 72 + tiger/src/lib.rs | 1363 +----- tiger/src/tables.rs | 1035 +++++ tiger/tests/data/tiger.blb | Bin 0 -> 881 bytes tiger/tests/data/tiger2.blb | Bin 0 -> 165 bytes tiger/tests/mod.rs | 4 + whirlpool/CHANGELOG.md | 6 + whirlpool/Cargo.toml | 10 +- whirlpool/examples/whirlpool_sum.rs | 47 - whirlpool/src/compress.rs | 60 + whirlpool/src/consts.rs | 4121 ++++++++--------- whirlpool/src/lib.rs | 227 +- whirlpool/src/utils.rs | 50 - whirlpool/tests/data/whirlpool.blb | Bin 1430 -> 1442 bytes 222 files changed, 6970 insertions(+), 9207 deletions(-) rename .github/workflows/{ripemd160.yml => ripemd.yml} (94%) delete mode 100644 .github/workflows/ripemd256.yml delete mode 100644 .github/workflows/ripemd320.yml delete mode 100644 blake2/examples/blake2b_sum.rs delete mode 100644 blake2/examples/blake2s_sum.rs delete mode 100644 blake2/src/blake2.rs delete mode 100644 blake2/src/blake2b.rs delete mode 100644 blake2/src/blake2s.rs create mode 100644 blake2/src/macros.rs rename {ripemd160 => fsb}/LICENSE-APACHE (100%) rename {ripemd160 => fsb}/LICENSE-MIT (89%) create mode 100644 fsb/benches/fsb160.rs create mode 100644 fsb/benches/fsb224.rs create mode 100644 fsb/benches/fsb256.rs create mode 100644 fsb/benches/fsb384.rs create mode 100644 fsb/benches/fsb512.rs delete mode 100644 gost94/examples/gost94_cryptopro_sum.rs delete mode 100644 gost94/examples/gost94_test_sum.rs delete mode 100644 gost94/src/cryptopro.rs rename gost94/src/{gost94.rs => gost94_core.rs} (63%) delete mode 100644 gost94/src/macros.rs create mode 100644 gost94/src/params.rs delete mode 100644 gost94/src/s2015.rs delete mode 100644 gost94/src/test_param.rs create mode 100644 groestl/src/compress1024.rs create mode 100644 groestl/src/compress512.rs delete mode 100644 groestl/src/consts.rs delete mode 100644 groestl/src/groestl.rs mode change 100755 => 100644 groestl/src/lib.rs delete mode 100644 groestl/src/macros.rs delete mode 100644 groestl/src/matrix.rs delete mode 100644 groestl/src/state.rs create mode 100644 groestl/src/table.rs delete mode 100644 md2/examples/md2sum.rs delete mode 100644 md4/examples/md4sum.rs delete mode 100644 md5/examples/md5sum.rs rename md5/src/{utils.rs => compress.rs} (79%) delete mode 100644 md5/src/consts.rs create mode 100644 ripemd/CHANGELOG.md rename {ripemd320 => ripemd}/Cargo.toml (56%) rename {ripemd256 => ripemd}/LICENSE-APACHE (100%) rename {ripemd256 => ripemd}/LICENSE-MIT (88%) rename {ripemd160 => ripemd}/README.md (93%) create mode 100644 ripemd/benches/ripemd160.rs create mode 100644 ripemd/benches/ripemd320.rs rename ripemd160/src/block.rs => ripemd/src/c160.rs (98%) rename ripemd256/src/block.rs => ripemd/src/c256.rs (98%) rename ripemd320/src/block.rs => ripemd/src/c320.rs (98%) create mode 100644 ripemd/src/lib.rs create mode 100644 ripemd/tests/data/ripemd160.blb create mode 100644 ripemd/tests/data/ripemd256.blb create mode 100644 ripemd/tests/data/ripemd320.blb create mode 100644 ripemd/tests/lib.rs delete mode 100644 ripemd160/CHANGELOG.md delete mode 100644 ripemd160/Cargo.toml delete mode 100644 ripemd160/benches/lib.rs delete mode 100644 ripemd160/examples/ripemd160sum.rs delete mode 100644 ripemd160/src/lib.rs delete mode 100644 ripemd160/tests/data/one_million_a.bin delete mode 100644 ripemd160/tests/data/ripemd160.blb delete mode 100644 ripemd160/tests/lib.rs delete mode 100644 ripemd256/.gitignore delete mode 100644 ripemd256/Cargo.toml delete mode 100644 ripemd256/README.md delete mode 100644 ripemd256/examples/ripemd256sum.rs delete mode 100644 ripemd256/src/lib.rs delete mode 100644 ripemd256/tests/lib.rs delete mode 100644 ripemd320/CHANGELOG.md delete mode 100644 ripemd320/LICENSE-APACHE delete mode 100644 ripemd320/LICENSE-MIT delete mode 100644 ripemd320/README.md delete mode 100644 ripemd320/benches/lib.rs delete mode 100644 ripemd320/examples/ripemd320sum.rs delete mode 100644 ripemd320/src/lib.rs delete mode 100644 ripemd320/tests/data/one_million_a.bin delete mode 100644 ripemd320/tests/data/ripemd320.blb delete mode 100644 ripemd320/tests/lib.rs delete mode 100644 sha1/examples/sha1sum.rs delete mode 100644 sha1/src/consts.rs delete mode 100644 sha2/examples/sha256sum.rs delete mode 100644 sha2/examples/sha512sum.rs delete mode 100644 sha3/examples/sha3_256sum.rs delete mode 100644 sha3/examples/sha3_512sum.rs delete mode 100644 sha3/src/paddings.rs delete mode 100644 sha3/src/reader.rs delete mode 100644 shabal/examples/shabal256sum.rs delete mode 100644 shabal/examples/shabal512sum.rs delete mode 100644 shabal/src/shabal.rs create mode 100644 shabal/src/state.rs delete mode 100644 sm3/examples/sm3sum.rs rename sm3/src/{sm3.rs => compress.rs} (81%) delete mode 100644 sm3/tests/data/sm3_one_million_a.bin delete mode 100644 streebog/examples/streebog256sum.rs delete mode 100644 streebog/examples/streebog512sum.rs create mode 100644 streebog/src/streebog256.rs create mode 100644 streebog/src/streebog512.rs create mode 100644 tiger/src/compress.rs create mode 100644 tiger/src/tables.rs create mode 100644 tiger/tests/data/tiger.blb create mode 100644 tiger/tests/data/tiger2.blb create mode 100644 tiger/tests/mod.rs delete mode 100644 whirlpool/examples/whirlpool_sum.rs create mode 100644 whirlpool/src/compress.rs delete mode 100644 whirlpool/src/utils.rs diff --git a/.github/workflows/fsb.yml b/.github/workflows/fsb.yml index f8a36ffa4..737f53401 100644 --- a/.github/workflows/fsb.yml +++ b/.github/workflows/fsb.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.47.0 # MSRV + - 1.41.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -42,7 +42,7 @@ jobs: strategy: matrix: rust: - - 1.47.0 # MSRV + - 1.41.0 # MSRV - stable steps: - uses: actions/checkout@v1 @@ -54,5 +54,4 @@ jobs: - run: cargo check --all-features - run: cargo test --no-default-features - run: cargo test - - run: cargo test --features asm - run: cargo test --all-features diff --git a/.github/workflows/ripemd160.yml b/.github/workflows/ripemd.yml similarity index 94% rename from .github/workflows/ripemd160.yml rename to .github/workflows/ripemd.yml index 7d78d12d6..cf0ee5ff6 100644 --- a/.github/workflows/ripemd160.yml +++ b/.github/workflows/ripemd.yml @@ -1,16 +1,16 @@ -name: ripemd160 +name: ripemd on: pull_request: paths: - - "ripemd160/**" + - "ripemd/**" - "Cargo.*" push: branches: master defaults: run: - working-directory: ripemd160 + working-directory: ripemd env: CARGO_INCREMENTAL: 0 diff --git a/.github/workflows/ripemd256.yml b/.github/workflows/ripemd256.yml deleted file mode 100644 index 324f85b5e..000000000 --- a/.github/workflows/ripemd256.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: ripemd256 - -on: - pull_request: - paths: - - "ripemd256/**" - - "Cargo.*" - push: - branches: master - -defaults: - run: - working-directory: ripemd256 - -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} - - test: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - override: true - - run: cargo check --all-features - - run: cargo test --no-default-features - - run: cargo test - - run: cargo test --all-features - diff --git a/.github/workflows/ripemd320.yml b/.github/workflows/ripemd320.yml deleted file mode 100644 index dbd541b01..000000000 --- a/.github/workflows/ripemd320.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: ripemd320 - -on: - pull_request: - paths: - - "ripemd320/**" - - "Cargo.*" - push: - branches: master - -defaults: - run: - working-directory: ripemd320 - -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} - - test: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - override: true - - run: cargo check --all-features - - run: cargo test --no-default-features - - run: cargo test - - run: cargo test --all-features diff --git a/.github/workflows/sha2.yml b/.github/workflows/sha2.yml index 75ae8d9a6..0e2e34d70 100644 --- a/.github/workflows/sha2.yml +++ b/.github/workflows/sha2.yml @@ -129,6 +129,10 @@ jobs: rust: stable runs-on: ubuntu-latest + defaults: + run: + # Cross mounts only current package, i.e. by default it ignores workspace's Cargo.toml + working-directory: . steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 @@ -137,6 +141,11 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - run: cargo install cross - - run: cross test --target ${{ matrix.target }} --release - - run: cross test --target ${{ matrix.target }} --release --features asm + - name: Install precompiled cross + run: | + export URL=$(curl -s https://api.github.com/repos/rust-embedded/cross/releases/latest | jq -r '.assets[] | select(.name | contains("x86_64-unknown-linux-gnu.tar.gz")) | .browser_download_url') + wget -O /tmp/binaries.tar.gz $URL + tar -C /tmp -xzf /tmp/binaries.tar.gz + mv /tmp/cross ~/.cargo/bin + - run: cross test --package sha2 --target ${{ matrix.target }} --release + - run: cross test --package sha2 --target ${{ matrix.target }} --release --features asm diff --git a/Cargo.lock b/Cargo.lock index cba495698..fd7f57c1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,50 +4,31 @@ version = 3 [[package]] name = "blake2" -version = "0.9.2" +version = "0.10.0" dependencies = [ - "crypto-mac", "digest", "hex-literal", - "opaque-debug", ] [[package]] name = "blobby" -version = "0.1.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe5f8c2940b65859ece4b3b2ba02d2b12c87cab455fd42dee2556a187bb2cf6" -dependencies = [ - "byteorder", -] +checksum = "fc52553543ecb104069b0ff9e0fcc5c739ad16202935528a112d974e8f1a4ee8" [[package]] name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +version = "0.10.0" +source = "git+https://github.com/RustCrypto/utils?branch=block-buffer/v0.10#c47a851d747fa79df02567ab4d9faf40a1093855" dependencies = [ - "block-padding", "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "cc" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" @@ -65,34 +46,31 @@ dependencies = [ ] [[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +name = "crypto-common" +version = "0.1.0" +source = "git+https://github.com/RustCrypto/traits/?branch=digest/v0.10#6391acdb926578f0c0f7e4d4e0618c42f361aebf" dependencies = [ - "blobby", "generic-array", - "subtle", ] [[package]] name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +version = "0.10.0" +source = "git+https://github.com/RustCrypto/traits/?branch=digest/v0.10#6391acdb926578f0c0f7e4d4e0618c42f361aebf" dependencies = [ "blobby", + "block-buffer", + "crypto-common", "generic-array", + "subtle", ] [[package]] name = "fsb" -version = "0.0.2" +version = "0.1.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", "whirlpool", ] @@ -108,22 +86,18 @@ dependencies = [ [[package]] name = "gost94" -version = "0.9.1" +version = "0.10.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", ] [[package]] name = "groestl" -version = "0.9.0" +version = "0.10.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", ] [[package]] @@ -147,7 +121,7 @@ dependencies = [ [[package]] name = "k12" -version = "0.1.0" +version = "0.2.0" dependencies = [ "digest", "hex-literal", @@ -161,56 +135,44 @@ checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" [[package]] name = "libc" -version = "0.2.101" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" [[package]] name = "md-5" -version = "0.9.1" +version = "0.10.0" dependencies = [ - "block-buffer", "digest", "hex-literal", "md5-asm", - "opaque-debug", ] [[package]] name = "md2" -version = "0.9.0" +version = "0.10.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", ] [[package]] name = "md4" -version = "0.9.0" +version = "0.10.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", ] [[package]] name = "md5-asm" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b47e5a1261ecd6ba951d1ad392534743310e513ef1e2609023368798829f33e" +checksum = "73b9a6f25ec11ea27e22d7fc8beafda909da44ece95f63e94f1eeb23d19bb5c7" dependencies = [ "cc", ] -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -218,45 +180,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] -name = "ripemd160" -version = "0.9.1" -dependencies = [ - "block-buffer", - "digest", - "hex-literal", - "opaque-debug", -] - -[[package]] -name = "ripemd256" +name = "ripemd" version = "0.1.0" dependencies = [ - "block-buffer", - "digest", - "hex-literal", - "opaque-debug", -] - -[[package]] -name = "ripemd320" -version = "0.9.0" -dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", ] [[package]] name = "sha-1" -version = "0.9.8" +version = "0.10.0" dependencies = [ - "block-buffer", "cfg-if", "cpufeatures", "digest", "hex-literal", - "opaque-debug", "sha1-asm", ] @@ -271,14 +209,12 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.8" +version = "0.10.0" dependencies = [ - "block-buffer", "cfg-if", "cpufeatures", "digest", "hex-literal", - "opaque-debug", "sha2-asm", ] @@ -293,43 +229,35 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.0" dependencies = [ - "block-buffer", "digest", "hex-literal", "keccak", - "opaque-debug", ] [[package]] name = "shabal" -version = "0.3.0" +version = "0.4.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", ] [[package]] name = "sm3" -version = "0.3.0" +version = "0.4.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", ] [[package]] name = "streebog" -version = "0.9.2" +version = "0.10.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", ] [[package]] @@ -340,19 +268,17 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "tiger" -version = "0.1.0" +version = "0.2.0" dependencies = [ - "block-buffer", - "byteorder", "digest", "hex-literal", ] [[package]] name = "typenum" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "version_check" @@ -362,20 +288,18 @@ checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "whirlpool" -version = "0.9.0" +version = "0.10.0" dependencies = [ - "block-buffer", "digest", "hex-literal", - "opaque-debug", "whirlpool-asm", ] [[package]] name = "whirlpool-asm" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbb23be8b0dec6fafef14563c42ec98bbfc33f2a97ed5bc99cd8b50ea5c68097" +checksum = "4b0930846e800a97c78fd09a494b25d1f0780be9face03b7a05151e3104a8284" dependencies = [ "cc", ] diff --git a/Cargo.toml b/Cargo.toml index 00547e603..91c900778 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,14 @@ [workspace] members = [ - "fsb", "blake2", + "fsb", "gost94", "groestl", "k12", "md2", "md4", "md5", - "ripemd160", - "ripemd256", - "ripemd320", + "ripemd", "sha1", "sha2", "sha3", @@ -23,3 +21,7 @@ members = [ [profile.dev] opt-level = 2 + +[patch.crates-io] +digest = { git = "https://github.com/RustCrypto/traits/", branch = "digest/v0.10" } +block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "block-buffer/v0.10" } diff --git a/README.md b/README.md index c2b1fb186..79f3ec283 100644 --- a/README.md +++ b/README.md @@ -1,99 +1,89 @@ -# RustCrypto: hashes [![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] +# RustCrypto: Hashes [![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] Collection of [cryptographic hash functions][1] written in pure Rust. -All algorithms reside in the separate crates and implemented using traits from -[`digest`](https://docs.rs/digest/) crate. Additionally all crates do not -require the standard library (i.e. `no_std` capable) and can be easily used for -bare-metal or WebAssembly programming. - -## Supported algorithms -**Note:** For new applications, or where compatibility with other existing -standards is not a primary concern, we strongly recommend to use either -BLAKE2, SHA-2 or SHA-3. - -| Name | Algorithm | Crates.io | Documentation | Build Status | [Security] | -|-------------|------------|-----------|---------------|--------------|------------| -| `blake2` | [BLAKE2] | [![crates.io](https://img.shields.io/crates/v/blake2.svg)](https://crates.io/crates/blake2) | [![Documentation](https://docs.rs/blake2/badge.svg)](https://docs.rs/blake2) | [![build](https://github.com/rustcrypto/hashes/workflows/blake2/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:blake2+branch:master) | :green_heart: | -| `fsb` | [FSB] | [![crates.io](https://img.shields.io/crates/v/fsb.svg)](https://crates.io/crates/fsb) | [![Documentation](https://docs.rs/fsb/badge.svg)](https://docs.rs/fsb) | [![build](https://github.com/rustcrypto/hashes/workflows/fsb/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/fsb/actions?query=workflow:fsb+branch:master) | :green_heart: | -| `gost94` | [GOST94] (GOST R 34.11-94) | [![crates.io](https://img.shields.io/crates/v/gost94.svg)](https://crates.io/crates/gost94) | [![Documentation](https://docs.rs/gost94/badge.svg)](https://docs.rs/gost94) | [![build](https://github.com/rustcrypto/hashes/workflows/gost94/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:gost94+branch:master) | :yellow_heart: | -| `groestl` | [Grøstl] (Groestl) | [![crates.io](https://img.shields.io/crates/v/groestl.svg)](https://crates.io/crates/groestl) | [![Documentation](https://docs.rs/groestl/badge.svg)](https://docs.rs/groestl) | [![build](https://github.com/rustcrypto/hashes/workflows/groestl/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:groestl+branch:master) | :green_heart: | -| `k12` | [KangarooTwelve] | [![crates.io](https://img.shields.io/crates/v/k12.svg)](https://crates.io/crates/k12) | [![Documentation](https://docs.rs/k12/badge.svg)](https://docs.rs/k12) | [![build](https://github.com/rustcrypto/hashes/workflows/k12/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:k12+branch:master) | :green_heart: | -| `md2` | [MD2] | [![crates.io](https://img.shields.io/crates/v/md2.svg)](https://crates.io/crates/md2) | [![Documentation](https://docs.rs/md2/badge.svg)](https://docs.rs/md2) | [![build](https://github.com/rustcrypto/hashes/workflows/md2/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:md2+branch:master) | :broken_heart: | -| `md4` | [MD4] | [![crates.io](https://img.shields.io/crates/v/md4.svg)](https://crates.io/crates/md4) | [![Documentation](https://docs.rs/md4/badge.svg)](https://docs.rs/md4) | [![build](https://github.com/rustcrypto/hashes/workflows/md4/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:md4+branch:master) | :broken_heart: | -| `md-5` [:exclamation:] | [MD5] | [![crates.io](https://img.shields.io/crates/v/md-5.svg)](https://crates.io/crates/md-5) | [![Documentation](https://docs.rs/md-5/badge.svg)](https://docs.rs/md-5) | [![build](https://github.com/rustcrypto/hashes/workflows/md5/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:md5+branch:master) | :broken_heart: | -| `ripemd160` | [RIPEMD-160] | [![crates.io](https://img.shields.io/crates/v/ripemd160.svg)](https://crates.io/crates/ripemd160) | [![Documentation](https://docs.rs/ripemd160/badge.svg)](https://docs.rs/ripemd160) | [![build](https://github.com/rustcrypto/hashes/workflows/ripemd160/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:ripemd160+branch:master) | :green_heart: | -| `ripemd256` | [RIPEMD-256] | [![crates.io](https://img.shields.io/crates/v/ripemd256.svg)](https://crates.io/crates/ripemd256) | [![Documentation](https://docs.rs/ripemd256/badge.svg)](https://docs.rs/ripemd256) | [![build](https://github.com/rustcrypto/hashes/workflows/ripemd256/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:ripemd256+branch:master) | :green_heart:* | -| `ripemd320` | [RIPEMD-320] | [![crates.io](https://img.shields.io/crates/v/ripemd320.svg)](https://crates.io/crates/ripemd320) | [![Documentation](https://docs.rs/ripemd320/badge.svg)](https://docs.rs/ripemd320) | [![build](https://github.com/rustcrypto/hashes/workflows/ripemd320/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:ripemd320+branch:master) | :green_heart:* | -| `sha-1` [:exclamation:] | [SHA-1] | [![crates.io](https://img.shields.io/crates/v/sha-1.svg)](https://crates.io/crates/sha-1) | [![Documentation](https://docs.rs/sha-1/badge.svg)](https://docs.rs/sha-1) | [![build](https://github.com/rustcrypto/hashes/workflows/sha1/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:sha1+branch:master) | :broken_heart: | -| `sha2` | [SHA-2] | [![crates.io](https://img.shields.io/crates/v/sha2.svg)](https://crates.io/crates/sha2) | [![Documentation](https://docs.rs/sha2/badge.svg)](https://docs.rs/sha2) | [![build](https://github.com/rustcrypto/hashes/workflows/sha2/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:sha2+branch:master) | :green_heart: | -| `sha3` | [SHA-3] (Keccak) | [![crates.io](https://img.shields.io/crates/v/sha3.svg)](https://crates.io/crates/sha3) | [![Documentation](https://docs.rs/sha3/badge.svg)](https://docs.rs/sha3) | [![build](https://github.com/rustcrypto/hashes/workflows/sha3/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:sha3+branch:master) | :green_heart: | -| `shabal` | [SHABAL] | [![crates.io](https://img.shields.io/crates/v/shabal.svg)](https://crates.io/crates/shabal) | [![Documentation](https://docs.rs/shabal/badge.svg)](https://docs.rs/shabal) | [![build](https://github.com/rustcrypto/hashes/workflows/shabal/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:shabal+branch:master) | :green_heart: | -| `sm3` | [SM3 (OSCCA GM/T 0004-2012)][SM3] | [![crates.io](https://img.shields.io/crates/v/sm3.svg)](https://crates.io/crates/sm3) | [![Documentation](https://docs.rs/sm3/badge.svg)](https://docs.rs/sm3) | [![build](https://github.com/rustcrypto/hashes/workflows/sm3/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:sm3+branch:master) | :green_heart: | -| `streebog` | [Streebog] (GOST R 34.11-2012) | [![crates.io](https://img.shields.io/crates/v/streebog.svg)](https://crates.io/crates/streebog) | [![Documentation](https://docs.rs/streebog/badge.svg)](https://docs.rs/streebog) | [![build](https://github.com/rustcrypto/hashes/workflows/streebog/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:streebog+branch:master) | :yellow_heart: | -| `tiger` | [Tiger] | [![crates.io](https://img.shields.io/crates/v/tiger.svg)](https://crates.io/crates/tiger) | [![Documentation](https://docs.rs/tiger/badge.svg)](https://docs.rs/tiger) | [![build](https://github.com/rustcrypto/hashes/workflows/tiger/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:tiger+branch:master) | :green_heart: | -| `whirlpool` | [Whirlpool] | [![crates.io](https://img.shields.io/crates/v/whirlpool.svg)](https://crates.io/crates/whirlpool) | [![Documentation](https://docs.rs/whirlpool/badge.svg)](https://docs.rs/whirlpool) | [![build](https://github.com/rustcrypto/hashes/workflows/whirlpool/badge.svg?branch=master&event=push)](https://github.com/RustCrypto/hashes/actions?query=workflow:whirlpool+branch:master) | :green_heart: | - -NOTE: the [BLAKE3 crate](https://github.com/BLAKE3-team/BLAKE3) implements the `digest` (and `crypto-mac`) traits used by the rest of the hashes in this repository, but is maintained by the BLAKE3 team. - -\* RIPEMD-256 provides only the same security as RIPEMD-128, and RIPEMD-320 provides only the same security as RIPEMD-160 +All algorithms reside in the separate crates and implemented using traits from [`digest`](https://docs.rs/digest/) crate. +Additionally all crates do not require the standard library (i.e. `no_std` capable) and can be easily used for bare-metal or WebAssembly programming. + +## Supported Algorithms + +**Note:** For new applications, or where compatibility with other existing standards is not a primary concern, we strongly recommend to use either BLAKE2, SHA-2 or SHA-3. + +| Algorithm | Crate | Crates.io | Documentation | MSRV | [Security] | +|-----------|-------|:---------:|:-------------:|:----:|:----------:| +| [BLAKE2] | `blake2` | [![crates.io](https://img.shields.io/crates/v/blake2.svg)](https://crates.io/crates/blake2) | [![Documentation](https://docs.rs/blake2/badge.svg)](https://docs.rs/blake2) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [FSB] | `fsb` | [![crates.io](https://img.shields.io/crates/v/fsb.svg)](https://crates.io/crates/fsb) | [![Documentation](https://docs.rs/fsb/badge.svg)](https://docs.rs/fsb) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [GOST R 34.11-94][GOST94] | `gost94` | [![crates.io](https://img.shields.io/crates/v/gost94.svg)](https://crates.io/crates/gost94) | [![Documentation](https://docs.rs/gost94/badge.svg)](https://docs.rs/gost94) | ![Minimum Supported Rust Version][msrv-1.41] | :yellow_heart: | +| [Grøstl] (Groestl) | `groestl` | [![crates.io](https://img.shields.io/crates/v/groestl.svg)](https://crates.io/crates/groestl) | [![Documentation](https://docs.rs/groestl/badge.svg)](https://docs.rs/groestl) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [KangarooTwelve] | `k12` | [![crates.io](https://img.shields.io/crates/v/k12.svg)](https://crates.io/crates/k12) | [![Documentation](https://docs.rs/k12/badge.svg)](https://docs.rs/k12) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [MD2] | `md2` | [![crates.io](https://img.shields.io/crates/v/md2.svg)](https://crates.io/crates/md2) | [![Documentation](https://docs.rs/md2/badge.svg)](https://docs.rs/md2) | ![Minimum Supported Rust Version][msrv-1.41] | :broken_heart: | +| [MD4] | `md4` | [![crates.io](https://img.shields.io/crates/v/md4.svg)](https://crates.io/crates/md4) | [![Documentation](https://docs.rs/md4/badge.svg)](https://docs.rs/md4) | ![Minimum Supported Rust Version][msrv-1.41] | :broken_heart: | +| [MD5] | `md-5` [:exclamation:] | [![crates.io](https://img.shields.io/crates/v/md-5.svg)](https://crates.io/crates/md-5) | [![Documentation](https://docs.rs/md-5/badge.svg)](https://docs.rs/md-5) | ![Minimum Supported Rust Version][msrv-1.41] | :broken_heart: | +| [RIPEMD] | `ripemd` | [![crates.io](https://img.shields.io/crates/v/ripemd.svg)](https://crates.io/crates/ripemd) | [![Documentation](https://docs.rs/ripemd/badge.svg)](https://docs.rs/ripemd) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [SHA-1] | `sha-1` [:exclamation:] | [![crates.io](https://img.shields.io/crates/v/sha-1.svg)](https://crates.io/crates/sha-1) | [![Documentation](https://docs.rs/sha-1/badge.svg)](https://docs.rs/sha-1) | ![Minimum Supported Rust Version][msrv-1.41] | :broken_heart: | +| [SHA-2] | `sha2` | [![crates.io](https://img.shields.io/crates/v/sha2.svg)](https://crates.io/crates/sha2) | [![Documentation](https://docs.rs/sha2/badge.svg)](https://docs.rs/sha2) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [SHA-3] (Keccak) | `sha3` | [![crates.io](https://img.shields.io/crates/v/sha3.svg)](https://crates.io/crates/sha3) | [![Documentation](https://docs.rs/sha3/badge.svg)](https://docs.rs/sha3) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [SHABAL] | `shabal` | [![crates.io](https://img.shields.io/crates/v/shabal.svg)](https://crates.io/crates/shabal) | [![Documentation](https://docs.rs/shabal/badge.svg)](https://docs.rs/shabal) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [SM3] (OSCCA GM/T 0004-2012) | `sm3` | [![crates.io](https://img.shields.io/crates/v/sm3.svg)](https://crates.io/crates/sm3) | [![Documentation](https://docs.rs/sm3/badge.svg)](https://docs.rs/sm3) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [Streebog] (GOST R 34.11-2012) | `streebog` | [![crates.io](https://img.shields.io/crates/v/streebog.svg)](https://crates.io/crates/streebog) | [![Documentation](https://docs.rs/streebog/badge.svg)](https://docs.rs/streebog) | ![Minimum Supported Rust Version][msrv-1.41] | :yellow_heart: | +| [Tiger] | `tiger` | [![crates.io](https://img.shields.io/crates/v/tiger.svg)](https://crates.io/crates/tiger) | [![Documentation](https://docs.rs/tiger/badge.svg)](https://docs.rs/tiger) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | +| [Whirlpool] | `whirlpool` | [![crates.io](https://img.shields.io/crates/v/whirlpool.svg)](https://crates.io/crates/whirlpool) | [![Documentation](https://docs.rs/whirlpool/badge.svg)](https://docs.rs/whirlpool) | ![Minimum Supported Rust Version][msrv-1.41] | :green_heart: | + +NOTE: the [BLAKE3 crate](https://github.com/BLAKE3-team/BLAKE3) implements the `digest` traits used by the rest of the hashes in this repository, but is maintained by the BLAKE3 team. [Security]: https://en.wikipedia.org/wiki/Hash_function_security_summary [:exclamation:]: #crate-names -### Crate names -Whenever possible crates are published under the the same name as the crate -folder. Owners of `md5` and `sha1` crates declined -([1](https://github.com/stainless-steel/md5/pull/2), -[2](https://github.com/mitsuhiko/rust-sha1/issues/17)) to participate in this -project. This is why crates marked by :exclamation: are published under -`md-5` and `sha-1` names respectively. +### Crate Names + +Whenever possible crates are published under the the same name as the crate folder. +Owners of `md5` and `sha1` crates declined ([1](https://github.com/stainless-steel/md5/pull/2), [2](https://github.com/mitsuhiko/rust-sha1/issues/17)) to participate in this project +Those crates do not implement the [`digest`] traits, so they are not interoperable with the RustCrypto ecosystem. +This is why crates marked by :exclamation: are published under `md-5` and `sha-1` names respectively. ### Security Level Legend -The following describes the security level ratings associated with each -hash function (i.e. algorithms, not the specific implementation): + +The following describes the security level ratings associated with each hash function (i.e. algorithms, not the specific implementation): | Heart | Description | -|----------------|-------------| +|:--------------:|-------------| | :green_heart: | No known successful attacks | | :yellow_heart: | Theoretical break: security lower than claimed | | :broken_heart: | Attack demonstrated in practice: avoid if at all possible | See the [Security] page on Wikipedia for more information. -### Minimum Supported Rust Version (MSRV) -All crates in this repository support Rust 1.21 or higher. In future -minimally supported version of Rust can be changed, but it will be done with -a minor version bump. +### Minimum Supported Rust Version (MSRV) Policy + +MSRV bumps are considered breaking changes and will be performed only with minor version bump. ## Usage -Let us demonstrate how to use crates in this repository using BLAKE2b as an -example. -First add `blake2` crate to your `Cargo.toml`: +Let us demonstrate how to use crates in this repository using SHA-2 as an example. + +First add `sha2` crate to your `Cargo.toml`: ```toml [dependencies] -blake2 = "0.9" +sha2 = "0.10" ``` -Note that crates in this repository have an enabled by default `std` feature. +Note that all crates in this repository have an enabled by default `std` feature. So if you plan to use the crate in `no_std` environments, don't forget to disable it: ```toml [dependencies] -blake2 = { version="0.9", default-features = false } +sha2 = { version = "0.10", default-features = false } ``` -`blake2` and other crates re-export `digest` crate and `Digest` trait for -convenience, so you don't have to add `digest` crate as an explicit dependency. +`sha2` and other crates re-export the `digest` crate and the `Digest` trait for convenience, so you don't have to add `digest` crate as an explicit dependency. Now you can write the following code: -```Rust -use blake2::{Blake2b, Digest}; +```rust +use sha2::{Sha256, Digest}; -let mut hasher = Blake2b::new(); +let mut hasher = Sha256::new(); let data = b"Hello world!"; hasher.update(data); // `update` can be called repeatedly and is generic over `AsRef<[u8]>` @@ -103,64 +93,56 @@ let hash = hasher.finalize(); println!("Result: {:x}", hash); ``` -In this example `hash` has type [`GenericArray`][2], which is a generic -alternative to `[u8; 64]`. +In this example `hash` has type `GenericArray`, which is a generic alternative to `[u8; 32]` defined in the [`generic-array`] crate. -Alternatively you can use chained approach, which is equivalent to the previous -example: +Alternatively, you can use chained approach, which is equivalent to the previous example: -```Rust -use blake2::{Blake2b, Digest}; +```rust +use sha2::{Sha256, Digest}; -let hash = Blake2b::new() +let hash = Sha256::new() .chain(b"Hello world!") .chain("String data") .finalize(); println!("Result: {:x}", hash); ``` -If the whole message is available you also can use convenience `digest` method: +If a complete message is available, then you also can use the convenience `digest` method: -```Rust -use blake2::{Blake2b, Digest}; +```rust +use sha2::{Sha256, Digest}; -let hash = Blake2b::digest(b"my message"); +let hash = Sha256::digest(b"my message"); println!("Result: {:x}", hash); ``` -### Hashing `Read`able objects +### Hashing `Read`able Objects -If you want to hash data from [`Read`][3] trait (e.g. from file) you can rely on -implementation of [`Write`][4] trait (requires an enabled-by-default `std` feature): +If you want to hash data from a type which imlements the [`Read`] trait, you can rely on implementation of the [`Write`] trait (requires enabled-by-default `std` feature): -```Rust -use blake2::{Blake2b, Digest}; +```rust +use sha2::{Sha256, Digest}; use std::{fs, io}; let mut file = fs::File::open(&path)?; -let mut hasher = Blake2b::new(); +let mut hasher = Sha256::new(); let n = io::copy(&mut file, &mut hasher)?; let hash = hasher.finalize(); -println!("Path: {}", path); + println!("Bytes processed: {}", n); println!("Hash value: {:x}", hash); ``` ### Hash-based Message Authentication Code (HMAC) -If you want to calculate [Hash-based Message Authentication Code][5] (HMAC), -you can use generic implementation from [`hmac`](https://docs.rs/hmac) crate, -which is a part of the [RustCrypto/MACs][6] repository. +If you want to calculate [Hash-based Message Authentication Code][HMAC] (HMAC), you can use the generic implementation from [`hmac`] crate, which is a part of the [RustCrypto/MACs] repository. -### Generic code +### Generic Code -You can write generic code over `Digest` (or other traits from `digest` crate) -trait which will work over different hash functions: +You can write generic code over the `Digest` trait (or other traits from the `digest` crate) which will work over different hash functions: -```Rust -use digest::Digest; -use blake2::Blake2b; -use sha2::Sha256; +```rust +use sha2::{Sha256, Sha512, Digest}; // Toy example, do not use it in practice! // Instead use crates from: https://github.com/RustCrypto/password-hashing @@ -172,15 +154,31 @@ fn hash_password(password: &str, salt: &str, output: &mut [u8]) { output.copy_from_slice(&hasher.finalize()) } -let mut buf1 = [0u8; 64]; -hash_password::("my_password", "abcd", &mut buf1); +let mut buf1 = [0u8; 32]; +hash_password::("my_password", "abcd", &mut buf1); -let mut buf2 = [0u8; 32]; -hash_password::("my_password", "abcd", &mut buf2); +let mut buf2 = [0u8; 64]; +hash_password::("my_password", "abcd", &mut buf2); ``` -If you want to use hash functions with trait objects, use `digest::DynDigest` -trait. +If you want to use hash functions with trait objects, you can use the [`DynDigest`] trait: + +```rust +use sha2::{Sha256, Sha512, digest::DynDigest}; + +fn dyn_hash(hasher: &mut dyn DynDigest, data: &[u8]) -> Box<[u8]> { + hasher.update(data); + hasher.finalize_reset() +} + +let mut sha256_hasher = Sha256::default(); +let mut sha512_hasher = Sha512::default(); + +let res1 = dyn_hash(&mut sha256_hasher, b"foo"); +let res2 = dyn_hash(&mut sha256_hasher, b"bar"); +let res3 = dyn_hash(&mut sha512_hasher, b"foo"); +let res4 = dyn_hash(&mut sha512_hasher, b"bar"); +``` ## License @@ -193,9 +191,7 @@ 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. +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) @@ -203,15 +199,18 @@ dual licensed as above, without any additional terms or conditions. [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [deps-image]: https://deps.rs/repo/github/RustCrypto/hashes/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/hashes +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg [//]: # (footnotes) [1]: https://en.wikipedia.org/wiki/Cryptographic_hash_function -[2]: https://docs.rs/generic-array -[3]: https://doc.rust-lang.org/std/io/trait.Read.html -[4]: https://doc.rust-lang.org/std/io/trait.Write.html -[5]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code -[6]: https://github.com/RustCrypto/MACs +[`generic-array`]: https://docs.rs/generic-array +[HMAC]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code +[`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html +[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html +[`hmac`]: https://docs.rs/hmac +[RustCrypto/MACs]: https://github.com/RustCrypto/MACs +[`DynDigest`]: https://docs.rs/digest/0.10.0/digest/trait.DynDigest.html [//]: # (algorithms) @@ -223,9 +222,7 @@ dual licensed as above, without any additional terms or conditions. [MD2]: https://en.wikipedia.org/wiki/MD2_(cryptography) [MD4]: https://en.wikipedia.org/wiki/MD4 [MD5]: https://en.wikipedia.org/wiki/MD5 -[RIPEMD-160]: https://en.wikipedia.org/wiki/RIPEMD -[RIPEMD-256]: https://en.wikipedia.org/wiki/RIPEMD -[RIPEMD-320]: https://en.wikipedia.org/wiki/RIPEMD +[RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD [SHA-1]: https://en.wikipedia.org/wiki/SHA-1 [SHA-2]: https://en.wikipedia.org/wiki/SHA-2 [SHA-3]: https://en.wikipedia.org/wiki/SHA-3 diff --git a/blake2/CHANGELOG.md b/blake2/CHANGELOG.md index 60bf2e2dd..4e6351605 100644 --- a/blake2/CHANGELOG.md +++ b/blake2/CHANGELOG.md @@ -5,6 +5,12 @@ 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.10.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 and remove dependency on `crypto-mac` ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.9.2 (2021-08-25) ### Fixed - Building with `simd_opt` on recent nightlies ([#301]) diff --git a/blake2/Cargo.toml b/blake2/Cargo.toml index 6d25e15a7..45f8c94cc 100644 --- a/blake2/Cargo.toml +++ b/blake2/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "blake2" -version = "0.9.2" +name = "blake2" # Also update html_root_url in lib.rs when bumping this +version = "0.10.0" # Also update html_root_url in lib.rs when bumping this description = "BLAKE2 hash functions" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" @@ -12,18 +12,15 @@ keywords = ["crypto", "blake2", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -crypto-mac = "0.8" -opaque-debug = "0.3" +digest = { version = "0.10", features = ["mac"] } [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } -crypto-mac = { version = "0.8", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] default = ["std"] -std = ["digest/std", "crypto-mac/std"] +std = ["digest/std"] simd = [] simd_opt = ["simd"] simd_asm = ["simd_opt"] diff --git a/blake2/examples/blake2b_sum.rs b/blake2/examples/blake2b_sum.rs deleted file mode 100644 index 31e0ff11e..000000000 --- a/blake2/examples/blake2b_sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use blake2::{Blake2b, Digest}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/blake2/examples/blake2s_sum.rs b/blake2/examples/blake2s_sum.rs deleted file mode 100644 index 38be51d03..000000000 --- a/blake2/examples/blake2s_sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use blake2::{Blake2s, Digest}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/blake2/src/blake2.rs b/blake2/src/blake2.rs deleted file mode 100644 index 3255a30e9..000000000 --- a/blake2/src/blake2.rs +++ /dev/null @@ -1,414 +0,0 @@ -macro_rules! blake2_impl { - ( - $state:ident, $fix_state:ident, $word:ident, $vec:ident, $bytes:ident, - $block_size:ident, $R1:expr, $R2:expr, $R3:expr, $R4:expr, $IV:expr, - $vardoc:expr, $doc:expr, - ) => { - use $crate::as_bytes::AsBytes; - use $crate::simd::{$vec, Vector4}; - - use core::{cmp, convert::TryInto, ops::Div}; - use crypto_mac::{InvalidKeyLength, Mac, NewMac}; - use digest::generic_array::typenum::{Unsigned, U4}; - use digest::generic_array::GenericArray; - use digest::InvalidOutputSize; - use digest::{BlockInput, FixedOutputDirty, Reset, Update, VariableOutputDirty}; - - type Output = GenericArray; - - #[derive(Clone)] - #[doc=$vardoc] - pub struct $state { - m: [$word; 16], - h: [$vec; 2], - t: u64, - n: usize, - - h0: [$vec; 2], - m0: [$word; 16], - t0: u64, - } - - #[inline(always)] - fn iv0() -> $vec { - $vec::new($IV[0], $IV[1], $IV[2], $IV[3]) - } - #[inline(always)] - fn iv1() -> $vec { - $vec::new($IV[4], $IV[5], $IV[6], $IV[7]) - } - - #[inline(always)] - fn quarter_round(v: &mut [$vec; 4], rd: u32, rb: u32, m: $vec) { - v[0] = v[0].wrapping_add(v[1]).wrapping_add(m.from_le()); - v[3] = (v[3] ^ v[0]).rotate_right_const(rd); - v[2] = v[2].wrapping_add(v[3]); - v[1] = (v[1] ^ v[2]).rotate_right_const(rb); - } - - #[inline(always)] - fn shuffle(v: &mut [$vec; 4]) { - v[1] = v[1].shuffle_left_1(); - v[2] = v[2].shuffle_left_2(); - v[3] = v[3].shuffle_left_3(); - } - - #[inline(always)] - fn unshuffle(v: &mut [$vec; 4]) { - v[1] = v[1].shuffle_right_1(); - v[2] = v[2].shuffle_right_2(); - v[3] = v[3].shuffle_right_3(); - } - - #[inline(always)] - fn round(v: &mut [$vec; 4], m: &[$word; 16], s: &[usize; 16]) { - quarter_round(v, $R1, $R2, $vec::gather(m, s[0], s[2], s[4], s[6])); - quarter_round(v, $R3, $R4, $vec::gather(m, s[1], s[3], s[5], s[7])); - - shuffle(v); - quarter_round(v, $R1, $R2, $vec::gather(m, s[8], s[10], s[12], s[14])); - quarter_round(v, $R3, $R4, $vec::gather(m, s[9], s[11], s[13], s[15])); - unshuffle(v); - } - - impl $state { - /// Creates a new hashing context with a key. - /// - /// **WARNING!** If you plan to use it for variable output MAC, then - /// make sure to compare codes in constant time! It can be done - /// for example by using `subtle` crate. - pub fn new_keyed(key: &[u8], output_size: usize) -> Self { - Self::with_params(key, &[], &[], output_size) - } - - /// Creates a new hashing context with the full set of sequential-mode parameters. - pub fn with_params( - key: &[u8], - salt: &[u8], - persona: &[u8], - output_size: usize, - ) -> Self { - let kk = key.len(); - assert!(kk <= $bytes::to_usize()); - assert!(output_size <= $bytes::to_usize()); - - // The number of bytes needed to express two words. - let length = $bytes::to_usize() / 4; - assert!(salt.len() <= length); - assert!(persona.len() <= length); - - // Build a parameter block - let mut p = [0 as $word; 8]; - p[0] = 0x0101_0000 ^ ((kk as $word) << 8) ^ (output_size as $word); - - // salt is two words long - if salt.len() < length { - let mut padded_salt = - GenericArray::>::Output>::default(); - for i in 0..salt.len() { - padded_salt[i] = salt[i]; - } - p[4] = $word::from_le_bytes(padded_salt[0..length / 2].try_into().unwrap()); - p[5] = $word::from_le_bytes( - padded_salt[length / 2..padded_salt.len()] - .try_into() - .unwrap(), - ); - } else { - p[4] = $word::from_le_bytes(salt[0..salt.len() / 2].try_into().unwrap()); - p[5] = - $word::from_le_bytes(salt[salt.len() / 2..salt.len()].try_into().unwrap()); - } - - // persona is also two words long - if persona.len() < length { - let mut padded_persona = - GenericArray::>::Output>::default(); - for i in 0..persona.len() { - padded_persona[i] = persona[i]; - } - p[6] = $word::from_le_bytes(padded_persona[0..length / 2].try_into().unwrap()); - p[7] = $word::from_le_bytes( - padded_persona[length / 2..padded_persona.len()] - .try_into() - .unwrap(), - ); - } else { - p[6] = $word::from_le_bytes(persona[0..length / 2].try_into().unwrap()); - p[7] = $word::from_le_bytes( - persona[length / 2..persona.len()].try_into().unwrap(), - ); - } - - let mut state = Self::with_parameter_block(&p); - - if kk > 0 { - copy(key, state.m.as_mut_bytes()); - state.t = 2 * $bytes::to_u64(); - } - - state.t0 = state.t; - state.m0 = state.m; - state - } - - #[doc(hidden)] - pub fn with_parameter_block(p: &[$word; 8]) -> Self { - let nn = p[0] as u8 as usize; - let kk = (p[0] >> 8) as u8 as usize; - assert!(nn >= 1 && nn <= $bytes::to_usize()); - assert!(kk <= $bytes::to_usize()); - - let h0 = [ - iv0() ^ $vec::new(p[0], p[1], p[2], p[3]), - iv1() ^ $vec::new(p[4], p[5], p[6], p[7]), - ]; - - $state { - m: [0; 16], - h: h0, - t: 0, - n: nn, - - t0: 0, - m0: [0; 16], - h0, - } - } - - /// Updates the hashing context with more data. - fn update(&mut self, data: &[u8]) { - let mut rest = data; - - let block = 2 * $bytes::to_usize(); - - let off = self.t as usize % block; - if off != 0 || self.t == 0 { - let len = cmp::min(block - off, rest.len()); - - let part = &rest[..len]; - rest = &rest[part.len()..]; - - copy(part, &mut self.m.as_mut_bytes()[off..]); - self.t = self - .t - .checked_add(part.len() as u64) - .expect("hash data length overflow"); - } - - while rest.len() >= block { - self.compress(0, 0); - - let part = &rest[..block]; - rest = &rest[part.len()..]; - - copy(part, &mut self.m.as_mut_bytes()); - self.t = self - .t - .checked_add(part.len() as u64) - .expect("hash data length overflow"); - } - - let n = rest.len(); - if n > 0 { - self.compress(0, 0); - - copy(rest, &mut self.m.as_mut_bytes()); - self.t = self - .t - .checked_add(rest.len() as u64) - .expect("hash data length overflow"); - } - } - - #[doc(hidden)] - pub fn finalize_last_node(mut self) -> Output { - self.finalize_with_flag(!0) - } - - fn finalize_with_flag(&mut self, f1: $word) -> Output { - let off = self.t as usize % (2 * $bytes::to_usize()); - if off != 0 { - self.m.as_mut_bytes()[off..].iter_mut().for_each(|b| *b = 0); - } - - self.compress(!0, f1); - - let buf = [self.h[0].to_le(), self.h[1].to_le()]; - - let mut out = GenericArray::default(); - copy(buf.as_bytes(), &mut out); - out - } - - fn compress(&mut self, f0: $word, f1: $word) { - use $crate::consts::SIGMA; - - let m = &self.m; - let h = &mut self.h; - - let t0 = self.t as $word; - let t1 = match $bytes::to_u8() { - 64 => 0, - 32 => (self.t >> 32) as $word, - _ => unreachable!(), - }; - - let mut v = [h[0], h[1], iv0(), iv1() ^ $vec::new(t0, t1, f0, f1)]; - - round(&mut v, m, &SIGMA[0]); - round(&mut v, m, &SIGMA[1]); - round(&mut v, m, &SIGMA[2]); - round(&mut v, m, &SIGMA[3]); - round(&mut v, m, &SIGMA[4]); - round(&mut v, m, &SIGMA[5]); - round(&mut v, m, &SIGMA[6]); - round(&mut v, m, &SIGMA[7]); - round(&mut v, m, &SIGMA[8]); - round(&mut v, m, &SIGMA[9]); - if $bytes::to_u8() == 64 { - round(&mut v, m, &SIGMA[0]); - round(&mut v, m, &SIGMA[1]); - } - - h[0] = h[0] ^ (v[0] ^ v[2]); - h[1] = h[1] ^ (v[1] ^ v[3]); - } - } - - impl Default for $state { - fn default() -> Self { - Self::new_keyed(&[], $bytes::to_usize()) - } - } - - impl BlockInput for $state { - type BlockSize = $block_size; - } - - impl Update for $state { - fn update(&mut self, data: impl AsRef<[u8]>) { - self.update(data.as_ref()); - } - } - - impl VariableOutputDirty for $state { - fn new(output_size: usize) -> Result { - if output_size == 0 || output_size > $bytes::to_usize() { - return Err(InvalidOutputSize); - } - Ok(Self::new_keyed(&[], output_size)) - } - - fn output_size(&self) -> usize { - self.n - } - - fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])) { - let n = self.n; - let res = self.finalize_with_flag(0); - f(&res[..n]); - } - } - - impl Reset for $state { - fn reset(&mut self) { - self.t = self.t0; - self.m = self.m0; - self.h = self.h0; - } - } - - opaque_debug::implement!($state); - digest::impl_write!($state); - - #[derive(Clone)] - #[doc=$doc] - pub struct $fix_state { - state: $state, - } - - impl $fix_state { - /// Creates a new hashing context with the full set of sequential-mode parameters. - pub fn with_params(key: &[u8], salt: &[u8], persona: &[u8]) -> Self { - let state = $state::with_params(key, salt, persona, $bytes::to_usize()); - Self { state } - } - } - - impl Default for $fix_state { - fn default() -> Self { - let state = $state::new_keyed(&[], $bytes::to_usize()); - Self { state } - } - } - - impl BlockInput for $fix_state { - type BlockSize = $block_size; - } - - impl Update for $fix_state { - fn update(&mut self, data: impl AsRef<[u8]>) { - self.state.update(data.as_ref()); - } - } - - impl FixedOutputDirty for $fix_state { - type OutputSize = $bytes; - - fn finalize_into_dirty(&mut self, out: &mut Output) { - out.copy_from_slice(&self.state.finalize_with_flag(0)); - } - } - - impl Reset for $fix_state { - fn reset(&mut self) { - self.state.reset() - } - } - - impl NewMac for $fix_state { - type KeySize = $bytes; - - fn new(key: &GenericArray) -> Self { - let state = $state::new_keyed(key, $bytes::to_usize()); - Self { state } - } - - fn new_varkey(key: &[u8]) -> Result { - if key.len() > $bytes::to_usize() { - Err(InvalidKeyLength) - } else { - let state = $state::new_keyed(key, $bytes::to_usize()); - Ok(Self { state }) - } - } - } - - impl Mac for $fix_state { - type OutputSize = $bytes; - - fn update(&mut self, data: &[u8]) { - self.state.update(data); - } - - fn reset(&mut self) { - ::reset(self) - } - - fn finalize(mut self) -> crypto_mac::Output { - crypto_mac::Output::new(self.state.finalize_with_flag(0)) - } - } - - opaque_debug::implement!($fix_state); - digest::impl_write!($fix_state); - - fn copy(src: &[u8], dst: &mut [u8]) { - assert!(dst.len() >= src.len()); - unsafe { - core::ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len()); - } - } - }; -} diff --git a/blake2/src/blake2b.rs b/blake2/src/blake2b.rs deleted file mode 100644 index 3afc18d84..000000000 --- a/blake2/src/blake2b.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::consts::BLAKE2B_IV; -use digest::generic_array::typenum::{U128, U64}; - -blake2_impl!( - VarBlake2b, - Blake2b, - u64, - u64x4, - U64, - U128, - 32, - 24, - 16, - 63, - BLAKE2B_IV, - "Blake2b instance with a variable output.", - "Blake2b instance with a fixed output.", -); diff --git a/blake2/src/blake2s.rs b/blake2/src/blake2s.rs deleted file mode 100644 index 5306ed992..000000000 --- a/blake2/src/blake2s.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::consts::BLAKE2S_IV; -use digest::generic_array::typenum::{U32, U64}; - -blake2_impl!( - VarBlake2s, - Blake2s, - u32, - u32x4, - U32, - U64, - 16, - 12, - 8, - 7, - BLAKE2S_IV, - "Blake2s instance with a variable output.", - "Blake2s instance with a fixed output.", -); diff --git a/blake2/src/lib.rs b/blake2/src/lib.rs index b74c7b5bf..6d153cba4 100644 --- a/blake2/src/lib.rs +++ b/blake2/src/lib.rs @@ -2,14 +2,14 @@ //! //! # Usage //! -//! `Blake2b` can be used in the following way: +//! [`Blake2b512`] and [`Blake2s256`] can be used in the following way: //! //! ```rust -//! use blake2::{Blake2b, Blake2s, Digest}; +//! use blake2::{Blake2b512, Blake2s256, Digest}; //! use hex_literal::hex; //! -//! // create a Blake2b object -//! let mut hasher = Blake2b::new(); +//! // create a Blake2b512 object +//! let mut hasher = Blake2b512::new(); //! //! // write input message //! hasher.update(b"hello world"); @@ -21,8 +21,8 @@ //! c05a037cddbed06e309bf334942c4e58cdf1a46e237911ccd7fcf9787cbc7fd0 //! ")[..]); //! -//! // same example for `Blake2s`: -//! let mut hasher = Blake2s::new(); +//! // same example for Blake2s256: +//! let mut hasher = Blake2s256::new(); //! hasher.update(b"hello world"); //! let res = hasher.finalize(); //! assert_eq!(res[..], hex!(" @@ -34,45 +34,32 @@ //! //! ## Variable output size //! -//! If you need variable sized output you can use `VarBlake2b` and `VarBlake2s` -//! which support variable output sizes through `VariableOutput` trait. `Update` -//! trait has to be imported as well. +//! This implementation supports run and compile time variable sizes. //! +//! Run time variable output example: //! ```rust -//! use blake2::VarBlake2b; +//! use blake2::Blake2bVar; //! use blake2::digest::{Update, VariableOutput}; +//! use hex_literal::hex; //! -//! let mut hasher = VarBlake2b::new(10).unwrap(); +//! let mut hasher = Blake2bVar::new(10).unwrap(); //! hasher.update(b"my_input"); //! hasher.finalize_variable(|res| { -//! assert_eq!(res, [44, 197, 92, 132, 228, 22, 146, 78, 100, 0]) +//! assert_eq!(res, hex!("2cc55c84e416924e6400")) //! }) //! ``` //! -//! ## Message Authentication Code (MAC) -//! -//! BLAKE2 can be used as a MAC without any additional constructs: -//! +//! Compile time variable output example: //! ```rust -//! use blake2::Blake2b; -//! use blake2::crypto_mac::{Mac, NewMac}; -//! -//! let mut hasher = Blake2b::new_varkey(b"my key").unwrap(); -//! hasher.update(b"hello world"); +//! use blake2::{Blake2b, Digest, digest::consts::U10}; +//! use hex_literal::hex; //! -//! // `result` has type `crypto_mac::Output` which is a thin wrapper around -//! // a byte array and provides a constant time equality check -//! let result = hasher.finalize(); -//! // To get underlying array use the `into_bytes` method, but be careful, -//! // since incorrect use of the code value may permit timing attacks which -//! // defeat the security provided by the `crypto_mac::Output` -//! let code_bytes = result.into_bytes(); +//! type Blake2b80 = Blake2b; //! -//! // To verify the message it's recommended to use `verify` method -//! let mut hasher = Blake2b::new_varkey(b"my key").unwrap(); -//! hasher.update(b"hello world"); -//! // `verify` return `Ok(())` if code is correct, `Err(MacError)` otherwise -//! hasher.verify(&code_bytes).unwrap(); +//! let mut hasher = Blake2b80::new(); +//! hasher.update(b"my_input"); +//! let res = hasher.finalize(); +//! assert_eq!(res[..], hex!("2cc55c84e416924e6400")[..]); //! ``` //! //! # Acknowledgment @@ -83,8 +70,9 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/blake2/0.10.0" )] #![warn(missing_docs, rust_2018_idioms)] #![cfg_attr(feature = "simd", feature(platform_intrinsics, repr_simd))] @@ -94,19 +82,93 @@ #[cfg(feature = "std")] extern crate std; +pub use digest::{self, Digest}; + +use core::{convert::TryInto, fmt, marker::PhantomData, ops::Div}; +use digest::{ + block_buffer::{Lazy, LazyBuffer}, + consts::{U128, U32, U4, U64}, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, + CtVariableCoreWrapper, OutputSizeUser, RtVariableCoreWrapper, UpdateCore, + VariableOutputCore, + }, + crypto_common::{InvalidLength, Key, KeyInit, KeySizeUser}, + generic_array::{ + typenum::{IsLessOrEqual, LeEq, NonZero, Unsigned}, + ArrayLength, GenericArray, + }, + FixedOutput, HashMarker, InvalidOutputSize, MacMarker, Output, Update, +}; + mod as_bytes; mod consts; mod simd; #[macro_use] -mod blake2; +mod macros; -mod blake2b; -mod blake2s; +use as_bytes::AsBytes; +use consts::{BLAKE2B_IV, BLAKE2S_IV}; +use simd::{u32x4, u64x4, Vector4}; -pub use crypto_mac; -pub use digest::{self, Digest}; +blake2_impl!( + Blake2bVarCore, + "Blake2b", + u64, + u64x4, + U64, + U128, + 32, + 24, + 16, + 63, + BLAKE2B_IV, + "Blake2b instance with a variable output.", + "Blake2b instance with a fixed output.", +); + +/// BLAKE2b which allows to choose output size at runtime. +pub type Blake2bVar = RtVariableCoreWrapper; +/// Core hasher state of BLAKE2b generic over output size. +pub type Blake2bCore = CtVariableCoreWrapper; +/// BLAKE2b generic over output size. +pub type Blake2b = CoreWrapper>; +/// BLAKE2b-512 hasher state. +pub type Blake2b512 = Blake2b; + +blake2_mac_impl!(Blake2bMac, Blake2bVarCore, U64, "Blake2b MAC function"); + +/// BLAKE2b-512 MAC state. +pub type Blake2bMac512 = Blake2bMac; + +blake2_impl!( + Blake2sVarCore, + "Blake2s", + u32, + u32x4, + U32, + U64, + 16, + 12, + 8, + 7, + BLAKE2S_IV, + "Blake2s instance with a variable output.", + "Blake2s instance with a fixed output.", +); + +/// BLAKE2s which allows to choose output size at runtime. +pub type Blake2sVar = RtVariableCoreWrapper; +/// Core hasher state of BLAKE2s generic over output size. +pub type Blake2sCore = CtVariableCoreWrapper; +/// BLAKE2s generic over output size. +pub type Blake2s = CoreWrapper>; +/// BLAKE2s-256 hasher state. +pub type Blake2s256 = Blake2s; + +blake2_mac_impl!(Blake2sMac, Blake2sVarCore, U32, "Blake2s MAC function"); -pub use crate::blake2b::{Blake2b, VarBlake2b}; -pub use crate::blake2s::{Blake2s, VarBlake2s}; +/// BLAKE2s-256 MAC state. +pub type Blake2sMac256 = Blake2sMac; diff --git a/blake2/src/macros.rs b/blake2/src/macros.rs new file mode 100644 index 000000000..fd583e7ea --- /dev/null +++ b/blake2/src/macros.rs @@ -0,0 +1,371 @@ +macro_rules! blake2_impl { + ( + $name:ident, $alg_name:expr, $word:ident, $vec:ident, $bytes:ident, + $block_size:ident, $R1:expr, $R2:expr, $R3:expr, $R4:expr, $IV:expr, + $vardoc:expr, $doc:expr, + ) => { + #[derive(Clone)] + #[doc=$vardoc] + pub struct $name { + h: [$vec; 2], + t: u64, + } + + impl $name { + #[inline(always)] + fn iv0() -> $vec { + $vec::new($IV[0], $IV[1], $IV[2], $IV[3]) + } + #[inline(always)] + fn iv1() -> $vec { + $vec::new($IV[4], $IV[5], $IV[6], $IV[7]) + } + + /// Creates a new context with the full set of sequential-mode parameters. + pub fn new_with_params( + salt: &[u8], + persona: &[u8], + key_size: usize, + output_size: usize, + ) -> Self { + assert!(key_size <= $bytes::to_usize()); + assert!(output_size <= $bytes::to_usize()); + + // The number of bytes needed to express two words. + let length = $bytes::to_usize() / 4; + assert!(salt.len() <= length); + assert!(persona.len() <= length); + + // Build a parameter block + let mut p = [0 as $word; 8]; + p[0] = 0x0101_0000 ^ ((key_size as $word) << 8) ^ (output_size as $word); + + // salt is two words long + if salt.len() < length { + let mut padded_salt = + GenericArray::>::Output>::default(); + for i in 0..salt.len() { + padded_salt[i] = salt[i]; + } + p[4] = $word::from_le_bytes(padded_salt[0..length / 2].try_into().unwrap()); + p[5] = $word::from_le_bytes( + padded_salt[length / 2..padded_salt.len()] + .try_into() + .unwrap(), + ); + } else { + p[4] = $word::from_le_bytes(salt[0..salt.len() / 2].try_into().unwrap()); + p[5] = + $word::from_le_bytes(salt[salt.len() / 2..salt.len()].try_into().unwrap()); + } + + // persona is also two words long + if persona.len() < length { + let mut padded_persona = + GenericArray::>::Output>::default(); + for i in 0..persona.len() { + padded_persona[i] = persona[i]; + } + p[6] = $word::from_le_bytes(padded_persona[0..length / 2].try_into().unwrap()); + p[7] = $word::from_le_bytes( + padded_persona[length / 2..padded_persona.len()] + .try_into() + .unwrap(), + ); + } else { + p[6] = $word::from_le_bytes(persona[0..length / 2].try_into().unwrap()); + p[7] = $word::from_le_bytes( + persona[length / 2..persona.len()].try_into().unwrap(), + ); + } + + $name { + h: [ + Self::iv0() ^ $vec::new(p[0], p[1], p[2], p[3]), + Self::iv1() ^ $vec::new(p[4], p[5], p[6], p[7]), + ], + t: 0, + } + } + + fn finalize_with_flag( + &mut self, + final_block: &GenericArray, + flag: $word, + ) -> GenericArray { + self.compress(final_block, !0, flag); + let buf = [self.h[0].to_le(), self.h[1].to_le()]; + GenericArray::clone_from_slice(buf.as_bytes()) + } + + fn compress(&mut self, block: &Block, f0: $word, f1: $word) { + use $crate::consts::SIGMA; + + #[inline(always)] + fn quarter_round(v: &mut [$vec; 4], rd: u32, rb: u32, m: $vec) { + v[0] = v[0].wrapping_add(v[1]).wrapping_add(m.from_le()); + v[3] = (v[3] ^ v[0]).rotate_right_const(rd); + v[2] = v[2].wrapping_add(v[3]); + v[1] = (v[1] ^ v[2]).rotate_right_const(rb); + } + + #[inline(always)] + fn shuffle(v: &mut [$vec; 4]) { + v[1] = v[1].shuffle_left_1(); + v[2] = v[2].shuffle_left_2(); + v[3] = v[3].shuffle_left_3(); + } + + #[inline(always)] + fn unshuffle(v: &mut [$vec; 4]) { + v[1] = v[1].shuffle_right_1(); + v[2] = v[2].shuffle_right_2(); + v[3] = v[3].shuffle_right_3(); + } + + #[inline(always)] + fn round(v: &mut [$vec; 4], m: &[$word; 16], s: &[usize; 16]) { + quarter_round(v, $R1, $R2, $vec::gather(m, s[0], s[2], s[4], s[6])); + quarter_round(v, $R3, $R4, $vec::gather(m, s[1], s[3], s[5], s[7])); + + shuffle(v); + quarter_round(v, $R1, $R2, $vec::gather(m, s[8], s[10], s[12], s[14])); + quarter_round(v, $R3, $R4, $vec::gather(m, s[9], s[11], s[13], s[15])); + unshuffle(v); + } + + let mut m: [$word; 16] = Default::default(); + let n = core::mem::size_of::<$word>(); + for (v, chunk) in m.iter_mut().zip(block.chunks_exact(n)) { + *v = $word::from_le_bytes(chunk.try_into().unwrap()); + } + let h = &mut self.h; + + let t0 = self.t as $word; + let t1 = match $bytes::to_u8() { + 64 => 0, + 32 => (self.t >> 32) as $word, + _ => unreachable!(), + }; + + let mut v = [ + h[0], + h[1], + Self::iv0(), + Self::iv1() ^ $vec::new(t0, t1, f0, f1), + ]; + + round(&mut v, &m, &SIGMA[0]); + round(&mut v, &m, &SIGMA[1]); + round(&mut v, &m, &SIGMA[2]); + round(&mut v, &m, &SIGMA[3]); + round(&mut v, &m, &SIGMA[4]); + round(&mut v, &m, &SIGMA[5]); + round(&mut v, &m, &SIGMA[6]); + round(&mut v, &m, &SIGMA[7]); + round(&mut v, &m, &SIGMA[8]); + round(&mut v, &m, &SIGMA[9]); + if $bytes::to_u8() == 64 { + round(&mut v, &m, &SIGMA[0]); + round(&mut v, &m, &SIGMA[1]); + } + + h[0] = h[0] ^ (v[0] ^ v[2]); + h[1] = h[1] ^ (v[1] ^ v[3]); + } + } + + impl HashMarker for $name {} + + impl BlockSizeUser for $name { + type BlockSize = $block_size; + } + + impl BufferKindUser for $name { + type BufferKind = Lazy; + } + + impl UpdateCore for $name { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + self.t += block.len() as u64; + self.compress(block, 0, 0); + } + } + } + + impl VariableOutputCore for $name { + type MaxOutputSize = $bytes; + + #[inline] + fn new(output_size: usize) -> Result { + if output_size > Self::MaxOutputSize::USIZE { + return Err(InvalidOutputSize); + } + Ok(Self::new_with_params(&[], &[], 0, output_size)) + } + + #[inline] + fn finalize_variable_core( + &mut self, + buffer: &mut Buffer, + output_size: usize, + f: impl FnOnce(&[u8]), + ) { + self.t += buffer.get_pos() as u64; + let block = buffer.pad_with_zeros(); + let res = self.finalize_with_flag(block, 0); + f(&res[..output_size]); + } + } + + impl AlgorithmName for $name { + #[inline] + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str($alg_name) + } + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + }; +} + +macro_rules! blake2_mac_impl { + ( + $name:ident, $hash:ty, $max_size:ty, $doc:expr + ) => { + #[derive(Clone)] + #[doc=$doc] + pub struct $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + core: $hash, + buffer: LazyBuffer<<$hash as BlockSizeUser>::BlockSize>, + _out: PhantomData, + } + + impl $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + /// Create new instance using provided key, salt, and persona. + /// + /// Key length should not be bigger than block size, salt and persona + /// length should not be bigger than quarter of block size. If any + /// of those conditions is false the method will return an error. + #[inline] + pub fn new_with_salt_and_personal( + key: &[u8], + salt: &[u8], + persona: &[u8], + ) -> Result { + let kl = key.len(); + let bs = <$hash as BlockSizeUser>::BlockSize::USIZE; + let qbs = bs / 4; + if kl > bs || salt.len() > qbs || persona.len() > qbs { + return Err(InvalidLength); + } + let mut key_block = Block::<$hash>::default(); + key_block[..kl].copy_from_slice(key); + Ok(Self { + core: <$hash>::new_with_params(salt, persona, key.len(), OutSize::USIZE), + buffer: LazyBuffer::new(&key_block), + _out: PhantomData, + }) + } + } + + impl KeySizeUser for $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + type KeySize = <$hash as BlockSizeUser>::BlockSize; + } + + impl KeyInit for $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + fn new(key: &Key) -> Self { + Self { + core: <$hash>::new_with_params(key, &[], key.len(), OutSize::USIZE), + buffer: LazyBuffer::new(key), + _out: PhantomData, + } + } + + fn new_from_slice(key: &[u8]) -> Result { + let kl = key.len(); + if kl > <$hash as BlockSizeUser>::BlockSize::USIZE { + return Err(InvalidLength); + } + let mut key_block = Block::<$hash>::default(); + key_block[..kl].copy_from_slice(key); + Ok(Self { + core: <$hash>::new_with_params(&[], &[], key.len(), OutSize::USIZE), + buffer: LazyBuffer::new(&key_block), + _out: PhantomData, + }) + } + } + + impl Update for $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + #[inline] + fn update(&mut self, input: &[u8]) { + let Self { core, buffer, .. } = self; + buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); + } + } + + impl OutputSizeUser for $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + type OutputSize = OutSize; + } + + impl FixedOutput for $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + #[inline] + fn finalize_into(mut self, out: &mut Output) { + let Self { core, buffer, .. } = &mut self; + core.finalize_variable_core(buffer, OutSize::USIZE, |res| out.copy_from_slice(res)); + } + } + + impl MacMarker for $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + } + + impl fmt::Debug for $name + where + OutSize: ArrayLength + IsLessOrEqual<$max_size>, + LeEq: NonZero, + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}{} {{ ... }}", stringify!($name), OutSize::USIZE) + } + } + }; +} diff --git a/blake2/tests/data/blake2b/fixed.blb b/blake2/tests/data/blake2b/fixed.blb index 39d4192093fb7ddaba517df1112e5f4e9f7de355..c999b74c6944b834a9212b1eb068bf9e8d61343f 100644 GIT binary patch delta 23 dcmdnSxQUU4fuVt6BBujm*hDXFCLpuS0RTiy1@8a= delta 27 icmdnQxQ&rBDJMTEsnU?aVIqqIqxM8sZAOQQMGgRSf(PXQ diff --git a/blake2/tests/data/blake2b/mac.blb b/blake2/tests/data/blake2b/mac.blb index 46522340d01322321a26c48b46accc028403a067..eaa6c03959299bdeaa8f508268a1c0f9f04cc902 100644 GIT binary patch delta 3911 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 delta 15 WcmdNlEG7mI{F<#JArkE!b&haWumzutp)MZaRH99fue1djT?5fLWw6t#Q zeOMALU!-NjWL{{DKx~Q%#k`?NNL@r44@E(T6!L*)K+{yI<_pb)^wdax&@8A%p~=ED zjc6!FEY)R(|GOnkUZ@sRdmtKO&=9Ro3W8=srW&MRD3;^b$onmsGk@N@=Z7utO?>m_ z$kVOeUZl;c79Z5;_)2B^!<9@HBBXbkgV<6{iiJXP&_FFxI5Zb}uTUfu56QKuHUpXm z1?!MzK?zVNT~Z8`IDwax7)3vCDO@2ksPuImcfqIcVl5AYyw$DK%bW*!v}IK>qrcsh z7XQ6)TGYY1H~Ilj?mzKc$FB{aH1v*ErOO2+ zQG?xmC2`3pCQCu%0*+tkol+g$>8R3)FnPi&-$_d|Gn$s0cR4jHCCb3ZG@#)qlcl0D z4fFd*X#O;4A!OJAN>_qp&`pJup>!zUP^!;5|NWk|dEvDo1w?4c;P|~Nt6NLQJoAv5 zc!d~0zN?&nv!Ar_a+v$PiiqT`-ZhW5)kjyACgOHKl|RdRC(6 zl|r4NRZz8*YQ|6&w91TR0b}ZdZXc|(4m|tItxkK9^R|nEas2H;BNAiG5ARR}NC$t^IzNCk9@+^Vc9Ke%`M;O1&kI`4)aHY>U1iiIknJtIkR&=E*JiWCnWg-SdW z-v`>X4tNdc_!A={{CB5p>uWJ~rrW2VOBStpWfA2WVs~We)2N25+jCu6dJ>Y=9G_SD zqDo>oY|Ij;_Cu~m3H3gHh6~(`O7rw=Zye5Bv?G9}r=ane1)sdOv8pu4B4f6jtCIJW z$g8jC#^p{9bRD(SN55Bf<9aVR@r zs^$2W0!f_qG|l(P+Y+XXPSuEPOZlC+`IkmV$jF4O?^@{_7EkrJ-r{qWv(!|El#c|U5>N7EUo*`H(p zo#prp-MF9!Q=k2GUNyPK)4lF!X8x0J+1b0yk49XN^)d75&N3uuJcroZ0E!tx=b@j0 zBqJex+672Eh}0Rn2pLZ$8AF$#9>F9N=rS~T8rGGe*yE(32RJ^fFmvpOp85LkoDPW_ zuX&|KXdcV-cysUjyp-o&yEgQ9VHxJa{pcnn!>1!@i#zH7)J&&IIh3w&{Fot5a|WcP zWNwuIW^3&&PMWZ#NK$n7d0ES|m%lx}>{7-utk8HBvFBkF>jqt8{MrbDEpQzrqezk+ z)C~2GBK3q?pwTl(_RtL|d?u+6bd%$A>>5s#_v~(1Tv<^3BTehG#)CZdTDgzI_`|95 zf3~aY#xfkx_$y)s(G+upZb8Rla5r|i8$-ZwHkAelW(mJR{bEVZ&~0eq9MT}@4wMi_ za)s_f8|RXE=pIxRPZ|o{hwjcJxj_#gQ6kA*C|&&!vP~k5gdRcTl1U!WV<#RO(}$-{@J98X9(ptLdS0z}u5m6%ICLfY@$9qv)~V*@vJ6k8o*?yOKF#3;J%y|m zki4O1G=CatJoFq|u#n^fy?}PfNWRcZ=terp4|)ZO7m+4Iuc7{nNrBKCC~^rY2zm?U zEybGcv1TLS(^4u0qx25ymPrbM-a~=QNTJa0Q1)_CIP?K(SV4+}K0<9PNi(2NkYg5U z7W5gKy_ysQeSvnaA;prEzwpANY+@Wy<;z!IkP28^AFQntdQ$}|##2%B*MUM$-No zQO8JY9%gsIYj*~GHvx`77vKP}=+|p)D zJqQsKyiVtQz!fkBQuDDu{Jl$qLosM(!P~j2cbuJ|9THksbTPc`bY07;M}uqE4xex9 z5w2;Xd$2omL!UW9@+}Ct0~Ua80YFbL959bSPbikaZ2~=@SOM-^0eT3r1`ceMikUi{ zWO#$AK+hxHEcgKnoYIP&b4NcL)5FK(`=j(CCB2E3R_m*Z>b0|u>9-%j=t;!}6I?1p zh#pjIfq_K;J*RXBb`t0@#SSpq222Ke0GWh9peN8u2m*QmGmC*>z#h0m2myNA@Kfa@ zXPkI!6WWy7rKWFI`RE5SmPsca`c-svg~L3isW^@CsV_k&6rnztL2o+{4)g_< z5F!Bw;0Iv_&<}{;A;r_7w_1N(zutjD3<`t@IS>mBu;6XN%P#LTaeI*)UEjR)vgJ3` z!4;q5*pWvud!J3wY_3#eap-eGC}<}_@qjaMYbQ-zs51!H{=1~znf9N*8u*_#a$PPC z`@H_z*g-G!K1>*H;dSPXx@+0FUs>wHq}n;dSQ2KSl-X`fmjbu|g@jbV)q>A7s=9h> zOs&Piz^al@p50HC{b)VDASF@b<37I?R;gZ>SQ`2UBUHQxpD>vcG(@o8OV`SDjmmC? zM9@&kejnA;pkYvjLh6tkHc{qYIvIuP*EF2cN8}&qzjGUc$cDV ztA_fPkFKGdZF1W#uMfjF-??yR<7@w&3uDd>%-_vq`e+=9*xpi_!~hxvIUOWPAP?xY zLWa<2$ft~IMvy1Rw>et(Jur3V>-|D<%NHT$j&zghB8$4UmZNSybxbe6HJ`~kqj3z! zzx}Yl{_YhO{~E8kKR@bN&mHa3s=1*gsAafKT+X>AjRj0*j7BfaFDj?`O`x&R`f{lj z)Bo#U#k_F89RC8@pJ%n0KBn;%)NYRUagh395(kZk@)e@rOA|Q0s+QYf@P3N8PU&7i z_@ZUSPG>tNelh#nN85N!l3KJ~8k5ma6CcFRRnjDMtWV_l15MuFCq7MTY&YUv`HlSC zR|oapr3FO? z$!Np*}>co=O3$j?Tw5}%WCbt^2zUk%^$il8SR-ap6P7mWiOTOLWCszeoqH(Q_iE+1R+%+rC%Xr~O~_${}07P~nq@AO-#qkSRdh`rh3 zG!f<&9?G|0G?L|bMERI3o}nbV<& QleGUaWf9(keJ7>=0igL^00000 delta 4793 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 literal 40 wcmYew$xlkEG~`Q6Do#mFOV3El&reD$5>&7_wR{Ep?N5=m&(EkC)jA0Q06^IgF8}}l diff --git a/blake2/tests/lib.rs b/blake2/tests/lib.rs index ba42b9ffd..2115af47a 100644 --- a/blake2/tests/lib.rs +++ b/blake2/tests/lib.rs @@ -3,16 +3,21 @@ use digest::dev::{digest_test, variable_test}; use digest::new_test; -new_test!(blake2b_fixed, "blake2b/fixed", blake2::Blake2b, digest_test); +new_test!( + blake2b_fixed, + "blake2b/fixed", + blake2::Blake2b512, + digest_test, +); new_test!( blake2b_variable, "blake2b/variable", - blake2::VarBlake2b, - variable_test + blake2::Blake2bVar, + variable_test, ); new_test!( blake2s_variable, "blake2s/variable", - blake2::VarBlake2s, - variable_test + blake2::Blake2sVar, + variable_test, ); diff --git a/blake2/tests/mac.rs b/blake2/tests/mac.rs index 833c563e3..d57e91de2 100644 --- a/blake2/tests/mac.rs +++ b/blake2/tests/mac.rs @@ -1,6 +1,4 @@ -#![no_std] +use digest::new_mac_test; -use crypto_mac::new_test; - -new_test!(blake2b_mac, "blake2b/mac", blake2::Blake2b); -new_test!(blake2s_mac, "blake2s/mac", blake2::Blake2s); +new_mac_test!(blake2b_mac, "blake2b/mac", blake2::Blake2bMac512); +new_mac_test!(blake2s_mac, "blake2s/mac", blake2::Blake2sMac256); diff --git a/blake2/tests/persona.rs b/blake2/tests/persona.rs index 4defcc801..49e6574e9 100644 --- a/blake2/tests/persona.rs +++ b/blake2/tests/persona.rs @@ -1,23 +1,40 @@ -use blake2::{Blake2b, Blake2s, Digest}; +use blake2::{digest::FixedOutput, Blake2bMac512, Blake2sMac256}; use hex_literal::hex; #[test] +#[rustfmt::skip] fn blake2s_persona() { - let key_bytes = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); - let persona = "personal"; - let persona_bytes = persona.as_bytes(); - let ctx = Blake2s::with_params(&key_bytes, &[], persona_bytes); + let key= hex!(" + 000102030405060708090a0b0c0d0e0f + 101112131415161718191a1b1c1d1e1f + "); + let persona = b"personal"; + let ctx = Blake2sMac256::new_with_salt_and_personal(&key, &[], persona).unwrap(); assert_eq!( - ctx.finalize().as_slice(), - &hex!("25a4ee63b594aed3f88a971e1877ef7099534f9097291f88fb86c79b5e70d022")[..] + ctx.finalize_fixed()[..], + hex!(" + 25a4ee63b594aed3f88a971e1877ef70 + 99534f9097291f88fb86c79b5e70d022 + ")[..], ); } #[test] +#[rustfmt::skip] fn blake2b_persona() { - let key_bytes = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); - let persona = "personal"; - let persona_bytes = persona.as_bytes(); - let ctx = Blake2b::with_params(&key_bytes, &[], persona_bytes); - assert_eq!(ctx.finalize().as_slice(), &hex!("03de3b295dcfc3b25b05abb09bc95fe3e9ff3073638badc68101d1e42019d0771dd07525a3aae8318e92c5e5d967ba92e4810d0021d7bf3b49da0b4b4a8a4e1f")[..]); + let key = hex!(" + 000102030405060708090a0b0c0d0e0f + 101112131415161718191a1b1c1d1e1f + "); + let persona = b"personal"; + let ctx = Blake2bMac512::new_with_salt_and_personal(&key, &[], persona).unwrap(); + assert_eq!( + ctx.finalize_fixed()[..], + hex!(" + 03de3b295dcfc3b25b05abb09bc95fe3 + e9ff3073638badc68101d1e42019d077 + 1dd07525a3aae8318e92c5e5d967ba92 + e4810d0021d7bf3b49da0b4b4a8a4e1f + ")[..], + ); } diff --git a/fsb/CHANGELOG.md b/fsb/CHANGELOG.md index bea8879e4..7d75d02e9 100644 --- a/fsb/CHANGELOG.md +++ b/fsb/CHANGELOG.md @@ -5,6 +5,12 @@ 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 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.0.2 (2020-07-21) - Fixed `Reset` implementation bug. Reduce crate size by using binary dump of `PI` ([#300]) diff --git a/fsb/Cargo.toml b/fsb/Cargo.toml index 9eb9fd6fd..96ffe6042 100644 --- a/fsb/Cargo.toml +++ b/fsb/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "fsb" description = "FSB hash function" -version = "0.0.2" +version = "0.1.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -11,15 +11,13 @@ keywords = ["crypto", "fsb", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -whirlpool = { version = "0.9", path = "../whirlpool", default-features = false } -digest = "0.9" -block-buffer = { version = "0.9", features = ["block-padding"] } -opaque-debug = "0.3" +digest = "0.10" +whirlpool = { version = "0.10", path = "../whirlpool", default-features = false } [dev-dependencies] +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" -digest = { version = "0.9", features = ["dev"] } [features] -asm = ["whirlpool/asm"] -std = ["whirlpool/std"] +default = ["std"] +std = ["digest/std"] diff --git a/ripemd160/LICENSE-APACHE b/fsb/LICENSE-APACHE similarity index 100% rename from ripemd160/LICENSE-APACHE rename to fsb/LICENSE-APACHE diff --git a/ripemd160/LICENSE-MIT b/fsb/LICENSE-MIT similarity index 89% rename from ripemd160/LICENSE-MIT rename to fsb/LICENSE-MIT index 66cf75563..c869ada57 100644 --- a/ripemd160/LICENSE-MIT +++ b/fsb/LICENSE-MIT @@ -1,6 +1,4 @@ -Copyright (c) 2006-2009 Graydon Hoare -Copyright (c) 2009-2013 Mozilla Foundation -Copyright (c) 2016 Artyom Pavlov +Copyright (c) 2021 The RustCrypto Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/fsb/README.md b/fsb/README.md index 53319e926..bff04069c 100644 --- a/fsb/README.md +++ b/fsb/README.md @@ -13,7 +13,7 @@ Pure Rust implementation of the [FSB hash function][1] family. ## Minimum Supported Rust Version -Rust **1.47** or higher. +Rust **1.41** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. diff --git a/fsb/benches/fsb160.rs b/fsb/benches/fsb160.rs new file mode 100644 index 000000000..8294f9d22 --- /dev/null +++ b/fsb/benches/fsb160.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(fsb::Fsb160); diff --git a/fsb/benches/fsb224.rs b/fsb/benches/fsb224.rs new file mode 100644 index 000000000..b8c65dbae --- /dev/null +++ b/fsb/benches/fsb224.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(fsb::Fsb224); diff --git a/fsb/benches/fsb256.rs b/fsb/benches/fsb256.rs new file mode 100644 index 000000000..7a2f33bc4 --- /dev/null +++ b/fsb/benches/fsb256.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(fsb::Fsb256); diff --git a/fsb/benches/fsb384.rs b/fsb/benches/fsb384.rs new file mode 100644 index 000000000..a241d1151 --- /dev/null +++ b/fsb/benches/fsb384.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(fsb::Fsb384); diff --git a/fsb/benches/fsb512.rs b/fsb/benches/fsb512.rs new file mode 100644 index 000000000..1cfd5f2c4 --- /dev/null +++ b/fsb/benches/fsb512.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(fsb::Fsb512); diff --git a/fsb/src/lib.rs b/fsb/src/lib.rs index a8b69eabd..619f2df0d 100644 --- a/fsb/src/lib.rs +++ b/fsb/src/lib.rs @@ -39,38 +39,36 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/fsb/0.1.0" )] -#![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] #![allow(non_snake_case)] -extern crate alloc; - -#[cfg(feature = "std")] -extern crate std; - -use alloc::vec; - #[macro_use] mod macros; +use core::fmt; pub use digest::{self, Digest}; -use whirlpool::Whirlpool; - -use core::convert::TryInto; // Double check this contains all values in the reference implementation static PI: &[u8; 272384] = include_bytes!("pi.bin"); -use block_buffer::BlockBuffer; -use digest::generic_array::GenericArray; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::{typenum::Unsigned, GenericArray}, + HashMarker, Output, +}; // FSB-160 fsb_impl!( Fsb160, + Fsb160Core, 160, U60, U20, @@ -79,12 +77,14 @@ fsb_impl!( 640, 653, 1120, - "FSB-160 hash function." + "FSB-160 hasher state", + "Core FSB-160 hasher state", ); // FSB-224 fsb_impl!( Fsb224, + Fsb224Core, 224, U84, U28, @@ -93,12 +93,14 @@ fsb_impl!( 896, 907, 1568, - "FSB-224 hash function." + "FSB-224 hasher state", + "Core FSB-224 hasher state", ); // FSB-256 fsb_impl!( Fsb256, + Fsb256Core, 256, U96, U32, @@ -107,12 +109,14 @@ fsb_impl!( 1024, 1061, 1792, - "FSB-256 hash function." + "FSB-256 hasher state", + "Core FSB-256 hasher state", ); // FSB-384 fsb_impl!( Fsb384, + Fsb384Core, 384, U115, U48, @@ -121,12 +125,14 @@ fsb_impl!( 1472, 1483, 2392, - "FSB-384 hash function." + "FSB-384 hasher state", + "Core FSB-384 hasher state", ); // FSB-512 fsb_impl!( Fsb512, + Fsb512Core, 512, U155, U64, @@ -135,5 +141,6 @@ fsb_impl!( 1984, 1987, 3224, - "FSB-512 hash function." + "FSB-512 hasher state", + "Core FSB-512 hasher state", ); diff --git a/fsb/src/macros.rs b/fsb/src/macros.rs index 8400722a4..620cb6d2b 100644 --- a/fsb/src/macros.rs +++ b/fsb/src/macros.rs @@ -1,57 +1,94 @@ macro_rules! fsb_impl { ( - $state:ident, $state_num:expr, $blocksize:ident, $outputsize:ident, $n:expr, $w:expr, - $r:expr, $p:expr, $s:expr, $doc:expr + $full_state:ident, $state:ident, $state_num:expr, $blocksize:ident, $outputsize:ident, $n:expr, $w:expr, + $r:expr, $p:expr, $s:expr, $full_doc:expr, $doc:expr, ) => { use digest::consts::{$blocksize, $outputsize}; #[derive(Clone)] #[doc=$doc] pub struct $state { - /// bit size of the message till the current moment (the bit size is represented by a 64 bit - /// number) - bit_length: u64, - /// size of the message being processed - buffer: BlockBuffer<$blocksize>, - /// value of the input vector - hash: [u8; $r / 8], + blocks_len: u64, + state: [u8; $r / 8], } + impl HashMarker for $state {} + + impl BlockSizeUser for $state { + type BlockSize = $blocksize; + } + + impl OutputSizeUser for $state { + type OutputSize = $outputsize; + } + + impl BufferKindUser for $state { + type BufferKind = Eager; + } + + impl UpdateCore for $state { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.blocks_len += blocks.len() as u64; + for block in blocks { + Self::compress(&mut self.state, Self::convert(block)); + } + } + } + + impl FixedOutputCore for $state { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let block_bytes = self.blocks_len * Self::BlockSize::U64; + let bit_len = 8 * (block_bytes + buffer.get_pos() as u64); + let mut h = self.state; + buffer.len64_padding_be(bit_len, |b| Self::compress(&mut h, Self::convert(b))); + + let res = whirlpool::Whirlpool::digest(&h[..]); + let n = out.len(); + out.copy_from_slice(&res[..n]); + } + } + + impl Default for $state { + #[inline] + fn default() -> Self { + Self { + blocks_len: 0u64, + state: [0u8; $r / 8], + } + } + } + + impl Reset for $state { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } + } + + impl AlgorithmName for $state { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(stringify!($full_state)) + } + } + + impl fmt::Debug for $state { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(concat!(stringify!($state), " { ... }")) + } + } + + #[doc=$full_doc] + pub type $full_state = CoreWrapper<$state>; + impl $state { - // constants const SIZE_OUTPUT_COMPRESS: usize = $r / 8; const SIZE_INPUT_COMPRESS: usize = $s / 8; - const HASH_OUTPUT_SIZE: usize = $state_num / 8; const SIZE_MSG_CHUNKS: usize = Self::SIZE_INPUT_COMPRESS - Self::SIZE_OUTPUT_COMPRESS; const SIZE_VECTORS: usize = $p / 8 + 1; const SHIFT: u8 = 8 - ($p % 8) as u8; - fn update_len(&mut self, len: u64) { - self.bit_length += len * 8; - } - - fn finalize_inner(&mut self) { - let hash = &mut self.hash; - let pos = self.buffer.position(); - if pos < Self::SIZE_MSG_CHUNKS - 8 { - let mut padding = vec![0; Self::SIZE_MSG_CHUNKS - pos - 8]; - padding[0] = 128u8; - padding.extend_from_slice(&Self::helper_transform_usize(self.bit_length)); - self.buffer - .input_block(&padding, |b| Self::compress(hash, Self::convert(b))); - } else { - let mut padding = vec![0; Self::SIZE_MSG_CHUNKS - pos]; - padding[0] = 128u8; - self.buffer - .input_block(&padding, |b| Self::compress(hash, Self::convert(b))); - let mut second_padding = vec![0; Self::SIZE_MSG_CHUNKS - 8]; - second_padding - .extend_from_slice(&Self::helper_transform_usize(self.bit_length)); - self.buffer - .input_block(&second_padding, |b| Self::compress(hash, Self::convert(b))); - } - } - fn define_iv(index: usize) -> [u8; Self::SIZE_VECTORS] { let mut subset_pi: [u8; Self::SIZE_VECTORS] = [0u8; Self::SIZE_VECTORS]; subset_pi.copy_from_slice( @@ -72,21 +109,21 @@ macro_rules! fsb_impl { /// $(W_i)_{i\in[0;w-1]}$ between $0$ and $n - 1$. The value of each $W_i$ is computed /// from the inputs bits like this: /// $W_i = i \times (n / w) + IV_i + M_i \times 2^{r / w}. - fn computing_W_indices( + fn computing_w_indices( input_vector: &[u8; Self::SIZE_OUTPUT_COMPRESS], message: &[u8; Self::SIZE_MSG_CHUNKS], ) -> [u32; $w] { - let mut W_indices: [u32; $w] = [0; $w]; + let mut wind: [u32; $w] = [0; $w]; let divided_message: [u8; $w] = Self::dividing_bits(message, ($s - $r) / $w); for i in 0..($w) { let message_i = divided_message[i] as u32; - W_indices[i] = (i * $n / $w) as u32 + wind[i] = (i * $n / $w) as u32 + input_vector[i] as u32 + (message_i << ($r / $w) as u8); } - W_indices + wind } /// This function servers the purpose presented in table 3, of breaking a bit array into @@ -133,7 +170,7 @@ macro_rules! fsb_impl { ) { let mut initial_vector = [0u8; Self::SIZE_OUTPUT_COMPRESS]; - let w_indices = Self::computing_W_indices(hash, message_block); + let w_indices = Self::computing_w_indices(hash, message_block); for w_index in w_indices.iter() { let chosen_vec = w_index / $r as u32; let shift_value = w_index % $r as u32; @@ -149,18 +186,6 @@ macro_rules! fsb_impl { *hash = initial_vector; } - fn final_compression( - initial_vector: [u8; Self::SIZE_OUTPUT_COMPRESS], - ) -> [u8; Self::HASH_OUTPUT_SIZE] { - // Now we use Whirpool - let mut result = [0u8; Self::HASH_OUTPUT_SIZE]; - let mut hasher = Whirlpool::new(); - - Update::update(&mut hasher, &initial_vector); - result.copy_from_slice(&hasher.finalize()[..Self::HASH_OUTPUT_SIZE]); - result - } - fn shift_and_truncate( array: &mut [u8; Self::SIZE_VECTORS], shift_value: u32, @@ -170,9 +195,7 @@ macro_rules! fsb_impl { let mut truncated = [0u8; Self::SIZE_OUTPUT_COMPRESS]; if shift_value == 0 { - array[..Self::SIZE_OUTPUT_COMPRESS] - .try_into() - .expect("SIZE_VECTORS is always bigger than SIZE_OUTPUT_COMPRESS") + truncated.copy_from_slice(&array[..Self::SIZE_OUTPUT_COMPRESS]); } else if shift_value <= (bits_in_cue as u32) { let bytes_to_shift = 1; let starting_byte = (array_len - bytes_to_shift) as usize; @@ -183,8 +206,6 @@ macro_rules! fsb_impl { truncated[position] ^= array[position - 1] >> (8 - shift_value); truncated[position] ^= array[position] << shift_value; } - - truncated } else { // First we need to decide which is the last byte and bit that will go to the first position. // Then, we build our truncated array from there. Recall that the last byte is not complete, @@ -246,8 +267,6 @@ macro_rules! fsb_impl { } } } - - truncated } else { truncated[..bytes_to_shift].clone_from_slice( &array[starting_byte..(starting_byte + bytes_to_shift)], @@ -261,76 +280,14 @@ macro_rules! fsb_impl { truncated[position] ^= array[index] << (8 - bits_in_cue); truncated[position] ^= array[index + 1] >> bits_in_cue; } - truncated } } - } - - // I'm trying to avoid use unsafe code for this transformation. We are certain that the bit - // size of the buffer can be represented in 8 bytes. - fn helper_transform_usize(x: u64) -> [u8; 8] { - let b1: u8 = ((x >> 56) & 0xff) as u8; - let b2: u8 = ((x >> 48) & 0xff) as u8; - let b3: u8 = ((x >> 40) & 0xff) as u8; - let b4: u8 = ((x >> 32) & 0xff) as u8; - let b5: u8 = ((x >> 24) & 0xff) as u8; - let b6: u8 = ((x >> 16) & 0xff) as u8; - let b7: u8 = ((x >> 8) & 0xff) as u8; - let b8: u8 = (x & 0xff) as u8; - [b1, b2, b3, b4, b5, b6, b7, b8] + truncated } fn convert(block: &GenericArray) -> &[u8; Self::SIZE_MSG_CHUNKS] { - #[allow(unsafe_code)] - unsafe { - &*(block.as_ptr() as *const [u8; Self::SIZE_MSG_CHUNKS]) - } - } - } - - impl Default for $state { - fn default() -> Self { - Self { - bit_length: 0u64, - buffer: BlockBuffer::default(), - hash: [0u8; $r / 8], - } - } - } - - impl BlockInput for $state { - type BlockSize = $blocksize; - } - - impl Update for $state { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - self.update_len(input.len() as u64); - - let hash = &mut self.hash; - self.buffer - .input_block(input, |b| $state::compress(hash, $state::convert(b))); - } - } - - impl FixedOutputDirty for $state { - type OutputSize = $outputsize; - - fn finalize_into_dirty(&mut self, out: &mut GenericArray) { - self.finalize_inner(); - let final_whirpool = $state::final_compression(self.hash); - out.copy_from_slice(&final_whirpool) - } - } - - impl Reset for $state { - fn reset(&mut self) { - self.buffer.reset(); - self.hash = [0u8; $r / 8]; - self.bit_length = 0; + unsafe { &*(block.as_ptr() as *const [u8; Self::SIZE_MSG_CHUNKS]) } } } - opaque_debug::implement!($state); - digest::impl_write!($state); }; } diff --git a/fsb/tests/data/fsb160.blb b/fsb/tests/data/fsb160.blb index deecdfec303bb8ef168b39d361f3c9bc170c7e7c..7ea2346e72caf894116241710f82361ba36998bf 100644 GIT binary patch delta 107 zcmbQt*vlx(z?G4jlasHJ*YkX4pO4#;Q#En@DKnOqH#%JO4x6Z~?W(aTK2PP?@AP1M zE>&f#qh~m;R@!x$lw=kGp+ZSfVh#{06y%rW=N5pG#{Rwf22%aM&u`U G%1;0rS1jBB delta 91 zcmV-h0Hpto0h0kEVr*|>VtFwIXk~0{Zxn8f=b4U7Mx@GoUXNs$rFVfq(Mv0l9V-?T xqF-(##`|YeKMExyI>pQh)p8=tC3OG* diff --git a/fsb/tests/data/fsb224.blb b/fsb/tests/data/fsb224.blb index 57ca2febcff73a22056e1004825ae22a3f854a19..9a476c7239400c5ff8673837f54e229123ff9e0e 100644 GIT binary patch delta 82 zcmZ3@xRjBDfh!|5Cnw)xBA*On*hFn@OAFacy^~H|GdBHm$|q&%Lt&d!D-J*7u(}vJ hQG=b)q$INl2o*|-5_5o1p&-8`KeqskEGG8L008wIVniJ=NIQYD#1K&Vhsl$ZmA3I+Kk N`MCvPq%d)!0sxUt6=47X diff --git a/fsb/tests/data/fsb384.blb b/fsb/tests/data/fsb384.blb index 65cc572e6dcb5fad87d4d224333bb85125aa3a5b..60ce430d1cf53b5202ea8e1c818fd36026c6db3f 100644 GIT binary patch delta 36 qcmaFP_>hrX=STrr+YJEEhYM5y delta 64 zcmaFJ_?(e1DJMTEsnU=&BQ+-{-(Vt#0i*UrOKnDjiKzxMQYD#1K&Vhsl$ZmA3I+Kk N`MCvPWH51~0RXq|7GVGY diff --git a/fsb/tests/data/fsb512.blb b/fsb/tests/data/fsb512.blb index fa6c7b3d9c5c3c9666f7c7c8ab27b22ed4f8bac1..f20de348a655f613b1379f08576ab9cbe4a847b3 100644 GIT binary patch delta 39 rcmbQvG=+(ifh!|5CnvvwVIrRcW7tH0Z6+YI+JVtz;vOjw^ST27**XiX delta 64 zcmbQjG@XerDJMTEsnU=&BQ+-{-(e!B1EcmtFKtGLiRBJ5QYD#1K&Vhsl$ZmA3I+Kk N`MCvP(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/gost94/examples/gost94_test_sum.rs b/gost94/examples/gost94_test_sum.rs deleted file mode 100644 index 8f31b1906..000000000 --- a/gost94/examples/gost94_test_sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use gost94::{Digest, Gost94Test}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/gost94/src/cryptopro.rs b/gost94/src/cryptopro.rs deleted file mode 100644 index e290472ca..000000000 --- a/gost94/src/cryptopro.rs +++ /dev/null @@ -1,12 +0,0 @@ -const S_CRYPTO_PRO: SBox = [ - [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], - [7, 15, 12, 14, 9, 4, 1, 0, 3, 11, 5, 2, 6, 10, 8, 13], - [4, 10, 7, 12, 0, 15, 2, 8, 14, 1, 6, 5, 13, 11, 9, 3], - [7, 6, 4, 11, 9, 12, 2, 10, 1, 8, 0, 14, 15, 13, 3, 5], - [7, 6, 2, 4, 13, 9, 15, 0, 10, 1, 5, 11, 8, 14, 12, 3], - [13, 14, 4, 1, 7, 0, 5, 10, 3, 12, 8, 15, 6, 2, 9, 11], - [1, 3, 10, 9, 5, 11, 4, 15, 8, 6, 7, 14, 13, 0, 2, 12], -]; - -gost94_impl!(Gost94CryptoPro, S_CRYPTO_PRO); diff --git a/gost94/src/gost94.rs b/gost94/src/gost94_core.rs similarity index 63% rename from gost94/src/gost94.rs rename to gost94/src/gost94_core.rs index 8bbb0fe5a..569789a0b 100644 --- a/gost94/src/gost94.rs +++ b/gost94/src/gost94_core.rs @@ -1,19 +1,23 @@ #![allow(clippy::many_single_char_names)] -use block_buffer::block_padding::ZeroPadding; -use block_buffer::BlockBuffer; -use core::convert::TryInto; -use digest::{consts::U32, generic_array::GenericArray}; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; - -pub(crate) type Block = [u8; 32]; +use core::{convert::TryInto, fmt}; +use digest::{ + block_buffer::Eager, + consts::U32, + core_api::{ + AlgorithmName, Block as TBlock, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::{typenum::Unsigned, GenericArray}, + HashMarker, Output, +}; + +use crate::params::{Block, Gost94Params, SBox}; const C: Block = [ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, ]; -pub type SBox = [[u8; 16]; 8]; - fn sbox(a: u32, s: &SBox) -> u32 { let mut v = 0; @@ -114,15 +118,23 @@ fn psi(block: &mut Block) { block.copy_from_slice(&out); } +#[inline(always)] +fn adc(a: &mut u64, b: u64, carry: &mut u64) { + let ret = (*a as u128) + (b as u128) + (*carry as u128); + *a = ret as u64; + *carry = (ret >> 64) as u64; +} + +/// Core GOST94 algorithm generic over parameters. #[derive(Clone)] -struct Gost94State { - s: SBox, +pub struct Gost94Core { h: Block, n: [u64; 4], sigma: [u64; 4], + _m: core::marker::PhantomData

, } -impl Gost94State { +impl Gost94Core

{ fn shuffle(&mut self, m: &Block, s: &Block) { let mut res = Block::default(); res.copy_from_slice(s); @@ -141,23 +153,23 @@ impl Gost94State { let mut s = Block::default(); s.copy_from_slice(&self.h); let k = p(x(&self.h, m)); - encrypt(&mut s[0..8], k, &self.s); + encrypt(&mut s[0..8], k, &P::S_BOX); let u = a(self.h); let v = a(a(*m)); let k = p(x(&u, &v)); - encrypt(&mut s[8..16], k, &self.s); + encrypt(&mut s[8..16], k, &P::S_BOX); let mut u = a(u); x_mut(&mut u, &C); let v = a(a(v)); let k = p(x(&u, &v)); - encrypt(&mut s[16..24], k, &self.s); + encrypt(&mut s[16..24], k, &P::S_BOX); let u = a(u); let v = a(a(v)); let k = p(x(&u, &v)); - encrypt(&mut s[24..32], k, &self.s); + encrypt(&mut s[24..32], k, &P::S_BOX); self.shuffle(m, &s); } @@ -178,92 +190,88 @@ impl Gost94State { adc(&mut self.n[3], 0, &mut carry); } - fn process_block(&mut self, block: &GenericArray) { + #[inline(always)] + fn compress(&mut self, block: &GenericArray) { let block = unsafe { &*(block.as_ptr() as *const [u8; 32]) }; self.f(block); self.update_sigma(block); } } -/// GOST94 -#[derive(Clone)] -pub struct Gost94 { - buffer: BlockBuffer, - state: Gost94State, - h0: Block, -} - -impl Gost94 { - /// Create new [`Gost94`] instance with given S-Box and IV - pub fn new(s: SBox, h: Block) -> Self { - let n = Default::default(); - let sigma = Default::default(); - Gost94 { - buffer: Default::default(), - h0: h, - state: Gost94State { s, h, n, sigma }, - } - } -} +impl HashMarker for Gost94Core

{} -impl BlockInput for Gost94 { +impl BlockSizeUser for Gost94Core

{ type BlockSize = U32; } -impl Update for Gost94 { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - let s = &mut self.state; - s.update_n(input.len()); - self.buffer.input_block(input, |d| s.process_block(d)); - } +impl BufferKindUser for Gost94Core

{ + type BufferKind = Eager; } -impl FixedOutputDirty for Gost94 { +impl OutputSizeUser for Gost94Core

{ type OutputSize = U32; +} - fn finalize_into_dirty(&mut self, out: &mut GenericArray) { - let self_state = &mut self.state; - - if self.buffer.position() != 0 { - let block = self - .buffer - .pad_with::() - .expect("we never use input_lazy"); +impl UpdateCore for Gost94Core

{ + #[inline] + fn update_blocks(&mut self, blocks: &[TBlock]) { + let len = Self::BlockSize::USIZE * blocks.len(); + self.update_n(len); + blocks.iter().for_each(|b| self.compress(b)); + } +} - self_state.process_block(block); +impl FixedOutputCore for Gost94Core

{ + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + if buffer.get_pos() != 0 { + self.update_n(buffer.get_pos()); + self.compress(buffer.pad_with_zeros()); } let mut buf = Block::default(); - for (o, v) in buf.chunks_exact_mut(8).zip(self_state.n.iter()) { + for (o, v) in buf.chunks_exact_mut(8).zip(self.n.iter()) { o.copy_from_slice(&v.to_le_bytes()); } - self_state.f(&buf); + self.f(&buf); - for (o, v) in buf.chunks_exact_mut(8).zip(self_state.sigma.iter()) { + for (o, v) in buf.chunks_exact_mut(8).zip(self.sigma.iter()) { o.copy_from_slice(&v.to_le_bytes()); } - self_state.f(&buf); + self.f(&buf); - out.copy_from_slice(&self.state.h); + out.copy_from_slice(&self.h); + } +} + +impl Default for Gost94Core

{ + #[inline] + fn default() -> Self { + Self { + h: P::H0, + n: Default::default(), + sigma: Default::default(), + _m: Default::default(), + } } } -impl Reset for Gost94 { +impl Reset for Gost94Core

{ + #[inline] fn reset(&mut self) { - self.buffer.reset(); - self.state.n = Default::default(); - self.state.h = self.h0; - self.state.sigma = Default::default(); + *self = Default::default(); } } -#[inline(always)] -fn adc(a: &mut u64, b: u64, carry: &mut u64) { - let ret = (*a as u128) + (b as u128) + (*carry as u128); - *a = ret as u64; - *carry = (ret >> 64) as u64; +impl AlgorithmName for Gost94Core

{ + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(P::NAME) + } } -opaque_debug::implement!(Gost94); -digest::impl_write!(Gost94); +impl fmt::Debug for Gost94Core

{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str(P::NAME)?; + f.write_str("Core { .. }") + } +} diff --git a/gost94/src/lib.rs b/gost94/src/lib.rs index 7754c3c49..8427b2c55 100644 --- a/gost94/src/lib.rs +++ b/gost94/src/lib.rs @@ -1,22 +1,21 @@ //! An implementation of the [GOST R 34.11-94][1] cryptographic hash algorithm. //! //! # Usage -//! //! ```rust -//! use gost94::{Gost94Test, Digest}; +//! use gost94::{Gost94CryptoPro, Digest}; //! use hex_literal::hex; //! -//! // create a Gost94 hasher instance with test S-box -//! let mut hasher = Gost94Test::new(); +//! // create Gost94 hasher instance with CryptoPro params +//! let mut hasher = Gost94CryptoPro::new(); //! //! // process input message -//! hasher.update(b"hello world"); +//! hasher.update("The quick brown fox jumps over the lazy dog"); //! //! // acquire hash digest in the form of GenericArray, //! // which in this case is equivalent to [u8; 32] //! let result = hasher.finalize(); //! assert_eq!(result[..], hex!(" -//! 1bb6ce69d2e895a78489c87a0712a2f40258d1fae3a4666c23f8f487bef0e22a +//! 9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76 //! ")); //! ``` //! @@ -27,25 +26,28 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/gost94/0.10.0" )] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "std")] extern crate std; -#[macro_use] -mod macros; +use digest::core_api::CoreWrapper; -mod cryptopro; -mod gost94; -mod s2015; -mod test_param; +mod gost94_core; +/// GOST94 parameters. +pub mod params; pub use digest::{self, Digest}; -pub use crate::cryptopro::Gost94CryptoPro; -pub use crate::gost94::Gost94; -pub use crate::s2015::Gost94s2015; -pub use crate::test_param::Gost94Test; +pub use gost94_core::Gost94Core; + +/// GOST94 hash function with CryptoPro parameters. +pub type Gost94CryptoPro = CoreWrapper>; +/// GOST94 hash function with S-box defined in GOST R 34.12-2015. +pub type Gost94s2015 = CoreWrapper>; +/// GOST94 hash function with test parameters. +pub type Gost94Test = CoreWrapper>; diff --git a/gost94/src/macros.rs b/gost94/src/macros.rs deleted file mode 100644 index cd78628e7..000000000 --- a/gost94/src/macros.rs +++ /dev/null @@ -1,48 +0,0 @@ -macro_rules! gost94_impl { - ($state:ident, $sbox:expr) => { - use digest::{consts::U32, BlockInput, FixedOutputDirty, Reset, Update}; - use $crate::gost94::{Block, Gost94, SBox}; - - /// GOST94 state - #[derive(Clone)] - pub struct $state { - sh: Gost94, - } - - impl Default for $state { - fn default() -> Self { - $state { - sh: Gost94::new($sbox, Block::default()), - } - } - } - - impl BlockInput for $state { - type BlockSize = U32; - } - - impl Update for $state { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - self.sh.update(input); - } - } - - impl FixedOutputDirty for $state { - type OutputSize = U32; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.sh.finalize_into_dirty(out) - } - } - - impl Reset for $state { - fn reset(&mut self) { - self.sh.reset() - } - } - - opaque_debug::implement!($state); - digest::impl_write!($state); - }; -} diff --git a/gost94/src/params.rs b/gost94/src/params.rs new file mode 100644 index 000000000..c7bf9459a --- /dev/null +++ b/gost94/src/params.rs @@ -0,0 +1,70 @@ +pub(crate) type Block = [u8; 32]; +pub(crate) type SBox = [[u8; 16]; 8]; + +/// Trait for storing parameter constants. +// TODO: replace with const generics +pub trait Gost94Params { + /// S-box value. + const S_BOX: SBox; + /// Initialization vector value. + const H0: Block; + /// Algorithm name + const NAME: &'static str; +} + +/// CryptoPro parameters. +#[derive(Copy, Clone, Default)] +pub struct CryptoProParam; + +impl Gost94Params for CryptoProParam { + const S_BOX: SBox = [ + [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], + [7, 15, 12, 14, 9, 4, 1, 0, 3, 11, 5, 2, 6, 10, 8, 13], + [4, 10, 7, 12, 0, 15, 2, 8, 14, 1, 6, 5, 13, 11, 9, 3], + [7, 6, 4, 11, 9, 12, 2, 10, 1, 8, 0, 14, 15, 13, 3, 5], + [7, 6, 2, 4, 13, 9, 15, 0, 10, 1, 5, 11, 8, 14, 12, 3], + [13, 14, 4, 1, 7, 0, 5, 10, 3, 12, 8, 15, 6, 2, 9, 11], + [1, 3, 10, 9, 5, 11, 4, 15, 8, 6, 7, 14, 13, 0, 2, 12], + ]; + const H0: Block = [0; 32]; + const NAME: &'static str = "Gost94CryptoPro"; +} + +/// S-Box defined in GOST R 34.12-2015. +#[derive(Copy, Clone, Default)] +pub struct S2015Param; + +impl Gost94Params for S2015Param { + const S_BOX: SBox = [ + [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], + [11, 3, 5, 8, 2, 15, 10, 13, 14, 1, 7, 4, 12, 9, 6, 0], + [12, 8, 2, 1, 13, 4, 15, 6, 7, 0, 10, 5, 3, 14, 9, 11], + [7, 15, 5, 10, 8, 1, 6, 13, 0, 9, 3, 14, 11, 4, 2, 12], + [5, 13, 15, 6, 9, 2, 12, 10, 11, 7, 8, 1, 4, 3, 14, 0], + [8, 14, 2, 5, 6, 9, 1, 12, 15, 4, 11, 0, 13, 10, 3, 7], + [1, 7, 14, 13, 0, 5, 8, 3, 4, 15, 10, 6, 9, 12, 11, 2], + ]; + const H0: Block = [0; 32]; + const NAME: &'static str = "Gost94s2015"; +} + +/// Test parameters. +#[derive(Copy, Clone, Default)] +pub struct TestParam; + +impl Gost94Params for TestParam { + const S_BOX: SBox = [ + [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], + [5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11], + [7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3], + [6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2], + [4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14], + [13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12], + [1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12], + ]; + const H0: Block = [0; 32]; + const NAME: &'static str = "Gost94Test"; +} diff --git a/gost94/src/s2015.rs b/gost94/src/s2015.rs deleted file mode 100644 index ac01a5c29..000000000 --- a/gost94/src/s2015.rs +++ /dev/null @@ -1,12 +0,0 @@ -const S2015: SBox = [ - [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], - [11, 3, 5, 8, 2, 15, 10, 13, 14, 1, 7, 4, 12, 9, 6, 0], - [12, 8, 2, 1, 13, 4, 15, 6, 7, 0, 10, 5, 3, 14, 9, 11], - [7, 15, 5, 10, 8, 1, 6, 13, 0, 9, 3, 14, 11, 4, 2, 12], - [5, 13, 15, 6, 9, 2, 12, 10, 11, 7, 8, 1, 4, 3, 14, 0], - [8, 14, 2, 5, 6, 9, 1, 12, 15, 4, 11, 0, 13, 10, 3, 7], - [1, 7, 14, 13, 0, 5, 8, 3, 4, 15, 10, 6, 9, 12, 11, 2], -]; - -gost94_impl!(Gost94s2015, S2015); diff --git a/gost94/src/test_param.rs b/gost94/src/test_param.rs deleted file mode 100644 index f1b202f6e..000000000 --- a/gost94/src/test_param.rs +++ /dev/null @@ -1,12 +0,0 @@ -const S_TEST: SBox = [ - [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], - [5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11], - [7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3], - [6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2], - [4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14], - [13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12], - [1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12], -]; - -gost94_impl!(Gost94Test, S_TEST); diff --git a/gost94/tests/data/cryptopro.blb b/gost94/tests/data/cryptopro.blb index 8ff577b113fadbfef769831daaa30a841b94828a..ace31477a6dc60621a000071b6d07c20808dcdda 100644 GIT binary patch delta 168 zcmey&@{Wa>fx%%SrvfumqQgWT1y;7iq-2MQfeHdLxv9m)iRq~dDVgc1#U&0C8x@!u z876KloOpm=$w9{Jc%s|H-CxvyDT^s)zxc>I>Fr>+GgC!+D z-C=S8qXHv{tIg;zc`uOdF!>&s{0}5kCMz%*DLNc3=84&J>iop0LzB|;6<_T2`yOm~ Q(;+TiD)Ek?!Lk5B04#1jZ2$lO delta 146 zcmaFI@|i^^DJMTEsnU=^VTN41&0?Mwk@jZ(mfy~H!fON>!)DJBj_^9ttn70w>;Pk; z!bCL%R_4T{WQB>|3Icq&sl~;K>8T1Sndzy;B?=R(6&M>PF07fjfrU|FvK*rVqxNKb mMr|NF8_L#TNzPAKn7jkXRhWDeO#T9rMw6wPjDRA3ObP(qxGYcr diff --git a/gost94/tests/data/test.blb b/gost94/tests/data/test.blb index 12fcc2b563b2cde38c965081b38921e8c48bd724..94f08fe9ac11afac38e241071e8e9d99d5d08a32 100644 GIT binary patch delta 168 zcmey&@{Wa>fx%%SrvfumqQgWT1y;7iq-2MQfeHdLxv9m)iRq~dDVgc1#U&0C8x@!u z876KloOpm=$su_0;TlwN&xbc#($rBkhSW@!S z9VQnrDlme$+Kdj9_X61tlkb7a|3ETjvI3KlqJz8CuJC1C<-As9!fd7of4}nk==)T@ PV#~VlyPeiaUxPRR0*pEr delta 146 zcmaFI@|i^^DJMTEsnU=^;auy^IY-ii{{MR%vwBuFQ^o2nhc2; + +#[inline(always)] +fn column(x: &[u64; COLS], c: [usize; 8]) -> u64 { + let mut t = 0; + for i in 0..8 { + let sl = 8 * (7 - i); + let idx = ((x[c[i]] >> sl) & 0xFF) as usize; + t ^= TABLE[i][idx]; + } + t +} + +#[inline(always)] +fn rndq(mut x: [u64; COLS], r: u64) -> [u64; COLS] { + for i in 0..COLS { + x[i] ^= u64::MAX.wrapping_sub((i as u64) << 4) ^ r; + } + [ + column(&x, [1, 3, 5, 11, 0, 2, 4, 6]), + column(&x, [2, 4, 6, 12, 1, 3, 5, 7]), + column(&x, [3, 5, 7, 13, 2, 4, 6, 8]), + column(&x, [4, 6, 8, 14, 3, 5, 7, 9]), + column(&x, [5, 7, 9, 15, 4, 6, 8, 10]), + column(&x, [6, 8, 10, 0, 5, 7, 9, 11]), + column(&x, [7, 9, 11, 1, 6, 8, 10, 12]), + column(&x, [8, 10, 12, 2, 7, 9, 11, 13]), + column(&x, [9, 11, 13, 3, 8, 10, 12, 14]), + column(&x, [10, 12, 14, 4, 9, 11, 13, 15]), + column(&x, [11, 13, 15, 5, 10, 12, 14, 0]), + column(&x, [12, 14, 0, 6, 11, 13, 15, 1]), + column(&x, [13, 15, 1, 7, 12, 14, 0, 2]), + column(&x, [14, 0, 2, 8, 13, 15, 1, 3]), + column(&x, [15, 1, 3, 9, 14, 0, 2, 4]), + column(&x, [0, 2, 4, 10, 15, 1, 3, 5]), + ] +} + +#[inline(always)] +fn rndp(mut x: [u64; COLS], r: u64) -> [u64; COLS] { + for i in 0..COLS { + x[i] ^= ((i as u64) << 60) ^ r; + } + [ + column(&x, [0, 1, 2, 3, 4, 5, 6, 11]), + column(&x, [1, 2, 3, 4, 5, 6, 7, 12]), + column(&x, [2, 3, 4, 5, 6, 7, 8, 13]), + column(&x, [3, 4, 5, 6, 7, 8, 9, 14]), + column(&x, [4, 5, 6, 7, 8, 9, 10, 15]), + column(&x, [5, 6, 7, 8, 9, 10, 11, 0]), + column(&x, [6, 7, 8, 9, 10, 11, 12, 1]), + column(&x, [7, 8, 9, 10, 11, 12, 13, 2]), + column(&x, [8, 9, 10, 11, 12, 13, 14, 3]), + column(&x, [9, 10, 11, 12, 13, 14, 15, 4]), + column(&x, [10, 11, 12, 13, 14, 15, 0, 5]), + column(&x, [11, 12, 13, 14, 15, 0, 1, 6]), + column(&x, [12, 13, 14, 15, 0, 1, 2, 7]), + column(&x, [13, 14, 15, 0, 1, 2, 3, 8]), + column(&x, [14, 15, 0, 1, 2, 3, 4, 9]), + column(&x, [15, 0, 1, 2, 3, 4, 5, 10]), + ] +} + +pub(crate) fn compress(h: &mut [u64; COLS], block: &Block) { + let mut q = [0u64; COLS]; + for (chunk, v) in block.chunks_exact(8).zip(q.iter_mut()) { + *v = u64::from_be_bytes(chunk.try_into().unwrap()); + } + let mut p = [0u64; COLS]; + for i in 0..COLS { + p[i] = h[i] ^ q[i]; + } + for i in 0..ROUNDS { + q = rndq(q, i); + } + for i in 0..ROUNDS { + p = rndp(p, i << 56); + } + for i in 0..COLS { + h[i] ^= q[i] ^ p[i]; + } +} + +pub(crate) fn p(h: &[u64; COLS]) -> [u64; COLS] { + let mut p = *h; + for i in 0..ROUNDS { + p = rndp(p, i << 56); + } + for i in 0..COLS { + p[i] ^= h[i]; + } + p +} diff --git a/groestl/src/compress512.rs b/groestl/src/compress512.rs new file mode 100644 index 000000000..1db8d4091 --- /dev/null +++ b/groestl/src/compress512.rs @@ -0,0 +1,83 @@ +#![allow(clippy::needless_range_loop)] +use crate::table::TABLE; +use core::{convert::TryInto, u64}; +type Block = super::Block; + +pub(crate) const COLS: usize = 8; +const ROUNDS: u64 = 10; + +#[inline(always)] +fn column(x: &[u64; COLS], c: [usize; 8]) -> u64 { + let mut t = 0; + for i in 0..8 { + let sl = 8 * (7 - i); + let idx = ((x[c[i]] >> sl) & 0xFF) as usize; + t ^= TABLE[i][idx]; + } + t +} + +#[inline(always)] +fn rndq(mut x: [u64; COLS], r: u64) -> [u64; COLS] { + for i in 0..COLS { + x[i] ^= u64::MAX.wrapping_sub((i as u64) << 4) ^ r; + } + [ + column(&x, [1, 3, 5, 7, 0, 2, 4, 6]), + column(&x, [2, 4, 6, 0, 1, 3, 5, 7]), + column(&x, [3, 5, 7, 1, 2, 4, 6, 0]), + column(&x, [4, 6, 0, 2, 3, 5, 7, 1]), + column(&x, [5, 7, 1, 3, 4, 6, 0, 2]), + column(&x, [6, 0, 2, 4, 5, 7, 1, 3]), + column(&x, [7, 1, 3, 5, 6, 0, 2, 4]), + column(&x, [0, 2, 4, 6, 7, 1, 3, 5]), + ] +} + +#[inline(always)] +fn rndp(mut x: [u64; COLS], r: u64) -> [u64; COLS] { + for i in 0..COLS { + x[i] ^= ((i as u64) << 60) ^ r; + } + [ + column(&x, [0, 1, 2, 3, 4, 5, 6, 7]), + column(&x, [1, 2, 3, 4, 5, 6, 7, 0]), + column(&x, [2, 3, 4, 5, 6, 7, 0, 1]), + column(&x, [3, 4, 5, 6, 7, 0, 1, 2]), + column(&x, [4, 5, 6, 7, 0, 1, 2, 3]), + column(&x, [5, 6, 7, 0, 1, 2, 3, 4]), + column(&x, [6, 7, 0, 1, 2, 3, 4, 5]), + column(&x, [7, 0, 1, 2, 3, 4, 5, 6]), + ] +} + +pub(crate) fn compress(h: &mut [u64; COLS], block: &Block) { + let mut q = [0u64; COLS]; + for (chunk, v) in block.chunks_exact(8).zip(q.iter_mut()) { + *v = u64::from_be_bytes(chunk.try_into().unwrap()); + } + let mut p = [0u64; COLS]; + for i in 0..COLS { + p[i] = h[i] ^ q[i]; + } + for i in 0..ROUNDS { + q = rndq(q, i); + } + for i in 0..ROUNDS { + p = rndp(p, i << 56); + } + for i in 0..COLS { + h[i] ^= q[i] ^ p[i]; + } +} + +pub(crate) fn p(h: &[u64; COLS]) -> [u64; COLS] { + let mut p = *h; + for i in 0..ROUNDS { + p = rndp(p, i << 56); + } + for i in 0..COLS { + p[i] ^= h[i]; + } + p +} diff --git a/groestl/src/consts.rs b/groestl/src/consts.rs deleted file mode 100644 index 6b09c6a25..000000000 --- a/groestl/src/consts.rs +++ /dev/null @@ -1,55 +0,0 @@ -pub const SBOX: [u8; 256] = [ - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, -]; - -pub const C_P: [u8; 128] = [ - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -]; -pub const C_Q: [u8; 128] = [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xef, 0xdf, 0xcf, 0xbf, 0xaf, 0x9f, 0x8f, 0x7f, 0x6f, 0x5f, 0x4f, 0x3f, 0x2f, 0x1f, 0x0f, -]; - -pub const B: [[u8; 8]; 8] = [ - [2, 2, 3, 4, 5, 3, 5, 7], - [7, 2, 2, 3, 4, 5, 3, 5], - [5, 7, 2, 2, 3, 4, 5, 3], - [3, 5, 7, 2, 2, 3, 4, 5], - [5, 3, 5, 7, 2, 2, 3, 4], - [4, 5, 3, 5, 7, 2, 2, 3], - [3, 4, 5, 3, 5, 7, 2, 2], - [2, 3, 4, 5, 3, 5, 7, 2], -]; - -pub const SHIFTS_P: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7]; -pub const SHIFTS_Q: [u8; 8] = [1, 3, 5, 7, 0, 2, 4, 6]; -pub const SHIFTS_P_WIDE: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 11]; -pub const SHIFTS_Q_WIDE: [u8; 8] = [1, 3, 5, 11, 0, 2, 4, 6]; diff --git a/groestl/src/groestl.rs b/groestl/src/groestl.rs deleted file mode 100644 index 1690de283..000000000 --- a/groestl/src/groestl.rs +++ /dev/null @@ -1,76 +0,0 @@ -use block_buffer::BlockBuffer; -use core::ops::Div; -use digest::generic_array::typenum::{Quot, U8}; -use digest::generic_array::{ArrayLength, GenericArray}; - -use crate::state::{xor_generic_array, GroestlState}; - -#[derive(Clone)] -pub struct Groestl -where - BlockSize: ArrayLength + Div + Default, - BlockSize::ArrayType: Copy, - Quot: ArrayLength, -{ - buffer: BlockBuffer, - state: GroestlState, - pub output_size: usize, -} - -impl Groestl -where - BlockSize: ArrayLength + Div + Default, - BlockSize::ArrayType: Copy, - Quot: ArrayLength, - Self: Clone, -{ - pub fn new(output_size: usize) -> Result { - match BlockSize::to_usize() { - 128 => { - if output_size <= 32 || output_size > 64 { - return Err(digest::InvalidOutputSize); - } - } - 64 => { - if output_size == 0 || output_size > 32 { - return Err(digest::InvalidOutputSize); - } - } - _ => unreachable!(), - }; - - let state = GroestlState::new(output_size); - Ok(Groestl { - buffer: Default::default(), - state, - output_size, - }) - } - - pub fn process(&mut self, input: &[u8]) { - let s = &mut self.state; - self.buffer.input_block(input, |b| s.compress(b)); - } - - pub fn finalize(&mut self) -> GenericArray { - let res = { - let state = &mut self.state; - let l = if self.buffer.remaining() <= 8 { - state.num_blocks + 2 - } else { - state.num_blocks + 1 - }; - self.buffer.len64_padding_be(l, |b| state.compress(b)); - xor_generic_array(&state.p(&state.state), &state.state) - }; - - self.buffer = Default::default(); - self.state = GroestlState::new(self.output_size); - res - } - - pub fn reset(&mut self) { - self.state = GroestlState::new(self.output_size); - self.buffer.reset(); - } -} diff --git a/groestl/src/lib.rs b/groestl/src/lib.rs old mode 100755 new mode 100644 index d4c8155ec..d7fb0d617 --- a/groestl/src/lib.rs +++ b/groestl/src/lib.rs @@ -2,14 +2,7 @@ //! //! # Usage //! -//! Groestl can produce a digest of any size between 1 and 64 bytes inclusive. -//! This crate defines the common digest sizes (`Groestl224`, `Groestl256`, -//! `Groestl384`, and `Groestl512`), but allows you to specify a custom size -//! with the `GroestlSmall` and `GroestlBig` structs. `GroestlSmall` allows you -//! to specify a digest size between 1 and 32 inclusive, and `GroestlBig` allows -//! you to specify a digest size between 33 and 64 inclusive. -//! -//! ```rust +//! ``` //! use groestl::{Digest, Groestl256}; //! use hex_literal::hex; //! @@ -34,33 +27,204 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/groestl/0.10.0" )] #![deny(unsafe_code)] #![warn(rust_2018_idioms)] -#[cfg(feature = "std")] -extern crate std; - pub use digest::{self, Digest}; -mod consts; -mod groestl; -mod matrix; -mod state; -#[macro_use] -mod macros; - -use crate::groestl::Groestl; -use digest::consts::{U128, U28, U32, U48, U64}; -use digest::generic_array::typenum::Unsigned; -use digest::{BlockInput, FixedOutputDirty, InvalidOutputSize, Reset, Update, VariableOutputDirty}; - -impl_groestl!(Groestl512, U64, U128); -impl_groestl!(Groestl384, U48, U128); -impl_groestl!(Groestl256, U32, U64); -impl_groestl!(Groestl224, U28, U64); - -impl_variable_groestl!(GroestlBig, U128, 32, 64); -impl_variable_groestl!(GroestlSmall, U64, 0, 32); +use core::fmt; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, + CtVariableCoreWrapper, RtVariableCoreWrapper, UpdateCore, VariableOutputCore, + }, + generic_array::typenum::{Unsigned, U128, U28, U32, U48, U64}, + HashMarker, InvalidOutputSize, +}; + +mod compress1024; +mod compress512; +mod table; + +/// Lowest-level core hasher state of the short Groestl variant. +#[derive(Clone)] +pub struct GroestlShortVarCore { + state: [u64; compress512::COLS], + blocks_len: u64, +} + +impl HashMarker for GroestlShortVarCore {} + +impl BlockSizeUser for GroestlShortVarCore { + type BlockSize = U64; +} + +impl BufferKindUser for GroestlShortVarCore { + type BufferKind = Eager; +} + +impl UpdateCore for GroestlShortVarCore { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.blocks_len += blocks.len() as u64; + for block in blocks { + compress512::compress(&mut self.state, block); + } + } +} + +impl VariableOutputCore for GroestlShortVarCore { + type MaxOutputSize = U32; + + #[inline] + fn new(output_size: usize) -> Result { + if output_size > Self::MaxOutputSize::USIZE { + return Err(InvalidOutputSize); + } + let mut state = [0; compress512::COLS]; + state[compress512::COLS - 1] = 8 * output_size as u64; + let blocks_len = 0; + Ok(Self { state, blocks_len }) + } + + #[inline] + fn finalize_variable_core( + &mut self, + buffer: &mut Buffer, + output_size: usize, + f: impl FnOnce(&[u8]), + ) { + let blocks_len = if buffer.remaining() <= 8 { + self.blocks_len + 2 + } else { + self.blocks_len + 1 + }; + buffer.len64_padding_be(blocks_len, |b| compress512::compress(&mut self.state, b)); + let res = compress512::p(&self.state); + let mut buf = [0; Self::MaxOutputSize::USIZE]; + let n = compress512::COLS / 2; + for (chunk, v) in buf.chunks_exact_mut(8).zip(res[n..].iter()) { + chunk.copy_from_slice(&v.to_be_bytes()); + } + f(&buf[buf.len() - output_size..]) + } +} + +impl AlgorithmName for GroestlShortVarCore { + #[inline] + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("GroestlShort") + } +} + +impl fmt::Debug for GroestlShortVarCore { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("GroestlShortVarCore { ... }") + } +} + +/// Short Groestl variant which allows to choose output size at runtime. +pub type GroestlShortVar = RtVariableCoreWrapper; +/// Core hasher state of the short Groestl variant generic over output size. +pub type GroestlShortCore = CtVariableCoreWrapper; +/// Hasher state of the short Groestl variant generic over output size. +pub type GroestlShort = CoreWrapper>; + +/// Groestl-224 hasher state. +pub type Groestl224 = CoreWrapper>; +/// Groestl-256 hasher state. +pub type Groestl256 = CoreWrapper>; + +/// Lowest-level core hasher state of the long Groestl variant. +#[derive(Clone)] +pub struct GroestlLongVarCore { + state: [u64; compress1024::COLS], + blocks_len: u64, +} + +impl HashMarker for GroestlLongVarCore {} + +impl BlockSizeUser for GroestlLongVarCore { + type BlockSize = U128; +} + +impl BufferKindUser for GroestlLongVarCore { + type BufferKind = Eager; +} + +impl UpdateCore for GroestlLongVarCore { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.blocks_len += blocks.len() as u64; + for block in blocks { + compress1024::compress(&mut self.state, block); + } + } +} + +impl VariableOutputCore for GroestlLongVarCore { + type MaxOutputSize = U64; + + #[inline] + fn new(output_size: usize) -> Result { + if output_size > Self::MaxOutputSize::USIZE { + return Err(InvalidOutputSize); + } + let mut state = [0; compress1024::COLS]; + state[compress1024::COLS - 1] = 8 * output_size as u64; + let blocks_len = 0; + Ok(Self { state, blocks_len }) + } + + #[inline] + fn finalize_variable_core( + &mut self, + buffer: &mut Buffer, + output_size: usize, + f: impl FnOnce(&[u8]), + ) { + let blocks_len = if buffer.remaining() <= 8 { + self.blocks_len + 2 + } else { + self.blocks_len + 1 + }; + buffer.len64_padding_be(blocks_len, |b| compress1024::compress(&mut self.state, b)); + let res = compress1024::p(&self.state); + let mut buf = [0; Self::MaxOutputSize::USIZE]; + let n = compress1024::COLS / 2; + for (chunk, v) in buf.chunks_exact_mut(8).zip(res[n..].iter()) { + chunk.copy_from_slice(&v.to_be_bytes()); + } + f(&buf[buf.len() - output_size..]) + } +} + +impl AlgorithmName for GroestlLongVarCore { + #[inline] + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("GroestlLong") + } +} + +impl fmt::Debug for GroestlLongVarCore { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("GroestlLongVarCore { ... }") + } +} + +/// Long Groestl variant which allows to choose output size at runtime. +pub type GroestlLongVar = RtVariableCoreWrapper; +/// Core hasher state of the long Groestl variant generic over output size. +pub type GroestlLongCore = CtVariableCoreWrapper; +/// Hasher state of the long Groestl variant generic over output size. +pub type GroestlLong = CoreWrapper>; + +/// Groestl-384 hasher state. +pub type Groestl384 = CoreWrapper>; +/// Groestl-512 hasher state. +pub type Groestl512 = CoreWrapper>; diff --git a/groestl/src/macros.rs b/groestl/src/macros.rs deleted file mode 100644 index 00a54e338..000000000 --- a/groestl/src/macros.rs +++ /dev/null @@ -1,95 +0,0 @@ -macro_rules! impl_groestl { - ($state:ident, $output:ident, $block:ident) => { - #[derive(Clone)] - pub struct $state { - groestl: Groestl<$block>, - } - - impl Default for $state { - fn default() -> Self { - $state { - groestl: Groestl::new($output::to_usize()).unwrap(), - } - } - } - - impl BlockInput for $state { - type BlockSize = $block; - } - - impl Update for $state { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - self.groestl.process(input); - } - } - - impl FixedOutputDirty for $state { - type OutputSize = $output; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - let block = self.groestl.finalize(); - let n = block.len() - Self::OutputSize::to_usize(); - out.copy_from_slice(&block[n..]) - } - } - - impl Reset for $state { - fn reset(&mut self) { - self.groestl.reset() - } - } - - opaque_debug::implement!($state); - digest::impl_write!($state); - }; -} - -macro_rules! impl_variable_groestl { - ($state:ident, $block:ident, $min:expr, $max:expr) => { - #[derive(Clone)] - pub struct $state { - groestl: Groestl<$block>, - } - - impl BlockInput for $state { - type BlockSize = $block; - } - - impl Update for $state { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.groestl.process(input.as_ref()); - } - } - - impl VariableOutputDirty for $state { - fn new(output_size: usize) -> Result { - if output_size == $min || output_size > $max { - return Err(InvalidOutputSize); - } - Ok($state { - groestl: Groestl::new(output_size).unwrap(), - }) - } - - fn output_size(&self) -> usize { - self.groestl.output_size - } - - fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])) { - let block = self.groestl.finalize(); - let n = block.len() - self.groestl.output_size; - f(&block[n..]); - } - } - - impl Reset for $state { - fn reset(&mut self) { - self.groestl.reset() - } - } - - opaque_debug::implement!($state); - digest::impl_write!($state); - }; -} diff --git a/groestl/src/matrix.rs b/groestl/src/matrix.rs deleted file mode 100644 index 433ddb66f..000000000 --- a/groestl/src/matrix.rs +++ /dev/null @@ -1,87 +0,0 @@ -use core::ops::{Index, IndexMut}; -use digest::generic_array::{ArrayLength, GenericArray}; - -#[derive(Debug, Eq, PartialEq)] -pub struct Matrix>, C: ArrayLength> { - pub state: GenericArray, R>, -} - -impl Default for Matrix -where - R: ArrayLength>, - C: ArrayLength, -{ - fn default() -> Self { - Matrix { - state: GenericArray::default(), - } - } -} - -impl Index for Matrix -where - R: ArrayLength>, - C: ArrayLength, -{ - type Output = GenericArray; - - fn index(&self, index: usize) -> &Self::Output { - &self.state[index] - } -} - -impl IndexMut for Matrix -where - R: ArrayLength>, - C: ArrayLength, -{ - fn index_mut(&mut self, index: usize) -> &mut Self::Output { - &mut self.state[index] - } -} - -fn poly_mul(a: u8, b: usize) -> usize { - let mut val = match a { - 2 => b << 1, - 3 => b ^ poly_mul(2, b), - 4 => b << 2, - 5 => b ^ poly_mul(4, b), - 7 => b ^ poly_mul(2, b) ^ poly_mul(4, b), - _ => unreachable!(), - }; - - if val >= 512 { - val ^= 0x11b << 1; - } - if val >= 256 { - val ^= 0x11b; - } - val -} - -impl Matrix -where - R: ArrayLength>, - C: ArrayLength, -{ - pub fn rows(&self) -> usize { - R::to_usize() - } - - pub fn cols(&self) -> usize { - C::to_usize() - } - - pub fn mul_array(&self, a: &[[u8; 8]; 8]) -> Self { - let mut res = Matrix::default(); - for i in 0..8 { - for j in 0..self.cols() { - for k in 0..8 { - res[i][j] ^= poly_mul(a[i][k], self[k][j] as usize) as u8; - } - } - } - - res - } -} diff --git a/groestl/src/state.rs b/groestl/src/state.rs deleted file mode 100644 index f1e4dd424..000000000 --- a/groestl/src/state.rs +++ /dev/null @@ -1,293 +0,0 @@ -use core::ops::Div; - -use crate::consts::{B, C_P, C_Q, SBOX, SHIFTS_P, SHIFTS_P_WIDE, SHIFTS_Q, SHIFTS_Q_WIDE}; -use crate::matrix::Matrix; -use digest::generic_array::typenum::{Quot, U8}; -use digest::generic_array::{ArrayLength, GenericArray}; - -#[derive(Copy, Clone)] -pub struct GroestlState -where - BlockSize: ArrayLength + Div, - BlockSize::ArrayType: Copy, - Quot: ArrayLength, -{ - pub state: GenericArray, - rounds: u8, - pub num_blocks: u64, -} - -pub fn xor_generic_array>( - a1: &GenericArray, - a2: &GenericArray, -) -> GenericArray { - let mut res = GenericArray::default(); - for i in 0..L::to_usize() { - res[i] = a1[i] ^ a2[i]; - } - res -} - -fn gcd(a: usize, b: usize) -> usize { - if b == 0 { - return a; - } - gcd(b, a % b) -} - -impl GroestlState -where - BlockSize: ArrayLength + Div, - BlockSize::ArrayType: Copy, - Quot: ArrayLength, -{ - pub fn new(output_size: usize) -> Self { - let block_bytes = BlockSize::to_usize(); - let output_bits = output_size * 8; - - let mut state = GenericArray::default(); - let n = output_bits as u64; - state[block_bytes - 8..].copy_from_slice(&n.to_be_bytes()); - let rounds = match block_bytes { - 128 => 14, - 64 => 10, - _ => unreachable!(), - }; - - GroestlState { - state, - rounds, - num_blocks: 0, - } - } - - fn wide(&self) -> bool { - match BlockSize::to_usize() { - 128 => true, - 64 => false, - _ => unreachable!(), - } - } - - pub fn compress(&mut self, input_block: &GenericArray) { - self.state = xor_generic_array( - &xor_generic_array( - &self.p(&xor_generic_array(&self.state, input_block)), - &self.q(input_block), - ), - &self.state, - ); - self.num_blocks += 1; - } - - fn block_to_matrix( - &self, - block: &GenericArray, - ) -> Matrix> { - let mut matrix = Matrix::>::default(); - - let rows = matrix.rows(); - for i in 0..matrix.cols() { - for j in 0..rows { - matrix[j][i] = block[i * rows + j]; - } - } - - matrix - } - - fn matrix_to_block( - &self, - matrix: &Matrix>, - ) -> GenericArray { - let mut block = GenericArray::default(); - - let rows = matrix.rows(); - for i in 0..matrix.cols() { - for j in 0..rows { - block[i * rows + j] = matrix[j][i]; - } - } - - block - } - - pub fn p(&self, block: &GenericArray) -> GenericArray { - let shifts = if self.wide() { SHIFTS_P_WIDE } else { SHIFTS_P }; - let mut matrix = self.block_to_matrix(block); - for round in 0..self.rounds { - self.add_round_constant(&mut matrix, C_P, round); - self.sub_bytes(&mut matrix); - self.shift_bytes(&mut matrix, shifts); - matrix = matrix.mul_array(&B); - } - self.matrix_to_block(&matrix) - } - - fn q(&self, block: &GenericArray) -> GenericArray { - let shifts = if self.wide() { SHIFTS_Q_WIDE } else { SHIFTS_Q }; - let mut matrix = self.block_to_matrix(block); - for round in 0..self.rounds { - self.add_round_constant(&mut matrix, C_Q, round); - self.sub_bytes(&mut matrix); - self.shift_bytes(&mut matrix, shifts); - matrix = matrix.mul_array(&B); - } - self.matrix_to_block(&matrix) - } - - fn add_round_constant( - &self, - matrix: &mut Matrix>, - c: [u8; 128], - round: u8, - ) { - for i in 0..matrix.rows() { - for j in 0..matrix.cols() { - matrix[i][j] ^= c[i * 16 + j]; - - if (c[0] == 0x00 && i == 0) || (c[0] == 0xff && i == 7) { - matrix[i][j] ^= round; - } - } - } - } - - fn sub_bytes(&self, matrix: &mut Matrix>) { - for i in 0..matrix.rows() { - for j in 0..matrix.cols() { - matrix[i][j] = SBOX[matrix[i][j] as usize]; - } - } - } - - fn shift_bytes(&self, matrix: &mut Matrix>, shifts: [u8; 8]) { - let cols = matrix.cols(); - for i in 0..matrix.rows() { - let shift = shifts[i] as usize; - if shift == 0 { - continue; - } - let d = gcd(shift, cols); - for j in 0..d { - let mut k = j; - let tmp = matrix[i][k]; - loop { - let pos = k.wrapping_add(shift) % cols; - if pos == j { - break; - } - matrix[i][k] = matrix[i][pos]; - k = pos; - } - matrix[i][k] = tmp; - } - } - } -} - -#[cfg(test)] -mod test { - use super::{xor_generic_array, GroestlState}; - use crate::consts::{C_P, C_Q, SHIFTS_P}; - use digest::generic_array::typenum::U64; - use digest::generic_array::GenericArray; - - fn get_padding_block() -> GenericArray { - let padding_block: [u8; 64] = [ - 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, - ]; - - GenericArray::clone_from_slice(&padding_block) - } - - #[test] - fn test_shift_bytes() { - let s = GroestlState::::new(32); - let mut block = GenericArray::default(); - for i in 0..64 { - block[i] = i as u8; - } - let mut matrix = s.block_to_matrix(&block); - s.shift_bytes(&mut matrix, SHIFTS_P); - let block = s.matrix_to_block(&matrix); - let expected = [ - 0, 9, 18, 27, 36, 45, 54, 63, 8, 17, 26, 35, 44, 53, 62, 7, 16, 25, 34, 43, 52, 61, 6, - 15, 24, 33, 42, 51, 60, 5, 14, 23, 32, 41, 50, 59, 4, 13, 22, 31, 40, 49, 58, 3, 12, - 21, 30, 39, 48, 57, 2, 11, 20, 29, 38, 47, 56, 1, 10, 19, 28, 37, 46, 55, - ]; - assert_eq!(&block[..], &expected[..]); - } - - #[test] - fn test_p() { - let padding_chunk = get_padding_block(); - let s = GroestlState::::new(32); - let block = xor_generic_array(&s.state, GenericArray::from_slice(&padding_chunk)); - - let p_block = s.p(&block); - let expected = [ - 247, 236, 141, 217, 73, 225, 112, 216, 1, 155, 85, 192, 152, 168, 174, 72, 112, 253, - 159, 53, 7, 6, 8, 115, 58, 242, 7, 115, 148, 150, 157, 25, 18, 220, 11, 5, 178, 10, - 110, 94, 44, 56, 110, 67, 107, 234, 102, 163, 243, 212, 49, 25, 46, 17, 170, 84, 5, 76, - 239, 51, 4, 107, 94, 20, - ]; - assert_eq!(&p_block[..], &expected[..]); - } - - #[test] - fn test_q() { - let padding_chunk = get_padding_block(); - let s = GroestlState::::new(32); - let q_block = s.q(GenericArray::from_slice(&padding_chunk)); - let expected = [ - 189, 183, 105, 133, 208, 106, 34, 36, 82, 37, 180, 250, 229, 59, 230, 223, 215, 245, - 53, 117, 167, 139, 150, 186, 210, 17, 220, 57, 116, 134, 209, 51, 124, 108, 84, 91, 79, - 103, 148, 27, 135, 183, 144, 226, 59, 242, 87, 81, 109, 211, 84, 185, 192, 172, 88, - 210, 8, 121, 31, 242, 158, 227, 207, 13, - ]; - assert_eq!(&q_block[..], &expected[..]); - } - - #[test] - fn test_block_to_matrix() { - let s = GroestlState::::new(32); - let mut block1 = GenericArray::default(); - for i in 0..block1.len() { - block1[i] = i as u8; - } - let m = s.block_to_matrix(&block1); - let block2 = s.matrix_to_block(&m); - assert_eq!(block1, block2); - } - - #[test] - fn test_add_round_constant() { - let padding_chunk = get_padding_block(); - let s = GroestlState::::new(32); - - let mut m = s.block_to_matrix(GenericArray::from_slice(&padding_chunk)); - s.add_round_constant(&mut m, C_P, 0); - let b = s.matrix_to_block(&m); - let expected = [ - 128, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, - 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, - 0, 112, 0, 0, 0, 0, 0, 0, 1, - ]; - assert_eq!(&b[..], &expected[..]); - - let mut m = s.block_to_matrix(GenericArray::from_slice(&padding_chunk)); - s.add_round_constant(&mut m, C_Q, 0); - let b = s.matrix_to_block(&m); - let expected = [ - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8e, - ]; - assert_eq!(&b[..], &expected[..]); - } -} diff --git a/groestl/src/table.rs b/groestl/src/table.rs new file mode 100644 index 000000000..fe1e729dc --- /dev/null +++ b/groestl/src/table.rs @@ -0,0 +1,11 @@ +#[rustfmt::skip] +pub(crate) const TABLE: [[u64; 256]; 8] = [ + [0xc632f4a5f497a5c6, 0xf86f978497eb84f8, 0xee5eb099b0c799ee, 0xf67a8c8d8cf78df6, 0xffe8170d17e50dff, 0xd60adcbddcb7bdd6, 0xde16c8b1c8a7b1de, 0x916dfc54fc395491, 0x6090f050f0c05060, 0x0207050305040302, 0xce2ee0a9e087a9ce, 0x56d1877d87ac7d56, 0xe7cc2b192bd519e7, 0xb513a662a67162b5, 0x4d7c31e6319ae64d, 0xec59b59ab5c39aec, 0x8f40cf45cf05458f, 0x1fa3bc9dbc3e9d1f, 0x8949c040c0094089, 0xfa68928792ef87fa, 0xefd03f153fc515ef, 0xb29426eb267febb2, 0x8ece40c94007c98e, 0xfbe61d0b1ded0bfb, 0x416e2fec2f82ec41, 0xb31aa967a97d67b3, 0x5f431cfd1cbefd5f, 0x456025ea258aea45, 0x23f9dabfda46bf23, 0x535102f702a6f753, 0xe445a196a1d396e4, 0x9b76ed5bed2d5b9b, 0x75285dc25deac275, 0xe1c5241c24d91ce1, 0x3dd4e9aee97aae3d, 0x4cf2be6abe986a4c, 0x6c82ee5aeed85a6c, 0x7ebdc341c3fc417e, 0xf5f3060206f102f5, 0x8352d14fd11d4f83, 0x688ce45ce4d05c68, 0x515607f407a2f451, 0xd18d5c345cb934d1, 0xf9e1180818e908f9, 0xe24cae93aedf93e2, 0xab3e9573954d73ab, 0x6297f553f5c45362, 0x2a6b413f41543f2a, 0x081c140c14100c08, 0x9563f652f6315295, 0x46e9af65af8c6546, 0x9d7fe25ee2215e9d, 0x3048782878602830, 0x37cff8a1f86ea137, 0x0a1b110f11140f0a, 0x2febc4b5c45eb52f, 0x0e151b091b1c090e, 0x247e5a365a483624, 0x1badb69bb6369b1b, 0xdf98473d47a53ddf, 0xcda76a266a8126cd, 0x4ef5bb69bb9c694e, 0x7f334ccd4cfecd7f, 0xea50ba9fbacf9fea, 0x123f2d1b2d241b12, 0x1da4b99eb93a9e1d, 0x58c49c749cb07458, 0x3446722e72682e34, 0x3641772d776c2d36, 0xdc11cdb2cda3b2dc, 0xb49d29ee2973eeb4, 0x5b4d16fb16b6fb5b, 0xa4a501f60153f6a4, 0x76a1d74dd7ec4d76, 0xb714a361a37561b7, 0x7d3449ce49face7d, 0x52df8d7b8da47b52, 0xdd9f423e42a13edd, 0x5ecd937193bc715e, 0x13b1a297a2269713, 0xa6a204f50457f5a6, 0xb901b868b86968b9, 0x0000000000000000, 0xc1b5742c74992cc1, 0x40e0a060a0806040, 0xe3c2211f21dd1fe3, 0x793a43c843f2c879, 0xb69a2ced2c77edb6, 0xd40dd9bed9b3bed4, 0x8d47ca46ca01468d, 0x671770d970ced967, 0x72afdd4bdde44b72, 0x94ed79de7933de94, 0x98ff67d4672bd498, 0xb09323e8237be8b0, 0x855bde4ade114a85, 0xbb06bd6bbd6d6bbb, 0xc5bb7e2a7e912ac5, 0x4f7b34e5349ee54f, 0xedd73a163ac116ed, 0x86d254c55417c586, 0x9af862d7622fd79a, 0x6699ff55ffcc5566, 0x11b6a794a7229411, 0x8ac04acf4a0fcf8a, 0xe9d9301030c910e9, 0x040e0a060a080604, 0xfe66988198e781fe, 0xa0ab0bf00b5bf0a0, 0x78b4cc44ccf04478, 0x25f0d5bad54aba25, 0x4b753ee33e96e34b, 0xa2ac0ef30e5ff3a2, 0x5d4419fe19bafe5d, 0x80db5bc05b1bc080, 0x0580858a850a8a05, 0x3fd3ecadec7ead3f, 0x21fedfbcdf42bc21, 0x70a8d848d8e04870, 0xf1fd0c040cf904f1, 0x63197adf7ac6df63, 0x772f58c158eec177, 0xaf309f759f4575af, 0x42e7a563a5846342, 0x2070503050403020, 0xe5cb2e1a2ed11ae5, 0xfdef120e12e10efd, 0xbf08b76db7656dbf, 0x8155d44cd4194c81, 0x18243c143c301418, 0x26795f355f4c3526, 0xc3b2712f719d2fc3, 0xbe8638e13867e1be, 0x35c8fda2fd6aa235, 0x88c74fcc4f0bcc88, 0x2e654b394b5c392e, 0x936af957f93d5793, 0x55580df20daaf255, 0xfc619d829de382fc, 0x7ab3c947c9f4477a, 0xc827efacef8bacc8, 0xba8832e7326fe7ba, 0x324f7d2b7d642b32, 0xe642a495a4d795e6, 0xc03bfba0fb9ba0c0, 0x19aab398b3329819, 0x9ef668d16827d19e, 0xa322817f815d7fa3, 0x44eeaa66aa886644, 0x54d6827e82a87e54, 0x3bdde6abe676ab3b, 0x0b959e839e16830b, 0x8cc945ca4503ca8c, 0xc7bc7b297b9529c7, 0x6b056ed36ed6d36b, 0x286c443c44503c28, 0xa72c8b798b5579a7, 0xbc813de23d63e2bc, 0x1631271d272c1d16, 0xad379a769a4176ad, 0xdb964d3b4dad3bdb, 0x649efa56fac85664, 0x74a6d24ed2e84e74, 0x1436221e22281e14, 0x92e476db763fdb92, 0x0c121e0a1e180a0c, 0x48fcb46cb4906c48, 0xb88f37e4376be4b8, 0x9f78e75de7255d9f, 0xbd0fb26eb2616ebd, 0x43692aef2a86ef43, 0xc435f1a6f193a6c4, 0x39dae3a8e372a839, 0x31c6f7a4f762a431, 0xd38a593759bd37d3, 0xf274868b86ff8bf2, 0xd583563256b132d5, 0x8b4ec543c50d438b, 0x6e85eb59ebdc596e, 0xda18c2b7c2afb7da, 0x018e8f8c8f028c01, 0xb11dac64ac7964b1, 0x9cf16dd26d23d29c, 0x49723be03b92e049, 0xd81fc7b4c7abb4d8, 0xacb915fa1543faac, 0xf3fa090709fd07f3, 0xcfa06f256f8525cf, 0xca20eaafea8fafca, 0xf47d898e89f38ef4, 0x476720e9208ee947, 0x1038281828201810, 0x6f0b64d564ded56f, 0xf073838883fb88f0, 0x4afbb16fb1946f4a, 0x5cca967296b8725c, 0x38546c246c702438, 0x575f08f108aef157, 0x732152c752e6c773, 0x9764f351f3355197, 0xcbae6523658d23cb, 0xa125847c84597ca1, 0xe857bf9cbfcb9ce8, 0x3e5d6321637c213e, 0x96ea7cdd7c37dd96, 0x611e7fdc7fc2dc61, 0x0d9c9186911a860d, 0x0f9b9485941e850f, 0xe04bab90abdb90e0, 0x7cbac642c6f8427c, 0x712657c457e2c471, 0xcc29e5aae583aacc, 0x90e373d8733bd890, 0x06090f050f0c0506, 0xf7f4030103f501f7, 0x1c2a36123638121c, 0xc23cfea3fe9fa3c2, 0x6a8be15fe1d45f6a, 0xaebe10f91047f9ae, 0x69026bd06bd2d069, 0x17bfa891a82e9117, 0x9971e858e8295899, 0x3a5369276974273a, 0x27f7d0b9d04eb927, 0xd991483848a938d9, 0xebde351335cd13eb, 0x2be5ceb3ce56b32b, 0x2277553355443322, 0xd204d6bbd6bfbbd2, 0xa9399070904970a9, 0x07878089800e8907, 0x33c1f2a7f266a733, 0x2decc1b6c15ab62d, 0x3c5a66226678223c, 0x15b8ad92ad2a9215, 0xc9a96020608920c9, 0x875cdb49db154987, 0xaab01aff1a4fffaa, 0x50d8887888a07850, 0xa52b8e7a8e517aa5, 0x03898a8f8a068f03, 0x594a13f813b2f859, 0x09929b809b128009, 0x1a2339173934171a, 0x651075da75cada65, 0xd784533153b531d7, 0x84d551c65113c684, 0xd003d3b8d3bbb8d0, 0x82dc5ec35e1fc382, 0x29e2cbb0cb52b029, 0x5ac3997799b4775a, 0x1e2d3311333c111e, 0x7b3d46cb46f6cb7b, 0xa8b71ffc1f4bfca8, 0x6d0c61d661dad66d, 0x2c624e3a4e583a2c], + [0xc6c632f4a5f497a5, 0xf8f86f978497eb84, 0xeeee5eb099b0c799, 0xf6f67a8c8d8cf78d, 0xffffe8170d17e50d, 0xd6d60adcbddcb7bd, 0xdede16c8b1c8a7b1, 0x91916dfc54fc3954, 0x606090f050f0c050, 0x0202070503050403, 0xcece2ee0a9e087a9, 0x5656d1877d87ac7d, 0xe7e7cc2b192bd519, 0xb5b513a662a67162, 0x4d4d7c31e6319ae6, 0xecec59b59ab5c39a, 0x8f8f40cf45cf0545, 0x1f1fa3bc9dbc3e9d, 0x898949c040c00940, 0xfafa68928792ef87, 0xefefd03f153fc515, 0xb2b29426eb267feb, 0x8e8ece40c94007c9, 0xfbfbe61d0b1ded0b, 0x41416e2fec2f82ec, 0xb3b31aa967a97d67, 0x5f5f431cfd1cbefd, 0x45456025ea258aea, 0x2323f9dabfda46bf, 0x53535102f702a6f7, 0xe4e445a196a1d396, 0x9b9b76ed5bed2d5b, 0x7575285dc25deac2, 0xe1e1c5241c24d91c, 0x3d3dd4e9aee97aae, 0x4c4cf2be6abe986a, 0x6c6c82ee5aeed85a, 0x7e7ebdc341c3fc41, 0xf5f5f3060206f102, 0x838352d14fd11d4f, 0x68688ce45ce4d05c, 0x51515607f407a2f4, 0xd1d18d5c345cb934, 0xf9f9e1180818e908, 0xe2e24cae93aedf93, 0xabab3e9573954d73, 0x626297f553f5c453, 0x2a2a6b413f41543f, 0x08081c140c14100c, 0x959563f652f63152, 0x4646e9af65af8c65, 0x9d9d7fe25ee2215e, 0x3030487828786028, 0x3737cff8a1f86ea1, 0x0a0a1b110f11140f, 0x2f2febc4b5c45eb5, 0x0e0e151b091b1c09, 0x24247e5a365a4836, 0x1b1badb69bb6369b, 0xdfdf98473d47a53d, 0xcdcda76a266a8126, 0x4e4ef5bb69bb9c69, 0x7f7f334ccd4cfecd, 0xeaea50ba9fbacf9f, 0x12123f2d1b2d241b, 0x1d1da4b99eb93a9e, 0x5858c49c749cb074, 0x343446722e72682e, 0x363641772d776c2d, 0xdcdc11cdb2cda3b2, 0xb4b49d29ee2973ee, 0x5b5b4d16fb16b6fb, 0xa4a4a501f60153f6, 0x7676a1d74dd7ec4d, 0xb7b714a361a37561, 0x7d7d3449ce49face, 0x5252df8d7b8da47b, 0xdddd9f423e42a13e, 0x5e5ecd937193bc71, 0x1313b1a297a22697, 0xa6a6a204f50457f5, 0xb9b901b868b86968, 0x0000000000000000, 0xc1c1b5742c74992c, 0x4040e0a060a08060, 0xe3e3c2211f21dd1f, 0x79793a43c843f2c8, 0xb6b69a2ced2c77ed, 0xd4d40dd9bed9b3be, 0x8d8d47ca46ca0146, 0x67671770d970ced9, 0x7272afdd4bdde44b, 0x9494ed79de7933de, 0x9898ff67d4672bd4, 0xb0b09323e8237be8, 0x85855bde4ade114a, 0xbbbb06bd6bbd6d6b, 0xc5c5bb7e2a7e912a, 0x4f4f7b34e5349ee5, 0xededd73a163ac116, 0x8686d254c55417c5, 0x9a9af862d7622fd7, 0x666699ff55ffcc55, 0x1111b6a794a72294, 0x8a8ac04acf4a0fcf, 0xe9e9d9301030c910, 0x04040e0a060a0806, 0xfefe66988198e781, 0xa0a0ab0bf00b5bf0, 0x7878b4cc44ccf044, 0x2525f0d5bad54aba, 0x4b4b753ee33e96e3, 0xa2a2ac0ef30e5ff3, 0x5d5d4419fe19bafe, 0x8080db5bc05b1bc0, 0x050580858a850a8a, 0x3f3fd3ecadec7ead, 0x2121fedfbcdf42bc, 0x7070a8d848d8e048, 0xf1f1fd0c040cf904, 0x6363197adf7ac6df, 0x77772f58c158eec1, 0xafaf309f759f4575, 0x4242e7a563a58463, 0x2020705030504030, 0xe5e5cb2e1a2ed11a, 0xfdfdef120e12e10e, 0xbfbf08b76db7656d, 0x818155d44cd4194c, 0x1818243c143c3014, 0x2626795f355f4c35, 0xc3c3b2712f719d2f, 0xbebe8638e13867e1, 0x3535c8fda2fd6aa2, 0x8888c74fcc4f0bcc, 0x2e2e654b394b5c39, 0x93936af957f93d57, 0x5555580df20daaf2, 0xfcfc619d829de382, 0x7a7ab3c947c9f447, 0xc8c827efacef8bac, 0xbaba8832e7326fe7, 0x32324f7d2b7d642b, 0xe6e642a495a4d795, 0xc0c03bfba0fb9ba0, 0x1919aab398b33298, 0x9e9ef668d16827d1, 0xa3a322817f815d7f, 0x4444eeaa66aa8866, 0x5454d6827e82a87e, 0x3b3bdde6abe676ab, 0x0b0b959e839e1683, 0x8c8cc945ca4503ca, 0xc7c7bc7b297b9529, 0x6b6b056ed36ed6d3, 0x28286c443c44503c, 0xa7a72c8b798b5579, 0xbcbc813de23d63e2, 0x161631271d272c1d, 0xadad379a769a4176, 0xdbdb964d3b4dad3b, 0x64649efa56fac856, 0x7474a6d24ed2e84e, 0x141436221e22281e, 0x9292e476db763fdb, 0x0c0c121e0a1e180a, 0x4848fcb46cb4906c, 0xb8b88f37e4376be4, 0x9f9f78e75de7255d, 0xbdbd0fb26eb2616e, 0x4343692aef2a86ef, 0xc4c435f1a6f193a6, 0x3939dae3a8e372a8, 0x3131c6f7a4f762a4, 0xd3d38a593759bd37, 0xf2f274868b86ff8b, 0xd5d583563256b132, 0x8b8b4ec543c50d43, 0x6e6e85eb59ebdc59, 0xdada18c2b7c2afb7, 0x01018e8f8c8f028c, 0xb1b11dac64ac7964, 0x9c9cf16dd26d23d2, 0x4949723be03b92e0, 0xd8d81fc7b4c7abb4, 0xacacb915fa1543fa, 0xf3f3fa090709fd07, 0xcfcfa06f256f8525, 0xcaca20eaafea8faf, 0xf4f47d898e89f38e, 0x47476720e9208ee9, 0x1010382818282018, 0x6f6f0b64d564ded5, 0xf0f073838883fb88, 0x4a4afbb16fb1946f, 0x5c5cca967296b872, 0x3838546c246c7024, 0x57575f08f108aef1, 0x73732152c752e6c7, 0x979764f351f33551, 0xcbcbae6523658d23, 0xa1a125847c84597c, 0xe8e857bf9cbfcb9c, 0x3e3e5d6321637c21, 0x9696ea7cdd7c37dd, 0x61611e7fdc7fc2dc, 0x0d0d9c9186911a86, 0x0f0f9b9485941e85, 0xe0e04bab90abdb90, 0x7c7cbac642c6f842, 0x71712657c457e2c4, 0xcccc29e5aae583aa, 0x9090e373d8733bd8, 0x0606090f050f0c05, 0xf7f7f4030103f501, 0x1c1c2a3612363812, 0xc2c23cfea3fe9fa3, 0x6a6a8be15fe1d45f, 0xaeaebe10f91047f9, 0x6969026bd06bd2d0, 0x1717bfa891a82e91, 0x999971e858e82958, 0x3a3a536927697427, 0x2727f7d0b9d04eb9, 0xd9d991483848a938, 0xebebde351335cd13, 0x2b2be5ceb3ce56b3, 0x2222775533554433, 0xd2d204d6bbd6bfbb, 0xa9a9399070904970, 0x0707878089800e89, 0x3333c1f2a7f266a7, 0x2d2decc1b6c15ab6, 0x3c3c5a6622667822, 0x1515b8ad92ad2a92, 0xc9c9a96020608920, 0x87875cdb49db1549, 0xaaaab01aff1a4fff, 0x5050d8887888a078, 0xa5a52b8e7a8e517a, 0x0303898a8f8a068f, 0x59594a13f813b2f8, 0x0909929b809b1280, 0x1a1a233917393417, 0x65651075da75cada, 0xd7d784533153b531, 0x8484d551c65113c6, 0xd0d003d3b8d3bbb8, 0x8282dc5ec35e1fc3, 0x2929e2cbb0cb52b0, 0x5a5ac3997799b477, 0x1e1e2d3311333c11, 0x7b7b3d46cb46f6cb, 0xa8a8b71ffc1f4bfc, 0x6d6d0c61d661dad6, 0x2c2c624e3a4e583a], + [0xa5c6c632f4a5f497, 0x84f8f86f978497eb, 0x99eeee5eb099b0c7, 0x8df6f67a8c8d8cf7, 0x0dffffe8170d17e5, 0xbdd6d60adcbddcb7, 0xb1dede16c8b1c8a7, 0x5491916dfc54fc39, 0x50606090f050f0c0, 0x0302020705030504, 0xa9cece2ee0a9e087, 0x7d5656d1877d87ac, 0x19e7e7cc2b192bd5, 0x62b5b513a662a671, 0xe64d4d7c31e6319a, 0x9aecec59b59ab5c3, 0x458f8f40cf45cf05, 0x9d1f1fa3bc9dbc3e, 0x40898949c040c009, 0x87fafa68928792ef, 0x15efefd03f153fc5, 0xebb2b29426eb267f, 0xc98e8ece40c94007, 0x0bfbfbe61d0b1ded, 0xec41416e2fec2f82, 0x67b3b31aa967a97d, 0xfd5f5f431cfd1cbe, 0xea45456025ea258a, 0xbf2323f9dabfda46, 0xf753535102f702a6, 0x96e4e445a196a1d3, 0x5b9b9b76ed5bed2d, 0xc27575285dc25dea, 0x1ce1e1c5241c24d9, 0xae3d3dd4e9aee97a, 0x6a4c4cf2be6abe98, 0x5a6c6c82ee5aeed8, 0x417e7ebdc341c3fc, 0x02f5f5f3060206f1, 0x4f838352d14fd11d, 0x5c68688ce45ce4d0, 0xf451515607f407a2, 0x34d1d18d5c345cb9, 0x08f9f9e1180818e9, 0x93e2e24cae93aedf, 0x73abab3e9573954d, 0x53626297f553f5c4, 0x3f2a2a6b413f4154, 0x0c08081c140c1410, 0x52959563f652f631, 0x654646e9af65af8c, 0x5e9d9d7fe25ee221, 0x2830304878287860, 0xa13737cff8a1f86e, 0x0f0a0a1b110f1114, 0xb52f2febc4b5c45e, 0x090e0e151b091b1c, 0x3624247e5a365a48, 0x9b1b1badb69bb636, 0x3ddfdf98473d47a5, 0x26cdcda76a266a81, 0x694e4ef5bb69bb9c, 0xcd7f7f334ccd4cfe, 0x9feaea50ba9fbacf, 0x1b12123f2d1b2d24, 0x9e1d1da4b99eb93a, 0x745858c49c749cb0, 0x2e343446722e7268, 0x2d363641772d776c, 0xb2dcdc11cdb2cda3, 0xeeb4b49d29ee2973, 0xfb5b5b4d16fb16b6, 0xf6a4a4a501f60153, 0x4d7676a1d74dd7ec, 0x61b7b714a361a375, 0xce7d7d3449ce49fa, 0x7b5252df8d7b8da4, 0x3edddd9f423e42a1, 0x715e5ecd937193bc, 0x971313b1a297a226, 0xf5a6a6a204f50457, 0x68b9b901b868b869, 0x0000000000000000, 0x2cc1c1b5742c7499, 0x604040e0a060a080, 0x1fe3e3c2211f21dd, 0xc879793a43c843f2, 0xedb6b69a2ced2c77, 0xbed4d40dd9bed9b3, 0x468d8d47ca46ca01, 0xd967671770d970ce, 0x4b7272afdd4bdde4, 0xde9494ed79de7933, 0xd49898ff67d4672b, 0xe8b0b09323e8237b, 0x4a85855bde4ade11, 0x6bbbbb06bd6bbd6d, 0x2ac5c5bb7e2a7e91, 0xe54f4f7b34e5349e, 0x16ededd73a163ac1, 0xc58686d254c55417, 0xd79a9af862d7622f, 0x55666699ff55ffcc, 0x941111b6a794a722, 0xcf8a8ac04acf4a0f, 0x10e9e9d9301030c9, 0x0604040e0a060a08, 0x81fefe66988198e7, 0xf0a0a0ab0bf00b5b, 0x447878b4cc44ccf0, 0xba2525f0d5bad54a, 0xe34b4b753ee33e96, 0xf3a2a2ac0ef30e5f, 0xfe5d5d4419fe19ba, 0xc08080db5bc05b1b, 0x8a050580858a850a, 0xad3f3fd3ecadec7e, 0xbc2121fedfbcdf42, 0x487070a8d848d8e0, 0x04f1f1fd0c040cf9, 0xdf6363197adf7ac6, 0xc177772f58c158ee, 0x75afaf309f759f45, 0x634242e7a563a584, 0x3020207050305040, 0x1ae5e5cb2e1a2ed1, 0x0efdfdef120e12e1, 0x6dbfbf08b76db765, 0x4c818155d44cd419, 0x141818243c143c30, 0x352626795f355f4c, 0x2fc3c3b2712f719d, 0xe1bebe8638e13867, 0xa23535c8fda2fd6a, 0xcc8888c74fcc4f0b, 0x392e2e654b394b5c, 0x5793936af957f93d, 0xf25555580df20daa, 0x82fcfc619d829de3, 0x477a7ab3c947c9f4, 0xacc8c827efacef8b, 0xe7baba8832e7326f, 0x2b32324f7d2b7d64, 0x95e6e642a495a4d7, 0xa0c0c03bfba0fb9b, 0x981919aab398b332, 0xd19e9ef668d16827, 0x7fa3a322817f815d, 0x664444eeaa66aa88, 0x7e5454d6827e82a8, 0xab3b3bdde6abe676, 0x830b0b959e839e16, 0xca8c8cc945ca4503, 0x29c7c7bc7b297b95, 0xd36b6b056ed36ed6, 0x3c28286c443c4450, 0x79a7a72c8b798b55, 0xe2bcbc813de23d63, 0x1d161631271d272c, 0x76adad379a769a41, 0x3bdbdb964d3b4dad, 0x5664649efa56fac8, 0x4e7474a6d24ed2e8, 0x1e141436221e2228, 0xdb9292e476db763f, 0x0a0c0c121e0a1e18, 0x6c4848fcb46cb490, 0xe4b8b88f37e4376b, 0x5d9f9f78e75de725, 0x6ebdbd0fb26eb261, 0xef4343692aef2a86, 0xa6c4c435f1a6f193, 0xa83939dae3a8e372, 0xa43131c6f7a4f762, 0x37d3d38a593759bd, 0x8bf2f274868b86ff, 0x32d5d583563256b1, 0x438b8b4ec543c50d, 0x596e6e85eb59ebdc, 0xb7dada18c2b7c2af, 0x8c01018e8f8c8f02, 0x64b1b11dac64ac79, 0xd29c9cf16dd26d23, 0xe04949723be03b92, 0xb4d8d81fc7b4c7ab, 0xfaacacb915fa1543, 0x07f3f3fa090709fd, 0x25cfcfa06f256f85, 0xafcaca20eaafea8f, 0x8ef4f47d898e89f3, 0xe947476720e9208e, 0x1810103828182820, 0xd56f6f0b64d564de, 0x88f0f073838883fb, 0x6f4a4afbb16fb194, 0x725c5cca967296b8, 0x243838546c246c70, 0xf157575f08f108ae, 0xc773732152c752e6, 0x51979764f351f335, 0x23cbcbae6523658d, 0x7ca1a125847c8459, 0x9ce8e857bf9cbfcb, 0x213e3e5d6321637c, 0xdd9696ea7cdd7c37, 0xdc61611e7fdc7fc2, 0x860d0d9c9186911a, 0x850f0f9b9485941e, 0x90e0e04bab90abdb, 0x427c7cbac642c6f8, 0xc471712657c457e2, 0xaacccc29e5aae583, 0xd89090e373d8733b, 0x050606090f050f0c, 0x01f7f7f4030103f5, 0x121c1c2a36123638, 0xa3c2c23cfea3fe9f, 0x5f6a6a8be15fe1d4, 0xf9aeaebe10f91047, 0xd06969026bd06bd2, 0x911717bfa891a82e, 0x58999971e858e829, 0x273a3a5369276974, 0xb92727f7d0b9d04e, 0x38d9d991483848a9, 0x13ebebde351335cd, 0xb32b2be5ceb3ce56, 0x3322227755335544, 0xbbd2d204d6bbd6bf, 0x70a9a93990709049, 0x890707878089800e, 0xa73333c1f2a7f266, 0xb62d2decc1b6c15a, 0x223c3c5a66226678, 0x921515b8ad92ad2a, 0x20c9c9a960206089, 0x4987875cdb49db15, 0xffaaaab01aff1a4f, 0x785050d8887888a0, 0x7aa5a52b8e7a8e51, 0x8f0303898a8f8a06, 0xf859594a13f813b2, 0x800909929b809b12, 0x171a1a2339173934, 0xda65651075da75ca, 0x31d7d784533153b5, 0xc68484d551c65113, 0xb8d0d003d3b8d3bb, 0xc38282dc5ec35e1f, 0xb02929e2cbb0cb52, 0x775a5ac3997799b4, 0x111e1e2d3311333c, 0xcb7b7b3d46cb46f6, 0xfca8a8b71ffc1f4b, 0xd66d6d0c61d661da, 0x3a2c2c624e3a4e58], + [0x97a5c6c632f4a5f4, 0xeb84f8f86f978497, 0xc799eeee5eb099b0, 0xf78df6f67a8c8d8c, 0xe50dffffe8170d17, 0xb7bdd6d60adcbddc, 0xa7b1dede16c8b1c8, 0x395491916dfc54fc, 0xc050606090f050f0, 0x0403020207050305, 0x87a9cece2ee0a9e0, 0xac7d5656d1877d87, 0xd519e7e7cc2b192b, 0x7162b5b513a662a6, 0x9ae64d4d7c31e631, 0xc39aecec59b59ab5, 0x05458f8f40cf45cf, 0x3e9d1f1fa3bc9dbc, 0x0940898949c040c0, 0xef87fafa68928792, 0xc515efefd03f153f, 0x7febb2b29426eb26, 0x07c98e8ece40c940, 0xed0bfbfbe61d0b1d, 0x82ec41416e2fec2f, 0x7d67b3b31aa967a9, 0xbefd5f5f431cfd1c, 0x8aea45456025ea25, 0x46bf2323f9dabfda, 0xa6f753535102f702, 0xd396e4e445a196a1, 0x2d5b9b9b76ed5bed, 0xeac27575285dc25d, 0xd91ce1e1c5241c24, 0x7aae3d3dd4e9aee9, 0x986a4c4cf2be6abe, 0xd85a6c6c82ee5aee, 0xfc417e7ebdc341c3, 0xf102f5f5f3060206, 0x1d4f838352d14fd1, 0xd05c68688ce45ce4, 0xa2f451515607f407, 0xb934d1d18d5c345c, 0xe908f9f9e1180818, 0xdf93e2e24cae93ae, 0x4d73abab3e957395, 0xc453626297f553f5, 0x543f2a2a6b413f41, 0x100c08081c140c14, 0x3152959563f652f6, 0x8c654646e9af65af, 0x215e9d9d7fe25ee2, 0x6028303048782878, 0x6ea13737cff8a1f8, 0x140f0a0a1b110f11, 0x5eb52f2febc4b5c4, 0x1c090e0e151b091b, 0x483624247e5a365a, 0x369b1b1badb69bb6, 0xa53ddfdf98473d47, 0x8126cdcda76a266a, 0x9c694e4ef5bb69bb, 0xfecd7f7f334ccd4c, 0xcf9feaea50ba9fba, 0x241b12123f2d1b2d, 0x3a9e1d1da4b99eb9, 0xb0745858c49c749c, 0x682e343446722e72, 0x6c2d363641772d77, 0xa3b2dcdc11cdb2cd, 0x73eeb4b49d29ee29, 0xb6fb5b5b4d16fb16, 0x53f6a4a4a501f601, 0xec4d7676a1d74dd7, 0x7561b7b714a361a3, 0xface7d7d3449ce49, 0xa47b5252df8d7b8d, 0xa13edddd9f423e42, 0xbc715e5ecd937193, 0x26971313b1a297a2, 0x57f5a6a6a204f504, 0x6968b9b901b868b8, 0x0000000000000000, 0x992cc1c1b5742c74, 0x80604040e0a060a0, 0xdd1fe3e3c2211f21, 0xf2c879793a43c843, 0x77edb6b69a2ced2c, 0xb3bed4d40dd9bed9, 0x01468d8d47ca46ca, 0xced967671770d970, 0xe44b7272afdd4bdd, 0x33de9494ed79de79, 0x2bd49898ff67d467, 0x7be8b0b09323e823, 0x114a85855bde4ade, 0x6d6bbbbb06bd6bbd, 0x912ac5c5bb7e2a7e, 0x9ee54f4f7b34e534, 0xc116ededd73a163a, 0x17c58686d254c554, 0x2fd79a9af862d762, 0xcc55666699ff55ff, 0x22941111b6a794a7, 0x0fcf8a8ac04acf4a, 0xc910e9e9d9301030, 0x080604040e0a060a, 0xe781fefe66988198, 0x5bf0a0a0ab0bf00b, 0xf0447878b4cc44cc, 0x4aba2525f0d5bad5, 0x96e34b4b753ee33e, 0x5ff3a2a2ac0ef30e, 0xbafe5d5d4419fe19, 0x1bc08080db5bc05b, 0x0a8a050580858a85, 0x7ead3f3fd3ecadec, 0x42bc2121fedfbcdf, 0xe0487070a8d848d8, 0xf904f1f1fd0c040c, 0xc6df6363197adf7a, 0xeec177772f58c158, 0x4575afaf309f759f, 0x84634242e7a563a5, 0x4030202070503050, 0xd11ae5e5cb2e1a2e, 0xe10efdfdef120e12, 0x656dbfbf08b76db7, 0x194c818155d44cd4, 0x30141818243c143c, 0x4c352626795f355f, 0x9d2fc3c3b2712f71, 0x67e1bebe8638e138, 0x6aa23535c8fda2fd, 0x0bcc8888c74fcc4f, 0x5c392e2e654b394b, 0x3d5793936af957f9, 0xaaf25555580df20d, 0xe382fcfc619d829d, 0xf4477a7ab3c947c9, 0x8bacc8c827efacef, 0x6fe7baba8832e732, 0x642b32324f7d2b7d, 0xd795e6e642a495a4, 0x9ba0c0c03bfba0fb, 0x32981919aab398b3, 0x27d19e9ef668d168, 0x5d7fa3a322817f81, 0x88664444eeaa66aa, 0xa87e5454d6827e82, 0x76ab3b3bdde6abe6, 0x16830b0b959e839e, 0x03ca8c8cc945ca45, 0x9529c7c7bc7b297b, 0xd6d36b6b056ed36e, 0x503c28286c443c44, 0x5579a7a72c8b798b, 0x63e2bcbc813de23d, 0x2c1d161631271d27, 0x4176adad379a769a, 0xad3bdbdb964d3b4d, 0xc85664649efa56fa, 0xe84e7474a6d24ed2, 0x281e141436221e22, 0x3fdb9292e476db76, 0x180a0c0c121e0a1e, 0x906c4848fcb46cb4, 0x6be4b8b88f37e437, 0x255d9f9f78e75de7, 0x616ebdbd0fb26eb2, 0x86ef4343692aef2a, 0x93a6c4c435f1a6f1, 0x72a83939dae3a8e3, 0x62a43131c6f7a4f7, 0xbd37d3d38a593759, 0xff8bf2f274868b86, 0xb132d5d583563256, 0x0d438b8b4ec543c5, 0xdc596e6e85eb59eb, 0xafb7dada18c2b7c2, 0x028c01018e8f8c8f, 0x7964b1b11dac64ac, 0x23d29c9cf16dd26d, 0x92e04949723be03b, 0xabb4d8d81fc7b4c7, 0x43faacacb915fa15, 0xfd07f3f3fa090709, 0x8525cfcfa06f256f, 0x8fafcaca20eaafea, 0xf38ef4f47d898e89, 0x8ee947476720e920, 0x2018101038281828, 0xded56f6f0b64d564, 0xfb88f0f073838883, 0x946f4a4afbb16fb1, 0xb8725c5cca967296, 0x70243838546c246c, 0xaef157575f08f108, 0xe6c773732152c752, 0x3551979764f351f3, 0x8d23cbcbae652365, 0x597ca1a125847c84, 0xcb9ce8e857bf9cbf, 0x7c213e3e5d632163, 0x37dd9696ea7cdd7c, 0xc2dc61611e7fdc7f, 0x1a860d0d9c918691, 0x1e850f0f9b948594, 0xdb90e0e04bab90ab, 0xf8427c7cbac642c6, 0xe2c471712657c457, 0x83aacccc29e5aae5, 0x3bd89090e373d873, 0x0c050606090f050f, 0xf501f7f7f4030103, 0x38121c1c2a361236, 0x9fa3c2c23cfea3fe, 0xd45f6a6a8be15fe1, 0x47f9aeaebe10f910, 0xd2d06969026bd06b, 0x2e911717bfa891a8, 0x2958999971e858e8, 0x74273a3a53692769, 0x4eb92727f7d0b9d0, 0xa938d9d991483848, 0xcd13ebebde351335, 0x56b32b2be5ceb3ce, 0x4433222277553355, 0xbfbbd2d204d6bbd6, 0x4970a9a939907090, 0x0e89070787808980, 0x66a73333c1f2a7f2, 0x5ab62d2decc1b6c1, 0x78223c3c5a662266, 0x2a921515b8ad92ad, 0x8920c9c9a9602060, 0x154987875cdb49db, 0x4fffaaaab01aff1a, 0xa0785050d8887888, 0x517aa5a52b8e7a8e, 0x068f0303898a8f8a, 0xb2f859594a13f813, 0x12800909929b809b, 0x34171a1a23391739, 0xcada65651075da75, 0xb531d7d784533153, 0x13c68484d551c651, 0xbbb8d0d003d3b8d3, 0x1fc38282dc5ec35e, 0x52b02929e2cbb0cb, 0xb4775a5ac3997799, 0x3c111e1e2d331133, 0xf6cb7b7b3d46cb46, 0x4bfca8a8b71ffc1f, 0xdad66d6d0c61d661, 0x583a2c2c624e3a4e], + [0xf497a5c6c632f4a5, 0x97eb84f8f86f9784, 0xb0c799eeee5eb099, 0x8cf78df6f67a8c8d, 0x17e50dffffe8170d, 0xdcb7bdd6d60adcbd, 0xc8a7b1dede16c8b1, 0xfc395491916dfc54, 0xf0c050606090f050, 0x0504030202070503, 0xe087a9cece2ee0a9, 0x87ac7d5656d1877d, 0x2bd519e7e7cc2b19, 0xa67162b5b513a662, 0x319ae64d4d7c31e6, 0xb5c39aecec59b59a, 0xcf05458f8f40cf45, 0xbc3e9d1f1fa3bc9d, 0xc00940898949c040, 0x92ef87fafa689287, 0x3fc515efefd03f15, 0x267febb2b29426eb, 0x4007c98e8ece40c9, 0x1ded0bfbfbe61d0b, 0x2f82ec41416e2fec, 0xa97d67b3b31aa967, 0x1cbefd5f5f431cfd, 0x258aea45456025ea, 0xda46bf2323f9dabf, 0x02a6f753535102f7, 0xa1d396e4e445a196, 0xed2d5b9b9b76ed5b, 0x5deac27575285dc2, 0x24d91ce1e1c5241c, 0xe97aae3d3dd4e9ae, 0xbe986a4c4cf2be6a, 0xeed85a6c6c82ee5a, 0xc3fc417e7ebdc341, 0x06f102f5f5f30602, 0xd11d4f838352d14f, 0xe4d05c68688ce45c, 0x07a2f451515607f4, 0x5cb934d1d18d5c34, 0x18e908f9f9e11808, 0xaedf93e2e24cae93, 0x954d73abab3e9573, 0xf5c453626297f553, 0x41543f2a2a6b413f, 0x14100c08081c140c, 0xf63152959563f652, 0xaf8c654646e9af65, 0xe2215e9d9d7fe25e, 0x7860283030487828, 0xf86ea13737cff8a1, 0x11140f0a0a1b110f, 0xc45eb52f2febc4b5, 0x1b1c090e0e151b09, 0x5a483624247e5a36, 0xb6369b1b1badb69b, 0x47a53ddfdf98473d, 0x6a8126cdcda76a26, 0xbb9c694e4ef5bb69, 0x4cfecd7f7f334ccd, 0xbacf9feaea50ba9f, 0x2d241b12123f2d1b, 0xb93a9e1d1da4b99e, 0x9cb0745858c49c74, 0x72682e343446722e, 0x776c2d363641772d, 0xcda3b2dcdc11cdb2, 0x2973eeb4b49d29ee, 0x16b6fb5b5b4d16fb, 0x0153f6a4a4a501f6, 0xd7ec4d7676a1d74d, 0xa37561b7b714a361, 0x49face7d7d3449ce, 0x8da47b5252df8d7b, 0x42a13edddd9f423e, 0x93bc715e5ecd9371, 0xa226971313b1a297, 0x0457f5a6a6a204f5, 0xb86968b9b901b868, 0x0000000000000000, 0x74992cc1c1b5742c, 0xa080604040e0a060, 0x21dd1fe3e3c2211f, 0x43f2c879793a43c8, 0x2c77edb6b69a2ced, 0xd9b3bed4d40dd9be, 0xca01468d8d47ca46, 0x70ced967671770d9, 0xdde44b7272afdd4b, 0x7933de9494ed79de, 0x672bd49898ff67d4, 0x237be8b0b09323e8, 0xde114a85855bde4a, 0xbd6d6bbbbb06bd6b, 0x7e912ac5c5bb7e2a, 0x349ee54f4f7b34e5, 0x3ac116ededd73a16, 0x5417c58686d254c5, 0x622fd79a9af862d7, 0xffcc55666699ff55, 0xa722941111b6a794, 0x4a0fcf8a8ac04acf, 0x30c910e9e9d93010, 0x0a080604040e0a06, 0x98e781fefe669881, 0x0b5bf0a0a0ab0bf0, 0xccf0447878b4cc44, 0xd54aba2525f0d5ba, 0x3e96e34b4b753ee3, 0x0e5ff3a2a2ac0ef3, 0x19bafe5d5d4419fe, 0x5b1bc08080db5bc0, 0x850a8a050580858a, 0xec7ead3f3fd3ecad, 0xdf42bc2121fedfbc, 0xd8e0487070a8d848, 0x0cf904f1f1fd0c04, 0x7ac6df6363197adf, 0x58eec177772f58c1, 0x9f4575afaf309f75, 0xa584634242e7a563, 0x5040302020705030, 0x2ed11ae5e5cb2e1a, 0x12e10efdfdef120e, 0xb7656dbfbf08b76d, 0xd4194c818155d44c, 0x3c30141818243c14, 0x5f4c352626795f35, 0x719d2fc3c3b2712f, 0x3867e1bebe8638e1, 0xfd6aa23535c8fda2, 0x4f0bcc8888c74fcc, 0x4b5c392e2e654b39, 0xf93d5793936af957, 0x0daaf25555580df2, 0x9de382fcfc619d82, 0xc9f4477a7ab3c947, 0xef8bacc8c827efac, 0x326fe7baba8832e7, 0x7d642b32324f7d2b, 0xa4d795e6e642a495, 0xfb9ba0c0c03bfba0, 0xb332981919aab398, 0x6827d19e9ef668d1, 0x815d7fa3a322817f, 0xaa88664444eeaa66, 0x82a87e5454d6827e, 0xe676ab3b3bdde6ab, 0x9e16830b0b959e83, 0x4503ca8c8cc945ca, 0x7b9529c7c7bc7b29, 0x6ed6d36b6b056ed3, 0x44503c28286c443c, 0x8b5579a7a72c8b79, 0x3d63e2bcbc813de2, 0x272c1d161631271d, 0x9a4176adad379a76, 0x4dad3bdbdb964d3b, 0xfac85664649efa56, 0xd2e84e7474a6d24e, 0x22281e141436221e, 0x763fdb9292e476db, 0x1e180a0c0c121e0a, 0xb4906c4848fcb46c, 0x376be4b8b88f37e4, 0xe7255d9f9f78e75d, 0xb2616ebdbd0fb26e, 0x2a86ef4343692aef, 0xf193a6c4c435f1a6, 0xe372a83939dae3a8, 0xf762a43131c6f7a4, 0x59bd37d3d38a5937, 0x86ff8bf2f274868b, 0x56b132d5d5835632, 0xc50d438b8b4ec543, 0xebdc596e6e85eb59, 0xc2afb7dada18c2b7, 0x8f028c01018e8f8c, 0xac7964b1b11dac64, 0x6d23d29c9cf16dd2, 0x3b92e04949723be0, 0xc7abb4d8d81fc7b4, 0x1543faacacb915fa, 0x09fd07f3f3fa0907, 0x6f8525cfcfa06f25, 0xea8fafcaca20eaaf, 0x89f38ef4f47d898e, 0x208ee947476720e9, 0x2820181010382818, 0x64ded56f6f0b64d5, 0x83fb88f0f0738388, 0xb1946f4a4afbb16f, 0x96b8725c5cca9672, 0x6c70243838546c24, 0x08aef157575f08f1, 0x52e6c773732152c7, 0xf33551979764f351, 0x658d23cbcbae6523, 0x84597ca1a125847c, 0xbfcb9ce8e857bf9c, 0x637c213e3e5d6321, 0x7c37dd9696ea7cdd, 0x7fc2dc61611e7fdc, 0x911a860d0d9c9186, 0x941e850f0f9b9485, 0xabdb90e0e04bab90, 0xc6f8427c7cbac642, 0x57e2c471712657c4, 0xe583aacccc29e5aa, 0x733bd89090e373d8, 0x0f0c050606090f05, 0x03f501f7f7f40301, 0x3638121c1c2a3612, 0xfe9fa3c2c23cfea3, 0xe1d45f6a6a8be15f, 0x1047f9aeaebe10f9, 0x6bd2d06969026bd0, 0xa82e911717bfa891, 0xe82958999971e858, 0x6974273a3a536927, 0xd04eb92727f7d0b9, 0x48a938d9d9914838, 0x35cd13ebebde3513, 0xce56b32b2be5ceb3, 0x5544332222775533, 0xd6bfbbd2d204d6bb, 0x904970a9a9399070, 0x800e890707878089, 0xf266a73333c1f2a7, 0xc15ab62d2decc1b6, 0x6678223c3c5a6622, 0xad2a921515b8ad92, 0x608920c9c9a96020, 0xdb154987875cdb49, 0x1a4fffaaaab01aff, 0x88a0785050d88878, 0x8e517aa5a52b8e7a, 0x8a068f0303898a8f, 0x13b2f859594a13f8, 0x9b12800909929b80, 0x3934171a1a233917, 0x75cada65651075da, 0x53b531d7d7845331, 0x5113c68484d551c6, 0xd3bbb8d0d003d3b8, 0x5e1fc38282dc5ec3, 0xcb52b02929e2cbb0, 0x99b4775a5ac39977, 0x333c111e1e2d3311, 0x46f6cb7b7b3d46cb, 0x1f4bfca8a8b71ffc, 0x61dad66d6d0c61d6, 0x4e583a2c2c624e3a], + [0xa5f497a5c6c632f4, 0x8497eb84f8f86f97, 0x99b0c799eeee5eb0, 0x8d8cf78df6f67a8c, 0x0d17e50dffffe817, 0xbddcb7bdd6d60adc, 0xb1c8a7b1dede16c8, 0x54fc395491916dfc, 0x50f0c050606090f0, 0x0305040302020705, 0xa9e087a9cece2ee0, 0x7d87ac7d5656d187, 0x192bd519e7e7cc2b, 0x62a67162b5b513a6, 0xe6319ae64d4d7c31, 0x9ab5c39aecec59b5, 0x45cf05458f8f40cf, 0x9dbc3e9d1f1fa3bc, 0x40c00940898949c0, 0x8792ef87fafa6892, 0x153fc515efefd03f, 0xeb267febb2b29426, 0xc94007c98e8ece40, 0x0b1ded0bfbfbe61d, 0xec2f82ec41416e2f, 0x67a97d67b3b31aa9, 0xfd1cbefd5f5f431c, 0xea258aea45456025, 0xbfda46bf2323f9da, 0xf702a6f753535102, 0x96a1d396e4e445a1, 0x5bed2d5b9b9b76ed, 0xc25deac27575285d, 0x1c24d91ce1e1c524, 0xaee97aae3d3dd4e9, 0x6abe986a4c4cf2be, 0x5aeed85a6c6c82ee, 0x41c3fc417e7ebdc3, 0x0206f102f5f5f306, 0x4fd11d4f838352d1, 0x5ce4d05c68688ce4, 0xf407a2f451515607, 0x345cb934d1d18d5c, 0x0818e908f9f9e118, 0x93aedf93e2e24cae, 0x73954d73abab3e95, 0x53f5c453626297f5, 0x3f41543f2a2a6b41, 0x0c14100c08081c14, 0x52f63152959563f6, 0x65af8c654646e9af, 0x5ee2215e9d9d7fe2, 0x2878602830304878, 0xa1f86ea13737cff8, 0x0f11140f0a0a1b11, 0xb5c45eb52f2febc4, 0x091b1c090e0e151b, 0x365a483624247e5a, 0x9bb6369b1b1badb6, 0x3d47a53ddfdf9847, 0x266a8126cdcda76a, 0x69bb9c694e4ef5bb, 0xcd4cfecd7f7f334c, 0x9fbacf9feaea50ba, 0x1b2d241b12123f2d, 0x9eb93a9e1d1da4b9, 0x749cb0745858c49c, 0x2e72682e34344672, 0x2d776c2d36364177, 0xb2cda3b2dcdc11cd, 0xee2973eeb4b49d29, 0xfb16b6fb5b5b4d16, 0xf60153f6a4a4a501, 0x4dd7ec4d7676a1d7, 0x61a37561b7b714a3, 0xce49face7d7d3449, 0x7b8da47b5252df8d, 0x3e42a13edddd9f42, 0x7193bc715e5ecd93, 0x97a226971313b1a2, 0xf50457f5a6a6a204, 0x68b86968b9b901b8, 0x0000000000000000, 0x2c74992cc1c1b574, 0x60a080604040e0a0, 0x1f21dd1fe3e3c221, 0xc843f2c879793a43, 0xed2c77edb6b69a2c, 0xbed9b3bed4d40dd9, 0x46ca01468d8d47ca, 0xd970ced967671770, 0x4bdde44b7272afdd, 0xde7933de9494ed79, 0xd4672bd49898ff67, 0xe8237be8b0b09323, 0x4ade114a85855bde, 0x6bbd6d6bbbbb06bd, 0x2a7e912ac5c5bb7e, 0xe5349ee54f4f7b34, 0x163ac116ededd73a, 0xc55417c58686d254, 0xd7622fd79a9af862, 0x55ffcc55666699ff, 0x94a722941111b6a7, 0xcf4a0fcf8a8ac04a, 0x1030c910e9e9d930, 0x060a080604040e0a, 0x8198e781fefe6698, 0xf00b5bf0a0a0ab0b, 0x44ccf0447878b4cc, 0xbad54aba2525f0d5, 0xe33e96e34b4b753e, 0xf30e5ff3a2a2ac0e, 0xfe19bafe5d5d4419, 0xc05b1bc08080db5b, 0x8a850a8a05058085, 0xadec7ead3f3fd3ec, 0xbcdf42bc2121fedf, 0x48d8e0487070a8d8, 0x040cf904f1f1fd0c, 0xdf7ac6df6363197a, 0xc158eec177772f58, 0x759f4575afaf309f, 0x63a584634242e7a5, 0x3050403020207050, 0x1a2ed11ae5e5cb2e, 0x0e12e10efdfdef12, 0x6db7656dbfbf08b7, 0x4cd4194c818155d4, 0x143c30141818243c, 0x355f4c352626795f, 0x2f719d2fc3c3b271, 0xe13867e1bebe8638, 0xa2fd6aa23535c8fd, 0xcc4f0bcc8888c74f, 0x394b5c392e2e654b, 0x57f93d5793936af9, 0xf20daaf25555580d, 0x829de382fcfc619d, 0x47c9f4477a7ab3c9, 0xacef8bacc8c827ef, 0xe7326fe7baba8832, 0x2b7d642b32324f7d, 0x95a4d795e6e642a4, 0xa0fb9ba0c0c03bfb, 0x98b332981919aab3, 0xd16827d19e9ef668, 0x7f815d7fa3a32281, 0x66aa88664444eeaa, 0x7e82a87e5454d682, 0xabe676ab3b3bdde6, 0x839e16830b0b959e, 0xca4503ca8c8cc945, 0x297b9529c7c7bc7b, 0xd36ed6d36b6b056e, 0x3c44503c28286c44, 0x798b5579a7a72c8b, 0xe23d63e2bcbc813d, 0x1d272c1d16163127, 0x769a4176adad379a, 0x3b4dad3bdbdb964d, 0x56fac85664649efa, 0x4ed2e84e7474a6d2, 0x1e22281e14143622, 0xdb763fdb9292e476, 0x0a1e180a0c0c121e, 0x6cb4906c4848fcb4, 0xe4376be4b8b88f37, 0x5de7255d9f9f78e7, 0x6eb2616ebdbd0fb2, 0xef2a86ef4343692a, 0xa6f193a6c4c435f1, 0xa8e372a83939dae3, 0xa4f762a43131c6f7, 0x3759bd37d3d38a59, 0x8b86ff8bf2f27486, 0x3256b132d5d58356, 0x43c50d438b8b4ec5, 0x59ebdc596e6e85eb, 0xb7c2afb7dada18c2, 0x8c8f028c01018e8f, 0x64ac7964b1b11dac, 0xd26d23d29c9cf16d, 0xe03b92e04949723b, 0xb4c7abb4d8d81fc7, 0xfa1543faacacb915, 0x0709fd07f3f3fa09, 0x256f8525cfcfa06f, 0xafea8fafcaca20ea, 0x8e89f38ef4f47d89, 0xe9208ee947476720, 0x1828201810103828, 0xd564ded56f6f0b64, 0x8883fb88f0f07383, 0x6fb1946f4a4afbb1, 0x7296b8725c5cca96, 0x246c70243838546c, 0xf108aef157575f08, 0xc752e6c773732152, 0x51f33551979764f3, 0x23658d23cbcbae65, 0x7c84597ca1a12584, 0x9cbfcb9ce8e857bf, 0x21637c213e3e5d63, 0xdd7c37dd9696ea7c, 0xdc7fc2dc61611e7f, 0x86911a860d0d9c91, 0x85941e850f0f9b94, 0x90abdb90e0e04bab, 0x42c6f8427c7cbac6, 0xc457e2c471712657, 0xaae583aacccc29e5, 0xd8733bd89090e373, 0x050f0c050606090f, 0x0103f501f7f7f403, 0x123638121c1c2a36, 0xa3fe9fa3c2c23cfe, 0x5fe1d45f6a6a8be1, 0xf91047f9aeaebe10, 0xd06bd2d06969026b, 0x91a82e911717bfa8, 0x58e82958999971e8, 0x276974273a3a5369, 0xb9d04eb92727f7d0, 0x3848a938d9d99148, 0x1335cd13ebebde35, 0xb3ce56b32b2be5ce, 0x3355443322227755, 0xbbd6bfbbd2d204d6, 0x70904970a9a93990, 0x89800e8907078780, 0xa7f266a73333c1f2, 0xb6c15ab62d2decc1, 0x226678223c3c5a66, 0x92ad2a921515b8ad, 0x20608920c9c9a960, 0x49db154987875cdb, 0xff1a4fffaaaab01a, 0x7888a0785050d888, 0x7a8e517aa5a52b8e, 0x8f8a068f0303898a, 0xf813b2f859594a13, 0x809b12800909929b, 0x173934171a1a2339, 0xda75cada65651075, 0x3153b531d7d78453, 0xc65113c68484d551, 0xb8d3bbb8d0d003d3, 0xc35e1fc38282dc5e, 0xb0cb52b02929e2cb, 0x7799b4775a5ac399, 0x11333c111e1e2d33, 0xcb46f6cb7b7b3d46, 0xfc1f4bfca8a8b71f, 0xd661dad66d6d0c61, 0x3a4e583a2c2c624e], + [0xf4a5f497a5c6c632, 0x978497eb84f8f86f, 0xb099b0c799eeee5e, 0x8c8d8cf78df6f67a, 0x170d17e50dffffe8, 0xdcbddcb7bdd6d60a, 0xc8b1c8a7b1dede16, 0xfc54fc395491916d, 0xf050f0c050606090, 0x0503050403020207, 0xe0a9e087a9cece2e, 0x877d87ac7d5656d1, 0x2b192bd519e7e7cc, 0xa662a67162b5b513, 0x31e6319ae64d4d7c, 0xb59ab5c39aecec59, 0xcf45cf05458f8f40, 0xbc9dbc3e9d1f1fa3, 0xc040c00940898949, 0x928792ef87fafa68, 0x3f153fc515efefd0, 0x26eb267febb2b294, 0x40c94007c98e8ece, 0x1d0b1ded0bfbfbe6, 0x2fec2f82ec41416e, 0xa967a97d67b3b31a, 0x1cfd1cbefd5f5f43, 0x25ea258aea454560, 0xdabfda46bf2323f9, 0x02f702a6f7535351, 0xa196a1d396e4e445, 0xed5bed2d5b9b9b76, 0x5dc25deac2757528, 0x241c24d91ce1e1c5, 0xe9aee97aae3d3dd4, 0xbe6abe986a4c4cf2, 0xee5aeed85a6c6c82, 0xc341c3fc417e7ebd, 0x060206f102f5f5f3, 0xd14fd11d4f838352, 0xe45ce4d05c68688c, 0x07f407a2f4515156, 0x5c345cb934d1d18d, 0x180818e908f9f9e1, 0xae93aedf93e2e24c, 0x9573954d73abab3e, 0xf553f5c453626297, 0x413f41543f2a2a6b, 0x140c14100c08081c, 0xf652f63152959563, 0xaf65af8c654646e9, 0xe25ee2215e9d9d7f, 0x7828786028303048, 0xf8a1f86ea13737cf, 0x110f11140f0a0a1b, 0xc4b5c45eb52f2feb, 0x1b091b1c090e0e15, 0x5a365a483624247e, 0xb69bb6369b1b1bad, 0x473d47a53ddfdf98, 0x6a266a8126cdcda7, 0xbb69bb9c694e4ef5, 0x4ccd4cfecd7f7f33, 0xba9fbacf9feaea50, 0x2d1b2d241b12123f, 0xb99eb93a9e1d1da4, 0x9c749cb0745858c4, 0x722e72682e343446, 0x772d776c2d363641, 0xcdb2cda3b2dcdc11, 0x29ee2973eeb4b49d, 0x16fb16b6fb5b5b4d, 0x01f60153f6a4a4a5, 0xd74dd7ec4d7676a1, 0xa361a37561b7b714, 0x49ce49face7d7d34, 0x8d7b8da47b5252df, 0x423e42a13edddd9f, 0x937193bc715e5ecd, 0xa297a226971313b1, 0x04f50457f5a6a6a2, 0xb868b86968b9b901, 0x0000000000000000, 0x742c74992cc1c1b5, 0xa060a080604040e0, 0x211f21dd1fe3e3c2, 0x43c843f2c879793a, 0x2ced2c77edb6b69a, 0xd9bed9b3bed4d40d, 0xca46ca01468d8d47, 0x70d970ced9676717, 0xdd4bdde44b7272af, 0x79de7933de9494ed, 0x67d4672bd49898ff, 0x23e8237be8b0b093, 0xde4ade114a85855b, 0xbd6bbd6d6bbbbb06, 0x7e2a7e912ac5c5bb, 0x34e5349ee54f4f7b, 0x3a163ac116ededd7, 0x54c55417c58686d2, 0x62d7622fd79a9af8, 0xff55ffcc55666699, 0xa794a722941111b6, 0x4acf4a0fcf8a8ac0, 0x301030c910e9e9d9, 0x0a060a080604040e, 0x988198e781fefe66, 0x0bf00b5bf0a0a0ab, 0xcc44ccf0447878b4, 0xd5bad54aba2525f0, 0x3ee33e96e34b4b75, 0x0ef30e5ff3a2a2ac, 0x19fe19bafe5d5d44, 0x5bc05b1bc08080db, 0x858a850a8a050580, 0xecadec7ead3f3fd3, 0xdfbcdf42bc2121fe, 0xd848d8e0487070a8, 0x0c040cf904f1f1fd, 0x7adf7ac6df636319, 0x58c158eec177772f, 0x9f759f4575afaf30, 0xa563a584634242e7, 0x5030504030202070, 0x2e1a2ed11ae5e5cb, 0x120e12e10efdfdef, 0xb76db7656dbfbf08, 0xd44cd4194c818155, 0x3c143c3014181824, 0x5f355f4c35262679, 0x712f719d2fc3c3b2, 0x38e13867e1bebe86, 0xfda2fd6aa23535c8, 0x4fcc4f0bcc8888c7, 0x4b394b5c392e2e65, 0xf957f93d5793936a, 0x0df20daaf2555558, 0x9d829de382fcfc61, 0xc947c9f4477a7ab3, 0xefacef8bacc8c827, 0x32e7326fe7baba88, 0x7d2b7d642b32324f, 0xa495a4d795e6e642, 0xfba0fb9ba0c0c03b, 0xb398b332981919aa, 0x68d16827d19e9ef6, 0x817f815d7fa3a322, 0xaa66aa88664444ee, 0x827e82a87e5454d6, 0xe6abe676ab3b3bdd, 0x9e839e16830b0b95, 0x45ca4503ca8c8cc9, 0x7b297b9529c7c7bc, 0x6ed36ed6d36b6b05, 0x443c44503c28286c, 0x8b798b5579a7a72c, 0x3de23d63e2bcbc81, 0x271d272c1d161631, 0x9a769a4176adad37, 0x4d3b4dad3bdbdb96, 0xfa56fac85664649e, 0xd24ed2e84e7474a6, 0x221e22281e141436, 0x76db763fdb9292e4, 0x1e0a1e180a0c0c12, 0xb46cb4906c4848fc, 0x37e4376be4b8b88f, 0xe75de7255d9f9f78, 0xb26eb2616ebdbd0f, 0x2aef2a86ef434369, 0xf1a6f193a6c4c435, 0xe3a8e372a83939da, 0xf7a4f762a43131c6, 0x593759bd37d3d38a, 0x868b86ff8bf2f274, 0x563256b132d5d583, 0xc543c50d438b8b4e, 0xeb59ebdc596e6e85, 0xc2b7c2afb7dada18, 0x8f8c8f028c01018e, 0xac64ac7964b1b11d, 0x6dd26d23d29c9cf1, 0x3be03b92e0494972, 0xc7b4c7abb4d8d81f, 0x15fa1543faacacb9, 0x090709fd07f3f3fa, 0x6f256f8525cfcfa0, 0xeaafea8fafcaca20, 0x898e89f38ef4f47d, 0x20e9208ee9474767, 0x2818282018101038, 0x64d564ded56f6f0b, 0x838883fb88f0f073, 0xb16fb1946f4a4afb, 0x967296b8725c5cca, 0x6c246c7024383854, 0x08f108aef157575f, 0x52c752e6c7737321, 0xf351f33551979764, 0x6523658d23cbcbae, 0x847c84597ca1a125, 0xbf9cbfcb9ce8e857, 0x6321637c213e3e5d, 0x7cdd7c37dd9696ea, 0x7fdc7fc2dc61611e, 0x9186911a860d0d9c, 0x9485941e850f0f9b, 0xab90abdb90e0e04b, 0xc642c6f8427c7cba, 0x57c457e2c4717126, 0xe5aae583aacccc29, 0x73d8733bd89090e3, 0x0f050f0c05060609, 0x030103f501f7f7f4, 0x36123638121c1c2a, 0xfea3fe9fa3c2c23c, 0xe15fe1d45f6a6a8b, 0x10f91047f9aeaebe, 0x6bd06bd2d0696902, 0xa891a82e911717bf, 0xe858e82958999971, 0x69276974273a3a53, 0xd0b9d04eb92727f7, 0x483848a938d9d991, 0x351335cd13ebebde, 0xceb3ce56b32b2be5, 0x5533554433222277, 0xd6bbd6bfbbd2d204, 0x9070904970a9a939, 0x8089800e89070787, 0xf2a7f266a73333c1, 0xc1b6c15ab62d2dec, 0x66226678223c3c5a, 0xad92ad2a921515b8, 0x6020608920c9c9a9, 0xdb49db154987875c, 0x1aff1a4fffaaaab0, 0x887888a0785050d8, 0x8e7a8e517aa5a52b, 0x8a8f8a068f030389, 0x13f813b2f859594a, 0x9b809b1280090992, 0x39173934171a1a23, 0x75da75cada656510, 0x533153b531d7d784, 0x51c65113c68484d5, 0xd3b8d3bbb8d0d003, 0x5ec35e1fc38282dc, 0xcbb0cb52b02929e2, 0x997799b4775a5ac3, 0x3311333c111e1e2d, 0x46cb46f6cb7b7b3d, 0x1ffc1f4bfca8a8b7, 0x61d661dad66d6d0c, 0x4e3a4e583a2c2c62], + [0x32f4a5f497a5c6c6, 0x6f978497eb84f8f8, 0x5eb099b0c799eeee, 0x7a8c8d8cf78df6f6, 0xe8170d17e50dffff, 0x0adcbddcb7bdd6d6, 0x16c8b1c8a7b1dede, 0x6dfc54fc39549191, 0x90f050f0c0506060, 0x0705030504030202, 0x2ee0a9e087a9cece, 0xd1877d87ac7d5656, 0xcc2b192bd519e7e7, 0x13a662a67162b5b5, 0x7c31e6319ae64d4d, 0x59b59ab5c39aecec, 0x40cf45cf05458f8f, 0xa3bc9dbc3e9d1f1f, 0x49c040c009408989, 0x68928792ef87fafa, 0xd03f153fc515efef, 0x9426eb267febb2b2, 0xce40c94007c98e8e, 0xe61d0b1ded0bfbfb, 0x6e2fec2f82ec4141, 0x1aa967a97d67b3b3, 0x431cfd1cbefd5f5f, 0x6025ea258aea4545, 0xf9dabfda46bf2323, 0x5102f702a6f75353, 0x45a196a1d396e4e4, 0x76ed5bed2d5b9b9b, 0x285dc25deac27575, 0xc5241c24d91ce1e1, 0xd4e9aee97aae3d3d, 0xf2be6abe986a4c4c, 0x82ee5aeed85a6c6c, 0xbdc341c3fc417e7e, 0xf3060206f102f5f5, 0x52d14fd11d4f8383, 0x8ce45ce4d05c6868, 0x5607f407a2f45151, 0x8d5c345cb934d1d1, 0xe1180818e908f9f9, 0x4cae93aedf93e2e2, 0x3e9573954d73abab, 0x97f553f5c4536262, 0x6b413f41543f2a2a, 0x1c140c14100c0808, 0x63f652f631529595, 0xe9af65af8c654646, 0x7fe25ee2215e9d9d, 0x4878287860283030, 0xcff8a1f86ea13737, 0x1b110f11140f0a0a, 0xebc4b5c45eb52f2f, 0x151b091b1c090e0e, 0x7e5a365a48362424, 0xadb69bb6369b1b1b, 0x98473d47a53ddfdf, 0xa76a266a8126cdcd, 0xf5bb69bb9c694e4e, 0x334ccd4cfecd7f7f, 0x50ba9fbacf9feaea, 0x3f2d1b2d241b1212, 0xa4b99eb93a9e1d1d, 0xc49c749cb0745858, 0x46722e72682e3434, 0x41772d776c2d3636, 0x11cdb2cda3b2dcdc, 0x9d29ee2973eeb4b4, 0x4d16fb16b6fb5b5b, 0xa501f60153f6a4a4, 0xa1d74dd7ec4d7676, 0x14a361a37561b7b7, 0x3449ce49face7d7d, 0xdf8d7b8da47b5252, 0x9f423e42a13edddd, 0xcd937193bc715e5e, 0xb1a297a226971313, 0xa204f50457f5a6a6, 0x01b868b86968b9b9, 0x0000000000000000, 0xb5742c74992cc1c1, 0xe0a060a080604040, 0xc2211f21dd1fe3e3, 0x3a43c843f2c87979, 0x9a2ced2c77edb6b6, 0x0dd9bed9b3bed4d4, 0x47ca46ca01468d8d, 0x1770d970ced96767, 0xafdd4bdde44b7272, 0xed79de7933de9494, 0xff67d4672bd49898, 0x9323e8237be8b0b0, 0x5bde4ade114a8585, 0x06bd6bbd6d6bbbbb, 0xbb7e2a7e912ac5c5, 0x7b34e5349ee54f4f, 0xd73a163ac116eded, 0xd254c55417c58686, 0xf862d7622fd79a9a, 0x99ff55ffcc556666, 0xb6a794a722941111, 0xc04acf4a0fcf8a8a, 0xd9301030c910e9e9, 0x0e0a060a08060404, 0x66988198e781fefe, 0xab0bf00b5bf0a0a0, 0xb4cc44ccf0447878, 0xf0d5bad54aba2525, 0x753ee33e96e34b4b, 0xac0ef30e5ff3a2a2, 0x4419fe19bafe5d5d, 0xdb5bc05b1bc08080, 0x80858a850a8a0505, 0xd3ecadec7ead3f3f, 0xfedfbcdf42bc2121, 0xa8d848d8e0487070, 0xfd0c040cf904f1f1, 0x197adf7ac6df6363, 0x2f58c158eec17777, 0x309f759f4575afaf, 0xe7a563a584634242, 0x7050305040302020, 0xcb2e1a2ed11ae5e5, 0xef120e12e10efdfd, 0x08b76db7656dbfbf, 0x55d44cd4194c8181, 0x243c143c30141818, 0x795f355f4c352626, 0xb2712f719d2fc3c3, 0x8638e13867e1bebe, 0xc8fda2fd6aa23535, 0xc74fcc4f0bcc8888, 0x654b394b5c392e2e, 0x6af957f93d579393, 0x580df20daaf25555, 0x619d829de382fcfc, 0xb3c947c9f4477a7a, 0x27efacef8bacc8c8, 0x8832e7326fe7baba, 0x4f7d2b7d642b3232, 0x42a495a4d795e6e6, 0x3bfba0fb9ba0c0c0, 0xaab398b332981919, 0xf668d16827d19e9e, 0x22817f815d7fa3a3, 0xeeaa66aa88664444, 0xd6827e82a87e5454, 0xdde6abe676ab3b3b, 0x959e839e16830b0b, 0xc945ca4503ca8c8c, 0xbc7b297b9529c7c7, 0x056ed36ed6d36b6b, 0x6c443c44503c2828, 0x2c8b798b5579a7a7, 0x813de23d63e2bcbc, 0x31271d272c1d1616, 0x379a769a4176adad, 0x964d3b4dad3bdbdb, 0x9efa56fac8566464, 0xa6d24ed2e84e7474, 0x36221e22281e1414, 0xe476db763fdb9292, 0x121e0a1e180a0c0c, 0xfcb46cb4906c4848, 0x8f37e4376be4b8b8, 0x78e75de7255d9f9f, 0x0fb26eb2616ebdbd, 0x692aef2a86ef4343, 0x35f1a6f193a6c4c4, 0xdae3a8e372a83939, 0xc6f7a4f762a43131, 0x8a593759bd37d3d3, 0x74868b86ff8bf2f2, 0x83563256b132d5d5, 0x4ec543c50d438b8b, 0x85eb59ebdc596e6e, 0x18c2b7c2afb7dada, 0x8e8f8c8f028c0101, 0x1dac64ac7964b1b1, 0xf16dd26d23d29c9c, 0x723be03b92e04949, 0x1fc7b4c7abb4d8d8, 0xb915fa1543faacac, 0xfa090709fd07f3f3, 0xa06f256f8525cfcf, 0x20eaafea8fafcaca, 0x7d898e89f38ef4f4, 0x6720e9208ee94747, 0x3828182820181010, 0x0b64d564ded56f6f, 0x73838883fb88f0f0, 0xfbb16fb1946f4a4a, 0xca967296b8725c5c, 0x546c246c70243838, 0x5f08f108aef15757, 0x2152c752e6c77373, 0x64f351f335519797, 0xae6523658d23cbcb, 0x25847c84597ca1a1, 0x57bf9cbfcb9ce8e8, 0x5d6321637c213e3e, 0xea7cdd7c37dd9696, 0x1e7fdc7fc2dc6161, 0x9c9186911a860d0d, 0x9b9485941e850f0f, 0x4bab90abdb90e0e0, 0xbac642c6f8427c7c, 0x2657c457e2c47171, 0x29e5aae583aacccc, 0xe373d8733bd89090, 0x090f050f0c050606, 0xf4030103f501f7f7, 0x2a36123638121c1c, 0x3cfea3fe9fa3c2c2, 0x8be15fe1d45f6a6a, 0xbe10f91047f9aeae, 0x026bd06bd2d06969, 0xbfa891a82e911717, 0x71e858e829589999, 0x5369276974273a3a, 0xf7d0b9d04eb92727, 0x91483848a938d9d9, 0xde351335cd13ebeb, 0xe5ceb3ce56b32b2b, 0x7755335544332222, 0x04d6bbd6bfbbd2d2, 0x399070904970a9a9, 0x878089800e890707, 0xc1f2a7f266a73333, 0xecc1b6c15ab62d2d, 0x5a66226678223c3c, 0xb8ad92ad2a921515, 0xa96020608920c9c9, 0x5cdb49db15498787, 0xb01aff1a4fffaaaa, 0xd8887888a0785050, 0x2b8e7a8e517aa5a5, 0x898a8f8a068f0303, 0x4a13f813b2f85959, 0x929b809b12800909, 0x2339173934171a1a, 0x1075da75cada6565, 0x84533153b531d7d7, 0xd551c65113c68484, 0x03d3b8d3bbb8d0d0, 0xdc5ec35e1fc38282, 0xe2cbb0cb52b02929, 0xc3997799b4775a5a, 0x2d3311333c111e1e, 0x3d46cb46f6cb7b7b, 0xb71ffc1f4bfca8a8, 0x0c61d661dad66d6d, 0x624e3a4e583a2c2c], +]; diff --git a/groestl/tests/data/groestl224.blb b/groestl/tests/data/groestl224.blb index 090b5473e7e417908a70d4737e6dfaab9f0a765f..1705d414cfc570f59fdadfc3c773c02eac1e6ad6 100644 GIT binary patch delta 5591 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 delta 5599 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 diff --git a/groestl/tests/data/groestl256.blb b/groestl/tests/data/groestl256.blb index b24aed4db07b5c3caefba62ab0c9a975a83fcc51..122de3971d024919c9e66e1ceeb0aadda7e06ac5 100644 GIT binary patch delta 4316 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 delta 4132 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 Cl~?Ql diff --git a/groestl/tests/data/groestl384.blb b/groestl/tests/data/groestl384.blb index 72174f6a8d5211772557f7e6ba26de889ab21d23..cf0e6a1522610915b71ec9c48d12f9bb4c33cff3 100644 GIT binary patch delta 3509 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 diff --git a/groestl/tests/data/groestl512.blb b/groestl/tests/data/groestl512.blb index 89b904f19b9a02b99beff8dada74b842979b044b..24ce9ee34a8655f5cad718c8a4c4cdbf1ea2e588 100644 GIT binary patch delta 3765 zcmXBWd0dTYAII@d(ms_WY0@SwM20G9{LbE-Ix#Q-`y{sbF|IGz3M`c;yVJLYWms-zzVHJXM62 z{?nINFMYgG_k1YqH6LwJ;UIdmFiOH6%4la)r@nt71)6IKSLf07T~hcaoL)^eyuOK2NJ54mrB zW1~3qVat{8`Rs`n7g;3LEU>)=pQm1KS) zjXn{3itZMe<@5P02d)HdaA-tjGl}IzX_IzAnvN_V3Uq9OeuaE#(&T37>SUH5={xO) z`kh$*^taOP%utKTcr4{mdFeIbFS@Bt{W?odfYmo1b0>xHM{SJLZ-7~ zsABp7$kT%rOT``sA;%f4ILevP30VkM0wsw<&}dIqB1L*0hBUlb$rRw##j5ZYqb%}L zre6q)7iY|6ZoN;`%FLRKIg@#FmO_=@-MHlM!%CwvpB~6_CM$!AXZAwVd|8=P=z9cm zoW;tboLNU9TR&DdE%EDvtY))vDP{ICXq-PQpA!B1A=5dm0*asWC1f1HDx`%01JKw& zp>L@?^lB)0$|IAu->p{$ZZ^^Vrs^S2*?}C&sVnd}!t5Yc5p@NffO6&v#bO2Oo_i9? z3uY-&Z}2IoAcUnveIZ{#@=%sC4TPSC*34t6(pU5T1C`2H>U2(a2HFzF(xkz#v(WZ% zmKI$P{~BtD5W|%`-}Bpp2r=6Femw1{Qw}eGwBeU9aiDSWtebB`c$*fK1YLU{{VhSa;@60|OsWkhFUzlFY7 z$TFs@3kRV+aV%4M6n7aq63;THxAEUW-y{eF>5bdvci-QB@edW=UyR@>OX0VwNo(U3?8HPhr{9<&^8t zzEqY2JxRR*eU-*?q+#hdp*!g;Co<0X5&A2GcZ>yy!6|3?ADI% zyfArV!IFii?aF!0%;eUE4rbm)yJ;!Ql`bv41GQ(d-06ANUFgCxmIrBO{{%hHW(l&( z`5Ds6WqHxu+#yLJ^ukzxSZuj{mX}-#sZc<-79zqeZ4{$+BeFS zep=8Uky>P{|IX&_yL0VR;;!i~ZRFXskmCS~FMNd9ZzU^;K419@v`o$lro-~bP|ato zP`dru6XSvJ28dfC5t$7Xw7PF#gOYsXxzLph318ZMG9qU-J z^kUsB=+1f}aUkOo17KXp!A-7GeG?H)n1Ipga%Al^ze?o0rSef)}%YUH<<*Y2S*!mV4yN#7ivD^NFA}fTE zW7|LHEv8TRS4)a)j=N}e?nc6|$8&DQZfFbRpsRxOT>8D@9r9Pi$|r{}-b1#PtO8n6 z`8SldomEKf+y8-Dt5|Y+TJ-^XvV&Db(w!e6X|<3zQF^r@P*N?7o!^}q7ZJ7dxt~>a z;mrCSAGeM%*qt}b+v-(Mq&FuIs)dP*c9~uI;LU5BKAw^f9vYohGw(`bLi2CF@8v6w z#&Y9XBTQXe7oC1w`7ugksMtp#Wb+!&iKPqo3^%)&$?3h7WbrnFE6iU(%@`2RPLWi67_>+-9Q+H1SQg;hgb+gw_9TAMq-9nN`uXj6QvDhOd$&|EbGO&}8LOF% zB#nYwrT`_34Enmo8Ti1+q#1js0?YRbNfsU5>jJ!HWRv5*X+Xw4A<3ov`&@y?jC`_b zbpw)Gg_`EsKQxX6*|7Gv3P}OIY<0&pp-o5%DWh#V(8iF{vo;Sv+AbtTl-@oAXm1yI zJpcd0u7jmWnH`=u?1Yr)b%z(^w4bF+dHcPgK1h|`?e~FZ9AK%_>H{;Ovj>E_)`+T+ z7uUXg#ne8?qb3C(^u<^OY0-^?vmnz>mJY>t`ax}wEpI{tG_E!KsMw`5=I=GBx& z_XJ~2>0y~uYfs3(Hz5mh?+t~@ds&urxpy99afD?}Nk?SRF-S`9kAy)XM_IO1aWouy z0@;(aF9Is=V>!_2zDUUE7|W3s9GedvIVLo9O_JL^*T1M)l*b2({X9F7cYhS-ddQi6 z>W_xpzGS(O{L2{VCge(n0}G&n0hT-U4a7nQ$5|dU|M)_v4-)k5cpMacg5^cEC*q+G XkPpo`nE*ANWckvAlZ&8Pr^NpNH-m34 delta 3227 zcmW;Od00q^8V2zDk;qbsl&us}N@S;2MnO}1T8Z91KF}H3lkEaKm5<-J^<1C}OIF(r@XhXlFQ;-eRaS4SyO=qrIzYts3QTu9tql zmG-L4_pKtMs!A9hR}K4-R#OSbnrh*66(g1D@HCoEAEIaAv(XGXth!1B3aUrY&1$Gb zVp5Gr`Y!zw8rS@ZMopEOxL$K6J+PL_EUcJlfDqB?^7bqUba9d{nD5 zpN^}e5{>h9qUnBhRTf}*-34?_bCrb{Y`&2G&D;ZK^%hZU>#0et9erA~wKr?sxshw1 zGG3G?^;8z4g~ej#xfUu*@Y-St9bu^wgF?#~x@&!vSVYy2r7Jg3S&H5bmeQqk984O< z(d!$k#N$rGczQx3l>}rpN}ydDt1Lrg<7M=BdO19-meZH4)YRC`e@1CwYDku=k8x2} zbA`3F$_fNpuVA5qUI~{bE9sL>R92yq%_=(CMrAdw*{r4~+NvaChixL=rKw61<~2>C zjhm??V`#Hvx{Llo-a(eO^&JE4`|% z;&=;{b;hI1O77=p)zMXc^-{_st&O7Py&MMh(>XJ?0?4osQFMgCbt7sVw7txUCm7;5B=Tp=nwQRbamfFzi?N{hhw*V`ffLs z-Duo>H+`wQN&!r@fIg)vdtl(Phd$t;vKJpc_R_n0sO&>UkA3vEo?6#zX0ZE3-#|TW z>*Korh0$`GOe@95o+^cK?N!Lq+g>U~XxF=lF7K_fA5MMt(`9{B4#3Xy0R7NYH^(nw8}+9jJ`;B4^Sz=qJR>5$QYGUB#kMh$Bk9Fgv_y*=!kJDmr*$G zG94SJ@*BUfp6xDx-C{xw169SoPfqdzTE z`7hj-|Ce@Iq4GB(SNu(ftW^02xhwynGgqnni?UV!()U)YyoXidd)gvNeH|2PjFuIiEg=833;r+a$epNmSwkqgtVHrO_#t#pP4?*0%i8D&WP(=z#rs zR;i{6-_0sEShv}Rha949@oBRyZI!Ol6l2qy(lK;1oK9~>zoeVPDWf?(EJMW(YclNU zqjU>=&1gZ}ZBavm;#Xh4@I~LEVvqbS_FUhh9Z)~hf$o*5(h{+mE$Kb9Bi>~?($-s5 zoG@;y6TOOVh09x8(cfribl>Johi_A9je>2h=|^-M*luq_`)pTn!P@OE^ttU?wTjK# z_IZB%mB~_R3$LuU+{e=Ga3-rA{h4kLw;k>2h#e{&uy02Px}5F^$DJMN@jF#IVcX75 z^nJQBtg<`P{@E&Bupzq(eU0u4^PH}?Jr zzbD;hw@NQW?CwP$qV{$(ss(iVIZwptPV56Z1VPp77h_NoUY~ z@pw;P+G(#!KZNb=M<1g54p&RYj>ec!WY0@mltGS(G@_v<}$lgDc(P!EV?gzZ+!~-hcxO%{wwmYaY z48aG7(Z^^Xd_U+z`yNv9Mam&x`VBoCZ4M8o;}5I&;lg1*y6F)We@r~$PoJPiK#q=} zM<3N1M%I&ZJz`&P8b4F9^Qg*5lph_*tj{r(QHVb_ihe?mMvLR4>Dc2c0XTa+fVMlK zG6umX#?a^Jv8aA>EFF4MWgK>$97mfJs|3QUIFK%+gYa*05Iypg%6O!n8c)kF`ajCo B*|q=x diff --git a/k12/CHANGELOG.md b/k12/CHANGELOG.md index da46bb91a..c6400fda1 100644 --- a/k12/CHANGELOG.md +++ b/k12/CHANGELOG.md @@ -5,6 +5,12 @@ 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.2.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.1.0 (2020-06-09) ### Changed - Update to `digest` v0.9 release; MSRV 1.41+ ([#155]) diff --git a/k12/Cargo.toml b/k12/Cargo.toml index 7b227d4dd..d736e0827 100644 --- a/k12/Cargo.toml +++ b/k12/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "k12" -version = "0.1.0" +version = "0.2.0" # Also update html_root_url in lib.rs when bumping this description = "Experimental pure Rust implementation of the KangarooTwelve hash function" authors = ["Diggory Hardy "] license = "Apache-2.0 OR MIT" @@ -12,10 +12,10 @@ keywords = ["crypto", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = { version = "0.9", features = ["alloc"] } +digest = { version = "0.10", features = ["alloc"] } [dev-dependencies] -digest = { version = "0.9", features = ["alloc", "dev"] } +digest = { version = "0.10", features = ["alloc", "dev"] } hex-literal = "0.2" [features] diff --git a/k12/src/lib.rs b/k12/src/lib.rs index 8c467d869..47e15deb3 100644 --- a/k12/src/lib.rs +++ b/k12/src/lib.rs @@ -10,8 +10,9 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/k12/0.2.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -28,7 +29,7 @@ mod lanes; // TODO(tarcieri): eliminate usage of `Vec` use alloc::vec::Vec; use core::{cmp::min, convert::TryInto, mem}; -use digest::{ExtendableOutputDirty, Reset, Update, XofReader}; +use digest::{ExtendableOutput, HashMarker, Reset, Update, XofReader}; /// The KangarooTwelve extendable-output function (XOF). #[derive(Debug, Default)] @@ -57,17 +58,26 @@ impl KangarooTwelve { } } +impl HashMarker for KangarooTwelve {} + impl Update for KangarooTwelve { - /// Input data into the hash function - fn update(&mut self, bytes: impl AsRef<[u8]>) { - self.buffer.extend_from_slice(bytes.as_ref()); + fn update(&mut self, bytes: &[u8]) { + self.buffer.extend_from_slice(bytes); } } -impl ExtendableOutputDirty for KangarooTwelve { +impl ExtendableOutput for KangarooTwelve { type Reader = Reader; - fn finalize_xof_dirty(&mut self) -> Self::Reader { + fn finalize_xof(self) -> Self::Reader { + Reader { + buffer: self.buffer, + customization: self.customization, + finished: false, + } + } + + fn finalize_xof_reset(&mut self) -> Self::Reader { let mut buffer = vec![]; let mut customization = vec![]; diff --git a/k12/tests/lib.rs b/k12/tests/lib.rs index a71c0a2cd..e6ddc4434 100644 --- a/k12/tests/lib.rs +++ b/k12/tests/lib.rs @@ -4,6 +4,12 @@ use k12::{ KangarooTwelve, }; +fn digest_and_box(data: &[u8], n: usize) -> Box<[u8]> { + let mut h = KangarooTwelve::new(); + h.update(data); + h.finalize_boxed(n) +} + fn read_bytes>(s: T) -> Box<[u8]> { fn b(c: u8) -> u8 { match c { @@ -36,7 +42,7 @@ fn read_bytes>(s: T) -> Box<[u8]> { fn empty() { // Source: reference paper assert_eq!( - KangarooTwelve::new().chain(b"").finalize_boxed(32), + digest_and_box(b"", 32), read_bytes( "1a c2 d4 50 fc 3b 42 05 d1 9d a7 bf ca 1b 37 51 3c 08 03 57 7a c7 16 7f 06 fe 2c e1 f0 ef 39 e5" @@ -44,7 +50,7 @@ fn empty() { ); assert_eq!( - KangarooTwelve::new().chain(b"").finalize_boxed(64), + digest_and_box(b"", 64), read_bytes( "1a c2 d4 50 fc 3b 42 05 d1 9d a7 bf ca 1b 37 51 3c 08 03 57 7a c7 16 7f 06 fe 2c e1 f0 ef 39 e5 42 69 c0 56 b8 c8 2e @@ -53,7 +59,7 @@ fn empty() { ); assert_eq!( - KangarooTwelve::new().chain(b"").finalize_boxed(10032)[10000..], + digest_and_box(b"", 10032)[10000..], read_bytes( "e8 dc 56 36 42 f7 22 8c 84 68 4c 89 84 05 d3 a8 34 79 91 58 c0 79 b1 28 80 27 7a 1d 28 e2 ff 6d" @@ -84,7 +90,7 @@ fn pat_m() { { let len = 17usize.pow(i); let m: Vec = (0..len).map(|j| (j % 251) as u8).collect(); - let result = KangarooTwelve::new().chain(&m).finalize_boxed(32); + let result = digest_and_box(&m, 32); assert_eq!(result, read_bytes(expected[i as usize])); } } @@ -105,9 +111,9 @@ fn pat_c() { let m: Vec = iter::repeat(0xFF).take(2usize.pow(i) - 1).collect(); let len = 41usize.pow(i); let c: Vec = (0..len).map(|j| (j % 251) as u8).collect(); - let result = KangarooTwelve::new_with_customization(c) - .chain(&m) - .finalize_boxed(32); + let mut h = KangarooTwelve::new_with_customization(c); + h.update(&m); + let result = h.finalize_boxed(32); assert_eq!(result, read_bytes(expected[i as usize])); } } diff --git a/md2/CHANGELOG.md b/md2/CHANGELOG.md index 2319dae63..aaec8e9e1 100644 --- a/md2/CHANGELOG.md +++ b/md2/CHANGELOG.md @@ -5,6 +5,12 @@ 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.10.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.9.0 (2020-06-12) ### Changed - Bump `opaque-debug` to v0.3.0 ([#168]) diff --git a/md2/Cargo.toml b/md2/Cargo.toml index a025061d8..33b7833fc 100644 --- a/md2/Cargo.toml +++ b/md2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "md2" -version = "0.9.0" +version = "0.10.0" # Also update html_root_url in lib.rs when bumping this license = "MIT OR Apache-2.0" authors = ["RustCrypto Developers"] description = "MD2 hash function" @@ -12,12 +12,10 @@ keywords = ["crypto", "md2", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = { version = "0.9", features = ["block-padding"] } -opaque-debug = "0.3" +digest = "0.10" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/md2/examples/md2sum.rs b/md2/examples/md2sum.rs deleted file mode 100644 index 14a94ff78..000000000 --- a/md2/examples/md2sum.rs +++ /dev/null @@ -1,39 +0,0 @@ -use md2::{Digest, Md2}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = Md2::new(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - println!("{:x}\t{}", &sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process(&mut file, &path); - } - } - } else { - process(&mut io::stdin(), "-"); - } -} diff --git a/md2/src/lib.rs b/md2/src/lib.rs index 07ca1e68c..d41a1178e 100644 --- a/md2/src/lib.rs +++ b/md2/src/lib.rs @@ -25,52 +25,40 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/md2/0.10.0" )] #![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "std")] -extern crate std; - pub use digest::{self, Digest}; -use block_buffer::{block_padding::Pkcs7, BlockBuffer}; -use digest::{consts::U16, generic_array::GenericArray}; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; +use core::fmt; +use digest::{ + block_buffer::Eager, + consts::U16, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + HashMarker, Output, +}; mod consts; -type Block = GenericArray; - +/// Core MD2 hasher state. #[derive(Clone)] -struct Md2State { +pub struct Md2Core { x: [u8; 48], - checksum: Block, -} - -impl Default for Md2State { - fn default() -> Self { - Self { - x: [0; 48], - checksum: Default::default(), - } - } -} - -/// The MD2 hasher -#[derive(Clone, Default)] -pub struct Md2 { - buffer: BlockBuffer, - state: Md2State, + checksum: Block, } -impl Md2State { - fn process_block(&mut self, input: &Block) { +impl Md2Core { + fn compress(&mut self, block: &Block) { // Update state for j in 0..16 { - self.x[16 + j] = input[j]; + self.x[16 + j] = block[j]; self.x[32 + j] = self.x[16 + j] ^ self.x[j]; } @@ -86,48 +74,78 @@ impl Md2State { // Update checksum let mut l = self.checksum[15]; for j in 0..16 { - self.checksum[j] ^= consts::S[(input[j] ^ l) as usize]; + self.checksum[j] ^= consts::S[(block[j] ^ l) as usize]; l = self.checksum[j]; } } } -impl BlockInput for Md2 { +impl HashMarker for Md2Core {} + +impl BlockSizeUser for Md2Core { type BlockSize = U16; } -impl Update for Md2 { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - let s = &mut self.state; - self.buffer.input_block(input, |d| s.process_block(d)); - } +impl BufferKindUser for Md2Core { + type BufferKind = Eager; } -impl FixedOutputDirty for Md2 { +impl OutputSizeUser for Md2Core { type OutputSize = U16; +} - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - let buf = self - .buffer - .pad_with::() - .expect("we never use input_lazy"); - - self.state.process_block(buf); +impl UpdateCore for Md2Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + self.compress(block) + } + } +} - let checksum = self.state.checksum; - self.state.process_block(&checksum); +impl FixedOutputCore for Md2Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let pos = buffer.get_pos(); + let rem = buffer.remaining() as u8; + let block = buffer.pad_with_zeros(); + block[pos..].iter_mut().for_each(|b| *b = rem); + + self.compress(block); + let checksum = self.checksum; + self.compress(&checksum); + out.copy_from_slice(&self.x[0..16]); + } +} - out.copy_from_slice(&self.state.x[0..16]); +impl Default for Md2Core { + #[inline] + fn default() -> Self { + Self { + x: [0; 48], + checksum: Default::default(), + } } } -impl Reset for Md2 { +impl Reset for Md2Core { + #[inline] fn reset(&mut self) { - self.state = Default::default(); - self.buffer.reset(); + *self = Default::default(); + } +} + +impl AlgorithmName for Md2Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Md2") + } +} + +impl fmt::Debug for Md2Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Md2Core { ... }") } } -opaque_debug::implement!(Md2); -digest::impl_write!(Md2); +/// MD2 hasher state. +pub type Md2 = CoreWrapper; diff --git a/md2/tests/data/md2.blb b/md2/tests/data/md2.blb index 4b03cb78d28042aad2291e70ccd7e919a1869c6f..986c38e60151529f71a05890121ec76aae74f031 100644 GIT binary patch delta 71 zcmbQt*vrVo5H^uRTS$TVMig(-Tpbs^8KtU*^N$n)MK#ot^V1cwJ9#EeO6$43{}#iN b*PrEC85EiWo-TgmBWn9eJ!XDGrg|{|Tjm6P(p()Ey&0vdhVzdU0wuJS1+qJNCQVA~ hxxN1u!;;sZ(reader: &mut R, name: &str) { - let mut sh: D = Default::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/md4/src/lib.rs b/md4/src/lib.rs index f2360fbf8..afbf0c31a 100644 --- a/md4/src/lib.rs +++ b/md4/src/lib.rs @@ -25,166 +25,175 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/md4/0.10.0" )] #![deny(unsafe_code)] #![warn(rust_2018_idioms)] #![allow(clippy::many_single_char_names)] -#[cfg(feature = "std")] -extern crate std; - -use core::convert::TryInto; pub use digest::{self, Digest}; -use block_buffer::BlockBuffer; +use core::{convert::TryInto, fmt}; use digest::{ - consts::{U16, U64}, - generic_array::GenericArray, + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::typenum::{Unsigned, U16, U64}, + HashMarker, Output, }; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; -// initial values for Md4State -const S: [u32; 4] = [0x6745_2301, 0xEFCD_AB89, 0x98BA_DCFE, 0x1032_5476]; +#[derive(Clone)] +pub struct Md4Core { + block_len: u64, + state: [u32; 4], +} -type Block = GenericArray; +impl HashMarker for Md4Core {} -#[derive(Copy, Clone)] -struct Md4State { - s: [u32; 4], +impl BlockSizeUser for Md4Core { + type BlockSize = U64; } -/// The MD4 hasher -#[derive(Clone, Default)] -pub struct Md4 { - length_bytes: u64, - buffer: BlockBuffer, - state: Md4State, +impl BufferKindUser for Md4Core { + type BufferKind = Eager; } -impl Md4State { - fn process_block(&mut self, input: &Block) { - fn f(x: u32, y: u32, z: u32) -> u32 { - (x & y) | (!x & z) - } +impl OutputSizeUser for Md4Core { + type OutputSize = U16; +} - fn g(x: u32, y: u32, z: u32) -> u32 { - (x & y) | (x & z) | (y & z) +impl UpdateCore for Md4Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.block_len = self.block_len.wrapping_add(blocks.len() as u64); + for block in blocks { + compress(&mut self.state, block); } + } +} - fn h(x: u32, y: u32, z: u32) -> u32 { - x ^ y ^ z +impl FixedOutputCore for Md4Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bit_len = self + .block_len + .wrapping_mul(Self::BlockSize::U64) + .wrapping_add(buffer.get_pos() as u64) + .wrapping_mul(8); + let mut state = self.state; + buffer.len64_padding_le(bit_len, |block| compress(&mut state, block)); + + for (chunk, v) in out.chunks_exact_mut(4).zip(state.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); } + } +} - fn op1(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 { - a.wrapping_add(f(b, c, d)).wrapping_add(k).rotate_left(s) +impl Default for Md4Core { + #[inline] + fn default() -> Self { + let state = [0x6745_2301, 0xEFCD_AB89, 0x98BA_DCFE, 0x1032_5476]; + Self { + state, + block_len: 0, } + } +} - fn op2(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 { - a.wrapping_add(g(b, c, d)) - .wrapping_add(k) - .wrapping_add(0x5A82_7999) - .rotate_left(s) - } +impl Reset for Md4Core { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } +} - fn op3(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 { - a.wrapping_add(h(b, c, d)) - .wrapping_add(k) - .wrapping_add(0x6ED9_EBA1) - .rotate_left(s) - } +impl AlgorithmName for Md4Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Md4") + } +} - let mut a = self.s[0]; - let mut b = self.s[1]; - let mut c = self.s[2]; - let mut d = self.s[3]; +impl fmt::Debug for Md4Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Md4Core { ... }") + } +} - // load block to data - let mut data = [0u32; 16]; - for (o, chunk) in data.iter_mut().zip(input.chunks_exact(4)) { - *o = u32::from_le_bytes(chunk.try_into().unwrap()); - } +/// MD4 hasher state. +pub type Md4 = CoreWrapper; - // round 1 - for &i in &[0, 4, 8, 12] { - a = op1(a, b, c, d, data[i], 3); - d = op1(d, a, b, c, data[i + 1], 7); - c = op1(c, d, a, b, data[i + 2], 11); - b = op1(b, c, d, a, data[i + 3], 19); - } +fn compress(state: &mut [u32; 4], input: &Block) { + fn f(x: u32, y: u32, z: u32) -> u32 { + (x & y) | (!x & z) + } - // round 2 - for i in 0..4 { - a = op2(a, b, c, d, data[i], 3); - d = op2(d, a, b, c, data[i + 4], 5); - c = op2(c, d, a, b, data[i + 8], 9); - b = op2(b, c, d, a, data[i + 12], 13); - } + fn g(x: u32, y: u32, z: u32) -> u32 { + (x & y) | (x & z) | (y & z) + } - // round 3 - for &i in &[0, 2, 1, 3] { - a = op3(a, b, c, d, data[i], 3); - d = op3(d, a, b, c, data[i + 8], 9); - c = op3(c, d, a, b, data[i + 4], 11); - b = op3(b, c, d, a, data[i + 12], 15); - } + fn h(x: u32, y: u32, z: u32) -> u32 { + x ^ y ^ z + } - self.s[0] = self.s[0].wrapping_add(a); - self.s[1] = self.s[1].wrapping_add(b); - self.s[2] = self.s[2].wrapping_add(c); - self.s[3] = self.s[3].wrapping_add(d); + fn op1(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 { + a.wrapping_add(f(b, c, d)).wrapping_add(k).rotate_left(s) } -} -impl Default for Md4State { - fn default() -> Self { - Md4State { s: S } + fn op2(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 { + a.wrapping_add(g(b, c, d)) + .wrapping_add(k) + .wrapping_add(0x5A82_7999) + .rotate_left(s) } -} -impl Md4 { - fn finalize_inner(&mut self) { - let state = &mut self.state; - let l = (self.length_bytes << 3) as u64; - self.buffer.len64_padding_le(l, |d| state.process_block(d)) + fn op3(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 { + a.wrapping_add(h(b, c, d)) + .wrapping_add(k) + .wrapping_add(0x6ED9_EBA1) + .rotate_left(s) } -} -impl BlockInput for Md4 { - type BlockSize = U64; -} + let mut a = state[0]; + let mut b = state[1]; + let mut c = state[2]; + let mut d = state[3]; -impl Update for Md4 { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - // Unlike Sha1 and Sha2, the length value in MD4 is defined as - // the length of the message mod 2^64 - ie: integer overflow is OK. - self.length_bytes = self.length_bytes.wrapping_add(input.len() as u64); - let s = &mut self.state; - self.buffer.input_block(input, |d| s.process_block(d)); + // load block to data + let mut data = [0u32; 16]; + for (o, chunk) in data.iter_mut().zip(input.chunks_exact(4)) { + *o = u32::from_le_bytes(chunk.try_into().unwrap()); } -} - -impl FixedOutputDirty for Md4 { - type OutputSize = U16; - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.finalize_inner(); + // round 1 + for &i in &[0, 4, 8, 12] { + a = op1(a, b, c, d, data[i], 3); + d = op1(d, a, b, c, data[i + 1], 7); + c = op1(c, d, a, b, data[i + 2], 11); + b = op1(b, c, d, a, data[i + 3], 19); + } - for (chunk, v) in out.chunks_exact_mut(4).zip(self.state.s.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } + // round 2 + for i in 0..4 { + a = op2(a, b, c, d, data[i], 3); + d = op2(d, a, b, c, data[i + 4], 5); + c = op2(c, d, a, b, data[i + 8], 9); + b = op2(b, c, d, a, data[i + 12], 13); } -} -impl Reset for Md4 { - fn reset(&mut self) { - self.state = Default::default(); - self.length_bytes = 0; - self.buffer.reset(); + // round 3 + for &i in &[0, 2, 1, 3] { + a = op3(a, b, c, d, data[i], 3); + d = op3(d, a, b, c, data[i + 8], 9); + c = op3(c, d, a, b, data[i + 4], 11); + b = op3(b, c, d, a, data[i + 12], 15); } -} -opaque_debug::implement!(Md4); -digest::impl_write!(Md4); + state[0] = state[0].wrapping_add(a); + state[1] = state[1].wrapping_add(b); + state[2] = state[2].wrapping_add(c); + state[3] = state[3].wrapping_add(d); +} diff --git a/md4/tests/data/md4.blb b/md4/tests/data/md4.blb index e590934ec0e73541b547a9dc8c4dbc193b17a529..63ad206a56d338f40ad2bc971bd7bf9d163d88f7 100644 GIT binary patch delta 244 zcmdnVyoI@*fkDCW+W7|;vtAl*w~4&|;6UdArbLCkPjxoSKDKjHiDUhJ``T|6w#1}l zg(V)0RqGXR1jQfZdQr8kXs%3dYH@L5da6Q7W_oIIiNZ}`uEvy*`7b2eJ=h)|XY@7! zYD!5>OV7y6%FfBn%P%M_DlRE4E3c@mQn)@(#-MBI?z5clR=iEV@2I=7W@4Y6umX#H zYttvk+om$l)E@>v|L~+iVX^?D92AQPDLl6Jy)(z+ljIz`YBB#atY%@89T>HR6r|r} rF3DaYC=ny+p0s-1x(Og*4Uy#hbcG#x!aUEJdY8^i*9}|CD109P$2Vn_ delta 234 zcmdnOypuU8DJMTEsnU=^!0_7n2N$zm8g93Vy#C-o=K;nkK^ALM#bwXA3^Uv6q~abkL^LP}(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/md5/src/utils.rs b/md5/src/compress.rs similarity index 79% rename from md5/src/utils.rs rename to md5/src/compress.rs index 9cd0259bc..46857038e 100644 --- a/md5/src/utils.rs +++ b/md5/src/compress.rs @@ -1,7 +1,21 @@ -#![allow(clippy::many_single_char_names)] -use crate::consts::RC; +#![allow(clippy::many_single_char_names, clippy::unreadable_literal)] use core::convert::TryInto; +const RC: [u32; 64] = [ + // round 1 + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + // round 2 + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + // round 3 + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + // round 4 + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, +]; + #[inline(always)] fn op_f(w: u32, x: u32, y: u32, z: u32, m: u32, c: u32, s: u32) -> u32 { ((x & y) | (!x & z)) @@ -42,7 +56,7 @@ fn op_i(w: u32, x: u32, y: u32, z: u32, m: u32, c: u32, s: u32) -> u32 { } #[inline] -pub fn compress(state: &mut [u32; 4], input: &[u8; 64]) { +pub fn compress_block(state: &mut [u32; 4], input: &[u8; 64]) { let mut a = state[0]; let mut b = state[1]; let mut c = state[2]; @@ -142,3 +156,10 @@ pub fn compress(state: &mut [u32; 4], input: &[u8; 64]) { state[2] = state[2].wrapping_add(c); state[3] = state[3].wrapping_add(d); } + +#[inline] +pub fn compress(state: &mut [u32; 4], blocks: &[[u8; 64]]) { + for block in blocks { + compress_block(state, block) + } +} diff --git a/md5/src/consts.rs b/md5/src/consts.rs deleted file mode 100644 index e9b94edb7..000000000 --- a/md5/src/consts.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![allow(clippy::unreadable_literal)] - -/// Round constants -#[cfg(not(feature = "asm"))] -pub static RC: [u32; 64] = [ - // round 1 - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - // round 2 - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - // round 3 - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - // round 4 - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, -]; - -/// Init state -pub const S0: [u32; 4] = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]; diff --git a/md5/src/lib.rs b/md5/src/lib.rs index 2bb9913d5..fadaf5192 100644 --- a/md5/src/lib.rs +++ b/md5/src/lib.rs @@ -25,102 +25,115 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/md-5/0.10.0" )] -#![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "asm")] -extern crate md5_asm as utils; - -#[cfg(feature = "std")] -extern crate std; +extern crate md5_asm as compress; #[cfg(not(feature = "asm"))] -mod utils; +mod compress; pub use digest::{self, Digest}; -use crate::utils::compress; +use compress::compress; + +use core::{fmt, slice::from_ref}; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::typenum::{Unsigned, U16, U64}, + HashMarker, Output, +}; +/// Core MD5 hasher state. +#[derive(Clone)] +pub struct Md5Core { + block_len: u64, + state: [u32; 4], +} -use block_buffer::BlockBuffer; -use digest::generic_array::typenum::{U16, U64}; -use digest::generic_array::GenericArray; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; +impl HashMarker for Md5Core {} -mod consts; +impl BlockSizeUser for Md5Core { + type BlockSize = U64; +} -/// The MD5 hasher -#[derive(Clone)] -pub struct Md5 { - length_bytes: u64, - buffer: BlockBuffer, - state: [u32; 4], +impl BufferKindUser for Md5Core { + type BufferKind = Eager; } -impl Default for Md5 { - fn default() -> Self { - Md5 { - length_bytes: 0, - buffer: Default::default(), - state: consts::S0, - } - } +impl OutputSizeUser for Md5Core { + type OutputSize = U16; } -#[inline(always)] -fn convert(d: &GenericArray) -> &[u8; 64] { - #[allow(unsafe_code)] - unsafe { - &*(d.as_ptr() as *const [u8; 64]) +impl UpdateCore for Md5Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.block_len = self.block_len.wrapping_add(blocks.len() as u64); + compress(&mut self.state, convert(blocks)) } } -impl Md5 { +impl FixedOutputCore for Md5Core { #[inline] - fn finalize_inner(&mut self) { - let s = &mut self.state; - let l = (self.length_bytes << 3) as u64; - self.buffer.len64_padding_le(l, |d| compress(s, convert(d))); + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bit_len = self + .block_len + .wrapping_mul(Self::BlockSize::U64) + .wrapping_add(buffer.get_pos() as u64) + .wrapping_mul(8); + let mut s = self.state; + buffer.len64_padding_le(bit_len, |b| compress(&mut s, convert(from_ref(b)))); + for (chunk, v) in out.chunks_exact_mut(4).zip(s.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); + } } } -impl BlockInput for Md5 { - type BlockSize = U64; +impl Default for Md5Core { + #[inline] + fn default() -> Self { + Self { + block_len: 0, + state: [0x6745_2301, 0xEFCD_AB89, 0x98BA_DCFE, 0x1032_5476], + } + } } -impl Update for Md5 { +impl Reset for Md5Core { #[inline] - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - // Unlike Sha1 and Sha2, the length value in MD5 is defined as - // the length of the message mod 2^64 - ie: integer overflow is OK. - self.length_bytes = self.length_bytes.wrapping_add(input.len() as u64); - let s = &mut self.state; - self.buffer.input_block(input, |d| compress(s, convert(d))); + fn reset(&mut self) { + *self = Default::default(); } } -impl FixedOutputDirty for Md5 { - type OutputSize = U16; - - #[inline] - fn finalize_into_dirty(&mut self, out: &mut GenericArray) { - self.finalize_inner(); - for (chunk, v) in out.chunks_exact_mut(4).zip(self.state.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } +impl AlgorithmName for Md5Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Md5") } } -impl Reset for Md5 { - fn reset(&mut self) { - self.state = consts::S0; - self.length_bytes = 0; - self.buffer.reset(); +impl fmt::Debug for Md5Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Md5Core { ... }") } } -opaque_debug::implement!(Md5); -digest::impl_write!(Md5); +/// MD5 hasher state. +pub type Md5 = CoreWrapper; + +const BLOCK_SIZE: usize = ::BlockSize::USIZE; + +#[inline(always)] +fn convert(blocks: &[Block]) -> &[[u8; BLOCK_SIZE]] { + // SAFETY: GenericArray and [u8; 64] have + // exactly the same memory layout + let p = blocks.as_ptr() as *const [u8; BLOCK_SIZE]; + unsafe { core::slice::from_raw_parts(p, blocks.len()) } +} diff --git a/md5/tests/data/md5.blb b/md5/tests/data/md5.blb index 37f86c4c4f938aea19a337e5f540ecd21f173f4a..3f6d643839fe7be82b7bbe1a2c74a08e7b748468 100644 GIT binary patch delta 140 zcmV;70CWG=8OIqE001D=9gNwJ0I~$>fC-rF_(FbGksT`%Af6C?oi{7Cf@|0vHA18r z)>x4pD-Z1QQ^czp=i+T@j9A?QFE>Rd$uc}-F_DJMTEsnUpnL4e_kY|qVphD|Il8#rgY`QcQj%`h=gTSS0io0L7o&Rkm+^BpIga*`T#)zea=_P+}Vgi;w`r%dnT4U9*J)n-=~Q?}}wD F1OQgBJkS6D diff --git a/ripemd/CHANGELOG.md b/ripemd/CHANGELOG.md new file mode 100644 index 000000000..56fbc112c --- /dev/null +++ b/ripemd/CHANGELOG.md @@ -0,0 +1,12 @@ +# 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 (2021-01-25) +- Initial release of merged `ripemd160` and `ripemd320` crates updated +to `digest` v0.10. ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 diff --git a/ripemd320/Cargo.toml b/ripemd/Cargo.toml similarity index 56% rename from ripemd320/Cargo.toml rename to ripemd/Cargo.toml index 6083fe0ef..9487f7fb9 100644 --- a/ripemd320/Cargo.toml +++ b/ripemd/Cargo.toml @@ -1,23 +1,21 @@ [package] -name = "ripemd320" -version = "0.9.0" -description = "RIPEMD-320 hash function" +name = "ripemd" +version = "0.1.0" # Also update html_root_url in lib.rs when bumping this +description = "Pure Rust implementation of the RIPEMD hash functions" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2018" -documentation = "https://docs.rs/ripemd320" +documentation = "https://docs.rs/ripemd" repository = "https://github.com/RustCrypto/hashes" -keywords = ["crypto", "ripemd320", "hash", "digest"] +keywords = ["crypto", "ripemd", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = "0.9" -opaque-debug = "0.3" +digest = "0.10" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/ripemd256/LICENSE-APACHE b/ripemd/LICENSE-APACHE similarity index 100% rename from ripemd256/LICENSE-APACHE rename to ripemd/LICENSE-APACHE diff --git a/ripemd256/LICENSE-MIT b/ripemd/LICENSE-MIT similarity index 88% rename from ripemd256/LICENSE-MIT rename to ripemd/LICENSE-MIT index a239acf63..efb0b5f8b 100644 --- a/ripemd256/LICENSE-MIT +++ b/ripemd/LICENSE-MIT @@ -1,6 +1,4 @@ -Copyright (c) 2006-2009 Graydon Hoare -Copyright (c) 2009-2013 Mozilla Foundation -Copyright (c) 2016 The RustCrypto Project Developers +Copyright (c) 2021 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/ripemd160/README.md b/ripemd/README.md similarity index 93% rename from ripemd160/README.md rename to ripemd/README.md index 29a18e4a0..64f72e493 100644 --- a/ripemd160/README.md +++ b/ripemd/README.md @@ -1,4 +1,4 @@ -# RustCrypto: RIPEMD160 +# RustCrypto: RIPEMD [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] @@ -7,7 +7,7 @@ [![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] -Pure Rust implementation of the [RIPEMD160 hash function][1]. +Pure Rust implementation of the [RIPEMD] hash functions. [Documentation][docs-link] @@ -53,4 +53,4 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) -[1]: https://en.wikipedia.org/wiki/RIPEMD +[RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD diff --git a/ripemd/benches/ripemd160.rs b/ripemd/benches/ripemd160.rs new file mode 100644 index 000000000..618c30e8e --- /dev/null +++ b/ripemd/benches/ripemd160.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(ripemd::Ripemd160); diff --git a/ripemd/benches/ripemd320.rs b/ripemd/benches/ripemd320.rs new file mode 100644 index 000000000..8a399a7ee --- /dev/null +++ b/ripemd/benches/ripemd320.rs @@ -0,0 +1,4 @@ +#![no_std] +#![feature(test)] + +digest::bench!(ripemd::Ripemd320); diff --git a/ripemd160/src/block.rs b/ripemd/src/c160.rs similarity index 98% rename from ripemd160/src/block.rs rename to ripemd/src/c160.rs index fccf1ab60..2163e848f 100644 --- a/ripemd160/src/block.rs +++ b/ripemd/src/c160.rs @@ -1,6 +1,5 @@ +use super::{Block, Ripemd160Core}; use core::convert::TryInto; -use digest::generic_array::typenum::U64; -use digest::generic_array::GenericArray; pub const DIGEST_BUF_LEN: usize = 5; pub const WORK_BUF_LEN: usize = 16; @@ -13,8 +12,6 @@ pub const H0: [u32; DIGEST_BUF_LEN] = [ 0xc3d2_e1f0, ]; -type Block = GenericArray; - macro_rules! round( ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $x:expr, $bits:expr, $add:expr, $round:expr) => ({ @@ -115,7 +112,7 @@ macro_rules! process_block( }); ); -pub fn process_msg_block(h: &mut [u32; DIGEST_BUF_LEN], data: &Block) { +pub fn compress(h: &mut [u32; DIGEST_BUF_LEN], data: &Block) { let mut w = [0u32; WORK_BUF_LEN]; for (o, chunk) in w.iter_mut().zip(data.chunks_exact(4)) { *o = u32::from_le_bytes(chunk.try_into().unwrap()); diff --git a/ripemd256/src/block.rs b/ripemd/src/c256.rs similarity index 98% rename from ripemd256/src/block.rs rename to ripemd/src/c256.rs index de085350c..a7d6e51a9 100644 --- a/ripemd256/src/block.rs +++ b/ripemd/src/c256.rs @@ -1,6 +1,5 @@ +use super::{Block, Ripemd256Core}; use core::{convert::TryInto, mem::swap}; -use digest::generic_array::typenum::U64; -use digest::generic_array::GenericArray; pub const DIGEST_BUF_LEN: usize = 8; pub const HALF_DIGEST_BUF_LEN: usize = DIGEST_BUF_LEN / 2; @@ -17,8 +16,6 @@ pub const H0: [u32; DIGEST_BUF_LEN] = [ 0x0123_4567, ]; -type Block = GenericArray; - macro_rules! round( ($a:expr, $b:expr, $c:expr, $d:expr, $x:expr, $bits:expr, $add:expr, $round:expr) => ({ @@ -122,7 +119,7 @@ macro_rules! process_block( }); ); -pub fn process_msg_block(h: &mut [u32; DIGEST_BUF_LEN], data: &Block) { +pub fn compress(h: &mut [u32; DIGEST_BUF_LEN], data: &Block) { let mut w = [0u32; WORK_BUF_LEN]; for (o, chunk) in w.iter_mut().zip(data.chunks_exact(4)) { *o = u32::from_le_bytes(chunk.try_into().unwrap()); diff --git a/ripemd320/src/block.rs b/ripemd/src/c320.rs similarity index 98% rename from ripemd320/src/block.rs rename to ripemd/src/c320.rs index 4834ead90..89b174066 100644 --- a/ripemd320/src/block.rs +++ b/ripemd/src/c320.rs @@ -1,6 +1,5 @@ +use super::{Block, Ripemd320Core}; use core::{convert::TryInto, mem::swap}; -use digest::generic_array::typenum::U64; -use digest::generic_array::GenericArray; pub const HALF_DIGEST_BUF_LEN: usize = 5; pub const DIGEST_BUF_LEN: usize = 10; @@ -19,8 +18,6 @@ pub const H0: [u32; DIGEST_BUF_LEN] = [ 0x3c2d_1e0f, ]; -type Block = GenericArray; - macro_rules! round( ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $x:expr, $bits:expr, $add:expr, $round:expr) => ({ @@ -145,7 +142,7 @@ macro_rules! process_block( }); ); -pub fn process_msg_block(h: &mut [u32; DIGEST_BUF_LEN], data: &Block) { +pub fn compress(h: &mut [u32; DIGEST_BUF_LEN], data: &Block) { let mut w = [0u32; WORK_BUF_LEN]; for (o, chunk) in w.iter_mut().zip(data.chunks_exact(4)) { *o = u32::from_le_bytes(chunk.try_into().unwrap()); diff --git a/ripemd/src/lib.rs b/ripemd/src/lib.rs new file mode 100644 index 000000000..c428d4f12 --- /dev/null +++ b/ripemd/src/lib.rs @@ -0,0 +1,299 @@ +//! An implementation of the [RIPEMD] cryptographic hash. +//! +//! This crate implements only the modified 1996 versions, not the original +//! one from 1992. +//! +//! Note that RIPEMD-256 provides only the same security as RIPEMD-128, +//! and RIPEMD-320 provides only the same security as RIPEMD-160. +//! +//! # Usage +//! +//! ```rust +//! use hex_literal::hex; +//! use ripemd::{Ripemd160, Ripemd320, Digest}; +//! +//! // create a RIPEMD-160 hasher instance +//! let mut hasher = Ripemd160::new(); +//! +//! // process input message +//! hasher.update(b"Hello world!"); +//! +//! // acquire hash digest in the form of GenericArray, +//! // which in this case is equivalent to [u8; 20] +//! let result = hasher.finalize(); +//! assert_eq!(result[..], hex!("7f772647d88750add82d8e1a7a3e5c0902a346a3")); +//! +//! // same for RIPEMD-320 +//! let mut hasher = Ripemd320::new(); +//! hasher.update(b"Hello world!"); +//! let result = hasher.finalize(); +//! assert_eq!(&result[..], &hex!(" +//! f1c1c231d301abcf2d7daae0269ff3e7bc68e623 +//! ad723aa068d316b056d26b7d1bb6f0cc0f28336d +//! ")[..]); +//! ``` +//! +//! Also see [RustCrypto/hashes] readme. +//! +//! [RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD +//! [RustCrypto/hashes]: https://github.com/RustCrypto/hashes + +#![no_std] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/ripemd/0.1.0" +)] +#![deny(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms)] + +pub use digest::{self, Digest}; + +use core::fmt; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::typenum::{Unsigned, U20, U32, U40, U64}, + HashMarker, Output, +}; + +mod c160; +mod c256; +mod c320; + +/// Core RIPEMD-160 hasher state. +#[derive(Clone)] +pub struct Ripemd160Core { + h: [u32; c160::DIGEST_BUF_LEN], + block_len: u64, +} + +impl HashMarker for Ripemd160Core {} + +impl BlockSizeUser for Ripemd160Core { + type BlockSize = U64; +} + +impl BufferKindUser for Ripemd160Core { + type BufferKind = Eager; +} + +impl OutputSizeUser for Ripemd160Core { + type OutputSize = U20; +} + +impl UpdateCore for Ripemd160Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + // Assumes that `block_len` does not overflow + self.block_len += blocks.len() as u64; + for block in blocks { + c160::compress(&mut self.h, block); + } + } +} + +impl FixedOutputCore for Ripemd160Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bs = Self::BlockSize::U64; + let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len); + let mut h = self.h; + buffer.len64_padding_le(bit_len, |block| c160::compress(&mut h, block)); + + for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); + } + } +} + +impl Default for Ripemd160Core { + #[inline] + fn default() -> Self { + Self { + h: c160::H0, + block_len: 0, + } + } +} + +impl Reset for Ripemd160Core { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } +} + +impl AlgorithmName for Ripemd160Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Ripemd160") + } +} + +impl fmt::Debug for Ripemd160Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Ripemd160Core { ... }") + } +} + +/// RIPEMD-160 hasher state. +pub type Ripemd160 = CoreWrapper; + +/// Core RIPEMD-256 hasher state. +#[derive(Clone)] +pub struct Ripemd256Core { + h: [u32; c256::DIGEST_BUF_LEN], + block_len: u64, +} + +impl HashMarker for Ripemd256Core {} + +impl BlockSizeUser for Ripemd256Core { + type BlockSize = U64; +} + +impl BufferKindUser for Ripemd256Core { + type BufferKind = Eager; +} + +impl OutputSizeUser for Ripemd256Core { + type OutputSize = U32; +} + +impl UpdateCore for Ripemd256Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + // Assumes that `block_len` does not overflow + self.block_len += blocks.len() as u64; + for block in blocks { + c256::compress(&mut self.h, block); + } + } +} + +impl FixedOutputCore for Ripemd256Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bs = Self::BlockSize::U64; + let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len); + let mut h = self.h; + buffer.len64_padding_le(bit_len, |block| c256::compress(&mut h, block)); + + for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); + } + } +} + +impl Default for Ripemd256Core { + #[inline] + fn default() -> Self { + Self { + h: c256::H0, + block_len: 0, + } + } +} + +impl Reset for Ripemd256Core { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } +} + +impl AlgorithmName for Ripemd256Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Ripemd256") + } +} + +impl fmt::Debug for Ripemd256Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Ripemd256Core { ... }") + } +} + +/// RIPEMD-160 hasher state. +pub type Ripemd256 = CoreWrapper; + +/// Core RIPEMD-320 hasher state. +#[derive(Clone)] +pub struct Ripemd320Core { + h: [u32; c320::DIGEST_BUF_LEN], + block_len: u64, +} + +impl HashMarker for Ripemd320Core {} + +impl BlockSizeUser for Ripemd320Core { + type BlockSize = U64; +} + +impl BufferKindUser for Ripemd320Core { + type BufferKind = Eager; +} + +impl OutputSizeUser for Ripemd320Core { + type OutputSize = U40; +} + +impl UpdateCore for Ripemd320Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + // Assumes that `block_len` does not overflow + self.block_len += blocks.len() as u64; + for block in blocks { + c320::compress(&mut self.h, block); + } + } +} + +impl FixedOutputCore for Ripemd320Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bs = Self::BlockSize::U64; + let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len); + let mut h = self.h; + buffer.len64_padding_le(bit_len, |block| c320::compress(&mut h, block)); + + for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); + } + } +} + +impl Default for Ripemd320Core { + #[inline] + fn default() -> Self { + Self { + h: c320::H0, + block_len: 0, + } + } +} + +impl Reset for Ripemd320Core { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } +} + +impl AlgorithmName for Ripemd320Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Ripemd320") + } +} + +impl fmt::Debug for Ripemd320Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Ripemd320Core { ... }") + } +} + +/// RIPEMD-320 hasher state. +pub type Ripemd320 = CoreWrapper; diff --git a/ripemd/tests/data/ripemd160.blb b/ripemd/tests/data/ripemd160.blb new file mode 100644 index 0000000000000000000000000000000000000000..ee23310ad6ab51220dd3b338c1ab886c6665f808 GIT binary patch literal 234 zcmZQzOH4}E=-b5c{Xy)Es@W`FeKU@2X#W_+{igsZkpe`iK$HeV=|GeLM43R81w`3E zlmkS$K$HhW`9M?vM1>kc3xX}Y=J0epVO@};e&@@qTS>3A!$LAr6$(o;ld~0)it@|z z6w>l56tYTl3yKx;%TkLJN`TTiiB**fDf#Id=AVte^=_}edHwB`X;TZ=rpx@iYfZEP d$v^{y6^ia>avC?s?bx=KyZrgKk6x#)0|4S=WQ+g+ literal 0 HcmV?d00001 diff --git a/ripemd/tests/data/ripemd256.blb b/ripemd/tests/data/ripemd256.blb new file mode 100644 index 0000000000000000000000000000000000000000..733bc577211cb4f5d9af3447a2619017d3f1ed9b GIT binary patch literal 516 zcmZQzaA4Zy;}_p|R-*h*&^2F!$5p!1OMc76G9@>xW6XGbG)R{z(c!1Do$HP8uQ$0S z?%K{Jw~Obu^pg!0HnYy3?Xa3?lBuc6mY9_6uzqizQuo}R-RHiZ(q(>jdm-0>J+-Hw zWbny3U3yvSIy+S+H?_DpF+EiwB{My>xWu9TWnt+onI~0&zA+PhEOjPG96yqM&?Pn0 z>(Bj=rR+R>CO|_|Qq$5iGPAOCa`W;F3X6(MO3TVCDytk)<{Frk$}JKr&;Gfv>rCUG zifMvffzzk8H{F%LS=$?ETmaGw(hf2KWC+L{kWnDhKn8-$1Q`o58Du!fe2^6m7S1f8 z&8v=`IB`>`wfOnUhFQP0_)X3n&Rh9hU+kM%pM8y^le3Gfo4bdnm$#3vpMOALP;f|S zSa?Ka6mIt#7#bOyn3|beSUQ9|Ea6xqwq0R|i^{smGP~s;Cttj<-$DH2iurZR?v*dt w(VzfVi_k?8%Yp6hnJR~=9;klyr8(jlthk#OCTMQ8UFbI+&|@ippP>Y_Y(^19dQP5*V+@9v+sbITlt z0HtfOVTr*xcS;Zb{d(+Pwd2lD#j3B5$+d=y*A_(aooEo1u`*h~F>?n~V!*kIRyK>D zY7tA9wsMwMPRhNNRuwK5rt|09@8|W&A^I~nxU*iH&ig->EioxM;GPfTW>)`BgXMEM z*A@3oGLVZB=ZJp)_u!6;Vuf}kKlE2RUGuqpBtuswH?_DpF+EiwB{My>xFo=;Pa{C@ zO01K9MvMR4%VN)Wwi^Gk*P3`~e#;fr6TR7f|BGtBWz{fFHvw9blA4yDk(rg9lbe@c zP*_x4Qd(ACQCSsmYVXEI?n&-k3X@l5pJSb>qhZqX#r_+Ibs^FT&|Oa&PXG8<$($Oe!lAbUVo1za#$K9%RY5|i|j9lqZ)m)=uI zcoccxXZDsQYCU|DqxX~)tjs)lp=jZn8b>E*7gslT4^J;|A74NJfWV;OkkGL3h{!11 z?l&+rGBz(&expected); +} + +#[test] +fn ripemd256_1million_a() { + one_million_a::(&hex!( + "ac953744e10e31514c150d4d8d7b677342e33399788296e43ae4850ce4f97978" + )); +} + +#[test] +fn ripemd320_1million_a() { + let expected = + hex!("bdee37f4371e20646b8b0d862dda16292ae36f40965e8c8509e63d1dbddecc503e2b63eb9245bb66"); + one_million_a::(&expected); +} diff --git a/ripemd160/CHANGELOG.md b/ripemd160/CHANGELOG.md deleted file mode 100644 index 22305f2b8..000000000 --- a/ripemd160/CHANGELOG.md +++ /dev/null @@ -1,50 +0,0 @@ -# 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.9.1 (2020-06-28) -### Changed -- Update to `block-buffer` v0.9 ([#164]) -- Update to `opaque-debug` v0.3 ([#168]) - -[#164]: https://github.com/RustCrypto/hashes/pull/164 -[#168]: https://github.com/RustCrypto/hashes/pull/168 - -## 0.9.0 (2020-06-10) -### Changed -- Update to `digest` v0.9 release ([#155]) -- Use new `*Dirty` traits from the `digest` crate ([#153]) -- Bump `block-buffer` to v0.8 release ([#151]) -- Rename `*result*` to `finalize` ([#148]) -- Upgrade to Rust 2018 edition ([#129]) - -[#155]: https://github.com/RustCrypto/hashes/pull/155 -[#153]: https://github.com/RustCrypto/hashes/pull/153 -[#151]: https://github.com/RustCrypto/hashes/pull/151 -[#148]: https://github.com/RustCrypto/hashes/pull/148 -[#129]: https://github.com/RustCrypto/hashes/pull/129 - -## 0.8.0 (2018-10-02) - -## 0.7.0 (2017-11-15) - -## 0.6.0 (2017-06-12) - -## 0.5.2 (2017-06-04) - -## 0.5.1 (2017-05-02) - -## 0.5.0 (2017-04-06) - -## 0.4.1 (2017-01-20) - -## 0.4.0 (2016-12-25) - -## 0.3.0 (2016-11-17) - -## 0.2.0 (2016-10-14) - -## 0.1.0 (2016-10-06) diff --git a/ripemd160/Cargo.toml b/ripemd160/Cargo.toml deleted file mode 100644 index 9f1861621..000000000 --- a/ripemd160/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "ripemd160" -version = "0.9.1" -description = "RIPEMD-160 hash function" -authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" -edition = "2018" -documentation = "https://docs.rs/ripemd160" -repository = "https://github.com/RustCrypto/hashes" -keywords = ["crypto", "ripemd160", "hash", "digest"] -categories = ["cryptography", "no-std"] - -[dependencies] -digest = "0.9" -block-buffer = "0.9" -opaque-debug = "0.3" - -[dev-dependencies] -digest = { version = "0.9", features = ["dev"] } -hex-literal = "0.2" - -[features] -default = ["std"] -std = ["digest/std"] diff --git a/ripemd160/benches/lib.rs b/ripemd160/benches/lib.rs deleted file mode 100644 index c665c0793..000000000 --- a/ripemd160/benches/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![no_std] -#![feature(test)] - -digest::bench!(ripemd160::Ripemd160); diff --git a/ripemd160/examples/ripemd160sum.rs b/ripemd160/examples/ripemd160sum.rs deleted file mode 100644 index 4f71a12af..000000000 --- a/ripemd160/examples/ripemd160sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use ripemd160::{Digest, Ripemd160}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/ripemd160/src/lib.rs b/ripemd160/src/lib.rs deleted file mode 100644 index 544d4ae2e..000000000 --- a/ripemd160/src/lib.rs +++ /dev/null @@ -1,101 +0,0 @@ -//! An implementation of the [RIPEMD-160][1] cryptographic hash. -//! -//! # Usage -//! -//! ```rust -//! use hex_literal::hex; -//! use ripemd160::{Ripemd160, Digest}; -//! -//! // create a RIPEMD-160 hasher instance -//! let mut hasher = Ripemd160::new(); -//! -//! // process input message -//! hasher.update(b"Hello world!"); -//! -//! // acquire hash digest in the form of GenericArray, -//! // which in this case is equivalent to [u8; 20] -//! let result = hasher.finalize(); -//! assert_eq!(result[..], hex!("7f772647d88750add82d8e1a7a3e5c0902a346a3")); -//! ``` -//! -//! Also see [RustCrypto/hashes][2] readme. -//! -//! [1]: https://en.wikipedia.org/wiki/RIPEMD -//! [2]: https://github.com/RustCrypto/hashes - -#![no_std] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" -)] -#![deny(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] - -#[cfg(feature = "std")] -extern crate std; - -mod block; - -pub use digest::{self, Digest}; - -use crate::block::{process_msg_block, DIGEST_BUF_LEN, H0}; -use block_buffer::BlockBuffer; -use digest::consts::{U20, U64}; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; - -/// Structure representing the state of a Ripemd160 computation -#[derive(Clone)] -pub struct Ripemd160 { - h: [u32; DIGEST_BUF_LEN], - len: u64, - buffer: BlockBuffer, -} - -impl Default for Ripemd160 { - fn default() -> Self { - Ripemd160 { - h: H0, - len: 0, - buffer: Default::default(), - } - } -} - -impl BlockInput for Ripemd160 { - type BlockSize = U64; -} - -impl Update for Ripemd160 { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - // Assumes that input.len() can be converted to u64 without overflow - self.len += input.len() as u64; - let h = &mut self.h; - self.buffer.input_block(input, |b| process_msg_block(h, b)); - } -} - -impl FixedOutputDirty for Ripemd160 { - type OutputSize = U20; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - let h = &mut self.h; - let l = self.len << 3; - self.buffer.len64_padding_le(l, |b| process_msg_block(h, b)); - - for (chunk, v) in out.chunks_exact_mut(4).zip(self.h.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - } -} - -impl Reset for Ripemd160 { - fn reset(&mut self) { - self.buffer.reset(); - self.len = 0; - self.h = H0; - } -} - -opaque_debug::implement!(Ripemd160); -digest::impl_write!(Ripemd160); diff --git a/ripemd160/tests/data/one_million_a.bin b/ripemd160/tests/data/one_million_a.bin deleted file mode 100644 index df1956351..000000000 --- a/ripemd160/tests/data/one_million_a.bin +++ /dev/null @@ -1 +0,0 @@ -Rx2Ci{m7h%( \ No newline at end of file diff --git a/ripemd160/tests/data/ripemd160.blb b/ripemd160/tests/data/ripemd160.blb deleted file mode 100644 index c3ce45f16..000000000 --- a/ripemd160/tests/data/ripemd160.blb +++ /dev/null @@ -1 +0,0 @@ -blobby1abc]zJưZ 8abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqS8J l'b++The quick brown fox jumps over the lazy dog72{Ԗqg;+The quick brown fox jumps over the lazy cog ri 3^ wJ \ No newline at end of file diff --git a/ripemd160/tests/lib.rs b/ripemd160/tests/lib.rs deleted file mode 100644 index ccb7bce78..000000000 --- a/ripemd160/tests/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! Test messages from FIPS 180-1 -#![no_std] - -use digest::dev::{digest_test, one_million_a}; -use digest::new_test; - -new_test!( - ripemd160_main, - "ripemd160", - ripemd160::Ripemd160, - digest_test -); - -#[test] -fn ripemd160_1million_a() { - let output = include_bytes!("data/one_million_a.bin"); - one_million_a::(output); -} diff --git a/ripemd256/.gitignore b/ripemd256/.gitignore deleted file mode 100644 index 96ef6c0b9..000000000 --- a/ripemd256/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -Cargo.lock diff --git a/ripemd256/Cargo.toml b/ripemd256/Cargo.toml deleted file mode 100644 index 67fe29899..000000000 --- a/ripemd256/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "ripemd256" -version = "0.1.0" -authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -edition = "2018" -readme = "README.md" -keywords = ["crypto", "ripemd256", "hash", "digest"] -categories = ["cryptography", "no-std"] -description = "RIPEMD-256 hash function" -repository = "https://github.com/RustCrypto/hashes" - - -[dependencies] -block-buffer = "0.9" -digest = "0.9" -opaque-debug = "0.3" - -[dev-dependencies] -digest = { version = "0.9", features = ["dev"] } -hex-literal = "0.2" - -[features] -default = ["std"] -std = ["digest/std"] diff --git a/ripemd256/README.md b/ripemd256/README.md deleted file mode 100644 index b0bab35e7..000000000 --- a/ripemd256/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# RustCrypto: RIPEMD256 -Pure Rust implementation of the [RIPEMD256 hash function][1]. - -## Minimum Supported Rust Version - -Rust **1.41** 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 - -[1]: https://en.wikipedia.org/wiki/RIPEMD diff --git a/ripemd256/examples/ripemd256sum.rs b/ripemd256/examples/ripemd256sum.rs deleted file mode 100644 index 6a6ad1a5c..000000000 --- a/ripemd256/examples/ripemd256sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use ripemd256::{Digest, Ripemd256}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/ripemd256/src/lib.rs b/ripemd256/src/lib.rs deleted file mode 100644 index 70b6344a7..000000000 --- a/ripemd256/src/lib.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! An implementation of the [RIPEMD-256][1] cryptographic hash. -//! -//! # Usage -//! -//! ```rust -//! use hex_literal::hex; -//! use ripemd256::{Ripemd256, Digest}; -//! -//! // create a RIPEMD-256 hasher instance -//! let mut hasher = Ripemd256::new(); -//! -//! // process input message -//! hasher.update(b"Hello world!"); -//! -//! // acquire hash digest in the form of GenericArray, -//! // which in this case is equivalent to [u8; 32] -//! let expected = hex!("2700f1122c7bd5df165b0615efbbbc54f551aef2401738811a5aea19ccb9233a"); -//! let result = hasher.finalize(); -//! assert_eq!(&result[..], &expected[..]); -//! ``` -//! -//! [1]: https://en.wikipedia.org/wiki/RIPEMD - -#![no_std] -#![deny(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] - -#[cfg(feature = "std")] -extern crate std; - -mod block; - -pub use digest::{self, Digest}; - -use block::{process_msg_block, DIGEST_BUF_LEN, H0}; -use block_buffer::BlockBuffer; -use digest::{ - consts::{U32, U64}, - BlockInput, FixedOutputDirty, Reset, Update, -}; - -/// Structure representing the state of a Ripemd256 computation -#[derive(Clone)] -pub struct Ripemd256 { - h: [u32; DIGEST_BUF_LEN], - len: u64, - buffer: BlockBuffer, -} - -impl Default for Ripemd256 { - fn default() -> Self { - Ripemd256 { - h: H0, - len: 0, - buffer: Default::default(), - } - } -} - -impl BlockInput for Ripemd256 { - type BlockSize = U64; -} - -impl Update for Ripemd256 { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - // Assumes that input.len() can be converted to u64 without overflow - self.len += input.len() as u64; - let h = &mut self.h; - self.buffer.input_block(input, |b| process_msg_block(h, b)); - } -} - -impl FixedOutputDirty for Ripemd256 { - type OutputSize = U32; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - let h = &mut self.h; - let l = self.len << 3; - self.buffer.len64_padding_le(l, |b| process_msg_block(h, b)); - for (chunk, v) in out.chunks_exact_mut(4).zip(self.h.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - } -} - -impl Reset for Ripemd256 { - fn reset(&mut self) { - self.buffer.reset(); - self.len = 0; - self.h = H0; - } -} - -opaque_debug::implement!(Ripemd256); -digest::impl_write!(Ripemd256); diff --git a/ripemd256/tests/lib.rs b/ripemd256/tests/lib.rs deleted file mode 100644 index 099ad9968..000000000 --- a/ripemd256/tests/lib.rs +++ /dev/null @@ -1,53 +0,0 @@ -use digest::dev::one_million_a; -use hex_literal::hex; -use ripemd256::{Digest, Ripemd256}; - -fn hash_test(msg: &str, expected: [u8; 32]) { - let mut hasher = Ripemd256::new(); - hasher.update(msg.as_bytes()); - let result = hasher.finalize(); - assert_eq!(result[..], expected); -} - -#[test] -fn ripemd256_messages() { - hash_test( - "", - hex!("02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d"), - ); - hash_test( - "a", - hex!("f9333e45d857f5d90a91bab70a1eba0cfb1be4b0783c9acfcd883a9134692925"), - ); - hash_test( - "abc", - hex!("afbd6e228b9d8cbbcef5ca2d03e6dba10ac0bc7dcbe4680e1e42d2e975459b65"), - ); - hash_test( - "message digest", - hex!("87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e"), - ); - hash_test( - "abcdefghijklmnopqrstuvwxyz", - hex!("649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133"), - ); - hash_test( - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - hex!("3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f"), - ); - hash_test( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - hex!("5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8"), - ); - hash_test( - "12345678901234567890123456789012345678901234567890123456789012345678901234567890", - hex!("06fdcc7a409548aaf91368c06a6275b553e3f099bf0ea4edfd6778df89a890dd"), - ); -} - -#[test] -fn ripemd256_1million_a() { - one_million_a::(&hex!( - "ac953744e10e31514c150d4d8d7b677342e33399788296e43ae4850ce4f97978" - )); -} diff --git a/ripemd320/CHANGELOG.md b/ripemd320/CHANGELOG.md deleted file mode 100644 index 58dfc426a..000000000 --- a/ripemd320/CHANGELOG.md +++ /dev/null @@ -1,25 +0,0 @@ -# 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.9.0 (2020-06-12) -### Changed -- Bump `opaque-debug` to v0.3.0 ([#168]) -- Bump `digest` to v0.9 release; MSRV 1.41 ([#155]) -- Use new `*Dirty` traits from the `digest` crate ([#153]) -- Bump `block-buffer` to v0.8 release ([#151]) -- Rename `*result*` to `finalize` ([#148]) -- Upgrade to Rust 2018 edition ([#130]) - -[#168]: https://github.com/RustCrypto/hashes/pull/168 -[#155]: https://github.com/RustCrypto/hashes/pull/155 -[#153]: https://github.com/RustCrypto/hashes/pull/153 -[#151]: https://github.com/RustCrypto/hashes/pull/151 -[#148]: https://github.com/RustCrypto/hashes/pull/148 -[#130]: https://github.com/RustCrypto/hashes/pull/130 - -## 0.8.0 (2019-02-11) -- Initial release diff --git a/ripemd320/LICENSE-APACHE b/ripemd320/LICENSE-APACHE deleted file mode 100644 index 78173fa2e..000000000 --- a/ripemd320/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - 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/ripemd320/LICENSE-MIT b/ripemd320/LICENSE-MIT deleted file mode 100644 index a239acf63..000000000 --- a/ripemd320/LICENSE-MIT +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2006-2009 Graydon Hoare -Copyright (c) 2009-2013 Mozilla Foundation -Copyright (c) 2016 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/ripemd320/README.md b/ripemd320/README.md deleted file mode 100644 index ba34c4c46..000000000 --- a/ripemd320/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# RustCrypto: RIPEMD320 - -[![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] - -Pure Rust implementation of the [RIPEMD320 hash function][1]. - -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.41** 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/ripemd320.svg -[crate-link]: https://crates.io/crates/ripemd320 -[docs-image]: https://docs.rs/ripemd320/badge.svg -[docs-link]: https://docs.rs/ripemd320/ -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg -[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes -[build-image]: https://github.com/RustCrypto/hashes/workflows/ripemd320/badge.svg?branch=master -[build-link]: https://github.com/RustCrypto/hashes/actions?query=workflow%3Aripemd320 - -[//]: # (general links) - -[1]: https://en.wikipedia.org/wiki/RIPEMD diff --git a/ripemd320/benches/lib.rs b/ripemd320/benches/lib.rs deleted file mode 100644 index c8e49596b..000000000 --- a/ripemd320/benches/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![no_std] -#![feature(test)] - -digest::bench!(ripemd320::Ripemd320); diff --git a/ripemd320/examples/ripemd320sum.rs b/ripemd320/examples/ripemd320sum.rs deleted file mode 100644 index 0b1f49fa3..000000000 --- a/ripemd320/examples/ripemd320sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use ripemd320::{Digest, Ripemd320}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/ripemd320/src/lib.rs b/ripemd320/src/lib.rs deleted file mode 100644 index ba6f32ce0..000000000 --- a/ripemd320/src/lib.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! An implementation of the [RIPEMD-320][1] cryptographic hash. -//! -//! # Usage -//! -//! ```rust -//! use hex_literal::hex; -//! use ripemd320::{Ripemd320, Digest}; -//! -//! // create a RIPEMD-320 hasher instance -//! let mut hasher = Ripemd320::new(); -//! -//! // process input message -//! hasher.update(b"Hello world!"); -//! -//! // acquire hash digest in the form of GenericArray, -//! // which in this case is equivalent to [u8; 40] -//! let expected = hex!("f1c1c231d301abcf2d7daae0269ff3e7bc68e623ad723aa068d316b056d26b7d1bb6f0cc0f28336d"); -//! let result = hasher.finalize(); -//! assert_eq!(&result[..], &expected[..]); -//! ``` -//! -//! Also see [RustCrypto/hashes][2] readme. -//! -//! [1]: https://en.wikipedia.org/wiki/RIPEMD -//! [2]: https://github.com/RustCrypto/hashes - -#![no_std] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" -)] -#![deny(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] - -#[cfg(feature = "std")] -extern crate std; - -mod block; - -pub use digest::{self, Digest}; - -use crate::block::{process_msg_block, DIGEST_BUF_LEN, H0}; - -use block_buffer::BlockBuffer; -use digest::consts::{U40, U64}; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; - -/// Structure representing the state of a ripemd320 computation -#[derive(Clone)] -pub struct Ripemd320 { - h: [u32; DIGEST_BUF_LEN], - len: u64, - buffer: BlockBuffer, -} - -impl Default for Ripemd320 { - fn default() -> Self { - Ripemd320 { - h: H0, - len: 0, - buffer: Default::default(), - } - } -} - -impl BlockInput for Ripemd320 { - type BlockSize = U64; -} - -impl Update for Ripemd320 { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - // Assumes that input.len() can be converted to u64 without overflow - self.len += input.len() as u64; - let h = &mut self.h; - self.buffer.input_block(input, |b| process_msg_block(h, b)); - } -} - -impl FixedOutputDirty for Ripemd320 { - type OutputSize = U40; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - let h = &mut self.h; - let l = self.len << 3; - self.buffer.len64_padding_le(l, |b| process_msg_block(h, b)); - for (chunk, v) in out.chunks_exact_mut(4).zip(self.h.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - } -} - -impl Reset for Ripemd320 { - fn reset(&mut self) { - self.buffer.reset(); - self.len = 0; - self.h = H0; - } -} - -opaque_debug::implement!(Ripemd320); -digest::impl_write!(Ripemd320); diff --git a/ripemd320/tests/data/one_million_a.bin b/ripemd320/tests/data/one_million_a.bin deleted file mode 100644 index ebf119470..000000000 --- a/ripemd320/tests/data/one_million_a.bin +++ /dev/null @@ -1 +0,0 @@ -77 dk -)*o@^ =P>+cEf \ No newline at end of file diff --git a/ripemd320/tests/data/ripemd320.blb b/ripemd320/tests/data/ripemd320.blb deleted file mode 100644 index 2b5f1d993021b892f982f39b4ade7519996dbc56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 508 zcmYew$xlkEG-OW8&)1ON^iI+ts^O7v-I7IT_Z4%`s1fls>RjrgJbCiE*Xd3Fb=dFj zpSN?%90m=gYq4R8!8vzI5B~jn>|V9w&QHavuaC*KhKtu0MDd+y5S6hqTEH=L2VUgsK<`SdlYT~v|J=)B&v&*O|FYMbcxisi71a~H*?#|vYQJUGFiw{OT9T5QmY$KB zm7SBDmtRm=R9sS8R$ftArEzNS#zyW*?pz9!S7o1LovNc@((}ds8;9fcz_i^CZ2{Kvrp7Fj+p8=erV<^pYLE z-!qrqQ%HCedEaODmL+OEe3PU1loYJYJb9sL;Tk(fCubK|H+K(DFK-`TKmUNhpx}_u zu<(e;DBSKhFf=kYF*P%{u+(@P;^}ZAH~mw|Ao{pS7Sx*Uw3O N(leF0TWs2v002Z$-P-^F diff --git a/ripemd320/tests/lib.rs b/ripemd320/tests/lib.rs deleted file mode 100644 index 727131595..000000000 --- a/ripemd320/tests/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! Test messages from FIPS 180-1 and from the RIPEMD-160 webpage[1] -//! [1] https://homes.esat.kuleuven.be/~bosselae/ripemd160.html -#![no_std] - -use digest::dev::{digest_test, one_million_a}; -use digest::new_test; - -new_test!( - ripemd320_main, - "ripemd320", - ripemd320::Ripemd320, - digest_test -); - -#[test] -fn ripemd320_1million_a() { - let output = include_bytes!("data/one_million_a.bin"); - one_million_a::(&output[..]); -} diff --git a/sha1/CHANGELOG.md b/sha1/CHANGELOG.md index 17cd4b9e9..0a7eb63a4 100644 --- a/sha1/CHANGELOG.md +++ b/sha1/CHANGELOG.md @@ -5,6 +5,12 @@ 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.10.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.9.8 (2021-08-27) ### Changed - Bump `cpufeatures` dependency to 0.2 ([#306]) diff --git a/sha1/Cargo.toml b/sha1/Cargo.toml index cbf261eca..3c8c14624 100644 --- a/sha1/Cargo.toml +++ b/sha1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sha-1" -version = "0.9.8" +version = "0.10.0" # Also update html_root_url in lib.rs when bumping this description = "SHA-1 hash function" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" @@ -15,9 +15,7 @@ categories = ["cryptography", "no-std"] name = "sha1" [dependencies] -digest = "0.9" -block-buffer = "0.9" -opaque-debug = "0.3" +digest = "0.10" cfg-if = "1.0" sha1-asm = { version = "0.5", optional = true } @@ -25,7 +23,7 @@ sha1-asm = { version = "0.5", optional = true } cpufeatures = "0.2" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] @@ -35,9 +33,6 @@ asm = ["sha1-asm"] compress = [] # Expose compress function force-soft = [] # Force software implementation -# DEPRECATED: use `asm` instead -asm-aarch64 = ["asm"] - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/sha1/examples/sha1sum.rs b/sha1/examples/sha1sum.rs deleted file mode 100644 index 78d0cbf90..000000000 --- a/sha1/examples/sha1sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use sha1::{Digest, Sha1}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/sha1/src/compress.rs b/sha1/src/compress.rs index b45f87bc2..feba6fd05 100644 --- a/sha1/src/compress.rs +++ b/sha1/src/compress.rs @@ -1,5 +1,5 @@ -use digest::consts::U64; -use digest::generic_array::GenericArray; +use crate::{Block, BlockSizeUser, Sha1Core}; +use digest::generic_array::typenum::Unsigned; cfg_if::cfg_if! { if #[cfg(feature = "force-soft")] { @@ -14,9 +14,7 @@ cfg_if::cfg_if! { mod soft; #[cfg(feature = "asm")] mod soft { - pub(crate) fn compress(state: &mut [u32; 5], blocks: &[[u8; 64]]) { - sha1_asm::compress(state, blocks) - } + pub use sha1_asm::compress; } mod x86; use x86::compress as compress_inner; @@ -26,12 +24,15 @@ cfg_if::cfg_if! { } } +const BLOCK_SIZE: usize = ::BlockSize::USIZE; + /// SHA-1 compression function #[cfg_attr(docsrs, doc(cfg(feature = "compress")))] -pub fn compress(state: &mut [u32; 5], blocks: &[GenericArray]) { +pub fn compress(state: &mut [u32; 5], blocks: &[Block]) { // SAFETY: GenericArray and [u8; 64] have // exactly the same memory layout #[allow(unsafe_code)] - let blocks: &[[u8; 64]] = unsafe { &*(blocks as *const _ as *const [[u8; 64]]) }; + let blocks: &[[u8; BLOCK_SIZE]] = + unsafe { &*(blocks as *const _ as *const [[u8; BLOCK_SIZE]]) }; compress_inner(state, blocks); } diff --git a/sha1/src/compress/soft.rs b/sha1/src/compress/soft.rs index 19366fb13..f4777e7cc 100644 --- a/sha1/src/compress/soft.rs +++ b/sha1/src/compress/soft.rs @@ -1,7 +1,9 @@ #![allow(clippy::many_single_char_names)] -use crate::consts::{BLOCK_LEN, K0, K1, K2, K3}; +use super::BLOCK_SIZE; use core::convert::TryInto; +const K: [u32; 4] = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6]; + #[inline(always)] fn add(a: [u32; 4], b: [u32; 4]) -> [u32; 4] { [ @@ -47,16 +49,11 @@ fn sha1_first_half(abcd: [u32; 4], msg: [u32; 4]) -> [u32; 4] { } fn sha1_digest_round_x4(abcd: [u32; 4], work: [u32; 4], i: i8) -> [u32; 4] { - const K0V: [u32; 4] = [K0, K0, K0, K0]; - const K1V: [u32; 4] = [K1, K1, K1, K1]; - const K2V: [u32; 4] = [K2, K2, K2, K2]; - const K3V: [u32; 4] = [K3, K3, K3, K3]; - match i { - 0 => sha1rnds4c(abcd, add(work, K0V)), - 1 => sha1rnds4p(abcd, add(work, K1V)), - 2 => sha1rnds4m(abcd, add(work, K2V)), - 3 => sha1rnds4p(abcd, add(work, K3V)), + 0 => sha1rnds4c(abcd, add(work, [K[0]; 4])), + 1 => sha1rnds4p(abcd, add(work, [K[1]; 4])), + 2 => sha1rnds4m(abcd, add(work, [K[2]; 4])), + 3 => sha1rnds4p(abcd, add(work, [K[3]; 4])), _ => unreachable!("unknown icosaround index"), } } @@ -247,8 +244,8 @@ fn sha1_digest_block_u32(state: &mut [u32; 5], block: &[u32; 16]) { state[4] = state[4].wrapping_add(e); } -pub fn compress(state: &mut [u32; 5], blocks: &[[u8; 64]]) { - let mut block_u32 = [0u32; BLOCK_LEN]; +pub fn compress(state: &mut [u32; 5], blocks: &[[u8; BLOCK_SIZE]]) { + let mut block_u32 = [0u32; BLOCK_SIZE / 4]; // since LLVM can't properly use aliasing yet it will make // unnecessary state stores without this copy let mut state_cpy = *state; diff --git a/sha1/src/consts.rs b/sha1/src/consts.rs deleted file mode 100644 index c227df3a9..000000000 --- a/sha1/src/consts.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![allow(clippy::unreadable_literal, dead_code)] - -pub const STATE_LEN: usize = 5; - -pub const BLOCK_LEN: usize = 16; - -pub const K0: u32 = 0x5A827999u32; -pub const K1: u32 = 0x6ED9EBA1u32; -pub const K2: u32 = 0x8F1BBCDCu32; -pub const K3: u32 = 0xCA62C1D6u32; - -pub const H: [u32; STATE_LEN] = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]; diff --git a/sha1/src/lib.rs b/sha1/src/lib.rs index e1c8ac4a0..134108e77 100644 --- a/sha1/src/lib.rs +++ b/sha1/src/lib.rs @@ -36,81 +36,105 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/sha-1/0.10.0" )] -#![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "std")] -extern crate std; +pub use digest::{self, Digest}; + +use core::{fmt, slice::from_ref}; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::typenum::{Unsigned, U20, U64}, + HashMarker, Output, +}; mod compress; -mod consts; #[cfg(feature = "compress")] -pub use crate::compress::compress; +pub use compress::compress; #[cfg(not(feature = "compress"))] -use crate::compress::compress; -use crate::consts::{H, STATE_LEN}; -use block_buffer::BlockBuffer; -use digest::consts::{U20, U64}; -pub use digest::{self, Digest}; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; +use compress::compress; + +const STATE_LEN: usize = 5; -/// Structure representing the state of a SHA-1 computation +/// Core SHA-1 hasher state. #[derive(Clone)] -pub struct Sha1 { +pub struct Sha1Core { h: [u32; STATE_LEN], - len: u64, - buffer: BlockBuffer, + block_len: u64, } -impl Default for Sha1 { - fn default() -> Self { - Sha1 { - h: H, - len: 0u64, - buffer: Default::default(), - } - } -} +impl HashMarker for Sha1Core {} -impl BlockInput for Sha1 { +impl BlockSizeUser for Sha1Core { type BlockSize = U64; } -impl Update for Sha1 { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - // Assumes that `length_bits<<3` will not overflow - self.len += input.len() as u64; - let state = &mut self.h; - self.buffer.input_blocks(input, |d| compress(state, d)); - } +impl BufferKindUser for Sha1Core { + type BufferKind = Eager; } -impl FixedOutputDirty for Sha1 { +impl OutputSizeUser for Sha1Core { type OutputSize = U20; +} + +impl UpdateCore for Sha1Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.block_len += blocks.len() as u64; + compress(&mut self.h, blocks); + } +} - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - let s = &mut self.h; - let l = self.len << 3; - self.buffer - .len64_padding_be(l, |d| compress(s, core::slice::from_ref(d))); - for (chunk, v) in out.chunks_exact_mut(4).zip(self.h.iter()) { +impl FixedOutputCore for Sha1Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bs = Self::BlockSize::U64; + let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len); + + let mut h = self.h; + buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b))); + for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) { chunk.copy_from_slice(&v.to_be_bytes()); } } } -impl Reset for Sha1 { +impl Default for Sha1Core { + #[inline] + fn default() -> Self { + Self { + h: [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0], + block_len: 0, + } + } +} + +impl Reset for Sha1Core { + #[inline] fn reset(&mut self) { - self.h = H; - self.len = 0; - self.buffer.reset(); + *self = Default::default(); + } +} + +impl AlgorithmName for Sha1Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Sha1") + } +} + +impl fmt::Debug for Sha1Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Sha1Core { ... }") } } -opaque_debug::implement!(Sha1); -digest::impl_write!(Sha1); +/// SHA-1 hasher state. +pub type Sha1 = CoreWrapper; diff --git a/sha1/tests/data/sha1.blb b/sha1/tests/data/sha1.blb index 13ae2df262cc1e53a4528d0e7e2c11092eedd392..e8dc49163c0c33f4048bfebb2b28b82707e28483 100644 GIT binary patch delta 112 zcmV-$0FVFh0qOx800v=VV<@SaJ~l@Nfoi%wC2@FA!fc$-*qv~ZAvhK&gqS`=96Qo( zx~@v0`B5q5}D0D-|f-pDcgU SUK=|4)96|Y(S4f`4Yaeiu`_W1 delta 118 zcmV-+0Ez$V0q_AKVr*|>VtFwGVPazxshK`DM+Sjvx;`awcu>M@oY2^vIFTDT78Hb- zK13Wl(r&u0N}>5tDdpuxaPcdVswf#`Z)X%Q)ZxZ@Ehzl$gr4EMcIP=8lj{;Ik*X^d Y6yBdKf6`tXI{MS-S_{#An-C4Ov$MZ7F8}}l diff --git a/sha2/CHANGELOG.md b/sha2/CHANGELOG.md index 433465d0b..3738c63a4 100644 --- a/sha2/CHANGELOG.md +++ b/sha2/CHANGELOG.md @@ -5,6 +5,12 @@ 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.10.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.9.8 (2021-09-09) ### Fixed - Bug in the AVX2 backend ([#314]) diff --git a/sha2/Cargo.toml b/sha2/Cargo.toml index cf17feb8e..5a9984032 100644 --- a/sha2/Cargo.toml +++ b/sha2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sha2" -version = "0.9.8" +version = "0.10.0" # Also update html_root_url in lib.rs when bumping this description = """ Pure Rust implementation of the SHA-2 hash function family including SHA-224, SHA-256, SHA-384, and SHA-512. @@ -15,9 +15,7 @@ keywords = ["crypto", "sha2", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = "0.9" -opaque-debug = "0.3" +digest = "0.10" cfg-if = "1.0" sha2-asm = { version = "0.6.1", optional = true } @@ -25,7 +23,7 @@ sha2-asm = { version = "0.6.1", optional = true } cpufeatures = "0.2" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/sha2/examples/sha256sum.rs b/sha2/examples/sha256sum.rs deleted file mode 100644 index 31ee97929..000000000 --- a/sha2/examples/sha256sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use sha2::{Digest, Sha256}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/sha2/examples/sha512sum.rs b/sha2/examples/sha512sum.rs deleted file mode 100644 index 9d4785acd..000000000 --- a/sha2/examples/sha512sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use sha2::{Digest, Sha512}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/sha2/src/lib.rs b/sha2/src/lib.rs index 1927067e1..9e2e43627 100644 --- a/sha2/src/lib.rs +++ b/sha2/src/lib.rs @@ -55,22 +55,186 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/sha2/0.10.0" )] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "std")] -extern crate std; +pub use digest::{self, Digest}; + +use core::{fmt, mem::size_of, slice::from_ref}; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::{ + typenum::{Unsigned, U128, U28, U32, U48, U64}, + GenericArray, + }, + HashMarker, Output, +}; mod consts; mod sha256; mod sha512; -pub use digest::{self, Digest}; #[cfg(feature = "compress")] pub use sha256::compress256; -pub use sha256::{Sha224, Sha256}; #[cfg(feature = "compress")] pub use sha512::compress512; -pub use sha512::{Sha384, Sha512, Sha512Trunc224, Sha512Trunc256}; + +macro_rules! implement { + ( + $name:ident, $full_name:ident, $init:expr, $block_size:ty, $out_size:ty, + $compress:expr, $word:ty, $dword:ty, $alg_name:expr, + ) => { + #[doc = "Core "] + #[doc = $alg_name] + #[doc = " hasher state."] + #[derive(Clone)] + pub struct $name { + state: [$word; 8], + block_len: $dword, + } + + impl HashMarker for $name {} + + impl BlockSizeUser for $name { + type BlockSize = $block_size; + } + + impl BufferKindUser for $name { + type BufferKind = Eager; + } + + impl OutputSizeUser for $name { + type OutputSize = $out_size; + } + + impl UpdateCore for $name { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.block_len += blocks.len() as $dword; + $compress(&mut self.state, blocks); + } + } + + impl FixedOutputCore for $name { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bs = Self::BlockSize::U64 as $dword; + let bit_len = 8 * (buffer.get_pos() as $dword + bs * self.block_len); + let pad = bit_len.to_be_bytes(); + let s = &mut self.state; + buffer.digest_pad(0x80, &pad, |b| $compress(s, from_ref(b))); + let n = size_of::<$word>(); + for (chunk, v) in out.chunks_mut(n).zip(s.iter()) { + chunk.copy_from_slice(&v.to_be_bytes()[..chunk.len()]); + } + } + } + + impl Default for $name { + #[inline] + fn default() -> Self { + Self { + state: $init, + block_len: 0, + } + } + } + + impl Reset for $name { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } + } + + impl AlgorithmName for $name { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(stringify!($full_name)) + } + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + #[doc = $alg_name] + #[doc = " hasher state."] + pub type $full_name = CoreWrapper<$name>; + }; +} + +implement!( + Sha224Core, + Sha224, + consts::H224, + U64, + U28, + sha256::compress256, + u32, + u64, + "SHA-224", +); +implement!( + Sha256Core, + Sha256, + consts::H256, + U64, + U32, + sha256::compress256, + u32, + u64, + "SHA-256", +); +implement!( + Sha512Trunc224Core, + Sha512Trunc224, + consts::H512_TRUNC_224, + U128, + U28, + sha512::compress512, + u64, + u128, + "SHA-512/224", +); +implement!( + Sha512Trunc256Core, + Sha512Trunc256, + consts::H512_TRUNC_256, + U128, + U32, + sha512::compress512, + u64, + u128, + "SHA-512/256", +); +implement!( + Sha384Core, + Sha384, + consts::H384, + U128, + U48, + sha512::compress512, + u64, + u128, + "SHA-384", +); +implement!( + Sha512Core, + Sha512, + consts::H512, + U128, + U64, + sha512::compress512, + u64, + u128, + "SHA-512", +); diff --git a/sha2/src/sha256.rs b/sha2/src/sha256.rs index 5e5909657..5ee19f6f7 100644 --- a/sha2/src/sha256.rs +++ b/sha2/src/sha256.rs @@ -1,142 +1,4 @@ -//! SHA-256 -use crate::consts::{H224, H256, STATE_LEN}; -use block_buffer::BlockBuffer; -use core::slice::from_ref; -use digest::consts::{U28, U32, U64}; -use digest::generic_array::GenericArray; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; - -type BlockSize = U64; - -/// Structure that keeps state of the Sha-256 operation and -/// contains the logic necessary to perform the final calculations. -#[derive(Clone)] -struct Engine256 { - len: u64, - buffer: BlockBuffer, - state: [u32; 8], -} - -impl Engine256 { - fn new(h: &[u32; STATE_LEN]) -> Engine256 { - Engine256 { - len: 0, - buffer: Default::default(), - state: *h, - } - } - - fn update(&mut self, input: &[u8]) { - // Assumes that input.len() can be converted to u64 without overflow - self.len += (input.len() as u64) << 3; - let s = &mut self.state; - self.buffer.input_blocks(input, |b| compress256(s, b)); - } - - fn finish(&mut self) { - let s = &mut self.state; - let l = self.len; - self.buffer - .len64_padding_be(l, |b| compress256(s, from_ref(b))); - } - - fn reset(&mut self, h: &[u32; STATE_LEN]) { - self.len = 0; - self.buffer.reset(); - self.state = *h; - } -} - -/// The SHA-256 hash algorithm with the SHA-256 initial hash value. -#[derive(Clone)] -pub struct Sha256 { - engine: Engine256, -} - -impl Default for Sha256 { - fn default() -> Self { - Sha256 { - engine: Engine256::new(&H256), - } - } -} - -impl BlockInput for Sha256 { - type BlockSize = BlockSize; -} - -impl Update for Sha256 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.update(input.as_ref()); - } -} - -impl FixedOutputDirty for Sha256 { - type OutputSize = U32; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let s = self.engine.state; - for (chunk, v) in out.chunks_exact_mut(4).zip(s.iter()) { - chunk.copy_from_slice(&v.to_be_bytes()); - } - } -} - -impl Reset for Sha256 { - fn reset(&mut self) { - self.engine.reset(&H256); - } -} - -/// The SHA-256 hash algorithm with the SHA-224 initial hash value. The result -/// is truncated to 224 bits. -#[derive(Clone)] -pub struct Sha224 { - engine: Engine256, -} - -impl Default for Sha224 { - fn default() -> Self { - Sha224 { - engine: Engine256::new(&H224), - } - } -} - -impl BlockInput for Sha224 { - type BlockSize = BlockSize; -} - -impl Update for Sha224 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.update(input.as_ref()); - } -} - -impl FixedOutputDirty for Sha224 { - type OutputSize = U28; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let s = &self.engine.state[..7]; - for (chunk, v) in out.chunks_exact_mut(4).zip(s.iter()) { - chunk.copy_from_slice(&v.to_be_bytes()); - } - } -} - -impl Reset for Sha224 { - fn reset(&mut self) { - self.engine.reset(&H224); - } -} - -opaque_debug::implement!(Sha224); -opaque_debug::implement!(Sha256); - -digest::impl_write!(Sha224); -digest::impl_write!(Sha256); +use super::{GenericArray, U64}; cfg_if::cfg_if! { if #[cfg(feature = "force-soft")] { @@ -147,9 +9,7 @@ cfg_if::cfg_if! { mod soft; #[cfg(feature = "asm")] mod soft { - pub(crate) fn compress(state: &mut [u32; 8], blocks: &[[u8; 64]]) { - sha2_asm::compress256(state, blocks); - } + pub(crate) use sha2_asm::compress256 as compress; } mod x86; use x86::compress; @@ -171,7 +31,7 @@ cfg_if::cfg_if! { pub fn compress256(state: &mut [u32; 8], blocks: &[GenericArray]) { // SAFETY: GenericArray and [u8; 64] have // exactly the same memory layout - #[allow(unsafe_code)] - let blocks: &[[u8; 64]] = unsafe { &*(blocks as *const _ as *const [[u8; 64]]) }; + let p = blocks.as_ptr() as *const [u8; 64]; + let blocks = unsafe { core::slice::from_raw_parts(p, blocks.len()) }; compress(state, blocks) } diff --git a/sha2/src/sha512.rs b/sha2/src/sha512.rs index 22f141e43..c52927ba3 100644 --- a/sha2/src/sha512.rs +++ b/sha2/src/sha512.rs @@ -1,231 +1,4 @@ -//! SHA-512 -use crate::consts::{H384, H512, H512_TRUNC_224, H512_TRUNC_256, STATE_LEN}; -use block_buffer::BlockBuffer; -use core::slice::from_ref; -use digest::consts::{U128, U28, U32, U48, U64}; -use digest::generic_array::GenericArray; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; - -type BlockSize = U128; - -/// Structure that keeps state of the Sha-512 operation and -/// contains the logic necessary to perform the final calculations. -#[derive(Clone)] -struct Engine512 { - len: u128, - buffer: BlockBuffer, - state: [u64; 8], -} - -impl Engine512 { - fn new(h: &[u64; STATE_LEN]) -> Engine512 { - Engine512 { - len: 0, - buffer: Default::default(), - state: *h, - } - } - - fn update(&mut self, input: &[u8]) { - self.len += (input.len() as u128) << 3; - let s = &mut self.state; - self.buffer.input_blocks(input, |b| compress512(s, b)); - } - - fn finish(&mut self) { - let s = &mut self.state; - self.buffer - .len128_padding_be(self.len, |d| compress512(s, from_ref(d))); - } - - fn reset(&mut self, h: &[u64; STATE_LEN]) { - self.len = 0; - self.buffer.reset(); - self.state = *h; - } -} - -/// The SHA-512 hash algorithm with the SHA-512 initial hash value. -#[derive(Clone)] -pub struct Sha512 { - engine: Engine512, -} - -impl Default for Sha512 { - fn default() -> Self { - Sha512 { - engine: Engine512::new(&H512), - } - } -} - -impl BlockInput for Sha512 { - type BlockSize = BlockSize; -} - -impl Update for Sha512 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.update(input.as_ref()); - } -} - -impl FixedOutputDirty for Sha512 { - type OutputSize = U64; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let s = self.engine.state; - for (chunk, v) in out.chunks_exact_mut(8).zip(s.iter()) { - chunk.copy_from_slice(&v.to_be_bytes()); - } - } -} - -impl Reset for Sha512 { - fn reset(&mut self) { - self.engine.reset(&H512); - } -} - -/// The SHA-512 hash algorithm with the SHA-384 initial hash value. The result -/// is truncated to 384 bits. -#[derive(Clone)] -pub struct Sha384 { - engine: Engine512, -} - -impl Default for Sha384 { - fn default() -> Self { - Sha384 { - engine: Engine512::new(&H384), - } - } -} - -impl BlockInput for Sha384 { - type BlockSize = BlockSize; -} - -impl Update for Sha384 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.update(input.as_ref()); - } -} - -impl FixedOutputDirty for Sha384 { - type OutputSize = U48; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let s = &self.engine.state[..6]; - for (chunk, v) in out.chunks_exact_mut(8).zip(s.iter()) { - chunk.copy_from_slice(&v.to_be_bytes()); - } - } -} - -impl Reset for Sha384 { - fn reset(&mut self) { - self.engine.reset(&H384); - } -} - -/// The SHA-512 hash algorithm with the SHA-512/256 initial hash value. The -/// result is truncated to 256 bits. -#[derive(Clone)] -pub struct Sha512Trunc256 { - engine: Engine512, -} - -impl Default for Sha512Trunc256 { - fn default() -> Self { - Sha512Trunc256 { - engine: Engine512::new(&H512_TRUNC_256), - } - } -} - -impl BlockInput for Sha512Trunc256 { - type BlockSize = BlockSize; -} - -impl Update for Sha512Trunc256 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.update(input.as_ref()); - } -} - -impl FixedOutputDirty for Sha512Trunc256 { - type OutputSize = U32; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let s = &self.engine.state[..4]; - for (chunk, v) in out.chunks_exact_mut(8).zip(s.iter()) { - chunk.copy_from_slice(&v.to_be_bytes()); - } - } -} - -impl Reset for Sha512Trunc256 { - fn reset(&mut self) { - self.engine.reset(&H512_TRUNC_256); - } -} - -/// The SHA-512 hash algorithm with the SHA-512/224 initial hash value. -/// The result is truncated to 224 bits. -#[derive(Clone)] -pub struct Sha512Trunc224 { - engine: Engine512, -} - -impl Default for Sha512Trunc224 { - fn default() -> Self { - Sha512Trunc224 { - engine: Engine512::new(&H512_TRUNC_224), - } - } -} - -impl BlockInput for Sha512Trunc224 { - type BlockSize = BlockSize; -} - -impl Update for Sha512Trunc224 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.update(input.as_ref()); - } -} - -impl FixedOutputDirty for Sha512Trunc224 { - type OutputSize = U28; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let s = &self.engine.state; - for (chunk, v) in out.chunks_exact_mut(8).zip(s[..3].iter()) { - chunk.copy_from_slice(&v.to_be_bytes()); - } - out[24..28].copy_from_slice(&s[3].to_be_bytes()[..4]); - } -} - -impl Reset for Sha512Trunc224 { - fn reset(&mut self) { - self.engine.reset(&H512_TRUNC_224); - } -} - -opaque_debug::implement!(Sha384); -opaque_debug::implement!(Sha512); -opaque_debug::implement!(Sha512Trunc224); -opaque_debug::implement!(Sha512Trunc256); - -digest::impl_write!(Sha384); -digest::impl_write!(Sha512); -digest::impl_write!(Sha512Trunc224); -digest::impl_write!(Sha512Trunc256); +use super::{GenericArray, U128}; cfg_if::cfg_if! { if #[cfg(feature = "force-soft")] { @@ -254,9 +27,9 @@ cfg_if::cfg_if! { /// functionality of SHA-512. #[cfg_attr(docsrs, doc(cfg(feature = "compress")))] pub fn compress512(state: &mut [u64; 8], blocks: &[GenericArray]) { - // SAFETY: GenericArray and [u8; 128] have + // SAFETY: GenericArray and [u8; 64] have // exactly the same memory layout - #[allow(unsafe_code)] - let blocks: &[[u8; 128]] = unsafe { &*(blocks as *const _ as *const [[u8; 128]]) }; + let p = blocks.as_ptr() as *const [u8; 128]; + let blocks = unsafe { core::slice::from_raw_parts(p, blocks.len()) }; compress(state, blocks) } diff --git a/sha2/tests/data/sha224.blb b/sha2/tests/data/sha224.blb index 50759c294c8a4983e4621143d2a25009c8b0eeac..69327048a92015fdd77c8aa346f33537b33743c8 100644 GIT binary patch delta 55 zcmV-70LcHi0kQ!D0020V2^;}dk#8#=ICBmVo7bqLD;&AmpqipGT_iAAecQmpi>;9r NC0LPfECD!?oE!#g6j%TN delta 87 zcmdnQxPwtGDJMTEsnU=^=AsuVtFwDAmgyaLYVv<6q@_=$eC}sBqy#xPg8fgxccrvYQwL@RB^go$Yej1fQk diff --git a/sha2/tests/data/sha512.blb b/sha2/tests/data/sha512.blb index b073a77cb7fc2b17a4dcbf8b9ff23354c7407045..bb2ec390c19b32edc9a94780256ae5208ebd38d2 100644 GIT binary patch delta 35 ncmZ3&w2+B~fuVt6BBujm*hDXFCLpuSfiVKeWYz<+pEv*jo9_ve delta 38 scmZ3;w1kN>DJMTEsnU?aVIqqIqxM8sZAOQQMGlNQKo*mp!^DRU0M%;?6aWAK diff --git a/sha2/tests/data/sha512_224.blb b/sha2/tests/data/sha512_224.blb index 4d2ef87ff011d6043334e2cfb3a690cbd2822905..3c3ab8facce9063c162fadfbfec7e768f92f9cfb 100644 GIT binary patch delta 55 zcmV-70LcHi0kQ!D0020V2^;}dk#8#=IFwA%gnzX~Sk!l2ut-`^05K8B<=Un{=OV_c NH&~HxECD!?oE#Ps6zc#0 delta 87 zcmdnQxPwtGDJMTEsnU=^Chx*sriT0#^HlG#@km}?({^fi`?UpkFT@yIw|vo_sG!X# rGtozeQ3uG9)04@~npEi-cZ5wmvsADC=dtc=Zks3#=}Pf)tVQ<#{`Dds diff --git a/sha2/tests/data/sha512_256.blb b/sha2/tests/data/sha512_256.blb index 5346c9494df4f0764cb5d4cde99318b345f87595..acd380aa0c33624eae718dfa7a7e0fe68548d6a0 100644 GIT binary patch delta 32 mcmX@YxQ~&Ufx%%SrvhWxL@jMbhlybdj1fQHt~u6ad4}8~p$P diff --git a/sha2/tests/lib.rs b/sha2/tests/lib.rs index fe120455b..6e8db6975 100644 --- a/sha2/tests/lib.rs +++ b/sha2/tests/lib.rs @@ -36,7 +36,7 @@ fn sha512_avx2_bug() { 2a3e943072f30afa45f2bf57ccd386f29b76dbcdb3a861224ca0b77bc3f55c7a d3880a49c0c9c166eedf7f209c41b380896886155acb8f6c7c07044343a3e692 "); - let res = sha2::Sha512::digest(&msg); + let res = sha2::Sha512::digest(&msg[..]); assert_eq!(res[..], expected[..]); } diff --git a/sha3/CHANGELOG.md b/sha3/CHANGELOG.md index 6d2b6b7bc..fee3168a8 100644 --- a/sha3/CHANGELOG.md +++ b/sha3/CHANGELOG.md @@ -5,6 +5,11 @@ 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.10.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 ## 0.9.1 (2020-06-28) ### Changed diff --git a/sha3/Cargo.toml b/sha3/Cargo.toml index 57824552d..faae04c30 100644 --- a/sha3/Cargo.toml +++ b/sha3/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sha3" -version = "0.9.1" +version = "0.10.0" # Also update html_root_url in lib.rs when bumping this description = "SHA-3 (Keccak) hash function" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" @@ -12,13 +12,11 @@ keywords = ["crypto", "sha3", "keccak", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = { version = "0.9", features = ["block-padding"] } -opaque-debug = "0.3" +digest = "0.10" keccak = "0.1" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/sha3/examples/sha3_256sum.rs b/sha3/examples/sha3_256sum.rs deleted file mode 100644 index bc9da2e08..000000000 --- a/sha3/examples/sha3_256sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use sha3::{Digest, Sha3_256}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/sha3/examples/sha3_512sum.rs b/sha3/examples/sha3_512sum.rs deleted file mode 100644 index 1bfbe3b89..000000000 --- a/sha3/examples/sha3_512sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use sha3::{Digest, Sha3_512}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/sha3/src/lib.rs b/sha3/src/lib.rs index 831762955..b6dcee0b2 100644 --- a/sha3/src/lib.rs +++ b/sha3/src/lib.rs @@ -58,106 +58,72 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/sha3/0.10.0" )] #![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "std")] -extern crate std; - pub use digest::{self, Digest}; -use block_buffer::BlockBuffer; -use digest::consts::{U104, U136, U144, U168, U200, U28, U32, U48, U64, U72}; -use digest::generic_array::typenum::Unsigned; -use digest::{BlockInput, ExtendableOutputDirty, FixedOutputDirty, Reset, Update}; +use core::fmt; +use digest::{ + block_buffer::Eager, + consts::{U104, U136, U144, U168, U200, U28, U32, U48, U64, U72}, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, + ExtendableOutputCore, FixedOutputCore, OutputSizeUser, Reset, UpdateCore, XofReaderCore, + XofReaderCoreWrapper, + }, + HashMarker, Output, +}; -mod paddings; #[macro_use] mod macros; -mod reader; mod state; -pub use crate::reader::Sha3XofReader; use crate::state::Sha3State; -sha3_impl!( - Keccak224, - U28, - U144, - paddings::Keccak, - "Keccak-224 hash function." -); -sha3_impl!( - Keccak256, - U32, - U136, - paddings::Keccak, - "Keccak-256 hash function." -); -sha3_impl!( - Keccak384, - U48, - U104, - paddings::Keccak, - "Keccak-384 hash function." -); -sha3_impl!( - Keccak512, - U64, - U72, - paddings::Keccak, - "Keccak-512 hash function." -); +// Paddings +const KECCAK: u8 = 0x01; +const SHA3: u8 = 0x06; +const SHAKE: u8 = 0x1f; -sha3_impl!( +impl_sha3!(Keccak224Core, Keccak224, U28, U144, KECCAK, "Keccak-224"); +impl_sha3!(Keccak256Core, Keccak256, U32, U136, KECCAK, "Keccak-256"); +impl_sha3!(Keccak384Core, Keccak384, U48, U104, KECCAK, "Keccak-384"); +impl_sha3!(Keccak512Core, Keccak512, U64, U72, KECCAK, "Keccak-512"); + +impl_sha3!( + Keccak256FullCore, Keccak256Full, U200, U136, - paddings::Keccak, - "SHA-3 variant used in CryptoNight." + KECCAK, + "SHA-3 CryptoNight variant", ); -sha3_impl!( - Sha3_224, - U28, - U144, - paddings::Sha3, - "SHA-3-224 hash function." -); -sha3_impl!( - Sha3_256, - U32, - U136, - paddings::Sha3, - "SHA-3-256 hash function." -); -sha3_impl!( - Sha3_384, - U48, - U104, - paddings::Sha3, - "SHA-3-384 hash function." -); -sha3_impl!( - Sha3_512, - U64, - U72, - paddings::Sha3, - "SHA-3-512 hash function." -); +impl_sha3!(Sha3_224Core, Sha3_224, U28, U144, SHA3, "SHA-3-224"); +impl_sha3!(Sha3_256Core, Sha3_256, U32, U136, SHA3, "SHA-3-256"); +impl_sha3!(Sha3_384Core, Sha3_384, U48, U104, SHA3, "SHA-3-384"); +impl_sha3!(Sha3_512Core, Sha3_512, U64, U72, SHA3, "SHA-3-512"); -shake_impl!( +impl_shake!( + Shake128Core, Shake128, + Shake128ReaderCore, + Shake128Reader, U168, - paddings::Shake, - "SHAKE128 extendable output (XOF) hash function" + SHAKE, + "SHAKE128", ); -shake_impl!( +impl_shake!( + Shake256Core, Shake256, + Shake256ReaderCore, + Shake256Reader, U136, - paddings::Shake, - "SHAKE256 extendable output (XOF) hash function" + SHAKE, + "SHAKE256", ); diff --git a/sha3/src/macros.rs b/sha3/src/macros.rs index b690124c8..1ec96367b 100644 --- a/sha3/src/macros.rs +++ b/sha3/src/macros.rs @@ -1,49 +1,50 @@ -macro_rules! impl_state { - ($state:ident, $rate:ident, $padding:ty, $doc:expr) => { +macro_rules! impl_sha3 { + ( + $name:ident, $full_name:ident, $output_size:ident, + $rate:ident, $pad:expr, $alg_name:expr $(,)? + ) => { + #[doc = "Core "] + #[doc = $alg_name] + #[doc = " hasher state."] + #[derive(Clone)] #[allow(non_camel_case_types)] - #[derive(Clone, Default)] - #[doc=$doc] - pub struct $state { + pub struct $name { state: Sha3State, - buffer: BlockBuffer<$rate>, } - impl $state { - fn absorb(&mut self, input: &[u8]) { - let s = &mut self.state; - self.buffer.input_block(input, |b| s.absorb_block(b)); - } + impl HashMarker for $name {} - fn apply_padding(&mut self) { - let buf = self - .buffer - .pad_with::<$padding>() - .expect("we never use input_lazy"); - self.state.absorb_block(buf); - } + impl BlockSizeUser for $name { + type BlockSize = $rate; } - }; -} -macro_rules! sha3_impl { - ($state:ident, $output_size:ident, $rate:ident, $padding:ty, $doc:expr) => { - impl_state!($state, $rate, $padding, $doc); + impl BufferKindUser for $name { + type BufferKind = Eager; + } - impl BlockInput for $state { - type BlockSize = $rate; + impl OutputSizeUser for $name { + type OutputSize = $output_size; } - impl Update for $state { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.absorb(input.as_ref()) + impl UpdateCore for $name { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + self.state.absorb_block(block) + } } } - impl FixedOutputDirty for $state { - type OutputSize = $output_size; + impl FixedOutputCore for $name { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let pos = buffer.get_pos(); + let block = buffer.pad_with_zeros(); + block[pos] = $pad; + let n = block.len(); + block[n - 1] |= 0x80; - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.apply_padding(); + self.state.absorb_block(block); let n = out.len(); self.state.as_bytes(|state| { @@ -52,46 +53,151 @@ macro_rules! sha3_impl { } } - impl Reset for $state { + impl Default for $name { + #[inline] + fn default() -> Self { + Self { + state: Default::default(), + } + } + } + + impl Reset for $name { + #[inline] fn reset(&mut self) { - self.state = Default::default(); - self.buffer.reset(); + *self = Default::default(); } } - opaque_debug::implement!($state); - digest::impl_write!($state); + impl AlgorithmName for $name { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(stringify!($full_name)) + } + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + #[doc = $alg_name] + #[doc = " hasher state."] + pub type $full_name = CoreWrapper<$name>; }; } -macro_rules! shake_impl { - ($state:ident, $rate:ident, $padding:ty, $doc:expr) => { - impl_state!($state, $rate, $padding, $doc); +macro_rules! impl_shake { + ( + $name:ident, $full_name:ident, $reader:ident, $reader_full:ident, + $rate:ident, $pad:expr, $alg_name:expr, + ) => { + #[doc = "Core "] + #[doc = $alg_name] + #[doc = " hasher state."] + #[derive(Clone)] + #[allow(non_camel_case_types)] + pub struct $name { + state: Sha3State, + } + + impl HashMarker for $name {} + + impl BlockSizeUser for $name { + type BlockSize = $rate; + } + + impl BufferKindUser for $name { + type BufferKind = Eager; + } - impl Update for $state { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.absorb(input.as_ref()) + impl UpdateCore for $name { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + self.state.absorb_block(block) + } } } - impl ExtendableOutputDirty for $state { - type Reader = Sha3XofReader; + impl ExtendableOutputCore for $name { + type ReaderCore = $reader; + + #[inline] + fn finalize_xof_core(&mut self, buffer: &mut Buffer) -> Self::ReaderCore { + let pos = buffer.get_pos(); + let block = buffer.pad_with_zeros(); + block[pos] = $pad; + let n = block.len(); + block[n - 1] |= 0x80; + + self.state.absorb_block(block); + $reader { + state: self.state.clone(), + } + } + } - fn finalize_xof_dirty(&mut self) -> Sha3XofReader { - self.apply_padding(); - let r = $rate::to_usize(); - Sha3XofReader::new(self.state.clone(), r) + impl Default for $name { + #[inline] + fn default() -> Self { + Self { + state: Default::default(), + } } } - impl Reset for $state { + impl Reset for $name { + #[inline] fn reset(&mut self) { - self.state = Default::default(); - self.buffer.reset(); + *self = Default::default(); + } + } + + impl AlgorithmName for $name { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(stringify!($full_name)) + } + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + #[doc = "Core "] + #[doc = $alg_name] + #[doc = " reader state."] + #[derive(Clone)] + #[allow(non_camel_case_types)] + pub struct $reader { + state: Sha3State, + } + + impl BlockSizeUser for $reader { + type BlockSize = $rate; + } + + impl XofReaderCore for $reader { + #[inline] + fn read_block(&mut self) -> Block { + let mut block = Block::::default(); + let n = block.len(); + self.state.as_bytes(|state| { + block.copy_from_slice(&state[..n]); + }); + self.state.apply_f(); + block } } - opaque_debug::implement!($state); - digest::impl_write!($state); + #[doc = $alg_name] + #[doc = " hasher state."] + pub type $full_name = CoreWrapper<$name>; + + #[doc = $alg_name] + #[doc = " reader state."] + pub type $reader_full = XofReaderCoreWrapper<$name>; }; } diff --git a/sha3/src/paddings.rs b/sha3/src/paddings.rs deleted file mode 100644 index d11c87f89..000000000 --- a/sha3/src/paddings.rs +++ /dev/null @@ -1,33 +0,0 @@ -use block_buffer::block_padding::{PadError, Padding, UnpadError}; - -macro_rules! impl_padding { - ($name:ident, $pad:expr) => { - // it does not work with empty enum as it required to have Default impl - // for it for some unclear reason. - #[derive(Copy, Clone, Default)] - pub struct $name; - - impl Padding for $name { - #[inline(always)] - fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError> { - if pos >= block.len() { - return Err(PadError); - } - block[pos] = $pad; - block[pos + 1..].iter_mut().for_each(|b| *b = 0); - let n = block.len(); - block[n - 1] |= 0x80; - Ok(()) - } - - #[inline(always)] - fn unpad(_data: &[u8]) -> Result<&[u8], UnpadError> { - unimplemented!(); - } - } - }; -} - -impl_padding!(Keccak, 0x01); -impl_padding!(Sha3, 0x06); -impl_padding!(Shake, 0x1f); diff --git a/sha3/src/reader.rs b/sha3/src/reader.rs deleted file mode 100644 index fbb2d716e..000000000 --- a/sha3/src/reader.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::state::Sha3State; -use digest::XofReader; -#[cfg(feature = "std")] -use std::io; - -/// Reader state for extracting extendable output. -pub struct Sha3XofReader { - state: Sha3State, - rate: usize, - pos: usize, -} - -impl Sha3XofReader { - pub(crate) fn new(state: Sha3State, rate: usize) -> Self { - Sha3XofReader { - state, - rate, - pos: 0, - } - } -} - -impl XofReader for Sha3XofReader { - fn read(&mut self, mut buffer: &mut [u8]) { - let rem = self.rate - self.pos; - let n = buffer.len(); - if n >= rem { - let (l, r) = { buffer }.split_at_mut(rem); - buffer = r; - self.state.as_bytes(|state| { - l.copy_from_slice(&state[self.pos..self.rate]); - }); - self.state.apply_f(); - } else { - self.state.as_bytes(|state| { - buffer.copy_from_slice(&state[self.pos..self.pos + n]); - }); - self.pos += n; - return; - } - - while buffer.len() >= self.rate { - let (l, r) = { buffer }.split_at_mut(self.rate); - buffer = r; - - self.state.as_bytes(|state| { - l.copy_from_slice(&state[..self.rate]); - }); - self.state.apply_f(); - } - - let n = buffer.len(); - self.pos = n; - self.state.as_bytes(|state| { - buffer.copy_from_slice(&state[..n]); - }); - } -} - -#[cfg(feature = "std")] -impl io::Read for Sha3XofReader { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - ::read(self, buf); - Ok(buf.len()) - } -} diff --git a/sha3/tests/data/keccak_224.blb b/sha3/tests/data/keccak_224.blb index 97d8c497501e3df277a8edc6527a188868a97fbe..393d0acebd1cb819b00a8d382444ace7f9a79bd6 100644 GIT binary patch delta 9 QcmY$DXJ%lqn8+yu00krgHUIzs literal 37 tcmYew$xlkEG-QzZE@2*^z2YH<`Q96sQ`hbYo!A-1^e0r?W4k5SUH~8%55)ig diff --git a/sha3/tests/data/keccak_256.blb b/sha3/tests/data/keccak_256.blb index 6558741ba3542c1cd8f121bd69a6e672adfde652..d964e20947587921b1e8f1927eb062b988e7cab3 100644 GIT binary patch delta 29 lcmZ3-xRQ~Xfx%%Srvfw68Hb5F3QP?Q6MY>R9VYfE003xD2W0>N delta 62 zcmV-E0KxyM0j>coVr*|>VtFwDAjQ%~0fzS@Jd%EWvfRf5z~un8Q_6xTJA3-r1YL!s UZ~@F9ktQGkK#@p50U(iyAS~D!3;+NC diff --git a/sha3/tests/data/keccak_256_full.blb b/sha3/tests/data/keccak_256_full.blb index 733224241dcd4efe9e69bef8c821c7608268f3f1..71af3f2347ee593f91f0e8369ada7b2c8a3a680a 100644 GIT binary patch delta 245 zcmX>sby`Z2K`SLyAwM@SGpV##A*D1avm`Mur8KumV4~a!S(C)1(!7+!ykdpq#L|+~ zoJ57Z{5&8|PAzE?n9Rg@LO?1xu`D&QL?Jb|pd`NtD0q|cgqT`tg+g9tMrKYvgi=V$ z1gYP~bb>Kray_#S6Oglp`2=Ii$Y@_Ku+ddqAQ@+FuuL)c3C5bqHavD9 IWz{?<0DL1;EC2ui delta 236 zcmX>tby!L+DJMTEsnSq1B~>9mH!m}(v{)gfG%2$rF)yVw_ryfW6EaeXNu_xyiFw5e z$%&;UsX2)XdHH!joSa&6V&cCO{JhDDWvPiJ3aPmTCHX}sCSPMbAu60&p^%rEk(rYZ zp%l_GOHNGQ!gPXBXL2pG4&#Z*tC>$Q8ci-?F#@tzu$*8tm|Vze0Aw#_1+jD3KQ9c~)CaOVIYDLyae>Ti-~x$za)ZRHxKA+J OO?Kw71G1ZWP5=PsqgTEF diff --git a/sha3/tests/data/keccak_384.blb b/sha3/tests/data/keccak_384.blb index c21ab269bbb33b2fc88b7769296fb0b1c57c84b8..2509429442ac211eaccbc0e8a62dd247f0fed1a1 100644 GIT binary patch delta 9 QcmcCCW@cbWn8;}W00%4qng9R* delta 15 WcmXrEYybcu(F7F$ diff --git a/sha3/tests/data/keccak_512.blb b/sha3/tests/data/keccak_512.blb index 687719d2642db55e41bae09d65e11461c17052c9..a9e47e0770ae2f87f08d3671e5e195c6578fb28a 100644 GIT binary patch delta 10 RcmeZtVPRlsV3^41000T?0qg(( delta 15 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 bf7&J03$5Xb(lDGDZ8|BW)sUj%1f(IUFbJ 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 RhiM1jokX`UL23DR=Kpx^#h3s9 delta 4244 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 diff --git a/sha3/tests/data/sha3_384.blb b/sha3/tests/data/sha3_384.blb index b5006290dccb219abd6cbe8a7b4dcde662dc8372..802759adf6a77a96ac1a1e0dd232954ef1dbcac2 100644 GIT binary patch delta 3551 zcmWmGdsxkP0LO8sl5Q$TD(PM-t@4v3-K3HvNxCWWD@i5QQc031iK5GgE|elF<&td} zV`etDWz1z5V_9xfZnI5p?eqKRJnz@<`#H~fo^!wPK%u-xL1~aemsqJLXy`n@>1}Qu z>y|d>f>`M%C=~ctE{~Uqm3Nr|7%E#N6R}K21Y)-=flyZp6ACg8~k|5&KkaQwVg@{9w%IAb!m57IrY6fvcLINJEE+eAV zh(wgBWfC%VA{mbASwx$J6x>$NCW1AHRIJfhPV{RCn)=Z_?iH`cDD-^VeD#`$i9>mw zj>MrkJnxo}0lDT1qD+&>#7WIu!bOY7Mv~S_;-Q2b=xXN?&?a*6gZ3)Idl-?2WyA7` z*Ant!Azw{2%LRosgK%A5K!gn+CsRQ2@HK1|9YM>W)z8||Mn2ZX(9N%h&(t&>j+Kz3 zvzCMR5|m*#qLAnuL8zd6L=lmoOQ@kncO7A*M`$2Oub8+YK@-aQ>xs?!gf>p;mk|CV z2{~4b+(0NA5IS%&*hrj`po^CVr9|E+LEF$h^7Biv^+_#mp_+$VMvFKxiVJ=8jVj|J z*N`wkhv6n-k`ZBuWTVYQzXW608kZBtjR{jcGp-==ObB!AH>o5hn-Z2tH?1NR%?K+v znSnSj!3OsG~jlL0k^6%xCW%FhDj2kZ~+ck01YDakE zmfcPw*Pif2hy5-h$bs;~YKLaRVl3g0(6PITehC4v74{HU1R@Z!aV?8~~U)x>PqvUb-7l+Fs)eTw&`F$c*IB^t;cBgiZ!X^;m zD4x(kI64!NSm?Zu(4I&{Vamk)#0v@YVCr&!xa>m2R82a_?wrKtr)N?pQRPa+;f(7c zBFl}4M~mAR#9VhG0UO=FBs@I?9m}jlkDtO~y?!(gbvyD@wbX2vv52)ETqWX5kFU5& z^dyo|=XsczHJM03!Q>;vL@y#0iC#wu(5K=Q1d1-;O2dd_(wt}tbC3W-9AJ% z6n81OwooR~`FqHpR+qQg%ZVWr&jq9=I5Ba`+wHY;atGLc`bc_`u~zf;%b z!ED;Moc%G4$j31MQ^YU+g2LKCP?-K5ab`N9fH%`m6Gs9FB|HxJo@k#zDC5qIGelz` zp@J)cKM-4I5^6X*^GBjAh|s{vptD5LEJ729XPqNf1q(__Q{Ia>6fEf4JcvbYgK~KJ zqmsvAUI&^MPrLngwut|Nc?WIS%s$UMyqZnOVIFdU=nWxsU^M3<@njC6i;JTd1?Pt%$MF99lw*zRKbFd4v_>=UpRQ<`XtZntz?}j3I21 z7ITA`x`41l_JUuDnIhqUeDNj`9!m&VAA5@s;|NDo#@!~CEF_#zzwkF=c|75aw)i_l z(IP?LE<$C&&2Deq4sH8Fz0RM;Z_HV`;Ea8_h^|Fky5QrYyIlU3K)6DE@$bab#e_Qy z67LcHiG(L?lkO90$%Gf&lK&tKmk{2VxulyIn?m?POnE@~EG7Jqx%5vWGL`VhhSVM+ zHH`>BW7e z)kFd=ul}1jQ$Qr*O~D)D=^7##25bKzv=WoTm{C3%$n3DD|{xc}yI1`Q~?>M&KKx89k z!+RoXBawsBjUR}TQX&_}Nh`-bCa>fAavLUoIFrtvv6)_}~7gAJ23v zr5tb#IhTKZU9si^@lW*;BI3&hBj&PY~Xa>x1K+-ZO>KV?sLFz!!S+XUl_mQ;I{^JvquC}9WPu2V6?-{52yL)tUxA>ka=Q292NB9!1X(a9 zZn5EIksX4{Eo0cPX<6%=YcXb7uFlQ(?4iB0FrGAWKK_HW&6Ob_QN_6&9gZP}g)eEv5q}03fU@totztwxN^&13P9;P>VvP;?Y31t*E`Vi+NsNij*FX7Qds3Em! zD)Cj5psG2nW_VZO^A{req$3R&@ATu*qMd{$s&`H!?n%&w)-Hb{au*@ThF#N%YZ7#z z)Eq#}Y9@41&^&|alAw=|&4EO~Zo&X7ch4j)NHD~^-9g0kJ%llG_sk+L?h(|q17?|8 z7R?@QB|@o%XQr6Y63nw=3FbK3GMi9sB`o3E8bWN6V1;j6=MeHX!UjHVp+v0&TU=-h zBTV)Zb_m`ZPP9sJz^%OzgwRe1h;5G~j!SUFv-Y{f)DA&iZj#V3WnJI)g;^pBI(X=W zLmg2()YwNj!((4GQ76F#7x&F0toIYHh}=J)I3mFvkN3wAeg_CoEI+V-xGBL4DhEX( f=^){aZ3knC4-$M~-x)_#bP|3z-MNq$eMtBp{{TqK delta 3260 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 P&+?|a^K+rW7sUSnVi19@ delta 3213 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 diff --git a/sha3/tests/data/shake128.blb b/sha3/tests/data/shake128.blb index 70177c7db265c2adcb09643eb3dc94903a7ab29b..58fb20814850605daf4df0664f02ba562e2c945a 100644 GIT binary patch delta 4013 zcmXBVc~sBYAIEX;t7%eAk|ar+v`LesNt-qyX_6!?ut4gocp{zx(q0?>^qo_xYUj{haUT+@d1w6En3nTC^x?u}(+m8ki?+^_%f( z)tJnp78{I(5cxsUL}QFlnyMkbGpxJiZ)F?jnL7BKn#|V}dPXnmZe09wdv$Hikhf}7 ztR-3-53liBRBtb8J}3w@KaAX^tZgYVr*KIbg{nkp2AL)y>7U3JUwpv!)pA$H=G_NY#GE2?> zGZ2PW1rL|hXn0p%b-EnBe0A&myjLpdv=i;DGZVcp42knCw~FxG|Gd>)%k^feShg1$ zqCy>PItU{h&6?LWVLhLiZ+T}oW#D{sgY*1YCGU=+z1^cYxni|uG?#m2Xqw*k9NxPzwe4xu zk985`B2UskgHr59#O9 z3FA>N!qThdx|y?f>mGmA;8Cqzm_LV&-MxI%PM@k@)@tU;ZH{WIz*SiJ6gCao*S8_G+!vO^~lFbGN{g&$$comlr%NfjSRCf%1)) z6=3KsC`cOh?hJVL7SvCA`&k2H`~(Hdu>oCxc>#h#MaY0K2Ou>}P^3%`?+UC57ZfE+A{>EB5rU%S zmB?PpA$tt}9*7?38-N|yVQ-GEogf>Pw`lpg@Q zR6%LdA>AE_PZu;nCQR%FteYq(LvG0Q0ID;EmbT?v*KI=;o=p;zC0|VTM6t~glr8OZ zy?}AKf^y{eJa1rAo}gU0CEo{lkuNAu))w>zx=k09FP&!i0qHZ;S1#nlqOaOtq@*Da z&h|%Zo~@)QKhF(-0_G`c$vz7Lp}7l0E8WxYbq<8$Z?SBVYTA;Q^g*jyqNFPyEDeI} zmMQ5;2kr|^WF>u>xw0R0Y^9QcJh7@jq+6_HDD~C^L(yxLjATs70BCcGlCj*nJ_P!> zUdco@{WcH^E>$v>A!VUZahcH8Yr}0Trq{hzEZeN2ncTefN5sahN*1ztdl(eDL&-{p z?HUAa*rjAGOZS9BANMHP$fmu6p|E{Qb~5}x1hnaZl7rmx#}J4PDLKlPha;ikhn1XU z?9rjn{-a9H^5F3($l!#~(GUL7!n$x!7aL`>ld8H%i}GQpQ_7WGaJ2h`MNS58ggGLSPrco3mvUi3X#VjCO~$NltQIL%{WNbD22&o zPZFUoPn5zXJs%GxKUa#7DKC?tyDya@W#y}%p#F7AQF6eWWay7KO40Jq`kx_(f0bgS z(C_lf)1R<7r&!yxUU{Of&1&zWcZXm zoWZ9JCi3Y~f!1GLcEwt)Pt)LQHdKK1NLyHwqwHxqeBU0{;_9wc2#D2!Hf-7pHe@qTngeg~ zgpGKcH_e56`M}2P=}YtAbH1<%U+|~-aC87{$}xRt0bJV$HsiX!v=E-!54PZG!L$f& zI{>!gb^~cKylEh8&0Bt?C9qEzY{S0cB;gz3upQrupr!E7LtqC^9ZJh!%_!KBwW4V` zToMgC@%k8I*fSP(X77=-0=_j8cHuj5v=Yu34ZCtyJpBqAjD_9Ua2&0IcaMYJ`S=ED8>avuE#XHJEKdD1j0h0O}!5Vk0!jquq*IF!%Nq%wG75gf*u zvuP7-J_inG%XzdJu9yc$@TCQ`1Bhx7Q! z89D}+omHQE0dG1_C%~UBs9YfU=ZpWh^Ceh=U9Qky=>J`THM!v$orI5Ehqd_F4LSwS zxCv`>(QPV+L+`-49CnXR!^V}c9-CCr8Tg+nSf3w1ptJDKhp++f{)f)NxizpM=RKkG zaPU*uh(n&!1-Qct*qA%kQU(0H7B=CRb#xIv^cpth!*A&lJg*)$;|1^NGCcA|m~64h|~&af|c=pr7#OJ%(!a;ntoA?Lb?gaPaoz9{LUe+BBX6_*#!+EZ72Mg59&i{B@eQQhKuN^Jk!^_9O$-H8$_zzx`0H^ShMDYQhJ04Es`9FyU zxF{K(z_U}tN4PK*&fuBpq7g2b0B3PwhG>GPWy0A!eUfPY>TEcNr{{=IU-zfLxm@^* T_zV~3!FfD0Uwna!rU~&sG9+NL delta 4144 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 X^>gr-xDyZX_?xd6iND1z^AP_BCDG76 diff --git a/sha3/tests/data/shake256.blb b/sha3/tests/data/shake256.blb index e2ee0bb6472c3a2df5db43e367fefa4e027e8c35..c5340e26a8c37aae213c650d98122e30c11791e0 100644 GIT binary patch delta 4013 zcmXBVc~sBYAIEX;t7%eAk|ar+v`LesNt-qyX_6!?ut4gocp{zx(q0?>^qo_xYUj{haUT+@d1w6En3nTC^x?u}(+m8ki?+^_%f( z)tJnp78{I(5cxsUL}QFlnyMkbGpxJiZ)F?jnL7BKn#|V}dPXnmZe09wdv$Hikhf}7 ztR-3-53liBRBtb8J}3w@KaAX^tZgYVr*KIbg{nkp2AL)y>7U3JUwpv!)pA$H=G_NY#GE2?> zGZ2PW1rL|hXn0p%b-EnBe0A&myjLpdv=i;DGZVcp42knCw~FxG|Gd>)%k^feShg1$ zqCy>PItU{h&6?LWVLhLiZ+T}oW#D{sgY*1YCGU=+z1^cYxni|uG?#m2Xqw*k9NxPzwe4xu zk985`B2UskgHr59#O9 z3FA>N!qThdx|y?f>mGmA;8Cqzm_LV&-MxI%PM@k@)@tU;ZH{WIz*SiJ6gCao*S8_G+!vO^~lFbGN{g&$$comlr%NfjSRCf%1)) z6=3KsC`cOh?hJVL7SvCA`&k2H`~(Hdu>oCxc>#h#MaY0K2Ou>}P^3%`?+UC57ZfE+A{>EB5rU%S zmB?PpA$tt}9*7?38-N|yVQ-GEogf>Pw`lpg@Q zR6%LdA>AE_PZu;nCQR%FteYq(LvG0Q0ID;EmbT?v*KI=;o=p;zC0|VTM6t~glr8OZ zy?}AKf^y{eJa1rAo}gU0CEo{lkuNAu))w>zx=k09FP&!i0qHZ;S1#nlqOaOtq@*Da z&h|%Zo~@)QKhF(-0_G`c$vz7Lp}7l0E8WxYbq<8$Z?SBVYTA;Q^g*jyqNFPyEDeI} zmMQ5;2kr|^WF>u>xw0R0Y^9QcJh7@jq+6_HDD~C^L(yxLjATs70BCcGlCj*nJ_P!> zUdco@{WcH^E>$v>A!VUZahcH8Yr}0Trq{hzEZeN2ncTefN5sahN*1ztdl(eDL&-{p z?HUAa*rjAGOZS9BANMHP$fmu6p|E{Qb~5}x1hnaZl7rmx#}J4PDLKlPha;ikhn1XU z?9rjn{-a9H^5F3($l!#~(GUL7!n$x!7aL`>ld8H%i}GQpQ_7WGaJ2h`MNS58ggGLSPrco3mvUi3X#VjCO~$NltQIL%{WNbD22&o zPZFUoPn5zXJs%GxKUa#7DKC?tyDya@W#y}%p#F7AQF6eWWay7KO40Jq`kx_(f0bgS z(C_lf)1R<7r&!yxUU{Of&1&zWcZXm zoWZ9JCi3Y~f!1GLcEwt)Pt)LQHdKK1NLyHwqwHxqeBU0{;_9wc2#D2!Hf-7pHe@qTngeg~ zgpGKcH_e56`M}2P=}YtAbH1<%U+|~-aC87{$}xRt0bJV$HsiX!v=E-!54PZG!L$f& zI{>!gb^~cKylEh8&0Bt?C9qEzY{S0cB;gz3upQrupr!E7LtqC^9ZJh!%_!KBwW4V` zToMgC@%k8I*fSP(X77=-0=_j8cHuj5v=Yu34ZCtyJpBqAjD_9Ua2&0IcaMYJ`S=ED8>avuE#XHJEKdD1j0h0O}!5Vk0!jquq*IF!%Nq%wG75gf*u zvuP7-J_inG%XzdJu9yc$@TCQ`1Bhx7Q! z89D}+omHQE0dG1_C%~UBs9YfU=ZpWh^Ceh=U9Qky=>J`THM!v$orI5Ehqd_F4LSwS zxCv`>(QPV+L+`-49CnXR!^V}c9-CCr8Tg+nSf3w1ptJDKhp++f{)f)NxizpM=RKkG zaPU*uh(n&!1-Qct*qA%kQU(0H7B=CRb#xIv^cpth!*A&lJg*)$;|1^NGCcA|m~64h|~&af|c=pr7#OJ%(!a;ntoA?Lb?gaPaoz9{LUe+BBX6_*#!+EZ72Mg59&i{B@eQQhKuN^Jk!^_9O$-H8$_zzx`0H^ShMDYQhJ04Es`9FyU zxF{K(z_U}tN4PK*&fuBpq7g2b0B3PwhG>GPWy0A!eUfPY>TEcNr{{=IU-zfLxm@^* T_zV~3!FfD0Uwna!rU~&sG9+NL delta 4144 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 X^>gr-xDyZX_?xd6iND1z^AP_BCDG76 diff --git a/shabal/CHANGELOG.md b/shabal/CHANGELOG.md index d44eb49f9..02c4ef9bc 100644 --- a/shabal/CHANGELOG.md +++ b/shabal/CHANGELOG.md @@ -5,6 +5,12 @@ 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.4.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.3.0 (2020-06-12) ### Changed - Bump `opaque-debug` to v0.3.0 ([#168]) diff --git a/shabal/Cargo.toml b/shabal/Cargo.toml index a83f02704..e0f0edb9d 100644 --- a/shabal/Cargo.toml +++ b/shabal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shabal" -version = "0.3.0" +version = "0.4.0" # Also update html_root_url in lib.rs when bumping this description = "Shabal hash functions" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" @@ -12,12 +12,10 @@ keywords = ["crypto", "shabal", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = { version = "0.9", features = ["block-padding"] } -opaque-debug = "0.3" +digest = "0.10" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/shabal/examples/shabal256sum.rs b/shabal/examples/shabal256sum.rs deleted file mode 100644 index 5a5186183..000000000 --- a/shabal/examples/shabal256sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use shabal::{Digest, Shabal256}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/shabal/examples/shabal512sum.rs b/shabal/examples/shabal512sum.rs deleted file mode 100644 index b045f6581..000000000 --- a/shabal/examples/shabal512sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use shabal::{Digest, Shabal512}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/shabal/src/consts.rs b/shabal/src/consts.rs index 27fddcdbe..73150fb45 100644 --- a/shabal/src/consts.rs +++ b/shabal/src/consts.rs @@ -1,264 +1,106 @@ -pub const A_INIT_512: [u32; 12] = [ - 0x2072_8DFD, - 0x46C0_BD53, - 0xE782_B699, - 0x5530_4632, - 0x71B4_EF90, - 0x0EA9_E82C, - 0xDBB9_30F1, - 0xFAD0_6B8B, - 0xBE0C_AE40, - 0x8BD1_4410, - 0x76D2_ADAC, - 0x28AC_AB7F, -]; +//! Shabal initialization constants. -pub const B_INIT_512: [u32; 16] = [ - 0xC109_9CB7, - 0x07B3_85F3, - 0xE744_2C26, - 0xCC8A_D640, - 0xEB6F_56C7, - 0x1EA8_1AA9, - 0x73B9_D314, - 0x1DE8_5D08, - 0x4891_0A5A, - 0x893B_22DB, - 0xC5A0_DF44, - 0xBBC4_324E, - 0x72D2_F240, - 0x7594_1D99, - 0x6D8B_DE82, - 0xA1A7_502B, -]; +#[rustfmt::skip] +pub(crate) const INIT_192: ([u32; 12], [u32; 16], [u32; 16]) = ( + [ + 0xFD74_9ED4, 0xB798_E530, 0x3390_4B6F, 0x46BD_A85E, + 0x0769_34B4, 0x454B_4058, 0x77F7_4527, 0xFB4C_F465, + 0x6293_1DA9, 0xE778_C8DB, 0x22B3_998E, 0xAC15_CFB9, + ], + [ + 0x58BC_BAC4, 0xEC47_A08E, 0xAEE9_33B2, 0xDFCB_C824, + 0xA794_4804, 0xBF65_BDB0, 0x5A9D_4502, 0x5997_9AF7, + 0xC5CE_A54E, 0x4B6B_8150, 0x16E7_1909, 0x7D63_2319, + 0x9305_73A0, 0xF34C_63D1, 0xCAF9_14B4, 0xFDD6_612C, + ], + [ + 0x6155_0878, 0x89EF_2B75, 0xA166_0C46, 0x7EF3_855B, + 0x7297_B58C, 0x1BC6_7793, 0x7FB1_C723, 0xB66F_C640, + 0x1A48_B71C, 0xF097_6D17, 0x088C_E80A, 0xA454_EDF3, + 0x1C09_6BF4, 0xAC76_224B, 0x5215_781C, 0xCD5D_2669, + ], +); -pub const C_INIT_512: [u32; 16] = [ - 0xD9BF_68D1, - 0x58BA_D750, - 0x5602_8CB2, - 0x8134_F359, - 0xB5D4_69D8, - 0x941A_8CC2, - 0x418B_2A6E, - 0x0405_2780, - 0x7F07_D787, - 0x5194_358F, - 0x3C60_D665, - 0xBE97_D79A, - 0x950C_3434, - 0xAED9_A06D, - 0x2537_DC8D, - 0x7CDB_5969, -]; +#[rustfmt::skip] +pub(crate) const INIT_224: ([u32; 12], [u32; 16], [u32; 16]) = ( + [ + 0xA520_1467, 0xA9B8_D94A, 0xD4CE_D997, 0x6837_9D7B, + 0xA7FC_73BA, 0xF1A2_546B, 0x6067_82BF, 0xE0BC_FD0F, + 0x2F25_374E, 0x069A_149F, 0x5E2D_FF25, 0xFAEC_F061, + ], + [ + 0xEC99_05D8, 0xF218_50CF, 0xC0A7_46C8, 0x21DA_D498, + 0x3515_6EEB, 0x088C_97F2, 0x2630_3E40, 0x8A2D_4FB5, + 0xFEEE_44B6, 0x8A1E_9573, 0x7B81_111A, 0xCBC1_39F0, + 0xA351_3861, 0x1D2C_362E, 0x918C_580E, 0xB58E_1B9C, + ], + [ + 0xE4B5_73A1, 0x4C1A_0880, 0x1E90_7C51, 0x0480_7EFD, + 0x3AD8_CDE5, 0x16B2_1302, 0x0251_2C53, 0x2204_CB18, + 0x9940_5F2D, 0xE5B6_48A1, 0x70AB_1D43, 0xA10C_25C2, + 0x16F1_AC05, 0x38BB_EB56, 0x9B01_DC60, 0xB109_6D83, + ], +); -pub const A_INIT_384: [u32; 12] = [ - 0xC8FC_A331, - 0xE55C_504E, - 0x003E_BF26, - 0xBB6B_8D83, - 0x7B04_48C1, - 0x41B8_2789, - 0x0A7C_9601, - 0x8D65_9CFF, - 0xB6E2_673E, - 0xCA54_C77B, - 0x1460_FD7E, - 0x3FCB_8F2D, -]; +#[rustfmt::skip] +pub(crate) const INIT_256: ([u32; 12], [u32; 16], [u32; 16]) = ( + [ + 0x52F8_4552, 0xE54B_7999, 0x2D8E_E3EC, 0xB964_5191, + 0xE007_8B86, 0xBB7C_44C9, 0xD2B5_C1CA, 0xB0D2_EB8C, + 0x14CE_5A45, 0x22AF_50DC, 0xEFFD_BC6B, 0xEB21_B74A, + ], + [ + 0xB555_C6EE, 0x3E71_0596, 0xA72A_652F, 0x9301_515F, + 0xDA28_C1FA, 0x696F_D868, 0x9CB6_BF72, 0x0AFE_4002, + 0xA6E0_3615, 0x5138_C1D4, 0xBE21_6306, 0xB38B_8890, + 0x3EA8_B96B, 0x3299_ACE4, 0x3092_4DD4, 0x55CB_34A5, + ], + [ + 0xB405_F031, 0xC423_3EBA, 0xB373_3979, 0xC0DD_9D55, + 0xC51C_28AE, 0xA327_B8E1, 0x56C5_6167, 0xED61_4433, + 0x88B5_9D60, 0x60E2_CEBA, 0x758B_4B8B, 0x83E8_2A7F, + 0xBC96_8828, 0xE6E0_0BF7, 0xBA83_9E55, 0x9B49_1C60, + ], +); -pub const B_INIT_384: [u32; 16] = [ - 0x5272_91FC, - 0x2A16_455F, - 0x78E6_27E5, - 0x944F_169F, - 0x1CA6_F016, - 0xA854_EA25, - 0x8DB9_8ABE, - 0xF2C6_2641, - 0x3011_7DCB, - 0xCF5C_4309, - 0x9371_1A25, - 0xF9F6_71B8, - 0xB01D_2116, - 0x333F_4B89, - 0xB285_D165, - 0x8682_9B36, -]; +#[rustfmt::skip] +pub(crate) const INIT_384: ([u32; 12], [u32; 16], [u32; 16]) = ( + [ + 0xC8FC_A331, 0xE55C_504E, 0x003E_BF26, 0xBB6B_8D83, + 0x7B04_48C1, 0x41B8_2789, 0x0A7C_9601, 0x8D65_9CFF, + 0xB6E2_673E, 0xCA54_C77B, 0x1460_FD7E, 0x3FCB_8F2D, + ], + [ + 0x5272_91FC, 0x2A16_455F, 0x78E6_27E5, 0x944F_169F, + 0x1CA6_F016, 0xA854_EA25, 0x8DB9_8ABE, 0xF2C6_2641, + 0x3011_7DCB, 0xCF5C_4309, 0x9371_1A25, 0xF9F6_71B8, + 0xB01D_2116, 0x333F_4B89, 0xB285_D165, 0x8682_9B36, + ], + [ + 0xF764_B11A, 0x7617_2146, 0xCEF6_934D, 0xC6D2_8399, + 0xFE09_5F61, 0x5E60_18B4, 0x5048_ECF5, 0x5135_3261, + 0x6E6E_36DC, 0x6313_0DAD, 0xA9C6_9BD6, 0x1E90_EA0C, + 0x7C35_073B, 0x28D9_5E6D, 0xAA34_0E0D, 0xCB3D_EE70, + ], +); -pub const C_INIT_384: [u32; 16] = [ - 0xF764_B11A, - 0x7617_2146, - 0xCEF6_934D, - 0xC6D2_8399, - 0xFE09_5F61, - 0x5E60_18B4, - 0x5048_ECF5, - 0x5135_3261, - 0x6E6E_36DC, - 0x6313_0DAD, - 0xA9C6_9BD6, - 0x1E90_EA0C, - 0x7C35_073B, - 0x28D9_5E6D, - 0xAA34_0E0D, - 0xCB3D_EE70, -]; - -pub const A_INIT_256: [u32; 12] = [ - 0x52F8_4552, - 0xE54B_7999, - 0x2D8E_E3EC, - 0xB964_5191, - 0xE007_8B86, - 0xBB7C_44C9, - 0xD2B5_C1CA, - 0xB0D2_EB8C, - 0x14CE_5A45, - 0x22AF_50DC, - 0xEFFD_BC6B, - 0xEB21_B74A, -]; - -pub const B_INIT_256: [u32; 16] = [ - 0xB555_C6EE, - 0x3E71_0596, - 0xA72A_652F, - 0x9301_515F, - 0xDA28_C1FA, - 0x696F_D868, - 0x9CB6_BF72, - 0x0AFE_4002, - 0xA6E0_3615, - 0x5138_C1D4, - 0xBE21_6306, - 0xB38B_8890, - 0x3EA8_B96B, - 0x3299_ACE4, - 0x3092_4DD4, - 0x55CB_34A5, -]; - -pub const C_INIT_256: [u32; 16] = [ - 0xB405_F031, - 0xC423_3EBA, - 0xB373_3979, - 0xC0DD_9D55, - 0xC51C_28AE, - 0xA327_B8E1, - 0x56C5_6167, - 0xED61_4433, - 0x88B5_9D60, - 0x60E2_CEBA, - 0x758B_4B8B, - 0x83E8_2A7F, - 0xBC96_8828, - 0xE6E0_0BF7, - 0xBA83_9E55, - 0x9B49_1C60, -]; - -pub const A_INIT_224: [u32; 12] = [ - 0xA520_1467, - 0xA9B8_D94A, - 0xD4CE_D997, - 0x6837_9D7B, - 0xA7FC_73BA, - 0xF1A2_546B, - 0x6067_82BF, - 0xE0BC_FD0F, - 0x2F25_374E, - 0x069A_149F, - 0x5E2D_FF25, - 0xFAEC_F061, -]; - -pub const B_INIT_224: [u32; 16] = [ - 0xEC99_05D8, - 0xF218_50CF, - 0xC0A7_46C8, - 0x21DA_D498, - 0x3515_6EEB, - 0x088C_97F2, - 0x2630_3E40, - 0x8A2D_4FB5, - 0xFEEE_44B6, - 0x8A1E_9573, - 0x7B81_111A, - 0xCBC1_39F0, - 0xA351_3861, - 0x1D2C_362E, - 0x918C_580E, - 0xB58E_1B9C, -]; - -pub const C_INIT_224: [u32; 16] = [ - 0xE4B5_73A1, - 0x4C1A_0880, - 0x1E90_7C51, - 0x0480_7EFD, - 0x3AD8_CDE5, - 0x16B2_1302, - 0x0251_2C53, - 0x2204_CB18, - 0x9940_5F2D, - 0xE5B6_48A1, - 0x70AB_1D43, - 0xA10C_25C2, - 0x16F1_AC05, - 0x38BB_EB56, - 0x9B01_DC60, - 0xB109_6D83, -]; - -pub const A_INIT_192: [u32; 12] = [ - 0xFD74_9ED4, - 0xB798_E530, - 0x3390_4B6F, - 0x46BD_A85E, - 0x0769_34B4, - 0x454B_4058, - 0x77F7_4527, - 0xFB4C_F465, - 0x6293_1DA9, - 0xE778_C8DB, - 0x22B3_998E, - 0xAC15_CFB9, -]; - -pub const B_INIT_192: [u32; 16] = [ - 0x58BC_BAC4, - 0xEC47_A08E, - 0xAEE9_33B2, - 0xDFCB_C824, - 0xA794_4804, - 0xBF65_BDB0, - 0x5A9D_4502, - 0x5997_9AF7, - 0xC5CE_A54E, - 0x4B6B_8150, - 0x16E7_1909, - 0x7D63_2319, - 0x9305_73A0, - 0xF34C_63D1, - 0xCAF9_14B4, - 0xFDD6_612C, -]; - -pub const C_INIT_192: [u32; 16] = [ - 0x6155_0878, - 0x89EF_2B75, - 0xA166_0C46, - 0x7EF3_855B, - 0x7297_B58C, - 0x1BC6_7793, - 0x7FB1_C723, - 0xB66F_C640, - 0x1A48_B71C, - 0xF097_6D17, - 0x088C_E80A, - 0xA454_EDF3, - 0x1C09_6BF4, - 0xAC76_224B, - 0x5215_781C, - 0xCD5D_2669, -]; +#[rustfmt::skip] +pub(crate) const INIT_512: ([u32; 12], [u32; 16], [u32; 16]) = ( + [ + 0x2072_8DFD, 0x46C0_BD53, 0xE782_B699, 0x5530_4632, + 0x71B4_EF90, 0x0EA9_E82C, 0xDBB9_30F1, 0xFAD0_6B8B, + 0xBE0C_AE40, 0x8BD1_4410, 0x76D2_ADAC, 0x28AC_AB7F, + ], + [ + 0xC109_9CB7, 0x07B3_85F3, 0xE744_2C26, 0xCC8A_D640, + 0xEB6F_56C7, 0x1EA8_1AA9, 0x73B9_D314, 0x1DE8_5D08, + 0x4891_0A5A, 0x893B_22DB, 0xC5A0_DF44, 0xBBC4_324E, + 0x72D2_F240, 0x7594_1D99, 0x6D8B_DE82, 0xA1A7_502B, + ], + [ + 0xD9BF_68D1, 0x58BA_D750, 0x5602_8CB2, 0x8134_F359, + 0xB5D4_69D8, 0x941A_8CC2, 0x418B_2A6E, 0x0405_2780, + 0x7F07_D787, 0x5194_358F, 0x3C60_D665, 0xBE97_D79A, + 0x950C_3434, 0xAED9_A06D, 0x2537_DC8D, 0x7CDB_5969, + ], +); diff --git a/shabal/src/lib.rs b/shabal/src/lib.rs index ecb5e96e1..8cb3ca23a 100644 --- a/shabal/src/lib.rs +++ b/shabal/src/lib.rs @@ -26,7 +26,9 @@ //! // acquire hash digest in the form of GenericArray, //! // which in this case is equivalent to [u8; 32] //! let result = hasher.finalize(); -//! assert_eq!(result[..], hex!("d945dee21ffca23ac232763aa9cac6c15805f144db9d6c97395437e01c8595a8")); +//! assert_eq!(result[..], hex!(" +//! d945dee21ffca23ac232763aa9cac6c15805f144db9d6c97395437e01c8595a8 +//! ")[..]); //! ``` //! //! Also see [RustCrypto/hashes][2] readme. @@ -36,8 +38,9 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/shabal/0.4.0" )] #![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -46,7 +49,107 @@ extern crate std; mod consts; -mod shabal; +mod state; -pub use crate::shabal::{Shabal192, Shabal224, Shabal256, Shabal384, Shabal512}; pub use digest::{self, Digest}; + +use core::fmt; +use digest::{ + block_buffer::Eager, + consts::{U24, U28, U32, U48, U64}, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::typenum::Unsigned, + HashMarker, Output, +}; +use state::{compress, compress_final, BlockSize, EngineState}; + +macro_rules! impl_core { + ($name:ident, $full_name:ident, $init:expr, $out_size:ty, $alg_name:expr) => { + #[doc = "Core "] + #[doc = $alg_name] + #[doc = " hasher state."] + #[derive(Clone)] + pub struct $name { + state: EngineState, + } + + impl HashMarker for $name {} + + impl BlockSizeUser for $name { + type BlockSize = BlockSize; + } + + impl BufferKindUser for $name { + type BufferKind = Eager; + } + + impl OutputSizeUser for $name { + type OutputSize = $out_size; + } + + impl UpdateCore for $name { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + compress(&mut self.state, block) + } + } + } + + impl FixedOutputCore for $name { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let pos = buffer.get_pos(); + let block = buffer.pad_with_zeros(); + block[pos] = 0x80; + compress_final(&mut self.state, &block); + let n = 16 - <$out_size>::USIZE / 4; + let b = &self.state.get_b()[n..]; + for (chunk, v) in out.chunks_exact_mut(4).zip(b.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); + } + } + } + + impl Default for $name { + #[inline] + fn default() -> Self { + Self { + state: EngineState::new($init), + } + } + } + + impl Reset for $name { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } + } + + impl AlgorithmName for $name { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(stringify!($full_name)) + } + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + #[doc = $alg_name] + #[doc = " hasher state."] + pub type $full_name = CoreWrapper<$name>; + }; +} + +impl_core!(Shabal192Core, Shabal192, consts::INIT_192, U24, "Shabal192"); +impl_core!(Shabal224Core, Shabal224, consts::INIT_224, U28, "Shabal224"); +impl_core!(Shabal256Core, Shabal256, consts::INIT_256, U32, "Shabal256"); +impl_core!(Shabal384Core, Shabal384, consts::INIT_384, U48, "Shabal384"); +impl_core!(Shabal512Core, Shabal512, consts::INIT_512, U64, "Shabal512"); diff --git a/shabal/src/shabal.rs b/shabal/src/shabal.rs deleted file mode 100644 index 09d3879be..000000000 --- a/shabal/src/shabal.rs +++ /dev/null @@ -1,513 +0,0 @@ -//! Shabal -use block_buffer::block_padding::Iso7816; -use block_buffer::BlockBuffer; -use core::convert::TryInto; -use digest::{ - consts::{U24, U28, U32, U48, U64}, - generic_array::GenericArray, -}; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; - -use crate::consts::{ - A_INIT_192, A_INIT_224, A_INIT_256, A_INIT_384, A_INIT_512, B_INIT_192, B_INIT_224, B_INIT_256, - B_INIT_384, B_INIT_512, C_INIT_192, C_INIT_224, C_INIT_256, C_INIT_384, C_INIT_512, -}; - -type BlockSize = U64; -type Block = GenericArray; - -/// A structure that represents that state of a digest computation for the -/// Shabal family of digest functions -#[derive(Clone)] -struct EngineState { - a: [u32; 12], - b: [u32; 16], - c: [u32; 16], - whigh: u32, - wlow: u32, -} - -impl EngineState { - fn new(a: &[u32; 12], b: &[u32; 16], c: &[u32; 16]) -> Self { - Self { - a: *a, - b: *b, - c: *c, - wlow: 1, - whigh: 0, - } - } - - fn process_block(&mut self, block: &Block) { - #[allow(unsafe_code)] - let block = unsafe { &*(block.as_ptr() as *const [u8; 64]) }; - compress(self, block); - } - - fn process_final_block(&mut self, block: &Block) { - #[allow(unsafe_code)] - let block = unsafe { &*(block.as_ptr() as *const [u8; 64]) }; - compress_final(self, block); - } - - #[inline] - fn add_m(&mut self, m: &[u32; 16]) { - for (b, m) in self.b.iter_mut().zip(m) { - *b = b.wrapping_add(*m); - } - } - - #[inline] - fn sub_m(&mut self, m: &[u32; 16]) { - for (c, m) in self.c.iter_mut().zip(m) { - *c = c.wrapping_sub(*m); - } - } - - #[inline] - fn inc_w(&mut self) { - self.wlow = self.wlow.wrapping_add(1); - if self.wlow == 0 { - self.whigh = self.whigh.wrapping_add(1); - } - } - - #[inline] - fn xor_w(&mut self) { - self.a[0] ^= self.wlow; - self.a[1] ^= self.whigh; - } - - #[inline] - fn perm(&mut self, m: &[u32; 16]) { - for b in self.b.iter_mut() { - *b = b.wrapping_shl(17) | b.wrapping_shr(15); - } - self.perm_blocks(m); - - let a = &mut self.a; - let c = &self.c; - a[0] = a[0] - .wrapping_add(c[11]) - .wrapping_add(c[15]) - .wrapping_add(c[3]); - a[1] = a[1] - .wrapping_add(c[12]) - .wrapping_add(c[0]) - .wrapping_add(c[4]); - a[2] = a[2] - .wrapping_add(c[13]) - .wrapping_add(c[1]) - .wrapping_add(c[5]); - a[3] = a[3] - .wrapping_add(c[14]) - .wrapping_add(c[2]) - .wrapping_add(c[6]); - a[4] = a[4] - .wrapping_add(c[15]) - .wrapping_add(c[3]) - .wrapping_add(c[7]); - a[5] = a[5] - .wrapping_add(c[0]) - .wrapping_add(c[4]) - .wrapping_add(c[8]); - a[6] = a[6] - .wrapping_add(c[1]) - .wrapping_add(c[5]) - .wrapping_add(c[9]); - a[7] = a[7] - .wrapping_add(c[2]) - .wrapping_add(c[6]) - .wrapping_add(c[10]); - a[8] = a[8] - .wrapping_add(c[3]) - .wrapping_add(c[7]) - .wrapping_add(c[11]); - a[9] = a[9] - .wrapping_add(c[4]) - .wrapping_add(c[8]) - .wrapping_add(c[12]); - a[10] = a[10] - .wrapping_add(c[5]) - .wrapping_add(c[9]) - .wrapping_add(c[13]); - a[11] = a[11] - .wrapping_add(c[6]) - .wrapping_add(c[10]) - .wrapping_add(c[14]); - } - - #[inline] - #[allow(clippy::too_many_arguments)] - fn perm_elt( - &mut self, - xa0: usize, - xa1: usize, - xb0: usize, - xb1: usize, - xb2: usize, - xb3: usize, - xc0: usize, - xm: u32, - ) { - let a = &mut self.a; - let b = &mut self.b; - let xc = self.c[xc0]; - - a[xa0] = (a[xa0] - ^ ((a[xa1].wrapping_shl(15u32) | a[xa1].wrapping_shr(17u32)).wrapping_mul(5u32)) - ^ xc) - .wrapping_mul(3u32) - ^ b[xb1] - ^ (b[xb2] & !b[xb3]) - ^ xm; - b[xb0] = !((b[xb0].wrapping_shl(1) | b[xb0].wrapping_shr(31)) ^ a[xa0]); - } - - #[inline] - fn perm_blocks(&mut self, m: &[u32; 16]) { - self.perm_elt(0, 11, 0, 13, 9, 6, 8, m[0]); - self.perm_elt(1, 0, 1, 14, 10, 7, 7, m[1]); - self.perm_elt(2, 1, 2, 15, 11, 8, 6, m[2]); - self.perm_elt(3, 2, 3, 0, 12, 9, 5, m[3]); - self.perm_elt(4, 3, 4, 1, 13, 10, 4, m[4]); - self.perm_elt(5, 4, 5, 2, 14, 11, 3, m[5]); - self.perm_elt(6, 5, 6, 3, 15, 12, 2, m[6]); - self.perm_elt(7, 6, 7, 4, 0, 13, 1, m[7]); - self.perm_elt(8, 7, 8, 5, 1, 14, 0, m[8]); - self.perm_elt(9, 8, 9, 6, 2, 15, 15, m[9]); - self.perm_elt(10, 9, 10, 7, 3, 0, 14, m[10]); - self.perm_elt(11, 10, 11, 8, 4, 1, 13, m[11]); - self.perm_elt(0, 11, 12, 9, 5, 2, 12, m[12]); - self.perm_elt(1, 0, 13, 10, 6, 3, 11, m[13]); - self.perm_elt(2, 1, 14, 11, 7, 4, 10, m[14]); - self.perm_elt(3, 2, 15, 12, 8, 5, 9, m[15]); - self.perm_elt(4, 3, 0, 13, 9, 6, 8, m[0]); - self.perm_elt(5, 4, 1, 14, 10, 7, 7, m[1]); - self.perm_elt(6, 5, 2, 15, 11, 8, 6, m[2]); - self.perm_elt(7, 6, 3, 0, 12, 9, 5, m[3]); - self.perm_elt(8, 7, 4, 1, 13, 10, 4, m[4]); - self.perm_elt(9, 8, 5, 2, 14, 11, 3, m[5]); - self.perm_elt(10, 9, 6, 3, 15, 12, 2, m[6]); - self.perm_elt(11, 10, 7, 4, 0, 13, 1, m[7]); - self.perm_elt(0, 11, 8, 5, 1, 14, 0, m[8]); - self.perm_elt(1, 0, 9, 6, 2, 15, 15, m[9]); - self.perm_elt(2, 1, 10, 7, 3, 0, 14, m[10]); - self.perm_elt(3, 2, 11, 8, 4, 1, 13, m[11]); - self.perm_elt(4, 3, 12, 9, 5, 2, 12, m[12]); - self.perm_elt(5, 4, 13, 10, 6, 3, 11, m[13]); - self.perm_elt(6, 5, 14, 11, 7, 4, 10, m[14]); - self.perm_elt(7, 6, 15, 12, 8, 5, 9, m[15]); - self.perm_elt(8, 7, 0, 13, 9, 6, 8, m[0]); - self.perm_elt(9, 8, 1, 14, 10, 7, 7, m[1]); - self.perm_elt(10, 9, 2, 15, 11, 8, 6, m[2]); - self.perm_elt(11, 10, 3, 0, 12, 9, 5, m[3]); - self.perm_elt(0, 11, 4, 1, 13, 10, 4, m[4]); - self.perm_elt(1, 0, 5, 2, 14, 11, 3, m[5]); - self.perm_elt(2, 1, 6, 3, 15, 12, 2, m[6]); - self.perm_elt(3, 2, 7, 4, 0, 13, 1, m[7]); - self.perm_elt(4, 3, 8, 5, 1, 14, 0, m[8]); - self.perm_elt(5, 4, 9, 6, 2, 15, 15, m[9]); - self.perm_elt(6, 5, 10, 7, 3, 0, 14, m[10]); - self.perm_elt(7, 6, 11, 8, 4, 1, 13, m[11]); - self.perm_elt(8, 7, 12, 9, 5, 2, 12, m[12]); - self.perm_elt(9, 8, 13, 10, 6, 3, 11, m[13]); - self.perm_elt(10, 9, 14, 11, 7, 4, 10, m[14]); - self.perm_elt(11, 10, 15, 12, 8, 5, 9, m[15]); - } - - #[inline] - fn swap_b_c(&mut self) { - ::core::mem::swap(&mut self.b, &mut self.c); - } -} - -/// A structure that keeps track of the state of the Shabal operation and -/// contains the logic necessary to perform the final calculations. -#[derive(Clone)] -struct Engine256 { - buffer: BlockBuffer, - state: EngineState, -} - -impl Engine256 { - fn new(a: &[u32; 12], b: &[u32; 16], c: &[u32; 16]) -> Engine256 { - Engine256 { - buffer: Default::default(), - state: EngineState::new(a, b, c), - } - } - - fn input(&mut self, input: &[u8]) { - let s = &mut self.state; - self.buffer.input_block(input, |b| s.process_block(b)); - } - - fn finish(&mut self) { - let state = &mut self.state; - let block = self.buffer.pad_with::().unwrap(); - state.process_final_block(block); - } - - fn reset(&mut self, a: &[u32; 12], b: &[u32; 16], c: &[u32; 16]) { - self.state = EngineState::new(a, b, c); - self.buffer.reset(); - } -} - -/// The Shabal hash algorithm with the Shabal-512 initial hash value. -#[derive(Clone)] -pub struct Shabal512 { - engine: Engine256, -} - -impl Default for Shabal512 { - fn default() -> Self { - Self { - engine: Engine256::new(&A_INIT_512, &B_INIT_512, &C_INIT_512), - } - } -} - -impl BlockInput for Shabal512 { - type BlockSize = BlockSize; -} - -impl Update for Shabal512 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.input(input.as_ref()); - } -} - -impl FixedOutputDirty for Shabal512 { - type OutputSize = U64; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let b = &self.engine.state.b[0..16]; - for (chunk, v) in out.chunks_exact_mut(4).zip(b.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - } -} - -impl Reset for Shabal512 { - fn reset(&mut self) { - self.engine.reset(&A_INIT_512, &B_INIT_512, &C_INIT_512); - } -} - -/// The Shabal hash algorithm with the Shabal-384 initial hash value. The result -/// is truncated to 384 bits. -#[derive(Clone)] -pub struct Shabal384 { - engine: Engine256, -} - -impl Default for Shabal384 { - fn default() -> Self { - Self { - engine: Engine256::new(&A_INIT_384, &B_INIT_384, &C_INIT_384), - } - } -} - -impl BlockInput for Shabal384 { - type BlockSize = BlockSize; -} - -impl Update for Shabal384 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.input(input.as_ref()); - } -} - -impl FixedOutputDirty for Shabal384 { - type OutputSize = U48; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let b = &self.engine.state.b[4..16]; - for (chunk, v) in out.chunks_exact_mut(4).zip(b.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - } -} - -impl Reset for Shabal384 { - fn reset(&mut self) { - self.engine.reset(&A_INIT_384, &B_INIT_384, &C_INIT_384); - } -} - -/// The Shabal hash algorithm with the Shabal-256 initial hash value. The result -/// is truncated to 256 bits. -#[derive(Clone)] -pub struct Shabal256 { - engine: Engine256, -} - -impl Default for Shabal256 { - fn default() -> Self { - Self { - engine: Engine256::new(&A_INIT_256, &B_INIT_256, &C_INIT_256), - } - } -} - -impl BlockInput for Shabal256 { - type BlockSize = BlockSize; -} - -impl Update for Shabal256 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.input(input.as_ref()); - } -} - -impl FixedOutputDirty for Shabal256 { - type OutputSize = U32; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let b = &self.engine.state.b[8..16]; - for (chunk, v) in out.chunks_exact_mut(4).zip(b.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - } -} - -impl Reset for Shabal256 { - fn reset(&mut self) { - self.engine.reset(&A_INIT_256, &B_INIT_256, &C_INIT_256); - } -} - -/// The Shabal hash algorithm with the Shabal-224 initial hash value. The result -/// is truncated to 224 bits. -#[derive(Clone)] -pub struct Shabal224 { - engine: Engine256, -} - -impl Default for Shabal224 { - fn default() -> Self { - Self { - engine: Engine256::new(&A_INIT_224, &B_INIT_224, &C_INIT_224), - } - } -} - -impl BlockInput for Shabal224 { - type BlockSize = BlockSize; -} - -impl Update for Shabal224 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.input(input.as_ref()); - } -} - -impl FixedOutputDirty for Shabal224 { - type OutputSize = U28; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let b = &self.engine.state.b[9..16]; - for (chunk, v) in out.chunks_exact_mut(4).zip(b.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - } -} - -impl Reset for Shabal224 { - fn reset(&mut self) { - self.engine.reset(&A_INIT_224, &B_INIT_224, &C_INIT_224); - } -} - -/// The Shabal hash algorithm with the Shabal-192 initial hash value. The result -/// is truncated to 192 bits. -#[derive(Clone)] -pub struct Shabal192 { - engine: Engine256, -} - -impl Default for Shabal192 { - fn default() -> Self { - Self { - engine: Engine256::new(&A_INIT_192, &B_INIT_192, &C_INIT_192), - } - } -} - -impl BlockInput for Shabal192 { - type BlockSize = BlockSize; -} - -impl Update for Shabal192 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.engine.input(input.as_ref()); - } -} - -impl FixedOutputDirty for Shabal192 { - type OutputSize = U24; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - self.engine.finish(); - let b = &self.engine.state.b[10..16]; - for (chunk, v) in out.chunks_exact_mut(4).zip(b.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - } -} - -impl Reset for Shabal192 { - fn reset(&mut self) { - self.engine.reset(&A_INIT_192, &B_INIT_192, &C_INIT_192); - } -} - -opaque_debug::implement!(Shabal512); -opaque_debug::implement!(Shabal384); -opaque_debug::implement!(Shabal256); -opaque_debug::implement!(Shabal224); -opaque_debug::implement!(Shabal192); - -digest::impl_write!(Shabal512); -digest::impl_write!(Shabal384); -digest::impl_write!(Shabal256); -digest::impl_write!(Shabal224); -digest::impl_write!(Shabal192); - -#[inline] -fn read_m(input: &[u8; 64]) -> [u32; 16] { - let mut m = [0u32; 16]; - for (o, chunk) in m.iter_mut().zip(input.chunks_exact(4)) { - *o = u32::from_le_bytes(chunk.try_into().unwrap()); - } - m -} - -fn compress(state: &mut EngineState, input: &[u8; 64]) { - let m = read_m(input); - state.add_m(&m); - state.xor_w(); - state.perm(&m); - state.sub_m(&m); - state.swap_b_c(); - state.inc_w(); -} - -fn compress_final(state: &mut EngineState, input: &[u8; 64]) { - let m = read_m(input); - state.add_m(&m); - state.xor_w(); - state.perm(&m); - for _ in 0..3 { - state.swap_b_c(); - state.xor_w(); - state.perm(&m); - } -} diff --git a/shabal/src/state.rs b/shabal/src/state.rs new file mode 100644 index 000000000..1d26a3fa8 --- /dev/null +++ b/shabal/src/state.rs @@ -0,0 +1,226 @@ +use core::{convert::TryInto, mem}; +use digest::{consts::U64, generic_array::GenericArray}; + +pub(crate) type BlockSize = U64; +pub(crate) type Block = GenericArray; + +/// Inner state of Shabal hash functions. +#[derive(Clone)] +pub(crate) struct EngineState { + a: [u32; 12], + b: [u32; 16], + c: [u32; 16], + whigh: u32, + wlow: u32, +} + +impl EngineState { + pub(crate) const fn new((a, b, c): ([u32; 12], [u32; 16], [u32; 16])) -> Self { + let (wlow, whigh) = (1, 0); + Self { + a, + b, + c, + wlow, + whigh, + } + } + + pub(crate) fn get_b(&self) -> &[u32; 16] { + &self.b + } + + fn add_m(&mut self, m: &[u32; 16]) { + for (b, m) in self.b.iter_mut().zip(m) { + *b = b.wrapping_add(*m); + } + } + + fn sub_m(&mut self, m: &[u32; 16]) { + for (c, m) in self.c.iter_mut().zip(m) { + *c = c.wrapping_sub(*m); + } + } + + fn inc_w(&mut self) { + self.wlow = self.wlow.wrapping_add(1); + if self.wlow == 0 { + self.whigh = self.whigh.wrapping_add(1); + } + } + + fn xor_w(&mut self) { + self.a[0] ^= self.wlow; + self.a[1] ^= self.whigh; + } + + fn perm(&mut self, m: &[u32; 16]) { + for b in self.b.iter_mut() { + *b = b.wrapping_shl(17) | b.wrapping_shr(15); + } + self.perm_blocks(m); + + let a = &mut self.a; + let c = &self.c; + a[0] = a[0] + .wrapping_add(c[11]) + .wrapping_add(c[15]) + .wrapping_add(c[3]); + a[1] = a[1] + .wrapping_add(c[12]) + .wrapping_add(c[0]) + .wrapping_add(c[4]); + a[2] = a[2] + .wrapping_add(c[13]) + .wrapping_add(c[1]) + .wrapping_add(c[5]); + a[3] = a[3] + .wrapping_add(c[14]) + .wrapping_add(c[2]) + .wrapping_add(c[6]); + a[4] = a[4] + .wrapping_add(c[15]) + .wrapping_add(c[3]) + .wrapping_add(c[7]); + a[5] = a[5] + .wrapping_add(c[0]) + .wrapping_add(c[4]) + .wrapping_add(c[8]); + a[6] = a[6] + .wrapping_add(c[1]) + .wrapping_add(c[5]) + .wrapping_add(c[9]); + a[7] = a[7] + .wrapping_add(c[2]) + .wrapping_add(c[6]) + .wrapping_add(c[10]); + a[8] = a[8] + .wrapping_add(c[3]) + .wrapping_add(c[7]) + .wrapping_add(c[11]); + a[9] = a[9] + .wrapping_add(c[4]) + .wrapping_add(c[8]) + .wrapping_add(c[12]); + a[10] = a[10] + .wrapping_add(c[5]) + .wrapping_add(c[9]) + .wrapping_add(c[13]); + a[11] = a[11] + .wrapping_add(c[6]) + .wrapping_add(c[10]) + .wrapping_add(c[14]); + } + + #[allow(clippy::too_many_arguments)] + fn perm_elt( + &mut self, + xa0: usize, + xa1: usize, + xb0: usize, + xb1: usize, + xb2: usize, + xb3: usize, + xc0: usize, + xm: u32, + ) { + let a = &mut self.a; + let b = &mut self.b; + let xc = self.c[xc0]; + + a[xa0] = (a[xa0] + ^ ((a[xa1].wrapping_shl(15u32) | a[xa1].wrapping_shr(17u32)).wrapping_mul(5u32)) + ^ xc) + .wrapping_mul(3u32) + ^ b[xb1] + ^ (b[xb2] & !b[xb3]) + ^ xm; + b[xb0] = !((b[xb0].wrapping_shl(1) | b[xb0].wrapping_shr(31)) ^ a[xa0]); + } + + fn perm_blocks(&mut self, m: &[u32; 16]) { + self.perm_elt(0, 11, 0, 13, 9, 6, 8, m[0]); + self.perm_elt(1, 0, 1, 14, 10, 7, 7, m[1]); + self.perm_elt(2, 1, 2, 15, 11, 8, 6, m[2]); + self.perm_elt(3, 2, 3, 0, 12, 9, 5, m[3]); + self.perm_elt(4, 3, 4, 1, 13, 10, 4, m[4]); + self.perm_elt(5, 4, 5, 2, 14, 11, 3, m[5]); + self.perm_elt(6, 5, 6, 3, 15, 12, 2, m[6]); + self.perm_elt(7, 6, 7, 4, 0, 13, 1, m[7]); + self.perm_elt(8, 7, 8, 5, 1, 14, 0, m[8]); + self.perm_elt(9, 8, 9, 6, 2, 15, 15, m[9]); + self.perm_elt(10, 9, 10, 7, 3, 0, 14, m[10]); + self.perm_elt(11, 10, 11, 8, 4, 1, 13, m[11]); + self.perm_elt(0, 11, 12, 9, 5, 2, 12, m[12]); + self.perm_elt(1, 0, 13, 10, 6, 3, 11, m[13]); + self.perm_elt(2, 1, 14, 11, 7, 4, 10, m[14]); + self.perm_elt(3, 2, 15, 12, 8, 5, 9, m[15]); + self.perm_elt(4, 3, 0, 13, 9, 6, 8, m[0]); + self.perm_elt(5, 4, 1, 14, 10, 7, 7, m[1]); + self.perm_elt(6, 5, 2, 15, 11, 8, 6, m[2]); + self.perm_elt(7, 6, 3, 0, 12, 9, 5, m[3]); + self.perm_elt(8, 7, 4, 1, 13, 10, 4, m[4]); + self.perm_elt(9, 8, 5, 2, 14, 11, 3, m[5]); + self.perm_elt(10, 9, 6, 3, 15, 12, 2, m[6]); + self.perm_elt(11, 10, 7, 4, 0, 13, 1, m[7]); + self.perm_elt(0, 11, 8, 5, 1, 14, 0, m[8]); + self.perm_elt(1, 0, 9, 6, 2, 15, 15, m[9]); + self.perm_elt(2, 1, 10, 7, 3, 0, 14, m[10]); + self.perm_elt(3, 2, 11, 8, 4, 1, 13, m[11]); + self.perm_elt(4, 3, 12, 9, 5, 2, 12, m[12]); + self.perm_elt(5, 4, 13, 10, 6, 3, 11, m[13]); + self.perm_elt(6, 5, 14, 11, 7, 4, 10, m[14]); + self.perm_elt(7, 6, 15, 12, 8, 5, 9, m[15]); + self.perm_elt(8, 7, 0, 13, 9, 6, 8, m[0]); + self.perm_elt(9, 8, 1, 14, 10, 7, 7, m[1]); + self.perm_elt(10, 9, 2, 15, 11, 8, 6, m[2]); + self.perm_elt(11, 10, 3, 0, 12, 9, 5, m[3]); + self.perm_elt(0, 11, 4, 1, 13, 10, 4, m[4]); + self.perm_elt(1, 0, 5, 2, 14, 11, 3, m[5]); + self.perm_elt(2, 1, 6, 3, 15, 12, 2, m[6]); + self.perm_elt(3, 2, 7, 4, 0, 13, 1, m[7]); + self.perm_elt(4, 3, 8, 5, 1, 14, 0, m[8]); + self.perm_elt(5, 4, 9, 6, 2, 15, 15, m[9]); + self.perm_elt(6, 5, 10, 7, 3, 0, 14, m[10]); + self.perm_elt(7, 6, 11, 8, 4, 1, 13, m[11]); + self.perm_elt(8, 7, 12, 9, 5, 2, 12, m[12]); + self.perm_elt(9, 8, 13, 10, 6, 3, 11, m[13]); + self.perm_elt(10, 9, 14, 11, 7, 4, 10, m[14]); + self.perm_elt(11, 10, 15, 12, 8, 5, 9, m[15]); + } + + fn swap_b_c(&mut self) { + mem::swap(&mut self.b, &mut self.c); + } +} + +#[inline] +fn read_m(input: &Block) -> [u32; 16] { + let mut m = [0u32; 16]; + for (o, chunk) in m.iter_mut().zip(input.chunks_exact(4)) { + *o = u32::from_le_bytes(chunk.try_into().unwrap()); + } + m +} + +pub(crate) fn compress(state: &mut EngineState, input: &Block) { + let m = read_m(input); + state.add_m(&m); + state.xor_w(); + state.perm(&m); + state.sub_m(&m); + state.swap_b_c(); + state.inc_w(); +} + +pub(crate) fn compress_final(state: &mut EngineState, input: &Block) { + let m = read_m(input); + state.add_m(&m); + state.xor_w(); + state.perm(&m); + for _ in 0..3 { + state.swap_b_c(); + state.xor_w(); + state.perm(&m); + } +} diff --git a/shabal/tests/data/shabal192.blb b/shabal/tests/data/shabal192.blb index b205df8a2bb62fe25b9b2e135b42c1cce52a9218..7eb0a87195b0ad1b20304e2a6a003903f21a2f79 100644 GIT binary patch delta 760 zcmZn=XcCBKU`jOT*F1UtVUhhlwy)nWYp!np@xF24+0(3<|5y@}3{u#NiWBOlD|Wgl zT5#F5`yRUd$h&z`{A;$vq-29XeAT8I$8No!{CwvUzvkjurR&s{juqOx-~dXd7)(r* zVCMp{QVk|HNO16gnP~=!Jk7s8v`%?%6j~)S#qmL@NswVhnk^GYD^7&w)4!Mq0Ut@xq!*a%s^keWPkk4MW%V@7j^E}dLa1dkArMW6hncT zUur>OjzU3EYHns~kwSTXo_dKwQEG8!dY+!aEpO5sgP<$W)`nlc;2CQGw;OBw7t*&+Xa{raWi z^Qy$XLrAM|c!R*?zbqb72F5~l5B3NgDf%Cp9W=pq z;gRd-(9e3P( zUus*)#EpA8&a~?AK7DKu$p)5AlUS*2VOB7M>B+7c5=T>VxerHO*>7)hZQnh1hbXucE2pt|2FZ*nGHFblWiF_r6h`OOnCGEux53}KmMvey;|(E%EAmE zzhp1BoZP@@DJ7A)e(BVc@{>b;gsT2ik`HrG(UGmJ6=4z7ntYj2i&0|oKSl{g%gN$Q zmOyqOlLVvHw(~-KMt}jQ49srllL)6OG&H}n`PQM z;a?tK{nWFd8YQiW@x9;EPP zTTTvS2D+(e%}2w(|NpPuo&BvtD)#w4g_*ZJPEERbFkBE9#Rs*wUXF05P2pf@>| zRS&4NhgE{nZSpc!Hz4~hknJ*=oy`Tv_F3Jy;F>{`zlpI-d=l1W- Gcbowr(KCzy diff --git a/shabal/tests/data/shabal224.blb b/shabal/tests/data/shabal224.blb index 29de7decf9d77fecfe3844450c1a4527227c2867..cdcb37f5f4fe19d5ea8ba0530baa34b6575c55e8 100644 GIT binary patch delta 577 zcmew%@JoP&fho~qB9{ycOJb76L@gOsw#1}li;3PcY#cyFip9iS8FnrZE7fA+1Q}f( zFf+|U_P6+-IVu?v8i`XXLfL2Bd~dNZ-#lh!!BN=^Z9a&abc=~MWw->OoD7SJ|7DDY zV7yEVG5@ly8AT~awmBaOyLehN>_ClvMeV1G0HFoP0nW2l(Q(e zx^a2xVv+B5|Ed((x=vl@i(Pq8{j`U`R@N)_MUyu%S~6Npegjk{M1W>&f3sAGz0|DiDfi{njUbN`#lLo`?6=V9UtOVYF!=(D1W^4;78%B*$!x5KK(+-dP_Mw`P*x8h zXCA8zW6b2;ta?E9E06@wWOg<;Ajgjl$l;ir&E^8+Y+#dNbeMdWO##S$2a+(D%*`Gl zZy_>e`!p>oI|pdoux*2ktdw&%gFk_Hgn{|Ck+R ztZyajmvl4-ROZb1lWaA45t9{A`CXuL>B+yCq~&C|!#|2Gj@J-rRd~&Q&~2s>Pi5FU z{pie6`)49^oF|(wI|G$hFoR5=%4`W_p9iudCckBlkdrA4{&X;&@koB(iwvX0C?~_#lIb${>gjDqe@@W1SlwQ5P*_y0Vm&u=a;fiGkIBKTzz~`| zhgF7AZ}Lu7Js|r9knJ{^jm-_n_GOb{beWvZ<^r-6$X1wqmJJxhlivZ^5tDh?fesd# zvVEIK{_p(O*1A}iH(Dz;O;G$*EXdSvm B`40d9 diff --git a/shabal/tests/data/shabal256.blb b/shabal/tests/data/shabal256.blb index e978cb199206b9af4844fdbc52ef6102e2423c19..643aea8b17241dbc44f58f19dade3b307148d97e 100644 GIT binary patch delta 453 zcmew$_(_n3fho~pB9{USOJb74L_Gy|S)y=0oetYmLDNYf%dWxYr^8NnH zqD>Pt*FQRK&%(k1RFvW{u~LDZ3&cuwn7BZJg9pq^bC`HSfs+ryPIs92QGrVU%E@q; zEX}CEEd=9cI!tzBRL~WH^Rpa6uGOiyRMu3*-xXPrVtDvA)6I7Oyl*+P^!CnWXU{h) z2%0>ZQIpYO@?J&-#-hph7%hQp2_^-`kja)zT0nLRkX{$d+bS zU^JU-!z>MCM=&ceHLy*tWOfE}_5vk<1~G#TVgX7ROtxf+Pvp_*QM38v>=Vwh!4qs^8^k7WX7L6Z@SjD2(O|Lys|1j3$*RDZG&zdZ5XkOf z1sWzWc`d64kn;^F5i?nwO%KR+V*^U?OipKW19H}ZI2@DDv$+5{BJ2u4(iBXFv4h=G h&K?02x&Y)fa!mfn-U8&5aVRhrOrFkR0g~WQ000+Mkoo`s delta 556 zcmew)_(6~>DJMTEsnU=!QDGvB0t-`OlEOp{1y<(7q-2GOz6!c5Kt_s!Xy=29kDIhr z8Q%Px5as(V$;abbob#vu$M>EWnx)-4^(iYzRjR_oSqg@1U}l=aOI87$s?Ob#zrOYT z3l$WrWq<$8jxYMg!!t5%d6vyD53@tmr7KK)t-!?rAOjo7H8(T0 zNTEDGPrXE;D782XLQ zCCtu1gLW{3EV#)Gbd&z$NuE6^@rS=XS2JCbaZI$4eM9JpyFo>18*jaI+AniAVzMbq z1W-#Kivpwf-s|1j3#;U+*I60iv5XkNXvOOlRX7vEFzW~{KlSSF| zfNU2w1xB~YX>4vl_F5p@W%7A87a&`NT>(g%g2^x-88Nwn9c0%N_M=J_z+?@j0YrO!k^aw*$(garUsQOx`R diff --git a/shabal/tests/data/shabal384.blb b/shabal/tests/data/shabal384.blb index 266410a76fe307f804892da16a1d49e63d021db9..3dcbf4062ffacea0ba464d5db01ac460a36c1844 100644 GIT binary patch delta 373 zcmX}lzbl1N9LI6zJm)#jc^(hlmn@Vi?OcZBZ4T1axw@I|I delta 393 zcmX}mJxjv?5C&i_-$|W>LP3;(gSOc6c56G@QVIoK6uXEd8f&Cq)S@^FE$A5TAE@Bw zqJubzzd!^Boty+`(aFJ!U)%G(9Cvr0yh}QMtLyvwdGZix&=k){RDiB}{yL&I3{9|s z=me%7D?s!F%lPIdc${FHKcNY(6CCR|ZGlIGg#8yo@C{+i`On+nPXeVmtE36MqJWBg zs1(Jw;tanj8S#`F_ls)WABjtRt(L^^Dkdiuf}YoMd;Opt27Pz0+nE`-{a`0-c5>i( z4OHfVR+i~2agkrOc+0d7YVfk&5TA?d{H)98JZFGXylSMxyW%{b8F}%exW);yCSEc@ zIUbog@uj%RFJ@JowLleKvnt|KvC9vZEB+8Sc-D?@9oV2DU)V!&!2uOGbPD2Q2VXIv BZ&d&Q diff --git a/shabal/tests/data/shabal512.blb b/shabal/tests/data/shabal512.blb index d874809f72a15122e6fdebfd9181af170f57daab..2d57688f9b83a9f8a4fcf2d424336c5a957d3359 100644 GIT binary patch delta 404 zcmX}lPb&pc7zXe;XXebDIWu%aa$|8f6iK7Ru+Up{Q_4aX7V0+R&%Kno_eQz9QN93g zS>I0}HtH^X2eFWB?d>Qc?>qkNp5ODFw{uy%EhRXh+8w!HyHhmhjCH^~^+^sa#WdWm(dL2Tfgo?wjlG=*68%d88Q q#utB)HDy2m9-0#4+|U%^gUNr60+7cV8^H;0uK|cU&V(_e9>O;P&UC2& delta 394 zcmX}lze@sf7{_s*`+Z+;4UC8m8bS%dO(p0hVB-Lu2+2 zv<1=9<{Y#&HU~XtKepHV!^8Lcx_rN^!frnduksWiHeqN%h"] +authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2018" @@ -12,12 +12,10 @@ keywords = ["crypto", "sm3", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = "0.9" -opaque-debug = "0.3" +digest = "0.10" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/sm3/LICENSE-MIT b/sm3/LICENSE-MIT index 78d6d79a4..c869ada57 100644 --- a/sm3/LICENSE-MIT +++ b/sm3/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2016 Artyom Pavlov +Copyright (c) 2021 The RustCrypto Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/sm3/examples/sm3sum.rs b/sm3/examples/sm3sum.rs deleted file mode 100644 index 94ec40810..000000000 --- a/sm3/examples/sm3sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use sm3::{Digest, Sm3}; -use std::env; -use std::fs; -use std::io::{self, Read}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/sm3/src/sm3.rs b/sm3/src/compress.rs similarity index 81% rename from sm3/src/sm3.rs rename to sm3/src/compress.rs index 42be5cf5c..731efb3c6 100644 --- a/sm3/src/sm3.rs +++ b/sm3/src/compress.rs @@ -1,67 +1,6 @@ -//! SM3 #![allow(clippy::many_single_char_names, clippy::too_many_arguments)] -use crate::consts::{SM3_IV, T32}; -use block_buffer::BlockBuffer; +use crate::{consts::T32, Block, Sm3Core}; use core::convert::TryInto; -use core::slice::from_ref; -use digest::consts::{U32, U64}; -use digest::generic_array::GenericArray; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; - -/// The SM3 hash algorithm with the SM3 initial hash value. -#[derive(Clone)] -pub struct Sm3 { - len: u64, - buffer: BlockBuffer, - state: [u32; 8], -} - -impl Default for Sm3 { - fn default() -> Self { - Sm3 { - len: 0, - buffer: Default::default(), - state: SM3_IV, - } - } -} - -impl BlockInput for Sm3 { - type BlockSize = U64; -} - -impl Update for Sm3 { - fn update(&mut self, input: impl AsRef<[u8]>) { - self.len += (input.as_ref().len() as u64) << 3; - let s = &mut self.state; - self.buffer - .input_blocks(input.as_ref(), |b| sm3_compress(s, b)); - } -} - -impl FixedOutputDirty for Sm3 { - type OutputSize = U32; - - fn finalize_into_dirty(&mut self, out: &mut digest::Output) { - let s = &mut self.state; - let l = self.len; - self.buffer - .len64_padding_be(l, |b| sm3_compress(s, from_ref(b))); - - let s = self.state; - for (chunk, v) in out.chunks_exact_mut(4).zip(s.iter()) { - chunk.copy_from_slice(&v.to_be_bytes()); - } - } -} - -impl Reset for Sm3 { - fn reset(&mut self) { - self.len = 0; - self.buffer.reset(); - self.state = SM3_IV; - } -} #[inline(always)] fn ff1(x: u32, y: u32, z: u32) -> u32 { @@ -209,7 +148,7 @@ macro_rules! R2 { }}; } -fn sm3_digest_block_u32(state: &mut [u32; 8], block: &[u32; 16]) { +fn compress_u32(state: &mut [u32; 8], block: &[u32; 16]) { let mut x: [u32; 16] = *block; let mut a = state[0]; @@ -296,15 +235,12 @@ fn sm3_digest_block_u32(state: &mut [u32; 8], block: &[u32; 16]) { state[7] ^= h; } -pub fn sm3_compress(state: &mut [u32; 8], blocks: &[GenericArray]) { - #[allow(unsafe_code)] - let blocks = unsafe { &*(blocks as *const _ as *const [[u8; 64]]) }; - - let mut w = [0u32; 16]; +pub(crate) fn compress(state: &mut [u32; 8], blocks: &[Block]) { for block in blocks { + let mut w = [0u32; 16]; for (o, chunk) in w.iter_mut().zip(block.chunks_exact(4)) { *o = u32::from_be_bytes(chunk.try_into().unwrap()); } - sm3_digest_block_u32(state, &w); + compress_u32(state, &w); } } diff --git a/sm3/src/consts.rs b/sm3/src/consts.rs index 1e997c221..792bdfbea 100644 --- a/sm3/src/consts.rs +++ b/sm3/src/consts.rs @@ -1,6 +1,6 @@ #![allow(clippy::unreadable_literal)] -pub const T32: [u32; 64] = [ +pub(crate) const T32: [u32; 64] = [ 0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb, 0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc, 0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce, 0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6, 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c, 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce, @@ -11,6 +11,6 @@ pub const T32: [u32; 64] = [ 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec, 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5, ]; -pub static SM3_IV: [u32; 8] = [ +pub(crate) static H0: [u32; 8] = [ 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e, ]; diff --git a/sm3/src/lib.rs b/sm3/src/lib.rs index ca9001d60..95062fa46 100644 --- a/sm3/src/lib.rs +++ b/sm3/src/lib.rs @@ -30,25 +30,102 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/sm3/0.4.0" )] #![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "std")] -extern crate std; +pub use digest::{self, Digest}; + +use core::{fmt, slice::from_ref}; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::typenum::{Unsigned, U32, U64}, + HashMarker, Output, +}; +mod compress; mod consts; -mod sm3; -pub use digest::{self, Digest}; +use compress::compress; + +/// Core SM3 hasher state. +#[derive(Clone)] +pub struct Sm3Core { + block_len: u64, + h: [u32; 8], +} + +impl HashMarker for Sm3Core {} + +impl BlockSizeUser for Sm3Core { + type BlockSize = U64; +} + +impl BufferKindUser for Sm3Core { + type BufferKind = Eager; +} + +impl OutputSizeUser for Sm3Core { + type OutputSize = U32; +} + +impl UpdateCore for Sm3Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.block_len += blocks.len() as u64; + compress(&mut self.h, blocks); + } +} + +impl FixedOutputCore for Sm3Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bs = Self::BlockSize::U64; + let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len); + + let mut h = self.h; + buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b))); + for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) { + chunk.copy_from_slice(&v.to_be_bytes()); + } + } +} + +impl Default for Sm3Core { + #[inline] + fn default() -> Self { + Self { + h: consts::H0, + block_len: 0, + } + } +} -#[cfg(feature = "std")] -use digest::Update; +impl Reset for Sm3Core { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } +} -pub use crate::sm3::Sm3; +impl AlgorithmName for Sm3Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Sm3") + } +} -opaque_debug::implement!(Sm3); +impl fmt::Debug for Sm3Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Sm3Core { ... }") + } +} -digest::impl_write!(Sm3); +/// Sm3 hasher state. +pub type Sm3 = CoreWrapper; diff --git a/sm3/tests/data/sm3.blb b/sm3/tests/data/sm3.blb index 21d6e4b595eb1a3e44f5db8cacb59a27ce290881..345e7cff28af718471f159eb42cc41689416ca9c 100644 GIT binary patch delta 101 zcmey%xP^(Cfx%%SrvfWmVp6ihL_GyN6CficH7z|OGb=kMH!r`Su&B7Cw5+_MvdUox z|H~@hMP7f@OH;mOna=y-;HGt{_e^f`+D*PO3d=;NHZV-|cVKjwI6;9iY~n_3AnUFI E0Al|qF#rGn delta 78 zcmV-U0I~nH0{sClVr*|>VtFwDAR4kAgH_L=e~w`pNHORdk0QRv$0+{$bbin^>rjHK kD+6I-V<3?zAOS#;jyRE?2mv6G#~=YKk?1P{Ad?gUAmbYy%m4rY diff --git a/sm3/tests/data/sm3_one_million_a.bin b/sm3/tests/data/sm3_one_million_a.bin deleted file mode 100644 index bbc7bd22d..000000000 --- a/sm3/tests/data/sm3_one_million_a.bin +++ /dev/null @@ -1,2 +0,0 @@ -Ȫ)U@)1* -%z:s+; \ No newline at end of file diff --git a/sm3/tests/lib.rs b/sm3/tests/lib.rs index 100ca6754..df5a9056d 100644 --- a/sm3/tests/lib.rs +++ b/sm3/tests/lib.rs @@ -1,28 +1,16 @@ use digest::dev::{digest_test, one_million_a}; use digest::new_test; +use hex_literal::hex; +use sm3::Sm3; -new_test!(sm3_main, "sm3", sm3::Sm3, digest_test); +new_test!(sm3_main, "sm3", Sm3, digest_test); -#[test] -fn sm3_1million_a() { - let output = include_bytes!("data/sm3_one_million_a.bin"); - one_million_a::(output); -} - -/// Test vectors from libgcrypt #[test] #[rustfmt::skip] -fn sm3_tests() { - use digest::Digest; - use hex_literal::hex; - - let hash = &mut sm3::Sm3::new(); - - hash.update(b"abc"); - assert_eq!(hash.finalize_reset().as_slice(), - hex!("66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0")); - - hash.update(b"abcdefghijklmnopqrstuvwxyz"); - assert_eq!(hash.finalize_reset().as_slice(), - hex!("b80fe97a4da24afc277564f66a359ef440462ad28dcc6d63adb24d5c20a61595")); +fn sm3_1million_a() { + let expected = hex!(" + c8aaf89429554029e231941a2acc0ad6 + 1ff2a5acd8fadd25847a3a732b3b02c3 + "); + one_million_a::(&expected); } diff --git a/streebog/CHANGELOG.md b/streebog/CHANGELOG.md index da35bcac0..45109f417 100644 --- a/streebog/CHANGELOG.md +++ b/streebog/CHANGELOG.md @@ -5,6 +5,12 @@ 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.10.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.9.2 (2020-08-13) ### Changed - Documentation update ([#185]) diff --git a/streebog/Cargo.toml b/streebog/Cargo.toml index 7d8436b82..ade2b10d9 100644 --- a/streebog/Cargo.toml +++ b/streebog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "streebog" -version = "0.9.2" +version = "0.10.0" # Also update html_root_url in lib.rs when bumping this description = "Streebog (GOST R 34.11-2012) hash function" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" @@ -12,12 +12,10 @@ keywords = ["crypto", "streebog", "gost", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = { version = "0.9", features = ["block-padding"] } -opaque-debug = "0.3" +digest = "0.10" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/streebog/examples/streebog256sum.rs b/streebog/examples/streebog256sum.rs deleted file mode 100644 index 4973d262a..000000000 --- a/streebog/examples/streebog256sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use std::env; -use std::fs; -use std::io::{self, Read}; -use streebog::{Digest, Streebog256}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/streebog/examples/streebog512sum.rs b/streebog/examples/streebog512sum.rs deleted file mode 100644 index e2130ff63..000000000 --- a/streebog/examples/streebog512sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use std::env; -use std::fs; -use std::io::{self, Read}; -use streebog::{Digest, Streebog512}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh = D::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/streebog/src/lib.rs b/streebog/src/lib.rs index 53fc7eb94..75c840d4e 100644 --- a/streebog/src/lib.rs +++ b/streebog/src/lib.rs @@ -2,34 +2,29 @@ //! in GOST R 34.11-2012. //! //! # Usage -//! Hasher functionality is expressed via traits defined in the [`digest`] -//! crate. -//! //! ```rust //! use streebog::{Digest, Streebog256, Streebog512}; //! use hex_literal::hex; //! -//! // create a hasher object, to use it do not forget to import `Digest` trait +//! // create Streebog256 hasher state //! let mut hasher = Streebog256::new(); //! // write input message -//! hasher.update(b"my"); -//! hasher.update(b" "); -//! hasher.update(b"message"); +//! hasher.update("The quick brown fox jumps over the lazy dog"); //! // read hash digest (it will consume hasher) //! let result = hasher.finalize(); //! //! assert_eq!(result[..], hex!(" -//! a47752ba9491bd1d52dd5dcea6d8c08e9b1ee70c42a2fc3e0d1a2852468c1329 +//! 3e7dea7f2384b6c5a3d0e24aaa29c05e89ddd762145030ec22c71a6db8b2c1f4 //! ")[..]); //! //! // same for Streebog512 //! let mut hasher = Streebog512::new(); -//! hasher.update(b"my message"); +//! hasher.update("The quick brown fox jumps over the lazy dog."); //! let result = hasher.finalize(); //! //! assert_eq!(result[..], hex!(" -//! c40cc26c37a683c74459820d884b766d9c96697a8d168c0272db8f4ecca2935b -//! 4164ede98fc9c8d2bafb1249b238676c81f5b97f98c393b99fdf2dc961391484 +//! fe0c42f267d921f940faa72bd9fcf84f9f1bd7e9d055e9816e4c2ace1ec83be8 +//! 2d2957cd59b86e123d8f5adee80b3ca08a017599a9fc1a14d940cf87c77df070 //! ")[..]); //! ``` //! @@ -40,10 +35,10 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/streebog/0.10.0" )] -#![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "std")] @@ -51,22 +46,10 @@ extern crate std; mod consts; mod streebog; +mod streebog256; +mod streebog512; mod table; -use digest::consts::{U32, U64}; pub use digest::{self, Digest}; - -#[cfg(feature = "std")] -use digest::Update; - -/// Streebog-256 cryptographic hash function -pub type Streebog256 = streebog::Streebog; - -/// Streebog-512 cryptographic hash function -pub type Streebog512 = streebog::Streebog; - -opaque_debug::implement!(Streebog512); -opaque_debug::implement!(Streebog256); - -digest::impl_write!(Streebog512); -digest::impl_write!(Streebog256); +pub use streebog256::{Streebog256, Streebog256Core}; +pub use streebog512::{Streebog512, Streebog512Core}; diff --git a/streebog/src/streebog.rs b/streebog/src/streebog.rs index 9856d6621..18973d49d 100644 --- a/streebog/src/streebog.rs +++ b/streebog/src/streebog.rs @@ -1,8 +1,5 @@ -use block_buffer::{block_padding::ZeroPadding, BlockBuffer}; -use core::marker::PhantomData; -use digest::consts::U64; -use digest::generic_array::{ArrayLength, GenericArray}; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; +use core::convert::TryInto; +use digest::{block_buffer::EagerBuffer, consts::U64, generic_array::GenericArray}; use crate::consts::{BLOCK_SIZE, C}; use crate::table::SHUFFLED_LIN_TABLE; @@ -10,10 +7,10 @@ use crate::table::SHUFFLED_LIN_TABLE; type Block = [u8; 64]; #[derive(Copy, Clone)] -struct StreebogState { - h: Block, - n: Block, - sigma: Block, +pub(crate) struct StreebogState { + pub(crate) h: Block, + pub(crate) n: [u64; 8], + pub(crate) sigma: [u64; 8], } #[inline(always)] @@ -33,9 +30,7 @@ fn lps(h: &mut Block, n: &Block) { } } - for (chunk, v) in h.chunks_exact_mut(8).zip(buf.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } + *h = to_bytes(&buf); } impl StreebogState { @@ -60,126 +55,75 @@ impl StreebogState { } fn update_sigma(&mut self, m: &Block) { + let t = from_bytes(m); let mut carry = 0; - for (a, b) in self.sigma.iter_mut().zip(m.iter()) { - carry = (*a as u16) + (*b as u16) + (carry >> 8); - *a = (carry & 0xFF) as u8; - } + adc(&mut self.sigma[0], t[0], &mut carry); + adc(&mut self.sigma[1], t[1], &mut carry); + adc(&mut self.sigma[2], t[2], &mut carry); + adc(&mut self.sigma[3], t[3], &mut carry); + adc(&mut self.sigma[4], t[4], &mut carry); + adc(&mut self.sigma[5], t[5], &mut carry); + adc(&mut self.sigma[6], t[6], &mut carry); + adc(&mut self.sigma[7], t[7], &mut carry); } - fn update_n(&mut self, mut l: u8) { - let res = u16::from(self.n[0]) + (u16::from(l) << 3); - self.n[0] = (res & 0xff) as u8; - l = (res >> 8) as u8; - - for a in self.n.iter_mut().skip(1) { - let (res, over) = (*a).overflowing_add(l); - *a = res; - if over { - l = 1; - } else { - break; - } - } + fn update_n(&mut self, len: u64) { + let mut carry = 0; + // note: `len` can not be bigger than block size, + // so `8*len` will never overflow + adc(&mut self.n[0], 8 * len, &mut carry); + adc(&mut self.n[1], 0, &mut carry); + adc(&mut self.n[2], 0, &mut carry); + adc(&mut self.n[3], 0, &mut carry); + adc(&mut self.n[4], 0, &mut carry); + adc(&mut self.n[5], 0, &mut carry); + adc(&mut self.n[6], 0, &mut carry); + adc(&mut self.n[7], 0, &mut carry); } - fn process_block(&mut self, block: &GenericArray, msg_len: u8) { - #[allow(unsafe_code)] + fn compress(&mut self, block: &GenericArray, msg_len: u64) { let block = unsafe { &*(block.as_ptr() as *const [u8; 64]) }; - let n = self.n; - self.g(&n, block); + self.g(&to_bytes(&self.n), block); self.update_n(msg_len); self.update_sigma(block); } -} - -#[derive(Clone)] -pub struct Streebog + Copy> { - buffer: BlockBuffer, - state: StreebogState, - // Phantom data to tie digest size to the struct - digest_size: PhantomData, -} -impl Default for Streebog -where - N: ArrayLength + Copy, -{ - fn default() -> Self { - let h = match N::to_usize() { - 64 => [0u8; 64], - 32 => [1u8; 64], - _ => unreachable!(), - }; - Streebog { - buffer: Default::default(), - state: StreebogState { - h, - n: [0u8; 64], - sigma: [0u8; 64], - }, - digest_size: Default::default(), + pub(crate) fn update_blocks(&mut self, blocks: &[GenericArray]) { + for block in blocks { + self.compress(block, BLOCK_SIZE as u64); } } -} -impl BlockInput for Streebog -where - N: ArrayLength + Copy, -{ - type BlockSize = U64; + pub(crate) fn finalize(&mut self, buffer: &mut EagerBuffer) { + let pos = buffer.get_pos(); + // note that it's guaranteed that `compress` will be called only once + buffer.digest_pad(1, &[], |b| self.compress(b, pos as u64)); + self.g(&[0u8; 64], &to_bytes(&self.n)); + self.g(&[0u8; 64], &to_bytes(&self.sigma)); + } } -impl Update for Streebog -where - N: ArrayLength + Copy, -{ - fn update(&mut self, input: impl AsRef<[u8]>) { - let s = &mut self.state; - self.buffer - .input_block(input.as_ref(), |d| s.process_block(d, BLOCK_SIZE as u8)); - } +#[inline(always)] +fn adc(a: &mut u64, b: u64, carry: &mut u64) { + let ret = (*a as u128) + (b as u128) + (*carry as u128); + *a = ret as u64; + *carry = (ret >> 64) as u64; } -impl FixedOutputDirty for Streebog -where - N: ArrayLength + Copy, -{ - type OutputSize = N; - - fn finalize_into_dirty(&mut self, out: &mut GenericArray) { - let mut self_state = self.state; - let pos = self.buffer.position(); - - let block = self - .buffer - .pad_with::() - .expect("we never use input_lazy"); - block[pos] = 1; - self_state.process_block(block, pos as u8); - - let n = self_state.n; - self_state.g(&[0u8; 64], &n); - let sigma = self_state.sigma; - self_state.g(&[0u8; 64], &sigma); - - let n = BLOCK_SIZE - Self::OutputSize::to_usize(); - out.copy_from_slice(&self_state.h[n..]) +#[inline(always)] +fn to_bytes(b: &[u64; 8]) -> Block { + let mut t = [0; 64]; + for (chunk, v) in t.chunks_exact_mut(8).zip(b.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); } + t } -impl Reset for Streebog -where - N: ArrayLength + Copy, -{ - fn reset(&mut self) { - self.buffer.reset(); - self.state.h = match N::to_usize() { - 64 => [0u8; 64], - 32 => [1u8; 64], - _ => unreachable!(), - }; - self.state.n = [0; 64]; - self.state.sigma = [0; 64]; +#[inline(always)] +fn from_bytes(b: &Block) -> [u64; 8] { + let mut t = [0u64; 8]; + for (v, chunk) in t.iter_mut().zip(b.chunks_exact(8)) { + *v = u64::from_le_bytes(chunk.try_into().unwrap()); } + t } diff --git a/streebog/src/streebog256.rs b/streebog/src/streebog256.rs new file mode 100644 index 000000000..ef324b7c4 --- /dev/null +++ b/streebog/src/streebog256.rs @@ -0,0 +1,87 @@ +use core::fmt; +use digest::{ + block_buffer::Eager, + consts::{U32, U64}, + core_api::{ + AlgorithmName, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::GenericArray, + HashMarker, +}; + +use crate::streebog::StreebogState; + +/// Core Streebog256 hasher state. +#[derive(Clone)] +pub struct Streebog256Core { + state: StreebogState, +} + +impl HashMarker for Streebog256Core {} + +impl BlockSizeUser for Streebog256Core { + type BlockSize = U64; +} + +impl BufferKindUser for Streebog256Core { + type BufferKind = Eager; +} + +impl OutputSizeUser for Streebog256Core { + type OutputSize = U32; +} + +impl UpdateCore for Streebog256Core { + #[inline] + fn update_blocks(&mut self, blocks: &[GenericArray]) { + self.state.update_blocks(blocks); + } +} + +impl FixedOutputCore for Streebog256Core { + #[inline] + fn finalize_fixed_core( + &mut self, + buffer: &mut Buffer, + out: &mut GenericArray, + ) { + self.state.finalize(buffer); + out.copy_from_slice(&self.state.h[32..]) + } +} + +impl Default for Streebog256Core { + #[inline(always)] + fn default() -> Self { + Self { + state: StreebogState { + h: [1u8; 64], + n: Default::default(), + sigma: Default::default(), + }, + } + } +} + +impl Reset for Streebog256Core { + #[inline(always)] + fn reset(&mut self) { + *self = Default::default(); + } +} + +impl AlgorithmName for Streebog256Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Streebog256") + } +} + +impl fmt::Debug for Streebog256Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Streebog256Core { ... }") + } +} + +/// Streebog256 hasher state. +pub type Streebog256 = CoreWrapper; diff --git a/streebog/src/streebog512.rs b/streebog/src/streebog512.rs new file mode 100644 index 000000000..63d36b350 --- /dev/null +++ b/streebog/src/streebog512.rs @@ -0,0 +1,82 @@ +use core::fmt; +use digest::{ + block_buffer::Eager, + consts::U64, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + HashMarker, Output, +}; + +use crate::streebog::StreebogState; + +/// Core Streebog512 hasher state. +#[derive(Clone)] +pub struct Streebog512Core { + state: StreebogState, +} + +impl HashMarker for Streebog512Core {} + +impl BlockSizeUser for Streebog512Core { + type BlockSize = U64; +} + +impl BufferKindUser for Streebog512Core { + type BufferKind = Eager; +} + +impl OutputSizeUser for Streebog512Core { + type OutputSize = U64; +} + +impl UpdateCore for Streebog512Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.state.update_blocks(blocks); + } +} + +impl FixedOutputCore for Streebog512Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + self.state.finalize(buffer); + out.copy_from_slice(&self.state.h) + } +} + +impl Default for Streebog512Core { + #[inline(always)] + fn default() -> Self { + Self { + state: StreebogState { + h: [0u8; 64], + n: Default::default(), + sigma: Default::default(), + }, + } + } +} + +impl Reset for Streebog512Core { + #[inline(always)] + fn reset(&mut self) { + *self = Default::default(); + } +} + +impl AlgorithmName for Streebog512Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Streebog512") + } +} + +impl fmt::Debug for Streebog512Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Streebog512Core { ... }") + } +} + +/// Streebog512 hasher state. +pub type Streebog512 = CoreWrapper; diff --git a/streebog/tests/data/streebog256.blb b/streebog/tests/data/streebog256.blb index af1df789ef59daac497304333fefd5c1b6483778..149e1ec17ffea81e5b7a0cff74bbb62b8e6dafe7 100644 GIT binary patch delta 132 zcmdnPwwsNKp>Cpq_(XXPMu&+W3QP?G6Ei)O9p+y8=QqJ&UhInc;OV&~tQ!uTI;Qa_ zZB~hF0Gmx{U4H#qZW`q1ITZJ@>c=* cRZI#@jSQ0)GFeUDz{EEBHj@KTP=;9n0L$wt)Bpeg delta 158 zcmdnZwug-)DJMTEsnXDXqJrW?U6F~pTuKUaMdjY#h~)0PwQN_;cCVl6u@?fFvNw7z z3Hsae^l5b{gU7@a4@QNFYZZaSc?Cv?i60%56zCpq_(XXPrUr(I9u7|9VQDgIsnN; zM&ro^jJ!bBG!TEHqTJ*vCM6(OiphcT0ED{;$dzMuU~HJ2$ZS7(J~K%7BW4Ex>DnQs diff --git a/tiger/CHANGELOG.md b/tiger/CHANGELOG.md index ed74940b2..83799cb53 100644 --- a/tiger/CHANGELOG.md +++ b/tiger/CHANGELOG.md @@ -5,5 +5,14 @@ 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.2.0 (2021-11-22) +### Added +- `Tiger2` variant ([#217]) + +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.1.0 (2021-02-05) - Initial release diff --git a/tiger/Cargo.toml b/tiger/Cargo.toml index 144833559..3e3c7171d 100644 --- a/tiger/Cargo.toml +++ b/tiger/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "tiger" -version = "0.1.0" +version = "0.2.0" # Also update html_root_url in lib.rs when bumping this description = "Tiger hash function" -authors = ["Ulrik Mikaelsson ", "RustCrypto Developers"] +authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2018" @@ -12,12 +12,10 @@ keywords = ["crypto", "hash", "tiger", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = { version = "0.9", features = ["block-padding"] } -byteorder = { version = "1", default-features = false } +digest = "0.10" [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/tiger/LICENSE-MIT b/tiger/LICENSE-MIT index d967eab37..d62c85c68 100644 --- a/tiger/LICENSE-MIT +++ b/tiger/LICENSE-MIT @@ -1,3 +1,4 @@ +Copyright (c) 2021 RustCrypto Developers Copyright (c) 2020 Ulrik Mikaelsson Permission is hereby granted, free of charge, to any diff --git a/tiger/src/compress.rs b/tiger/src/compress.rs new file mode 100644 index 000000000..20f7c56fc --- /dev/null +++ b/tiger/src/compress.rs @@ -0,0 +1,72 @@ +use super::tables::{T1, T2, T3, T4}; +use super::State; +use core::convert::TryInto; +use digest::generic_array::{typenum::U64, GenericArray}; + +#[inline(always)] +fn round(a: &mut u64, b: &mut u64, c: &mut u64, x: &u64, mul: u8) { + *c ^= *x; + let c2: [u8; 8] = c.to_le_bytes(); + let a2 = T1[usize::from(c2[0])] + ^ T2[usize::from(c2[2])] + ^ T3[usize::from(c2[4])] + ^ T4[usize::from(c2[6])]; + let b2 = T4[usize::from(c2[1])] + ^ T3[usize::from(c2[3])] + ^ T2[usize::from(c2[5])] + ^ T1[usize::from(c2[7])]; + *a = a.wrapping_sub(a2); + *b = b.wrapping_add(b2).wrapping_mul(u64::from(mul)); +} + +#[inline(always)] +fn pass(a: &mut u64, b: &mut u64, c: &mut u64, x: &[u64; 8], mul: u8) { + round(a, b, c, &x[0], mul); + round(b, c, a, &x[1], mul); + round(c, a, b, &x[2], mul); + round(a, b, c, &x[3], mul); + round(b, c, a, &x[4], mul); + round(c, a, b, &x[5], mul); + round(a, b, c, &x[6], mul); + round(b, c, a, &x[7], mul); +} + +#[inline(always)] +fn key_schedule(x: &mut [u64; 8]) { + x[0] = x[0].wrapping_sub(x[7] ^ 0xA5A5_A5A5_A5A5_A5A5); + x[1] ^= x[0]; + x[2] = x[2].wrapping_add(x[1]); + x[3] = x[3].wrapping_sub(x[2] ^ ((!x[1]) << 19)); + x[4] ^= x[3]; + x[5] = x[5].wrapping_add(x[4]); + x[6] = x[6].wrapping_sub(x[5] ^ ((!x[4]) >> 23)); + x[7] ^= x[6]; + x[0] = x[0].wrapping_add(x[7]); + x[1] = x[1].wrapping_sub(x[0] ^ ((!x[7]) << 19)); + x[2] ^= x[1]; + x[3] = x[3].wrapping_add(x[2]); + x[4] = x[4].wrapping_sub(x[3] ^ ((!x[2]) >> 23)); + x[5] ^= x[4]; + x[6] = x[6].wrapping_add(x[5]); + x[7] = x[7].wrapping_sub(x[6] ^ 0x0123_4567_89AB_CDEF); +} + +pub(crate) fn compress(state: &mut State, blocks: &[GenericArray]) { + let mut block: [u64; 8] = Default::default(); + for raw_block in blocks { + for (o, chunk) in block.iter_mut().zip(raw_block.chunks_exact(8)) { + *o = u64::from_le_bytes(chunk.try_into().unwrap()); + } + let [mut a, mut b, mut c] = *state; + + pass(&mut a, &mut b, &mut c, &block, 5); + key_schedule(&mut block); + pass(&mut c, &mut a, &mut b, &block, 7); + key_schedule(&mut block); + pass(&mut b, &mut c, &mut a, &block, 9); + + state[0] ^= a; + state[1] = b.wrapping_sub(state[1]); + state[2] = c.wrapping_add(state[2]); + } +} diff --git a/tiger/src/lib.rs b/tiger/src/lib.rs index 9996735a2..8ef93ca50 100644 --- a/tiger/src/lib.rs +++ b/tiger/src/lib.rs @@ -1,1264 +1,211 @@ -//! The [Tiger][1] hash function, implemented through [Digest][2] +//! An implementation of the [Tiger][1] cryptographic hash algorithms. //! -//! [1]: http://www.cs.technion.ac.il/~biham/Reports/Tiger/tiger/tiger.html -//! [2]: https://crates.io/crates/digest +//! Tiger2 is a variant of the original Tiger with a small padding tweak. +//! +//! # Usage +//! +//! ```rust +//! use hex_literal::hex; +//! use tiger::{Tiger, Digest}; +//! +//! // create a Tiger object +//! let mut hasher = Tiger::new(); +//! +//! // process input message +//! hasher.update(b"hello world"); +//! +//! // acquire hash digest in the form of GenericArray, +//! // which in this case is equivalent to [u8; 24] +//! let result = hasher.finalize(); +//! assert_eq!(result[..], hex!("4c8fbddae0b6f25832af45e7c62811bb64ec3e43691e9cc3")); +//! ``` +//! +//! Also see [RustCrypto/hashes][2] readme. +//! +//! [1]: https://en.wikipedia.org/wiki/Tiger_(hash_function) +//! [2]: https://github.com/RustCrypto/hashes #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/tiger/0.2.0" )] #![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -pub use digest; - -use block_buffer::{ - generic_array::typenum::consts::U64 as BB_U64, generic_array::GenericArray as BB_GenericArray, - BlockBuffer, +pub use digest::{self, Digest}; + +use core::{fmt, slice::from_ref}; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::typenum::{Unsigned, U24, U64}, + HashMarker, Output, }; -use byteorder::{ByteOrder, LE}; -use digest::generic_array::typenum::{U24, U64}; -use digest::generic_array::GenericArray; -type BlockBuffer512 = BlockBuffer; +mod compress; +mod tables; +use compress::compress; -const PADDING_BLOCK: [u8; 64] = [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -]; - -const H0: [u64; 3] = [ +type State = [u64; 3]; +const S0: State = [ 0x0123_4567_89AB_CDEF, 0xFEDC_BA98_7654_3210, 0xF096_A5B4_C3B2_E187, ]; -/// The Tiger hasher +/// Core Tiger hasher state. #[derive(Clone)] -pub struct Tiger { - length_bytes: u64, - buffer: BlockBuffer512, - state: [u64; 3], +pub struct TigerCore { + block_len: u64, + state: State, } -impl Default for Tiger { - fn default() -> Self { - Tiger { - length_bytes: 0, - buffer: Default::default(), - state: H0, - } - } +impl HashMarker for TigerCore {} + +impl BlockSizeUser for TigerCore { + type BlockSize = U64; +} + +impl BufferKindUser for TigerCore { + type BufferKind = Eager; } -impl Tiger { +impl OutputSizeUser for TigerCore { + type OutputSize = U24; +} + +impl UpdateCore for TigerCore { #[inline] - fn fill_up_to(from: usize, to: usize, modulo: usize) -> usize { - let _from = from + 1; - let _to = to + modulo; - 1 + ((_to - _from) % modulo) + fn update_blocks(&mut self, blocks: &[Block]) { + self.block_len += blocks.len() as u64; + compress(&mut self.state, blocks); } +} +impl FixedOutputCore for TigerCore { #[inline] - fn finalize(&mut self) -> [u64; 3] { - { - let self_state = &mut self.state; - let pad_size = Self::fill_up_to(self.buffer.position(), 64 - 8, 64); - self.buffer.input_block(&PADDING_BLOCK[..pad_size], |d| { - Self::compress(self_state, d) - }); - - let mut length: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; - LE::write_u64(&mut length, (self.length_bytes << 3) as u64); - self.buffer - .input_block(&length, |d| Self::compress(self_state, d)); - - assert_eq!(self.buffer.position(), 0); + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bs = Self::BlockSize::U64 as u64; + let pos = buffer.get_pos() as u64; + let bit_len = 8 * (pos + bs * self.block_len); + + buffer.digest_pad(1, &bit_len.to_le_bytes(), |b| { + compress(&mut self.state, from_ref(b)) + }); + for (chunk, v) in out.chunks_exact_mut(8).zip(self.state.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); } - self.state } +} - fn consume(&mut self, input: &[u8]) { - // Unlike Sha1 and Sha2, the length value in Tiger is defined as - // the length of the message mod 2^64 - ie: integer overflow is OK. - self.length_bytes += input.len() as u64; - let self_state = &mut self.state; - self.buffer - .input_block(input, |d| Self::compress(self_state, d)); +impl Default for TigerCore { + fn default() -> Self { + Self { + block_len: 0, + state: S0, + } } +} - #[inline] - fn compress(state: &mut [u64; 3], input: &BB_GenericArray) { - let mut inputs: [u64; 8] = Default::default(); - LE::read_u64_into(input, &mut inputs); - let mut a = state[0]; - let mut b = state[1]; - let mut c = state[2]; - - Self::pass(&mut a, &mut b, &mut c, &inputs, 5); - Self::key_schedule(&mut inputs); - Self::pass(&mut c, &mut a, &mut b, &inputs, 7); - Self::key_schedule(&mut inputs); - Self::pass(&mut b, &mut c, &mut a, &inputs, 9); - - state[0] ^= a; - state[1] = b.wrapping_sub(state[1]); - state[2] = c.wrapping_add(state[2]); +impl Reset for TigerCore { + fn reset(&mut self) { + *self = Default::default(); } +} - #[inline] - fn pass(a: &mut u64, b: &mut u64, c: &mut u64, x: &[u64; 8], mul: u8) { - Self::round(a, b, c, &x[0], mul); - Self::round(b, c, a, &x[1], mul); - Self::round(c, a, b, &x[2], mul); - Self::round(a, b, c, &x[3], mul); - Self::round(b, c, a, &x[4], mul); - Self::round(c, a, b, &x[5], mul); - Self::round(a, b, c, &x[6], mul); - Self::round(b, c, a, &x[7], mul); +impl AlgorithmName for TigerCore { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Tiger") } +} - #[inline] - #[allow(clippy::trivially_copy_pass_by_ref)] - fn round(a: &mut u64, b: &mut u64, c: &mut u64, x: &u64, mul: u8) { - *c ^= *x; - let mut c_: [u8; 8] = Default::default(); - LE::write_u64(&mut c_, *c); - *a = a.wrapping_sub( - T1[c_[0] as usize] ^ T2[c_[2] as usize] ^ T3[c_[4] as usize] ^ T4[c_[6] as usize], - ); - *b = b.wrapping_add( - T4[c_[1] as usize] ^ T3[c_[3] as usize] ^ T2[c_[5] as usize] ^ T1[c_[7] as usize], - ); - *b = b.wrapping_mul(u64::from(mul)); +impl fmt::Debug for TigerCore { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("TigerCore { ... }") } +} - #[inline] - fn key_schedule(x: &mut [u64; 8]) { - x[0] = x[0].wrapping_sub(x[7] ^ 0xA5A5_A5A5_A5A5_A5A5); - x[1] ^= x[0]; - x[2] = x[2].wrapping_add(x[1]); - x[3] = x[3].wrapping_sub(x[2] ^ ((!x[1]) << 19)); - x[4] ^= x[3]; - x[5] = x[5].wrapping_add(x[4]); - x[6] = x[6].wrapping_sub(x[5] ^ ((!x[4]) >> 23)); - x[7] ^= x[6]; - x[0] = x[0].wrapping_add(x[7]); - x[1] = x[1].wrapping_sub(x[0] ^ ((!x[7]) << 19)); - x[2] ^= x[1]; - x[3] = x[3].wrapping_add(x[2]); - x[4] = x[4].wrapping_sub(x[3] ^ ((!x[2]) >> 23)); - x[5] ^= x[4]; - x[6] = x[6].wrapping_add(x[5]); - x[7] = x[7].wrapping_sub(x[6] ^ 0x0123_4567_89AB_CDEF); - } +/// Core Tiger2 hasher state. +#[derive(Clone)] +pub struct Tiger2Core { + block_len: u64, + state: State, } -impl digest::BlockInput for Tiger { +impl HashMarker for Tiger2Core {} + +impl BlockSizeUser for Tiger2Core { type BlockSize = U64; } -impl digest::Reset for Tiger { - fn reset(&mut self) { - self.buffer.reset(); - self.length_bytes = 0; - self.state = H0; - } +impl BufferKindUser for Tiger2Core { + type BufferKind = Eager; } -impl digest::Update for Tiger { - #[inline] +impl OutputSizeUser for Tiger2Core { + type OutputSize = U24; +} - fn update(&mut self, data: impl AsRef<[u8]>) { - self.consume(data.as_ref()); +impl UpdateCore for Tiger2Core { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + self.block_len += blocks.len() as u64; + compress(&mut self.state, blocks); } } -impl digest::FixedOutputDirty for Tiger { - type OutputSize = U24; - - fn finalize_into_dirty(&mut self, out: &mut GenericArray) { - LE::write_u64_into(&self.finalize(), &mut out.as_mut_slice()); +impl FixedOutputCore for Tiger2Core { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let bs = Self::BlockSize::U64 as u64; + let pos = buffer.get_pos() as u64; + let bit_len = 8 * (pos + bs * self.block_len); + + buffer.len64_padding_le(bit_len, |b| compress(&mut self.state, from_ref(b))); + for (chunk, v) in out.chunks_exact_mut(8).zip(self.state.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); + } } } -// Conditionally compile the module `test` only when the test-suite is run. -#[cfg(test)] -mod test { - use super::Tiger; - use digest::Digest; - use hex_literal::hex; +impl Default for Tiger2Core { + fn default() -> Self { + Self { + block_len: 0, + state: [ + 0x0123_4567_89AB_CDEF, + 0xFEDC_BA98_7654_3210, + 0xF096_A5B4_C3B2_E187, + ], + } + } +} - #[test] - fn test_vectors() { - let examples = [ - ("", hex!("3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3")), - ("abc", hex!("2aab1484e8c158f2bfb8c5ff41b57a525129131c957b5f93")), - ("Tiger", hex!("dd00230799f5009fec6debc838bb6a27df2b9d6f110c7937")), - ( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", - hex!("f71c8583902afb879edfe610f82c0d4786a3a534504486b5"), - ), - ( - "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789", - hex!("48ceeb6308b87d46e95d656112cdf18d97915f9765658957"), - ), - ( - "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham", - hex!("8a866829040a410c729ad23f5ada711603b3cdd357e4c15e"), - ), - ( - "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.", - hex!("ce55a6afd591f5ebac547ff84f89227f9331dab0b611c889"), - ), - ( - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - hex!("0f7bf9a19b9c58f2b7610df7e84f0ac3a71c631e7b53f78e"), - ), - ( - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - hex!("08c8dcb467e4c7f910966c399fdc9b164be15b792d432224"), - ), - ]; +impl Reset for Tiger2Core { + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } +} - for &(input, answer) in examples.iter() { - let result = Tiger::digest(input.as_bytes()); +impl AlgorithmName for Tiger2Core { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Tiger2") + } +} - assert_eq!(*result, answer); - } +impl fmt::Debug for Tiger2Core { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Tiger2Core { ... }") } } -static T1: [u64; 256] = [ - 0x02AA_B17C_F7E9_0C5E, /* 0 */ - 0xAC42_4B03_E243_A8EC, /* 1 */ - 0x72CD_5BE3_0DD5_FCD3, /* 2 */ - 0x6D01_9B93_F6F9_7F3A, /* 3 */ - 0xCD99_78FF_D21F_9193, /* 4 */ - 0x7573_A1C9_7080_29E2, /* 5 */ - 0xB164_326B_922A_83C3, /* 6 */ - 0x4688_3EEE_0491_5870, /* 7 */ - 0xEAAC_E305_7103_ECE6, /* 8 */ - 0xC541_69B8_08A3_535C, /* 9 */ - 0x4CE7_5491_8DDE_C47C, /* 10 */ - 0x0AA2_F4DF_DC0D_F40C, /* 11 */ - 0x10B7_6F18_A74D_BEFA, /* 12 */ - 0xC6CC_B623_5AD1_AB6A, /* 13 */ - 0x1372_6121_572F_E2FF, /* 14 */ - 0x1A48_8C6F_199D_921E, /* 15 */ - 0x4BC9_F9F4_DA00_07CA, /* 16 */ - 0x26F5_E6F6_E852_41C7, /* 17 */ - 0x8590_79DB_EA59_47B6, /* 18 */ - 0x4F18_85C5_C99E_8C92, /* 19 */ - 0xD78E_761E_A96F_864B, /* 20 */ - 0x8E36_428C_52B5_C17D, /* 21 */ - 0x69CF_6827_3730_63C1, /* 22 */ - 0xB607_C93D_9BB4_C56E, /* 23 */ - 0x7D82_0E76_0E76_B5EA, /* 24 */ - 0x645C_9CC6_F07F_DC42, /* 25 */ - 0xBF38_A078_2433_42E0, /* 26 */ - 0x5F6B_343C_9D2E_7D04, /* 27 */ - 0xF2C2_8AEB_600B_0EC6, /* 28 */ - 0x6C0E_D85F_7254_BCAC, /* 29 */ - 0x7159_2281_A4DB_4FE5, /* 30 */ - 0x1967_FA69_CE0F_ED9F, /* 31 */ - 0xFD52_93F8_B965_45DB, /* 32 */ - 0xC879_E9D7_F2A7_600B, /* 33 */ - 0x8602_4892_0193_194E, /* 34 */ - 0xA4F9_533B_2D9C_C0B3, /* 35 */ - 0x9053_836C_1595_7613, /* 36 */ - 0xDB6D_CF8A_FC35_7BF1, /* 37 */ - 0x18BE_EA7A_7A37_0F57, /* 38 */ - 0x0371_17CA_50B9_9066, /* 39 */ - 0x6AB3_0A97_7442_4A35, /* 40 */ - 0xF4E9_2F02_E325_249B, /* 41 */ - 0x7739_DB07_061C_CAE1, /* 42 */ - 0xD8F3_B49C_ECA4_2A05, /* 43 */ - 0xBD56_BE3F_5138_2F73, /* 44 */ - 0x45FA_ED58_43B0_BB28, /* 45 */ - 0x1C81_3D5C_11BF_1F83, /* 46 */ - 0x8AF0_E4B6_D75F_A169, /* 47 */ - 0x33EE_18A4_87AD_9999, /* 48 */ - 0x3C26_E8EA_B1C9_4410, /* 49 */ - 0xB510_102B_C0A8_22F9, /* 50 */ - 0x141E_EF31_0CE6_123B, /* 51 */ - 0xFC65_B900_59DD_B154, /* 52 */ - 0xE015_8640_C5E0_E607, /* 53 */ - 0x884E_0798_26C3_A3CF, /* 54 */ - 0x930D_0D95_23C5_35FD, /* 55 */ - 0x3563_8D75_4E9A_2B00, /* 56 */ - 0x4085_FCCF_4046_9DD5, /* 57 */ - 0xC4B1_7AD2_8BE2_3A4C, /* 58 */ - 0xCAB2_F0FC_6A3E_6A2E, /* 59 */ - 0x2860_971A_6B94_3FCD, /* 60 */ - 0x3DDE_6EE2_12E3_0446, /* 61 */ - 0x6222_F32A_E017_65AE, /* 62 */ - 0x5D55_0BB5_4783_08FE, /* 63 */ - 0xA9EF_A98D_A0ED_A22A, /* 64 */ - 0xC351_A716_86C4_0DA7, /* 65 */ - 0x1105_586D_9C86_7C84, /* 66 */ - 0xDCFF_EE85_FDA2_2853, /* 67 */ - 0xCCFB_D026_2C5E_EF76, /* 68 */ - 0xBAF2_94CB_8990_D201, /* 69 */ - 0xE694_64F5_2AFA_D975, /* 70 */ - 0x94B0_13AF_DF13_3E14, /* 71 */ - 0x06A7_D1A3_2823_C958, /* 72 */ - 0x6F95_FE51_30F6_1119, /* 73 */ - 0xD92A_B34E_462C_06C0, /* 74 */ - 0xED7B_DE33_887C_71D2, /* 75 */ - 0x7974_6D6E_6518_393E, /* 76 */ - 0x5BA4_1938_5D71_3329, /* 77 */ - 0x7C1B_A6B9_48A9_7564, /* 78 */ - 0x3198_7C19_7BFD_AC67, /* 79 */ - 0xDE6C_23C4_4B05_3D02, /* 80 */ - 0x581C_49FE_D002_D64D, /* 81 */ - 0xDD47_4D63_3826_1571, /* 82 */ - 0xAA45_46C3_E473_D062, /* 83 */ - 0x928F_CE34_9455_F860, /* 84 */ - 0x4816_1BBA_CAAB_94D9, /* 85 */ - 0x6391_2430_770E_6F68, /* 86 */ - 0x6EC8_A5E6_02C6_641C, /* 87 */ - 0x8728_2515_337D_DD2B, /* 88 */ - 0x2CDA_6B42_034B_701B, /* 89 */ - 0xB03D_37C1_81CB_096D, /* 90 */ - 0xE108_4382_66C7_1C6F, /* 91 */ - 0x2B31_80C7_EB51_B255, /* 92 */ - 0xDF92_B82F_96C0_8BBC, /* 93 */ - 0x5C68_C8C0_A632_F3BA, /* 94 */ - 0x5504_CC86_1C3D_0556, /* 95 */ - 0xABBF_A4E5_5FB2_6B8F, /* 96 */ - 0x4184_8B0A_B3BA_CEB4, /* 97 */ - 0xB334_A273_AA44_5D32, /* 98 */ - 0xBCA6_96F0_A85A_D881, /* 99 */ - 0x24F6_EC65_B528_D56C, /* 100 */ - 0x0CE1_512E_90F4_524A, /* 101 */ - 0x4E9D_D79D_5506_D35A, /* 102 */ - 0x2589_05FA_C6CE_9779, /* 103 */ - 0x2019_295B_3E10_9B33, /* 104 */ - 0xF8A9_478B_73A0_54CC, /* 105 */ - 0x2924_F2F9_3441_7EB0, /* 106 */ - 0x3993_357D_536D_1BC4, /* 107 */ - 0x38A8_1AC2_1DB6_FF8B, /* 108 */ - 0x47C4_FBF1_7D60_16BF, /* 109 */ - 0x1E0F_AADD_7667_E3F5, /* 110 */ - 0x7ABC_FF62_938B_EB96, /* 111 */ - 0xA78D_AD94_8FC1_79C9, /* 112 */ - 0x8F1F_98B7_2911_E50D, /* 113 */ - 0x61E4_8EAE_2712_1A91, /* 114 */ - 0x4D62_F7AD_3185_9808, /* 115 */ - 0xECEB_A345_EF5C_EAEB, /* 116 */ - 0xF5CE_B25E_BC96_84CE, /* 117 */ - 0xF633_E20C_B7F7_6221, /* 118 */ - 0xA32C_DF06_AB82_93E4, /* 119 */ - 0x985A_202C_A5EE_2CA4, /* 120 */ - 0xCF0B_8447_CC8A_8FB1, /* 121 */ - 0x9F76_5244_9798_59A3, /* 122 */ - 0xA8D5_16B1_A124_0017, /* 123 */ - 0x0BD7_BA3E_BB5D_C726, /* 124 */ - 0xE54B_CA55_B86A_DB39, /* 125 */ - 0x1D7A_3AFD_6C47_8063, /* 126 */ - 0x519E_C608_E766_9EDD, /* 127 */ - 0x0E57_15A2_D149_AA23, /* 128 */ - 0x177D_4571_848F_F194, /* 129 */ - 0xEEB5_5F32_4101_4C22, /* 130 */ - 0x0F5E_5CA1_3A6E_2EC2, /* 131 */ - 0x8029_927B_75F5_C361, /* 132 */ - 0xAD13_9FAB_C3D6_E436, /* 133 */ - 0x0D5D_F1A9_4CCF_402F, /* 134 */ - 0x3E8B_D948_BEA5_DFC8, /* 135 */ - 0xA5A0_D357_BD3F_F77E, /* 136 */ - 0xA2D1_2E25_1F74_F645, /* 137 */ - 0x66FD_9E52_5E81_A082, /* 138 */ - 0x2E0C_90CE_7F68_7A49, /* 139 */ - 0xC2E8_BCBE_BA97_3BC5, /* 140 */ - 0x0000_01BC_E509_745F, /* 141 */ - 0x4237_77BB_E6DA_B3D6, /* 142 */ - 0xD166_1C7E_AEF0_6EB5, /* 143 */ - 0xA178_1F35_4DAA_CFD8, /* 144 */ - 0x2D11_284A_2B16_AFFC, /* 145 */ - 0xF1FC_4F67_FA89_1D1F, /* 146 */ - 0x73EC_C25D_CB92_0ADA, /* 147 */ - 0xAE61_0C22_C2A1_2651, /* 148 */ - 0x96E0_A810_D356_B78A, /* 149 */ - 0x5A9A_381F_2FE7_870F, /* 150 */ - 0xD5AD_62ED_E94E_5530, /* 151 */ - 0xD225_E5E8_368D_1427, /* 152 */ - 0x6597_7B70_C7AF_4631, /* 153 */ - 0x99F8_89B2_DE39_D74F, /* 154 */ - 0x233F_30BF_54E1_D143, /* 155 */ - 0x9A96_75D3_D9A6_3C97, /* 156 */ - 0x5470_554F_F334_F9A8, /* 157 */ - 0x166A_CB74_4A4F_5688, /* 158 */ - 0x70C7_4CAA_B2E4_AEAD, /* 159 */ - 0xF0D0_9164_6F29_4D12, /* 160 */ - 0x57B8_2A89_6840_31D1, /* 161 */ - 0xEFD9_5A5A_61BE_0B6B, /* 162 */ - 0x2FBD_12E9_69F2_F29A, /* 163 */ - 0x9BD3_7013_FEFF_9FE8, /* 164 */ - 0x3F9B_0404_D608_5A06, /* 165 */ - 0x4940_C1F3_166C_FE15, /* 166 */ - 0x0954_2C4D_CDF3_DEFB, /* 167 */ - 0xB4C5_2183_85CD_5CE3, /* 168 */ - 0xC935_B7DC_4462_A641, /* 169 */ - 0x3417_F8A6_8ED3_B63F, /* 170 */ - 0xB809_5929_5B21_5B40, /* 171 */ - 0xF99C_DAEF_3B8C_8572, /* 172 */ - 0x018C_0614_F8FC_B95D, /* 173 */ - 0x1B14_ACCD_1A3A_CDF3, /* 174 */ - 0x84D4_71F2_00BB_732D, /* 175 */ - 0xC1A3_110E_95E8_DA16, /* 176 */ - 0x430A_7220_BF1A_82B8, /* 177 */ - 0xB77E_090D_39DF_210E, /* 178 */ - 0x5EF4_BD9F_3CD0_5E9D, /* 179 */ - 0x9D4F_F6DA_7E57_A444, /* 180 */ - 0xDA1D_60E1_83D4_A5F8, /* 181 */ - 0xB287_C384_1799_8E47, /* 182 */ - 0xFE3E_DC12_1BB3_1886, /* 183 */ - 0xC7FE_3CCC_980C_CBEF, /* 184 */ - 0xE46F_B590_189B_FD03, /* 185 */ - 0x3732_FD46_9A4C_57DC, /* 186 */ - 0x7EF7_00A0_7CF1_AD65, /* 187 */ - 0x59C6_4468_A31D_8859, /* 188 */ - 0x762F_B0B4_D45B_61F6, /* 189 */ - 0x155B_AED0_9904_7718, /* 190 */ - 0x6875_5E4C_3D50_BAA6, /* 191 */ - 0xE921_4E7F_22D8_B4DF, /* 192 */ - 0x2ADD_BF53_2EAC_95F4, /* 193 */ - 0x32AE_3909_B4BD_0109, /* 194 */ - 0x834D_F537_B08E_3450, /* 195 */ - 0xFA20_9DA8_4220_728D, /* 196 */ - 0x9E69_1D9B_9EFE_23F7, /* 197 */ - 0x0446_D288_C4AE_8D7F, /* 198 */ - 0x7B4C_C524_E169_785B, /* 199 */ - 0x21D8_7F01_35CA_1385, /* 200 */ - 0xCEBB_400F_137B_8AA5, /* 201 */ - 0x272E_2B66_5807_96BE, /* 202 */ - 0x3612_2641_25C2_B0DE, /* 203 */ - 0x0577_02BD_AD1E_FBB2, /* 204 */ - 0xD4BA_BB8E_ACF8_4BE9, /* 205 */ - 0x9158_3139_641B_C67B, /* 206 */ - 0x8BDC_2DE0_8036_E024, /* 207 */ - 0x603C_8156_F49F_68ED, /* 208 */ - 0xF7D2_36F7_DBEF_5111, /* 209 */ - 0x9727_C459_8AD2_1E80, /* 210 */ - 0xA08A_0896_670A_5FD7, /* 211 */ - 0xCB4A_8F43_09EB_A9CB, /* 212 */ - 0x81AF_564B_0F70_36A1, /* 213 */ - 0xC0B9_9AA7_7819_9ABD, /* 214 */ - 0x959F_1EC8_3FC8_E952, /* 215 */ - 0x8C50_5077_794A_81B9, /* 216 */ - 0x3ACA_AF8F_0563_38F0, /* 217 */ - 0x07B4_3F50_627A_6778, /* 218 */ - 0x4A44_AB49_F5EC_CC77, /* 219 */ - 0x3BC3_D6E4_B679_EE98, /* 220 */ - 0x9CC0_D4D1_CF14_108C, /* 221 */ - 0x4406_C00B_206B_C8A0, /* 222 */ - 0x82A1_8854_C8D7_2D89, /* 223 */ - 0x67E3_66B3_5C3C_432C, /* 224 */ - 0xB923_DD61_102B_37F2, /* 225 */ - 0x56AB_2779_D884_271D, /* 226 */ - 0xBE83_E1B0_FF15_25AF, /* 227 */ - 0xFB7C_65D4_217E_49A9, /* 228 */ - 0x6BDB_E0E7_6D48_E7D4, /* 229 */ - 0x08DF_8287_45D9_179E, /* 230 */ - 0x22EA_6A9A_DD53_BD34, /* 231 */ - 0xE36E_141C_5622_200A, /* 232 */ - 0x7F80_5D1B_8CB7_50EE, /* 233 */ - 0xAFE5_C7A5_9F58_E837, /* 234 */ - 0xE27F_996A_4FB1_C23C, /* 235 */ - 0xD386_7DFB_0775_F0D0, /* 236 */ - 0xD0E6_73DE_6E88_891A, /* 237 */ - 0x123A_EB9E_AFB8_6C25, /* 238 */ - 0x30F1_D5D5_C145_B895, /* 239 */ - 0xBB43_4A2D_EE72_69E7, /* 240 */ - 0x78CB_67EC_F931_FA38, /* 241 */ - 0xF33B_0372_323B_BF9C, /* 242 */ - 0x52D6_6336_FB27_9C74, /* 243 */ - 0x505F_33AC_0AFB_4EAA, /* 244 */ - 0xE8A5_CD99_A2CC_E187, /* 245 */ - 0x5349_7480_1E2D_30BB, /* 246 */ - 0x8D2D_5711_D587_6D90, /* 247 */ - 0x1F1A_4128_91BC_038E, /* 248 */ - 0xD6E2_E71D_82E5_6648, /* 249 */ - 0x7403_6C3A_4977_32B7, /* 250 */ - 0x89B6_7ED9_6361_F5AB, /* 251 */ - 0xFFED_95D8_F1EA_02A2, /* 252 */ - 0xE72B_3BD6_1464_D43D, /* 253 */ - 0xA630_0F17_0BDC_4820, /* 254 */ - 0xEBC1_8760_ED78_A77A, /* 255 */ -]; -static T2: [u64; 256] = [ - 0xE6A6_BE5A_05A1_2138, /* 256 */ - 0xB5A1_22A5_B4F8_7C98, /* 257 */ - 0x563C_6089_140B_6990, /* 258 */ - 0x4C46_CB2E_391F_5DD5, /* 259 */ - 0xD932_ADDB_C9B7_9434, /* 260 */ - 0x08EA_70E4_2015_AFF5, /* 261 */ - 0xD765_A667_3E47_8CF1, /* 262 */ - 0xC4FB_757E_AB27_8D99, /* 263 */ - 0xDF11_C686_2D6E_0692, /* 264 */ - 0xDDEB_84F1_0D7F_3B16, /* 265 */ - 0x6F2E_F604_A665_EA04, /* 266 */ - 0x4A8E_0F0F_F0E0_DFB3, /* 267 */ - 0xA5ED_EEF8_3DBC_BA51, /* 268 */ - 0xFC4F_0A2A_0EA4_371E, /* 269 */ - 0xE83E_1DA8_5CB3_8429, /* 270 */ - 0xDC8F_F882_BA1B_1CE2, /* 271 */ - 0xCD45_505E_8353_E80D, /* 272 */ - 0x18D1_9A00_D4DB_0717, /* 273 */ - 0x34A0_CFED_A5F3_8101, /* 274 */ - 0x0BE7_7E51_8887_CAF2, /* 275 */ - 0x1E34_1438_B3C4_5136, /* 276 */ - 0xE057_97F4_9089_CCF9, /* 277 */ - 0xFFD2_3F9D_F259_1D14, /* 278 */ - 0x543D_DA22_8595_C5CD, /* 279 */ - 0x661F_81FD_9905_2A33, /* 280 */ - 0x8736_E641_DB0F_7B76, /* 281 */ - 0x1522_7725_418E_5307, /* 282 */ - 0xE25F_7F46_162E_B2FA, /* 283 */ - 0x48A8_B212_6C13_D9FE, /* 284 */ - 0xAFDC_5417_92E7_6EEA, /* 285 */ - 0x03D9_12BF_C6D1_898F, /* 286 */ - 0x31B1_AAFA_1B83_F51B, /* 287 */ - 0xF1AC_2796_E42A_B7D9, /* 288 */ - 0x40A3_A7D7_FCD2_EBAC, /* 289 */ - 0x1056_136D_0AFB_BCC5, /* 290 */ - 0x7889_E1DD_9A6D_0C85, /* 291 */ - 0xD335_2578_2A79_74AA, /* 292 */ - 0xA7E2_5D09_078A_C09B, /* 293 */ - 0xBD41_38B3_EAC6_EDD0, /* 294 */ - 0x920A_BFBE_71EB_9E70, /* 295 */ - 0xA2A5_D0F5_4FC2_625C, /* 296 */ - 0xC054_E36B_0B12_90A3, /* 297 */ - 0xF6DD_59FF_62FE_932B, /* 298 */ - 0x3537_3545_11A8_AC7D, /* 299 */ - 0xCA84_5E91_72FA_DCD4, /* 300 */ - 0x84F8_2B60_329D_20DC, /* 301 */ - 0x79C6_2CE1_CD67_2F18, /* 302 */ - 0x8B09_A2AD_D124_642C, /* 303 */ - 0xD0C1_E96A_19D9_E726, /* 304 */ - 0x5A78_6A9B_4BA9_500C, /* 305 */ - 0x0E02_0336_634C_43F3, /* 306 */ - 0xC17B_474A_EB66_D822, /* 307 */ - 0x6A73_1AE3_EC9B_AAC2, /* 308 */ - 0x8226_667A_E084_0258, /* 309 */ - 0x67D4_5676_91CA_ECA5, /* 310 */ - 0x1D94_155C_4875_ADB5, /* 311 */ - 0x6D00_FD98_5B81_3FDF, /* 312 */ - 0x5128_6EFC_B774_CD06, /* 313 */ - 0x5E88_3447_1FA7_44AF, /* 314 */ - 0xF72C_A0AE_E761_AE2E, /* 315 */ - 0xBE40_E4CD_AEE8_E09A, /* 316 */ - 0xE997_0BBB_5118_F665, /* 317 */ - 0x726E_4BEB_33DF_1964, /* 318 */ - 0x703B_0007_2919_9762, /* 319 */ - 0x4631_D816_F5EF_30A7, /* 320 */ - 0xB880_B5B5_1504_A6BE, /* 321 */ - 0x6417_93C3_7ED8_4B6C, /* 322 */ - 0x7B21_ED77_F6E9_7D96, /* 323 */ - 0x7763_0631_2EF9_6B73, /* 324 */ - 0xAE52_8948_E86F_F3F4, /* 325 */ - 0x53DB_D7F2_86A3_F8F8, /* 326 */ - 0x16CA_DCE7_4CFC_1063, /* 327 */ - 0x005C_19BD_FA52_C6DD, /* 328 */ - 0x6886_8F5D_64D4_6AD3, /* 329 */ - 0x3A9D_512C_CF1E_186A, /* 330 */ - 0x367E_62C2_3856_60AE, /* 331 */ - 0xE359_E7EA_77DC_B1D7, /* 332 */ - 0x526C_0773_749A_BE6E, /* 333 */ - 0x735A_E5F9_D09F_734B, /* 334 */ - 0x493F_C7CC_8A55_8BA8, /* 335 */ - 0xB0B9_C153_3041_AB45, /* 336 */ - 0x3219_58BA_470A_59BD, /* 337 */ - 0x852D_B00B_5F46_C393, /* 338 */ - 0x9120_9B2B_D336_B0E5, /* 339 */ - 0x6E60_4F7D_659E_F19F, /* 340 */ - 0xB99A_8AE2_782C_CB24, /* 341 */ - 0xCCF5_2AB6_C814_C4C7, /* 342 */ - 0x4727_D9AF_BE11_727B, /* 343 */ - 0x7E95_0D0C_0121_B34D, /* 344 */ - 0x756F_4356_70AD_471F, /* 345 */ - 0xF5AD_D442_615A_6849, /* 346 */ - 0x4E87_E099_80B9_957A, /* 347 */ - 0x2ACF_A1DF_50AE_E355, /* 348 */ - 0xD898_263A_FD2F_D556, /* 349 */ - 0xC8F4_924D_D80C_8FD6, /* 350 */ - 0xCF99_CA3D_754A_173A, /* 351 */ - 0xFE47_7BAC_AF91_BF3C, /* 352 */ - 0xED53_71F6_D690_C12D, /* 353 */ - 0x831A_5C28_5E68_7094, /* 354 */ - 0xC5D3_C90A_3708_A0A4, /* 355 */ - 0x0F7F_9037_17D0_6580, /* 356 */ - 0x19F9_BB13_B8FD_F27F, /* 357 */ - 0xB1BD_6F1B_4D50_2843, /* 358 */ - 0x1C76_1BA3_8FFF_4012, /* 359 */ - 0x0D15_30C4_E2E2_1F3B, /* 360 */ - 0x8943_CE69_A737_2C8A, /* 361 */ - 0xE518_4E11_FEB5_CE66, /* 362 */ - 0x618B_DB80_BD73_6621, /* 363 */ - 0x7D29_BAD6_8B57_4D0B, /* 364 */ - 0x81BB_613E_25E6_FE5B, /* 365 */ - 0x071C_9C10_BC07_913F, /* 366 */ - 0xC7BE_EB79_09AC_2D97, /* 367 */ - 0xC3E5_8D35_3BC5_D757, /* 368 */ - 0xEB01_7892_F38F_61E8, /* 369 */ - 0xD4EF_FB9C_9B1C_C21A, /* 370 */ - 0x9972_7D26_F494_F7AB, /* 371 */ - 0xA3E0_63A2_956B_3E03, /* 372 */ - 0x9D4A_8B9A_4AA0_9C30, /* 373 */ - 0x3F6A_B7D5_0009_0FB4, /* 374 */ - 0x9CC0_F2A0_5726_8AC0, /* 375 */ - 0x3DEE_9D2D_EDBF_42D1, /* 376 */ - 0x330F_49C8_7960_A972, /* 377 */ - 0xC6B2_7202_8742_1B41, /* 378 */ - 0x0AC5_9EC0_7C00_369C, /* 379 */ - 0xEF4E_AC49_CB35_3425, /* 380 */ - 0xF450_244E_EF01_29D8, /* 381 */ - 0x8ACC_46E5_CAF4_DEB6, /* 382 */ - 0x2FFE_AB63_9892_63F7, /* 383 */ - 0x8F7C_B9FE_5D7A_4578, /* 384 */ - 0x5BD8_F764_4E63_4635, /* 385 */ - 0x427A_7315_BF2D_C900, /* 386 */ - 0x17D0_C4AA_2125_261C, /* 387 */ - 0x3992_486C_9351_8E50, /* 388 */ - 0xB4CB_FEE0_A2D7_D4C3, /* 389 */ - 0x7C75_D620_2C5D_DD8D, /* 390 */ - 0xDBC2_95D8_E35B_6C61, /* 391 */ - 0x60B3_69D3_0203_2B19, /* 392 */ - 0xCE42_685F_DCE4_4132, /* 393 */ - 0x06F3_DDB9_DDF6_5610, /* 394 */ - 0x8EA4_D21D_B5E1_48F0, /* 395 */ - 0x20B0_FCE6_2FCD_496F, /* 396 */ - 0x2C1B_9123_58B0_EE31, /* 397 */ - 0xB283_17B8_18F5_A308, /* 398 */ - 0xA89C_1E18_9CA6_D2CF, /* 399 */ - 0x0C6B_1857_6AAA_DBC8, /* 400 */ - 0xB65D_EAA9_1299_FAE3, /* 401 */ - 0xFB2B_794B_7F10_27E7, /* 402 */ - 0x04E4_317F_443B_5BEB, /* 403 */ - 0x4B85_2D32_5939_D0A6, /* 404 */ - 0xD5AE_6BEE_FB20_7FFC, /* 405 */ - 0x3096_82B2_81C7_D374, /* 406 */ - 0xBAE3_09A1_94C3_B475, /* 407 */ - 0x8CC3_F97B_13B4_9F05, /* 408 */ - 0x98A9_422F_F829_3967, /* 409 */ - 0x244B_16B0_1076_FF7C, /* 410 */ - 0xF8BF_571C_663D_67EE, /* 411 */ - 0x1F0D_6758_EEE3_0DA1, /* 412 */ - 0xC9B6_11D9_7ADE_B9B7, /* 413 */ - 0xB7AF_D588_7B6C_57A2, /* 414 */ - 0x6290_AE84_6B98_4FE1, /* 415 */ - 0x94DF_4CDE_ACC1_A5FD, /* 416 */ - 0x058A_5BD1_C548_3AFF, /* 417 */ - 0x6316_6CC1_42BA_3C37, /* 418 */ - 0x8DB8_526E_B2F7_6F40, /* 419 */ - 0xE108_8003_6F0D_6D4E, /* 420 */ - 0x9E05_23C9_971D_311D, /* 421 */ - 0x45EC_2824_CC7C_D691, /* 422 */ - 0x575B_8359_E623_82C9, /* 423 */ - 0xFA9E_400D_C488_9995, /* 424 */ - 0xD182_3ECB_4572_1568, /* 425 */ - 0xDAFD_983B_8206_082F, /* 426 */ - 0xAA7D_2908_2386_A8CB, /* 427 */ - 0x269F_CD44_03B8_7588, /* 428 */ - 0x1B91_F5F7_28BD_D1E0, /* 429 */ - 0xE466_9F39_0402_01F6, /* 430 */ - 0x7A1D_7C21_8CF0_4ADE, /* 431 */ - 0x6562_3C29_D79C_E5CE, /* 432 */ - 0x2368_4490_96C0_0BB1, /* 433 */ - 0xAB9B_F187_9DA5_03BA, /* 434 */ - 0xBC23_ECB1_A458_058E, /* 435 */ - 0x9A58_DF01_BB40_1ECC, /* 436 */ - 0xA070_E868_A85F_143D, /* 437 */ - 0x4FF1_8830_7DF2_239E, /* 438 */ - 0x14D5_65B4_1A64_1183, /* 439 */ - 0xEE13_3374_5270_1602, /* 440 */ - 0x950E_3DCF_3F28_5E09, /* 441 */ - 0x5993_0254_B9C8_0953, /* 442 */ - 0x3BF2_9940_8930_DA6D, /* 443 */ - 0xA955_943F_5369_1387, /* 444 */ - 0xA15E_DECA_A9CB_8784, /* 445 */ - 0x2914_2127_352B_E9A0, /* 446 */ - 0x76F0_371F_FF4E_7AFB, /* 447 */ - 0x0239_F450_274F_2228, /* 448 */ - 0xBB07_3AF0_1D5E_868B, /* 449 */ - 0xBFC8_0571_C10E_96C1, /* 450 */ - 0xD267_0885_6822_2E23, /* 451 */ - 0x9671_A3D4_8E80_B5B0, /* 452 */ - 0x55B5_D38A_E193_BB81, /* 453 */ - 0x693A_E2D0_A18B_04B8, /* 454 */ - 0x5C48_B4EC_ADD5_335F, /* 455 */ - 0xFD74_3B19_4916_A1CA, /* 456 */ - 0x2577_0181_34BE_98C4, /* 457 */ - 0xE779_87E8_3C54_A4AD, /* 458 */ - 0x28E1_1014_DA33_E1B9, /* 459 */ - 0x270C_C59E_226A_A213, /* 460 */ - 0x7149_5F75_6D1A_5F60, /* 461 */ - 0x9BE8_53FB_60AF_EF77, /* 462 */ - 0xADC7_86A7_F744_3DBF, /* 463 */ - 0x0904_4561_73B2_9A82, /* 464 */ - 0x58BC_7A66_C232_BD5E, /* 465 */ - 0xF306_558C_673A_C8B2, /* 466 */ - 0x41F6_39C6_B6C9_772A, /* 467 */ - 0x216D_EFE9_9FDA_35DA, /* 468 */ - 0x1164_0CC7_1C7B_E615, /* 469 */ - 0x93C4_3694_565C_5527, /* 470 */ - 0xEA03_8E62_4677_7839, /* 471 */ - 0xF9AB_F3CE_5A3E_2469, /* 472 */ - 0x741E_768D_0FD3_12D2, /* 473 */ - 0x0144_B883_CED6_52C6, /* 474 */ - 0xC20B_5A5B_A33F_8552, /* 475 */ - 0x1AE6_9633_C343_5A9D, /* 476 */ - 0x97A2_8CA4_088C_FDEC, /* 477 */ - 0x8824_A43C_1E96_F420, /* 478 */ - 0x3761_2FA6_6EEE_A746, /* 479 */ - 0x6B4C_B165_F9CF_0E5A, /* 480 */ - 0x43AA_1C06_A0AB_FB4A, /* 481 */ - 0x7F4D_C26F_F162_796B, /* 482 */ - 0x6CBA_CC8E_54ED_9B0F, /* 483 */ - 0xA6B7_FFEF_D2BB_253E, /* 484 */ - 0x2E25_BC95_B0A2_9D4F, /* 485 */ - 0x86D6_A58B_DEF1_388C, /* 486 */ - 0xDED7_4AC5_76B6_F054, /* 487 */ - 0x8030_BDBC_2B45_805D, /* 488 */ - 0x3C81_AF70_E94D_9289, /* 489 */ - 0x3EFF_6DDA_9E31_00DB, /* 490 */ - 0xB38D_C39F_DFCC_8847, /* 491 */ - 0x1238_8552_8D17_B87E, /* 492 */ - 0xF2DA_0ED2_40B1_B642, /* 493 */ - 0x44CE_FADC_D54B_F9A9, /* 494 */ - 0x1312_200E_433C_7EE6, /* 495 */ - 0x9FFC_C84F_3A78_C748, /* 496 */ - 0xF0CD_1F72_2485_76BB, /* 497 */ - 0xEC69_7405_3638_CFE4, /* 498 */ - 0x2BA7_B67C_0CEC_4E4C, /* 499 */ - 0xAC2F_4DF3_E5CE_32ED, /* 500 */ - 0xCB33_D143_26EA_4C11, /* 501 */ - 0xA4E9_044C_C77E_58BC, /* 502 */ - 0x5F51_3293_D934_FCEF, /* 503 */ - 0x5DC9_6455_06E5_5444, /* 504 */ - 0x50DE_418F_317D_E40A, /* 505 */ - 0x388C_B31A_69DD_E259, /* 506 */ - 0x2DB4_A834_5582_0A86, /* 507 */ - 0x9010_A91E_8471_1AE9, /* 508 */ - 0x4DF7_F0B7_B149_8371, /* 509 */ - 0xD62A_2EAB_C097_7179, /* 510 */ - 0x22FA_C097_AA8D_5C0E, /* 511 */ -]; -static T3: [u64; 256] = [ - 0xF49F_CC2F_F1DA_F39B, /* 512 */ - 0x487F_D5C6_6FF2_9281, /* 513 */ - 0xE8A3_0667_FCDC_A83F, /* 514 */ - 0x2C9B_4BE3_D2FC_CE63, /* 515 */ - 0xDA3F_F74B_93FB_BBC2, /* 516 */ - 0x2FA1_65D2_FE70_BA66, /* 517 */ - 0xA103_E279_970E_93D4, /* 518 */ - 0xBECD_EC77_B0E4_5E71, /* 519 */ - 0xCFB4_1E72_3985_E497, /* 520 */ - 0xB70A_AA02_5EF7_5017, /* 521 */ - 0xD423_09F0_3840_B8E0, /* 522 */ - 0x8EFC_1AD0_3589_8579, /* 523 */ - 0x96C6_920B_E2B2_ABC5, /* 524 */ - 0x66AF_4163_375A_9172, /* 525 */ - 0x2174_ABDC_CA71_27FB, /* 526 */ - 0xB33C_CEA6_4A72_FF41, /* 527 */ - 0xF04A_4933_0830_66A5, /* 528 */ - 0x8D97_0ACD_D728_9AF5, /* 529 */ - 0x8F96_E8E0_31C8_C25E, /* 530 */ - 0xF3FE_C022_7687_5D47, /* 531 */ - 0xEC7B_F310_0561_90DD, /* 532 */ - 0xF5AD_B0AE_BB0F_1491, /* 533 */ - 0x9B50_F885_0FD5_8892, /* 534 */ - 0x4975_4883_58B7_4DE8, /* 535 */ - 0xA335_4FF6_9153_1C61, /* 536 */ - 0x0702_BBE4_81D2_C6EE, /* 537 */ - 0x89FB_2405_7DED_ED98, /* 538 */ - 0xAC30_7513_8596_E902, /* 539 */ - 0x1D2D_3580_1727_72ED, /* 540 */ - 0xEB73_8FC2_8E6B_C30D, /* 541 */ - 0x5854_EF8F_6304_4326, /* 542 */ - 0x9E5C_5232_5ADD_3BBE, /* 543 */ - 0x90AA_53CF_325C_4623, /* 544 */ - 0xC1D2_4D51_349D_D067, /* 545 */ - 0x2051_CFEE_A69E_A624, /* 546 */ - 0x1322_0F0A_862E_7E4F, /* 547 */ - 0xCE39_3994_04E0_4864, /* 548 */ - 0xD9C4_2CA4_7086_FCB7, /* 549 */ - 0x685A_D223_8A03_E7CC, /* 550 */ - 0x0664_84B2_AB2F_F1DB, /* 551 */ - 0xFE9D_5D70_EFBF_79EC, /* 552 */ - 0x5B13_B9DD_9C48_1854, /* 553 */ - 0x15F0_D475_ED15_09AD, /* 554 */ - 0x0BEB_CD06_0EC7_9851, /* 555 */ - 0xD58C_6791_183A_B7F8, /* 556 */ - 0xD118_7C50_52F3_EEE4, /* 557 */ - 0xC95D_1192_E54E_82FF, /* 558 */ - 0x86EE_A14C_B9AC_6CA2, /* 559 */ - 0x3485_BEB1_5367_7D5D, /* 560 */ - 0xDD19_1D78_1F8C_492A, /* 561 */ - 0xF608_66BA_A784_EBF9, /* 562 */ - 0x518F_643B_A2D0_8C74, /* 563 */ - 0x8852_E956_E108_7C22, /* 564 */ - 0xA768_CB8D_C410_AE8D, /* 565 */ - 0x3804_7726_BFEC_8E1A, /* 566 */ - 0xA677_38B4_CD3B_45AA, /* 567 */ - 0xAD16_691C_EC0D_DE19, /* 568 */ - 0xC6D4_3193_8046_2E07, /* 569 */ - 0xC5A5_876D_0BA6_1938, /* 570 */ - 0x16B9_FA1F_A58F_D840, /* 571 */ - 0x188A_B117_3CA7_4F18, /* 572 */ - 0xABDA_2F98_C99C_021F, /* 573 */ - 0x3E05_80AB_134A_E816, /* 574 */ - 0x5F3B_05B7_7364_5ABB, /* 575 */ - 0x2501_A2BE_5575_F2F6, /* 576 */ - 0x1B2F_7400_4E7E_8BA9, /* 577 */ - 0x1CD7_5803_71E8_D953, /* 578 */ - 0x7F6E_D895_6276_4E30, /* 579 */ - 0xB159_26FF_596F_003D, /* 580 */ - 0x9F65_293D_A8C5_D6B9, /* 581 */ - 0x6ECE_F04D_D690_F84C, /* 582 */ - 0x4782_275F_FF33_AF88, /* 583 */ - 0xE414_3308_3F82_0801, /* 584 */ - 0xFD0D_FE40_9A1A_F9B5, /* 585 */ - 0x4325_A334_2CDB_396B, /* 586 */ - 0x8AE7_7E62_B301_B252, /* 587 */ - 0xC36F_9E9F_6655_615A, /* 588 */ - 0x8545_5A2D_92D3_2C09, /* 589 */ - 0xF2C7_DEA9_4947_7485, /* 590 */ - 0x63CF_B4C1_33A3_9EBA, /* 591 */ - 0x83B0_40CC_6EBC_5462, /* 592 */ - 0x3B94_54C8_FDB3_26B0, /* 593 */ - 0x56F5_6A9E_87FF_D78C, /* 594 */ - 0x2DC2_940D_99F4_2BC6, /* 595 */ - 0x98F7_DF09_6B09_6E2D, /* 596 */ - 0x19A6_E01E_3AD8_52BF, /* 597 */ - 0x42A9_9CCB_DBD4_B40B, /* 598 */ - 0xA599_98AF_45E9_C559, /* 599 */ - 0x3662_95E8_07D9_3186, /* 600 */ - 0x6B48_181B_FAA1_F773, /* 601 */ - 0x1FEC_57E2_157A_0A1D, /* 602 */ - 0x4667_446A_F620_1AD5, /* 603 */ - 0xE615_EBCA_CFB0_F075, /* 604 */ - 0xB8F3_1F4F_6829_0778, /* 605 */ - 0x2271_3ED6_CE22_D11E, /* 606 */ - 0x3057_C1A7_2EC3_C93B, /* 607 */ - 0xCB46_ACC3_7C3F_1F2F, /* 608 */ - 0xDBB8_93FD_02AA_F50E, /* 609 */ - 0x331F_D92E_600B_9FCF, /* 610 */ - 0xA498_F961_48EA_3AD6, /* 611 */ - 0xA8D8_426E_8B6A_83EA, /* 612 */ - 0xA089_B274_B773_5CDC, /* 613 */ - 0x87F6_B373_1E52_4A11, /* 614 */ - 0x1188_08E5_CBC9_6749, /* 615 */ - 0x9906_E4C7_B19B_D394, /* 616 */ - 0xAFED_7F7E_9B24_A20C, /* 617 */ - 0x6509_EADE_EB36_44A7, /* 618 */ - 0x6C1E_F1D3_E8EF_0EDE, /* 619 */ - 0xB9C9_7D43_E979_8FB4, /* 620 */ - 0xA2F2_D784_740C_28A3, /* 621 */ - 0x7B84_9647_6197_566F, /* 622 */ - 0x7A5B_E3E6_B65F_069D, /* 623 */ - 0xF963_30ED_78BE_6F10, /* 624 */ - 0xEEE6_0DE7_7A07_6A15, /* 625 */ - 0x2B4B_EE4A_A08B_9BD0, /* 626 */ - 0x6A56_A63E_C7B8_894E, /* 627 */ - 0x0212_1359_BA34_FEF4, /* 628 */ - 0x4CBF_99F8_2837_03FC, /* 629 */ - 0x3980_7135_0CAF_30C8, /* 630 */ - 0xD0A7_7A89_F017_687A, /* 631 */ - 0xF1C1_A9EB_9E42_3569, /* 632 */ - 0x8C79_7628_2DEE_8199, /* 633 */ - 0x5D17_37A5_DD1F_7ABD, /* 634 */ - 0x4F53_433C_09A9_FA80, /* 635 */ - 0xFA8B_0C53_DF7C_A1D9, /* 636 */ - 0x3FD9_DCBC_886C_CB77, /* 637 */ - 0xC040_917C_A91B_4720, /* 638 */ - 0x7DD0_0142_F9D1_DCDF, /* 639 */ - 0x8476_FC1D_4F38_7B58, /* 640 */ - 0x23F8_E7C5_F331_6503, /* 641 */ - 0x032A_2244_E7E3_7339, /* 642 */ - 0x5C87_A5D7_50F5_A74B, /* 643 */ - 0x082B_4CC4_3698_992E, /* 644 */ - 0xDF91_7BEC_B858_F63C, /* 645 */ - 0x3270_B8FC_5BF8_6DDA, /* 646 */ - 0x10AE_72BB_29B5_DD76, /* 647 */ - 0x576A_C94E_7700_362B, /* 648 */ - 0x1AD1_12DA_C61E_FB8F, /* 649 */ - 0x691B_C30E_C5FA_A427, /* 650 */ - 0xFF24_6311_CC32_7143, /* 651 */ - 0x3142_368E_30E5_3206, /* 652 */ - 0x7138_0E31_E02C_A396, /* 653 */ - 0x958D_5C96_0AAD_76F1, /* 654 */ - 0xF8D6_F430_C16D_A536, /* 655 */ - 0xC8FF_D13F_1BE7_E1D2, /* 656 */ - 0x7578_AE66_004D_DBE1, /* 657 */ - 0x0583_3F01_067B_E646, /* 658 */ - 0xBB34_B5AD_3BFE_586D, /* 659 */ - 0x095F_34C9_A12B_97F0, /* 660 */ - 0x247A_B645_25D6_0CA8, /* 661 */ - 0xDCDB_C6F3_0174_77D1, /* 662 */ - 0x4A2E_14D4_DECA_D24D, /* 663 */ - 0xBDB5_E6D9_BE0A_1EEB, /* 664 */ - 0x2A7E_70F7_7943_01AB, /* 665 */ - 0xDEF4_2D8A_2705_40FD, /* 666 */ - 0x0107_8EC0_A34C_22C1, /* 667 */ - 0xE5DE_511A_F4C1_6387, /* 668 */ - 0x7EBB_3A52_BD9A_330A, /* 669 */ - 0x7769_7857_AA7D_6435, /* 670 */ - 0x004E_8316_03AE_4C32, /* 671 */ - 0xE7A2_1020_AD78_E312, /* 672 */ - 0x9D41_A70C_6AB4_20F2, /* 673 */ - 0x28E0_6C18_EA11_41E6, /* 674 */ - 0xD2B2_8CBD_984F_6B28, /* 675 */ - 0x26B7_5F6C_446E_9D83, /* 676 */ - 0xBA47_568C_4D41_8D7F, /* 677 */ - 0xD80B_ADBF_E618_3D8E, /* 678 */ - 0x0E20_6D7F_5F16_6044, /* 679 */ - 0xE258_A439_11CB_CA3E, /* 680 */ - 0x723A_1746_B21D_C0BC, /* 681 */ - 0xC7CA_A854_F5D7_CDD3, /* 682 */ - 0x7CAC_3288_3D26_1D9C, /* 683 */ - 0x7690_C264_23BA_942C, /* 684 */ - 0x17E5_5524_4780_42B8, /* 685 */ - 0xE0BE_4776_56A2_389F, /* 686 */ - 0x4D28_9B5E_67AB_2DA0, /* 687 */ - 0x4486_2B9C_8FBB_FD31, /* 688 */ - 0xB47C_C804_9D14_1365, /* 689 */ - 0x822C_1B36_2B91_C793, /* 690 */ - 0x4EB1_4655_FB13_DFD8, /* 691 */ - 0x1ECB_BA07_14E2_A97B, /* 692 */ - 0x6143_459D_5CDE_5F14, /* 693 */ - 0x53A8_FBF1_D5F0_AC89, /* 694 */ - 0x97EA_04D8_1C5E_5B00, /* 695 */ - 0x6221_81A8_D4FD_B3F3, /* 696 */ - 0xE9BC_D341_572A_1208, /* 697 */ - 0x1411_2586_43CC_E58A, /* 698 */ - 0x9144_C5FE_A4C6_E0A4, /* 699 */ - 0x0D33_D065_65CF_620F, /* 700 */ - 0x54A4_8D48_9F21_9CA1, /* 701 */ - 0xC43E_5EAC_6D63_C821, /* 702 */ - 0xA972_8B3A_7277_0DAF, /* 703 */ - 0xD793_4E7B_20DF_87EF, /* 704 */ - 0xE355_03B6_1A3E_86E5, /* 705 */ - 0xCAE3_21FB_C819_D504, /* 706 */ - 0x129A_50B3_AC60_BFA6, /* 707 */ - 0xCD5E_68EA_7E9F_B6C3, /* 708 */ - 0xB01C_9019_9483_B1C7, /* 709 */ - 0x3DE9_3CD5_C295_376C, /* 710 */ - 0xAED5_2EDF_2AB9_AD13, /* 711 */ - 0x2E60_F512_C0A0_7884, /* 712 */ - 0xBC3D_86A3_E362_10C9, /* 713 */ - 0x3526_9D9B_1639_51CE, /* 714 */ - 0x0C7D_6E2A_D0CD_B5FA, /* 715 */ - 0x59E8_6297_D87F_5733, /* 716 */ - 0x298E_F221_898D_B0E7, /* 717 */ - 0x5500_0029_D1A5_AA7E, /* 718 */ - 0x8BC0_8AE1_B506_1B45, /* 719 */ - 0xC2C3_1C2B_6C92_703A, /* 720 */ - 0x94CC_596B_AF25_EF42, /* 721 */ - 0x0A1D_73DB_2254_0456, /* 722 */ - 0x04B6_A0F9_D9C4_179A, /* 723 */ - 0xEFFD_AFA2_AE3D_3C60, /* 724 */ - 0xF7C8_075B_B494_96C4, /* 725 */ - 0x9CC5_C714_1D1C_D4E3, /* 726 */ - 0x78BD_1638_218E_5534, /* 727 */ - 0xB2F1_1568_F850_246A, /* 728 */ - 0xEDFA_BCFA_9502_BC29, /* 729 */ - 0x796C_E5F2_DA23_051B, /* 730 */ - 0xAAE1_28B0_DC93_537C, /* 731 */ - 0x3A49_3DA0_EE4B_29AE, /* 732 */ - 0xB5DF_6B2C_4168_95D7, /* 733 */ - 0xFCAB_BD25_122D_7F37, /* 734 */ - 0x7081_0B58_105D_C4B1, /* 735 */ - 0xE10F_DD37_F788_2A90, /* 736 */ - 0x524D_CAB5_518A_3F5C, /* 737 */ - 0x3C9E_8587_8451_255B, /* 738 */ - 0x4029_8281_19BD_34E2, /* 739 */ - 0x74A0_5B6F_5D3C_ECCB, /* 740 */ - 0xB610_0215_42E1_3ECA, /* 741 */ - 0x0FF9_79D1_2F59_E2AC, /* 742 */ - 0x6037_DA27_E4F9_CC50, /* 743 */ - 0x5E92_975A_0DF1_847D, /* 744 */ - 0xD66D_E190_D3E6_23FE, /* 745 */ - 0x5032_D6B8_7B56_8048, /* 746 */ - 0x9A36_B7CE_8235_216E, /* 747 */ - 0x8027_2A7A_24F6_4B4A, /* 748 */ - 0x93EF_ED8B_8C69_16F7, /* 749 */ - 0x37DD_BFF4_4CCE_1555, /* 750 */ - 0x4B95_DB5D_4B99_BD25, /* 751 */ - 0x92D3_FDA1_6981_2FC0, /* 752 */ - 0xFB1A_4A9A_9066_0BB6, /* 753 */ - 0x730C_1969_46A4_B9B2, /* 754 */ - 0x81E2_89AA_7F49_DA68, /* 755 */ - 0x6466_9A0F_83B1_A05F, /* 756 */ - 0x27B3_FF7D_9644_F48B, /* 757 */ - 0xCC6B_615C_8DB6_75B3, /* 758 */ - 0x674F_20B9_BCEB_BE95, /* 759 */ - 0x6F31_2382_7565_5982, /* 760 */ - 0x5AE4_8871_3E45_CF05, /* 761 */ - 0xBF61_9F99_54C2_1157, /* 762 */ - 0xEABA_C460_40A8_EAE9, /* 763 */ - 0x454C_6FE9_F2C0_C1CD, /* 764 */ - 0x419C_F649_6412_691C, /* 765 */ - 0xD3DC_3BEF_265B_0F70, /* 766 */ - 0x6D0E_60F5_C357_8A9E, /* 767 */ -]; -static T4: [u64; 256] = [ - 0x5B0E_6085_2632_3C55, /* 768 */ - 0x1A46_C1A9_FA1B_59F5, /* 769 */ - 0xA9E2_45A1_7C4C_8FFA, /* 770 */ - 0x65CA_5159_DB29_55D7, /* 771 */ - 0x05DB_0A76_CE35_AFC2, /* 772 */ - 0x81EA_C77E_A911_3D45, /* 773 */ - 0x528E_F88A_B6AC_0A0D, /* 774 */ - 0xA09E_A253_597B_E3FF, /* 775 */ - 0x430D_DFB3_AC48_CD56, /* 776 */ - 0xC4B3_A67A_F45C_E46F, /* 777 */ - 0x4ECE_CFD8_FBE2_D05E, /* 778 */ - 0x3EF5_6F10_B399_35F0, /* 779 */ - 0x0B22_D682_9CD6_19C6, /* 780 */ - 0x17FD_460A_74DF_2069, /* 781 */ - 0x6CF8_CC8E_8510_ED40, /* 782 */ - 0xD6C8_24BF_3A6E_CAA7, /* 783 */ - 0x6124_3D58_1A81_7049, /* 784 */ - 0x048B_ACB6_BBC1_63A2, /* 785 */ - 0xD9A3_8AC2_7D44_CC32, /* 786 */ - 0x7FDD_FF5B_AAF4_10AB, /* 787 */ - 0xAD6D_495A_A804_824B, /* 788 */ - 0xE1A6_A74F_2D8C_9F94, /* 789 */ - 0xD4F7_8512_35DE_E8E3, /* 790 */ - 0xFD4B_7F88_6540_D893, /* 791 */ - 0x247C_2004_2AA4_BFDA, /* 792 */ - 0x096E_A1C5_17D1_327C, /* 793 */ - 0xD569_66B4_361A_6685, /* 794 */ - 0x277D_A5C3_1221_057D, /* 795 */ - 0x94D5_9893_A43A_CFF7, /* 796 */ - 0x64F0_C51C_CDC0_2281, /* 797 */ - 0x3D33_BCC4_FF61_89DB, /* 798 */ - 0xE005_CB18_4CE6_6AF1, /* 799 */ - 0xFF5C_CD1D_1DB9_9BEA, /* 800 */ - 0xB0B8_54A7_FE42_980F, /* 801 */ - 0x7BD4_6A6A_718D_4B9F, /* 802 */ - 0xD10F_A8CC_22A5_FD8C, /* 803 */ - 0xD314_8495_2BE4_BD31, /* 804 */ - 0xC7FA_975F_CB24_3847, /* 805 */ - 0x4886_ED1E_5846_C407, /* 806 */ - 0x28CD_DB79_1EB7_0B04, /* 807 */ - 0xC2B0_0BE2_F573_417F, /* 808 */ - 0x5C95_9045_2180_F877, /* 809 */ - 0x7A6B_DDFF_F370_EB00, /* 810 */ - 0xCE50_9E38_D6D9_D6A4, /* 811 */ - 0xEBEB_0F00_647F_A702, /* 812 */ - 0x1DCC_06CF_7660_6F06, /* 813 */ - 0xE4D9_F28B_A286_FF0A, /* 814 */ - 0xD85A_305D_C918_C262, /* 815 */ - 0x475B_1D87_3222_5F54, /* 816 */ - 0x2D4F_B516_68CC_B5FE, /* 817 */ - 0xA679_B9D9_D72B_BA20, /* 818 */ - 0x5384_1C0D_912D_43A5, /* 819 */ - 0x3B7E_AA48_BF12_A4E8, /* 820 */ - 0x781E_0E47_F22F_1DDF, /* 821 */ - 0xEFF2_0CE6_0AB5_0973, /* 822 */ - 0x20D2_61D1_9DFF_B742, /* 823 */ - 0x16A1_2B03_062A_2E39, /* 824 */ - 0x1960_EB22_3965_0495, /* 825 */ - 0x251C_16FE_D50E_B8B8, /* 826 */ - 0x9AC0_C330_F826_016E, /* 827 */ - 0xED15_2665_953E_7671, /* 828 */ - 0x02D6_3194_A636_9570, /* 829 */ - 0x5074_F083_94B1_C987, /* 830 */ - 0x70BA_598C_90B2_5CE1, /* 831 */ - 0x794A_1581_0B97_42F6, /* 832 */ - 0x0D59_25E9_FCAF_8C6C, /* 833 */ - 0x3067_716C_D868_744E, /* 834 */ - 0x910A_B077_E8D7_731B, /* 835 */ - 0x6A61_BBDB_5AC4_2F61, /* 836 */ - 0x9351_3EFB_F085_1567, /* 837 */ - 0xF494_724B_9E83_E9D5, /* 838 */ - 0xE887_E198_5C09_648D, /* 839 */ - 0x34B1_D3C6_7537_0CFD, /* 840 */ - 0xDC35_E433_BC0D_255D, /* 841 */ - 0xD0AA_B842_3413_1BE0, /* 842 */ - 0x0804_2A50_B48B_7EAF, /* 843 */ - 0x9997_C4EE_44A3_AB35, /* 844 */ - 0x829A_7B49_2017_99D0, /* 845 */ - 0x263B_8307_B7C5_4441, /* 846 */ - 0x752F_95F4_FD6A_6CA6, /* 847 */ - 0x9272_1740_2C08_C6E5, /* 848 */ - 0x2A8A_B754_A795_D9EE, /* 849 */ - 0xA442_F755_2F72_943D, /* 850 */ - 0x2C31_334E_1978_1208, /* 851 */ - 0x4FA9_8D7C_EAEE_6291, /* 852 */ - 0x55C3_862F_665D_B309, /* 853 */ - 0xBD06_1017_5D53_B1F3, /* 854 */ - 0x46FE_6CB8_4041_3F27, /* 855 */ - 0x3FE0_3792_DF0C_FA59, /* 856 */ - 0xCFE7_0037_2EB8_5E8F, /* 857 */ - 0xA7BE_29E7_ADBC_E118, /* 858 */ - 0xE544_EE5C_DE84_31DD, /* 859 */ - 0x8A78_1B1B_41F1_873E, /* 860 */ - 0xA5C9_4C78_A0D2_F0E7, /* 861 */ - 0x3941_2E28_77B6_0728, /* 862 */ - 0xA126_5EF3_AFC9_A62C, /* 863 */ - 0xBCC2_770C_6A25_06C5, /* 864 */ - 0x3AB6_6DD5_DCE1_CE12, /* 865 */ - 0xE654_99D0_4A67_5B37, /* 866 */ - 0x7D8F_5234_81BF_D216, /* 867 */ - 0x0F6F_64FC_EC15_F389, /* 868 */ - 0x74EF_BE61_8B5B_13C8, /* 869 */ - 0xACDC_82B7_1427_3E1D, /* 870 */ - 0xDD40_BFE0_0319_9D17, /* 871 */ - 0x37E9_9257_E7E0_61F8, /* 872 */ - 0xFA52_6269_0477_5AAA, /* 873 */ - 0x8BBB_F63A_463D_56F9, /* 874 */ - 0xF001_3F15_43A2_6E64, /* 875 */ - 0xA830_7E9F_879E_C898, /* 876 */ - 0xCC4C_27A4_1501_77CC, /* 877 */ - 0x1B43_2F2C_CA1D_3348, /* 878 */ - 0xDE1D_1F8F_9F6F_A013, /* 879 */ - 0x6066_02A0_47A7_DDD6, /* 880 */ - 0xD237_AB64_CC1C_B2C7, /* 881 */ - 0x9B93_8E72_25FC_D1D3, /* 882 */ - 0xEC4E_0370_8E0F_F476, /* 883 */ - 0xFEB2_FBDA_3D03_C12D, /* 884 */ - 0xAE0B_CED2_EE43_889A, /* 885 */ - 0x22CB_8923_EBFB_4F43, /* 886 */ - 0x6936_0D01_3CF7_396D, /* 887 */ - 0x855E_3602_D2D4_E022, /* 888 */ - 0x0738_05BA_D01F_784C, /* 889 */ - 0x33E1_7A13_3852_F546, /* 890 */ - 0xDF48_7405_8AC7_B638, /* 891 */ - 0xBA92_B29C_678A_A14A, /* 892 */ - 0x0CE8_9FC7_6CFA_ADCD, /* 893 */ - 0x5F9D_4E09_0833_9E34, /* 894 */ - 0xF1AF_E929_1F59_23B9, /* 895 */ - 0x6E34_80F6_0F4A_265F, /* 896 */ - 0xEEBF_3A2A_B29B_841C, /* 897 */ - 0xE219_38A8_8F91_B4AD, /* 898 */ - 0x57DF_EFF8_45C6_D3C3, /* 899 */ - 0x2F00_6B0B_F62C_AAF2, /* 900 */ - 0x62F4_79EF_6F75_EE78, /* 901 */ - 0x11A5_5AD4_1C89_16A9, /* 902 */ - 0xF229_D290_84FE_D453, /* 903 */ - 0x42F1_C27B_16B0_00E6, /* 904 */ - 0x2B1F_7674_9823_C074, /* 905 */ - 0x4B76_ECA3_C274_5360, /* 906 */ - 0x8C98_F463_B916_91BD, /* 907 */ - 0x14BC_C93C_F1AD_E66A, /* 908 */ - 0x8885_213E_6D45_8397, /* 909 */ - 0x8E17_7DF0_274D_4711, /* 910 */ - 0xB49B_73B5_503F_2951, /* 911 */ - 0x1016_8168_C3F9_6B6B, /* 912 */ - 0x0E3D_963B_63CA_B0AE, /* 913 */ - 0x8DFC_4B56_55A1_DB14, /* 914 */ - 0xF789_F135_6E14_DE5C, /* 915 */ - 0x683E_68AF_4E51_DAC1, /* 916 */ - 0xC9A8_4F9D_8D4B_0FD9, /* 917 */ - 0x3691_E03F_52A0_F9D1, /* 918 */ - 0x5ED8_6E46_E187_8E80, /* 919 */ - 0x3C71_1A0E_99D0_7150, /* 920 */ - 0x5A08_65B2_0C4E_9310, /* 921 */ - 0x56FB_FC1F_E4F0_682E, /* 922 */ - 0xEA8D_5DE3_105E_DF9B, /* 923 */ - 0x71AB_FDB1_2379_187A, /* 924 */ - 0x2EB9_9DE1_BEE7_7B9C, /* 925 */ - 0x21EC_C0EA_33CF_4523, /* 926 */ - 0x59A4_D752_1805_C7A1, /* 927 */ - 0x3896_F5EB_56AE_7C72, /* 928 */ - 0xAA63_8F3D_B18F_75DC, /* 929 */ - 0x9F39_358D_ABE9_808E, /* 930 */ - 0xB7DE_FA91_C00B_72AC, /* 931 */ - 0x6B55_41FD_6249_2D92, /* 932 */ - 0x6DC6_DEE8_F92E_4D5B, /* 933 */ - 0x353F_57AB_C4BE_EA7E, /* 934 */ - 0x7357_69D6_DA56_90CE, /* 935 */ - 0x0A23_4AA6_4239_1484, /* 936 */ - 0xF6F9_5080_28F8_0D9D, /* 937 */ - 0xB8E3_19A2_7AB3_F215, /* 938 */ - 0x31AD_9C11_5134_1A4D, /* 939 */ - 0x773C_22A5_7BEF_5805, /* 940 */ - 0x45C7_561A_0796_8633, /* 941 */ - 0xF913_DA9E_249D_BE36, /* 942 */ - 0xDA65_2D9B_78A6_4C68, /* 943 */ - 0x4C27_A97F_3BC3_34EF, /* 944 */ - 0x7662_1220_E66B_17F4, /* 945 */ - 0x9677_4389_9ACD_7D0B, /* 946 */ - 0xF3EE_5BCA_E0ED_6782, /* 947 */ - 0x409F_7536_00C8_79FC, /* 948 */ - 0x06D0_9A39_B592_6DB6, /* 949 */ - 0x6F83_AEB0_317A_C588, /* 950 */ - 0x01E6_CA4A_8638_1F21, /* 951 */ - 0x66FF_3462_D19F_3025, /* 952 */ - 0x7220_7C24_DDFD_3BFB, /* 953 */ - 0x4AF6_B6D3_E2EC_E2EB, /* 954 */ - 0x9C99_4DBE_C7EA_08DE, /* 955 */ - 0x49AC_E597_B09A_8BC4, /* 956 */ - 0xB38C_4766_CF07_97BA, /* 957 */ - 0x131B_9373_C57C_2A75, /* 958 */ - 0xB182_2CCE_6193_1E58, /* 959 */ - 0x9D75_55B9_09BA_1C0C, /* 960 */ - 0x127F_AFDD_937D_11D2, /* 961 */ - 0x29DA_3BAD_C66D_92E4, /* 962 */ - 0xA2C1_D571_54C2_ECBC, /* 963 */ - 0x58C5_134D_82F6_FE24, /* 964 */ - 0x1C3A_E351_5B62_274F, /* 965 */ - 0xE907_C82E_01CB_8126, /* 966 */ - 0xF8ED_0919_13E3_7FCB, /* 967 */ - 0x3249_D8F9_C800_46C9, /* 968 */ - 0x80CF_9BED_E388_FB63, /* 969 */ - 0x1881_539A_116C_F19E, /* 970 */ - 0x5103_F3F7_6BD5_2457, /* 971 */ - 0x15B7_E6F5_AE47_F7A8, /* 972 */ - 0xDBD7_C6DE_D47E_9CCF, /* 973 */ - 0x44E5_5C41_0228_BB1A, /* 974 */ - 0xB647_D425_5EDB_4E99, /* 975 */ - 0x5D11_882B_B8AA_FC30, /* 976 */ - 0xF509_8BBB_29D3_212A, /* 977 */ - 0x8FB5_EA14_E902_96B3, /* 978 */ - 0x677B_9421_57DD_025A, /* 979 */ - 0xFB58_E7C0_A390_ACB5, /* 980 */ - 0x89D3_674C_83BD_4A01, /* 981 */ - 0x9E2D_A4DF_4BF3_B93B, /* 982 */ - 0xFCC4_1E32_8CAB_4829, /* 983 */ - 0x03F3_8C96_BA58_2C52, /* 984 */ - 0xCAD1_BDBD_7FD8_5DB2, /* 985 */ - 0xBBB4_42C1_6082_AE83, /* 986 */ - 0xB95F_E86B_A5DA_9AB0, /* 987 */ - 0xB22E_0467_3771_A93F, /* 988 */ - 0x8453_58C9_4931_52D8, /* 989 */ - 0xBE2A_4886_97B4_541E, /* 990 */ - 0x95A2_DC2D_D38E_6966, /* 991 */ - 0xC02C_11AC_923C_852B, /* 992 */ - 0x2388_B199_0DF2_A87B, /* 993 */ - 0x7C80_08FA_1B4F_37BE, /* 994 */ - 0x1F70_D0C8_4D54_E503, /* 995 */ - 0x5490_ADEC_7ECE_57D4, /* 996 */ - 0x002B_3C27_D906_3A3A, /* 997 */ - 0x7EAE_A384_8030_A2BF, /* 998 */ - 0xC602_326D_ED20_03C0, /* 999 */ - 0x83A7_287D_69A9_4086, /* 1000 */ - 0xC57A_5FCB_30F5_7A8A, /* 1001 */ - 0xB568_44E4_79EB_E779, /* 1002 */ - 0xA373_B40F_05DC_BCE9, /* 1003 */ - 0xD71A_786E_8857_0EE2, /* 1004 */ - 0x879C_BACD_BDE8_F6A0, /* 1005 */ - 0x976A_D1BC_C164_A32F, /* 1006 */ - 0xAB21_E25E_9666_D78B, /* 1007 */ - 0x9010_63AA_E5E5_C33C, /* 1008 */ - 0x9818_B344_4869_8D90, /* 1009 */ - 0xE364_87AE_3E1E_8ABB, /* 1010 */ - 0xAFBD_F931_893B_DCB4, /* 1011 */ - 0x6345_A0DC_5FBB_D519, /* 1012 */ - 0x8628_FE26_9B94_65CA, /* 1013 */ - 0x1E5D_0160_3F9C_51EC, /* 1014 */ - 0x4DE4_4006_A150_49B7, /* 1015 */ - 0xBF6C_70E5_F776_CBB1, /* 1016 */ - 0x4112_18F2_EF55_2BED, /* 1017 */ - 0xCB0C_0708_705A_36A3, /* 1018 */ - 0xE74D_1475_4F98_6044, /* 1019 */ - 0xCD56_D943_0EA8_280E, /* 1020 */ - 0xC125_91D7_535F_5065, /* 1021 */ - 0xC832_23F1_720A_EF96, /* 1022 */ - 0xC3A0_396F_7363_A51F, /* 1023 */ -]; +/// Tiger hasher state. +pub type Tiger = CoreWrapper; +/// Tiger2 hasher state. +pub type Tiger2 = CoreWrapper; diff --git a/tiger/src/tables.rs b/tiger/src/tables.rs new file mode 100644 index 000000000..dc6e2c21e --- /dev/null +++ b/tiger/src/tables.rs @@ -0,0 +1,1035 @@ +pub(crate) static T1: [u64; 256] = [ + 0x02AA_B17C_F7E9_0C5E, + 0xAC42_4B03_E243_A8EC, + 0x72CD_5BE3_0DD5_FCD3, + 0x6D01_9B93_F6F9_7F3A, + 0xCD99_78FF_D21F_9193, + 0x7573_A1C9_7080_29E2, + 0xB164_326B_922A_83C3, + 0x4688_3EEE_0491_5870, + 0xEAAC_E305_7103_ECE6, + 0xC541_69B8_08A3_535C, + 0x4CE7_5491_8DDE_C47C, + 0x0AA2_F4DF_DC0D_F40C, + 0x10B7_6F18_A74D_BEFA, + 0xC6CC_B623_5AD1_AB6A, + 0x1372_6121_572F_E2FF, + 0x1A48_8C6F_199D_921E, + 0x4BC9_F9F4_DA00_07CA, + 0x26F5_E6F6_E852_41C7, + 0x8590_79DB_EA59_47B6, + 0x4F18_85C5_C99E_8C92, + 0xD78E_761E_A96F_864B, + 0x8E36_428C_52B5_C17D, + 0x69CF_6827_3730_63C1, + 0xB607_C93D_9BB4_C56E, + 0x7D82_0E76_0E76_B5EA, + 0x645C_9CC6_F07F_DC42, + 0xBF38_A078_2433_42E0, + 0x5F6B_343C_9D2E_7D04, + 0xF2C2_8AEB_600B_0EC6, + 0x6C0E_D85F_7254_BCAC, + 0x7159_2281_A4DB_4FE5, + 0x1967_FA69_CE0F_ED9F, + 0xFD52_93F8_B965_45DB, + 0xC879_E9D7_F2A7_600B, + 0x8602_4892_0193_194E, + 0xA4F9_533B_2D9C_C0B3, + 0x9053_836C_1595_7613, + 0xDB6D_CF8A_FC35_7BF1, + 0x18BE_EA7A_7A37_0F57, + 0x0371_17CA_50B9_9066, + 0x6AB3_0A97_7442_4A35, + 0xF4E9_2F02_E325_249B, + 0x7739_DB07_061C_CAE1, + 0xD8F3_B49C_ECA4_2A05, + 0xBD56_BE3F_5138_2F73, + 0x45FA_ED58_43B0_BB28, + 0x1C81_3D5C_11BF_1F83, + 0x8AF0_E4B6_D75F_A169, + 0x33EE_18A4_87AD_9999, + 0x3C26_E8EA_B1C9_4410, + 0xB510_102B_C0A8_22F9, + 0x141E_EF31_0CE6_123B, + 0xFC65_B900_59DD_B154, + 0xE015_8640_C5E0_E607, + 0x884E_0798_26C3_A3CF, + 0x930D_0D95_23C5_35FD, + 0x3563_8D75_4E9A_2B00, + 0x4085_FCCF_4046_9DD5, + 0xC4B1_7AD2_8BE2_3A4C, + 0xCAB2_F0FC_6A3E_6A2E, + 0x2860_971A_6B94_3FCD, + 0x3DDE_6EE2_12E3_0446, + 0x6222_F32A_E017_65AE, + 0x5D55_0BB5_4783_08FE, + 0xA9EF_A98D_A0ED_A22A, + 0xC351_A716_86C4_0DA7, + 0x1105_586D_9C86_7C84, + 0xDCFF_EE85_FDA2_2853, + 0xCCFB_D026_2C5E_EF76, + 0xBAF2_94CB_8990_D201, + 0xE694_64F5_2AFA_D975, + 0x94B0_13AF_DF13_3E14, + 0x06A7_D1A3_2823_C958, + 0x6F95_FE51_30F6_1119, + 0xD92A_B34E_462C_06C0, + 0xED7B_DE33_887C_71D2, + 0x7974_6D6E_6518_393E, + 0x5BA4_1938_5D71_3329, + 0x7C1B_A6B9_48A9_7564, + 0x3198_7C19_7BFD_AC67, + 0xDE6C_23C4_4B05_3D02, + 0x581C_49FE_D002_D64D, + 0xDD47_4D63_3826_1571, + 0xAA45_46C3_E473_D062, + 0x928F_CE34_9455_F860, + 0x4816_1BBA_CAAB_94D9, + 0x6391_2430_770E_6F68, + 0x6EC8_A5E6_02C6_641C, + 0x8728_2515_337D_DD2B, + 0x2CDA_6B42_034B_701B, + 0xB03D_37C1_81CB_096D, + 0xE108_4382_66C7_1C6F, + 0x2B31_80C7_EB51_B255, + 0xDF92_B82F_96C0_8BBC, + 0x5C68_C8C0_A632_F3BA, + 0x5504_CC86_1C3D_0556, + 0xABBF_A4E5_5FB2_6B8F, + 0x4184_8B0A_B3BA_CEB4, + 0xB334_A273_AA44_5D32, + 0xBCA6_96F0_A85A_D881, + 0x24F6_EC65_B528_D56C, + 0x0CE1_512E_90F4_524A, + 0x4E9D_D79D_5506_D35A, + 0x2589_05FA_C6CE_9779, + 0x2019_295B_3E10_9B33, + 0xF8A9_478B_73A0_54CC, + 0x2924_F2F9_3441_7EB0, + 0x3993_357D_536D_1BC4, + 0x38A8_1AC2_1DB6_FF8B, + 0x47C4_FBF1_7D60_16BF, + 0x1E0F_AADD_7667_E3F5, + 0x7ABC_FF62_938B_EB96, + 0xA78D_AD94_8FC1_79C9, + 0x8F1F_98B7_2911_E50D, + 0x61E4_8EAE_2712_1A91, + 0x4D62_F7AD_3185_9808, + 0xECEB_A345_EF5C_EAEB, + 0xF5CE_B25E_BC96_84CE, + 0xF633_E20C_B7F7_6221, + 0xA32C_DF06_AB82_93E4, + 0x985A_202C_A5EE_2CA4, + 0xCF0B_8447_CC8A_8FB1, + 0x9F76_5244_9798_59A3, + 0xA8D5_16B1_A124_0017, + 0x0BD7_BA3E_BB5D_C726, + 0xE54B_CA55_B86A_DB39, + 0x1D7A_3AFD_6C47_8063, + 0x519E_C608_E766_9EDD, + 0x0E57_15A2_D149_AA23, + 0x177D_4571_848F_F194, + 0xEEB5_5F32_4101_4C22, + 0x0F5E_5CA1_3A6E_2EC2, + 0x8029_927B_75F5_C361, + 0xAD13_9FAB_C3D6_E436, + 0x0D5D_F1A9_4CCF_402F, + 0x3E8B_D948_BEA5_DFC8, + 0xA5A0_D357_BD3F_F77E, + 0xA2D1_2E25_1F74_F645, + 0x66FD_9E52_5E81_A082, + 0x2E0C_90CE_7F68_7A49, + 0xC2E8_BCBE_BA97_3BC5, + 0x0000_01BC_E509_745F, + 0x4237_77BB_E6DA_B3D6, + 0xD166_1C7E_AEF0_6EB5, + 0xA178_1F35_4DAA_CFD8, + 0x2D11_284A_2B16_AFFC, + 0xF1FC_4F67_FA89_1D1F, + 0x73EC_C25D_CB92_0ADA, + 0xAE61_0C22_C2A1_2651, + 0x96E0_A810_D356_B78A, + 0x5A9A_381F_2FE7_870F, + 0xD5AD_62ED_E94E_5530, + 0xD225_E5E8_368D_1427, + 0x6597_7B70_C7AF_4631, + 0x99F8_89B2_DE39_D74F, + 0x233F_30BF_54E1_D143, + 0x9A96_75D3_D9A6_3C97, + 0x5470_554F_F334_F9A8, + 0x166A_CB74_4A4F_5688, + 0x70C7_4CAA_B2E4_AEAD, + 0xF0D0_9164_6F29_4D12, + 0x57B8_2A89_6840_31D1, + 0xEFD9_5A5A_61BE_0B6B, + 0x2FBD_12E9_69F2_F29A, + 0x9BD3_7013_FEFF_9FE8, + 0x3F9B_0404_D608_5A06, + 0x4940_C1F3_166C_FE15, + 0x0954_2C4D_CDF3_DEFB, + 0xB4C5_2183_85CD_5CE3, + 0xC935_B7DC_4462_A641, + 0x3417_F8A6_8ED3_B63F, + 0xB809_5929_5B21_5B40, + 0xF99C_DAEF_3B8C_8572, + 0x018C_0614_F8FC_B95D, + 0x1B14_ACCD_1A3A_CDF3, + 0x84D4_71F2_00BB_732D, + 0xC1A3_110E_95E8_DA16, + 0x430A_7220_BF1A_82B8, + 0xB77E_090D_39DF_210E, + 0x5EF4_BD9F_3CD0_5E9D, + 0x9D4F_F6DA_7E57_A444, + 0xDA1D_60E1_83D4_A5F8, + 0xB287_C384_1799_8E47, + 0xFE3E_DC12_1BB3_1886, + 0xC7FE_3CCC_980C_CBEF, + 0xE46F_B590_189B_FD03, + 0x3732_FD46_9A4C_57DC, + 0x7EF7_00A0_7CF1_AD65, + 0x59C6_4468_A31D_8859, + 0x762F_B0B4_D45B_61F6, + 0x155B_AED0_9904_7718, + 0x6875_5E4C_3D50_BAA6, + 0xE921_4E7F_22D8_B4DF, + 0x2ADD_BF53_2EAC_95F4, + 0x32AE_3909_B4BD_0109, + 0x834D_F537_B08E_3450, + 0xFA20_9DA8_4220_728D, + 0x9E69_1D9B_9EFE_23F7, + 0x0446_D288_C4AE_8D7F, + 0x7B4C_C524_E169_785B, + 0x21D8_7F01_35CA_1385, + 0xCEBB_400F_137B_8AA5, + 0x272E_2B66_5807_96BE, + 0x3612_2641_25C2_B0DE, + 0x0577_02BD_AD1E_FBB2, + 0xD4BA_BB8E_ACF8_4BE9, + 0x9158_3139_641B_C67B, + 0x8BDC_2DE0_8036_E024, + 0x603C_8156_F49F_68ED, + 0xF7D2_36F7_DBEF_5111, + 0x9727_C459_8AD2_1E80, + 0xA08A_0896_670A_5FD7, + 0xCB4A_8F43_09EB_A9CB, + 0x81AF_564B_0F70_36A1, + 0xC0B9_9AA7_7819_9ABD, + 0x959F_1EC8_3FC8_E952, + 0x8C50_5077_794A_81B9, + 0x3ACA_AF8F_0563_38F0, + 0x07B4_3F50_627A_6778, + 0x4A44_AB49_F5EC_CC77, + 0x3BC3_D6E4_B679_EE98, + 0x9CC0_D4D1_CF14_108C, + 0x4406_C00B_206B_C8A0, + 0x82A1_8854_C8D7_2D89, + 0x67E3_66B3_5C3C_432C, + 0xB923_DD61_102B_37F2, + 0x56AB_2779_D884_271D, + 0xBE83_E1B0_FF15_25AF, + 0xFB7C_65D4_217E_49A9, + 0x6BDB_E0E7_6D48_E7D4, + 0x08DF_8287_45D9_179E, + 0x22EA_6A9A_DD53_BD34, + 0xE36E_141C_5622_200A, + 0x7F80_5D1B_8CB7_50EE, + 0xAFE5_C7A5_9F58_E837, + 0xE27F_996A_4FB1_C23C, + 0xD386_7DFB_0775_F0D0, + 0xD0E6_73DE_6E88_891A, + 0x123A_EB9E_AFB8_6C25, + 0x30F1_D5D5_C145_B895, + 0xBB43_4A2D_EE72_69E7, + 0x78CB_67EC_F931_FA38, + 0xF33B_0372_323B_BF9C, + 0x52D6_6336_FB27_9C74, + 0x505F_33AC_0AFB_4EAA, + 0xE8A5_CD99_A2CC_E187, + 0x5349_7480_1E2D_30BB, + 0x8D2D_5711_D587_6D90, + 0x1F1A_4128_91BC_038E, + 0xD6E2_E71D_82E5_6648, + 0x7403_6C3A_4977_32B7, + 0x89B6_7ED9_6361_F5AB, + 0xFFED_95D8_F1EA_02A2, + 0xE72B_3BD6_1464_D43D, + 0xA630_0F17_0BDC_4820, + 0xEBC1_8760_ED78_A77A, +]; + +pub(crate) static T2: [u64; 256] = [ + 0xE6A6_BE5A_05A1_2138, + 0xB5A1_22A5_B4F8_7C98, + 0x563C_6089_140B_6990, + 0x4C46_CB2E_391F_5DD5, + 0xD932_ADDB_C9B7_9434, + 0x08EA_70E4_2015_AFF5, + 0xD765_A667_3E47_8CF1, + 0xC4FB_757E_AB27_8D99, + 0xDF11_C686_2D6E_0692, + 0xDDEB_84F1_0D7F_3B16, + 0x6F2E_F604_A665_EA04, + 0x4A8E_0F0F_F0E0_DFB3, + 0xA5ED_EEF8_3DBC_BA51, + 0xFC4F_0A2A_0EA4_371E, + 0xE83E_1DA8_5CB3_8429, + 0xDC8F_F882_BA1B_1CE2, + 0xCD45_505E_8353_E80D, + 0x18D1_9A00_D4DB_0717, + 0x34A0_CFED_A5F3_8101, + 0x0BE7_7E51_8887_CAF2, + 0x1E34_1438_B3C4_5136, + 0xE057_97F4_9089_CCF9, + 0xFFD2_3F9D_F259_1D14, + 0x543D_DA22_8595_C5CD, + 0x661F_81FD_9905_2A33, + 0x8736_E641_DB0F_7B76, + 0x1522_7725_418E_5307, + 0xE25F_7F46_162E_B2FA, + 0x48A8_B212_6C13_D9FE, + 0xAFDC_5417_92E7_6EEA, + 0x03D9_12BF_C6D1_898F, + 0x31B1_AAFA_1B83_F51B, + 0xF1AC_2796_E42A_B7D9, + 0x40A3_A7D7_FCD2_EBAC, + 0x1056_136D_0AFB_BCC5, + 0x7889_E1DD_9A6D_0C85, + 0xD335_2578_2A79_74AA, + 0xA7E2_5D09_078A_C09B, + 0xBD41_38B3_EAC6_EDD0, + 0x920A_BFBE_71EB_9E70, + 0xA2A5_D0F5_4FC2_625C, + 0xC054_E36B_0B12_90A3, + 0xF6DD_59FF_62FE_932B, + 0x3537_3545_11A8_AC7D, + 0xCA84_5E91_72FA_DCD4, + 0x84F8_2B60_329D_20DC, + 0x79C6_2CE1_CD67_2F18, + 0x8B09_A2AD_D124_642C, + 0xD0C1_E96A_19D9_E726, + 0x5A78_6A9B_4BA9_500C, + 0x0E02_0336_634C_43F3, + 0xC17B_474A_EB66_D822, + 0x6A73_1AE3_EC9B_AAC2, + 0x8226_667A_E084_0258, + 0x67D4_5676_91CA_ECA5, + 0x1D94_155C_4875_ADB5, + 0x6D00_FD98_5B81_3FDF, + 0x5128_6EFC_B774_CD06, + 0x5E88_3447_1FA7_44AF, + 0xF72C_A0AE_E761_AE2E, + 0xBE40_E4CD_AEE8_E09A, + 0xE997_0BBB_5118_F665, + 0x726E_4BEB_33DF_1964, + 0x703B_0007_2919_9762, + 0x4631_D816_F5EF_30A7, + 0xB880_B5B5_1504_A6BE, + 0x6417_93C3_7ED8_4B6C, + 0x7B21_ED77_F6E9_7D96, + 0x7763_0631_2EF9_6B73, + 0xAE52_8948_E86F_F3F4, + 0x53DB_D7F2_86A3_F8F8, + 0x16CA_DCE7_4CFC_1063, + 0x005C_19BD_FA52_C6DD, + 0x6886_8F5D_64D4_6AD3, + 0x3A9D_512C_CF1E_186A, + 0x367E_62C2_3856_60AE, + 0xE359_E7EA_77DC_B1D7, + 0x526C_0773_749A_BE6E, + 0x735A_E5F9_D09F_734B, + 0x493F_C7CC_8A55_8BA8, + 0xB0B9_C153_3041_AB45, + 0x3219_58BA_470A_59BD, + 0x852D_B00B_5F46_C393, + 0x9120_9B2B_D336_B0E5, + 0x6E60_4F7D_659E_F19F, + 0xB99A_8AE2_782C_CB24, + 0xCCF5_2AB6_C814_C4C7, + 0x4727_D9AF_BE11_727B, + 0x7E95_0D0C_0121_B34D, + 0x756F_4356_70AD_471F, + 0xF5AD_D442_615A_6849, + 0x4E87_E099_80B9_957A, + 0x2ACF_A1DF_50AE_E355, + 0xD898_263A_FD2F_D556, + 0xC8F4_924D_D80C_8FD6, + 0xCF99_CA3D_754A_173A, + 0xFE47_7BAC_AF91_BF3C, + 0xED53_71F6_D690_C12D, + 0x831A_5C28_5E68_7094, + 0xC5D3_C90A_3708_A0A4, + 0x0F7F_9037_17D0_6580, + 0x19F9_BB13_B8FD_F27F, + 0xB1BD_6F1B_4D50_2843, + 0x1C76_1BA3_8FFF_4012, + 0x0D15_30C4_E2E2_1F3B, + 0x8943_CE69_A737_2C8A, + 0xE518_4E11_FEB5_CE66, + 0x618B_DB80_BD73_6621, + 0x7D29_BAD6_8B57_4D0B, + 0x81BB_613E_25E6_FE5B, + 0x071C_9C10_BC07_913F, + 0xC7BE_EB79_09AC_2D97, + 0xC3E5_8D35_3BC5_D757, + 0xEB01_7892_F38F_61E8, + 0xD4EF_FB9C_9B1C_C21A, + 0x9972_7D26_F494_F7AB, + 0xA3E0_63A2_956B_3E03, + 0x9D4A_8B9A_4AA0_9C30, + 0x3F6A_B7D5_0009_0FB4, + 0x9CC0_F2A0_5726_8AC0, + 0x3DEE_9D2D_EDBF_42D1, + 0x330F_49C8_7960_A972, + 0xC6B2_7202_8742_1B41, + 0x0AC5_9EC0_7C00_369C, + 0xEF4E_AC49_CB35_3425, + 0xF450_244E_EF01_29D8, + 0x8ACC_46E5_CAF4_DEB6, + 0x2FFE_AB63_9892_63F7, + 0x8F7C_B9FE_5D7A_4578, + 0x5BD8_F764_4E63_4635, + 0x427A_7315_BF2D_C900, + 0x17D0_C4AA_2125_261C, + 0x3992_486C_9351_8E50, + 0xB4CB_FEE0_A2D7_D4C3, + 0x7C75_D620_2C5D_DD8D, + 0xDBC2_95D8_E35B_6C61, + 0x60B3_69D3_0203_2B19, + 0xCE42_685F_DCE4_4132, + 0x06F3_DDB9_DDF6_5610, + 0x8EA4_D21D_B5E1_48F0, + 0x20B0_FCE6_2FCD_496F, + 0x2C1B_9123_58B0_EE31, + 0xB283_17B8_18F5_A308, + 0xA89C_1E18_9CA6_D2CF, + 0x0C6B_1857_6AAA_DBC8, + 0xB65D_EAA9_1299_FAE3, + 0xFB2B_794B_7F10_27E7, + 0x04E4_317F_443B_5BEB, + 0x4B85_2D32_5939_D0A6, + 0xD5AE_6BEE_FB20_7FFC, + 0x3096_82B2_81C7_D374, + 0xBAE3_09A1_94C3_B475, + 0x8CC3_F97B_13B4_9F05, + 0x98A9_422F_F829_3967, + 0x244B_16B0_1076_FF7C, + 0xF8BF_571C_663D_67EE, + 0x1F0D_6758_EEE3_0DA1, + 0xC9B6_11D9_7ADE_B9B7, + 0xB7AF_D588_7B6C_57A2, + 0x6290_AE84_6B98_4FE1, + 0x94DF_4CDE_ACC1_A5FD, + 0x058A_5BD1_C548_3AFF, + 0x6316_6CC1_42BA_3C37, + 0x8DB8_526E_B2F7_6F40, + 0xE108_8003_6F0D_6D4E, + 0x9E05_23C9_971D_311D, + 0x45EC_2824_CC7C_D691, + 0x575B_8359_E623_82C9, + 0xFA9E_400D_C488_9995, + 0xD182_3ECB_4572_1568, + 0xDAFD_983B_8206_082F, + 0xAA7D_2908_2386_A8CB, + 0x269F_CD44_03B8_7588, + 0x1B91_F5F7_28BD_D1E0, + 0xE466_9F39_0402_01F6, + 0x7A1D_7C21_8CF0_4ADE, + 0x6562_3C29_D79C_E5CE, + 0x2368_4490_96C0_0BB1, + 0xAB9B_F187_9DA5_03BA, + 0xBC23_ECB1_A458_058E, + 0x9A58_DF01_BB40_1ECC, + 0xA070_E868_A85F_143D, + 0x4FF1_8830_7DF2_239E, + 0x14D5_65B4_1A64_1183, + 0xEE13_3374_5270_1602, + 0x950E_3DCF_3F28_5E09, + 0x5993_0254_B9C8_0953, + 0x3BF2_9940_8930_DA6D, + 0xA955_943F_5369_1387, + 0xA15E_DECA_A9CB_8784, + 0x2914_2127_352B_E9A0, + 0x76F0_371F_FF4E_7AFB, + 0x0239_F450_274F_2228, + 0xBB07_3AF0_1D5E_868B, + 0xBFC8_0571_C10E_96C1, + 0xD267_0885_6822_2E23, + 0x9671_A3D4_8E80_B5B0, + 0x55B5_D38A_E193_BB81, + 0x693A_E2D0_A18B_04B8, + 0x5C48_B4EC_ADD5_335F, + 0xFD74_3B19_4916_A1CA, + 0x2577_0181_34BE_98C4, + 0xE779_87E8_3C54_A4AD, + 0x28E1_1014_DA33_E1B9, + 0x270C_C59E_226A_A213, + 0x7149_5F75_6D1A_5F60, + 0x9BE8_53FB_60AF_EF77, + 0xADC7_86A7_F744_3DBF, + 0x0904_4561_73B2_9A82, + 0x58BC_7A66_C232_BD5E, + 0xF306_558C_673A_C8B2, + 0x41F6_39C6_B6C9_772A, + 0x216D_EFE9_9FDA_35DA, + 0x1164_0CC7_1C7B_E615, + 0x93C4_3694_565C_5527, + 0xEA03_8E62_4677_7839, + 0xF9AB_F3CE_5A3E_2469, + 0x741E_768D_0FD3_12D2, + 0x0144_B883_CED6_52C6, + 0xC20B_5A5B_A33F_8552, + 0x1AE6_9633_C343_5A9D, + 0x97A2_8CA4_088C_FDEC, + 0x8824_A43C_1E96_F420, + 0x3761_2FA6_6EEE_A746, + 0x6B4C_B165_F9CF_0E5A, + 0x43AA_1C06_A0AB_FB4A, + 0x7F4D_C26F_F162_796B, + 0x6CBA_CC8E_54ED_9B0F, + 0xA6B7_FFEF_D2BB_253E, + 0x2E25_BC95_B0A2_9D4F, + 0x86D6_A58B_DEF1_388C, + 0xDED7_4AC5_76B6_F054, + 0x8030_BDBC_2B45_805D, + 0x3C81_AF70_E94D_9289, + 0x3EFF_6DDA_9E31_00DB, + 0xB38D_C39F_DFCC_8847, + 0x1238_8552_8D17_B87E, + 0xF2DA_0ED2_40B1_B642, + 0x44CE_FADC_D54B_F9A9, + 0x1312_200E_433C_7EE6, + 0x9FFC_C84F_3A78_C748, + 0xF0CD_1F72_2485_76BB, + 0xEC69_7405_3638_CFE4, + 0x2BA7_B67C_0CEC_4E4C, + 0xAC2F_4DF3_E5CE_32ED, + 0xCB33_D143_26EA_4C11, + 0xA4E9_044C_C77E_58BC, + 0x5F51_3293_D934_FCEF, + 0x5DC9_6455_06E5_5444, + 0x50DE_418F_317D_E40A, + 0x388C_B31A_69DD_E259, + 0x2DB4_A834_5582_0A86, + 0x9010_A91E_8471_1AE9, + 0x4DF7_F0B7_B149_8371, + 0xD62A_2EAB_C097_7179, + 0x22FA_C097_AA8D_5C0E, +]; + +pub(crate) static T3: [u64; 256] = [ + 0xF49F_CC2F_F1DA_F39B, + 0x487F_D5C6_6FF2_9281, + 0xE8A3_0667_FCDC_A83F, + 0x2C9B_4BE3_D2FC_CE63, + 0xDA3F_F74B_93FB_BBC2, + 0x2FA1_65D2_FE70_BA66, + 0xA103_E279_970E_93D4, + 0xBECD_EC77_B0E4_5E71, + 0xCFB4_1E72_3985_E497, + 0xB70A_AA02_5EF7_5017, + 0xD423_09F0_3840_B8E0, + 0x8EFC_1AD0_3589_8579, + 0x96C6_920B_E2B2_ABC5, + 0x66AF_4163_375A_9172, + 0x2174_ABDC_CA71_27FB, + 0xB33C_CEA6_4A72_FF41, + 0xF04A_4933_0830_66A5, + 0x8D97_0ACD_D728_9AF5, + 0x8F96_E8E0_31C8_C25E, + 0xF3FE_C022_7687_5D47, + 0xEC7B_F310_0561_90DD, + 0xF5AD_B0AE_BB0F_1491, + 0x9B50_F885_0FD5_8892, + 0x4975_4883_58B7_4DE8, + 0xA335_4FF6_9153_1C61, + 0x0702_BBE4_81D2_C6EE, + 0x89FB_2405_7DED_ED98, + 0xAC30_7513_8596_E902, + 0x1D2D_3580_1727_72ED, + 0xEB73_8FC2_8E6B_C30D, + 0x5854_EF8F_6304_4326, + 0x9E5C_5232_5ADD_3BBE, + 0x90AA_53CF_325C_4623, + 0xC1D2_4D51_349D_D067, + 0x2051_CFEE_A69E_A624, + 0x1322_0F0A_862E_7E4F, + 0xCE39_3994_04E0_4864, + 0xD9C4_2CA4_7086_FCB7, + 0x685A_D223_8A03_E7CC, + 0x0664_84B2_AB2F_F1DB, + 0xFE9D_5D70_EFBF_79EC, + 0x5B13_B9DD_9C48_1854, + 0x15F0_D475_ED15_09AD, + 0x0BEB_CD06_0EC7_9851, + 0xD58C_6791_183A_B7F8, + 0xD118_7C50_52F3_EEE4, + 0xC95D_1192_E54E_82FF, + 0x86EE_A14C_B9AC_6CA2, + 0x3485_BEB1_5367_7D5D, + 0xDD19_1D78_1F8C_492A, + 0xF608_66BA_A784_EBF9, + 0x518F_643B_A2D0_8C74, + 0x8852_E956_E108_7C22, + 0xA768_CB8D_C410_AE8D, + 0x3804_7726_BFEC_8E1A, + 0xA677_38B4_CD3B_45AA, + 0xAD16_691C_EC0D_DE19, + 0xC6D4_3193_8046_2E07, + 0xC5A5_876D_0BA6_1938, + 0x16B9_FA1F_A58F_D840, + 0x188A_B117_3CA7_4F18, + 0xABDA_2F98_C99C_021F, + 0x3E05_80AB_134A_E816, + 0x5F3B_05B7_7364_5ABB, + 0x2501_A2BE_5575_F2F6, + 0x1B2F_7400_4E7E_8BA9, + 0x1CD7_5803_71E8_D953, + 0x7F6E_D895_6276_4E30, + 0xB159_26FF_596F_003D, + 0x9F65_293D_A8C5_D6B9, + 0x6ECE_F04D_D690_F84C, + 0x4782_275F_FF33_AF88, + 0xE414_3308_3F82_0801, + 0xFD0D_FE40_9A1A_F9B5, + 0x4325_A334_2CDB_396B, + 0x8AE7_7E62_B301_B252, + 0xC36F_9E9F_6655_615A, + 0x8545_5A2D_92D3_2C09, + 0xF2C7_DEA9_4947_7485, + 0x63CF_B4C1_33A3_9EBA, + 0x83B0_40CC_6EBC_5462, + 0x3B94_54C8_FDB3_26B0, + 0x56F5_6A9E_87FF_D78C, + 0x2DC2_940D_99F4_2BC6, + 0x98F7_DF09_6B09_6E2D, + 0x19A6_E01E_3AD8_52BF, + 0x42A9_9CCB_DBD4_B40B, + 0xA599_98AF_45E9_C559, + 0x3662_95E8_07D9_3186, + 0x6B48_181B_FAA1_F773, + 0x1FEC_57E2_157A_0A1D, + 0x4667_446A_F620_1AD5, + 0xE615_EBCA_CFB0_F075, + 0xB8F3_1F4F_6829_0778, + 0x2271_3ED6_CE22_D11E, + 0x3057_C1A7_2EC3_C93B, + 0xCB46_ACC3_7C3F_1F2F, + 0xDBB8_93FD_02AA_F50E, + 0x331F_D92E_600B_9FCF, + 0xA498_F961_48EA_3AD6, + 0xA8D8_426E_8B6A_83EA, + 0xA089_B274_B773_5CDC, + 0x87F6_B373_1E52_4A11, + 0x1188_08E5_CBC9_6749, + 0x9906_E4C7_B19B_D394, + 0xAFED_7F7E_9B24_A20C, + 0x6509_EADE_EB36_44A7, + 0x6C1E_F1D3_E8EF_0EDE, + 0xB9C9_7D43_E979_8FB4, + 0xA2F2_D784_740C_28A3, + 0x7B84_9647_6197_566F, + 0x7A5B_E3E6_B65F_069D, + 0xF963_30ED_78BE_6F10, + 0xEEE6_0DE7_7A07_6A15, + 0x2B4B_EE4A_A08B_9BD0, + 0x6A56_A63E_C7B8_894E, + 0x0212_1359_BA34_FEF4, + 0x4CBF_99F8_2837_03FC, + 0x3980_7135_0CAF_30C8, + 0xD0A7_7A89_F017_687A, + 0xF1C1_A9EB_9E42_3569, + 0x8C79_7628_2DEE_8199, + 0x5D17_37A5_DD1F_7ABD, + 0x4F53_433C_09A9_FA80, + 0xFA8B_0C53_DF7C_A1D9, + 0x3FD9_DCBC_886C_CB77, + 0xC040_917C_A91B_4720, + 0x7DD0_0142_F9D1_DCDF, + 0x8476_FC1D_4F38_7B58, + 0x23F8_E7C5_F331_6503, + 0x032A_2244_E7E3_7339, + 0x5C87_A5D7_50F5_A74B, + 0x082B_4CC4_3698_992E, + 0xDF91_7BEC_B858_F63C, + 0x3270_B8FC_5BF8_6DDA, + 0x10AE_72BB_29B5_DD76, + 0x576A_C94E_7700_362B, + 0x1AD1_12DA_C61E_FB8F, + 0x691B_C30E_C5FA_A427, + 0xFF24_6311_CC32_7143, + 0x3142_368E_30E5_3206, + 0x7138_0E31_E02C_A396, + 0x958D_5C96_0AAD_76F1, + 0xF8D6_F430_C16D_A536, + 0xC8FF_D13F_1BE7_E1D2, + 0x7578_AE66_004D_DBE1, + 0x0583_3F01_067B_E646, + 0xBB34_B5AD_3BFE_586D, + 0x095F_34C9_A12B_97F0, + 0x247A_B645_25D6_0CA8, + 0xDCDB_C6F3_0174_77D1, + 0x4A2E_14D4_DECA_D24D, + 0xBDB5_E6D9_BE0A_1EEB, + 0x2A7E_70F7_7943_01AB, + 0xDEF4_2D8A_2705_40FD, + 0x0107_8EC0_A34C_22C1, + 0xE5DE_511A_F4C1_6387, + 0x7EBB_3A52_BD9A_330A, + 0x7769_7857_AA7D_6435, + 0x004E_8316_03AE_4C32, + 0xE7A2_1020_AD78_E312, + 0x9D41_A70C_6AB4_20F2, + 0x28E0_6C18_EA11_41E6, + 0xD2B2_8CBD_984F_6B28, + 0x26B7_5F6C_446E_9D83, + 0xBA47_568C_4D41_8D7F, + 0xD80B_ADBF_E618_3D8E, + 0x0E20_6D7F_5F16_6044, + 0xE258_A439_11CB_CA3E, + 0x723A_1746_B21D_C0BC, + 0xC7CA_A854_F5D7_CDD3, + 0x7CAC_3288_3D26_1D9C, + 0x7690_C264_23BA_942C, + 0x17E5_5524_4780_42B8, + 0xE0BE_4776_56A2_389F, + 0x4D28_9B5E_67AB_2DA0, + 0x4486_2B9C_8FBB_FD31, + 0xB47C_C804_9D14_1365, + 0x822C_1B36_2B91_C793, + 0x4EB1_4655_FB13_DFD8, + 0x1ECB_BA07_14E2_A97B, + 0x6143_459D_5CDE_5F14, + 0x53A8_FBF1_D5F0_AC89, + 0x97EA_04D8_1C5E_5B00, + 0x6221_81A8_D4FD_B3F3, + 0xE9BC_D341_572A_1208, + 0x1411_2586_43CC_E58A, + 0x9144_C5FE_A4C6_E0A4, + 0x0D33_D065_65CF_620F, + 0x54A4_8D48_9F21_9CA1, + 0xC43E_5EAC_6D63_C821, + 0xA972_8B3A_7277_0DAF, + 0xD793_4E7B_20DF_87EF, + 0xE355_03B6_1A3E_86E5, + 0xCAE3_21FB_C819_D504, + 0x129A_50B3_AC60_BFA6, + 0xCD5E_68EA_7E9F_B6C3, + 0xB01C_9019_9483_B1C7, + 0x3DE9_3CD5_C295_376C, + 0xAED5_2EDF_2AB9_AD13, + 0x2E60_F512_C0A0_7884, + 0xBC3D_86A3_E362_10C9, + 0x3526_9D9B_1639_51CE, + 0x0C7D_6E2A_D0CD_B5FA, + 0x59E8_6297_D87F_5733, + 0x298E_F221_898D_B0E7, + 0x5500_0029_D1A5_AA7E, + 0x8BC0_8AE1_B506_1B45, + 0xC2C3_1C2B_6C92_703A, + 0x94CC_596B_AF25_EF42, + 0x0A1D_73DB_2254_0456, + 0x04B6_A0F9_D9C4_179A, + 0xEFFD_AFA2_AE3D_3C60, + 0xF7C8_075B_B494_96C4, + 0x9CC5_C714_1D1C_D4E3, + 0x78BD_1638_218E_5534, + 0xB2F1_1568_F850_246A, + 0xEDFA_BCFA_9502_BC29, + 0x796C_E5F2_DA23_051B, + 0xAAE1_28B0_DC93_537C, + 0x3A49_3DA0_EE4B_29AE, + 0xB5DF_6B2C_4168_95D7, + 0xFCAB_BD25_122D_7F37, + 0x7081_0B58_105D_C4B1, + 0xE10F_DD37_F788_2A90, + 0x524D_CAB5_518A_3F5C, + 0x3C9E_8587_8451_255B, + 0x4029_8281_19BD_34E2, + 0x74A0_5B6F_5D3C_ECCB, + 0xB610_0215_42E1_3ECA, + 0x0FF9_79D1_2F59_E2AC, + 0x6037_DA27_E4F9_CC50, + 0x5E92_975A_0DF1_847D, + 0xD66D_E190_D3E6_23FE, + 0x5032_D6B8_7B56_8048, + 0x9A36_B7CE_8235_216E, + 0x8027_2A7A_24F6_4B4A, + 0x93EF_ED8B_8C69_16F7, + 0x37DD_BFF4_4CCE_1555, + 0x4B95_DB5D_4B99_BD25, + 0x92D3_FDA1_6981_2FC0, + 0xFB1A_4A9A_9066_0BB6, + 0x730C_1969_46A4_B9B2, + 0x81E2_89AA_7F49_DA68, + 0x6466_9A0F_83B1_A05F, + 0x27B3_FF7D_9644_F48B, + 0xCC6B_615C_8DB6_75B3, + 0x674F_20B9_BCEB_BE95, + 0x6F31_2382_7565_5982, + 0x5AE4_8871_3E45_CF05, + 0xBF61_9F99_54C2_1157, + 0xEABA_C460_40A8_EAE9, + 0x454C_6FE9_F2C0_C1CD, + 0x419C_F649_6412_691C, + 0xD3DC_3BEF_265B_0F70, + 0x6D0E_60F5_C357_8A9E, +]; + +pub(crate) static T4: [u64; 256] = [ + 0x5B0E_6085_2632_3C55, + 0x1A46_C1A9_FA1B_59F5, + 0xA9E2_45A1_7C4C_8FFA, + 0x65CA_5159_DB29_55D7, + 0x05DB_0A76_CE35_AFC2, + 0x81EA_C77E_A911_3D45, + 0x528E_F88A_B6AC_0A0D, + 0xA09E_A253_597B_E3FF, + 0x430D_DFB3_AC48_CD56, + 0xC4B3_A67A_F45C_E46F, + 0x4ECE_CFD8_FBE2_D05E, + 0x3EF5_6F10_B399_35F0, + 0x0B22_D682_9CD6_19C6, + 0x17FD_460A_74DF_2069, + 0x6CF8_CC8E_8510_ED40, + 0xD6C8_24BF_3A6E_CAA7, + 0x6124_3D58_1A81_7049, + 0x048B_ACB6_BBC1_63A2, + 0xD9A3_8AC2_7D44_CC32, + 0x7FDD_FF5B_AAF4_10AB, + 0xAD6D_495A_A804_824B, + 0xE1A6_A74F_2D8C_9F94, + 0xD4F7_8512_35DE_E8E3, + 0xFD4B_7F88_6540_D893, + 0x247C_2004_2AA4_BFDA, + 0x096E_A1C5_17D1_327C, + 0xD569_66B4_361A_6685, + 0x277D_A5C3_1221_057D, + 0x94D5_9893_A43A_CFF7, + 0x64F0_C51C_CDC0_2281, + 0x3D33_BCC4_FF61_89DB, + 0xE005_CB18_4CE6_6AF1, + 0xFF5C_CD1D_1DB9_9BEA, + 0xB0B8_54A7_FE42_980F, + 0x7BD4_6A6A_718D_4B9F, + 0xD10F_A8CC_22A5_FD8C, + 0xD314_8495_2BE4_BD31, + 0xC7FA_975F_CB24_3847, + 0x4886_ED1E_5846_C407, + 0x28CD_DB79_1EB7_0B04, + 0xC2B0_0BE2_F573_417F, + 0x5C95_9045_2180_F877, + 0x7A6B_DDFF_F370_EB00, + 0xCE50_9E38_D6D9_D6A4, + 0xEBEB_0F00_647F_A702, + 0x1DCC_06CF_7660_6F06, + 0xE4D9_F28B_A286_FF0A, + 0xD85A_305D_C918_C262, + 0x475B_1D87_3222_5F54, + 0x2D4F_B516_68CC_B5FE, + 0xA679_B9D9_D72B_BA20, + 0x5384_1C0D_912D_43A5, + 0x3B7E_AA48_BF12_A4E8, + 0x781E_0E47_F22F_1DDF, + 0xEFF2_0CE6_0AB5_0973, + 0x20D2_61D1_9DFF_B742, + 0x16A1_2B03_062A_2E39, + 0x1960_EB22_3965_0495, + 0x251C_16FE_D50E_B8B8, + 0x9AC0_C330_F826_016E, + 0xED15_2665_953E_7671, + 0x02D6_3194_A636_9570, + 0x5074_F083_94B1_C987, + 0x70BA_598C_90B2_5CE1, + 0x794A_1581_0B97_42F6, + 0x0D59_25E9_FCAF_8C6C, + 0x3067_716C_D868_744E, + 0x910A_B077_E8D7_731B, + 0x6A61_BBDB_5AC4_2F61, + 0x9351_3EFB_F085_1567, + 0xF494_724B_9E83_E9D5, + 0xE887_E198_5C09_648D, + 0x34B1_D3C6_7537_0CFD, + 0xDC35_E433_BC0D_255D, + 0xD0AA_B842_3413_1BE0, + 0x0804_2A50_B48B_7EAF, + 0x9997_C4EE_44A3_AB35, + 0x829A_7B49_2017_99D0, + 0x263B_8307_B7C5_4441, + 0x752F_95F4_FD6A_6CA6, + 0x9272_1740_2C08_C6E5, + 0x2A8A_B754_A795_D9EE, + 0xA442_F755_2F72_943D, + 0x2C31_334E_1978_1208, + 0x4FA9_8D7C_EAEE_6291, + 0x55C3_862F_665D_B309, + 0xBD06_1017_5D53_B1F3, + 0x46FE_6CB8_4041_3F27, + 0x3FE0_3792_DF0C_FA59, + 0xCFE7_0037_2EB8_5E8F, + 0xA7BE_29E7_ADBC_E118, + 0xE544_EE5C_DE84_31DD, + 0x8A78_1B1B_41F1_873E, + 0xA5C9_4C78_A0D2_F0E7, + 0x3941_2E28_77B6_0728, + 0xA126_5EF3_AFC9_A62C, + 0xBCC2_770C_6A25_06C5, + 0x3AB6_6DD5_DCE1_CE12, + 0xE654_99D0_4A67_5B37, + 0x7D8F_5234_81BF_D216, + 0x0F6F_64FC_EC15_F389, + 0x74EF_BE61_8B5B_13C8, + 0xACDC_82B7_1427_3E1D, + 0xDD40_BFE0_0319_9D17, + 0x37E9_9257_E7E0_61F8, + 0xFA52_6269_0477_5AAA, + 0x8BBB_F63A_463D_56F9, + 0xF001_3F15_43A2_6E64, + 0xA830_7E9F_879E_C898, + 0xCC4C_27A4_1501_77CC, + 0x1B43_2F2C_CA1D_3348, + 0xDE1D_1F8F_9F6F_A013, + 0x6066_02A0_47A7_DDD6, + 0xD237_AB64_CC1C_B2C7, + 0x9B93_8E72_25FC_D1D3, + 0xEC4E_0370_8E0F_F476, + 0xFEB2_FBDA_3D03_C12D, + 0xAE0B_CED2_EE43_889A, + 0x22CB_8923_EBFB_4F43, + 0x6936_0D01_3CF7_396D, + 0x855E_3602_D2D4_E022, + 0x0738_05BA_D01F_784C, + 0x33E1_7A13_3852_F546, + 0xDF48_7405_8AC7_B638, + 0xBA92_B29C_678A_A14A, + 0x0CE8_9FC7_6CFA_ADCD, + 0x5F9D_4E09_0833_9E34, + 0xF1AF_E929_1F59_23B9, + 0x6E34_80F6_0F4A_265F, + 0xEEBF_3A2A_B29B_841C, + 0xE219_38A8_8F91_B4AD, + 0x57DF_EFF8_45C6_D3C3, + 0x2F00_6B0B_F62C_AAF2, + 0x62F4_79EF_6F75_EE78, + 0x11A5_5AD4_1C89_16A9, + 0xF229_D290_84FE_D453, + 0x42F1_C27B_16B0_00E6, + 0x2B1F_7674_9823_C074, + 0x4B76_ECA3_C274_5360, + 0x8C98_F463_B916_91BD, + 0x14BC_C93C_F1AD_E66A, + 0x8885_213E_6D45_8397, + 0x8E17_7DF0_274D_4711, + 0xB49B_73B5_503F_2951, + 0x1016_8168_C3F9_6B6B, + 0x0E3D_963B_63CA_B0AE, + 0x8DFC_4B56_55A1_DB14, + 0xF789_F135_6E14_DE5C, + 0x683E_68AF_4E51_DAC1, + 0xC9A8_4F9D_8D4B_0FD9, + 0x3691_E03F_52A0_F9D1, + 0x5ED8_6E46_E187_8E80, + 0x3C71_1A0E_99D0_7150, + 0x5A08_65B2_0C4E_9310, + 0x56FB_FC1F_E4F0_682E, + 0xEA8D_5DE3_105E_DF9B, + 0x71AB_FDB1_2379_187A, + 0x2EB9_9DE1_BEE7_7B9C, + 0x21EC_C0EA_33CF_4523, + 0x59A4_D752_1805_C7A1, + 0x3896_F5EB_56AE_7C72, + 0xAA63_8F3D_B18F_75DC, + 0x9F39_358D_ABE9_808E, + 0xB7DE_FA91_C00B_72AC, + 0x6B55_41FD_6249_2D92, + 0x6DC6_DEE8_F92E_4D5B, + 0x353F_57AB_C4BE_EA7E, + 0x7357_69D6_DA56_90CE, + 0x0A23_4AA6_4239_1484, + 0xF6F9_5080_28F8_0D9D, + 0xB8E3_19A2_7AB3_F215, + 0x31AD_9C11_5134_1A4D, + 0x773C_22A5_7BEF_5805, + 0x45C7_561A_0796_8633, + 0xF913_DA9E_249D_BE36, + 0xDA65_2D9B_78A6_4C68, + 0x4C27_A97F_3BC3_34EF, + 0x7662_1220_E66B_17F4, + 0x9677_4389_9ACD_7D0B, + 0xF3EE_5BCA_E0ED_6782, + 0x409F_7536_00C8_79FC, + 0x06D0_9A39_B592_6DB6, + 0x6F83_AEB0_317A_C588, + 0x01E6_CA4A_8638_1F21, + 0x66FF_3462_D19F_3025, + 0x7220_7C24_DDFD_3BFB, + 0x4AF6_B6D3_E2EC_E2EB, + 0x9C99_4DBE_C7EA_08DE, + 0x49AC_E597_B09A_8BC4, + 0xB38C_4766_CF07_97BA, + 0x131B_9373_C57C_2A75, + 0xB182_2CCE_6193_1E58, + 0x9D75_55B9_09BA_1C0C, + 0x127F_AFDD_937D_11D2, + 0x29DA_3BAD_C66D_92E4, + 0xA2C1_D571_54C2_ECBC, + 0x58C5_134D_82F6_FE24, + 0x1C3A_E351_5B62_274F, + 0xE907_C82E_01CB_8126, + 0xF8ED_0919_13E3_7FCB, + 0x3249_D8F9_C800_46C9, + 0x80CF_9BED_E388_FB63, + 0x1881_539A_116C_F19E, + 0x5103_F3F7_6BD5_2457, + 0x15B7_E6F5_AE47_F7A8, + 0xDBD7_C6DE_D47E_9CCF, + 0x44E5_5C41_0228_BB1A, + 0xB647_D425_5EDB_4E99, + 0x5D11_882B_B8AA_FC30, + 0xF509_8BBB_29D3_212A, + 0x8FB5_EA14_E902_96B3, + 0x677B_9421_57DD_025A, + 0xFB58_E7C0_A390_ACB5, + 0x89D3_674C_83BD_4A01, + 0x9E2D_A4DF_4BF3_B93B, + 0xFCC4_1E32_8CAB_4829, + 0x03F3_8C96_BA58_2C52, + 0xCAD1_BDBD_7FD8_5DB2, + 0xBBB4_42C1_6082_AE83, + 0xB95F_E86B_A5DA_9AB0, + 0xB22E_0467_3771_A93F, + 0x8453_58C9_4931_52D8, + 0xBE2A_4886_97B4_541E, + 0x95A2_DC2D_D38E_6966, + 0xC02C_11AC_923C_852B, + 0x2388_B199_0DF2_A87B, + 0x7C80_08FA_1B4F_37BE, + 0x1F70_D0C8_4D54_E503, + 0x5490_ADEC_7ECE_57D4, + 0x002B_3C27_D906_3A3A, + 0x7EAE_A384_8030_A2BF, + 0xC602_326D_ED20_03C0, + 0x83A7_287D_69A9_4086, + 0xC57A_5FCB_30F5_7A8A, + 0xB568_44E4_79EB_E779, + 0xA373_B40F_05DC_BCE9, + 0xD71A_786E_8857_0EE2, + 0x879C_BACD_BDE8_F6A0, + 0x976A_D1BC_C164_A32F, + 0xAB21_E25E_9666_D78B, + 0x9010_63AA_E5E5_C33C, + 0x9818_B344_4869_8D90, + 0xE364_87AE_3E1E_8ABB, + 0xAFBD_F931_893B_DCB4, + 0x6345_A0DC_5FBB_D519, + 0x8628_FE26_9B94_65CA, + 0x1E5D_0160_3F9C_51EC, + 0x4DE4_4006_A150_49B7, + 0xBF6C_70E5_F776_CBB1, + 0x4112_18F2_EF55_2BED, + 0xCB0C_0708_705A_36A3, + 0xE74D_1475_4F98_6044, + 0xCD56_D943_0EA8_280E, + 0xC125_91D7_535F_5065, + 0xC832_23F1_720A_EF96, + 0xC3A0_396F_7363_A51F, +]; diff --git a/tiger/tests/data/tiger.blb b/tiger/tests/data/tiger.blb new file mode 100644 index 0000000000000000000000000000000000000000..c936452a2736d1a2502d5ba28e0b0d479ae86e5a GIT binary patch literal 881 zcmZQzFff|DCYeY0gG&6Q-5bmD#KfxnB0P2P6@O++OiDJ;S}oG@;$Xz5{X35ScidVP z6sRdIGqpN?GFM1udTNouT?S?LnO_;^zsY@l!eV!p`hD%W`GP!^<_!#vPR=f_ZtfnQ zUfw>we*OW0LBS!RVc`*xQ9xr;Qq$5iGPAOCa`W;F3X6(MO3TVCDys|(jf_o9&CD$< zwRH`?%d|F6(E8mz@BTA^A3D75ZHt$h1h}+q#b>lFZnL!!h8uXCd!5X&qt@+ZY-*y= z*^j-`C&o`tP3;VCU;z6{L07?1!7Z`4M8Pk$T)`u;I77j$G%vX%Ge1v9A*oU!D8IN^ z!7(o-wWv5hPa!ccMZq;EQ^6@SBQe*Yt1Uy5h0BqrXx1hBs9S|%%$v_%4u5hmt|5<7 zqjeMtit>|FQ&TeY(u)=H(;zMk&QB{TPb^ARaLr3Dsw@DxQNdV8!8tKEsVFlgJyp-( zTpz@P@I6G1r#%&$N|L+o`!WV!0#?|qF71_KQ^PTbj&{^a;ifoVCG z^Y6?S^L`jzsq3ty5*Ct?s!&*(nVhYVRFq$yr;wIkp^#OYTL28nveY7l5}qGv82#J7ET^nHs@QtOA@tCx;$C?(pEWS}7{K6vvNF)p~SAs{nXEhyTs M%*$l*pBt|I00gWrO} fG=%e@uz`k^`unYt2CHfhzDe@`Zn5I#-pls^U?D`a literal 0 HcmV?d00001 diff --git a/tiger/tests/mod.rs b/tiger/tests/mod.rs new file mode 100644 index 000000000..6f2cca17f --- /dev/null +++ b/tiger/tests/mod.rs @@ -0,0 +1,4 @@ +use digest::{dev::digest_test, new_test}; + +new_test!(tiger, "tiger", tiger::Tiger, digest_test); +new_test!(tiger2, "tiger2", tiger::Tiger2, digest_test); diff --git a/whirlpool/CHANGELOG.md b/whirlpool/CHANGELOG.md index 2d3c97dfd..0c34ef2f9 100644 --- a/whirlpool/CHANGELOG.md +++ b/whirlpool/CHANGELOG.md @@ -5,6 +5,12 @@ 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.10.0 (2021-11-22) +### Changed +- Update to `digest` v0.10 ([#217]) + +[#217]: https://github.com/RustCrypto/hashes/pull/217 + ## 0.9.0 (2020-06-12) ### Changed - Bump `opaque-debug` to v0.3.0 ([#168]) diff --git a/whirlpool/Cargo.toml b/whirlpool/Cargo.toml index 395ed8a3c..777785c4a 100644 --- a/whirlpool/Cargo.toml +++ b/whirlpool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "whirlpool" -version = "0.9.0" +version = "0.10.0" # Also update html_root_url in lib.rs when bumping this description = "Whirlpool hash function" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" @@ -12,13 +12,11 @@ keywords = ["crypto", "whirlpool", "hash", "digest"] categories = ["cryptography", "no-std"] [dependencies] -digest = "0.9" -block-buffer = { version = "0.9", features = ["block-padding"] } -opaque-debug = "0.3" -whirlpool-asm = { version = "0.5", optional = true } +digest = "0.10" +whirlpool-asm = { version = "0.6", optional = true} [dev-dependencies] -digest = { version = "0.9", features = ["dev"] } +digest = { version = "0.10", features = ["dev"] } hex-literal = "0.2" [features] diff --git a/whirlpool/examples/whirlpool_sum.rs b/whirlpool/examples/whirlpool_sum.rs deleted file mode 100644 index fe2416b8f..000000000 --- a/whirlpool/examples/whirlpool_sum.rs +++ /dev/null @@ -1,47 +0,0 @@ -use std::env; -use std::fs; -use std::io::{self, Read}; -use whirlpool::{Digest, Whirlpool}; - -const BUFFER_SIZE: usize = 1024; - -/// Print digest result as hex string and name pair -fn print_result(sum: &[u8], name: &str) { - for byte in sum { - print!("{:02x}", byte); - } - println!("\t{}", name); -} - -/// Compute digest value for given `Reader` and print it -/// On any error simply return without doing anything -fn process(reader: &mut R, name: &str) { - let mut sh: D = Default::default(); - let mut buffer = [0u8; BUFFER_SIZE]; - loop { - let n = match reader.read(&mut buffer) { - Ok(n) => n, - Err(_) => return, - }; - sh.update(&buffer[..n]); - if n == 0 || n < BUFFER_SIZE { - break; - } - } - print_result(&sh.finalize(), name); -} - -fn main() { - let args = env::args(); - // Process files listed in command line arguments one by one - // If no files provided process input from stdin - if args.len() > 1 { - for path in args.skip(1) { - if let Ok(mut file) = fs::File::open(&path) { - process::(&mut file, &path); - } - } - } else { - process::(&mut io::stdin(), "-"); - } -} diff --git a/whirlpool/src/compress.rs b/whirlpool/src/compress.rs new file mode 100644 index 000000000..4f1664e30 --- /dev/null +++ b/whirlpool/src/compress.rs @@ -0,0 +1,60 @@ +use crate::BLOCK_SIZE; +use core::convert::TryInto; + +#[path = "consts.rs"] +mod consts; +use consts::*; + +fn compress_block(state: &mut [u64; 8], b: &[u8; BLOCK_SIZE]) { + let mut k = [0u64; 8]; + let mut block = [0u64; 8]; + let mut s = [0u64; 8]; + let mut l = [0u64; 8]; + + for (o, chunk) in block.iter_mut().zip(b.chunks_exact(8)) { + *o = u64::from_le_bytes(chunk.try_into().unwrap()); + } + k.copy_from_slice(state); + + for i in 0..8 { + s[i] = block[i] ^ k[i]; + } + + #[allow(clippy::needless_range_loop)] + for r in 0..R { + for i in 0..8 { + l[i] = C0[(k[(i) % 8] & 0xff) as usize] + ^ C1[((k[(7 + i) % 8] >> 8) & 0xff) as usize] + ^ C2[((k[(6 + i) % 8] >> 16) & 0xff) as usize] + ^ C3[((k[(5 + i) % 8] >> 24) & 0xff) as usize] + ^ C4[((k[(4 + i) % 8] >> 32) & 0xff) as usize] + ^ C5[((k[(3 + i) % 8] >> 40) & 0xff) as usize] + ^ C6[((k[(2 + i) % 8] >> 48) & 0xff) as usize] + ^ C7[((k[(1 + i) % 8] >> 56) & 0xff) as usize] + ^ if i == 0 { RC[r] } else { 0 }; + } + k = l; + for i in 0..8 { + l[i] = C0[(s[(i) % 8] & 0xff) as usize] + ^ C1[((s[(7 + i) % 8] >> 8) & 0xff) as usize] + ^ C2[((s[(6 + i) % 8] >> 16) & 0xff) as usize] + ^ C3[((s[(5 + i) % 8] >> 24) & 0xff) as usize] + ^ C4[((s[(4 + i) % 8] >> 32) & 0xff) as usize] + ^ C5[((s[(3 + i) % 8] >> 40) & 0xff) as usize] + ^ C6[((s[(2 + i) % 8] >> 48) & 0xff) as usize] + ^ C7[((s[(1 + i) % 8] >> 56) & 0xff) as usize] + ^ k[i]; + } + s = l; + } + + for i in 0..8 { + state[i] ^= s[i] ^ block[i]; + } +} + +pub(crate) fn compress(state: &mut [u64; 8], blocks: &[[u8; BLOCK_SIZE]]) { + for block in blocks { + compress_block(state, block); + } +} diff --git a/whirlpool/src/consts.rs b/whirlpool/src/consts.rs index aad56c63e..756437d21 100644 --- a/whirlpool/src/consts.rs +++ b/whirlpool/src/consts.rs @@ -1,2089 +1,2088 @@ #![allow(clippy::unreadable_literal)] -pub static R: usize = 10; +pub const R: usize = 10; -pub static RC: [u64; 11 /* R + 1 */] = [ - 0x0000000000000000, - 0x1823c6e887b8014f, - 0x36a6d2f5796f9152, - 0x60bc9b8ea30c7b35, - 0x1de0d7c22e4bfe57, - 0x157737e59ff04ada, - 0x58c9290ab1a06b85, - 0xbd5d10f4cb3e0567, - 0xe427418ba77d95d8, - 0xfbee7c66dd17479e, - 0xca2dbf07ad5a8333, +pub const RC: [u64; R] = [ + 0x4f01b887e8c62318, + 0x52916f79f5d2a636, + 0x357b0ca38e9bbc60, + 0x57fe4b2ec2d7e01d, + 0xda4af09fe5377715, + 0x856ba0b10a29c958, + 0x67053ecbf4105dbd, + 0xd8957da78b4127e4, + 0x9e4717dd667ceefb, + 0x33835aad07bf2dca, ]; -pub static C0: [u64; 256] = [ - 0x18186018c07830d8, - 0x23238c2305af4626, - 0xc6c63fc67ef991b8, - 0xe8e887e8136fcdfb, - 0x878726874ca113cb, - 0xb8b8dab8a9626d11, - 0x0101040108050209, - 0x4f4f214f426e9e0d, - 0x3636d836adee6c9b, - 0xa6a6a2a6590451ff, - 0xd2d26fd2debdb90c, - 0xf5f5f3f5fb06f70e, - 0x7979f979ef80f296, - 0x6f6fa16f5fcede30, - 0x91917e91fcef3f6d, - 0x52525552aa07a4f8, - 0x60609d6027fdc047, - 0xbcbccabc89766535, - 0x9b9b569baccd2b37, - 0x8e8e028e048c018a, - 0xa3a3b6a371155bd2, - 0x0c0c300c603c186c, - 0x7b7bf17bff8af684, - 0x3535d435b5e16a80, - 0x1d1d741de8693af5, - 0xe0e0a7e05347ddb3, - 0xd7d77bd7f6acb321, - 0xc2c22fc25eed999c, - 0x2e2eb82e6d965c43, - 0x4b4b314b627a9629, - 0xfefedffea321e15d, - 0x575741578216aed5, - 0x15155415a8412abd, - 0x7777c1779fb6eee8, - 0x3737dc37a5eb6e92, - 0xe5e5b3e57b56d79e, - 0x9f9f469f8cd92313, - 0xf0f0e7f0d317fd23, - 0x4a4a354a6a7f9420, - 0xdada4fda9e95a944, - 0x58587d58fa25b0a2, - 0xc9c903c906ca8fcf, - 0x2929a429558d527c, - 0x0a0a280a5022145a, - 0xb1b1feb1e14f7f50, - 0xa0a0baa0691a5dc9, - 0x6b6bb16b7fdad614, - 0x85852e855cab17d9, - 0xbdbdcebd8173673c, - 0x5d5d695dd234ba8f, - 0x1010401080502090, - 0xf4f4f7f4f303f507, - 0xcbcb0bcb16c08bdd, - 0x3e3ef83eedc67cd3, - 0x0505140528110a2d, - 0x676781671fe6ce78, - 0xe4e4b7e47353d597, - 0x27279c2725bb4e02, - 0x4141194132588273, - 0x8b8b168b2c9d0ba7, - 0xa7a7a6a7510153f6, - 0x7d7de97dcf94fab2, - 0x95956e95dcfb3749, - 0xd8d847d88e9fad56, - 0xfbfbcbfb8b30eb70, - 0xeeee9fee2371c1cd, - 0x7c7ced7cc791f8bb, - 0x6666856617e3cc71, - 0xdddd53dda68ea77b, - 0x17175c17b84b2eaf, - 0x4747014702468e45, - 0x9e9e429e84dc211a, - 0xcaca0fca1ec589d4, - 0x2d2db42d75995a58, - 0xbfbfc6bf9179632e, - 0x07071c07381b0e3f, - 0xadad8ead012347ac, - 0x5a5a755aea2fb4b0, - 0x838336836cb51bef, - 0x3333cc3385ff66b6, - 0x636391633ff2c65c, - 0x02020802100a0412, - 0xaaaa92aa39384993, - 0x7171d971afa8e2de, - 0xc8c807c80ecf8dc6, - 0x19196419c87d32d1, - 0x494939497270923b, - 0xd9d943d9869aaf5f, - 0xf2f2eff2c31df931, - 0xe3e3abe34b48dba8, - 0x5b5b715be22ab6b9, - 0x88881a8834920dbc, - 0x9a9a529aa4c8293e, - 0x262698262dbe4c0b, - 0x3232c8328dfa64bf, - 0xb0b0fab0e94a7d59, - 0xe9e983e91b6acff2, - 0x0f0f3c0f78331e77, - 0xd5d573d5e6a6b733, - 0x80803a8074ba1df4, - 0xbebec2be997c6127, - 0xcdcd13cd26de87eb, - 0x3434d034bde46889, - 0x48483d487a759032, - 0xffffdbffab24e354, - 0x7a7af57af78ff48d, - 0x90907a90f4ea3d64, - 0x5f5f615fc23ebe9d, - 0x202080201da0403d, - 0x6868bd6867d5d00f, - 0x1a1a681ad07234ca, - 0xaeae82ae192c41b7, - 0xb4b4eab4c95e757d, - 0x54544d549a19a8ce, - 0x93937693ece53b7f, - 0x222288220daa442f, - 0x64648d6407e9c863, - 0xf1f1e3f1db12ff2a, - 0x7373d173bfa2e6cc, - 0x12124812905a2482, - 0x40401d403a5d807a, - 0x0808200840281048, - 0xc3c32bc356e89b95, - 0xecec97ec337bc5df, - 0xdbdb4bdb9690ab4d, - 0xa1a1bea1611f5fc0, - 0x8d8d0e8d1c830791, - 0x3d3df43df5c97ac8, - 0x97976697ccf1335b, +pub const C0: [u64; 256] = [ + 0xd83078c018601818, + 0x2646af05238c2323, + 0xb891f97ec63fc6c6, + 0xfbcd6f13e887e8e8, + 0xcb13a14c87268787, + 0x116d62a9b8dab8b8, + 0x0902050801040101, + 0x0d9e6e424f214f4f, + 0x9b6ceead36d83636, + 0xff510459a6a2a6a6, + 0x0cb9bdded26fd2d2, + 0x0ef706fbf5f3f5f5, + 0x96f280ef79f97979, + 0x30dece5f6fa16f6f, + 0x6d3feffc917e9191, + 0xf8a407aa52555252, + 0x47c0fd27609d6060, + 0x35657689bccabcbc, + 0x372bcdac9b569b9b, + 0x8a018c048e028e8e, + 0xd25b1571a3b6a3a3, + 0x6c183c600c300c0c, + 0x84f68aff7bf17b7b, + 0x806ae1b535d43535, + 0xf53a69e81d741d1d, + 0xb3dd4753e0a7e0e0, + 0x21b3acf6d77bd7d7, + 0x9c99ed5ec22fc2c2, + 0x435c966d2eb82e2e, + 0x29967a624b314b4b, + 0x5de121a3fedffefe, + 0xd5ae168257415757, + 0xbd2a41a815541515, + 0xe8eeb69f77c17777, + 0x926eeba537dc3737, + 0x9ed7567be5b3e5e5, + 0x1323d98c9f469f9f, + 0x23fd17d3f0e7f0f0, + 0x20947f6a4a354a4a, + 0x44a9959eda4fdada, + 0xa2b025fa587d5858, + 0xcf8fca06c903c9c9, + 0x7c528d5529a42929, + 0x5a1422500a280a0a, + 0x507f4fe1b1feb1b1, + 0xc95d1a69a0baa0a0, + 0x14d6da7f6bb16b6b, + 0xd917ab5c852e8585, + 0x3c677381bdcebdbd, + 0x8fba34d25d695d5d, + 0x9020508010401010, + 0x07f503f3f4f7f4f4, + 0xdd8bc016cb0bcbcb, + 0xd37cc6ed3ef83e3e, + 0x2d0a112805140505, + 0x78cee61f67816767, + 0x97d55373e4b7e4e4, + 0x024ebb25279c2727, + 0x7382583241194141, + 0xa70b9d2c8b168b8b, + 0xf6530151a7a6a7a7, + 0xb2fa94cf7de97d7d, + 0x4937fbdc956e9595, + 0x56ad9f8ed847d8d8, + 0x70eb308bfbcbfbfb, + 0xcdc17123ee9feeee, + 0xbbf891c77ced7c7c, + 0x71cce31766856666, + 0x7ba78ea6dd53dddd, + 0xaf2e4bb8175c1717, + 0x458e460247014747, + 0x1a21dc849e429e9e, + 0xd489c51eca0fcaca, + 0x585a99752db42d2d, + 0x2e637991bfc6bfbf, + 0x3f0e1b38071c0707, + 0xac472301ad8eadad, + 0xb0b42fea5a755a5a, + 0xef1bb56c83368383, + 0xb666ff8533cc3333, + 0x5cc6f23f63916363, + 0x12040a1002080202, + 0x93493839aa92aaaa, + 0xdee2a8af71d97171, + 0xc68dcf0ec807c8c8, + 0xd1327dc819641919, + 0x3b92707249394949, + 0x5faf9a86d943d9d9, + 0x31f91dc3f2eff2f2, + 0xa8db484be3abe3e3, + 0xb9b62ae25b715b5b, + 0xbc0d9234881a8888, + 0x3e29c8a49a529a9a, + 0x0b4cbe2d26982626, + 0xbf64fa8d32c83232, + 0x597d4ae9b0fab0b0, + 0xf2cf6a1be983e9e9, + 0x771e33780f3c0f0f, + 0x33b7a6e6d573d5d5, + 0xf41dba74803a8080, + 0x27617c99bec2bebe, + 0xeb87de26cd13cdcd, + 0x8968e4bd34d03434, + 0x3290757a483d4848, + 0x54e324abffdbffff, + 0x8df48ff77af57a7a, + 0x643deaf4907a9090, + 0x9dbe3ec25f615f5f, + 0x3d40a01d20802020, + 0x0fd0d56768bd6868, + 0xca3472d01a681a1a, + 0xb7412c19ae82aeae, + 0x7d755ec9b4eab4b4, + 0xcea8199a544d5454, + 0x7f3be5ec93769393, + 0x2f44aa0d22882222, + 0x63c8e907648d6464, + 0x2aff12dbf1e3f1f1, + 0xcce6a2bf73d17373, + 0x82245a9012481212, + 0x7a805d3a401d4040, + 0x4810284008200808, + 0x959be856c32bc3c3, + 0xdfc57b33ec97ecec, + 0x4dab9096db4bdbdb, + 0xc05f1f61a1bea1a1, + 0x9107831c8d0e8d8d, + 0xc87ac9f53df43d3d, + 0x5b33f1cc97669797, 0x0000000000000000, - 0xcfcf1bcf36d483f9, - 0x2b2bac2b4587566e, - 0x7676c57697b3ece1, - 0x8282328264b019e6, - 0xd6d67fd6fea9b128, - 0x1b1b6c1bd87736c3, - 0xb5b5eeb5c15b7774, - 0xafaf86af112943be, - 0x6a6ab56a77dfd41d, - 0x50505d50ba0da0ea, - 0x45450945124c8a57, - 0xf3f3ebf3cb18fb38, - 0x3030c0309df060ad, - 0xefef9bef2b74c3c4, - 0x3f3ffc3fe5c37eda, - 0x55554955921caac7, - 0xa2a2b2a2791059db, - 0xeaea8fea0365c9e9, - 0x656589650fecca6a, - 0xbabad2bab9686903, - 0x2f2fbc2f65935e4a, - 0xc0c027c04ee79d8e, - 0xdede5fdebe81a160, - 0x1c1c701ce06c38fc, - 0xfdfdd3fdbb2ee746, - 0x4d4d294d52649a1f, - 0x92927292e4e03976, - 0x7575c9758fbceafa, - 0x06061806301e0c36, - 0x8a8a128a249809ae, - 0xb2b2f2b2f940794b, - 0xe6e6bfe66359d185, - 0x0e0e380e70361c7e, - 0x1f1f7c1ff8633ee7, - 0x6262956237f7c455, - 0xd4d477d4eea3b53a, - 0xa8a89aa829324d81, - 0x96966296c4f43152, - 0xf9f9c3f99b3aef62, - 0xc5c533c566f697a3, - 0x2525942535b14a10, - 0x59597959f220b2ab, - 0x84842a8454ae15d0, - 0x7272d572b7a7e4c5, - 0x3939e439d5dd72ec, - 0x4c4c2d4c5a619816, - 0x5e5e655eca3bbc94, - 0x7878fd78e785f09f, - 0x3838e038ddd870e5, - 0x8c8c0a8c14860598, - 0xd1d163d1c6b2bf17, - 0xa5a5aea5410b57e4, - 0xe2e2afe2434dd9a1, - 0x616199612ff8c24e, - 0xb3b3f6b3f1457b42, - 0x2121842115a54234, - 0x9c9c4a9c94d62508, - 0x1e1e781ef0663cee, - 0x4343114322528661, - 0xc7c73bc776fc93b1, - 0xfcfcd7fcb32be54f, - 0x0404100420140824, - 0x51515951b208a2e3, - 0x99995e99bcc72f25, - 0x6d6da96d4fc4da22, - 0x0d0d340d68391a65, - 0xfafacffa8335e979, - 0xdfdf5bdfb684a369, - 0x7e7ee57ed79bfca9, - 0x242490243db44819, - 0x3b3bec3bc5d776fe, - 0xabab96ab313d4b9a, - 0xcece1fce3ed181f0, - 0x1111441188552299, - 0x8f8f068f0c890383, - 0x4e4e254e4a6b9c04, - 0xb7b7e6b7d1517366, - 0xebeb8beb0b60cbe0, - 0x3c3cf03cfdcc78c1, - 0x81813e817cbf1ffd, - 0x94946a94d4fe3540, - 0xf7f7fbf7eb0cf31c, - 0xb9b9deb9a1676f18, - 0x13134c13985f268b, - 0x2c2cb02c7d9c5851, - 0xd3d36bd3d6b8bb05, - 0xe7e7bbe76b5cd38c, - 0x6e6ea56e57cbdc39, - 0xc4c437c46ef395aa, - 0x03030c03180f061b, - 0x565645568a13acdc, - 0x44440d441a49885e, - 0x7f7fe17fdf9efea0, - 0xa9a99ea921374f88, - 0x2a2aa82a4d825467, - 0xbbbbd6bbb16d6b0a, - 0xc1c123c146e29f87, - 0x53535153a202a6f1, - 0xdcdc57dcae8ba572, - 0x0b0b2c0b58271653, - 0x9d9d4e9d9cd32701, - 0x6c6cad6c47c1d82b, - 0x3131c43195f562a4, - 0x7474cd7487b9e8f3, - 0xf6f6fff6e309f115, - 0x464605460a438c4c, - 0xacac8aac092645a5, - 0x89891e893c970fb5, - 0x14145014a04428b4, - 0xe1e1a3e15b42dfba, - 0x16165816b04e2ca6, - 0x3a3ae83acdd274f7, - 0x6969b9696fd0d206, - 0x09092409482d1241, - 0x7070dd70a7ade0d7, - 0xb6b6e2b6d954716f, - 0xd0d067d0ceb7bd1e, - 0xeded93ed3b7ec7d6, - 0xcccc17cc2edb85e2, - 0x424215422a578468, - 0x98985a98b4c22d2c, - 0xa4a4aaa4490e55ed, - 0x2828a0285d885075, - 0x5c5c6d5cda31b886, - 0xf8f8c7f8933fed6b, - 0x8686228644a411c2, + 0xf983d436cf1bcfcf, + 0x6e5687452bac2b2b, + 0xe1ecb39776c57676, + 0xe619b06482328282, + 0x28b1a9fed67fd6d6, + 0xc33677d81b6c1b1b, + 0x74775bc1b5eeb5b5, + 0xbe432911af86afaf, + 0x1dd4df776ab56a6a, + 0xeaa00dba505d5050, + 0x578a4c1245094545, + 0x38fb18cbf3ebf3f3, + 0xad60f09d30c03030, + 0xc4c3742bef9befef, + 0xda7ec3e53ffc3f3f, + 0xc7aa1c9255495555, + 0xdb591079a2b2a2a2, + 0xe9c96503ea8feaea, + 0x6acaec0f65896565, + 0x036968b9bad2baba, + 0x4a5e93652fbc2f2f, + 0x8e9de74ec027c0c0, + 0x60a181bede5fdede, + 0xfc386ce01c701c1c, + 0x46e72ebbfdd3fdfd, + 0x1f9a64524d294d4d, + 0x7639e0e492729292, + 0xfaeabc8f75c97575, + 0x360c1e3006180606, + 0xae0998248a128a8a, + 0x4b7940f9b2f2b2b2, + 0x85d15963e6bfe6e6, + 0x7e1c36700e380e0e, + 0xe73e63f81f7c1f1f, + 0x55c4f73762956262, + 0x3ab5a3eed477d4d4, + 0x814d3229a89aa8a8, + 0x5231f4c496629696, + 0x62ef3a9bf9c3f9f9, + 0xa397f666c533c5c5, + 0x104ab13525942525, + 0xabb220f259795959, + 0xd015ae54842a8484, + 0xc5e4a7b772d57272, + 0xec72ddd539e43939, + 0x1698615a4c2d4c4c, + 0x94bc3bca5e655e5e, + 0x9ff085e778fd7878, + 0xe570d8dd38e03838, + 0x980586148c0a8c8c, + 0x17bfb2c6d163d1d1, + 0xe4570b41a5aea5a5, + 0xa1d94d43e2afe2e2, + 0x4ec2f82f61996161, + 0x427b45f1b3f6b3b3, + 0x3442a51521842121, + 0x0825d6949c4a9c9c, + 0xee3c66f01e781e1e, + 0x6186522243114343, + 0xb193fc76c73bc7c7, + 0x4fe52bb3fcd7fcfc, + 0x2408142004100404, + 0xe3a208b251595151, + 0x252fc7bc995e9999, + 0x22dac44f6da96d6d, + 0x651a39680d340d0d, + 0x79e93583facffafa, + 0x69a384b6df5bdfdf, + 0xa9fc9bd77ee57e7e, + 0x1948b43d24902424, + 0xfe76d7c53bec3b3b, + 0x9a4b3d31ab96abab, + 0xf081d13ece1fcece, + 0x9922558811441111, + 0x8303890c8f068f8f, + 0x049c6b4a4e254e4e, + 0x667351d1b7e6b7b7, + 0xe0cb600beb8bebeb, + 0xc178ccfd3cf03c3c, + 0xfd1fbf7c813e8181, + 0x4035fed4946a9494, + 0x1cf30cebf7fbf7f7, + 0x186f67a1b9deb9b9, + 0x8b265f98134c1313, + 0x51589c7d2cb02c2c, + 0x05bbb8d6d36bd3d3, + 0x8cd35c6be7bbe7e7, + 0x39dccb576ea56e6e, + 0xaa95f36ec437c4c4, + 0x1b060f18030c0303, + 0xdcac138a56455656, + 0x5e88491a440d4444, + 0xa0fe9edf7fe17f7f, + 0x884f3721a99ea9a9, + 0x6754824d2aa82a2a, + 0x0a6b6db1bbd6bbbb, + 0x879fe246c123c1c1, + 0xf1a602a253515353, + 0x72a58baedc57dcdc, + 0x531627580b2c0b0b, + 0x0127d39c9d4e9d9d, + 0x2bd8c1476cad6c6c, + 0xa462f59531c43131, + 0xf3e8b98774cd7474, + 0x15f109e3f6fff6f6, + 0x4c8c430a46054646, + 0xa5452609ac8aacac, + 0xb50f973c891e8989, + 0xb42844a014501414, + 0xbadf425be1a3e1e1, + 0xa62c4eb016581616, + 0xf774d2cd3ae83a3a, + 0x06d2d06f69b96969, + 0x41122d4809240909, + 0xd7e0ada770dd7070, + 0x6f7154d9b6e2b6b6, + 0x1ebdb7ced067d0d0, + 0xd6c77e3bed93eded, + 0xe285db2ecc17cccc, + 0x6884572a42154242, + 0x2c2dc2b4985a9898, + 0xed550e49a4aaa4a4, + 0x7550885d28a02828, + 0x86b831da5c6d5c5c, + 0x6bed3f93f8c7f8f8, + 0xc211a44486228686, ]; -pub static C1: [u64; 256] = [ - 0xd818186018c07830, - 0x2623238c2305af46, - 0xb8c6c63fc67ef991, - 0xfbe8e887e8136fcd, - 0xcb878726874ca113, - 0x11b8b8dab8a9626d, - 0x0901010401080502, - 0x0d4f4f214f426e9e, - 0x9b3636d836adee6c, - 0xffa6a6a2a6590451, - 0x0cd2d26fd2debdb9, - 0x0ef5f5f3f5fb06f7, - 0x967979f979ef80f2, - 0x306f6fa16f5fcede, - 0x6d91917e91fcef3f, - 0xf852525552aa07a4, - 0x4760609d6027fdc0, - 0x35bcbccabc897665, - 0x379b9b569baccd2b, - 0x8a8e8e028e048c01, - 0xd2a3a3b6a371155b, - 0x6c0c0c300c603c18, - 0x847b7bf17bff8af6, - 0x803535d435b5e16a, - 0xf51d1d741de8693a, - 0xb3e0e0a7e05347dd, - 0x21d7d77bd7f6acb3, - 0x9cc2c22fc25eed99, - 0x432e2eb82e6d965c, - 0x294b4b314b627a96, - 0x5dfefedffea321e1, - 0xd5575741578216ae, - 0xbd15155415a8412a, - 0xe87777c1779fb6ee, - 0x923737dc37a5eb6e, - 0x9ee5e5b3e57b56d7, - 0x139f9f469f8cd923, - 0x23f0f0e7f0d317fd, - 0x204a4a354a6a7f94, - 0x44dada4fda9e95a9, - 0xa258587d58fa25b0, - 0xcfc9c903c906ca8f, - 0x7c2929a429558d52, - 0x5a0a0a280a502214, - 0x50b1b1feb1e14f7f, - 0xc9a0a0baa0691a5d, - 0x146b6bb16b7fdad6, - 0xd985852e855cab17, - 0x3cbdbdcebd817367, - 0x8f5d5d695dd234ba, - 0x9010104010805020, - 0x07f4f4f7f4f303f5, - 0xddcbcb0bcb16c08b, - 0xd33e3ef83eedc67c, - 0x2d0505140528110a, - 0x78676781671fe6ce, - 0x97e4e4b7e47353d5, - 0x0227279c2725bb4e, - 0x7341411941325882, - 0xa78b8b168b2c9d0b, - 0xf6a7a7a6a7510153, - 0xb27d7de97dcf94fa, - 0x4995956e95dcfb37, - 0x56d8d847d88e9fad, - 0x70fbfbcbfb8b30eb, - 0xcdeeee9fee2371c1, - 0xbb7c7ced7cc791f8, - 0x716666856617e3cc, - 0x7bdddd53dda68ea7, - 0xaf17175c17b84b2e, - 0x454747014702468e, - 0x1a9e9e429e84dc21, - 0xd4caca0fca1ec589, - 0x582d2db42d75995a, - 0x2ebfbfc6bf917963, - 0x3f07071c07381b0e, - 0xacadad8ead012347, - 0xb05a5a755aea2fb4, - 0xef838336836cb51b, - 0xb63333cc3385ff66, - 0x5c636391633ff2c6, - 0x1202020802100a04, - 0x93aaaa92aa393849, - 0xde7171d971afa8e2, - 0xc6c8c807c80ecf8d, - 0xd119196419c87d32, - 0x3b49493949727092, - 0x5fd9d943d9869aaf, - 0x31f2f2eff2c31df9, - 0xa8e3e3abe34b48db, - 0xb95b5b715be22ab6, - 0xbc88881a8834920d, - 0x3e9a9a529aa4c829, - 0x0b262698262dbe4c, - 0xbf3232c8328dfa64, - 0x59b0b0fab0e94a7d, - 0xf2e9e983e91b6acf, - 0x770f0f3c0f78331e, - 0x33d5d573d5e6a6b7, - 0xf480803a8074ba1d, - 0x27bebec2be997c61, - 0xebcdcd13cd26de87, - 0x893434d034bde468, - 0x3248483d487a7590, - 0x54ffffdbffab24e3, - 0x8d7a7af57af78ff4, - 0x6490907a90f4ea3d, - 0x9d5f5f615fc23ebe, - 0x3d202080201da040, - 0x0f6868bd6867d5d0, - 0xca1a1a681ad07234, - 0xb7aeae82ae192c41, - 0x7db4b4eab4c95e75, - 0xce54544d549a19a8, - 0x7f93937693ece53b, - 0x2f222288220daa44, - 0x6364648d6407e9c8, - 0x2af1f1e3f1db12ff, - 0xcc7373d173bfa2e6, - 0x8212124812905a24, - 0x7a40401d403a5d80, - 0x4808082008402810, - 0x95c3c32bc356e89b, - 0xdfecec97ec337bc5, - 0x4ddbdb4bdb9690ab, - 0xc0a1a1bea1611f5f, - 0x918d8d0e8d1c8307, - 0xc83d3df43df5c97a, - 0x5b97976697ccf133, +pub const C1: [u64; 256] = [ + 0x3078c018601818d8, + 0x46af05238c232326, + 0x91f97ec63fc6c6b8, + 0xcd6f13e887e8e8fb, + 0x13a14c87268787cb, + 0x6d62a9b8dab8b811, + 0x0205080104010109, + 0x9e6e424f214f4f0d, + 0x6ceead36d836369b, + 0x510459a6a2a6a6ff, + 0xb9bdded26fd2d20c, + 0xf706fbf5f3f5f50e, + 0xf280ef79f9797996, + 0xdece5f6fa16f6f30, + 0x3feffc917e91916d, + 0xa407aa52555252f8, + 0xc0fd27609d606047, + 0x657689bccabcbc35, + 0x2bcdac9b569b9b37, + 0x018c048e028e8e8a, + 0x5b1571a3b6a3a3d2, + 0x183c600c300c0c6c, + 0xf68aff7bf17b7b84, + 0x6ae1b535d4353580, + 0x3a69e81d741d1df5, + 0xdd4753e0a7e0e0b3, + 0xb3acf6d77bd7d721, + 0x99ed5ec22fc2c29c, + 0x5c966d2eb82e2e43, + 0x967a624b314b4b29, + 0xe121a3fedffefe5d, + 0xae168257415757d5, + 0x2a41a815541515bd, + 0xeeb69f77c17777e8, + 0x6eeba537dc373792, + 0xd7567be5b3e5e59e, + 0x23d98c9f469f9f13, + 0xfd17d3f0e7f0f023, + 0x947f6a4a354a4a20, + 0xa9959eda4fdada44, + 0xb025fa587d5858a2, + 0x8fca06c903c9c9cf, + 0x528d5529a429297c, + 0x1422500a280a0a5a, + 0x7f4fe1b1feb1b150, + 0x5d1a69a0baa0a0c9, + 0xd6da7f6bb16b6b14, + 0x17ab5c852e8585d9, + 0x677381bdcebdbd3c, + 0xba34d25d695d5d8f, + 0x2050801040101090, + 0xf503f3f4f7f4f407, + 0x8bc016cb0bcbcbdd, + 0x7cc6ed3ef83e3ed3, + 0x0a1128051405052d, + 0xcee61f6781676778, + 0xd55373e4b7e4e497, + 0x4ebb25279c272702, + 0x8258324119414173, + 0x0b9d2c8b168b8ba7, + 0x530151a7a6a7a7f6, + 0xfa94cf7de97d7db2, + 0x37fbdc956e959549, + 0xad9f8ed847d8d856, + 0xeb308bfbcbfbfb70, + 0xc17123ee9feeeecd, + 0xf891c77ced7c7cbb, + 0xcce3176685666671, + 0xa78ea6dd53dddd7b, + 0x2e4bb8175c1717af, + 0x8e46024701474745, + 0x21dc849e429e9e1a, + 0x89c51eca0fcacad4, + 0x5a99752db42d2d58, + 0x637991bfc6bfbf2e, + 0x0e1b38071c07073f, + 0x472301ad8eadadac, + 0xb42fea5a755a5ab0, + 0x1bb56c83368383ef, + 0x66ff8533cc3333b6, + 0xc6f23f639163635c, + 0x040a100208020212, + 0x493839aa92aaaa93, + 0xe2a8af71d97171de, + 0x8dcf0ec807c8c8c6, + 0x327dc819641919d1, + 0x927072493949493b, + 0xaf9a86d943d9d95f, + 0xf91dc3f2eff2f231, + 0xdb484be3abe3e3a8, + 0xb62ae25b715b5bb9, + 0x0d9234881a8888bc, + 0x29c8a49a529a9a3e, + 0x4cbe2d269826260b, + 0x64fa8d32c83232bf, + 0x7d4ae9b0fab0b059, + 0xcf6a1be983e9e9f2, + 0x1e33780f3c0f0f77, + 0xb7a6e6d573d5d533, + 0x1dba74803a8080f4, + 0x617c99bec2bebe27, + 0x87de26cd13cdcdeb, + 0x68e4bd34d0343489, + 0x90757a483d484832, + 0xe324abffdbffff54, + 0xf48ff77af57a7a8d, + 0x3deaf4907a909064, + 0xbe3ec25f615f5f9d, + 0x40a01d208020203d, + 0xd0d56768bd68680f, + 0x3472d01a681a1aca, + 0x412c19ae82aeaeb7, + 0x755ec9b4eab4b47d, + 0xa8199a544d5454ce, + 0x3be5ec937693937f, + 0x44aa0d228822222f, + 0xc8e907648d646463, + 0xff12dbf1e3f1f12a, + 0xe6a2bf73d17373cc, + 0x245a901248121282, + 0x805d3a401d40407a, + 0x1028400820080848, + 0x9be856c32bc3c395, + 0xc57b33ec97ececdf, + 0xab9096db4bdbdb4d, + 0x5f1f61a1bea1a1c0, + 0x07831c8d0e8d8d91, + 0x7ac9f53df43d3dc8, + 0x33f1cc976697975b, 0x0000000000000000, - 0xf9cfcf1bcf36d483, - 0x6e2b2bac2b458756, - 0xe17676c57697b3ec, - 0xe68282328264b019, - 0x28d6d67fd6fea9b1, - 0xc31b1b6c1bd87736, - 0x74b5b5eeb5c15b77, - 0xbeafaf86af112943, - 0x1d6a6ab56a77dfd4, - 0xea50505d50ba0da0, - 0x5745450945124c8a, - 0x38f3f3ebf3cb18fb, - 0xad3030c0309df060, - 0xc4efef9bef2b74c3, - 0xda3f3ffc3fe5c37e, - 0xc755554955921caa, - 0xdba2a2b2a2791059, - 0xe9eaea8fea0365c9, - 0x6a656589650fecca, - 0x03babad2bab96869, - 0x4a2f2fbc2f65935e, - 0x8ec0c027c04ee79d, - 0x60dede5fdebe81a1, - 0xfc1c1c701ce06c38, - 0x46fdfdd3fdbb2ee7, - 0x1f4d4d294d52649a, - 0x7692927292e4e039, - 0xfa7575c9758fbcea, - 0x3606061806301e0c, - 0xae8a8a128a249809, - 0x4bb2b2f2b2f94079, - 0x85e6e6bfe66359d1, - 0x7e0e0e380e70361c, - 0xe71f1f7c1ff8633e, - 0x556262956237f7c4, - 0x3ad4d477d4eea3b5, - 0x81a8a89aa829324d, - 0x5296966296c4f431, - 0x62f9f9c3f99b3aef, - 0xa3c5c533c566f697, - 0x102525942535b14a, - 0xab59597959f220b2, - 0xd084842a8454ae15, - 0xc57272d572b7a7e4, - 0xec3939e439d5dd72, - 0x164c4c2d4c5a6198, - 0x945e5e655eca3bbc, - 0x9f7878fd78e785f0, - 0xe53838e038ddd870, - 0x988c8c0a8c148605, - 0x17d1d163d1c6b2bf, - 0xe4a5a5aea5410b57, - 0xa1e2e2afe2434dd9, - 0x4e616199612ff8c2, - 0x42b3b3f6b3f1457b, - 0x342121842115a542, - 0x089c9c4a9c94d625, - 0xee1e1e781ef0663c, - 0x6143431143225286, - 0xb1c7c73bc776fc93, - 0x4ffcfcd7fcb32be5, - 0x2404041004201408, - 0xe351515951b208a2, - 0x2599995e99bcc72f, - 0x226d6da96d4fc4da, - 0x650d0d340d68391a, - 0x79fafacffa8335e9, - 0x69dfdf5bdfb684a3, - 0xa97e7ee57ed79bfc, - 0x19242490243db448, - 0xfe3b3bec3bc5d776, - 0x9aabab96ab313d4b, - 0xf0cece1fce3ed181, - 0x9911114411885522, - 0x838f8f068f0c8903, - 0x044e4e254e4a6b9c, - 0x66b7b7e6b7d15173, - 0xe0ebeb8beb0b60cb, - 0xc13c3cf03cfdcc78, - 0xfd81813e817cbf1f, - 0x4094946a94d4fe35, - 0x1cf7f7fbf7eb0cf3, - 0x18b9b9deb9a1676f, - 0x8b13134c13985f26, - 0x512c2cb02c7d9c58, - 0x05d3d36bd3d6b8bb, - 0x8ce7e7bbe76b5cd3, - 0x396e6ea56e57cbdc, - 0xaac4c437c46ef395, - 0x1b03030c03180f06, - 0xdc565645568a13ac, - 0x5e44440d441a4988, - 0xa07f7fe17fdf9efe, - 0x88a9a99ea921374f, - 0x672a2aa82a4d8254, - 0x0abbbbd6bbb16d6b, - 0x87c1c123c146e29f, - 0xf153535153a202a6, - 0x72dcdc57dcae8ba5, - 0x530b0b2c0b582716, - 0x019d9d4e9d9cd327, - 0x2b6c6cad6c47c1d8, - 0xa43131c43195f562, - 0xf37474cd7487b9e8, - 0x15f6f6fff6e309f1, - 0x4c464605460a438c, - 0xa5acac8aac092645, - 0xb589891e893c970f, - 0xb414145014a04428, - 0xbae1e1a3e15b42df, - 0xa616165816b04e2c, - 0xf73a3ae83acdd274, - 0x066969b9696fd0d2, - 0x4109092409482d12, - 0xd77070dd70a7ade0, - 0x6fb6b6e2b6d95471, - 0x1ed0d067d0ceb7bd, - 0xd6eded93ed3b7ec7, - 0xe2cccc17cc2edb85, - 0x68424215422a5784, - 0x2c98985a98b4c22d, - 0xeda4a4aaa4490e55, - 0x752828a0285d8850, - 0x865c5c6d5cda31b8, - 0x6bf8f8c7f8933fed, - 0xc28686228644a411, + 0x83d436cf1bcfcff9, + 0x5687452bac2b2b6e, + 0xecb39776c57676e1, + 0x19b06482328282e6, + 0xb1a9fed67fd6d628, + 0x3677d81b6c1b1bc3, + 0x775bc1b5eeb5b574, + 0x432911af86afafbe, + 0xd4df776ab56a6a1d, + 0xa00dba505d5050ea, + 0x8a4c124509454557, + 0xfb18cbf3ebf3f338, + 0x60f09d30c03030ad, + 0xc3742bef9befefc4, + 0x7ec3e53ffc3f3fda, + 0xaa1c9255495555c7, + 0x591079a2b2a2a2db, + 0xc96503ea8feaeae9, + 0xcaec0f658965656a, + 0x6968b9bad2baba03, + 0x5e93652fbc2f2f4a, + 0x9de74ec027c0c08e, + 0xa181bede5fdede60, + 0x386ce01c701c1cfc, + 0xe72ebbfdd3fdfd46, + 0x9a64524d294d4d1f, + 0x39e0e49272929276, + 0xeabc8f75c97575fa, + 0x0c1e300618060636, + 0x0998248a128a8aae, + 0x7940f9b2f2b2b24b, + 0xd15963e6bfe6e685, + 0x1c36700e380e0e7e, + 0x3e63f81f7c1f1fe7, + 0xc4f7376295626255, + 0xb5a3eed477d4d43a, + 0x4d3229a89aa8a881, + 0x31f4c49662969652, + 0xef3a9bf9c3f9f962, + 0x97f666c533c5c5a3, + 0x4ab1352594252510, + 0xb220f259795959ab, + 0x15ae54842a8484d0, + 0xe4a7b772d57272c5, + 0x72ddd539e43939ec, + 0x98615a4c2d4c4c16, + 0xbc3bca5e655e5e94, + 0xf085e778fd78789f, + 0x70d8dd38e03838e5, + 0x0586148c0a8c8c98, + 0xbfb2c6d163d1d117, + 0x570b41a5aea5a5e4, + 0xd94d43e2afe2e2a1, + 0xc2f82f619961614e, + 0x7b45f1b3f6b3b342, + 0x42a5152184212134, + 0x25d6949c4a9c9c08, + 0x3c66f01e781e1eee, + 0x8652224311434361, + 0x93fc76c73bc7c7b1, + 0xe52bb3fcd7fcfc4f, + 0x0814200410040424, + 0xa208b251595151e3, + 0x2fc7bc995e999925, + 0xdac44f6da96d6d22, + 0x1a39680d340d0d65, + 0xe93583facffafa79, + 0xa384b6df5bdfdf69, + 0xfc9bd77ee57e7ea9, + 0x48b43d2490242419, + 0x76d7c53bec3b3bfe, + 0x4b3d31ab96abab9a, + 0x81d13ece1fcecef0, + 0x2255881144111199, + 0x03890c8f068f8f83, + 0x9c6b4a4e254e4e04, + 0x7351d1b7e6b7b766, + 0xcb600beb8bebebe0, + 0x78ccfd3cf03c3cc1, + 0x1fbf7c813e8181fd, + 0x35fed4946a949440, + 0xf30cebf7fbf7f71c, + 0x6f67a1b9deb9b918, + 0x265f98134c13138b, + 0x589c7d2cb02c2c51, + 0xbbb8d6d36bd3d305, + 0xd35c6be7bbe7e78c, + 0xdccb576ea56e6e39, + 0x95f36ec437c4c4aa, + 0x060f18030c03031b, + 0xac138a56455656dc, + 0x88491a440d44445e, + 0xfe9edf7fe17f7fa0, + 0x4f3721a99ea9a988, + 0x54824d2aa82a2a67, + 0x6b6db1bbd6bbbb0a, + 0x9fe246c123c1c187, + 0xa602a253515353f1, + 0xa58baedc57dcdc72, + 0x1627580b2c0b0b53, + 0x27d39c9d4e9d9d01, + 0xd8c1476cad6c6c2b, + 0x62f59531c43131a4, + 0xe8b98774cd7474f3, + 0xf109e3f6fff6f615, + 0x8c430a460546464c, + 0x452609ac8aacaca5, + 0x0f973c891e8989b5, + 0x2844a014501414b4, + 0xdf425be1a3e1e1ba, + 0x2c4eb016581616a6, + 0x74d2cd3ae83a3af7, + 0xd2d06f69b9696906, + 0x122d480924090941, + 0xe0ada770dd7070d7, + 0x7154d9b6e2b6b66f, + 0xbdb7ced067d0d01e, + 0xc77e3bed93ededd6, + 0x85db2ecc17cccce2, + 0x84572a4215424268, + 0x2dc2b4985a98982c, + 0x550e49a4aaa4a4ed, + 0x50885d28a0282875, + 0xb831da5c6d5c5c86, + 0xed3f93f8c7f8f86b, + 0x11a44486228686c2, ]; -pub static C2: [u64; 256] = [ - 0x30d818186018c078, - 0x462623238c2305af, - 0x91b8c6c63fc67ef9, - 0xcdfbe8e887e8136f, - 0x13cb878726874ca1, - 0x6d11b8b8dab8a962, - 0x0209010104010805, - 0x9e0d4f4f214f426e, - 0x6c9b3636d836adee, - 0x51ffa6a6a2a65904, - 0xb90cd2d26fd2debd, - 0xf70ef5f5f3f5fb06, - 0xf2967979f979ef80, - 0xde306f6fa16f5fce, - 0x3f6d91917e91fcef, - 0xa4f852525552aa07, - 0xc04760609d6027fd, - 0x6535bcbccabc8976, - 0x2b379b9b569baccd, - 0x018a8e8e028e048c, - 0x5bd2a3a3b6a37115, - 0x186c0c0c300c603c, - 0xf6847b7bf17bff8a, - 0x6a803535d435b5e1, - 0x3af51d1d741de869, - 0xddb3e0e0a7e05347, - 0xb321d7d77bd7f6ac, - 0x999cc2c22fc25eed, - 0x5c432e2eb82e6d96, - 0x96294b4b314b627a, - 0xe15dfefedffea321, - 0xaed5575741578216, - 0x2abd15155415a841, - 0xeee87777c1779fb6, - 0x6e923737dc37a5eb, - 0xd79ee5e5b3e57b56, - 0x23139f9f469f8cd9, - 0xfd23f0f0e7f0d317, - 0x94204a4a354a6a7f, - 0xa944dada4fda9e95, - 0xb0a258587d58fa25, - 0x8fcfc9c903c906ca, - 0x527c2929a429558d, - 0x145a0a0a280a5022, - 0x7f50b1b1feb1e14f, - 0x5dc9a0a0baa0691a, - 0xd6146b6bb16b7fda, - 0x17d985852e855cab, - 0x673cbdbdcebd8173, - 0xba8f5d5d695dd234, - 0x2090101040108050, - 0xf507f4f4f7f4f303, - 0x8bddcbcb0bcb16c0, - 0x7cd33e3ef83eedc6, - 0x0a2d050514052811, - 0xce78676781671fe6, - 0xd597e4e4b7e47353, - 0x4e0227279c2725bb, - 0x8273414119413258, - 0x0ba78b8b168b2c9d, - 0x53f6a7a7a6a75101, - 0xfab27d7de97dcf94, - 0x374995956e95dcfb, - 0xad56d8d847d88e9f, - 0xeb70fbfbcbfb8b30, - 0xc1cdeeee9fee2371, - 0xf8bb7c7ced7cc791, - 0xcc716666856617e3, - 0xa77bdddd53dda68e, - 0x2eaf17175c17b84b, - 0x8e45474701470246, - 0x211a9e9e429e84dc, - 0x89d4caca0fca1ec5, - 0x5a582d2db42d7599, - 0x632ebfbfc6bf9179, - 0x0e3f07071c07381b, - 0x47acadad8ead0123, - 0xb4b05a5a755aea2f, - 0x1bef838336836cb5, - 0x66b63333cc3385ff, - 0xc65c636391633ff2, - 0x041202020802100a, - 0x4993aaaa92aa3938, - 0xe2de7171d971afa8, - 0x8dc6c8c807c80ecf, - 0x32d119196419c87d, - 0x923b494939497270, - 0xaf5fd9d943d9869a, - 0xf931f2f2eff2c31d, - 0xdba8e3e3abe34b48, - 0xb6b95b5b715be22a, - 0x0dbc88881a883492, - 0x293e9a9a529aa4c8, - 0x4c0b262698262dbe, - 0x64bf3232c8328dfa, - 0x7d59b0b0fab0e94a, - 0xcff2e9e983e91b6a, - 0x1e770f0f3c0f7833, - 0xb733d5d573d5e6a6, - 0x1df480803a8074ba, - 0x6127bebec2be997c, - 0x87ebcdcd13cd26de, - 0x68893434d034bde4, - 0x903248483d487a75, - 0xe354ffffdbffab24, - 0xf48d7a7af57af78f, - 0x3d6490907a90f4ea, - 0xbe9d5f5f615fc23e, - 0x403d202080201da0, - 0xd00f6868bd6867d5, - 0x34ca1a1a681ad072, - 0x41b7aeae82ae192c, - 0x757db4b4eab4c95e, - 0xa8ce54544d549a19, - 0x3b7f93937693ece5, - 0x442f222288220daa, - 0xc86364648d6407e9, - 0xff2af1f1e3f1db12, - 0xe6cc7373d173bfa2, - 0x248212124812905a, - 0x807a40401d403a5d, - 0x1048080820084028, - 0x9b95c3c32bc356e8, - 0xc5dfecec97ec337b, - 0xab4ddbdb4bdb9690, - 0x5fc0a1a1bea1611f, - 0x07918d8d0e8d1c83, - 0x7ac83d3df43df5c9, - 0x335b97976697ccf1, +pub const C2: [u64; 256] = [ + 0x78c018601818d830, + 0xaf05238c23232646, + 0xf97ec63fc6c6b891, + 0x6f13e887e8e8fbcd, + 0xa14c87268787cb13, + 0x62a9b8dab8b8116d, + 0x0508010401010902, + 0x6e424f214f4f0d9e, + 0xeead36d836369b6c, + 0x0459a6a2a6a6ff51, + 0xbdded26fd2d20cb9, + 0x06fbf5f3f5f50ef7, + 0x80ef79f9797996f2, + 0xce5f6fa16f6f30de, + 0xeffc917e91916d3f, + 0x07aa52555252f8a4, + 0xfd27609d606047c0, + 0x7689bccabcbc3565, + 0xcdac9b569b9b372b, + 0x8c048e028e8e8a01, + 0x1571a3b6a3a3d25b, + 0x3c600c300c0c6c18, + 0x8aff7bf17b7b84f6, + 0xe1b535d43535806a, + 0x69e81d741d1df53a, + 0x4753e0a7e0e0b3dd, + 0xacf6d77bd7d721b3, + 0xed5ec22fc2c29c99, + 0x966d2eb82e2e435c, + 0x7a624b314b4b2996, + 0x21a3fedffefe5de1, + 0x168257415757d5ae, + 0x41a815541515bd2a, + 0xb69f77c17777e8ee, + 0xeba537dc3737926e, + 0x567be5b3e5e59ed7, + 0xd98c9f469f9f1323, + 0x17d3f0e7f0f023fd, + 0x7f6a4a354a4a2094, + 0x959eda4fdada44a9, + 0x25fa587d5858a2b0, + 0xca06c903c9c9cf8f, + 0x8d5529a429297c52, + 0x22500a280a0a5a14, + 0x4fe1b1feb1b1507f, + 0x1a69a0baa0a0c95d, + 0xda7f6bb16b6b14d6, + 0xab5c852e8585d917, + 0x7381bdcebdbd3c67, + 0x34d25d695d5d8fba, + 0x5080104010109020, + 0x03f3f4f7f4f407f5, + 0xc016cb0bcbcbdd8b, + 0xc6ed3ef83e3ed37c, + 0x1128051405052d0a, + 0xe61f6781676778ce, + 0x5373e4b7e4e497d5, + 0xbb25279c2727024e, + 0x5832411941417382, + 0x9d2c8b168b8ba70b, + 0x0151a7a6a7a7f653, + 0x94cf7de97d7db2fa, + 0xfbdc956e95954937, + 0x9f8ed847d8d856ad, + 0x308bfbcbfbfb70eb, + 0x7123ee9feeeecdc1, + 0x91c77ced7c7cbbf8, + 0xe3176685666671cc, + 0x8ea6dd53dddd7ba7, + 0x4bb8175c1717af2e, + 0x460247014747458e, + 0xdc849e429e9e1a21, + 0xc51eca0fcacad489, + 0x99752db42d2d585a, + 0x7991bfc6bfbf2e63, + 0x1b38071c07073f0e, + 0x2301ad8eadadac47, + 0x2fea5a755a5ab0b4, + 0xb56c83368383ef1b, + 0xff8533cc3333b666, + 0xf23f639163635cc6, + 0x0a10020802021204, + 0x3839aa92aaaa9349, + 0xa8af71d97171dee2, + 0xcf0ec807c8c8c68d, + 0x7dc819641919d132, + 0x7072493949493b92, + 0x9a86d943d9d95faf, + 0x1dc3f2eff2f231f9, + 0x484be3abe3e3a8db, + 0x2ae25b715b5bb9b6, + 0x9234881a8888bc0d, + 0xc8a49a529a9a3e29, + 0xbe2d269826260b4c, + 0xfa8d32c83232bf64, + 0x4ae9b0fab0b0597d, + 0x6a1be983e9e9f2cf, + 0x33780f3c0f0f771e, + 0xa6e6d573d5d533b7, + 0xba74803a8080f41d, + 0x7c99bec2bebe2761, + 0xde26cd13cdcdeb87, + 0xe4bd34d034348968, + 0x757a483d48483290, + 0x24abffdbffff54e3, + 0x8ff77af57a7a8df4, + 0xeaf4907a9090643d, + 0x3ec25f615f5f9dbe, + 0xa01d208020203d40, + 0xd56768bd68680fd0, + 0x72d01a681a1aca34, + 0x2c19ae82aeaeb741, + 0x5ec9b4eab4b47d75, + 0x199a544d5454cea8, + 0xe5ec937693937f3b, + 0xaa0d228822222f44, + 0xe907648d646463c8, + 0x12dbf1e3f1f12aff, + 0xa2bf73d17373cce6, + 0x5a90124812128224, + 0x5d3a401d40407a80, + 0x2840082008084810, + 0xe856c32bc3c3959b, + 0x7b33ec97ececdfc5, + 0x9096db4bdbdb4dab, + 0x1f61a1bea1a1c05f, + 0x831c8d0e8d8d9107, + 0xc9f53df43d3dc87a, + 0xf1cc976697975b33, 0x0000000000000000, - 0x83f9cfcf1bcf36d4, - 0x566e2b2bac2b4587, - 0xece17676c57697b3, - 0x19e68282328264b0, - 0xb128d6d67fd6fea9, - 0x36c31b1b6c1bd877, - 0x7774b5b5eeb5c15b, - 0x43beafaf86af1129, - 0xd41d6a6ab56a77df, - 0xa0ea50505d50ba0d, - 0x8a5745450945124c, - 0xfb38f3f3ebf3cb18, - 0x60ad3030c0309df0, - 0xc3c4efef9bef2b74, - 0x7eda3f3ffc3fe5c3, - 0xaac755554955921c, - 0x59dba2a2b2a27910, - 0xc9e9eaea8fea0365, - 0xca6a656589650fec, - 0x6903babad2bab968, - 0x5e4a2f2fbc2f6593, - 0x9d8ec0c027c04ee7, - 0xa160dede5fdebe81, - 0x38fc1c1c701ce06c, - 0xe746fdfdd3fdbb2e, - 0x9a1f4d4d294d5264, - 0x397692927292e4e0, - 0xeafa7575c9758fbc, - 0x0c3606061806301e, - 0x09ae8a8a128a2498, - 0x794bb2b2f2b2f940, - 0xd185e6e6bfe66359, - 0x1c7e0e0e380e7036, - 0x3ee71f1f7c1ff863, - 0xc4556262956237f7, - 0xb53ad4d477d4eea3, - 0x4d81a8a89aa82932, - 0x315296966296c4f4, - 0xef62f9f9c3f99b3a, - 0x97a3c5c533c566f6, - 0x4a102525942535b1, - 0xb2ab59597959f220, - 0x15d084842a8454ae, - 0xe4c57272d572b7a7, - 0x72ec3939e439d5dd, - 0x98164c4c2d4c5a61, - 0xbc945e5e655eca3b, - 0xf09f7878fd78e785, - 0x70e53838e038ddd8, - 0x05988c8c0a8c1486, - 0xbf17d1d163d1c6b2, - 0x57e4a5a5aea5410b, - 0xd9a1e2e2afe2434d, - 0xc24e616199612ff8, - 0x7b42b3b3f6b3f145, - 0x42342121842115a5, - 0x25089c9c4a9c94d6, - 0x3cee1e1e781ef066, - 0x8661434311432252, - 0x93b1c7c73bc776fc, - 0xe54ffcfcd7fcb32b, - 0x0824040410042014, - 0xa2e351515951b208, - 0x2f2599995e99bcc7, - 0xda226d6da96d4fc4, - 0x1a650d0d340d6839, - 0xe979fafacffa8335, - 0xa369dfdf5bdfb684, - 0xfca97e7ee57ed79b, - 0x4819242490243db4, - 0x76fe3b3bec3bc5d7, - 0x4b9aabab96ab313d, - 0x81f0cece1fce3ed1, - 0x2299111144118855, - 0x03838f8f068f0c89, - 0x9c044e4e254e4a6b, - 0x7366b7b7e6b7d151, - 0xcbe0ebeb8beb0b60, - 0x78c13c3cf03cfdcc, - 0x1ffd81813e817cbf, - 0x354094946a94d4fe, - 0xf31cf7f7fbf7eb0c, - 0x6f18b9b9deb9a167, - 0x268b13134c13985f, - 0x58512c2cb02c7d9c, - 0xbb05d3d36bd3d6b8, - 0xd38ce7e7bbe76b5c, - 0xdc396e6ea56e57cb, - 0x95aac4c437c46ef3, - 0x061b03030c03180f, - 0xacdc565645568a13, - 0x885e44440d441a49, - 0xfea07f7fe17fdf9e, - 0x4f88a9a99ea92137, - 0x54672a2aa82a4d82, - 0x6b0abbbbd6bbb16d, - 0x9f87c1c123c146e2, - 0xa6f153535153a202, - 0xa572dcdc57dcae8b, - 0x16530b0b2c0b5827, - 0x27019d9d4e9d9cd3, - 0xd82b6c6cad6c47c1, - 0x62a43131c43195f5, - 0xe8f37474cd7487b9, - 0xf115f6f6fff6e309, - 0x8c4c464605460a43, - 0x45a5acac8aac0926, - 0x0fb589891e893c97, - 0x28b414145014a044, - 0xdfbae1e1a3e15b42, - 0x2ca616165816b04e, - 0x74f73a3ae83acdd2, - 0xd2066969b9696fd0, - 0x124109092409482d, - 0xe0d77070dd70a7ad, - 0x716fb6b6e2b6d954, - 0xbd1ed0d067d0ceb7, - 0xc7d6eded93ed3b7e, - 0x85e2cccc17cc2edb, - 0x8468424215422a57, - 0x2d2c98985a98b4c2, - 0x55eda4a4aaa4490e, - 0x50752828a0285d88, - 0xb8865c5c6d5cda31, - 0xed6bf8f8c7f8933f, - 0x11c28686228644a4, + 0xd436cf1bcfcff983, + 0x87452bac2b2b6e56, + 0xb39776c57676e1ec, + 0xb06482328282e619, + 0xa9fed67fd6d628b1, + 0x77d81b6c1b1bc336, + 0x5bc1b5eeb5b57477, + 0x2911af86afafbe43, + 0xdf776ab56a6a1dd4, + 0x0dba505d5050eaa0, + 0x4c1245094545578a, + 0x18cbf3ebf3f338fb, + 0xf09d30c03030ad60, + 0x742bef9befefc4c3, + 0xc3e53ffc3f3fda7e, + 0x1c9255495555c7aa, + 0x1079a2b2a2a2db59, + 0x6503ea8feaeae9c9, + 0xec0f658965656aca, + 0x68b9bad2baba0369, + 0x93652fbc2f2f4a5e, + 0xe74ec027c0c08e9d, + 0x81bede5fdede60a1, + 0x6ce01c701c1cfc38, + 0x2ebbfdd3fdfd46e7, + 0x64524d294d4d1f9a, + 0xe0e4927292927639, + 0xbc8f75c97575faea, + 0x1e3006180606360c, + 0x98248a128a8aae09, + 0x40f9b2f2b2b24b79, + 0x5963e6bfe6e685d1, + 0x36700e380e0e7e1c, + 0x63f81f7c1f1fe73e, + 0xf7376295626255c4, + 0xa3eed477d4d43ab5, + 0x3229a89aa8a8814d, + 0xf4c4966296965231, + 0x3a9bf9c3f9f962ef, + 0xf666c533c5c5a397, + 0xb13525942525104a, + 0x20f259795959abb2, + 0xae54842a8484d015, + 0xa7b772d57272c5e4, + 0xddd539e43939ec72, + 0x615a4c2d4c4c1698, + 0x3bca5e655e5e94bc, + 0x85e778fd78789ff0, + 0xd8dd38e03838e570, + 0x86148c0a8c8c9805, + 0xb2c6d163d1d117bf, + 0x0b41a5aea5a5e457, + 0x4d43e2afe2e2a1d9, + 0xf82f619961614ec2, + 0x45f1b3f6b3b3427b, + 0xa515218421213442, + 0xd6949c4a9c9c0825, + 0x66f01e781e1eee3c, + 0x5222431143436186, + 0xfc76c73bc7c7b193, + 0x2bb3fcd7fcfc4fe5, + 0x1420041004042408, + 0x08b251595151e3a2, + 0xc7bc995e9999252f, + 0xc44f6da96d6d22da, + 0x39680d340d0d651a, + 0x3583facffafa79e9, + 0x84b6df5bdfdf69a3, + 0x9bd77ee57e7ea9fc, + 0xb43d249024241948, + 0xd7c53bec3b3bfe76, + 0x3d31ab96abab9a4b, + 0xd13ece1fcecef081, + 0x5588114411119922, + 0x890c8f068f8f8303, + 0x6b4a4e254e4e049c, + 0x51d1b7e6b7b76673, + 0x600beb8bebebe0cb, + 0xccfd3cf03c3cc178, + 0xbf7c813e8181fd1f, + 0xfed4946a94944035, + 0x0cebf7fbf7f71cf3, + 0x67a1b9deb9b9186f, + 0x5f98134c13138b26, + 0x9c7d2cb02c2c5158, + 0xb8d6d36bd3d305bb, + 0x5c6be7bbe7e78cd3, + 0xcb576ea56e6e39dc, + 0xf36ec437c4c4aa95, + 0x0f18030c03031b06, + 0x138a56455656dcac, + 0x491a440d44445e88, + 0x9edf7fe17f7fa0fe, + 0x3721a99ea9a9884f, + 0x824d2aa82a2a6754, + 0x6db1bbd6bbbb0a6b, + 0xe246c123c1c1879f, + 0x02a253515353f1a6, + 0x8baedc57dcdc72a5, + 0x27580b2c0b0b5316, + 0xd39c9d4e9d9d0127, + 0xc1476cad6c6c2bd8, + 0xf59531c43131a462, + 0xb98774cd7474f3e8, + 0x09e3f6fff6f615f1, + 0x430a460546464c8c, + 0x2609ac8aacaca545, + 0x973c891e8989b50f, + 0x44a014501414b428, + 0x425be1a3e1e1badf, + 0x4eb016581616a62c, + 0xd2cd3ae83a3af774, + 0xd06f69b9696906d2, + 0x2d48092409094112, + 0xada770dd7070d7e0, + 0x54d9b6e2b6b66f71, + 0xb7ced067d0d01ebd, + 0x7e3bed93ededd6c7, + 0xdb2ecc17cccce285, + 0x572a421542426884, + 0xc2b4985a98982c2d, + 0x0e49a4aaa4a4ed55, + 0x885d28a028287550, + 0x31da5c6d5c5c86b8, + 0x3f93f8c7f8f86bed, + 0xa44486228686c211, ]; -pub static C3: [u64; 256] = [ - 0x7830d818186018c0, - 0xaf462623238c2305, - 0xf991b8c6c63fc67e, - 0x6fcdfbe8e887e813, - 0xa113cb878726874c, - 0x626d11b8b8dab8a9, - 0x0502090101040108, - 0x6e9e0d4f4f214f42, - 0xee6c9b3636d836ad, - 0x0451ffa6a6a2a659, - 0xbdb90cd2d26fd2de, - 0x06f70ef5f5f3f5fb, - 0x80f2967979f979ef, - 0xcede306f6fa16f5f, - 0xef3f6d91917e91fc, - 0x07a4f852525552aa, - 0xfdc04760609d6027, - 0x766535bcbccabc89, - 0xcd2b379b9b569bac, - 0x8c018a8e8e028e04, - 0x155bd2a3a3b6a371, - 0x3c186c0c0c300c60, - 0x8af6847b7bf17bff, - 0xe16a803535d435b5, - 0x693af51d1d741de8, - 0x47ddb3e0e0a7e053, - 0xacb321d7d77bd7f6, - 0xed999cc2c22fc25e, - 0x965c432e2eb82e6d, - 0x7a96294b4b314b62, - 0x21e15dfefedffea3, - 0x16aed55757415782, - 0x412abd15155415a8, - 0xb6eee87777c1779f, - 0xeb6e923737dc37a5, - 0x56d79ee5e5b3e57b, - 0xd923139f9f469f8c, - 0x17fd23f0f0e7f0d3, - 0x7f94204a4a354a6a, - 0x95a944dada4fda9e, - 0x25b0a258587d58fa, - 0xca8fcfc9c903c906, - 0x8d527c2929a42955, - 0x22145a0a0a280a50, - 0x4f7f50b1b1feb1e1, - 0x1a5dc9a0a0baa069, - 0xdad6146b6bb16b7f, - 0xab17d985852e855c, - 0x73673cbdbdcebd81, - 0x34ba8f5d5d695dd2, - 0x5020901010401080, - 0x03f507f4f4f7f4f3, - 0xc08bddcbcb0bcb16, - 0xc67cd33e3ef83eed, - 0x110a2d0505140528, - 0xe6ce78676781671f, - 0x53d597e4e4b7e473, - 0xbb4e0227279c2725, - 0x5882734141194132, - 0x9d0ba78b8b168b2c, - 0x0153f6a7a7a6a751, - 0x94fab27d7de97dcf, - 0xfb374995956e95dc, - 0x9fad56d8d847d88e, - 0x30eb70fbfbcbfb8b, - 0x71c1cdeeee9fee23, - 0x91f8bb7c7ced7cc7, - 0xe3cc716666856617, - 0x8ea77bdddd53dda6, - 0x4b2eaf17175c17b8, - 0x468e454747014702, - 0xdc211a9e9e429e84, - 0xc589d4caca0fca1e, - 0x995a582d2db42d75, - 0x79632ebfbfc6bf91, - 0x1b0e3f07071c0738, - 0x2347acadad8ead01, - 0x2fb4b05a5a755aea, - 0xb51bef838336836c, - 0xff66b63333cc3385, - 0xf2c65c636391633f, - 0x0a04120202080210, - 0x384993aaaa92aa39, - 0xa8e2de7171d971af, - 0xcf8dc6c8c807c80e, - 0x7d32d119196419c8, - 0x70923b4949394972, - 0x9aaf5fd9d943d986, - 0x1df931f2f2eff2c3, - 0x48dba8e3e3abe34b, - 0x2ab6b95b5b715be2, - 0x920dbc88881a8834, - 0xc8293e9a9a529aa4, - 0xbe4c0b262698262d, - 0xfa64bf3232c8328d, - 0x4a7d59b0b0fab0e9, - 0x6acff2e9e983e91b, - 0x331e770f0f3c0f78, - 0xa6b733d5d573d5e6, - 0xba1df480803a8074, - 0x7c6127bebec2be99, - 0xde87ebcdcd13cd26, - 0xe468893434d034bd, - 0x75903248483d487a, - 0x24e354ffffdbffab, - 0x8ff48d7a7af57af7, - 0xea3d6490907a90f4, - 0x3ebe9d5f5f615fc2, - 0xa0403d202080201d, - 0xd5d00f6868bd6867, - 0x7234ca1a1a681ad0, - 0x2c41b7aeae82ae19, - 0x5e757db4b4eab4c9, - 0x19a8ce54544d549a, - 0xe53b7f93937693ec, - 0xaa442f222288220d, - 0xe9c86364648d6407, - 0x12ff2af1f1e3f1db, - 0xa2e6cc7373d173bf, - 0x5a24821212481290, - 0x5d807a40401d403a, - 0x2810480808200840, - 0xe89b95c3c32bc356, - 0x7bc5dfecec97ec33, - 0x90ab4ddbdb4bdb96, - 0x1f5fc0a1a1bea161, - 0x8307918d8d0e8d1c, - 0xc97ac83d3df43df5, - 0xf1335b97976697cc, +pub const C3: [u64; 256] = [ + 0xc018601818d83078, + 0x05238c23232646af, + 0x7ec63fc6c6b891f9, + 0x13e887e8e8fbcd6f, + 0x4c87268787cb13a1, + 0xa9b8dab8b8116d62, + 0x0801040101090205, + 0x424f214f4f0d9e6e, + 0xad36d836369b6cee, + 0x59a6a2a6a6ff5104, + 0xded26fd2d20cb9bd, + 0xfbf5f3f5f50ef706, + 0xef79f9797996f280, + 0x5f6fa16f6f30dece, + 0xfc917e91916d3fef, + 0xaa52555252f8a407, + 0x27609d606047c0fd, + 0x89bccabcbc356576, + 0xac9b569b9b372bcd, + 0x048e028e8e8a018c, + 0x71a3b6a3a3d25b15, + 0x600c300c0c6c183c, + 0xff7bf17b7b84f68a, + 0xb535d43535806ae1, + 0xe81d741d1df53a69, + 0x53e0a7e0e0b3dd47, + 0xf6d77bd7d721b3ac, + 0x5ec22fc2c29c99ed, + 0x6d2eb82e2e435c96, + 0x624b314b4b29967a, + 0xa3fedffefe5de121, + 0x8257415757d5ae16, + 0xa815541515bd2a41, + 0x9f77c17777e8eeb6, + 0xa537dc3737926eeb, + 0x7be5b3e5e59ed756, + 0x8c9f469f9f1323d9, + 0xd3f0e7f0f023fd17, + 0x6a4a354a4a20947f, + 0x9eda4fdada44a995, + 0xfa587d5858a2b025, + 0x06c903c9c9cf8fca, + 0x5529a429297c528d, + 0x500a280a0a5a1422, + 0xe1b1feb1b1507f4f, + 0x69a0baa0a0c95d1a, + 0x7f6bb16b6b14d6da, + 0x5c852e8585d917ab, + 0x81bdcebdbd3c6773, + 0xd25d695d5d8fba34, + 0x8010401010902050, + 0xf3f4f7f4f407f503, + 0x16cb0bcbcbdd8bc0, + 0xed3ef83e3ed37cc6, + 0x28051405052d0a11, + 0x1f6781676778cee6, + 0x73e4b7e4e497d553, + 0x25279c2727024ebb, + 0x3241194141738258, + 0x2c8b168b8ba70b9d, + 0x51a7a6a7a7f65301, + 0xcf7de97d7db2fa94, + 0xdc956e95954937fb, + 0x8ed847d8d856ad9f, + 0x8bfbcbfbfb70eb30, + 0x23ee9feeeecdc171, + 0xc77ced7c7cbbf891, + 0x176685666671cce3, + 0xa6dd53dddd7ba78e, + 0xb8175c1717af2e4b, + 0x0247014747458e46, + 0x849e429e9e1a21dc, + 0x1eca0fcacad489c5, + 0x752db42d2d585a99, + 0x91bfc6bfbf2e6379, + 0x38071c07073f0e1b, + 0x01ad8eadadac4723, + 0xea5a755a5ab0b42f, + 0x6c83368383ef1bb5, + 0x8533cc3333b666ff, + 0x3f639163635cc6f2, + 0x100208020212040a, + 0x39aa92aaaa934938, + 0xaf71d97171dee2a8, + 0x0ec807c8c8c68dcf, + 0xc819641919d1327d, + 0x72493949493b9270, + 0x86d943d9d95faf9a, + 0xc3f2eff2f231f91d, + 0x4be3abe3e3a8db48, + 0xe25b715b5bb9b62a, + 0x34881a8888bc0d92, + 0xa49a529a9a3e29c8, + 0x2d269826260b4cbe, + 0x8d32c83232bf64fa, + 0xe9b0fab0b0597d4a, + 0x1be983e9e9f2cf6a, + 0x780f3c0f0f771e33, + 0xe6d573d5d533b7a6, + 0x74803a8080f41dba, + 0x99bec2bebe27617c, + 0x26cd13cdcdeb87de, + 0xbd34d034348968e4, + 0x7a483d4848329075, + 0xabffdbffff54e324, + 0xf77af57a7a8df48f, + 0xf4907a9090643dea, + 0xc25f615f5f9dbe3e, + 0x1d208020203d40a0, + 0x6768bd68680fd0d5, + 0xd01a681a1aca3472, + 0x19ae82aeaeb7412c, + 0xc9b4eab4b47d755e, + 0x9a544d5454cea819, + 0xec937693937f3be5, + 0x0d228822222f44aa, + 0x07648d646463c8e9, + 0xdbf1e3f1f12aff12, + 0xbf73d17373cce6a2, + 0x901248121282245a, + 0x3a401d40407a805d, + 0x4008200808481028, + 0x56c32bc3c3959be8, + 0x33ec97ececdfc57b, + 0x96db4bdbdb4dab90, + 0x61a1bea1a1c05f1f, + 0x1c8d0e8d8d910783, + 0xf53df43d3dc87ac9, + 0xcc976697975b33f1, 0x0000000000000000, - 0xd483f9cfcf1bcf36, - 0x87566e2b2bac2b45, - 0xb3ece17676c57697, - 0xb019e68282328264, - 0xa9b128d6d67fd6fe, - 0x7736c31b1b6c1bd8, - 0x5b7774b5b5eeb5c1, - 0x2943beafaf86af11, - 0xdfd41d6a6ab56a77, - 0x0da0ea50505d50ba, - 0x4c8a574545094512, - 0x18fb38f3f3ebf3cb, - 0xf060ad3030c0309d, - 0x74c3c4efef9bef2b, - 0xc37eda3f3ffc3fe5, - 0x1caac75555495592, - 0x1059dba2a2b2a279, - 0x65c9e9eaea8fea03, - 0xecca6a656589650f, - 0x686903babad2bab9, - 0x935e4a2f2fbc2f65, - 0xe79d8ec0c027c04e, - 0x81a160dede5fdebe, - 0x6c38fc1c1c701ce0, - 0x2ee746fdfdd3fdbb, - 0x649a1f4d4d294d52, - 0xe0397692927292e4, - 0xbceafa7575c9758f, - 0x1e0c360606180630, - 0x9809ae8a8a128a24, - 0x40794bb2b2f2b2f9, - 0x59d185e6e6bfe663, - 0x361c7e0e0e380e70, - 0x633ee71f1f7c1ff8, - 0xf7c4556262956237, - 0xa3b53ad4d477d4ee, - 0x324d81a8a89aa829, - 0xf4315296966296c4, - 0x3aef62f9f9c3f99b, - 0xf697a3c5c533c566, - 0xb14a102525942535, - 0x20b2ab59597959f2, - 0xae15d084842a8454, - 0xa7e4c57272d572b7, - 0xdd72ec3939e439d5, - 0x6198164c4c2d4c5a, - 0x3bbc945e5e655eca, - 0x85f09f7878fd78e7, - 0xd870e53838e038dd, - 0x8605988c8c0a8c14, - 0xb2bf17d1d163d1c6, - 0x0b57e4a5a5aea541, - 0x4dd9a1e2e2afe243, - 0xf8c24e616199612f, - 0x457b42b3b3f6b3f1, - 0xa542342121842115, - 0xd625089c9c4a9c94, - 0x663cee1e1e781ef0, - 0x5286614343114322, - 0xfc93b1c7c73bc776, - 0x2be54ffcfcd7fcb3, - 0x1408240404100420, - 0x08a2e351515951b2, - 0xc72f2599995e99bc, - 0xc4da226d6da96d4f, - 0x391a650d0d340d68, - 0x35e979fafacffa83, - 0x84a369dfdf5bdfb6, - 0x9bfca97e7ee57ed7, - 0xb44819242490243d, - 0xd776fe3b3bec3bc5, - 0x3d4b9aabab96ab31, - 0xd181f0cece1fce3e, - 0x5522991111441188, - 0x8903838f8f068f0c, - 0x6b9c044e4e254e4a, - 0x517366b7b7e6b7d1, - 0x60cbe0ebeb8beb0b, - 0xcc78c13c3cf03cfd, - 0xbf1ffd81813e817c, - 0xfe354094946a94d4, - 0x0cf31cf7f7fbf7eb, - 0x676f18b9b9deb9a1, - 0x5f268b13134c1398, - 0x9c58512c2cb02c7d, - 0xb8bb05d3d36bd3d6, - 0x5cd38ce7e7bbe76b, - 0xcbdc396e6ea56e57, - 0xf395aac4c437c46e, - 0x0f061b03030c0318, - 0x13acdc565645568a, - 0x49885e44440d441a, - 0x9efea07f7fe17fdf, - 0x374f88a9a99ea921, - 0x8254672a2aa82a4d, - 0x6d6b0abbbbd6bbb1, - 0xe29f87c1c123c146, - 0x02a6f153535153a2, - 0x8ba572dcdc57dcae, - 0x2716530b0b2c0b58, - 0xd327019d9d4e9d9c, - 0xc1d82b6c6cad6c47, - 0xf562a43131c43195, - 0xb9e8f37474cd7487, - 0x09f115f6f6fff6e3, - 0x438c4c464605460a, - 0x2645a5acac8aac09, - 0x970fb589891e893c, - 0x4428b414145014a0, - 0x42dfbae1e1a3e15b, - 0x4e2ca616165816b0, - 0xd274f73a3ae83acd, - 0xd0d2066969b9696f, - 0x2d12410909240948, - 0xade0d77070dd70a7, - 0x54716fb6b6e2b6d9, - 0xb7bd1ed0d067d0ce, - 0x7ec7d6eded93ed3b, - 0xdb85e2cccc17cc2e, - 0x578468424215422a, - 0xc22d2c98985a98b4, - 0x0e55eda4a4aaa449, - 0x8850752828a0285d, - 0x31b8865c5c6d5cda, - 0x3fed6bf8f8c7f893, - 0xa411c28686228644, + 0x36cf1bcfcff983d4, + 0x452bac2b2b6e5687, + 0x9776c57676e1ecb3, + 0x6482328282e619b0, + 0xfed67fd6d628b1a9, + 0xd81b6c1b1bc33677, + 0xc1b5eeb5b574775b, + 0x11af86afafbe4329, + 0x776ab56a6a1dd4df, + 0xba505d5050eaa00d, + 0x1245094545578a4c, + 0xcbf3ebf3f338fb18, + 0x9d30c03030ad60f0, + 0x2bef9befefc4c374, + 0xe53ffc3f3fda7ec3, + 0x9255495555c7aa1c, + 0x79a2b2a2a2db5910, + 0x03ea8feaeae9c965, + 0x0f658965656acaec, + 0xb9bad2baba036968, + 0x652fbc2f2f4a5e93, + 0x4ec027c0c08e9de7, + 0xbede5fdede60a181, + 0xe01c701c1cfc386c, + 0xbbfdd3fdfd46e72e, + 0x524d294d4d1f9a64, + 0xe4927292927639e0, + 0x8f75c97575faeabc, + 0x3006180606360c1e, + 0x248a128a8aae0998, + 0xf9b2f2b2b24b7940, + 0x63e6bfe6e685d159, + 0x700e380e0e7e1c36, + 0xf81f7c1f1fe73e63, + 0x376295626255c4f7, + 0xeed477d4d43ab5a3, + 0x29a89aa8a8814d32, + 0xc4966296965231f4, + 0x9bf9c3f9f962ef3a, + 0x66c533c5c5a397f6, + 0x3525942525104ab1, + 0xf259795959abb220, + 0x54842a8484d015ae, + 0xb772d57272c5e4a7, + 0xd539e43939ec72dd, + 0x5a4c2d4c4c169861, + 0xca5e655e5e94bc3b, + 0xe778fd78789ff085, + 0xdd38e03838e570d8, + 0x148c0a8c8c980586, + 0xc6d163d1d117bfb2, + 0x41a5aea5a5e4570b, + 0x43e2afe2e2a1d94d, + 0x2f619961614ec2f8, + 0xf1b3f6b3b3427b45, + 0x15218421213442a5, + 0x949c4a9c9c0825d6, + 0xf01e781e1eee3c66, + 0x2243114343618652, + 0x76c73bc7c7b193fc, + 0xb3fcd7fcfc4fe52b, + 0x2004100404240814, + 0xb251595151e3a208, + 0xbc995e9999252fc7, + 0x4f6da96d6d22dac4, + 0x680d340d0d651a39, + 0x83facffafa79e935, + 0xb6df5bdfdf69a384, + 0xd77ee57e7ea9fc9b, + 0x3d249024241948b4, + 0xc53bec3b3bfe76d7, + 0x31ab96abab9a4b3d, + 0x3ece1fcecef081d1, + 0x8811441111992255, + 0x0c8f068f8f830389, + 0x4a4e254e4e049c6b, + 0xd1b7e6b7b7667351, + 0x0beb8bebebe0cb60, + 0xfd3cf03c3cc178cc, + 0x7c813e8181fd1fbf, + 0xd4946a94944035fe, + 0xebf7fbf7f71cf30c, + 0xa1b9deb9b9186f67, + 0x98134c13138b265f, + 0x7d2cb02c2c51589c, + 0xd6d36bd3d305bbb8, + 0x6be7bbe7e78cd35c, + 0x576ea56e6e39dccb, + 0x6ec437c4c4aa95f3, + 0x18030c03031b060f, + 0x8a56455656dcac13, + 0x1a440d44445e8849, + 0xdf7fe17f7fa0fe9e, + 0x21a99ea9a9884f37, + 0x4d2aa82a2a675482, + 0xb1bbd6bbbb0a6b6d, + 0x46c123c1c1879fe2, + 0xa253515353f1a602, + 0xaedc57dcdc72a58b, + 0x580b2c0b0b531627, + 0x9c9d4e9d9d0127d3, + 0x476cad6c6c2bd8c1, + 0x9531c43131a462f5, + 0x8774cd7474f3e8b9, + 0xe3f6fff6f615f109, + 0x0a460546464c8c43, + 0x09ac8aacaca54526, + 0x3c891e8989b50f97, + 0xa014501414b42844, + 0x5be1a3e1e1badf42, + 0xb016581616a62c4e, + 0xcd3ae83a3af774d2, + 0x6f69b9696906d2d0, + 0x480924090941122d, + 0xa770dd7070d7e0ad, + 0xd9b6e2b6b66f7154, + 0xced067d0d01ebdb7, + 0x3bed93ededd6c77e, + 0x2ecc17cccce285db, + 0x2a42154242688457, + 0xb4985a98982c2dc2, + 0x49a4aaa4a4ed550e, + 0x5d28a02828755088, + 0xda5c6d5c5c86b831, + 0x93f8c7f8f86bed3f, + 0x4486228686c211a4, ]; -pub static C4: [u64; 256] = [ - 0xc07830d818186018, - 0x05af462623238c23, - 0x7ef991b8c6c63fc6, - 0x136fcdfbe8e887e8, - 0x4ca113cb87872687, - 0xa9626d11b8b8dab8, - 0x0805020901010401, - 0x426e9e0d4f4f214f, - 0xadee6c9b3636d836, - 0x590451ffa6a6a2a6, - 0xdebdb90cd2d26fd2, - 0xfb06f70ef5f5f3f5, - 0xef80f2967979f979, - 0x5fcede306f6fa16f, - 0xfcef3f6d91917e91, - 0xaa07a4f852525552, - 0x27fdc04760609d60, - 0x89766535bcbccabc, - 0xaccd2b379b9b569b, - 0x048c018a8e8e028e, - 0x71155bd2a3a3b6a3, - 0x603c186c0c0c300c, - 0xff8af6847b7bf17b, - 0xb5e16a803535d435, - 0xe8693af51d1d741d, - 0x5347ddb3e0e0a7e0, - 0xf6acb321d7d77bd7, - 0x5eed999cc2c22fc2, - 0x6d965c432e2eb82e, - 0x627a96294b4b314b, - 0xa321e15dfefedffe, - 0x8216aed557574157, - 0xa8412abd15155415, - 0x9fb6eee87777c177, - 0xa5eb6e923737dc37, - 0x7b56d79ee5e5b3e5, - 0x8cd923139f9f469f, - 0xd317fd23f0f0e7f0, - 0x6a7f94204a4a354a, - 0x9e95a944dada4fda, - 0xfa25b0a258587d58, - 0x06ca8fcfc9c903c9, - 0x558d527c2929a429, - 0x5022145a0a0a280a, - 0xe14f7f50b1b1feb1, - 0x691a5dc9a0a0baa0, - 0x7fdad6146b6bb16b, - 0x5cab17d985852e85, - 0x8173673cbdbdcebd, - 0xd234ba8f5d5d695d, - 0x8050209010104010, - 0xf303f507f4f4f7f4, - 0x16c08bddcbcb0bcb, - 0xedc67cd33e3ef83e, - 0x28110a2d05051405, - 0x1fe6ce7867678167, - 0x7353d597e4e4b7e4, - 0x25bb4e0227279c27, - 0x3258827341411941, - 0x2c9d0ba78b8b168b, - 0x510153f6a7a7a6a7, - 0xcf94fab27d7de97d, - 0xdcfb374995956e95, - 0x8e9fad56d8d847d8, - 0x8b30eb70fbfbcbfb, - 0x2371c1cdeeee9fee, - 0xc791f8bb7c7ced7c, - 0x17e3cc7166668566, - 0xa68ea77bdddd53dd, - 0xb84b2eaf17175c17, - 0x02468e4547470147, - 0x84dc211a9e9e429e, - 0x1ec589d4caca0fca, - 0x75995a582d2db42d, - 0x9179632ebfbfc6bf, - 0x381b0e3f07071c07, - 0x012347acadad8ead, - 0xea2fb4b05a5a755a, - 0x6cb51bef83833683, - 0x85ff66b63333cc33, - 0x3ff2c65c63639163, - 0x100a041202020802, - 0x39384993aaaa92aa, - 0xafa8e2de7171d971, - 0x0ecf8dc6c8c807c8, - 0xc87d32d119196419, - 0x7270923b49493949, - 0x869aaf5fd9d943d9, - 0xc31df931f2f2eff2, - 0x4b48dba8e3e3abe3, - 0xe22ab6b95b5b715b, - 0x34920dbc88881a88, - 0xa4c8293e9a9a529a, - 0x2dbe4c0b26269826, - 0x8dfa64bf3232c832, - 0xe94a7d59b0b0fab0, - 0x1b6acff2e9e983e9, - 0x78331e770f0f3c0f, - 0xe6a6b733d5d573d5, - 0x74ba1df480803a80, - 0x997c6127bebec2be, - 0x26de87ebcdcd13cd, - 0xbde468893434d034, - 0x7a75903248483d48, - 0xab24e354ffffdbff, - 0xf78ff48d7a7af57a, - 0xf4ea3d6490907a90, - 0xc23ebe9d5f5f615f, - 0x1da0403d20208020, - 0x67d5d00f6868bd68, - 0xd07234ca1a1a681a, - 0x192c41b7aeae82ae, - 0xc95e757db4b4eab4, - 0x9a19a8ce54544d54, - 0xece53b7f93937693, - 0x0daa442f22228822, - 0x07e9c86364648d64, - 0xdb12ff2af1f1e3f1, - 0xbfa2e6cc7373d173, - 0x905a248212124812, - 0x3a5d807a40401d40, - 0x4028104808082008, - 0x56e89b95c3c32bc3, - 0x337bc5dfecec97ec, - 0x9690ab4ddbdb4bdb, - 0x611f5fc0a1a1bea1, - 0x1c8307918d8d0e8d, - 0xf5c97ac83d3df43d, - 0xccf1335b97976697, +pub const C4: [u64; 256] = [ + 0x18601818d83078c0, + 0x238c23232646af05, + 0xc63fc6c6b891f97e, + 0xe887e8e8fbcd6f13, + 0x87268787cb13a14c, + 0xb8dab8b8116d62a9, + 0x0104010109020508, + 0x4f214f4f0d9e6e42, + 0x36d836369b6ceead, + 0xa6a2a6a6ff510459, + 0xd26fd2d20cb9bdde, + 0xf5f3f5f50ef706fb, + 0x79f9797996f280ef, + 0x6fa16f6f30dece5f, + 0x917e91916d3feffc, + 0x52555252f8a407aa, + 0x609d606047c0fd27, + 0xbccabcbc35657689, + 0x9b569b9b372bcdac, + 0x8e028e8e8a018c04, + 0xa3b6a3a3d25b1571, + 0x0c300c0c6c183c60, + 0x7bf17b7b84f68aff, + 0x35d43535806ae1b5, + 0x1d741d1df53a69e8, + 0xe0a7e0e0b3dd4753, + 0xd77bd7d721b3acf6, + 0xc22fc2c29c99ed5e, + 0x2eb82e2e435c966d, + 0x4b314b4b29967a62, + 0xfedffefe5de121a3, + 0x57415757d5ae1682, + 0x15541515bd2a41a8, + 0x77c17777e8eeb69f, + 0x37dc3737926eeba5, + 0xe5b3e5e59ed7567b, + 0x9f469f9f1323d98c, + 0xf0e7f0f023fd17d3, + 0x4a354a4a20947f6a, + 0xda4fdada44a9959e, + 0x587d5858a2b025fa, + 0xc903c9c9cf8fca06, + 0x29a429297c528d55, + 0x0a280a0a5a142250, + 0xb1feb1b1507f4fe1, + 0xa0baa0a0c95d1a69, + 0x6bb16b6b14d6da7f, + 0x852e8585d917ab5c, + 0xbdcebdbd3c677381, + 0x5d695d5d8fba34d2, + 0x1040101090205080, + 0xf4f7f4f407f503f3, + 0xcb0bcbcbdd8bc016, + 0x3ef83e3ed37cc6ed, + 0x051405052d0a1128, + 0x6781676778cee61f, + 0xe4b7e4e497d55373, + 0x279c2727024ebb25, + 0x4119414173825832, + 0x8b168b8ba70b9d2c, + 0xa7a6a7a7f6530151, + 0x7de97d7db2fa94cf, + 0x956e95954937fbdc, + 0xd847d8d856ad9f8e, + 0xfbcbfbfb70eb308b, + 0xee9feeeecdc17123, + 0x7ced7c7cbbf891c7, + 0x6685666671cce317, + 0xdd53dddd7ba78ea6, + 0x175c1717af2e4bb8, + 0x47014747458e4602, + 0x9e429e9e1a21dc84, + 0xca0fcacad489c51e, + 0x2db42d2d585a9975, + 0xbfc6bfbf2e637991, + 0x071c07073f0e1b38, + 0xad8eadadac472301, + 0x5a755a5ab0b42fea, + 0x83368383ef1bb56c, + 0x33cc3333b666ff85, + 0x639163635cc6f23f, + 0x0208020212040a10, + 0xaa92aaaa93493839, + 0x71d97171dee2a8af, + 0xc807c8c8c68dcf0e, + 0x19641919d1327dc8, + 0x493949493b927072, + 0xd943d9d95faf9a86, + 0xf2eff2f231f91dc3, + 0xe3abe3e3a8db484b, + 0x5b715b5bb9b62ae2, + 0x881a8888bc0d9234, + 0x9a529a9a3e29c8a4, + 0x269826260b4cbe2d, + 0x32c83232bf64fa8d, + 0xb0fab0b0597d4ae9, + 0xe983e9e9f2cf6a1b, + 0x0f3c0f0f771e3378, + 0xd573d5d533b7a6e6, + 0x803a8080f41dba74, + 0xbec2bebe27617c99, + 0xcd13cdcdeb87de26, + 0x34d034348968e4bd, + 0x483d48483290757a, + 0xffdbffff54e324ab, + 0x7af57a7a8df48ff7, + 0x907a9090643deaf4, + 0x5f615f5f9dbe3ec2, + 0x208020203d40a01d, + 0x68bd68680fd0d567, + 0x1a681a1aca3472d0, + 0xae82aeaeb7412c19, + 0xb4eab4b47d755ec9, + 0x544d5454cea8199a, + 0x937693937f3be5ec, + 0x228822222f44aa0d, + 0x648d646463c8e907, + 0xf1e3f1f12aff12db, + 0x73d17373cce6a2bf, + 0x1248121282245a90, + 0x401d40407a805d3a, + 0x0820080848102840, + 0xc32bc3c3959be856, + 0xec97ececdfc57b33, + 0xdb4bdbdb4dab9096, + 0xa1bea1a1c05f1f61, + 0x8d0e8d8d9107831c, + 0x3df43d3dc87ac9f5, + 0x976697975b33f1cc, 0x0000000000000000, - 0x36d483f9cfcf1bcf, - 0x4587566e2b2bac2b, - 0x97b3ece17676c576, - 0x64b019e682823282, - 0xfea9b128d6d67fd6, - 0xd87736c31b1b6c1b, - 0xc15b7774b5b5eeb5, - 0x112943beafaf86af, - 0x77dfd41d6a6ab56a, - 0xba0da0ea50505d50, - 0x124c8a5745450945, - 0xcb18fb38f3f3ebf3, - 0x9df060ad3030c030, - 0x2b74c3c4efef9bef, - 0xe5c37eda3f3ffc3f, - 0x921caac755554955, - 0x791059dba2a2b2a2, - 0x0365c9e9eaea8fea, - 0x0fecca6a65658965, - 0xb9686903babad2ba, - 0x65935e4a2f2fbc2f, - 0x4ee79d8ec0c027c0, - 0xbe81a160dede5fde, - 0xe06c38fc1c1c701c, - 0xbb2ee746fdfdd3fd, - 0x52649a1f4d4d294d, - 0xe4e0397692927292, - 0x8fbceafa7575c975, - 0x301e0c3606061806, - 0x249809ae8a8a128a, - 0xf940794bb2b2f2b2, - 0x6359d185e6e6bfe6, - 0x70361c7e0e0e380e, - 0xf8633ee71f1f7c1f, - 0x37f7c45562629562, - 0xeea3b53ad4d477d4, - 0x29324d81a8a89aa8, - 0xc4f4315296966296, - 0x9b3aef62f9f9c3f9, - 0x66f697a3c5c533c5, - 0x35b14a1025259425, - 0xf220b2ab59597959, - 0x54ae15d084842a84, - 0xb7a7e4c57272d572, - 0xd5dd72ec3939e439, - 0x5a6198164c4c2d4c, - 0xca3bbc945e5e655e, - 0xe785f09f7878fd78, - 0xddd870e53838e038, - 0x148605988c8c0a8c, - 0xc6b2bf17d1d163d1, - 0x410b57e4a5a5aea5, - 0x434dd9a1e2e2afe2, - 0x2ff8c24e61619961, - 0xf1457b42b3b3f6b3, - 0x15a5423421218421, - 0x94d625089c9c4a9c, - 0xf0663cee1e1e781e, - 0x2252866143431143, - 0x76fc93b1c7c73bc7, - 0xb32be54ffcfcd7fc, - 0x2014082404041004, - 0xb208a2e351515951, - 0xbcc72f2599995e99, - 0x4fc4da226d6da96d, - 0x68391a650d0d340d, - 0x8335e979fafacffa, - 0xb684a369dfdf5bdf, - 0xd79bfca97e7ee57e, - 0x3db4481924249024, - 0xc5d776fe3b3bec3b, - 0x313d4b9aabab96ab, - 0x3ed181f0cece1fce, - 0x8855229911114411, - 0x0c8903838f8f068f, - 0x4a6b9c044e4e254e, - 0xd1517366b7b7e6b7, - 0x0b60cbe0ebeb8beb, - 0xfdcc78c13c3cf03c, - 0x7cbf1ffd81813e81, - 0xd4fe354094946a94, - 0xeb0cf31cf7f7fbf7, - 0xa1676f18b9b9deb9, - 0x985f268b13134c13, - 0x7d9c58512c2cb02c, - 0xd6b8bb05d3d36bd3, - 0x6b5cd38ce7e7bbe7, - 0x57cbdc396e6ea56e, - 0x6ef395aac4c437c4, - 0x180f061b03030c03, - 0x8a13acdc56564556, - 0x1a49885e44440d44, - 0xdf9efea07f7fe17f, - 0x21374f88a9a99ea9, - 0x4d8254672a2aa82a, - 0xb16d6b0abbbbd6bb, - 0x46e29f87c1c123c1, - 0xa202a6f153535153, - 0xae8ba572dcdc57dc, - 0x582716530b0b2c0b, - 0x9cd327019d9d4e9d, - 0x47c1d82b6c6cad6c, - 0x95f562a43131c431, - 0x87b9e8f37474cd74, - 0xe309f115f6f6fff6, - 0x0a438c4c46460546, - 0x092645a5acac8aac, - 0x3c970fb589891e89, - 0xa04428b414145014, - 0x5b42dfbae1e1a3e1, - 0xb04e2ca616165816, - 0xcdd274f73a3ae83a, - 0x6fd0d2066969b969, - 0x482d124109092409, - 0xa7ade0d77070dd70, - 0xd954716fb6b6e2b6, - 0xceb7bd1ed0d067d0, - 0x3b7ec7d6eded93ed, - 0x2edb85e2cccc17cc, - 0x2a57846842421542, - 0xb4c22d2c98985a98, - 0x490e55eda4a4aaa4, - 0x5d8850752828a028, - 0xda31b8865c5c6d5c, - 0x933fed6bf8f8c7f8, - 0x44a411c286862286, + 0xcf1bcfcff983d436, + 0x2bac2b2b6e568745, + 0x76c57676e1ecb397, + 0x82328282e619b064, + 0xd67fd6d628b1a9fe, + 0x1b6c1b1bc33677d8, + 0xb5eeb5b574775bc1, + 0xaf86afafbe432911, + 0x6ab56a6a1dd4df77, + 0x505d5050eaa00dba, + 0x45094545578a4c12, + 0xf3ebf3f338fb18cb, + 0x30c03030ad60f09d, + 0xef9befefc4c3742b, + 0x3ffc3f3fda7ec3e5, + 0x55495555c7aa1c92, + 0xa2b2a2a2db591079, + 0xea8feaeae9c96503, + 0x658965656acaec0f, + 0xbad2baba036968b9, + 0x2fbc2f2f4a5e9365, + 0xc027c0c08e9de74e, + 0xde5fdede60a181be, + 0x1c701c1cfc386ce0, + 0xfdd3fdfd46e72ebb, + 0x4d294d4d1f9a6452, + 0x927292927639e0e4, + 0x75c97575faeabc8f, + 0x06180606360c1e30, + 0x8a128a8aae099824, + 0xb2f2b2b24b7940f9, + 0xe6bfe6e685d15963, + 0x0e380e0e7e1c3670, + 0x1f7c1f1fe73e63f8, + 0x6295626255c4f737, + 0xd477d4d43ab5a3ee, + 0xa89aa8a8814d3229, + 0x966296965231f4c4, + 0xf9c3f9f962ef3a9b, + 0xc533c5c5a397f666, + 0x25942525104ab135, + 0x59795959abb220f2, + 0x842a8484d015ae54, + 0x72d57272c5e4a7b7, + 0x39e43939ec72ddd5, + 0x4c2d4c4c1698615a, + 0x5e655e5e94bc3bca, + 0x78fd78789ff085e7, + 0x38e03838e570d8dd, + 0x8c0a8c8c98058614, + 0xd163d1d117bfb2c6, + 0xa5aea5a5e4570b41, + 0xe2afe2e2a1d94d43, + 0x619961614ec2f82f, + 0xb3f6b3b3427b45f1, + 0x218421213442a515, + 0x9c4a9c9c0825d694, + 0x1e781e1eee3c66f0, + 0x4311434361865222, + 0xc73bc7c7b193fc76, + 0xfcd7fcfc4fe52bb3, + 0x0410040424081420, + 0x51595151e3a208b2, + 0x995e9999252fc7bc, + 0x6da96d6d22dac44f, + 0x0d340d0d651a3968, + 0xfacffafa79e93583, + 0xdf5bdfdf69a384b6, + 0x7ee57e7ea9fc9bd7, + 0x249024241948b43d, + 0x3bec3b3bfe76d7c5, + 0xab96abab9a4b3d31, + 0xce1fcecef081d13e, + 0x1144111199225588, + 0x8f068f8f8303890c, + 0x4e254e4e049c6b4a, + 0xb7e6b7b7667351d1, + 0xeb8bebebe0cb600b, + 0x3cf03c3cc178ccfd, + 0x813e8181fd1fbf7c, + 0x946a94944035fed4, + 0xf7fbf7f71cf30ceb, + 0xb9deb9b9186f67a1, + 0x134c13138b265f98, + 0x2cb02c2c51589c7d, + 0xd36bd3d305bbb8d6, + 0xe7bbe7e78cd35c6b, + 0x6ea56e6e39dccb57, + 0xc437c4c4aa95f36e, + 0x030c03031b060f18, + 0x56455656dcac138a, + 0x440d44445e88491a, + 0x7fe17f7fa0fe9edf, + 0xa99ea9a9884f3721, + 0x2aa82a2a6754824d, + 0xbbd6bbbb0a6b6db1, + 0xc123c1c1879fe246, + 0x53515353f1a602a2, + 0xdc57dcdc72a58bae, + 0x0b2c0b0b53162758, + 0x9d4e9d9d0127d39c, + 0x6cad6c6c2bd8c147, + 0x31c43131a462f595, + 0x74cd7474f3e8b987, + 0xf6fff6f615f109e3, + 0x460546464c8c430a, + 0xac8aacaca5452609, + 0x891e8989b50f973c, + 0x14501414b42844a0, + 0xe1a3e1e1badf425b, + 0x16581616a62c4eb0, + 0x3ae83a3af774d2cd, + 0x69b9696906d2d06f, + 0x0924090941122d48, + 0x70dd7070d7e0ada7, + 0xb6e2b6b66f7154d9, + 0xd067d0d01ebdb7ce, + 0xed93ededd6c77e3b, + 0xcc17cccce285db2e, + 0x421542426884572a, + 0x985a98982c2dc2b4, + 0xa4aaa4a4ed550e49, + 0x28a028287550885d, + 0x5c6d5c5c86b831da, + 0xf8c7f8f86bed3f93, + 0x86228686c211a444, ]; -pub static C5: [u64; 256] = [ - 0x18c07830d8181860, - 0x2305af462623238c, - 0xc67ef991b8c6c63f, - 0xe8136fcdfbe8e887, - 0x874ca113cb878726, - 0xb8a9626d11b8b8da, - 0x0108050209010104, - 0x4f426e9e0d4f4f21, - 0x36adee6c9b3636d8, - 0xa6590451ffa6a6a2, - 0xd2debdb90cd2d26f, - 0xf5fb06f70ef5f5f3, - 0x79ef80f2967979f9, - 0x6f5fcede306f6fa1, - 0x91fcef3f6d91917e, - 0x52aa07a4f8525255, - 0x6027fdc04760609d, - 0xbc89766535bcbcca, - 0x9baccd2b379b9b56, - 0x8e048c018a8e8e02, - 0xa371155bd2a3a3b6, - 0x0c603c186c0c0c30, - 0x7bff8af6847b7bf1, - 0x35b5e16a803535d4, - 0x1de8693af51d1d74, - 0xe05347ddb3e0e0a7, - 0xd7f6acb321d7d77b, - 0xc25eed999cc2c22f, - 0x2e6d965c432e2eb8, - 0x4b627a96294b4b31, - 0xfea321e15dfefedf, - 0x578216aed5575741, - 0x15a8412abd151554, - 0x779fb6eee87777c1, - 0x37a5eb6e923737dc, - 0xe57b56d79ee5e5b3, - 0x9f8cd923139f9f46, - 0xf0d317fd23f0f0e7, - 0x4a6a7f94204a4a35, - 0xda9e95a944dada4f, - 0x58fa25b0a258587d, - 0xc906ca8fcfc9c903, - 0x29558d527c2929a4, - 0x0a5022145a0a0a28, - 0xb1e14f7f50b1b1fe, - 0xa0691a5dc9a0a0ba, - 0x6b7fdad6146b6bb1, - 0x855cab17d985852e, - 0xbd8173673cbdbdce, - 0x5dd234ba8f5d5d69, - 0x1080502090101040, - 0xf4f303f507f4f4f7, - 0xcb16c08bddcbcb0b, - 0x3eedc67cd33e3ef8, - 0x0528110a2d050514, - 0x671fe6ce78676781, - 0xe47353d597e4e4b7, - 0x2725bb4e0227279c, - 0x4132588273414119, - 0x8b2c9d0ba78b8b16, - 0xa7510153f6a7a7a6, - 0x7dcf94fab27d7de9, - 0x95dcfb374995956e, - 0xd88e9fad56d8d847, - 0xfb8b30eb70fbfbcb, - 0xee2371c1cdeeee9f, - 0x7cc791f8bb7c7ced, - 0x6617e3cc71666685, - 0xdda68ea77bdddd53, - 0x17b84b2eaf17175c, - 0x4702468e45474701, - 0x9e84dc211a9e9e42, - 0xca1ec589d4caca0f, - 0x2d75995a582d2db4, - 0xbf9179632ebfbfc6, - 0x07381b0e3f07071c, - 0xad012347acadad8e, - 0x5aea2fb4b05a5a75, - 0x836cb51bef838336, - 0x3385ff66b63333cc, - 0x633ff2c65c636391, - 0x02100a0412020208, - 0xaa39384993aaaa92, - 0x71afa8e2de7171d9, - 0xc80ecf8dc6c8c807, - 0x19c87d32d1191964, - 0x497270923b494939, - 0xd9869aaf5fd9d943, - 0xf2c31df931f2f2ef, - 0xe34b48dba8e3e3ab, - 0x5be22ab6b95b5b71, - 0x8834920dbc88881a, - 0x9aa4c8293e9a9a52, - 0x262dbe4c0b262698, - 0x328dfa64bf3232c8, - 0xb0e94a7d59b0b0fa, - 0xe91b6acff2e9e983, - 0x0f78331e770f0f3c, - 0xd5e6a6b733d5d573, - 0x8074ba1df480803a, - 0xbe997c6127bebec2, - 0xcd26de87ebcdcd13, - 0x34bde468893434d0, - 0x487a75903248483d, - 0xffab24e354ffffdb, - 0x7af78ff48d7a7af5, - 0x90f4ea3d6490907a, - 0x5fc23ebe9d5f5f61, - 0x201da0403d202080, - 0x6867d5d00f6868bd, - 0x1ad07234ca1a1a68, - 0xae192c41b7aeae82, - 0xb4c95e757db4b4ea, - 0x549a19a8ce54544d, - 0x93ece53b7f939376, - 0x220daa442f222288, - 0x6407e9c86364648d, - 0xf1db12ff2af1f1e3, - 0x73bfa2e6cc7373d1, - 0x12905a2482121248, - 0x403a5d807a40401d, - 0x0840281048080820, - 0xc356e89b95c3c32b, - 0xec337bc5dfecec97, - 0xdb9690ab4ddbdb4b, - 0xa1611f5fc0a1a1be, - 0x8d1c8307918d8d0e, - 0x3df5c97ac83d3df4, - 0x97ccf1335b979766, +pub const C5: [u64; 256] = [ + 0x601818d83078c018, + 0x8c23232646af0523, + 0x3fc6c6b891f97ec6, + 0x87e8e8fbcd6f13e8, + 0x268787cb13a14c87, + 0xdab8b8116d62a9b8, + 0x0401010902050801, + 0x214f4f0d9e6e424f, + 0xd836369b6ceead36, + 0xa2a6a6ff510459a6, + 0x6fd2d20cb9bdded2, + 0xf3f5f50ef706fbf5, + 0xf9797996f280ef79, + 0xa16f6f30dece5f6f, + 0x7e91916d3feffc91, + 0x555252f8a407aa52, + 0x9d606047c0fd2760, + 0xcabcbc35657689bc, + 0x569b9b372bcdac9b, + 0x028e8e8a018c048e, + 0xb6a3a3d25b1571a3, + 0x300c0c6c183c600c, + 0xf17b7b84f68aff7b, + 0xd43535806ae1b535, + 0x741d1df53a69e81d, + 0xa7e0e0b3dd4753e0, + 0x7bd7d721b3acf6d7, + 0x2fc2c29c99ed5ec2, + 0xb82e2e435c966d2e, + 0x314b4b29967a624b, + 0xdffefe5de121a3fe, + 0x415757d5ae168257, + 0x541515bd2a41a815, + 0xc17777e8eeb69f77, + 0xdc3737926eeba537, + 0xb3e5e59ed7567be5, + 0x469f9f1323d98c9f, + 0xe7f0f023fd17d3f0, + 0x354a4a20947f6a4a, + 0x4fdada44a9959eda, + 0x7d5858a2b025fa58, + 0x03c9c9cf8fca06c9, + 0xa429297c528d5529, + 0x280a0a5a1422500a, + 0xfeb1b1507f4fe1b1, + 0xbaa0a0c95d1a69a0, + 0xb16b6b14d6da7f6b, + 0x2e8585d917ab5c85, + 0xcebdbd3c677381bd, + 0x695d5d8fba34d25d, + 0x4010109020508010, + 0xf7f4f407f503f3f4, + 0x0bcbcbdd8bc016cb, + 0xf83e3ed37cc6ed3e, + 0x1405052d0a112805, + 0x81676778cee61f67, + 0xb7e4e497d55373e4, + 0x9c2727024ebb2527, + 0x1941417382583241, + 0x168b8ba70b9d2c8b, + 0xa6a7a7f6530151a7, + 0xe97d7db2fa94cf7d, + 0x6e95954937fbdc95, + 0x47d8d856ad9f8ed8, + 0xcbfbfb70eb308bfb, + 0x9feeeecdc17123ee, + 0xed7c7cbbf891c77c, + 0x85666671cce31766, + 0x53dddd7ba78ea6dd, + 0x5c1717af2e4bb817, + 0x014747458e460247, + 0x429e9e1a21dc849e, + 0x0fcacad489c51eca, + 0xb42d2d585a99752d, + 0xc6bfbf2e637991bf, + 0x1c07073f0e1b3807, + 0x8eadadac472301ad, + 0x755a5ab0b42fea5a, + 0x368383ef1bb56c83, + 0xcc3333b666ff8533, + 0x9163635cc6f23f63, + 0x08020212040a1002, + 0x92aaaa93493839aa, + 0xd97171dee2a8af71, + 0x07c8c8c68dcf0ec8, + 0x641919d1327dc819, + 0x3949493b92707249, + 0x43d9d95faf9a86d9, + 0xeff2f231f91dc3f2, + 0xabe3e3a8db484be3, + 0x715b5bb9b62ae25b, + 0x1a8888bc0d923488, + 0x529a9a3e29c8a49a, + 0x9826260b4cbe2d26, + 0xc83232bf64fa8d32, + 0xfab0b0597d4ae9b0, + 0x83e9e9f2cf6a1be9, + 0x3c0f0f771e33780f, + 0x73d5d533b7a6e6d5, + 0x3a8080f41dba7480, + 0xc2bebe27617c99be, + 0x13cdcdeb87de26cd, + 0xd034348968e4bd34, + 0x3d48483290757a48, + 0xdbffff54e324abff, + 0xf57a7a8df48ff77a, + 0x7a9090643deaf490, + 0x615f5f9dbe3ec25f, + 0x8020203d40a01d20, + 0xbd68680fd0d56768, + 0x681a1aca3472d01a, + 0x82aeaeb7412c19ae, + 0xeab4b47d755ec9b4, + 0x4d5454cea8199a54, + 0x7693937f3be5ec93, + 0x8822222f44aa0d22, + 0x8d646463c8e90764, + 0xe3f1f12aff12dbf1, + 0xd17373cce6a2bf73, + 0x48121282245a9012, + 0x1d40407a805d3a40, + 0x2008084810284008, + 0x2bc3c3959be856c3, + 0x97ececdfc57b33ec, + 0x4bdbdb4dab9096db, + 0xbea1a1c05f1f61a1, + 0x0e8d8d9107831c8d, + 0xf43d3dc87ac9f53d, + 0x6697975b33f1cc97, 0x0000000000000000, - 0xcf36d483f9cfcf1b, - 0x2b4587566e2b2bac, - 0x7697b3ece17676c5, - 0x8264b019e6828232, - 0xd6fea9b128d6d67f, - 0x1bd87736c31b1b6c, - 0xb5c15b7774b5b5ee, - 0xaf112943beafaf86, - 0x6a77dfd41d6a6ab5, - 0x50ba0da0ea50505d, - 0x45124c8a57454509, - 0xf3cb18fb38f3f3eb, - 0x309df060ad3030c0, - 0xef2b74c3c4efef9b, - 0x3fe5c37eda3f3ffc, - 0x55921caac7555549, - 0xa2791059dba2a2b2, - 0xea0365c9e9eaea8f, - 0x650fecca6a656589, - 0xbab9686903babad2, - 0x2f65935e4a2f2fbc, - 0xc04ee79d8ec0c027, - 0xdebe81a160dede5f, - 0x1ce06c38fc1c1c70, - 0xfdbb2ee746fdfdd3, - 0x4d52649a1f4d4d29, - 0x92e4e03976929272, - 0x758fbceafa7575c9, - 0x06301e0c36060618, - 0x8a249809ae8a8a12, - 0xb2f940794bb2b2f2, - 0xe66359d185e6e6bf, - 0x0e70361c7e0e0e38, - 0x1ff8633ee71f1f7c, - 0x6237f7c455626295, - 0xd4eea3b53ad4d477, - 0xa829324d81a8a89a, - 0x96c4f43152969662, - 0xf99b3aef62f9f9c3, - 0xc566f697a3c5c533, - 0x2535b14a10252594, - 0x59f220b2ab595979, - 0x8454ae15d084842a, - 0x72b7a7e4c57272d5, - 0x39d5dd72ec3939e4, - 0x4c5a6198164c4c2d, - 0x5eca3bbc945e5e65, - 0x78e785f09f7878fd, - 0x38ddd870e53838e0, - 0x8c148605988c8c0a, - 0xd1c6b2bf17d1d163, - 0xa5410b57e4a5a5ae, - 0xe2434dd9a1e2e2af, - 0x612ff8c24e616199, - 0xb3f1457b42b3b3f6, - 0x2115a54234212184, - 0x9c94d625089c9c4a, - 0x1ef0663cee1e1e78, - 0x4322528661434311, - 0xc776fc93b1c7c73b, - 0xfcb32be54ffcfcd7, - 0x0420140824040410, - 0x51b208a2e3515159, - 0x99bcc72f2599995e, - 0x6d4fc4da226d6da9, - 0x0d68391a650d0d34, - 0xfa8335e979fafacf, - 0xdfb684a369dfdf5b, - 0x7ed79bfca97e7ee5, - 0x243db44819242490, - 0x3bc5d776fe3b3bec, - 0xab313d4b9aabab96, - 0xce3ed181f0cece1f, - 0x1188552299111144, - 0x8f0c8903838f8f06, - 0x4e4a6b9c044e4e25, - 0xb7d1517366b7b7e6, - 0xeb0b60cbe0ebeb8b, - 0x3cfdcc78c13c3cf0, - 0x817cbf1ffd81813e, - 0x94d4fe354094946a, - 0xf7eb0cf31cf7f7fb, - 0xb9a1676f18b9b9de, - 0x13985f268b13134c, - 0x2c7d9c58512c2cb0, - 0xd3d6b8bb05d3d36b, - 0xe76b5cd38ce7e7bb, - 0x6e57cbdc396e6ea5, - 0xc46ef395aac4c437, - 0x03180f061b03030c, - 0x568a13acdc565645, - 0x441a49885e44440d, - 0x7fdf9efea07f7fe1, - 0xa921374f88a9a99e, - 0x2a4d8254672a2aa8, - 0xbbb16d6b0abbbbd6, - 0xc146e29f87c1c123, - 0x53a202a6f1535351, - 0xdcae8ba572dcdc57, - 0x0b582716530b0b2c, - 0x9d9cd327019d9d4e, - 0x6c47c1d82b6c6cad, - 0x3195f562a43131c4, - 0x7487b9e8f37474cd, - 0xf6e309f115f6f6ff, - 0x460a438c4c464605, - 0xac092645a5acac8a, - 0x893c970fb589891e, - 0x14a04428b4141450, - 0xe15b42dfbae1e1a3, - 0x16b04e2ca6161658, - 0x3acdd274f73a3ae8, - 0x696fd0d2066969b9, - 0x09482d1241090924, - 0x70a7ade0d77070dd, - 0xb6d954716fb6b6e2, - 0xd0ceb7bd1ed0d067, - 0xed3b7ec7d6eded93, - 0xcc2edb85e2cccc17, - 0x422a578468424215, - 0x98b4c22d2c98985a, - 0xa4490e55eda4a4aa, - 0x285d8850752828a0, - 0x5cda31b8865c5c6d, - 0xf8933fed6bf8f8c7, - 0x8644a411c2868622, + 0x1bcfcff983d436cf, + 0xac2b2b6e5687452b, + 0xc57676e1ecb39776, + 0x328282e619b06482, + 0x7fd6d628b1a9fed6, + 0x6c1b1bc33677d81b, + 0xeeb5b574775bc1b5, + 0x86afafbe432911af, + 0xb56a6a1dd4df776a, + 0x5d5050eaa00dba50, + 0x094545578a4c1245, + 0xebf3f338fb18cbf3, + 0xc03030ad60f09d30, + 0x9befefc4c3742bef, + 0xfc3f3fda7ec3e53f, + 0x495555c7aa1c9255, + 0xb2a2a2db591079a2, + 0x8feaeae9c96503ea, + 0x8965656acaec0f65, + 0xd2baba036968b9ba, + 0xbc2f2f4a5e93652f, + 0x27c0c08e9de74ec0, + 0x5fdede60a181bede, + 0x701c1cfc386ce01c, + 0xd3fdfd46e72ebbfd, + 0x294d4d1f9a64524d, + 0x7292927639e0e492, + 0xc97575faeabc8f75, + 0x180606360c1e3006, + 0x128a8aae0998248a, + 0xf2b2b24b7940f9b2, + 0xbfe6e685d15963e6, + 0x380e0e7e1c36700e, + 0x7c1f1fe73e63f81f, + 0x95626255c4f73762, + 0x77d4d43ab5a3eed4, + 0x9aa8a8814d3229a8, + 0x6296965231f4c496, + 0xc3f9f962ef3a9bf9, + 0x33c5c5a397f666c5, + 0x942525104ab13525, + 0x795959abb220f259, + 0x2a8484d015ae5484, + 0xd57272c5e4a7b772, + 0xe43939ec72ddd539, + 0x2d4c4c1698615a4c, + 0x655e5e94bc3bca5e, + 0xfd78789ff085e778, + 0xe03838e570d8dd38, + 0x0a8c8c980586148c, + 0x63d1d117bfb2c6d1, + 0xaea5a5e4570b41a5, + 0xafe2e2a1d94d43e2, + 0x9961614ec2f82f61, + 0xf6b3b3427b45f1b3, + 0x8421213442a51521, + 0x4a9c9c0825d6949c, + 0x781e1eee3c66f01e, + 0x1143436186522243, + 0x3bc7c7b193fc76c7, + 0xd7fcfc4fe52bb3fc, + 0x1004042408142004, + 0x595151e3a208b251, + 0x5e9999252fc7bc99, + 0xa96d6d22dac44f6d, + 0x340d0d651a39680d, + 0xcffafa79e93583fa, + 0x5bdfdf69a384b6df, + 0xe57e7ea9fc9bd77e, + 0x9024241948b43d24, + 0xec3b3bfe76d7c53b, + 0x96abab9a4b3d31ab, + 0x1fcecef081d13ece, + 0x4411119922558811, + 0x068f8f8303890c8f, + 0x254e4e049c6b4a4e, + 0xe6b7b7667351d1b7, + 0x8bebebe0cb600beb, + 0xf03c3cc178ccfd3c, + 0x3e8181fd1fbf7c81, + 0x6a94944035fed494, + 0xfbf7f71cf30cebf7, + 0xdeb9b9186f67a1b9, + 0x4c13138b265f9813, + 0xb02c2c51589c7d2c, + 0x6bd3d305bbb8d6d3, + 0xbbe7e78cd35c6be7, + 0xa56e6e39dccb576e, + 0x37c4c4aa95f36ec4, + 0x0c03031b060f1803, + 0x455656dcac138a56, + 0x0d44445e88491a44, + 0xe17f7fa0fe9edf7f, + 0x9ea9a9884f3721a9, + 0xa82a2a6754824d2a, + 0xd6bbbb0a6b6db1bb, + 0x23c1c1879fe246c1, + 0x515353f1a602a253, + 0x57dcdc72a58baedc, + 0x2c0b0b531627580b, + 0x4e9d9d0127d39c9d, + 0xad6c6c2bd8c1476c, + 0xc43131a462f59531, + 0xcd7474f3e8b98774, + 0xfff6f615f109e3f6, + 0x0546464c8c430a46, + 0x8aacaca5452609ac, + 0x1e8989b50f973c89, + 0x501414b42844a014, + 0xa3e1e1badf425be1, + 0x581616a62c4eb016, + 0xe83a3af774d2cd3a, + 0xb9696906d2d06f69, + 0x24090941122d4809, + 0xdd7070d7e0ada770, + 0xe2b6b66f7154d9b6, + 0x67d0d01ebdb7ced0, + 0x93ededd6c77e3bed, + 0x17cccce285db2ecc, + 0x1542426884572a42, + 0x5a98982c2dc2b498, + 0xaaa4a4ed550e49a4, + 0xa028287550885d28, + 0x6d5c5c86b831da5c, + 0xc7f8f86bed3f93f8, + 0x228686c211a44486, ]; -pub static C6: [u64; 256] = [ - 0x6018c07830d81818, - 0x8c2305af46262323, - 0x3fc67ef991b8c6c6, - 0x87e8136fcdfbe8e8, - 0x26874ca113cb8787, - 0xdab8a9626d11b8b8, - 0x0401080502090101, - 0x214f426e9e0d4f4f, - 0xd836adee6c9b3636, - 0xa2a6590451ffa6a6, - 0x6fd2debdb90cd2d2, - 0xf3f5fb06f70ef5f5, - 0xf979ef80f2967979, - 0xa16f5fcede306f6f, - 0x7e91fcef3f6d9191, - 0x5552aa07a4f85252, - 0x9d6027fdc0476060, - 0xcabc89766535bcbc, - 0x569baccd2b379b9b, - 0x028e048c018a8e8e, - 0xb6a371155bd2a3a3, - 0x300c603c186c0c0c, - 0xf17bff8af6847b7b, - 0xd435b5e16a803535, - 0x741de8693af51d1d, - 0xa7e05347ddb3e0e0, - 0x7bd7f6acb321d7d7, - 0x2fc25eed999cc2c2, - 0xb82e6d965c432e2e, - 0x314b627a96294b4b, - 0xdffea321e15dfefe, - 0x41578216aed55757, - 0x5415a8412abd1515, - 0xc1779fb6eee87777, - 0xdc37a5eb6e923737, - 0xb3e57b56d79ee5e5, - 0x469f8cd923139f9f, - 0xe7f0d317fd23f0f0, - 0x354a6a7f94204a4a, - 0x4fda9e95a944dada, - 0x7d58fa25b0a25858, - 0x03c906ca8fcfc9c9, - 0xa429558d527c2929, - 0x280a5022145a0a0a, - 0xfeb1e14f7f50b1b1, - 0xbaa0691a5dc9a0a0, - 0xb16b7fdad6146b6b, - 0x2e855cab17d98585, - 0xcebd8173673cbdbd, - 0x695dd234ba8f5d5d, - 0x4010805020901010, - 0xf7f4f303f507f4f4, - 0x0bcb16c08bddcbcb, - 0xf83eedc67cd33e3e, - 0x140528110a2d0505, - 0x81671fe6ce786767, - 0xb7e47353d597e4e4, - 0x9c2725bb4e022727, - 0x1941325882734141, - 0x168b2c9d0ba78b8b, - 0xa6a7510153f6a7a7, - 0xe97dcf94fab27d7d, - 0x6e95dcfb37499595, - 0x47d88e9fad56d8d8, - 0xcbfb8b30eb70fbfb, - 0x9fee2371c1cdeeee, - 0xed7cc791f8bb7c7c, - 0x856617e3cc716666, - 0x53dda68ea77bdddd, - 0x5c17b84b2eaf1717, - 0x014702468e454747, - 0x429e84dc211a9e9e, - 0x0fca1ec589d4caca, - 0xb42d75995a582d2d, - 0xc6bf9179632ebfbf, - 0x1c07381b0e3f0707, - 0x8ead012347acadad, - 0x755aea2fb4b05a5a, - 0x36836cb51bef8383, - 0xcc3385ff66b63333, - 0x91633ff2c65c6363, - 0x0802100a04120202, - 0x92aa39384993aaaa, - 0xd971afa8e2de7171, - 0x07c80ecf8dc6c8c8, - 0x6419c87d32d11919, - 0x39497270923b4949, - 0x43d9869aaf5fd9d9, - 0xeff2c31df931f2f2, - 0xabe34b48dba8e3e3, - 0x715be22ab6b95b5b, - 0x1a8834920dbc8888, - 0x529aa4c8293e9a9a, - 0x98262dbe4c0b2626, - 0xc8328dfa64bf3232, - 0xfab0e94a7d59b0b0, - 0x83e91b6acff2e9e9, - 0x3c0f78331e770f0f, - 0x73d5e6a6b733d5d5, - 0x3a8074ba1df48080, - 0xc2be997c6127bebe, - 0x13cd26de87ebcdcd, - 0xd034bde468893434, - 0x3d487a7590324848, - 0xdbffab24e354ffff, - 0xf57af78ff48d7a7a, - 0x7a90f4ea3d649090, - 0x615fc23ebe9d5f5f, - 0x80201da0403d2020, - 0xbd6867d5d00f6868, - 0x681ad07234ca1a1a, - 0x82ae192c41b7aeae, - 0xeab4c95e757db4b4, - 0x4d549a19a8ce5454, - 0x7693ece53b7f9393, - 0x88220daa442f2222, - 0x8d6407e9c8636464, - 0xe3f1db12ff2af1f1, - 0xd173bfa2e6cc7373, - 0x4812905a24821212, - 0x1d403a5d807a4040, - 0x2008402810480808, - 0x2bc356e89b95c3c3, - 0x97ec337bc5dfecec, - 0x4bdb9690ab4ddbdb, - 0xbea1611f5fc0a1a1, - 0x0e8d1c8307918d8d, - 0xf43df5c97ac83d3d, - 0x6697ccf1335b9797, +pub const C6: [u64; 256] = [ + 0x1818d83078c01860, + 0x23232646af05238c, + 0xc6c6b891f97ec63f, + 0xe8e8fbcd6f13e887, + 0x8787cb13a14c8726, + 0xb8b8116d62a9b8da, + 0x0101090205080104, + 0x4f4f0d9e6e424f21, + 0x36369b6ceead36d8, + 0xa6a6ff510459a6a2, + 0xd2d20cb9bdded26f, + 0xf5f50ef706fbf5f3, + 0x797996f280ef79f9, + 0x6f6f30dece5f6fa1, + 0x91916d3feffc917e, + 0x5252f8a407aa5255, + 0x606047c0fd27609d, + 0xbcbc35657689bcca, + 0x9b9b372bcdac9b56, + 0x8e8e8a018c048e02, + 0xa3a3d25b1571a3b6, + 0x0c0c6c183c600c30, + 0x7b7b84f68aff7bf1, + 0x3535806ae1b535d4, + 0x1d1df53a69e81d74, + 0xe0e0b3dd4753e0a7, + 0xd7d721b3acf6d77b, + 0xc2c29c99ed5ec22f, + 0x2e2e435c966d2eb8, + 0x4b4b29967a624b31, + 0xfefe5de121a3fedf, + 0x5757d5ae16825741, + 0x1515bd2a41a81554, + 0x7777e8eeb69f77c1, + 0x3737926eeba537dc, + 0xe5e59ed7567be5b3, + 0x9f9f1323d98c9f46, + 0xf0f023fd17d3f0e7, + 0x4a4a20947f6a4a35, + 0xdada44a9959eda4f, + 0x5858a2b025fa587d, + 0xc9c9cf8fca06c903, + 0x29297c528d5529a4, + 0x0a0a5a1422500a28, + 0xb1b1507f4fe1b1fe, + 0xa0a0c95d1a69a0ba, + 0x6b6b14d6da7f6bb1, + 0x8585d917ab5c852e, + 0xbdbd3c677381bdce, + 0x5d5d8fba34d25d69, + 0x1010902050801040, + 0xf4f407f503f3f4f7, + 0xcbcbdd8bc016cb0b, + 0x3e3ed37cc6ed3ef8, + 0x05052d0a11280514, + 0x676778cee61f6781, + 0xe4e497d55373e4b7, + 0x2727024ebb25279c, + 0x4141738258324119, + 0x8b8ba70b9d2c8b16, + 0xa7a7f6530151a7a6, + 0x7d7db2fa94cf7de9, + 0x95954937fbdc956e, + 0xd8d856ad9f8ed847, + 0xfbfb70eb308bfbcb, + 0xeeeecdc17123ee9f, + 0x7c7cbbf891c77ced, + 0x666671cce3176685, + 0xdddd7ba78ea6dd53, + 0x1717af2e4bb8175c, + 0x4747458e46024701, + 0x9e9e1a21dc849e42, + 0xcacad489c51eca0f, + 0x2d2d585a99752db4, + 0xbfbf2e637991bfc6, + 0x07073f0e1b38071c, + 0xadadac472301ad8e, + 0x5a5ab0b42fea5a75, + 0x8383ef1bb56c8336, + 0x3333b666ff8533cc, + 0x63635cc6f23f6391, + 0x020212040a100208, + 0xaaaa93493839aa92, + 0x7171dee2a8af71d9, + 0xc8c8c68dcf0ec807, + 0x1919d1327dc81964, + 0x49493b9270724939, + 0xd9d95faf9a86d943, + 0xf2f231f91dc3f2ef, + 0xe3e3a8db484be3ab, + 0x5b5bb9b62ae25b71, + 0x8888bc0d9234881a, + 0x9a9a3e29c8a49a52, + 0x26260b4cbe2d2698, + 0x3232bf64fa8d32c8, + 0xb0b0597d4ae9b0fa, + 0xe9e9f2cf6a1be983, + 0x0f0f771e33780f3c, + 0xd5d533b7a6e6d573, + 0x8080f41dba74803a, + 0xbebe27617c99bec2, + 0xcdcdeb87de26cd13, + 0x34348968e4bd34d0, + 0x48483290757a483d, + 0xffff54e324abffdb, + 0x7a7a8df48ff77af5, + 0x9090643deaf4907a, + 0x5f5f9dbe3ec25f61, + 0x20203d40a01d2080, + 0x68680fd0d56768bd, + 0x1a1aca3472d01a68, + 0xaeaeb7412c19ae82, + 0xb4b47d755ec9b4ea, + 0x5454cea8199a544d, + 0x93937f3be5ec9376, + 0x22222f44aa0d2288, + 0x646463c8e907648d, + 0xf1f12aff12dbf1e3, + 0x7373cce6a2bf73d1, + 0x121282245a901248, + 0x40407a805d3a401d, + 0x0808481028400820, + 0xc3c3959be856c32b, + 0xececdfc57b33ec97, + 0xdbdb4dab9096db4b, + 0xa1a1c05f1f61a1be, + 0x8d8d9107831c8d0e, + 0x3d3dc87ac9f53df4, + 0x97975b33f1cc9766, 0x0000000000000000, - 0x1bcf36d483f9cfcf, - 0xac2b4587566e2b2b, - 0xc57697b3ece17676, - 0x328264b019e68282, - 0x7fd6fea9b128d6d6, - 0x6c1bd87736c31b1b, - 0xeeb5c15b7774b5b5, - 0x86af112943beafaf, - 0xb56a77dfd41d6a6a, - 0x5d50ba0da0ea5050, - 0x0945124c8a574545, - 0xebf3cb18fb38f3f3, - 0xc0309df060ad3030, - 0x9bef2b74c3c4efef, - 0xfc3fe5c37eda3f3f, - 0x4955921caac75555, - 0xb2a2791059dba2a2, - 0x8fea0365c9e9eaea, - 0x89650fecca6a6565, - 0xd2bab9686903baba, - 0xbc2f65935e4a2f2f, - 0x27c04ee79d8ec0c0, - 0x5fdebe81a160dede, - 0x701ce06c38fc1c1c, - 0xd3fdbb2ee746fdfd, - 0x294d52649a1f4d4d, - 0x7292e4e039769292, - 0xc9758fbceafa7575, - 0x1806301e0c360606, - 0x128a249809ae8a8a, - 0xf2b2f940794bb2b2, - 0xbfe66359d185e6e6, - 0x380e70361c7e0e0e, - 0x7c1ff8633ee71f1f, - 0x956237f7c4556262, - 0x77d4eea3b53ad4d4, - 0x9aa829324d81a8a8, - 0x6296c4f431529696, - 0xc3f99b3aef62f9f9, - 0x33c566f697a3c5c5, - 0x942535b14a102525, - 0x7959f220b2ab5959, - 0x2a8454ae15d08484, - 0xd572b7a7e4c57272, - 0xe439d5dd72ec3939, - 0x2d4c5a6198164c4c, - 0x655eca3bbc945e5e, - 0xfd78e785f09f7878, - 0xe038ddd870e53838, - 0x0a8c148605988c8c, - 0x63d1c6b2bf17d1d1, - 0xaea5410b57e4a5a5, - 0xafe2434dd9a1e2e2, - 0x99612ff8c24e6161, - 0xf6b3f1457b42b3b3, - 0x842115a542342121, - 0x4a9c94d625089c9c, - 0x781ef0663cee1e1e, - 0x1143225286614343, - 0x3bc776fc93b1c7c7, - 0xd7fcb32be54ffcfc, - 0x1004201408240404, - 0x5951b208a2e35151, - 0x5e99bcc72f259999, - 0xa96d4fc4da226d6d, - 0x340d68391a650d0d, - 0xcffa8335e979fafa, - 0x5bdfb684a369dfdf, - 0xe57ed79bfca97e7e, - 0x90243db448192424, - 0xec3bc5d776fe3b3b, - 0x96ab313d4b9aabab, - 0x1fce3ed181f0cece, - 0x4411885522991111, - 0x068f0c8903838f8f, - 0x254e4a6b9c044e4e, - 0xe6b7d1517366b7b7, - 0x8beb0b60cbe0ebeb, - 0xf03cfdcc78c13c3c, - 0x3e817cbf1ffd8181, - 0x6a94d4fe35409494, - 0xfbf7eb0cf31cf7f7, - 0xdeb9a1676f18b9b9, - 0x4c13985f268b1313, - 0xb02c7d9c58512c2c, - 0x6bd3d6b8bb05d3d3, - 0xbbe76b5cd38ce7e7, - 0xa56e57cbdc396e6e, - 0x37c46ef395aac4c4, - 0x0c03180f061b0303, - 0x45568a13acdc5656, - 0x0d441a49885e4444, - 0xe17fdf9efea07f7f, - 0x9ea921374f88a9a9, - 0xa82a4d8254672a2a, - 0xd6bbb16d6b0abbbb, - 0x23c146e29f87c1c1, - 0x5153a202a6f15353, - 0x57dcae8ba572dcdc, - 0x2c0b582716530b0b, - 0x4e9d9cd327019d9d, - 0xad6c47c1d82b6c6c, - 0xc43195f562a43131, - 0xcd7487b9e8f37474, - 0xfff6e309f115f6f6, - 0x05460a438c4c4646, - 0x8aac092645a5acac, - 0x1e893c970fb58989, - 0x5014a04428b41414, - 0xa3e15b42dfbae1e1, - 0x5816b04e2ca61616, - 0xe83acdd274f73a3a, - 0xb9696fd0d2066969, - 0x2409482d12410909, - 0xdd70a7ade0d77070, - 0xe2b6d954716fb6b6, - 0x67d0ceb7bd1ed0d0, - 0x93ed3b7ec7d6eded, - 0x17cc2edb85e2cccc, - 0x15422a5784684242, - 0x5a98b4c22d2c9898, - 0xaaa4490e55eda4a4, - 0xa0285d8850752828, - 0x6d5cda31b8865c5c, - 0xc7f8933fed6bf8f8, - 0x228644a411c28686, + 0xcfcff983d436cf1b, + 0x2b2b6e5687452bac, + 0x7676e1ecb39776c5, + 0x8282e619b0648232, + 0xd6d628b1a9fed67f, + 0x1b1bc33677d81b6c, + 0xb5b574775bc1b5ee, + 0xafafbe432911af86, + 0x6a6a1dd4df776ab5, + 0x5050eaa00dba505d, + 0x4545578a4c124509, + 0xf3f338fb18cbf3eb, + 0x3030ad60f09d30c0, + 0xefefc4c3742bef9b, + 0x3f3fda7ec3e53ffc, + 0x5555c7aa1c925549, + 0xa2a2db591079a2b2, + 0xeaeae9c96503ea8f, + 0x65656acaec0f6589, + 0xbaba036968b9bad2, + 0x2f2f4a5e93652fbc, + 0xc0c08e9de74ec027, + 0xdede60a181bede5f, + 0x1c1cfc386ce01c70, + 0xfdfd46e72ebbfdd3, + 0x4d4d1f9a64524d29, + 0x92927639e0e49272, + 0x7575faeabc8f75c9, + 0x0606360c1e300618, + 0x8a8aae0998248a12, + 0xb2b24b7940f9b2f2, + 0xe6e685d15963e6bf, + 0x0e0e7e1c36700e38, + 0x1f1fe73e63f81f7c, + 0x626255c4f7376295, + 0xd4d43ab5a3eed477, + 0xa8a8814d3229a89a, + 0x96965231f4c49662, + 0xf9f962ef3a9bf9c3, + 0xc5c5a397f666c533, + 0x2525104ab1352594, + 0x5959abb220f25979, + 0x8484d015ae54842a, + 0x7272c5e4a7b772d5, + 0x3939ec72ddd539e4, + 0x4c4c1698615a4c2d, + 0x5e5e94bc3bca5e65, + 0x78789ff085e778fd, + 0x3838e570d8dd38e0, + 0x8c8c980586148c0a, + 0xd1d117bfb2c6d163, + 0xa5a5e4570b41a5ae, + 0xe2e2a1d94d43e2af, + 0x61614ec2f82f6199, + 0xb3b3427b45f1b3f6, + 0x21213442a5152184, + 0x9c9c0825d6949c4a, + 0x1e1eee3c66f01e78, + 0x4343618652224311, + 0xc7c7b193fc76c73b, + 0xfcfc4fe52bb3fcd7, + 0x0404240814200410, + 0x5151e3a208b25159, + 0x9999252fc7bc995e, + 0x6d6d22dac44f6da9, + 0x0d0d651a39680d34, + 0xfafa79e93583facf, + 0xdfdf69a384b6df5b, + 0x7e7ea9fc9bd77ee5, + 0x24241948b43d2490, + 0x3b3bfe76d7c53bec, + 0xabab9a4b3d31ab96, + 0xcecef081d13ece1f, + 0x1111992255881144, + 0x8f8f8303890c8f06, + 0x4e4e049c6b4a4e25, + 0xb7b7667351d1b7e6, + 0xebebe0cb600beb8b, + 0x3c3cc178ccfd3cf0, + 0x8181fd1fbf7c813e, + 0x94944035fed4946a, + 0xf7f71cf30cebf7fb, + 0xb9b9186f67a1b9de, + 0x13138b265f98134c, + 0x2c2c51589c7d2cb0, + 0xd3d305bbb8d6d36b, + 0xe7e78cd35c6be7bb, + 0x6e6e39dccb576ea5, + 0xc4c4aa95f36ec437, + 0x03031b060f18030c, + 0x5656dcac138a5645, + 0x44445e88491a440d, + 0x7f7fa0fe9edf7fe1, + 0xa9a9884f3721a99e, + 0x2a2a6754824d2aa8, + 0xbbbb0a6b6db1bbd6, + 0xc1c1879fe246c123, + 0x5353f1a602a25351, + 0xdcdc72a58baedc57, + 0x0b0b531627580b2c, + 0x9d9d0127d39c9d4e, + 0x6c6c2bd8c1476cad, + 0x3131a462f59531c4, + 0x7474f3e8b98774cd, + 0xf6f615f109e3f6ff, + 0x46464c8c430a4605, + 0xacaca5452609ac8a, + 0x8989b50f973c891e, + 0x1414b42844a01450, + 0xe1e1badf425be1a3, + 0x1616a62c4eb01658, + 0x3a3af774d2cd3ae8, + 0x696906d2d06f69b9, + 0x090941122d480924, + 0x7070d7e0ada770dd, + 0xb6b66f7154d9b6e2, + 0xd0d01ebdb7ced067, + 0xededd6c77e3bed93, + 0xcccce285db2ecc17, + 0x42426884572a4215, + 0x98982c2dc2b4985a, + 0xa4a4ed550e49a4aa, + 0x28287550885d28a0, + 0x5c5c86b831da5c6d, + 0xf8f86bed3f93f8c7, + 0x8686c211a4448622, ]; -pub static C7: [u64; 256] = [ - 0x186018c07830d818, - 0x238c2305af462623, - 0xc63fc67ef991b8c6, - 0xe887e8136fcdfbe8, - 0x8726874ca113cb87, - 0xb8dab8a9626d11b8, - 0x0104010805020901, - 0x4f214f426e9e0d4f, - 0x36d836adee6c9b36, - 0xa6a2a6590451ffa6, - 0xd26fd2debdb90cd2, - 0xf5f3f5fb06f70ef5, - 0x79f979ef80f29679, - 0x6fa16f5fcede306f, - 0x917e91fcef3f6d91, - 0x525552aa07a4f852, - 0x609d6027fdc04760, - 0xbccabc89766535bc, - 0x9b569baccd2b379b, - 0x8e028e048c018a8e, - 0xa3b6a371155bd2a3, - 0x0c300c603c186c0c, - 0x7bf17bff8af6847b, - 0x35d435b5e16a8035, - 0x1d741de8693af51d, - 0xe0a7e05347ddb3e0, - 0xd77bd7f6acb321d7, - 0xc22fc25eed999cc2, - 0x2eb82e6d965c432e, - 0x4b314b627a96294b, - 0xfedffea321e15dfe, - 0x5741578216aed557, - 0x155415a8412abd15, - 0x77c1779fb6eee877, - 0x37dc37a5eb6e9237, - 0xe5b3e57b56d79ee5, - 0x9f469f8cd923139f, - 0xf0e7f0d317fd23f0, - 0x4a354a6a7f94204a, - 0xda4fda9e95a944da, - 0x587d58fa25b0a258, - 0xc903c906ca8fcfc9, - 0x29a429558d527c29, - 0x0a280a5022145a0a, - 0xb1feb1e14f7f50b1, - 0xa0baa0691a5dc9a0, - 0x6bb16b7fdad6146b, - 0x852e855cab17d985, - 0xbdcebd8173673cbd, - 0x5d695dd234ba8f5d, - 0x1040108050209010, - 0xf4f7f4f303f507f4, - 0xcb0bcb16c08bddcb, - 0x3ef83eedc67cd33e, - 0x05140528110a2d05, - 0x6781671fe6ce7867, - 0xe4b7e47353d597e4, - 0x279c2725bb4e0227, - 0x4119413258827341, - 0x8b168b2c9d0ba78b, - 0xa7a6a7510153f6a7, - 0x7de97dcf94fab27d, - 0x956e95dcfb374995, - 0xd847d88e9fad56d8, - 0xfbcbfb8b30eb70fb, - 0xee9fee2371c1cdee, - 0x7ced7cc791f8bb7c, - 0x66856617e3cc7166, - 0xdd53dda68ea77bdd, - 0x175c17b84b2eaf17, - 0x47014702468e4547, - 0x9e429e84dc211a9e, - 0xca0fca1ec589d4ca, - 0x2db42d75995a582d, - 0xbfc6bf9179632ebf, - 0x071c07381b0e3f07, - 0xad8ead012347acad, - 0x5a755aea2fb4b05a, - 0x8336836cb51bef83, - 0x33cc3385ff66b633, - 0x6391633ff2c65c63, - 0x020802100a041202, - 0xaa92aa39384993aa, - 0x71d971afa8e2de71, - 0xc807c80ecf8dc6c8, - 0x196419c87d32d119, - 0x4939497270923b49, - 0xd943d9869aaf5fd9, - 0xf2eff2c31df931f2, - 0xe3abe34b48dba8e3, - 0x5b715be22ab6b95b, - 0x881a8834920dbc88, - 0x9a529aa4c8293e9a, - 0x2698262dbe4c0b26, - 0x32c8328dfa64bf32, - 0xb0fab0e94a7d59b0, - 0xe983e91b6acff2e9, - 0x0f3c0f78331e770f, - 0xd573d5e6a6b733d5, - 0x803a8074ba1df480, - 0xbec2be997c6127be, - 0xcd13cd26de87ebcd, - 0x34d034bde4688934, - 0x483d487a75903248, - 0xffdbffab24e354ff, - 0x7af57af78ff48d7a, - 0x907a90f4ea3d6490, - 0x5f615fc23ebe9d5f, - 0x2080201da0403d20, - 0x68bd6867d5d00f68, - 0x1a681ad07234ca1a, - 0xae82ae192c41b7ae, - 0xb4eab4c95e757db4, - 0x544d549a19a8ce54, - 0x937693ece53b7f93, - 0x2288220daa442f22, - 0x648d6407e9c86364, - 0xf1e3f1db12ff2af1, - 0x73d173bfa2e6cc73, - 0x124812905a248212, - 0x401d403a5d807a40, - 0x0820084028104808, - 0xc32bc356e89b95c3, - 0xec97ec337bc5dfec, - 0xdb4bdb9690ab4ddb, - 0xa1bea1611f5fc0a1, - 0x8d0e8d1c8307918d, - 0x3df43df5c97ac83d, - 0x976697ccf1335b97, +pub const C7: [u64; 256] = [ + 0x18d83078c0186018, + 0x232646af05238c23, + 0xc6b891f97ec63fc6, + 0xe8fbcd6f13e887e8, + 0x87cb13a14c872687, + 0xb8116d62a9b8dab8, + 0x0109020508010401, + 0x4f0d9e6e424f214f, + 0x369b6ceead36d836, + 0xa6ff510459a6a2a6, + 0xd20cb9bdded26fd2, + 0xf50ef706fbf5f3f5, + 0x7996f280ef79f979, + 0x6f30dece5f6fa16f, + 0x916d3feffc917e91, + 0x52f8a407aa525552, + 0x6047c0fd27609d60, + 0xbc35657689bccabc, + 0x9b372bcdac9b569b, + 0x8e8a018c048e028e, + 0xa3d25b1571a3b6a3, + 0x0c6c183c600c300c, + 0x7b84f68aff7bf17b, + 0x35806ae1b535d435, + 0x1df53a69e81d741d, + 0xe0b3dd4753e0a7e0, + 0xd721b3acf6d77bd7, + 0xc29c99ed5ec22fc2, + 0x2e435c966d2eb82e, + 0x4b29967a624b314b, + 0xfe5de121a3fedffe, + 0x57d5ae1682574157, + 0x15bd2a41a8155415, + 0x77e8eeb69f77c177, + 0x37926eeba537dc37, + 0xe59ed7567be5b3e5, + 0x9f1323d98c9f469f, + 0xf023fd17d3f0e7f0, + 0x4a20947f6a4a354a, + 0xda44a9959eda4fda, + 0x58a2b025fa587d58, + 0xc9cf8fca06c903c9, + 0x297c528d5529a429, + 0x0a5a1422500a280a, + 0xb1507f4fe1b1feb1, + 0xa0c95d1a69a0baa0, + 0x6b14d6da7f6bb16b, + 0x85d917ab5c852e85, + 0xbd3c677381bdcebd, + 0x5d8fba34d25d695d, + 0x1090205080104010, + 0xf407f503f3f4f7f4, + 0xcbdd8bc016cb0bcb, + 0x3ed37cc6ed3ef83e, + 0x052d0a1128051405, + 0x6778cee61f678167, + 0xe497d55373e4b7e4, + 0x27024ebb25279c27, + 0x4173825832411941, + 0x8ba70b9d2c8b168b, + 0xa7f6530151a7a6a7, + 0x7db2fa94cf7de97d, + 0x954937fbdc956e95, + 0xd856ad9f8ed847d8, + 0xfb70eb308bfbcbfb, + 0xeecdc17123ee9fee, + 0x7cbbf891c77ced7c, + 0x6671cce317668566, + 0xdd7ba78ea6dd53dd, + 0x17af2e4bb8175c17, + 0x47458e4602470147, + 0x9e1a21dc849e429e, + 0xcad489c51eca0fca, + 0x2d585a99752db42d, + 0xbf2e637991bfc6bf, + 0x073f0e1b38071c07, + 0xadac472301ad8ead, + 0x5ab0b42fea5a755a, + 0x83ef1bb56c833683, + 0x33b666ff8533cc33, + 0x635cc6f23f639163, + 0x0212040a10020802, + 0xaa93493839aa92aa, + 0x71dee2a8af71d971, + 0xc8c68dcf0ec807c8, + 0x19d1327dc8196419, + 0x493b927072493949, + 0xd95faf9a86d943d9, + 0xf231f91dc3f2eff2, + 0xe3a8db484be3abe3, + 0x5bb9b62ae25b715b, + 0x88bc0d9234881a88, + 0x9a3e29c8a49a529a, + 0x260b4cbe2d269826, + 0x32bf64fa8d32c832, + 0xb0597d4ae9b0fab0, + 0xe9f2cf6a1be983e9, + 0x0f771e33780f3c0f, + 0xd533b7a6e6d573d5, + 0x80f41dba74803a80, + 0xbe27617c99bec2be, + 0xcdeb87de26cd13cd, + 0x348968e4bd34d034, + 0x483290757a483d48, + 0xff54e324abffdbff, + 0x7a8df48ff77af57a, + 0x90643deaf4907a90, + 0x5f9dbe3ec25f615f, + 0x203d40a01d208020, + 0x680fd0d56768bd68, + 0x1aca3472d01a681a, + 0xaeb7412c19ae82ae, + 0xb47d755ec9b4eab4, + 0x54cea8199a544d54, + 0x937f3be5ec937693, + 0x222f44aa0d228822, + 0x6463c8e907648d64, + 0xf12aff12dbf1e3f1, + 0x73cce6a2bf73d173, + 0x1282245a90124812, + 0x407a805d3a401d40, + 0x0848102840082008, + 0xc3959be856c32bc3, + 0xecdfc57b33ec97ec, + 0xdb4dab9096db4bdb, + 0xa1c05f1f61a1bea1, + 0x8d9107831c8d0e8d, + 0x3dc87ac9f53df43d, + 0x975b33f1cc976697, 0x0000000000000000, - 0xcf1bcf36d483f9cf, - 0x2bac2b4587566e2b, - 0x76c57697b3ece176, - 0x82328264b019e682, - 0xd67fd6fea9b128d6, - 0x1b6c1bd87736c31b, - 0xb5eeb5c15b7774b5, - 0xaf86af112943beaf, - 0x6ab56a77dfd41d6a, - 0x505d50ba0da0ea50, - 0x450945124c8a5745, - 0xf3ebf3cb18fb38f3, - 0x30c0309df060ad30, - 0xef9bef2b74c3c4ef, - 0x3ffc3fe5c37eda3f, - 0x554955921caac755, - 0xa2b2a2791059dba2, - 0xea8fea0365c9e9ea, - 0x6589650fecca6a65, - 0xbad2bab9686903ba, - 0x2fbc2f65935e4a2f, - 0xc027c04ee79d8ec0, - 0xde5fdebe81a160de, - 0x1c701ce06c38fc1c, - 0xfdd3fdbb2ee746fd, - 0x4d294d52649a1f4d, - 0x927292e4e0397692, - 0x75c9758fbceafa75, - 0x061806301e0c3606, - 0x8a128a249809ae8a, - 0xb2f2b2f940794bb2, - 0xe6bfe66359d185e6, - 0x0e380e70361c7e0e, - 0x1f7c1ff8633ee71f, - 0x62956237f7c45562, - 0xd477d4eea3b53ad4, - 0xa89aa829324d81a8, - 0x966296c4f4315296, - 0xf9c3f99b3aef62f9, - 0xc533c566f697a3c5, - 0x25942535b14a1025, - 0x597959f220b2ab59, - 0x842a8454ae15d084, - 0x72d572b7a7e4c572, - 0x39e439d5dd72ec39, - 0x4c2d4c5a6198164c, - 0x5e655eca3bbc945e, - 0x78fd78e785f09f78, - 0x38e038ddd870e538, - 0x8c0a8c148605988c, - 0xd163d1c6b2bf17d1, - 0xa5aea5410b57e4a5, - 0xe2afe2434dd9a1e2, - 0x6199612ff8c24e61, - 0xb3f6b3f1457b42b3, - 0x21842115a5423421, - 0x9c4a9c94d625089c, - 0x1e781ef0663cee1e, - 0x4311432252866143, - 0xc73bc776fc93b1c7, - 0xfcd7fcb32be54ffc, - 0x0410042014082404, - 0x515951b208a2e351, - 0x995e99bcc72f2599, - 0x6da96d4fc4da226d, - 0x0d340d68391a650d, - 0xfacffa8335e979fa, - 0xdf5bdfb684a369df, - 0x7ee57ed79bfca97e, - 0x2490243db4481924, - 0x3bec3bc5d776fe3b, - 0xab96ab313d4b9aab, - 0xce1fce3ed181f0ce, - 0x1144118855229911, - 0x8f068f0c8903838f, - 0x4e254e4a6b9c044e, - 0xb7e6b7d1517366b7, - 0xeb8beb0b60cbe0eb, - 0x3cf03cfdcc78c13c, - 0x813e817cbf1ffd81, - 0x946a94d4fe354094, - 0xf7fbf7eb0cf31cf7, - 0xb9deb9a1676f18b9, - 0x134c13985f268b13, - 0x2cb02c7d9c58512c, - 0xd36bd3d6b8bb05d3, - 0xe7bbe76b5cd38ce7, - 0x6ea56e57cbdc396e, - 0xc437c46ef395aac4, - 0x030c03180f061b03, - 0x5645568a13acdc56, - 0x440d441a49885e44, - 0x7fe17fdf9efea07f, - 0xa99ea921374f88a9, - 0x2aa82a4d8254672a, - 0xbbd6bbb16d6b0abb, - 0xc123c146e29f87c1, - 0x535153a202a6f153, - 0xdc57dcae8ba572dc, - 0x0b2c0b582716530b, - 0x9d4e9d9cd327019d, - 0x6cad6c47c1d82b6c, - 0x31c43195f562a431, - 0x74cd7487b9e8f374, - 0xf6fff6e309f115f6, - 0x4605460a438c4c46, - 0xac8aac092645a5ac, - 0x891e893c970fb589, - 0x145014a04428b414, - 0xe1a3e15b42dfbae1, - 0x165816b04e2ca616, - 0x3ae83acdd274f73a, - 0x69b9696fd0d20669, - 0x092409482d124109, - 0x70dd70a7ade0d770, - 0xb6e2b6d954716fb6, - 0xd067d0ceb7bd1ed0, - 0xed93ed3b7ec7d6ed, - 0xcc17cc2edb85e2cc, - 0x4215422a57846842, - 0x985a98b4c22d2c98, - 0xa4aaa4490e55eda4, - 0x28a0285d88507528, - 0x5c6d5cda31b8865c, - 0xf8c7f8933fed6bf8, - 0x86228644a411c286, + 0xcff983d436cf1bcf, + 0x2b6e5687452bac2b, + 0x76e1ecb39776c576, + 0x82e619b064823282, + 0xd628b1a9fed67fd6, + 0x1bc33677d81b6c1b, + 0xb574775bc1b5eeb5, + 0xafbe432911af86af, + 0x6a1dd4df776ab56a, + 0x50eaa00dba505d50, + 0x45578a4c12450945, + 0xf338fb18cbf3ebf3, + 0x30ad60f09d30c030, + 0xefc4c3742bef9bef, + 0x3fda7ec3e53ffc3f, + 0x55c7aa1c92554955, + 0xa2db591079a2b2a2, + 0xeae9c96503ea8fea, + 0x656acaec0f658965, + 0xba036968b9bad2ba, + 0x2f4a5e93652fbc2f, + 0xc08e9de74ec027c0, + 0xde60a181bede5fde, + 0x1cfc386ce01c701c, + 0xfd46e72ebbfdd3fd, + 0x4d1f9a64524d294d, + 0x927639e0e4927292, + 0x75faeabc8f75c975, + 0x06360c1e30061806, + 0x8aae0998248a128a, + 0xb24b7940f9b2f2b2, + 0xe685d15963e6bfe6, + 0x0e7e1c36700e380e, + 0x1fe73e63f81f7c1f, + 0x6255c4f737629562, + 0xd43ab5a3eed477d4, + 0xa8814d3229a89aa8, + 0x965231f4c4966296, + 0xf962ef3a9bf9c3f9, + 0xc5a397f666c533c5, + 0x25104ab135259425, + 0x59abb220f2597959, + 0x84d015ae54842a84, + 0x72c5e4a7b772d572, + 0x39ec72ddd539e439, + 0x4c1698615a4c2d4c, + 0x5e94bc3bca5e655e, + 0x789ff085e778fd78, + 0x38e570d8dd38e038, + 0x8c980586148c0a8c, + 0xd117bfb2c6d163d1, + 0xa5e4570b41a5aea5, + 0xe2a1d94d43e2afe2, + 0x614ec2f82f619961, + 0xb3427b45f1b3f6b3, + 0x213442a515218421, + 0x9c0825d6949c4a9c, + 0x1eee3c66f01e781e, + 0x4361865222431143, + 0xc7b193fc76c73bc7, + 0xfc4fe52bb3fcd7fc, + 0x0424081420041004, + 0x51e3a208b2515951, + 0x99252fc7bc995e99, + 0x6d22dac44f6da96d, + 0x0d651a39680d340d, + 0xfa79e93583facffa, + 0xdf69a384b6df5bdf, + 0x7ea9fc9bd77ee57e, + 0x241948b43d249024, + 0x3bfe76d7c53bec3b, + 0xab9a4b3d31ab96ab, + 0xcef081d13ece1fce, + 0x1199225588114411, + 0x8f8303890c8f068f, + 0x4e049c6b4a4e254e, + 0xb7667351d1b7e6b7, + 0xebe0cb600beb8beb, + 0x3cc178ccfd3cf03c, + 0x81fd1fbf7c813e81, + 0x944035fed4946a94, + 0xf71cf30cebf7fbf7, + 0xb9186f67a1b9deb9, + 0x138b265f98134c13, + 0x2c51589c7d2cb02c, + 0xd305bbb8d6d36bd3, + 0xe78cd35c6be7bbe7, + 0x6e39dccb576ea56e, + 0xc4aa95f36ec437c4, + 0x031b060f18030c03, + 0x56dcac138a564556, + 0x445e88491a440d44, + 0x7fa0fe9edf7fe17f, + 0xa9884f3721a99ea9, + 0x2a6754824d2aa82a, + 0xbb0a6b6db1bbd6bb, + 0xc1879fe246c123c1, + 0x53f1a602a2535153, + 0xdc72a58baedc57dc, + 0x0b531627580b2c0b, + 0x9d0127d39c9d4e9d, + 0x6c2bd8c1476cad6c, + 0x31a462f59531c431, + 0x74f3e8b98774cd74, + 0xf615f109e3f6fff6, + 0x464c8c430a460546, + 0xaca5452609ac8aac, + 0x89b50f973c891e89, + 0x14b42844a0145014, + 0xe1badf425be1a3e1, + 0x16a62c4eb0165816, + 0x3af774d2cd3ae83a, + 0x6906d2d06f69b969, + 0x0941122d48092409, + 0x70d7e0ada770dd70, + 0xb66f7154d9b6e2b6, + 0xd01ebdb7ced067d0, + 0xedd6c77e3bed93ed, + 0xcce285db2ecc17cc, + 0x426884572a421542, + 0x982c2dc2b4985a98, + 0xa4ed550e49a4aaa4, + 0x287550885d28a028, + 0x5c86b831da5c6d5c, + 0xf86bed3f93f8c7f8, + 0x86c211a444862286, ]; diff --git a/whirlpool/src/lib.rs b/whirlpool/src/lib.rs index e2e313f66..54197e8f2 100644 --- a/whirlpool/src/lib.rs +++ b/whirlpool/src/lib.rs @@ -37,163 +37,140 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/whirlpool/0.10.0" )] -#![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "std")] -extern crate std; - -#[cfg(feature = "asm")] -use whirlpool_asm as utils; +pub use digest::{self, Digest}; #[cfg(not(feature = "asm"))] -mod utils; - -#[cfg(not(feature = "asm"))] -mod consts; - -pub use digest::Digest; +mod compress; -use crate::utils::compress; +#[cfg(feature = "asm")] +use whirlpool_asm as compress; + +use compress::compress; + +use core::{fmt, slice::from_ref}; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + OutputSizeUser, Reset, UpdateCore, + }, + generic_array::typenum::{Unsigned, U64}, + HashMarker, Output, +}; + +/// Core Whirlpool hasher state. +#[derive(Clone)] +pub struct WhirlpoolCore { + bit_len: [u64; 4], + state: [u64; 8], +} -use block_buffer::{block_padding::Iso7816, BlockBuffer}; -use digest::{consts::U64, generic_array::GenericArray}; -use digest::{BlockInput, FixedOutputDirty, Reset, Update}; +impl HashMarker for WhirlpoolCore {} -type BlockSize = U64; +impl BlockSizeUser for WhirlpoolCore { + type BlockSize = U64; +} -/// Structure representing the state of a Whirlpool computation -#[derive(Clone)] -pub struct Whirlpool { - bit_length: [u8; 32], - buffer: BlockBuffer, - #[cfg(not(feature = "asm"))] - hash: [u64; 8], - #[cfg(feature = "asm")] - hash: [u8; 64], +impl BufferKindUser for WhirlpoolCore { + type BufferKind = Eager; } -impl Default for Whirlpool { - fn default() -> Self { - Self { - bit_length: [0u8; 32], - buffer: BlockBuffer::default(), - #[cfg(not(feature = "asm"))] - hash: [0u64; 8], - #[cfg(feature = "asm")] - hash: [0u8; 64], - } - } +impl OutputSizeUser for WhirlpoolCore { + type OutputSize = U64; } -fn convert(block: &GenericArray) -> &[u8; 64] { - #[allow(unsafe_code)] - unsafe { - &*(block.as_ptr() as *const [u8; 64]) +impl UpdateCore for WhirlpoolCore { + #[inline] + fn update_blocks(&mut self, blocks: &[Block]) { + let block_bits = 8 * BLOCK_SIZE as u64; + self.update_len(block_bits * (blocks.len() as u64)); + compress(&mut self.state, convert(blocks)); } } -impl Whirlpool { - #![cfg_attr( - feature = "cargo-clippy", - allow(clippy::identity_op, clippy::double_parens) - )] - fn update_len(&mut self, len: u64) { - let len_bits = [ - (len >> (56 + 5)) as u8, - ((len >> (48 + 5)) & 0xff) as u8, - ((len >> (40 + 5)) & 0xff) as u8, - ((len >> (32 + 5)) & 0xff) as u8, - ((len >> (24 + 5)) & 0xff) as u8, - ((len >> (16 + 5)) & 0xff) as u8, - ((len >> (8 + 5)) & 0xff) as u8, - ((len >> (0 + 5)) & 0xff) as u8, - ((len << 3) & 0xff) as u8, - ]; - - let mut carry = false; - for i in 0..32 { - let mut x = u16::from(self.bit_length[self.bit_length.len() - i - 1]); - - if i < len_bits.len() { - x += u16::from(len_bits[len_bits.len() - i - 1]); - } else if !carry { - break; - } - - if carry { - x += 1; - } - - carry = x > 0xff; - let pos = self.bit_length.len() - i - 1; - self.bit_length[pos] = (x & 0xff) as u8; - } - } +impl FixedOutputCore for WhirlpoolCore { + #[inline] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let pos = buffer.get_pos(); + self.update_len(8 * pos as u64); - fn finalize_inner(&mut self) { - // padding - let hash = &mut self.hash; - let pos = self.buffer.position(); - let buf = self - .buffer - .pad_with::() - .expect("we never use input_lazy"); - - if pos + 1 > self.bit_length.len() { - compress(hash, convert(buf)); - buf[..=pos].iter_mut().for_each(|b| *b = 0); + let mut buf = [0u8; 4 * 8]; + for (chunk, v) in buf.chunks_exact_mut(8).zip(self.bit_len.iter()) { + chunk.copy_from_slice(&v.to_be_bytes()); } - buf[32..].copy_from_slice(&self.bit_length); - compress(hash, convert(buf)); + let mut state = self.state; + buffer.digest_pad(0x80, &buf, |block| { + compress(&mut state, convert(from_ref(block))) + }); + + for (chunk, v) in out.chunks_exact_mut(8).zip(state.iter()) { + chunk.copy_from_slice(&v.to_le_bytes()); + } } } -impl BlockInput for Whirlpool { - type BlockSize = BlockSize; +impl WhirlpoolCore { + fn update_len(&mut self, len: u64) { + let mut carry = 0; + adc(&mut self.bit_len[3], len, &mut carry); + adc(&mut self.bit_len[2], 0, &mut carry); + adc(&mut self.bit_len[1], 0, &mut carry); + adc(&mut self.bit_len[0], 0, &mut carry); + } } -impl Update for Whirlpool { - fn update(&mut self, input: impl AsRef<[u8]>) { - let input = input.as_ref(); - self.update_len(input.len() as u64); - let hash = &mut self.hash; - self.buffer - .input_block(input, |b| compress(hash, convert(b))); +impl Default for WhirlpoolCore { + #[inline] + fn default() -> Self { + Self { + bit_len: Default::default(), + state: [0u64; 8], + } } } -impl FixedOutputDirty for Whirlpool { - type OutputSize = U64; - - #[cfg(not(feature = "asm"))] - fn finalize_into_dirty(&mut self, out: &mut GenericArray) { - self.finalize_inner(); - for (chunk, v) in out.chunks_exact_mut(8).zip(self.hash.iter()) { - chunk.copy_from_slice(&v.to_be_bytes()); - } +impl Reset for WhirlpoolCore { + #[inline] + fn reset(&mut self) { + *self = Default::default(); } +} - #[cfg(feature = "asm")] - fn finalize_into_dirty(&mut self, out: &mut GenericArray) { - self.finalize_inner(); - out.copy_from_slice(&self.hash) +impl AlgorithmName for WhirlpoolCore { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Whirlpool") } } -impl Reset for Whirlpool { - fn reset(&mut self) { - self.bit_length = [0u8; 32]; - self.buffer.reset(); - for v in self.hash.iter_mut() { - *v = 0; - } +impl fmt::Debug for WhirlpoolCore { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("WhirlpoolCore { ... }") } } -opaque_debug::implement!(Whirlpool); -digest::impl_write!(Whirlpool); +/// Whirlpool hasher state. +pub type Whirlpool = CoreWrapper; + +#[inline(always)] +fn adc(a: &mut u64, b: u64, carry: &mut u64) { + let ret = (*a as u128) + (b as u128) + (*carry as u128); + *a = ret as u64; + *carry = (ret >> 64) as u64; +} + +const BLOCK_SIZE: usize = ::BlockSize::USIZE; + +#[inline(always)] +fn convert(blocks: &[Block]) -> &[[u8; BLOCK_SIZE]] { + // SAFETY: GenericArray and [u8; 64] have + // exactly the same memory layout + let p = blocks.as_ptr() as *const [u8; BLOCK_SIZE]; + unsafe { core::slice::from_raw_parts(p, blocks.len()) } +} diff --git a/whirlpool/src/utils.rs b/whirlpool/src/utils.rs deleted file mode 100644 index 53312ce7f..000000000 --- a/whirlpool/src/utils.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::consts::*; -use core::convert::TryInto; - -pub fn compress(hash: &mut [u64; 8], buffer: &[u8; 64]) { - let mut k = [0u64; 8]; - let mut block = [0u64; 8]; - let mut state = [0u64; 8]; - let mut l = [0u64; 8]; - - for (o, chunk) in block.iter_mut().zip(buffer.chunks_exact(8)) { - *o = u64::from_be_bytes(chunk.try_into().unwrap()); - } - k.copy_from_slice(hash); - - for i in 0..8 { - state[i] = block[i] ^ k[i]; - } - - #[allow(clippy::needless_range_loop)] - for r in 1..=R { - for i in 0..8 { - l[i] = C0[(k[(i) % 8] >> 56) as usize] - ^ C1[((k[(7 + i) % 8] >> 48) & 0xff) as usize] - ^ C2[((k[(6 + i) % 8] >> 40) & 0xff) as usize] - ^ C3[((k[(5 + i) % 8] >> 32) & 0xff) as usize] - ^ C4[((k[(4 + i) % 8] >> 24) & 0xff) as usize] - ^ C5[((k[(3 + i) % 8] >> 16) & 0xff) as usize] - ^ C6[((k[(2 + i) % 8] >> 8) & 0xff) as usize] - ^ C7[((k[(1 + i) % 8]) & 0xff) as usize] - ^ if i == 0 { RC[r] } else { 0 }; - } - k = l; - for i in 0..8 { - l[i] = C0[(state[(i) % 8] >> 56) as usize] - ^ C1[((state[(7 + i) % 8] >> 48) & 0xff) as usize] - ^ C2[((state[(6 + i) % 8] >> 40) & 0xff) as usize] - ^ C3[((state[(5 + i) % 8] >> 32) & 0xff) as usize] - ^ C4[((state[(4 + i) % 8] >> 24) & 0xff) as usize] - ^ C5[((state[(3 + i) % 8] >> 16) & 0xff) as usize] - ^ C6[((state[(2 + i) % 8] >> 8) & 0xff) as usize] - ^ C7[((state[(1 + i) % 8]) & 0xff) as usize] - ^ k[i]; - } - state = l; - } - - for i in 0..8 { - hash[i] ^= state[i] ^ block[i]; - } -} diff --git a/whirlpool/tests/data/whirlpool.blb b/whirlpool/tests/data/whirlpool.blb index a82e549b5b106b36fddaf7d456b8d7445e7a15d8..4222b2787d0273459b64556c59b61f740c3a842f 100644 GIT binary patch delta 251 zcmbQny@;EIfuVt6BBuk75CaSV`5_LxA}}sk!2$<9F@yj}%UcH)ro;w@$p(xLY;1{1 z$v|c)ql2JKZfbFHVtT4VN@jX$aS2fLD5C?T$>bU)DJCFCk;#FvW^xjf9f-3K$f=ve ztT>sMSpd>pDVlyw7TYJZf+);n>v*&_Tm(RGN*uhUa{Nsbj-;f5d2Pya6ncEc*Ze