diff --git a/.github/workflows/aria.yml b/.github/workflows/aria.yml
new file mode 100644
index 00000000..47f45961
--- /dev/null
+++ b/.github/workflows/aria.yml
@@ -0,0 +1,64 @@
+name: aria
+
+on:
+ pull_request:
+ paths:
+ - "aria/**"
+ - "Cargo.*"
+ push:
+ branches: master
+
+defaults:
+ run:
+ working-directory: aria
+
+env:
+ CARGO_INCREMENTAL: 0
+ RUSTFLAGS: "-Dwarnings"
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ rust:
+ - 1.56.0 # MSRV
+ - stable
+ target:
+ - thumbv7em-none-eabi
+ - wasm32-unknown-unknown
+ steps:
+ - uses: actions/checkout@v3
+ - uses: RustCrypto/actions/cargo-cache@master
+ - 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 }}
+
+ minimal-versions:
+ uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
+ with:
+ working-directory: ${{ github.workflow }}
+
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ rust:
+ - 1.56.0 # MSRV
+ - stable
+ steps:
+ - uses: actions/checkout@v3
+ - uses: RustCrypto/actions/cargo-cache@master
+ - uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ matrix.rust }}
+ override: true
+ profile: minimal
+ - run: cargo check --all-features
+ - run: cargo test --no-default-features
+ - run: cargo test
+ - run: cargo test --all-features
diff --git a/Cargo.lock b/Cargo.lock
index e2caf0a3..970b540d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -13,6 +13,14 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "aria"
+version = "0.1.0"
+dependencies = [
+ "cipher",
+ "hex-literal",
+]
+
[[package]]
name = "belt-block"
version = "0.1.1"
diff --git a/Cargo.toml b/Cargo.toml
index 5c07c623..4b45587f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,7 @@
[workspace]
members = [
"aes",
+ "aria",
"belt-block",
"blowfish",
"camellia",
diff --git a/aria/CHANGELOG.md b/aria/CHANGELOG.md
new file mode 100644
index 00000000..956a57d2
--- /dev/null
+++ b/aria/CHANGELOG.md
@@ -0,0 +1,9 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.1.0 (UNRELEASED)
+- Initial release
diff --git a/aria/Cargo.toml b/aria/Cargo.toml
new file mode 100644
index 00000000..4ccbfcc3
--- /dev/null
+++ b/aria/Cargo.toml
@@ -0,0 +1,27 @@
+[package]
+name = "aria"
+version = "0.1.0"
+description = "Pure Rust implementation of the ARIA Encryption Algorithm"
+authors = ["RustCrypto Developers"]
+license = "MIT OR Apache-2.0"
+edition = "2021"
+rust-version = "1.56"
+readme = "README.md"
+documentation = "https://docs.rs/aria"
+repository = "https://github.com/RustCrypto/block-ciphers"
+keywords = ["crypto", "aria", "block-cipher"]
+categories = ["cryptography", "no-std"]
+
+[dependencies]
+cipher = "0.4.2"
+
+[dev-dependencies]
+cipher = { version = "0.4.2", features = ["dev"] }
+hex-literal = "0.3"
+
+[features]
+zeroize = ["cipher/zeroize"]
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
diff --git a/aria/LICENSE-APACHE b/aria/LICENSE-APACHE
new file mode 100644
index 00000000..78173fa2
--- /dev/null
+++ b/aria/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/aria/LICENSE-MIT b/aria/LICENSE-MIT
new file mode 100644
index 00000000..4ddf226a
--- /dev/null
+++ b/aria/LICENSE-MIT
@@ -0,0 +1,26 @@
+Copyright (c) 2018-2019 Friedel Ziegelmayer
+Copyright (c) 2018-2019 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/aria/README.md b/aria/README.md
new file mode 100644
index 00000000..f38e7364
--- /dev/null
+++ b/aria/README.md
@@ -0,0 +1,73 @@
+# RustCrypto: ARIA Cipher
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+[![Build Status][build-image]][build-link]
+[![HAZMAT][hazmat-image]][hazmat-link]
+
+Pure Rust implementation of the [ARIA block cipher][1].
+
+[Documentation][docs-link]
+
+
+
+## ⚠️ Security Warning: [Hazmat!][hazmat-link]
+
+This crate does not ensure ciphertexts are authentic (i.e. by using a MAC to
+verify ciphertext integrity), which can lead to serious vulnerabilities
+if used incorrectly!
+
+No security audits of this crate have ever been performed, and it has not been
+thoroughly assessed to ensure its operation is constant-time on common CPU
+architectures.
+
+USE AT YOUR OWN RISK!
+
+## Minimum Supported Rust Version
+
+Rust **1.56** or higher.
+
+Minimum supported Rust version can be changed in the future, but it will be
+done with a minor version bump.
+
+## SemVer Policy
+
+- All on-by-default features of this library are covered by SemVer
+- MSRV is considered exempt from SemVer as noted above
+
+## License
+
+Licensed under either of:
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/aria.svg
+[crate-link]: https://crates.io/crates/aria
+[docs-image]: https://docs.rs/aria/badge.svg
+[docs-link]: https://docs.rs/aria/
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg
+[hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg
+[hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260039-block-ciphers
+[build-image]: https://github.com/RustCrypto/block-ciphers/workflows/aria/badge.svg?branch=master&event=push
+[build-link]: https://github.com/RustCrypto/block-ciphers/actions?query=workflow%3Aaria
+
+[//]: # (general links)
+
+[1]: https://en.wikipedia.org/wiki/ARIA_(cipher)
diff --git a/aria/src/consts.rs b/aria/src/consts.rs
new file mode 100644
index 00000000..ead67da3
--- /dev/null
+++ b/aria/src/consts.rs
@@ -0,0 +1,98 @@
+pub const SB1: [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 SB2: [u8; 256] = [
+ 0xe2, 0x4e, 0x54, 0xfc, 0x94, 0xc2, 0x4a, 0xcc, 0x62, 0x0d, 0x6a, 0x46, 0x3c, 0x4d, 0x8b, 0xd1,
+ 0x5e, 0xfa, 0x64, 0xcb, 0xb4, 0x97, 0xbe, 0x2b, 0xbc, 0x77, 0x2e, 0x03, 0xd3, 0x19, 0x59, 0xc1,
+ 0x1d, 0x06, 0x41, 0x6b, 0x55, 0xf0, 0x99, 0x69, 0xea, 0x9c, 0x18, 0xae, 0x63, 0xdf, 0xe7, 0xbb,
+ 0x00, 0x73, 0x66, 0xfb, 0x96, 0x4c, 0x85, 0xe4, 0x3a, 0x09, 0x45, 0xaa, 0x0f, 0xee, 0x10, 0xeb,
+ 0x2d, 0x7f, 0xf4, 0x29, 0xac, 0xcf, 0xad, 0x91, 0x8d, 0x78, 0xc8, 0x95, 0xf9, 0x2f, 0xce, 0xcd,
+ 0x08, 0x7a, 0x88, 0x38, 0x5c, 0x83, 0x2a, 0x28, 0x47, 0xdb, 0xb8, 0xc7, 0x93, 0xa4, 0x12, 0x53,
+ 0xff, 0x87, 0x0e, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8e, 0x37, 0x74, 0x32, 0xca, 0xe9, 0xb1,
+ 0xb7, 0xab, 0x0c, 0xd7, 0xc4, 0x56, 0x42, 0x26, 0x07, 0x98, 0x60, 0xd9, 0xb6, 0xb9, 0x11, 0x40,
+ 0xec, 0x20, 0x8c, 0xbd, 0xa0, 0xc9, 0x84, 0x04, 0x49, 0x23, 0xf1, 0x4f, 0x50, 0x1f, 0x13, 0xdc,
+ 0xd8, 0xc0, 0x9e, 0x57, 0xe3, 0xc3, 0x7b, 0x65, 0x3b, 0x02, 0x8f, 0x3e, 0xe8, 0x25, 0x92, 0xe5,
+ 0x15, 0xdd, 0xfd, 0x17, 0xa9, 0xbf, 0xd4, 0x9a, 0x7e, 0xc5, 0x39, 0x67, 0xfe, 0x76, 0x9d, 0x43,
+ 0xa7, 0xe1, 0xd0, 0xf5, 0x68, 0xf2, 0x1b, 0x34, 0x70, 0x05, 0xa3, 0x8a, 0xd5, 0x79, 0x86, 0xa8,
+ 0x30, 0xc6, 0x51, 0x4b, 0x1e, 0xa6, 0x27, 0xf6, 0x35, 0xd2, 0x6e, 0x24, 0x16, 0x82, 0x5f, 0xda,
+ 0xe6, 0x75, 0xa2, 0xef, 0x2c, 0xb2, 0x1c, 0x9f, 0x5d, 0x6f, 0x80, 0x0a, 0x72, 0x44, 0x9b, 0x6c,
+ 0x90, 0x0b, 0x5b, 0x33, 0x7d, 0x5a, 0x52, 0xf3, 0x61, 0xa1, 0xf7, 0xb0, 0xd6, 0x3f, 0x7c, 0x6d,
+ 0xed, 0x14, 0xe0, 0xa5, 0x3d, 0x22, 0xb3, 0xf8, 0x89, 0xde, 0x71, 0x1a, 0xaf, 0xba, 0xb5, 0x81,
+];
+
+pub const SB3: [u8; 256] = [
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
+];
+
+pub const SB4: [u8; 256] = [
+ 0x30, 0x68, 0x99, 0x1b, 0x87, 0xb9, 0x21, 0x78, 0x50, 0x39, 0xdb, 0xe1, 0x72, 0x09, 0x62, 0x3c,
+ 0x3e, 0x7e, 0x5e, 0x8e, 0xf1, 0xa0, 0xcc, 0xa3, 0x2a, 0x1d, 0xfb, 0xb6, 0xd6, 0x20, 0xc4, 0x8d,
+ 0x81, 0x65, 0xf5, 0x89, 0xcb, 0x9d, 0x77, 0xc6, 0x57, 0x43, 0x56, 0x17, 0xd4, 0x40, 0x1a, 0x4d,
+ 0xc0, 0x63, 0x6c, 0xe3, 0xb7, 0xc8, 0x64, 0x6a, 0x53, 0xaa, 0x38, 0x98, 0x0c, 0xf4, 0x9b, 0xed,
+ 0x7f, 0x22, 0x76, 0xaf, 0xdd, 0x3a, 0x0b, 0x58, 0x67, 0x88, 0x06, 0xc3, 0x35, 0x0d, 0x01, 0x8b,
+ 0x8c, 0xc2, 0xe6, 0x5f, 0x02, 0x24, 0x75, 0x93, 0x66, 0x1e, 0xe5, 0xe2, 0x54, 0xd8, 0x10, 0xce,
+ 0x7a, 0xe8, 0x08, 0x2c, 0x12, 0x97, 0x32, 0xab, 0xb4, 0x27, 0x0a, 0x23, 0xdf, 0xef, 0xca, 0xd9,
+ 0xb8, 0xfa, 0xdc, 0x31, 0x6b, 0xd1, 0xad, 0x19, 0x49, 0xbd, 0x51, 0x96, 0xee, 0xe4, 0xa8, 0x41,
+ 0xda, 0xff, 0xcd, 0x55, 0x86, 0x36, 0xbe, 0x61, 0x52, 0xf8, 0xbb, 0x0e, 0x82, 0x48, 0x69, 0x9a,
+ 0xe0, 0x47, 0x9e, 0x5c, 0x04, 0x4b, 0x34, 0x15, 0x79, 0x26, 0xa7, 0xde, 0x29, 0xae, 0x92, 0xd7,
+ 0x84, 0xe9, 0xd2, 0xba, 0x5d, 0xf3, 0xc5, 0xb0, 0xbf, 0xa4, 0x3b, 0x71, 0x44, 0x46, 0x2b, 0xfc,
+ 0xeb, 0x6f, 0xd5, 0xf6, 0x14, 0xfe, 0x7c, 0x70, 0x5a, 0x7d, 0xfd, 0x2f, 0x18, 0x83, 0x16, 0xa5,
+ 0x91, 0x1f, 0x05, 0x95, 0x74, 0xa9, 0xc1, 0x5b, 0x4a, 0x85, 0x6d, 0x13, 0x07, 0x4f, 0x4e, 0x45,
+ 0xb2, 0x0f, 0xc9, 0x1c, 0xa6, 0xbc, 0xec, 0x73, 0x90, 0x7b, 0xcf, 0x59, 0x8f, 0xa1, 0xf9, 0x2d,
+ 0xf2, 0xb1, 0x00, 0x94, 0x37, 0x9f, 0xd0, 0x2e, 0x9c, 0x6e, 0x28, 0x3f, 0x80, 0xf0, 0x3d, 0xd3,
+ 0x25, 0x8a, 0xb5, 0xe7, 0x42, 0xb3, 0xc7, 0xea, 0xf7, 0x4c, 0x11, 0x33, 0x03, 0xa2, 0xac, 0x60,
+];
+
+pub const C1: u128 = 0x517cc1b727220a94fe13abe8fa9a6ee0;
+pub const C2: u128 = 0x6db14acc9e21c820ff28b1d5ef5de2b0;
+pub const C3: u128 = 0xdb92371d2126e9700324977504e8c90e;
+
+pub const DIFFUSE_CONSTS: [u128; 16] = [
+ 0x0000_0001_0100_0100_0101_0000_0001_0100,
+ 0x0000_0100_0001_0001_0101_0000_0100_0001,
+ 0x0001_0000_0100_0100_0000_0101_0100_0001,
+ 0x0100_0000_0001_0001_0000_0101_0001_0100,
+ 0x0100_0100_0001_0000_0100_0001_0000_0101,
+ 0x0001_0001_0100_0000_0001_0100_0000_0101,
+ 0x0100_0100_0000_0001_0001_0100_0101_0000,
+ 0x0001_0001_0000_0100_0100_0001_0101_0000,
+ 0x0101_0000_0100_0001_0000_0100_0001_0001,
+ 0x0101_0000_0001_0100_0000_0001_0100_0100,
+ 0x0000_0101_0001_0100_0100_0000_0001_0001,
+ 0x0000_0101_0100_0001_0001_0000_0100_0100,
+ 0x0001_0100_0000_0101_0001_0001_0100_0000,
+ 0x0100_0001_0000_0101_0100_0100_0001_0000,
+ 0x0100_0001_0101_0000_0001_0001_0000_0100,
+ 0x0001_0100_0101_0000_0100_0100_0000_0001,
+];
diff --git a/aria/src/lib.rs b/aria/src/lib.rs
new file mode 100644
index 00000000..7eac2dfc
--- /dev/null
+++ b/aria/src/lib.rs
@@ -0,0 +1,367 @@
+//! Pure Rust implementation of the [ARIA] block cipher ([RFC 5794]).
+//!
+//! # ⚠️ Security Warning: Hazmat!
+//!
+//! This crate implements only the low-level block cipher function, and is intended
+//! for use for implementing higher-level constructions *only*. It is NOT
+//! intended for direct use in applications.
+//!
+//! USE AT YOUR OWN RISK!
+//!
+//! # Examples
+//! ```
+//! use aria::cipher::generic_array::GenericArray;
+//! use aria::cipher::{Key, Block, BlockEncrypt, BlockDecrypt, KeyInit};
+//! use aria::Aria128;
+//!
+//! let key = GenericArray::from([0u8; 16]);
+//! let mut block = GenericArray::from([0u8; 16]);
+//! // Initialize cipher
+//! let cipher = Aria128::new(&key);
+//!
+//! let block_copy = block.clone();
+//! // Encrypt block in-place
+//! cipher.encrypt_block(&mut block);
+//! // And decrypt it back
+//! cipher.decrypt_block(&mut block);
+//! assert_eq!(block, block_copy);
+//! ```
+//!
+//! [ARIA]: https://en.wikipedia.org/wiki/ARIA_(cipher)
+//! [RFC 5794]: https://tools.ietf.org/html/rfc5794
+
+#![no_std]
+#![doc(
+ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg",
+ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg"
+)]
+#![deny(unsafe_code)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![warn(missing_docs, rust_2018_idioms)]
+
+mod consts;
+
+pub use cipher;
+
+use cipher::{
+ consts::{U16, U24, U32},
+ AlgorithmName, BlockCipher, Key, KeyInit, KeySizeUser,
+};
+use core::fmt;
+
+#[cfg(feature = "zeroize")]
+use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
+
+use crate::consts::{C1, C2, C3, DIFFUSE_CONSTS, SB1, SB2, SB3, SB4};
+
+#[inline(always)]
+fn diffuse(x: [u8; 16]) -> u128 {
+ DIFFUSE_CONSTS
+ .iter()
+ .zip(x)
+ .map(|(a, b)| a * b as u128)
+ .fold(0, |a, v| a ^ v)
+}
+
+#[inline(always)]
+fn a(x128: u128) -> u128 {
+ diffuse(x128.to_be_bytes())
+}
+
+fn sl2(x128: u128) -> u128 {
+ let x = x128.to_be_bytes();
+ let y = [
+ SB3[x[0] as usize],
+ SB4[x[1] as usize],
+ SB1[x[2] as usize],
+ SB2[x[3] as usize],
+ SB3[x[4] as usize],
+ SB4[x[5] as usize],
+ SB1[x[6] as usize],
+ SB2[x[7] as usize],
+ SB3[x[8] as usize],
+ SB4[x[9] as usize],
+ SB1[x[10] as usize],
+ SB2[x[11] as usize],
+ SB3[x[12] as usize],
+ SB4[x[13] as usize],
+ SB1[x[14] as usize],
+ SB2[x[15] as usize],
+ ];
+ u128::from_be_bytes(y)
+}
+
+fn fo(x128: u128) -> u128 {
+ let x = x128.to_be_bytes();
+ diffuse([
+ SB1[x[0] as usize],
+ SB2[x[1] as usize],
+ SB3[x[2] as usize],
+ SB4[x[3] as usize],
+ SB1[x[4] as usize],
+ SB2[x[5] as usize],
+ SB3[x[6] as usize],
+ SB4[x[7] as usize],
+ SB1[x[8] as usize],
+ SB2[x[9] as usize],
+ SB3[x[10] as usize],
+ SB4[x[11] as usize],
+ SB1[x[12] as usize],
+ SB2[x[13] as usize],
+ SB3[x[14] as usize],
+ SB4[x[15] as usize],
+ ])
+}
+
+fn fe(x128: u128) -> u128 {
+ let x = x128.to_be_bytes();
+ diffuse([
+ SB3[x[0] as usize],
+ SB4[x[1] as usize],
+ SB1[x[2] as usize],
+ SB2[x[3] as usize],
+ SB3[x[4] as usize],
+ SB4[x[5] as usize],
+ SB1[x[6] as usize],
+ SB2[x[7] as usize],
+ SB3[x[8] as usize],
+ SB4[x[9] as usize],
+ SB1[x[10] as usize],
+ SB2[x[11] as usize],
+ SB3[x[12] as usize],
+ SB4[x[13] as usize],
+ SB1[x[14] as usize],
+ SB2[x[15] as usize],
+ ])
+}
+
+impl KeyInit for Aria128 {
+ fn new(key: &Key) -> Self {
+ let kl = u128::from_be_bytes(key[0..16].try_into().unwrap());
+ let kr = u128::default();
+
+ let w0 = kl;
+ let w1 = fo(w0 ^ C1) ^ kr;
+ let w2 = fe(w1 ^ C2) ^ w0;
+ let w3 = fo(w2 ^ C3) ^ w1;
+
+ let ek = [
+ w0 ^ w1.rotate_right(19),
+ w1 ^ w2.rotate_right(19),
+ w2 ^ w3.rotate_right(19),
+ w3 ^ w0.rotate_right(19),
+ w0 ^ w1.rotate_right(31),
+ w1 ^ w2.rotate_right(31),
+ w2 ^ w3.rotate_right(31),
+ w3 ^ w0.rotate_right(31),
+ w0 ^ w1.rotate_left(61),
+ w1 ^ w2.rotate_left(61),
+ w2 ^ w3.rotate_left(61),
+ w3 ^ w0.rotate_left(61),
+ w0 ^ w1.rotate_left(31),
+ ];
+
+ let dk = [
+ ek[12],
+ a(ek[11]),
+ a(ek[10]),
+ a(ek[9]),
+ a(ek[8]),
+ a(ek[7]),
+ a(ek[6]),
+ a(ek[5]),
+ a(ek[4]),
+ a(ek[3]),
+ a(ek[2]),
+ a(ek[1]),
+ ek[0],
+ ];
+
+ Self { ek, dk }
+ }
+}
+
+impl KeyInit for Aria192 {
+ fn new(key: &Key) -> Self {
+ let kl = u128::from_be_bytes(key[0..16].try_into().unwrap());
+ let kr = u64::from_be_bytes(key[16..24].try_into().unwrap());
+ let kr = (kr as u128) << 64;
+
+ let w0 = kl;
+ let w1 = fo(w0 ^ C2) ^ kr;
+ let w2 = fe(w1 ^ C3) ^ w0;
+ let w3 = fo(w2 ^ C1) ^ w1;
+
+ let ek = [
+ w0 ^ w1.rotate_right(19),
+ w1 ^ w2.rotate_right(19),
+ w2 ^ w3.rotate_right(19),
+ w3 ^ w0.rotate_right(19),
+ w0 ^ w1.rotate_right(31),
+ w1 ^ w2.rotate_right(31),
+ w2 ^ w3.rotate_right(31),
+ w3 ^ w0.rotate_right(31),
+ w0 ^ w1.rotate_left(61),
+ w1 ^ w2.rotate_left(61),
+ w2 ^ w3.rotate_left(61),
+ w3 ^ w0.rotate_left(61),
+ w0 ^ w1.rotate_left(31),
+ w1 ^ w2.rotate_left(31),
+ w2 ^ w3.rotate_left(31),
+ ];
+
+ let dk = [
+ ek[14],
+ a(ek[13]),
+ a(ek[12]),
+ a(ek[11]),
+ a(ek[10]),
+ a(ek[9]),
+ a(ek[8]),
+ a(ek[7]),
+ a(ek[6]),
+ a(ek[5]),
+ a(ek[4]),
+ a(ek[3]),
+ a(ek[2]),
+ a(ek[1]),
+ ek[0],
+ ];
+
+ Self { ek, dk }
+ }
+}
+
+impl KeyInit for Aria256 {
+ fn new(key: &Key) -> Self {
+ let kl = u128::from_be_bytes(key[0..16].try_into().unwrap());
+ let kr = u128::from_be_bytes(key[16..32].try_into().unwrap());
+
+ let w0 = kl;
+ let w1 = fo(w0 ^ C3) ^ kr;
+ let w2 = fe(w1 ^ C1) ^ w0;
+ let w3 = fo(w2 ^ C2) ^ w1;
+
+ let ek = [
+ w0 ^ w1.rotate_right(19),
+ w1 ^ w2.rotate_right(19),
+ w2 ^ w3.rotate_right(19),
+ w3 ^ w0.rotate_right(19),
+ w0 ^ w1.rotate_right(31),
+ w1 ^ w2.rotate_right(31),
+ w2 ^ w3.rotate_right(31),
+ w3 ^ w0.rotate_right(31),
+ w0 ^ w1.rotate_left(61),
+ w1 ^ w2.rotate_left(61),
+ w2 ^ w3.rotate_left(61),
+ w3 ^ w0.rotate_left(61),
+ w0 ^ w1.rotate_left(31),
+ w1 ^ w2.rotate_left(31),
+ w2 ^ w3.rotate_left(31),
+ w3 ^ w0.rotate_left(31),
+ w0 ^ w1.rotate_left(19),
+ ];
+
+ let dk = [
+ ek[16],
+ a(ek[15]),
+ a(ek[14]),
+ a(ek[13]),
+ a(ek[12]),
+ a(ek[11]),
+ a(ek[10]),
+ a(ek[9]),
+ a(ek[8]),
+ a(ek[7]),
+ a(ek[6]),
+ a(ek[5]),
+ a(ek[4]),
+ a(ek[3]),
+ a(ek[2]),
+ a(ek[1]),
+ ek[0],
+ ];
+
+ Self { ek, dk }
+ }
+}
+
+macro_rules! impl_aria {
+ ($name:ident, $subkey_size:literal, $key_size:ty, $doc:literal) => {
+ #[doc = $doc]
+ #[derive(Clone)]
+ pub struct $name {
+ /// Encrypting subkeys.
+ ek: [u128; $subkey_size],
+ /// Encrypting subkeys.
+ dk: [u128; $subkey_size],
+ }
+ impl BlockCipher for $name {}
+
+ impl KeySizeUser for $name {
+ type KeySize = $key_size;
+ }
+
+ impl fmt::Debug for $name {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(concat!(stringify!($name), " { ... }"))
+ }
+ }
+
+ impl AlgorithmName for $name {
+ fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(stringify!($name))
+ }
+ }
+
+ #[cfg(feature = "zeroize")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
+ impl Drop for $name {
+ fn drop(&mut self) {
+ self.ek.zeroize();
+ self.dk.zeroize();
+ }
+ }
+
+ #[cfg(feature = "zeroize")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
+ impl ZeroizeOnDrop for $name {}
+
+ cipher::impl_simple_block_encdec!(
+ $name, U16, cipher, block,
+ encrypt: {
+ let mut p0 = u128::from_be_bytes((*block.get_in()).into());
+ let mut p1;
+
+ for i in (0..$subkey_size - 3).step_by(2) {
+ p1 = fo(p0 ^ cipher.ek[i]);
+ p0 = fe(p1 ^ cipher.ek[i + 1]);
+ }
+
+ let p1 = fo(p0 ^ cipher.ek[$subkey_size - 3]);
+ let c = sl2(p1 ^ cipher.ek[$subkey_size - 2]) ^ cipher.ek[$subkey_size - 1];
+
+ block.get_out().copy_from_slice(&c.to_be_bytes());
+ }
+ decrypt: {
+ let mut c0 = u128::from_be_bytes((*block.get_in()).into());
+ let mut c1;
+
+ for i in (0..$subkey_size - 3).step_by(2) {
+ c1 = fo(c0 ^ cipher.dk[i]);
+ c0 = fe(c1 ^ cipher.dk[i + 1]);
+ }
+
+ let c1 = fo(c0 ^ cipher.dk[$subkey_size - 3]);
+ let p = sl2(c1 ^ cipher.dk[$subkey_size - 2]) ^ cipher.dk[$subkey_size - 1];
+
+ block.get_out().copy_from_slice(&p.to_be_bytes());
+ }
+ );
+
+ };
+}
+
+impl_aria!(Aria128, 13, U16, "Aria-128 block cipher instance.");
+impl_aria!(Aria192, 15, U24, "Aria-192 block cipher instance.");
+impl_aria!(Aria256, 17, U32, "Aria-256 block cipher instance.");
diff --git a/aria/tests/mod.rs b/aria/tests/mod.rs
new file mode 100644
index 00000000..498d83c7
--- /dev/null
+++ b/aria/tests/mod.rs
@@ -0,0 +1,51 @@
+use aria::{Aria128, Aria192, Aria256};
+use cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt, KeyInit};
+use hex_literal::hex;
+
+/// Test vector from RFC 5794, Appendix A.1
+#[test]
+fn test_rfc5794_a1() {
+ let key = hex!("000102030405060708090a0b0c0d0e0f");
+ let pt = hex!("00112233445566778899aabbccddeeff");
+ let ct = hex!("d718fbd6ab644c739da95f3be6451778");
+
+ let c = Aria128::new_from_slice(&key).unwrap();
+
+ let mut buf = GenericArray::from(pt);
+ c.encrypt_block(&mut buf);
+ assert_eq!(buf.as_ref(), ct);
+ c.decrypt_block(&mut buf);
+ assert_eq!(buf.as_ref(), pt);
+}
+
+/// Test vector from RFC 5794, Appendix A.2
+#[test]
+fn test_rfc5794_a2() {
+ let key = hex!("000102030405060708090a0b0c0d0e0f1011121314151617");
+ let pt = hex!("00112233445566778899aabbccddeeff");
+ let ct = hex!("26449c1805dbe7aa25a468ce263a9e79");
+
+ let c = Aria192::new_from_slice(&key).unwrap();
+
+ let mut buf = GenericArray::from(pt);
+ c.encrypt_block(&mut buf);
+ assert_eq!(buf.as_ref(), ct);
+ c.decrypt_block(&mut buf);
+ assert_eq!(buf.as_ref(), pt);
+}
+
+/// Test vector from RFC 5794, Appendix A.3
+#[test]
+fn test_rfc5794_a3() {
+ let key = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
+ let pt = hex!("00112233445566778899aabbccddeeff");
+ let ct = hex!("f92bd7c79fb72e2f2b8f80c1972d24fc");
+
+ let c = Aria256::new_from_slice(&key).unwrap();
+
+ let mut buf = GenericArray::from(pt);
+ c.encrypt_block(&mut buf);
+ assert_eq!(buf.as_ref(), ct);
+ c.decrypt_block(&mut buf);
+ assert_eq!(buf.as_ref(), pt);
+}