From 386b44d48ee95fa517e9e5c5d411f6bd0fe8ca5d Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Fri, 14 May 2021 22:15:51 -0400 Subject: [PATCH 01/24] Initial Deoxys-II-128 implementation --- Cargo.lock | 16 ++ Cargo.toml | 1 + deoxys/Cargo.toml | 33 +++ deoxys/LICENSE-APACHE | 201 ++++++++++++++++++ deoxys/LICENSE-MIT | 25 +++ deoxys/src/aes_ref/gf256.rs | 25 +++ deoxys/src/aes_ref/mod.rs | 281 +++++++++++++++++++++++++ deoxys/src/deoxys_bc.rs | 200 ++++++++++++++++++ deoxys/src/lib.rs | 135 ++++++++++++ deoxys/src/modes.rs | 296 +++++++++++++++++++++++++++ deoxys/tests/deoxys_ii_128.rs | 367 +++++++++++++++++++++++++++++++++ deoxys/tests/deoxys_ii_256.rs | 375 ++++++++++++++++++++++++++++++++++ 12 files changed, 1955 insertions(+) create mode 100644 deoxys/Cargo.toml create mode 100644 deoxys/LICENSE-APACHE create mode 100644 deoxys/LICENSE-MIT create mode 100644 deoxys/src/aes_ref/gf256.rs create mode 100644 deoxys/src/aes_ref/mod.rs create mode 100644 deoxys/src/deoxys_bc.rs create mode 100644 deoxys/src/lib.rs create mode 100644 deoxys/src/modes.rs create mode 100644 deoxys/tests/deoxys_ii_128.rs create mode 100644 deoxys/tests/deoxys_ii_256.rs diff --git a/Cargo.lock b/Cargo.lock index d5e399c6..f08958d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,6 +242,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "deoxys" +version = "0.1.0" +dependencies = [ + "aead", + "hex", + "subtle", + "zeroize", +] + [[package]] name = "digest" version = "0.9.0" @@ -324,6 +334,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hex-literal" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 6cb65aa3..1074873d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "ccm", "chacha20poly1305", "crypto_box", + "deoxys", "eax", "mgm", "xsalsa20poly1305" diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml new file mode 100644 index 00000000..cb9af60b --- /dev/null +++ b/deoxys/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "deoxys" +version = "0.1.0" +authors = ["RustCrypto Developers, zer0x64"] +edition = "2018" +license = "Apache-2.0 OR MIT" +readme = "README.md" +documentation = "https://docs.rs/deoxys" +repository = "https://github.com/RustCrypto/AEADs" +keywords = ["aead", "deoxys", "deoxys-i", "deoxys-ii"] +categories = ["cryptography", "no-std"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +aead = { version = "0.4", default-features = false } +subtle = "2.4.0" +zeroize = { version = "1", default-features = false } + +[dev-dependencies] +aead = { version = "0.4", features = ["dev"], default-features = false } +hex = "0.4.3" + +[features] +default = ["alloc"] +std = ["aead/std", "alloc"] +alloc = ["aead/alloc"] +heapless = ["aead/heapless"] +stream = ["aead/stream"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/deoxys/LICENSE-APACHE b/deoxys/LICENSE-APACHE new file mode 100644 index 00000000..78173fa2 --- /dev/null +++ b/deoxys/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/deoxys/LICENSE-MIT b/deoxys/LICENSE-MIT new file mode 100644 index 00000000..b7f57116 --- /dev/null +++ b/deoxys/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 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/deoxys/src/aes_ref/gf256.rs b/deoxys/src/aes_ref/gf256.rs new file mode 100644 index 00000000..fd3be0c4 --- /dev/null +++ b/deoxys/src/aes_ref/gf256.rs @@ -0,0 +1,25 @@ +const ROOT: u8 = 0x1b; + +fn mul_by_2(value: u8) -> u8 { + let multiplied_val = value << 1; + if (value >> 7) == 1 { + multiplied_val ^ ROOT + } else { + multiplied_val + } +} + +pub fn mul(a: u8, b: u8) -> u8 { + let mut a = a; + let mut result = 0; + + for i in 0..8 { + if (b >> i) & 1 == 1 { + result = result ^ a; + } + + a = mul_by_2(a); + } + + result +} diff --git a/deoxys/src/aes_ref/mod.rs b/deoxys/src/aes_ref/mod.rs new file mode 100644 index 00000000..1d4c1f1f --- /dev/null +++ b/deoxys/src/aes_ref/mod.rs @@ -0,0 +1,281 @@ +mod gf256; + +use gf256::mul; + +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, +]; + +const RSBOX: [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, +]; + +const MIX_COLUMNS_MATRIX: [[u8; 4]; 4] = [[2, 3, 1, 1], [1, 2, 3, 1], [1, 1, 2, 3], [3, 1, 1, 2]]; + +const MIX_COLUMNS_MATRIX_INV: [[u8; 4]; 4] = [ + [14, 11, 13, 9], + [9, 14, 11, 13], + [13, 9, 14, 11], + [11, 13, 9, 14], +]; + +pub fn add_round_key(block: &mut [u8], key: &[u8]) { + for (x, k) in block.iter_mut().zip(key) { + *x = *x ^ k; + } +} + +pub fn encrypt_round(block: &mut [u8], round_key: &[u8]) { + sub_bytes(block, &SBOX); + shift_rows_left(block); + mix_columns(block, &MIX_COLUMNS_MATRIX); + add_round_key(block, round_key); +} + +pub fn decrypt_round(block: &mut [u8], round_key: &[u8]) { + add_round_key(block, round_key); + mix_columns(block, &MIX_COLUMNS_MATRIX_INV); + shift_rows_right(block); + sub_bytes(block, &RSBOX); +} + +fn sub_bytes(block: &mut [u8], sbox: &[u8; 256]) { + for x in block.iter_mut() { + *x = sbox[*x as usize]; + } +} + +fn shift_rows_left(block: &mut [u8]) { + let tmp = block[0 * 4 + 1]; + block[0 * 4 + 1] = block[1 * 4 + 1]; + block[1 * 4 + 1] = block[2 * 4 + 1]; + block[2 * 4 + 1] = block[3 * 4 + 1]; + block[3 * 4 + 1] = tmp; + + let tmp = block[0 * 4 + 2]; + block[0 * 4 + 2] = block[2 * 4 + 2]; + block[2 * 4 + 2] = tmp; + let tmp = block[1 * 4 + 2]; + block[1 * 4 + 2] = block[3 * 4 + 2]; + block[3 * 4 + 2] = tmp; + + let tmp = block[3 * 4 + 3]; + block[3 * 4 + 3] = block[2 * 4 + 3]; + block[2 * 4 + 3] = block[1 * 4 + 3]; + block[1 * 4 + 3] = block[0 * 4 + 3]; + block[0 * 4 + 3] = tmp; +} + +fn shift_rows_right(block: &mut [u8]) { + let tmp = block[3 * 4 + 1]; + block[3 * 4 + 1] = block[2 * 4 + 1]; + block[2 * 4 + 1] = block[1 * 4 + 1]; + block[1 * 4 + 1] = block[0 * 4 + 1]; + block[0 * 4 + 1] = tmp; + + let tmp = block[0 * 4 + 2]; + block[0 * 4 + 2] = block[2 * 4 + 2]; + block[2 * 4 + 2] = tmp; + let tmp = block[1 * 4 + 2]; + block[1 * 4 + 2] = block[3 * 4 + 2]; + block[3 * 4 + 2] = tmp; + + let tmp = block[0 * 4 + 3]; + block[0 * 4 + 3] = block[1 * 4 + 3]; + block[1 * 4 + 3] = block[2 * 4 + 3]; + block[2 * 4 + 3] = block[3 * 4 + 3]; + block[3 * 4 + 3] = tmp; +} + +fn mix_columns(block: &mut [u8], matrix: &[[u8; 4]; 4]) { + let mut result = [0u8; 16]; + + for i in 0..4 { + for j in 0..4 { + let mut value = 0; + + for k in 0..4 { + value = value ^ mul(block[i * 4 + k], matrix[j][k]) + } + result[i * 4 + j] = value; + } + } + + block.copy_from_slice(&result); +} + +// Test data used comes from here: http://www.herongyang.com/Cryptography/AES-Example-Vector-of-AES-Encryption.html +#[test] +fn test_encrypt_round() { + use core::convert::TryInto; + use hex; + + let mut block: [u8; 16] = hex::decode("00102030405060708090a0b0c0d0e0f0") + .unwrap() + .try_into() + .unwrap(); + let key: [u8; 16] = hex::decode("d6aa74fdd2af72fadaa678f1d6ab76fe") + .unwrap() + .try_into() + .unwrap(); + let result: [u8; 16] = hex::decode("89d810e8855ace682d1843d8cb128fe4") + .unwrap() + .try_into() + .unwrap(); + + encrypt_round(&mut block, &key); + + assert_eq!(&block, &result) +} + +#[test] +fn test_decrypt_round() { + // This test is lazy and based on the assumption that it encryption is correct and you can decrypt, it's good + use core::convert::TryInto; + use hex; + + let mut block: [u8; 16] = hex::decode("00102030405060708090a0b0c0d0e0f0") + .unwrap() + .try_into() + .unwrap(); + let key: [u8; 16] = hex::decode("d6aa74fdd2af72fadaa678f1d6ab76fe") + .unwrap() + .try_into() + .unwrap(); + let result: [u8; 16] = hex::decode("89d810e8855ace682d1843d8cb128fe4") + .unwrap() + .try_into() + .unwrap(); + + let plaintext = block.clone(); + + encrypt_round(&mut block, &key); + + assert_eq!(&block, &result); + + decrypt_round(&mut block, &key); + + assert_eq!(&block, &plaintext); +} + +#[test] +fn test_add_round_key() { + use core::convert::TryInto; + use hex; + + let mut block: [u8; 16] = hex::decode("00112233445566778899aabbccddeeff") + .unwrap() + .try_into() + .unwrap(); + let key: [u8; 16] = hex::decode("000102030405060708090a0b0c0d0e0f") + .unwrap() + .try_into() + .unwrap(); + let result: [u8; 16] = hex::decode("00102030405060708090a0b0c0d0e0f0") + .unwrap() + .try_into() + .unwrap(); + + add_round_key(&mut block, &key); + + assert_eq!(&block, &result) +} + +#[test] +fn test_sub_bytes() { + use core::convert::TryInto; + use hex; + + let mut block: [u8; 16] = hex::decode("00102030405060708090a0b0c0d0e0f0") + .unwrap() + .try_into() + .unwrap(); + let result: [u8; 16] = hex::decode("63cab7040953d051cd60e0e7ba70e18c") + .unwrap() + .try_into() + .unwrap(); + + let initial = block.clone(); + + sub_bytes(&mut block, &SBOX); + + assert_eq!(&block, &result); + + sub_bytes(&mut block, &RSBOX); + + assert_eq!(&block, &initial); +} + +#[test] +fn test_shift_rows() { + use core::convert::TryInto; + use hex; + + let mut block: [u8; 16] = hex::decode("63cab7040953d051cd60e0e7ba70e18c") + .unwrap() + .try_into() + .unwrap(); + let result: [u8; 16] = hex::decode("6353e08c0960e104cd70b751bacad0e7") + .unwrap() + .try_into() + .unwrap(); + + let initial = block.clone(); + + shift_rows_left(&mut block); + + assert_eq!(&block, &result); + + shift_rows_right(&mut block); + + assert_eq!(&block, &initial); +} + +#[test] +fn test_mix_columns() { + use core::convert::TryInto; + use hex; + + let mut block: [u8; 16] = hex::decode("6353e08c0960e104cd70b751bacad0e7") + .unwrap() + .try_into() + .unwrap(); + let result: [u8; 16] = hex::decode("5f72641557f5bc92f7be3b291db9f91a") + .unwrap() + .try_into() + .unwrap(); + + mix_columns(&mut block, &MIX_COLUMNS_MATRIX); + + assert_eq!(&block, &result) +} diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs new file mode 100644 index 00000000..4603ad41 --- /dev/null +++ b/deoxys/src/deoxys_bc.rs @@ -0,0 +1,200 @@ +use aead::{ + consts::{U16, U32, U48}, + generic_array::GenericArray, +}; + +use crate::aes_ref; + +use crate::DeoxysBcType; + +const H_PERM: [u8; 16] = [1, 6, 11, 12, 5, 10, 15, 0, 9, 14, 3, 4, 13, 2, 7, 8]; + +const RCON: [u8; 17] = [ + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, + 0x72, +]; + +pub struct DeoxysBc256; +pub struct DeoxysBc384; + +impl DeoxysBc256 { + fn key_schedule(tweakey: &[u8]) -> [[u8; 16]; 15] { + let mut subkeys: [[u8; 16]; 15] = Default::default(); + let mut tk1 = [0u8; 16]; + let mut tk2 = [0u8; 16]; + + tk2.copy_from_slice(&tweakey[..16]); + tk1.copy_from_slice(&tweakey[16..32]); + + // First key + let rcon = [ + 1, 2, 4, 8, RCON[0], RCON[0], RCON[0], RCON[0], 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + for i in 0..16 { + subkeys[0][i] = tk1[i] ^ tk2[i] ^ rcon[i]; + } + + // Other keys + for (index, subkey) in subkeys[1..].iter_mut().enumerate() { + let rcon = [ + 1, + 2, + 4, + 8, + RCON[index + 1], + RCON[index + 1], + RCON[index + 1], + RCON[index + 1], + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + h_substitution(&mut tk1); + lfsr2(&mut tk2); + h_substitution(&mut tk2); + + for i in 0..16 { + subkey[i] = tk1[i] ^ tk2[i] ^ rcon[i]; + } + } + + subkeys + } +} + +impl DeoxysBcType for DeoxysBc256 { + type KeySize = U16; + type TweakKeySize = U32; + + fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { + let keys: [[u8; 16]; 15] = Self::key_schedule(tweakey); + + aes_ref::add_round_key(block, &keys[0]); + + for k in &keys[1..15] { + aes_ref::encrypt_round(block, k) + } + } + + fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { + let keys: [[u8; 16]; 15] = Self::key_schedule(tweakey); + + for k in keys[1..15].iter().rev() { + aes_ref::decrypt_round(block, k) + } + + aes_ref::add_round_key(block, &keys[0]); + } +} + +impl DeoxysBc384 { + fn key_schedule(tweakey: &[u8]) -> [[u8; 16]; 17] { + let mut subkeys: [[u8; 16]; 17] = Default::default(); + let mut tk1 = [0u8; 16]; + let mut tk2 = [0u8; 16]; + let mut tk3 = [0u8; 16]; + + tk3.copy_from_slice(&tweakey[..16]); + tk2.copy_from_slice(&tweakey[16..32]); + tk1.copy_from_slice(&tweakey[32..]); + + // First key + let rcon = [ + 1, 2, 4, 8, RCON[0], RCON[0], RCON[0], RCON[0], 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + for i in 0..16 { + subkeys[0][i] = tk1[i] ^ tk2[i] ^ tk3[i] ^ rcon[i]; + } + + // Other keys + for (index, subkey) in subkeys[1..].iter_mut().enumerate() { + let rcon = [ + 1, + 2, + 4, + 8, + RCON[index + 1], + RCON[index + 1], + RCON[index + 1], + RCON[index + 1], + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + h_substitution(&mut tk1); + lfsr2(&mut tk2); + h_substitution(&mut tk2); + lfsr3(&mut tk3); + h_substitution(&mut tk3); + + for i in 0..16 { + subkey[i] = tk1[i] ^ tk2[i] ^ tk3[i] ^ rcon[i]; + } + } + + subkeys + } +} + +impl DeoxysBcType for DeoxysBc384 { + type KeySize = U32; + type TweakKeySize = U48; + + fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { + let keys: [[u8; 16]; 17] = Self::key_schedule(tweakey); + + aes_ref::add_round_key(block, &keys[0]); + + for k in &keys[1..17] { + aes_ref::encrypt_round(block, k) + } + } + + fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { + let keys: [[u8; 16]; 17] = Self::key_schedule(tweakey); + + for k in keys[1..17].iter().rev() { + aes_ref::decrypt_round(block, k) + } + + aes_ref::add_round_key(block, &keys[0]); + } +} + +fn h_substitution(tk: &mut [u8]) { + let mut result = [0u8; 16]; + + for i in 0..16 { + result[i] = tk[H_PERM[i] as usize]; + } + + tk.copy_from_slice(&result[..16]); +} + +fn lfsr2(tk: &mut [u8]) { + for x in tk { + let feedback = (*x >> 5) & 1; + *x = x.rotate_left(1); + *x ^= feedback; + } +} + +fn lfsr3(tk: &mut [u8]) { + for x in tk { + let feedback = (*x << 1) & 0x80; + *x = x.rotate_right(1); + *x ^= feedback; + } +} diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs new file mode 100644 index 00000000..f3b061b0 --- /dev/null +++ b/deoxys/src/lib.rs @@ -0,0 +1,135 @@ +//! [`Deoxys`] TODO + +#![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" +)] +#![warn(missing_docs, rust_2018_idioms)] + +pub mod deoxys_bc; +pub mod modes; + +mod aes_ref; + +use core::marker::PhantomData; + +pub use aead; + +use aead::{ + consts::{U0, U16, U8}, + generic_array::{ArrayLength, GenericArray}, + AeadCore, AeadInPlace, Error, NewAead, +}; + +use zeroize::Zeroize; + +pub type DeoxysII128 = Deoxys; +pub type DeoxysII256 = Deoxys; + +pub type Key = GenericArray; +pub type NonceDeoxysI = GenericArray; +pub type NonceDeoxysII = GenericArray; +pub type Tag = GenericArray; + +pub trait DeoxysMode +where + B: DeoxysBcType, +{ + fn encrypt_in_place( + nonce: &[u8], + associated_data: &[u8], + buffer: &mut [u8], + key: &GenericArray, + ) -> [u8; 16]; + + fn decrypt_in_place( + nonce: &[u8], + associated_data: &[u8], + buffer: &mut [u8], + tag: &[u8], + key: &GenericArray, + ) -> Result<(), aead::Error>; +} + +pub trait DeoxysBcType { + type KeySize: ArrayLength; + type TweakKeySize: ArrayLength; + + fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray); + fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray); +} + +pub struct Deoxys +where + M: DeoxysMode, + B: DeoxysBcType, +{ + key: GenericArray, + mode: PhantomData, +} + +impl NewAead for Deoxys +where + M: DeoxysMode, + B: DeoxysBcType, +{ + type KeySize = B::KeySize; + + fn new(key: &Key) -> Self { + Self { + key: key.clone(), + mode: PhantomData, + } + } +} + +impl AeadCore for Deoxys +where + M: DeoxysMode, + B: DeoxysBcType, +{ + type NonceSize = U16; + type TagSize = U16; + type CiphertextOverhead = U0; +} + +impl AeadInPlace for Deoxys +where + M: DeoxysMode, + B: DeoxysBcType, +{ + fn encrypt_in_place_detached( + &self, + nonce: &NonceDeoxysII, + associated_data: &[u8], + buffer: &mut [u8], + ) -> Result { + Ok(Tag::from(M::encrypt_in_place( + nonce.as_slice(), + associated_data, + buffer, + &self.key, + ))) + } + + fn decrypt_in_place_detached( + &self, + nonce: &NonceDeoxysII, + associated_data: &[u8], + buffer: &mut [u8], + tag: &Tag, + ) -> Result<(), Error> { + M::decrypt_in_place(nonce, associated_data, buffer, tag, &self.key) + } +} + +impl Drop for Deoxys +where + M: DeoxysMode, + B: DeoxysBcType, +{ + fn drop(&mut self) { + self.key.as_mut_slice().zeroize(); + } +} diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs new file mode 100644 index 00000000..ce45166e --- /dev/null +++ b/deoxys/src/modes.rs @@ -0,0 +1,296 @@ +use aead::generic_array::GenericArray; +use subtle::ConstantTimeEq; +use zeroize::Zeroize; + +use super::DeoxysBcType; +use super::DeoxysMode; + +const TWEAK_AD_N1: u8 = 0x30; +const TWEAK_AD_N2: u8 = 0x70; +const TWEAK_AD: u8 = 0x20; +const TWEAK_AD_LAST: u8 = 0x60; +const TWEAK_M: u8 = 0x00; +const TWEAK_TAG: u8 = 0x10; +const TWEAK_M_LAST: u8 = 0x40; +const TWEAK_CHKSUM: u8 = 0x50; + +pub struct DeoxysI; + +pub struct DeoxysII; + +impl DeoxysMode for DeoxysII +where + B: DeoxysBcType, +{ + fn encrypt_in_place( + nonce: &[u8], + associated_data: &[u8], + buffer: &mut [u8], + key: &GenericArray, + ) -> [u8; 16] { + let mut tag = [0u8; 16]; + let mut tweakey = GenericArray::::default(); + + tweakey[..key.len()].copy_from_slice(&key); + + // Associated Data + if associated_data.len() > 0 { + tweakey[key.len()] = TWEAK_AD; + + for (index, ad) in associated_data.chunks(16).enumerate() { + // Copy block number + tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + + if ad.len() == 16 { + let mut block = [0u8; 16]; + block.copy_from_slice(ad); + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } else { + // Last block + tweakey[key.len()] = TWEAK_AD_LAST; + + let mut block = [0u8; 16]; + block[0..ad.len()].copy_from_slice(ad); + + block[ad.len()] = 0x80; + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } + } + } + + tweakey[key.len()..].fill(0); + // Message authentication + if buffer.len() > 0 { + tweakey[key.len()] = TWEAK_M; + + for (index, data) in buffer.chunks(16).enumerate() { + // Copy block number + tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + + if data.len() == 16 { + let mut block = [0u8; 16]; + block.copy_from_slice(data); + + //panic!("{:x?}", &tweakey); + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } else { + // Last block + tweakey[key.len()] = TWEAK_M_LAST; + + let mut block = [0u8; 16]; + block[0..data.len()].copy_from_slice(data); + + block[data.len()] = 0x80; + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } + } + } + + tweakey[key.len()] = TWEAK_TAG; + tweakey[key.len() + 1..].copy_from_slice(&nonce[0..15]); + B::encrypt_in_place(&mut tag, &tweakey); + + // Message encryption + if buffer.len() > 0 { + tweakey[key.len()..].copy_from_slice(&tag); + tweakey[key.len()] |= 0x80; + + for (index, data) in buffer.chunks_mut(16).enumerate() { + let index_array = (index as u64).to_be_bytes(); + + // XOR in block numbers + for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { + *t = *t ^ i + } + + if data.len() == 16 { + let mut block = [0u8; 16]; + block[1..].copy_from_slice(&nonce[0..15]); + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in data.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } else { + // Last block + let mut block = [0u8; 16]; + block[1..].copy_from_slice(&nonce[0..15]); + + B::encrypt_in_place(&mut block, &tweakey); + + for (d, b) in data.iter_mut().zip(block.iter()) { + *d = *d ^ b; + } + } + + // XOR out block numbers + for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { + *t = *t ^ i + } + } + } + + // Zeroize tweakey since it contains the key + tweakey.zeroize(); + tag + } + + fn decrypt_in_place( + nonce: &[u8], + associated_data: &[u8], + buffer: &mut [u8], + tag: &[u8], + key: &GenericArray, + ) -> Result<(), aead::Error> { + let mut computed_tag = [0u8; 16]; + let mut tweakey = GenericArray::::default(); + + tweakey[..key.len()].copy_from_slice(&key); + + // Message decryption + if buffer.len() > 0 { + tweakey[key.len()..].copy_from_slice(&tag); + tweakey[key.len()] |= 0x80; + + for (index, data) in buffer.chunks_mut(16).enumerate() { + let index_array = (index as u64).to_be_bytes(); + + // XOR in block numbers + for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { + *t = *t ^ i + } + + if data.len() == 16 { + let mut block = [0u8; 16]; + block[1..].copy_from_slice(&nonce[0..15]); + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in data.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } else { + // Last block + let mut block = [0u8; 16]; + block[1..].copy_from_slice(&nonce[0..15]); + + B::encrypt_in_place(&mut block, &tweakey); + + for (d, b) in data.iter_mut().zip(block.iter()) { + *d = *d ^ b; + } + } + + // XOR out block numbers + for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { + *t = *t ^ i + } + } + } + + tweakey[key.len()..].fill(0); + // Associated Data + if associated_data.len() > 0 { + tweakey[key.len()] = TWEAK_AD; + + for (index, ad) in associated_data.chunks(16).enumerate() { + // Copy block number + tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + + if ad.len() == 16 { + let mut block = [0u8; 16]; + block.copy_from_slice(ad); + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in computed_tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } else { + // Last block + tweakey[key.len()] = TWEAK_AD_LAST; + + let mut block = [0u8; 16]; + block[0..ad.len()].copy_from_slice(ad); + + block[ad.len()] = 0x80; + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in computed_tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } + } + } + + tweakey[key.len()..].fill(0); + // Message authentication + if buffer.len() > 0 { + tweakey[key.len()] = TWEAK_M; + + for (index, data) in buffer.chunks(16).enumerate() { + // Copy block number + tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + + if data.len() == 16 { + let mut block = [0u8; 16]; + block.copy_from_slice(data); + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in computed_tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } else { + // Last block + tweakey[key.len()] = TWEAK_M_LAST; + + let mut block = [0u8; 16]; + block[0..data.len()].copy_from_slice(data); + + block[data.len()] = 0x80; + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in computed_tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } + } + } + + tweakey[key.len()] = TWEAK_TAG; + tweakey[key.len() + 1..].copy_from_slice(&nonce[0..15]); + B::encrypt_in_place(&mut computed_tag, &tweakey); + + // Zeroize tweakey since it contains the key + tweakey.zeroize(); + + if tag.ct_eq(&computed_tag).into() { + Ok(()) + } else { + Err(aead::Error) + } + } +} diff --git a/deoxys/tests/deoxys_ii_128.rs b/deoxys/tests/deoxys_ii_128.rs new file mode 100644 index 00000000..1df8556c --- /dev/null +++ b/deoxys/tests/deoxys_ii_128.rs @@ -0,0 +1,367 @@ +// Uses the official test vectors. +use deoxys::aead::generic_array::GenericArray; +use deoxys::aead::{Aead, NewAead, Payload}; +use deoxys::DeoxysII128; + +#[test] +fn test_deoxys_ii_128_1() { + use core::convert::TryInto; + use hex; + + let plaintext = Vec::new(); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex::decode("97d951f2fd129001483e831f2a6821e9") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_128_2() { + use core::convert::TryInto; + use hex; + + let plaintext = Vec::new(); + + let aad = + hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex::decode("3c197ca5317af5a2b95b178a60553132") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_128_3() { + use core::convert::TryInto; + use hex; + + let plaintext = Vec::new(); + + let aad = + hex::decode("a754f3387be992ffee5bee80e18b151900c6d69ec59786fb12d2eadb0750f82cf5").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex::decode("0a989ed78fa16776cd6c691ea734d874") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_128_4() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = + hex::decode("fa22f8eb84ee6d2388bdb16150232e856cd5fa3508bc589dad16d284208048c9").unwrap(); + + let tag: [u8; 16] = hex::decode("a381b06ef16db99df089e738c3b4064a") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_128_5() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("06ac1756eccece62bd743fa80c299f7baa3872b556130f52265919494bdc136db3").unwrap(); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = + hex::decode("82bf241958b324ed053555d23315d3cc20935527fc970ff34a9f521a95e302136d").unwrap(); + + let tag: [u8; 16] = hex::decode("0eadc8612d5208c491e93005195e9769") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_128_6() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + + let aad = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: [u8; 32] = + hex::decode("9cdb554dfc03bff4feeb94df7736038361a76532b6b5a9c0bdb64a74dee983ff") + .unwrap() + .try_into() + .unwrap(); + + let tag: [u8; 16] = hex::decode("bc1a7b5b8e961e65ceff6877ef9e4a98") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_128_7() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("039ca0907aa315a0d5ba020c84378840023d4ad3ba639787d3f6f46cb446bd63dc").unwrap(); + + let aad = hex::decode("000102030405060708090a0b0c0d0e0f10").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: [u8; 33] = + hex::decode("801f1b81878faca562c8c6c0859b166c2669fbc54b1784be637827b4905729bdf9") + .unwrap() + .try_into() + .unwrap(); + + let tag: [u8; 16] = hex::decode("fe4e9bcd26b96647350eda1e550cc994") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_128_8() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("95330042c3d48419798f9285fbd8d24968d7cee311f637463f8c0a1778f79d758a84e35b7d4a9fde2ed56fa796ad5a0f7004490ed32664ad69069678f53dfd7ee92e00a8ee34776b4d758536dc725ec4d48e2c11d0c5a16e4a2ce6c0e91604adb33a11127f50a46ea3cf5353d88a7a244c0f4337f449e68bf7c31feab02346d3c84c2335b8a06dc7df89dab05b6496fe428133c210c3bac68e18f026daa56662a41c36f9b55787fc1c5382d70b86e33be8555fd924606d2572c30a6ab6da71eccd4744ceb4e729519eef42ef4260db0e015832bfb0e742201fac36c711969a61243b08a77c372e44f76646fd1e9c9c06570447aa30527339baceb1d002e24e6ee3114f5a5daf0062bd372f824a60eebd74afc4fecffe74541933411b575295e27891abc71fc0e9597f65fc51be21962eea0aec96214b40a1a8ef32329df02a8b0ef038c48a1d5b2529ed01a820a6f262488de7791b07c5f941126be7893f7dadfb9639892264bc01af40402aa87a44df1754ce4e17226c41a8e3f05e4883d6ef4511e96378067f455f3a7275215622bfc71bb4db398b03b08e4bf6c54b2b6396c5b501fa26782fc36ad22044f5eb6a8f83efc8850d70ae4525d4e798f2aa1894621803394415f34cd4d002a2b3d393efa7d57f687b753830ff04798c240f05f581ce706f7d151417f09f17174cb87eff0e042c1860342b4ace069e1691e092e3").unwrap(); + + let aad = hex::decode("5b187979e145d7b5beebbc0e689e759a027b5588059419b06b1afe4224f8f56ecccb2bfe2cef9ecf103eb382172320a17c19dce14a3e38030d3443697845b992ff1e871c02e788d7b40264f52ef0733791dc82dacdfa987685b33423bed0c05e0a65bce48ce1006d16628ea21b4390e75be72e043f299d6290289f90007474bf4e9ffb6c774d762afec8f3a01b2db545611772c32386fe6c7332125f0750c4987988d1e0e727c3c295bc743a34d3196d5e2d14f11bf2c884265ba901e77144a4b5a77864ad082e945727786f376bfcae99048ee7a994a2ea87584cd2e7e83ffd0310cf9cdb2cff5cf8c9cc09c94becb3f37fb9b071a76ee7ae115a49f0d95b1a9ec97e5b62bcae2c3cf47a3d2cb1b3d3dcd1729c33266ad7b0899654949a6f09086b74297cb48227e566e1f401109495ea05d636a5025104cd04c2a3c59f396b858f7f025825baf667b29b4f7f692f3a6c0c8956575a8dd183d1d03bd372c214e005d6e1090d89f2d950b8ac856465943568bc320602f52bf67d30f0d8ec7a9550dcdef99a43404a6d32d8f6b537b3eed568e32ab7ee63e16be63009702995d4d9300114638ba4c874f02039f3f67e2df64946030edef1930f30d4e6b9ca95887539d1af2036c8f5cf129c54d5734224e09b3daab5fb0e74c848af70a49c1499a5e56bc5eea90395df5bfd3e84a1c0a5be02dd3f2e2353e5522aeadaafdbf44444").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext= + hex::decode("b8eddddb8d0042bb42fdf675bae285e504b90e4d73e02f99f790b2ffe7815dba40fe4c7bc886ce44505f6ac53d3bba5d3c73efd98daf4b7a5af250a5d100ff5558c211cb03a28d9519502d7d0fc85a6d73e618feb6b503af12cb0330bb9c5743b19996174a84dbf5bac38d10d207067e4ab211a62ad0f85dd8245dfb077443017b7847996fe7ed547b9e02051f1cbe39128e21486b4f73399d0a50d9a1111bed11ebb0547454d0a922633c83f0bba784571f63f55dc33f92e09862471945312d99e40b4ed739556f102afd43055497739a4b22d107e867cc652a5d96974ff785976c82bc1ff89731c780e84a257bb885cd23e00a7bdc7a68e0a1668516fb972721a777429c76cfd4adb45afa554d44a8932d133af8c9254fd3fef2bd0bb65801f2ffbf752f14eaa783e53c2342f021863598e88b20232a0c44e963dd8943e9a54213ffbb174b90e38b55aa9b223e9596acb1517ff21b7458b7694488047797c521883c00762e7227f1e8a5e3f11a43962bdccde8dc4009aef7628a96efa8793d6080982f9b00a7b97d93fd5928702e78427f34eb434e2286de00216b405c36105dc2e8dae68c3342a23274b32a6d2d8ac85239a8fa2947126f505a517fb18847104b21b0326b7fd67efb54f5d0b12b311ef998ebaf14939b7cdb44b35435eedf1ba5b07eea99533f1857b8cc1538290a8dbd44ca696c6bc2f1105451032a650c") + .unwrap(); + + let tag: [u8; 16] = hex::decode("e68a5de27beaeb6472611dfa9783602a") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} diff --git a/deoxys/tests/deoxys_ii_256.rs b/deoxys/tests/deoxys_ii_256.rs new file mode 100644 index 00000000..fa9ba0a2 --- /dev/null +++ b/deoxys/tests/deoxys_ii_256.rs @@ -0,0 +1,375 @@ +// Uses the official test vectors. +use deoxys::aead::generic_array::GenericArray; +use deoxys::aead::{Aead, NewAead, Payload}; +use deoxys::DeoxysII256; + +#[test] +fn test_deoxys_ii_256_1() { + use core::convert::TryInto; + use hex; + + let plaintext = Vec::new(); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = + hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex::decode("2b97bd77712f0cde975309959dfe1d7c") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_256_2() { + use core::convert::TryInto; + use hex; + + let plaintext = Vec::new(); + + let aad = + hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = + hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex::decode("54708ae5565a71f147bdb94d7ba3aed7") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_256_3() { + use core::convert::TryInto; + use hex; + + let plaintext = Vec::new(); + + let aad = + hex::decode("f495c9c03d29989695d98ff5d430650125805c1e0576d06f26cbda42b1f82238b8").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = + hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex::decode("3277689dc4208cc1ff59d15434a1baf1") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_256_4() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = + hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = + hex::decode("9da20db1c2781f6669257d87e2a4d9be1970f7581bef2c995e1149331e5e8cc1").unwrap(); + + let tag: [u8; 16] = hex::decode("92ce3aec3a4b72ff9eab71c2a93492fa") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_256_5() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("15cd77732f9d0c4c6e581ef400876ad9188c5b8850ebd38224da95d7cdc99f7acc").unwrap(); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = + hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: Vec = + hex::decode("e5ffd2abc5b459a73667756eda6443ede86c0883fc51dd75d22bb14992c684618c").unwrap(); + + let tag: [u8; 16] = hex::decode("5fa78d57308f19d0252072ee39df5ecc") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_256_6() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + + let aad = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = + hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: [u8; 32] = + hex::decode("109f8a168b36dfade02628a9e129d5257f03cc7912aefa79729b67b186a2b08f") + .unwrap() + .try_into() + .unwrap(); + + let tag: [u8; 16] = hex::decode("6549f9bf10acba0a451dbb2484a60d90") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_256_7() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("422857fb165af0a35c03199fb895604dca9cea6d788954962c419e0d5c225c0327").unwrap(); + + let aad = hex::decode("000102030405060708090a0b0c0d0e0f10").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = + hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext: [u8; 33] = + hex::decode("7d772203fa38be296d8d20d805163130c69aba8cb16ed845c2296c61a8f34b394e") + .unwrap() + .try_into() + .unwrap(); + + let tag: [u8; 16] = hex::decode("0b3f10e3933c78190b24b33008bf80e9") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_ii_256_8() { + use core::convert::TryInto; + use hex; + + let plaintext = + hex::decode("83dab23b1379e090755c99079cfe918cb737e989f2d720ccaff493a744927644fec3653211fa75306a83486e5c34ecfe63870c97251a73e4b9033ae374809711b211ed5d293a592e466a81170f1d85750b5ca025ccd4579947edbae9ec132bfb1a7233ad79fae30006a6699f143893861b975226ed9d3cfb8a240be232fbf4e83755d59d20bc2faa2ea5e5b0428427485cca5e76a89fe32bdd59ab4177ad7cb1899c101e3c4f7535129591390ebdf30140846078b13867bbb2efd6cf434afe356eb18d716b21fd664c26c908496534bf2cde6d6b897799016594fb6d9f830ae5f44ccec26d42ff0d1a21b80cdbe8c8c170a5f766fad884abcc781b5b8ebc0f559bfeaa4557b04d977d51411a7f47bf437d0280cf9f92bc4f9cd6226337a492320851955adae2cafea22a89c3132dd252e4728328eda05555dff3241404341b8aa502d45c456113af42a8e91a85e4b4e9555028982ec3d144722af0eb04a6d3b8127c3040629de53f5fd187048198e8f8e8cc857afcbae45c693fec12fc2149d5e7587d0121b1717d0147f6979f75e8f085293f705c3399a6cc8df7057bf481e6c374edf0a0af7479f858045357b7fe21021c3fabdaf012652bf2e5db257bd9490ce637a81477bd3f9814a2198fdb9afa9344321f2393798670e588c47a1924d592cda3eb5a96754dfd92d87ee1ffa9d4ee586c85d7518c5d2db57d0451c33de0").unwrap(); + + let aad = hex::decode("3290bb8441279dc6083a43e9048c3dc08966ab30d7a6b35759e7a13339f124918f3b5ab1affa65e6c0e3680eb33a6ec82424ab1ce5a40b8654e13d845c29b13896a1466a75fc875acba4527ded37ed00c600a357c9a6e586c74cf3d85cd3258c813218f319d12b82480e5124ff19ec00bda1fbb8bd25eeb3de9fcbf3296deba250caf7e9f4ef0be1918e24221dd0be888c59c166ad761d7b58462a1b1d44b04265b45827172c133dd5b6c870b9af7b21368d12a88f4efa1751047543d584382d9ec22e7550d50ecddba27d1f65453f1f3398de54ee8c1f4ac8e16f5523d89641e99a632380af0f0b1e6b0e192ec29bf1d8714978ff9fbfb93604142393e9a82c3aaebbbe15e3b4e5cfd18bdfe309315c9f9f830deebe2edcdc24f8eca90fda49f6646e789c5041fb5be933fa843278e95f3a54f8eb41f14777ea949d5ea442b01249e64816151a325769e264ed4acd5c3f21700ca755d5bc0c2c5f9453419510bc74f2d71621dcecb9efc9c24791b4bb560fb70a8231521d6560af89d8d50144d9c080863f043781153bcd59030e60bd17a6d7aa083211b67b581fa4f74cce4d030d1e8f9429fd725c110040d41eb6989ffb1595c72cbe3c9b78a8ab80d71a6a5283da77b89cae295bb13c14fbe466b617f4da8ad60b085e2ea153f6713ae0046aa31e0ba44e43ef36a111bf05c073a4e3624cd35f63a546f9142b35aa81b8826d").unwrap(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = + hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = GenericArray::from_slice(&key); + + let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = GenericArray::from_slice(&nonce); + + let ciphertext= + hex::decode("88294fcef65a1bdfd7baaa472816c64ef5bef2622b88c1ec5a739396157ef4935f3aa76449e391c32da28ee2857f399ac3dd95aed30cfb26cc0063cd4cd8f7431108176fbf370123856662b000a8348e5925fbb97c9ec0c737758330a7983f06b51590c1d2f5e5faaf0eb58e34e19e5fc85cec03d3926dd46a79ba7026e83dec24e07484c9103dd0cdb0edb505500caca5e1d5dbc71348cf00648821488ebaab7f9d84bbbf91b3c521dbef30110e7bd94f8dad5ab8e0cc5411ca9682d210d5d80c0c4bdbba8181789a4273d6deb80899fdcd976ca6f3a9770b54305f586a04256cfbeb4c11254e88559f294db3b9a94b80ab9f9a02cb4c0748de0af7818685521691dba5738be546dba13a56016fb8635af9dff50f25d1b17ad21707db2640a76a741e65e559b2afaaec0f37e18436bf02008f84dbd7b2698687a22376b65dc7524fca8a28709eee3f3caee3b28ed1173d1e08ee849e2ca63d2c90d555755c8fbafd5d2f4b37f06a1dbd6852ee2ffcfe79d510152e98fc4f3094f740a4aede9ee378b606d34576776bf5f1269f5385a84b3928433bfca177550ccfcd22cd0331bbc595e38c2758b2662476fa66354c4e84c7b360405aa3f5b2a48621bdca1a90c69b21789c91b5b8c568e3c741d99e22f6d7e26f2abed045f1d578b782ab4a5cf2af636d842b3012e180e4b045d8d15b057b69c92398a517053daf9be7c2935e") + .unwrap(); + + let tag: [u8; 16] = hex::decode("a616f0c218e18b526cf2a3f8c115e262") + .unwrap() + .try_into() + .unwrap(); + + let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} From ae85d52022bcc857cf57a81a9c4165766c0e3d17 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Sat, 15 May 2021 12:06:09 -0400 Subject: [PATCH 02/24] Replaced hex with hex-literal --- Cargo.lock | 22 ++--- deoxys/Cargo.toml | 2 +- deoxys/src/aes_ref/mod.rs | 113 ++++++++--------------- deoxys/tests/deoxys_ii_128.rs | 153 ++++++++++--------------------- deoxys/tests/deoxys_ii_256.rs | 163 ++++++++++------------------------ 5 files changed, 140 insertions(+), 313 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f08958d2..2819a391 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,7 +36,7 @@ dependencies = [ "cipher", "ctr", "ghash", - "hex-literal", + "hex-literal 0.2.1", "subtle", "zeroize", ] @@ -66,7 +66,7 @@ dependencies = [ "crypto-mac", "ctr", "dbl", - "hex-literal", + "hex-literal 0.2.1", "pmac", "zeroize", ] @@ -114,7 +114,7 @@ dependencies = [ "aead", "aes", "cipher", - "hex-literal", + "hex-literal 0.2.1", "subtle", ] @@ -247,7 +247,7 @@ name = "deoxys" version = "0.1.0" dependencies = [ "aead", - "hex", + "hex-literal 0.3.1", "subtle", "zeroize", ] @@ -334,12 +334,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "hex-literal" version = "0.2.1" @@ -350,6 +344,12 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "hex-literal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" + [[package]] name = "hex-literal-impl" version = "0.2.2" @@ -380,7 +380,7 @@ version = "0.4.1" dependencies = [ "aead", "cipher", - "hex-literal", + "hex-literal 0.2.1", "kuznyechik", "subtle", ] diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index cb9af60b..ce1da1f5 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -19,7 +19,7 @@ zeroize = { version = "1", default-features = false } [dev-dependencies] aead = { version = "0.4", features = ["dev"], default-features = false } -hex = "0.4.3" +hex-literal = "0.3.1" [features] default = ["alloc"] diff --git a/deoxys/src/aes_ref/mod.rs b/deoxys/src/aes_ref/mod.rs index 1d4c1f1f..8327f3b4 100644 --- a/deoxys/src/aes_ref/mod.rs +++ b/deoxys/src/aes_ref/mod.rs @@ -137,21 +137,13 @@ fn mix_columns(block: &mut [u8], matrix: &[[u8; 4]; 4]) { // Test data used comes from here: http://www.herongyang.com/Cryptography/AES-Example-Vector-of-AES-Encryption.html #[test] fn test_encrypt_round() { - use core::convert::TryInto; - use hex; - - let mut block: [u8; 16] = hex::decode("00102030405060708090a0b0c0d0e0f0") - .unwrap() - .try_into() - .unwrap(); - let key: [u8; 16] = hex::decode("d6aa74fdd2af72fadaa678f1d6ab76fe") - .unwrap() - .try_into() - .unwrap(); - let result: [u8; 16] = hex::decode("89d810e8855ace682d1843d8cb128fe4") - .unwrap() - .try_into() - .unwrap(); + use hex_literal::hex; + + let mut block: [u8; 16] = hex!("00102030405060708090a0b0c0d0e0f0"); + + let key: [u8; 16] = hex!("d6aa74fdd2af72fadaa678f1d6ab76fe"); + + let result: [u8; 16] = hex!("89d810e8855ace682d1843d8cb128fe4"); encrypt_round(&mut block, &key); @@ -161,21 +153,13 @@ fn test_encrypt_round() { #[test] fn test_decrypt_round() { // This test is lazy and based on the assumption that it encryption is correct and you can decrypt, it's good - use core::convert::TryInto; - use hex; - - let mut block: [u8; 16] = hex::decode("00102030405060708090a0b0c0d0e0f0") - .unwrap() - .try_into() - .unwrap(); - let key: [u8; 16] = hex::decode("d6aa74fdd2af72fadaa678f1d6ab76fe") - .unwrap() - .try_into() - .unwrap(); - let result: [u8; 16] = hex::decode("89d810e8855ace682d1843d8cb128fe4") - .unwrap() - .try_into() - .unwrap(); + use hex_literal::hex; + + let mut block: [u8; 16] = hex!("00102030405060708090a0b0c0d0e0f0"); + + let key: [u8; 16] = hex!("d6aa74fdd2af72fadaa678f1d6ab76fe"); + + let result: [u8; 16] = hex!("89d810e8855ace682d1843d8cb128fe4"); let plaintext = block.clone(); @@ -190,21 +174,13 @@ fn test_decrypt_round() { #[test] fn test_add_round_key() { - use core::convert::TryInto; - use hex; - - let mut block: [u8; 16] = hex::decode("00112233445566778899aabbccddeeff") - .unwrap() - .try_into() - .unwrap(); - let key: [u8; 16] = hex::decode("000102030405060708090a0b0c0d0e0f") - .unwrap() - .try_into() - .unwrap(); - let result: [u8; 16] = hex::decode("00102030405060708090a0b0c0d0e0f0") - .unwrap() - .try_into() - .unwrap(); + use hex_literal::hex; + + let mut block: [u8; 16] = hex!("00112233445566778899aabbccddeeff"); + + let key: [u8; 16] = hex!("000102030405060708090a0b0c0d0e0f"); + + let result: [u8; 16] = hex!("00102030405060708090a0b0c0d0e0f0"); add_round_key(&mut block, &key); @@ -213,17 +189,11 @@ fn test_add_round_key() { #[test] fn test_sub_bytes() { - use core::convert::TryInto; - use hex; - - let mut block: [u8; 16] = hex::decode("00102030405060708090a0b0c0d0e0f0") - .unwrap() - .try_into() - .unwrap(); - let result: [u8; 16] = hex::decode("63cab7040953d051cd60e0e7ba70e18c") - .unwrap() - .try_into() - .unwrap(); + use hex_literal::hex; + + let mut block: [u8; 16] = hex!("00102030405060708090a0b0c0d0e0f0"); + + let result: [u8; 16] = hex!("63cab7040953d051cd60e0e7ba70e18c"); let initial = block.clone(); @@ -238,17 +208,11 @@ fn test_sub_bytes() { #[test] fn test_shift_rows() { - use core::convert::TryInto; - use hex; - - let mut block: [u8; 16] = hex::decode("63cab7040953d051cd60e0e7ba70e18c") - .unwrap() - .try_into() - .unwrap(); - let result: [u8; 16] = hex::decode("6353e08c0960e104cd70b751bacad0e7") - .unwrap() - .try_into() - .unwrap(); + use hex_literal::hex; + + let mut block: [u8; 16] = hex!("63cab7040953d051cd60e0e7ba70e18c"); + + let result: [u8; 16] = hex!("6353e08c0960e104cd70b751bacad0e7"); let initial = block.clone(); @@ -263,17 +227,10 @@ fn test_shift_rows() { #[test] fn test_mix_columns() { - use core::convert::TryInto; - use hex; - - let mut block: [u8; 16] = hex::decode("6353e08c0960e104cd70b751bacad0e7") - .unwrap() - .try_into() - .unwrap(); - let result: [u8; 16] = hex::decode("5f72641557f5bc92f7be3b291db9f91a") - .unwrap() - .try_into() - .unwrap(); + use hex_literal::hex; + + let mut block: [u8; 16] = hex!("6353e08c0960e104cd70b751bacad0e7"); + let result: [u8; 16] = hex!("5f72641557f5bc92f7be3b291db9f91a"); mix_columns(&mut block, &MIX_COLUMNS_MATRIX); diff --git a/deoxys/tests/deoxys_ii_128.rs b/deoxys/tests/deoxys_ii_128.rs index 1df8556c..9ec38bce 100644 --- a/deoxys/tests/deoxys_ii_128.rs +++ b/deoxys/tests/deoxys_ii_128.rs @@ -3,11 +3,10 @@ use deoxys::aead::generic_array::GenericArray; use deoxys::aead::{Aead, NewAead, Payload}; use deoxys::DeoxysII128; +use hex_literal::hex; + #[test] fn test_deoxys_ii_128_1() { - use core::convert::TryInto; - use hex; - let plaintext = Vec::new(); let aad = Vec::new(); @@ -17,18 +16,15 @@ fn test_deoxys_ii_128_1() { aad: &aad, }; - let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: Vec = Vec::new(); - let tag: [u8; 16] = hex::decode("97d951f2fd129001483e831f2a6821e9") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("97d951f2fd129001483e831f2a6821e9"); let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); @@ -48,31 +44,24 @@ fn test_deoxys_ii_128_1() { #[test] fn test_deoxys_ii_128_2() { - use core::convert::TryInto; - use hex; - let plaintext = Vec::new(); - let aad = - hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + let aad = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: Vec = Vec::new(); - let tag: [u8; 16] = hex::decode("3c197ca5317af5a2b95b178a60553132") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("3c197ca5317af5a2b95b178a60553132"); let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); @@ -92,31 +81,24 @@ fn test_deoxys_ii_128_2() { #[test] fn test_deoxys_ii_128_3() { - use core::convert::TryInto; - use hex; - let plaintext = Vec::new(); - let aad = - hex::decode("a754f3387be992ffee5bee80e18b151900c6d69ec59786fb12d2eadb0750f82cf5").unwrap(); + let aad = hex!("a754f3387be992ffee5bee80e18b151900c6d69ec59786fb12d2eadb0750f82cf5"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: Vec = Vec::new(); - let tag: [u8; 16] = hex::decode("0a989ed78fa16776cd6c691ea734d874") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("0a989ed78fa16776cd6c691ea734d874"); let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); @@ -136,11 +118,7 @@ fn test_deoxys_ii_128_3() { #[test] fn test_deoxys_ii_128_4() { - use core::convert::TryInto; - use hex; - - let plaintext = - hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + let plaintext = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); let aad = Vec::new(); @@ -149,19 +127,15 @@ fn test_deoxys_ii_128_4() { aad: &aad, }; - let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); - let ciphertext: Vec = - hex::decode("fa22f8eb84ee6d2388bdb16150232e856cd5fa3508bc589dad16d284208048c9").unwrap(); + let ciphertext = hex!("fa22f8eb84ee6d2388bdb16150232e856cd5fa3508bc589dad16d284208048c9"); - let tag: [u8; 16] = hex::decode("a381b06ef16db99df089e738c3b4064a") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("a381b06ef16db99df089e738c3b4064a"); let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); @@ -176,16 +150,12 @@ fn test_deoxys_ii_128_4() { let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } #[test] fn test_deoxys_ii_128_5() { - use core::convert::TryInto; - use hex; - - let plaintext = - hex::decode("06ac1756eccece62bd743fa80c299f7baa3872b556130f52265919494bdc136db3").unwrap(); + let plaintext = hex!("06ac1756eccece62bd743fa80c299f7baa3872b556130f52265919494bdc136db3"); let aad = Vec::new(); @@ -194,19 +164,15 @@ fn test_deoxys_ii_128_5() { aad: &aad, }; - let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); - let ciphertext: Vec = - hex::decode("82bf241958b324ed053555d23315d3cc20935527fc970ff34a9f521a95e302136d").unwrap(); + let ciphertext = hex!("82bf241958b324ed053555d23315d3cc20935527fc970ff34a9f521a95e302136d"); - let tag: [u8; 16] = hex::decode("0eadc8612d5208c491e93005195e9769") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("0eadc8612d5208c491e93005195e9769"); let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); @@ -221,40 +187,30 @@ fn test_deoxys_ii_128_5() { let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } #[test] fn test_deoxys_ii_128_6() { - use core::convert::TryInto; - use hex; - - let plaintext = - hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + let plaintext = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); - let aad = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap(); + let aad = hex!("000102030405060708090a0b0c0d0e0f"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: [u8; 32] = - hex::decode("9cdb554dfc03bff4feeb94df7736038361a76532b6b5a9c0bdb64a74dee983ff") - .unwrap() - .try_into() - .unwrap(); + hex!("9cdb554dfc03bff4feeb94df7736038361a76532b6b5a9c0bdb64a74dee983ff"); - let tag: [u8; 16] = hex::decode("bc1a7b5b8e961e65ceff6877ef9e4a98") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("bc1a7b5b8e961e65ceff6877ef9e4a98"); let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); @@ -269,40 +225,30 @@ fn test_deoxys_ii_128_6() { let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } #[test] fn test_deoxys_ii_128_7() { - use core::convert::TryInto; - use hex; + let plaintext = hex!("039ca0907aa315a0d5ba020c84378840023d4ad3ba639787d3f6f46cb446bd63dc"); - let plaintext = - hex::decode("039ca0907aa315a0d5ba020c84378840023d4ad3ba639787d3f6f46cb446bd63dc").unwrap(); - - let aad = hex::decode("000102030405060708090a0b0c0d0e0f10").unwrap(); + let aad = hex!("000102030405060708090a0b0c0d0e0f10"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: [u8; 33] = - hex::decode("801f1b81878faca562c8c6c0859b166c2669fbc54b1784be637827b4905729bdf9") - .unwrap() - .try_into() - .unwrap(); + hex!("801f1b81878faca562c8c6c0859b166c2669fbc54b1784be637827b4905729bdf9"); - let tag: [u8; 16] = hex::decode("fe4e9bcd26b96647350eda1e550cc994") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("fe4e9bcd26b96647350eda1e550cc994"); let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); @@ -317,38 +263,31 @@ fn test_deoxys_ii_128_7() { let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } #[test] fn test_deoxys_ii_128_8() { - use core::convert::TryInto; - use hex; - let plaintext = - hex::decode("95330042c3d48419798f9285fbd8d24968d7cee311f637463f8c0a1778f79d758a84e35b7d4a9fde2ed56fa796ad5a0f7004490ed32664ad69069678f53dfd7ee92e00a8ee34776b4d758536dc725ec4d48e2c11d0c5a16e4a2ce6c0e91604adb33a11127f50a46ea3cf5353d88a7a244c0f4337f449e68bf7c31feab02346d3c84c2335b8a06dc7df89dab05b6496fe428133c210c3bac68e18f026daa56662a41c36f9b55787fc1c5382d70b86e33be8555fd924606d2572c30a6ab6da71eccd4744ceb4e729519eef42ef4260db0e015832bfb0e742201fac36c711969a61243b08a77c372e44f76646fd1e9c9c06570447aa30527339baceb1d002e24e6ee3114f5a5daf0062bd372f824a60eebd74afc4fecffe74541933411b575295e27891abc71fc0e9597f65fc51be21962eea0aec96214b40a1a8ef32329df02a8b0ef038c48a1d5b2529ed01a820a6f262488de7791b07c5f941126be7893f7dadfb9639892264bc01af40402aa87a44df1754ce4e17226c41a8e3f05e4883d6ef4511e96378067f455f3a7275215622bfc71bb4db398b03b08e4bf6c54b2b6396c5b501fa26782fc36ad22044f5eb6a8f83efc8850d70ae4525d4e798f2aa1894621803394415f34cd4d002a2b3d393efa7d57f687b753830ff04798c240f05f581ce706f7d151417f09f17174cb87eff0e042c1860342b4ace069e1691e092e3").unwrap(); + hex!("95330042c3d48419798f9285fbd8d24968d7cee311f637463f8c0a1778f79d758a84e35b7d4a9fde2ed56fa796ad5a0f7004490ed32664ad69069678f53dfd7ee92e00a8ee34776b4d758536dc725ec4d48e2c11d0c5a16e4a2ce6c0e91604adb33a11127f50a46ea3cf5353d88a7a244c0f4337f449e68bf7c31feab02346d3c84c2335b8a06dc7df89dab05b6496fe428133c210c3bac68e18f026daa56662a41c36f9b55787fc1c5382d70b86e33be8555fd924606d2572c30a6ab6da71eccd4744ceb4e729519eef42ef4260db0e015832bfb0e742201fac36c711969a61243b08a77c372e44f76646fd1e9c9c06570447aa30527339baceb1d002e24e6ee3114f5a5daf0062bd372f824a60eebd74afc4fecffe74541933411b575295e27891abc71fc0e9597f65fc51be21962eea0aec96214b40a1a8ef32329df02a8b0ef038c48a1d5b2529ed01a820a6f262488de7791b07c5f941126be7893f7dadfb9639892264bc01af40402aa87a44df1754ce4e17226c41a8e3f05e4883d6ef4511e96378067f455f3a7275215622bfc71bb4db398b03b08e4bf6c54b2b6396c5b501fa26782fc36ad22044f5eb6a8f83efc8850d70ae4525d4e798f2aa1894621803394415f34cd4d002a2b3d393efa7d57f687b753830ff04798c240f05f581ce706f7d151417f09f17174cb87eff0e042c1860342b4ace069e1691e092e3"); - let aad = hex::decode("5b187979e145d7b5beebbc0e689e759a027b5588059419b06b1afe4224f8f56ecccb2bfe2cef9ecf103eb382172320a17c19dce14a3e38030d3443697845b992ff1e871c02e788d7b40264f52ef0733791dc82dacdfa987685b33423bed0c05e0a65bce48ce1006d16628ea21b4390e75be72e043f299d6290289f90007474bf4e9ffb6c774d762afec8f3a01b2db545611772c32386fe6c7332125f0750c4987988d1e0e727c3c295bc743a34d3196d5e2d14f11bf2c884265ba901e77144a4b5a77864ad082e945727786f376bfcae99048ee7a994a2ea87584cd2e7e83ffd0310cf9cdb2cff5cf8c9cc09c94becb3f37fb9b071a76ee7ae115a49f0d95b1a9ec97e5b62bcae2c3cf47a3d2cb1b3d3dcd1729c33266ad7b0899654949a6f09086b74297cb48227e566e1f401109495ea05d636a5025104cd04c2a3c59f396b858f7f025825baf667b29b4f7f692f3a6c0c8956575a8dd183d1d03bd372c214e005d6e1090d89f2d950b8ac856465943568bc320602f52bf67d30f0d8ec7a9550dcdef99a43404a6d32d8f6b537b3eed568e32ab7ee63e16be63009702995d4d9300114638ba4c874f02039f3f67e2df64946030edef1930f30d4e6b9ca95887539d1af2036c8f5cf129c54d5734224e09b3daab5fb0e74c848af70a49c1499a5e56bc5eea90395df5bfd3e84a1c0a5be02dd3f2e2353e5522aeadaafdbf44444").unwrap(); + let aad = hex!("5b187979e145d7b5beebbc0e689e759a027b5588059419b06b1afe4224f8f56ecccb2bfe2cef9ecf103eb382172320a17c19dce14a3e38030d3443697845b992ff1e871c02e788d7b40264f52ef0733791dc82dacdfa987685b33423bed0c05e0a65bce48ce1006d16628ea21b4390e75be72e043f299d6290289f90007474bf4e9ffb6c774d762afec8f3a01b2db545611772c32386fe6c7332125f0750c4987988d1e0e727c3c295bc743a34d3196d5e2d14f11bf2c884265ba901e77144a4b5a77864ad082e945727786f376bfcae99048ee7a994a2ea87584cd2e7e83ffd0310cf9cdb2cff5cf8c9cc09c94becb3f37fb9b071a76ee7ae115a49f0d95b1a9ec97e5b62bcae2c3cf47a3d2cb1b3d3dcd1729c33266ad7b0899654949a6f09086b74297cb48227e566e1f401109495ea05d636a5025104cd04c2a3c59f396b858f7f025825baf667b29b4f7f692f3a6c0c8956575a8dd183d1d03bd372c214e005d6e1090d89f2d950b8ac856465943568bc320602f52bf67d30f0d8ec7a9550dcdef99a43404a6d32d8f6b537b3eed568e32ab7ee63e16be63009702995d4d9300114638ba4c874f02039f3f67e2df64946030edef1930f30d4e6b9ca95887539d1af2036c8f5cf129c54d5734224e09b3daab5fb0e74c848af70a49c1499a5e56bc5eea90395df5bfd3e84a1c0a5be02dd3f2e2353e5522aeadaafdbf44444"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = hex::decode("101112131415161718191a1b1c1d1e1f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext= - hex::decode("b8eddddb8d0042bb42fdf675bae285e504b90e4d73e02f99f790b2ffe7815dba40fe4c7bc886ce44505f6ac53d3bba5d3c73efd98daf4b7a5af250a5d100ff5558c211cb03a28d9519502d7d0fc85a6d73e618feb6b503af12cb0330bb9c5743b19996174a84dbf5bac38d10d207067e4ab211a62ad0f85dd8245dfb077443017b7847996fe7ed547b9e02051f1cbe39128e21486b4f73399d0a50d9a1111bed11ebb0547454d0a922633c83f0bba784571f63f55dc33f92e09862471945312d99e40b4ed739556f102afd43055497739a4b22d107e867cc652a5d96974ff785976c82bc1ff89731c780e84a257bb885cd23e00a7bdc7a68e0a1668516fb972721a777429c76cfd4adb45afa554d44a8932d133af8c9254fd3fef2bd0bb65801f2ffbf752f14eaa783e53c2342f021863598e88b20232a0c44e963dd8943e9a54213ffbb174b90e38b55aa9b223e9596acb1517ff21b7458b7694488047797c521883c00762e7227f1e8a5e3f11a43962bdccde8dc4009aef7628a96efa8793d6080982f9b00a7b97d93fd5928702e78427f34eb434e2286de00216b405c36105dc2e8dae68c3342a23274b32a6d2d8ac85239a8fa2947126f505a517fb18847104b21b0326b7fd67efb54f5d0b12b311ef998ebaf14939b7cdb44b35435eedf1ba5b07eea99533f1857b8cc1538290a8dbd44ca696c6bc2f1105451032a650c") - .unwrap(); + hex!("b8eddddb8d0042bb42fdf675bae285e504b90e4d73e02f99f790b2ffe7815dba40fe4c7bc886ce44505f6ac53d3bba5d3c73efd98daf4b7a5af250a5d100ff5558c211cb03a28d9519502d7d0fc85a6d73e618feb6b503af12cb0330bb9c5743b19996174a84dbf5bac38d10d207067e4ab211a62ad0f85dd8245dfb077443017b7847996fe7ed547b9e02051f1cbe39128e21486b4f73399d0a50d9a1111bed11ebb0547454d0a922633c83f0bba784571f63f55dc33f92e09862471945312d99e40b4ed739556f102afd43055497739a4b22d107e867cc652a5d96974ff785976c82bc1ff89731c780e84a257bb885cd23e00a7bdc7a68e0a1668516fb972721a777429c76cfd4adb45afa554d44a8932d133af8c9254fd3fef2bd0bb65801f2ffbf752f14eaa783e53c2342f021863598e88b20232a0c44e963dd8943e9a54213ffbb174b90e38b55aa9b223e9596acb1517ff21b7458b7694488047797c521883c00762e7227f1e8a5e3f11a43962bdccde8dc4009aef7628a96efa8793d6080982f9b00a7b97d93fd5928702e78427f34eb434e2286de00216b405c36105dc2e8dae68c3342a23274b32a6d2d8ac85239a8fa2947126f505a517fb18847104b21b0326b7fd67efb54f5d0b12b311ef998ebaf14939b7cdb44b35435eedf1ba5b07eea99533f1857b8cc1538290a8dbd44ca696c6bc2f1105451032a650c"); - let tag: [u8; 16] = hex::decode("e68a5de27beaeb6472611dfa9783602a") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("e68a5de27beaeb6472611dfa9783602a"); let encrypted = DeoxysII128::new(key).encrypt(nonce, payload).unwrap(); @@ -363,5 +302,5 @@ fn test_deoxys_ii_128_8() { let decrypted = DeoxysII128::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } diff --git a/deoxys/tests/deoxys_ii_256.rs b/deoxys/tests/deoxys_ii_256.rs index fa9ba0a2..bd7ad0ce 100644 --- a/deoxys/tests/deoxys_ii_256.rs +++ b/deoxys/tests/deoxys_ii_256.rs @@ -3,11 +3,10 @@ use deoxys::aead::generic_array::GenericArray; use deoxys::aead::{Aead, NewAead, Payload}; use deoxys::DeoxysII256; +use hex_literal::hex; + #[test] fn test_deoxys_ii_256_1() { - use core::convert::TryInto; - use hex; - let plaintext = Vec::new(); let aad = Vec::new(); @@ -17,19 +16,15 @@ fn test_deoxys_ii_256_1() { aad: &aad, }; - let key = - hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: Vec = Vec::new(); - let tag: [u8; 16] = hex::decode("2b97bd77712f0cde975309959dfe1d7c") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("2b97bd77712f0cde975309959dfe1d7c"); let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); @@ -49,32 +44,24 @@ fn test_deoxys_ii_256_1() { #[test] fn test_deoxys_ii_256_2() { - use core::convert::TryInto; - use hex; - let plaintext = Vec::new(); - let aad = - hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + let aad = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = - hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: Vec = Vec::new(); - let tag: [u8; 16] = hex::decode("54708ae5565a71f147bdb94d7ba3aed7") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("54708ae5565a71f147bdb94d7ba3aed7"); let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); @@ -94,32 +81,24 @@ fn test_deoxys_ii_256_2() { #[test] fn test_deoxys_ii_256_3() { - use core::convert::TryInto; - use hex; - let plaintext = Vec::new(); - let aad = - hex::decode("f495c9c03d29989695d98ff5d430650125805c1e0576d06f26cbda42b1f82238b8").unwrap(); + let aad = hex!("f495c9c03d29989695d98ff5d430650125805c1e0576d06f26cbda42b1f82238b8"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = - hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: Vec = Vec::new(); - let tag: [u8; 16] = hex::decode("3277689dc4208cc1ff59d15434a1baf1") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("3277689dc4208cc1ff59d15434a1baf1"); let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); @@ -139,11 +118,7 @@ fn test_deoxys_ii_256_3() { #[test] fn test_deoxys_ii_256_4() { - use core::convert::TryInto; - use hex; - - let plaintext = - hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + let plaintext = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); let aad = Vec::new(); @@ -152,20 +127,15 @@ fn test_deoxys_ii_256_4() { aad: &aad, }; - let key = - hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); - let ciphertext: Vec = - hex::decode("9da20db1c2781f6669257d87e2a4d9be1970f7581bef2c995e1149331e5e8cc1").unwrap(); + let ciphertext = hex!("9da20db1c2781f6669257d87e2a4d9be1970f7581bef2c995e1149331e5e8cc1"); - let tag: [u8; 16] = hex::decode("92ce3aec3a4b72ff9eab71c2a93492fa") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("92ce3aec3a4b72ff9eab71c2a93492fa"); let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); @@ -180,16 +150,12 @@ fn test_deoxys_ii_256_4() { let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } #[test] fn test_deoxys_ii_256_5() { - use core::convert::TryInto; - use hex; - - let plaintext = - hex::decode("15cd77732f9d0c4c6e581ef400876ad9188c5b8850ebd38224da95d7cdc99f7acc").unwrap(); + let plaintext = hex!("15cd77732f9d0c4c6e581ef400876ad9188c5b8850ebd38224da95d7cdc99f7acc"); let aad = Vec::new(); @@ -198,20 +164,15 @@ fn test_deoxys_ii_256_5() { aad: &aad, }; - let key = - hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); - let ciphertext: Vec = - hex::decode("e5ffd2abc5b459a73667756eda6443ede86c0883fc51dd75d22bb14992c684618c").unwrap(); + let ciphertext = hex!("e5ffd2abc5b459a73667756eda6443ede86c0883fc51dd75d22bb14992c684618c"); - let tag: [u8; 16] = hex::decode("5fa78d57308f19d0252072ee39df5ecc") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("5fa78d57308f19d0252072ee39df5ecc"); let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); @@ -226,41 +187,30 @@ fn test_deoxys_ii_256_5() { let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } #[test] fn test_deoxys_ii_256_6() { - use core::convert::TryInto; - use hex; - - let plaintext = - hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap(); + let plaintext = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); - let aad = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap(); + let aad = hex!("000102030405060708090a0b0c0d0e0f"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = - hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: [u8; 32] = - hex::decode("109f8a168b36dfade02628a9e129d5257f03cc7912aefa79729b67b186a2b08f") - .unwrap() - .try_into() - .unwrap(); + hex!("109f8a168b36dfade02628a9e129d5257f03cc7912aefa79729b67b186a2b08f"); - let tag: [u8; 16] = hex::decode("6549f9bf10acba0a451dbb2484a60d90") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("6549f9bf10acba0a451dbb2484a60d90"); let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); @@ -275,41 +225,30 @@ fn test_deoxys_ii_256_6() { let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } #[test] fn test_deoxys_ii_256_7() { - use core::convert::TryInto; - use hex; + let plaintext = hex!("422857fb165af0a35c03199fb895604dca9cea6d788954962c419e0d5c225c0327"); - let plaintext = - hex::decode("422857fb165af0a35c03199fb895604dca9cea6d788954962c419e0d5c225c0327").unwrap(); - - let aad = hex::decode("000102030405060708090a0b0c0d0e0f10").unwrap(); + let aad = hex!("000102030405060708090a0b0c0d0e0f10"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = - hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); let ciphertext: [u8; 33] = - hex::decode("7d772203fa38be296d8d20d805163130c69aba8cb16ed845c2296c61a8f34b394e") - .unwrap() - .try_into() - .unwrap(); + hex!("7d772203fa38be296d8d20d805163130c69aba8cb16ed845c2296c61a8f34b394e"); - let tag: [u8; 16] = hex::decode("0b3f10e3933c78190b24b33008bf80e9") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("0b3f10e3933c78190b24b33008bf80e9"); let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); @@ -324,39 +263,31 @@ fn test_deoxys_ii_256_7() { let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } #[test] fn test_deoxys_ii_256_8() { - use core::convert::TryInto; - use hex; - let plaintext = - hex::decode("83dab23b1379e090755c99079cfe918cb737e989f2d720ccaff493a744927644fec3653211fa75306a83486e5c34ecfe63870c97251a73e4b9033ae374809711b211ed5d293a592e466a81170f1d85750b5ca025ccd4579947edbae9ec132bfb1a7233ad79fae30006a6699f143893861b975226ed9d3cfb8a240be232fbf4e83755d59d20bc2faa2ea5e5b0428427485cca5e76a89fe32bdd59ab4177ad7cb1899c101e3c4f7535129591390ebdf30140846078b13867bbb2efd6cf434afe356eb18d716b21fd664c26c908496534bf2cde6d6b897799016594fb6d9f830ae5f44ccec26d42ff0d1a21b80cdbe8c8c170a5f766fad884abcc781b5b8ebc0f559bfeaa4557b04d977d51411a7f47bf437d0280cf9f92bc4f9cd6226337a492320851955adae2cafea22a89c3132dd252e4728328eda05555dff3241404341b8aa502d45c456113af42a8e91a85e4b4e9555028982ec3d144722af0eb04a6d3b8127c3040629de53f5fd187048198e8f8e8cc857afcbae45c693fec12fc2149d5e7587d0121b1717d0147f6979f75e8f085293f705c3399a6cc8df7057bf481e6c374edf0a0af7479f858045357b7fe21021c3fabdaf012652bf2e5db257bd9490ce637a81477bd3f9814a2198fdb9afa9344321f2393798670e588c47a1924d592cda3eb5a96754dfd92d87ee1ffa9d4ee586c85d7518c5d2db57d0451c33de0").unwrap(); + hex!("83dab23b1379e090755c99079cfe918cb737e989f2d720ccaff493a744927644fec3653211fa75306a83486e5c34ecfe63870c97251a73e4b9033ae374809711b211ed5d293a592e466a81170f1d85750b5ca025ccd4579947edbae9ec132bfb1a7233ad79fae30006a6699f143893861b975226ed9d3cfb8a240be232fbf4e83755d59d20bc2faa2ea5e5b0428427485cca5e76a89fe32bdd59ab4177ad7cb1899c101e3c4f7535129591390ebdf30140846078b13867bbb2efd6cf434afe356eb18d716b21fd664c26c908496534bf2cde6d6b897799016594fb6d9f830ae5f44ccec26d42ff0d1a21b80cdbe8c8c170a5f766fad884abcc781b5b8ebc0f559bfeaa4557b04d977d51411a7f47bf437d0280cf9f92bc4f9cd6226337a492320851955adae2cafea22a89c3132dd252e4728328eda05555dff3241404341b8aa502d45c456113af42a8e91a85e4b4e9555028982ec3d144722af0eb04a6d3b8127c3040629de53f5fd187048198e8f8e8cc857afcbae45c693fec12fc2149d5e7587d0121b1717d0147f6979f75e8f085293f705c3399a6cc8df7057bf481e6c374edf0a0af7479f858045357b7fe21021c3fabdaf012652bf2e5db257bd9490ce637a81477bd3f9814a2198fdb9afa9344321f2393798670e588c47a1924d592cda3eb5a96754dfd92d87ee1ffa9d4ee586c85d7518c5d2db57d0451c33de0"); - let aad = hex::decode("3290bb8441279dc6083a43e9048c3dc08966ab30d7a6b35759e7a13339f124918f3b5ab1affa65e6c0e3680eb33a6ec82424ab1ce5a40b8654e13d845c29b13896a1466a75fc875acba4527ded37ed00c600a357c9a6e586c74cf3d85cd3258c813218f319d12b82480e5124ff19ec00bda1fbb8bd25eeb3de9fcbf3296deba250caf7e9f4ef0be1918e24221dd0be888c59c166ad761d7b58462a1b1d44b04265b45827172c133dd5b6c870b9af7b21368d12a88f4efa1751047543d584382d9ec22e7550d50ecddba27d1f65453f1f3398de54ee8c1f4ac8e16f5523d89641e99a632380af0f0b1e6b0e192ec29bf1d8714978ff9fbfb93604142393e9a82c3aaebbbe15e3b4e5cfd18bdfe309315c9f9f830deebe2edcdc24f8eca90fda49f6646e789c5041fb5be933fa843278e95f3a54f8eb41f14777ea949d5ea442b01249e64816151a325769e264ed4acd5c3f21700ca755d5bc0c2c5f9453419510bc74f2d71621dcecb9efc9c24791b4bb560fb70a8231521d6560af89d8d50144d9c080863f043781153bcd59030e60bd17a6d7aa083211b67b581fa4f74cce4d030d1e8f9429fd725c110040d41eb6989ffb1595c72cbe3c9b78a8ab80d71a6a5283da77b89cae295bb13c14fbe466b617f4da8ad60b085e2ea153f6713ae0046aa31e0ba44e43ef36a111bf05c073a4e3624cd35f63a546f9142b35aa81b8826d").unwrap(); + let aad = hex!("3290bb8441279dc6083a43e9048c3dc08966ab30d7a6b35759e7a13339f124918f3b5ab1affa65e6c0e3680eb33a6ec82424ab1ce5a40b8654e13d845c29b13896a1466a75fc875acba4527ded37ed00c600a357c9a6e586c74cf3d85cd3258c813218f319d12b82480e5124ff19ec00bda1fbb8bd25eeb3de9fcbf3296deba250caf7e9f4ef0be1918e24221dd0be888c59c166ad761d7b58462a1b1d44b04265b45827172c133dd5b6c870b9af7b21368d12a88f4efa1751047543d584382d9ec22e7550d50ecddba27d1f65453f1f3398de54ee8c1f4ac8e16f5523d89641e99a632380af0f0b1e6b0e192ec29bf1d8714978ff9fbfb93604142393e9a82c3aaebbbe15e3b4e5cfd18bdfe309315c9f9f830deebe2edcdc24f8eca90fda49f6646e789c5041fb5be933fa843278e95f3a54f8eb41f14777ea949d5ea442b01249e64816151a325769e264ed4acd5c3f21700ca755d5bc0c2c5f9453419510bc74f2d71621dcecb9efc9c24791b4bb560fb70a8231521d6560af89d8d50144d9c080863f043781153bcd59030e60bd17a6d7aa083211b67b581fa4f74cce4d030d1e8f9429fd725c110040d41eb6989ffb1595c72cbe3c9b78a8ab80d71a6a5283da77b89cae295bb13c14fbe466b617f4da8ad60b085e2ea153f6713ae0046aa31e0ba44e43ef36a111bf05c073a4e3624cd35f63a546f9142b35aa81b8826d"); let payload = Payload { msg: &plaintext, aad: &aad, }; - let key = - hex::decode("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f").unwrap(); + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); let key = GenericArray::from_slice(&key); - let nonce = hex::decode("202122232425262728292a2b2c2d2e2f").unwrap(); + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); let nonce = GenericArray::from_slice(&nonce); - let ciphertext= - hex::decode("88294fcef65a1bdfd7baaa472816c64ef5bef2622b88c1ec5a739396157ef4935f3aa76449e391c32da28ee2857f399ac3dd95aed30cfb26cc0063cd4cd8f7431108176fbf370123856662b000a8348e5925fbb97c9ec0c737758330a7983f06b51590c1d2f5e5faaf0eb58e34e19e5fc85cec03d3926dd46a79ba7026e83dec24e07484c9103dd0cdb0edb505500caca5e1d5dbc71348cf00648821488ebaab7f9d84bbbf91b3c521dbef30110e7bd94f8dad5ab8e0cc5411ca9682d210d5d80c0c4bdbba8181789a4273d6deb80899fdcd976ca6f3a9770b54305f586a04256cfbeb4c11254e88559f294db3b9a94b80ab9f9a02cb4c0748de0af7818685521691dba5738be546dba13a56016fb8635af9dff50f25d1b17ad21707db2640a76a741e65e559b2afaaec0f37e18436bf02008f84dbd7b2698687a22376b65dc7524fca8a28709eee3f3caee3b28ed1173d1e08ee849e2ca63d2c90d555755c8fbafd5d2f4b37f06a1dbd6852ee2ffcfe79d510152e98fc4f3094f740a4aede9ee378b606d34576776bf5f1269f5385a84b3928433bfca177550ccfcd22cd0331bbc595e38c2758b2662476fa66354c4e84c7b360405aa3f5b2a48621bdca1a90c69b21789c91b5b8c568e3c741d99e22f6d7e26f2abed045f1d578b782ab4a5cf2af636d842b3012e180e4b045d8d15b057b69c92398a517053daf9be7c2935e") - .unwrap(); + let ciphertext = + hex!("88294fcef65a1bdfd7baaa472816c64ef5bef2622b88c1ec5a739396157ef4935f3aa76449e391c32da28ee2857f399ac3dd95aed30cfb26cc0063cd4cd8f7431108176fbf370123856662b000a8348e5925fbb97c9ec0c737758330a7983f06b51590c1d2f5e5faaf0eb58e34e19e5fc85cec03d3926dd46a79ba7026e83dec24e07484c9103dd0cdb0edb505500caca5e1d5dbc71348cf00648821488ebaab7f9d84bbbf91b3c521dbef30110e7bd94f8dad5ab8e0cc5411ca9682d210d5d80c0c4bdbba8181789a4273d6deb80899fdcd976ca6f3a9770b54305f586a04256cfbeb4c11254e88559f294db3b9a94b80ab9f9a02cb4c0748de0af7818685521691dba5738be546dba13a56016fb8635af9dff50f25d1b17ad21707db2640a76a741e65e559b2afaaec0f37e18436bf02008f84dbd7b2698687a22376b65dc7524fca8a28709eee3f3caee3b28ed1173d1e08ee849e2ca63d2c90d555755c8fbafd5d2f4b37f06a1dbd6852ee2ffcfe79d510152e98fc4f3094f740a4aede9ee378b606d34576776bf5f1269f5385a84b3928433bfca177550ccfcd22cd0331bbc595e38c2758b2662476fa66354c4e84c7b360405aa3f5b2a48621bdca1a90c69b21789c91b5b8c568e3c741d99e22f6d7e26f2abed045f1d578b782ab4a5cf2af636d842b3012e180e4b045d8d15b057b69c92398a517053daf9be7c2935e"); - let tag: [u8; 16] = hex::decode("a616f0c218e18b526cf2a3f8c115e262") - .unwrap() - .try_into() - .unwrap(); + let tag: [u8; 16] = hex!("a616f0c218e18b526cf2a3f8c115e262"); let encrypted = DeoxysII256::new(key).encrypt(nonce, payload).unwrap(); @@ -371,5 +302,5 @@ fn test_deoxys_ii_256_8() { let decrypted = DeoxysII256::new(key).decrypt(nonce, payload).unwrap(); - assert_eq!(plaintext, decrypted); + assert_eq!(&plaintext[..], &decrypted[..]); } From 1606511edca3173225dc147af3852dcb7a60ee9b Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Sat, 15 May 2021 20:35:50 -0400 Subject: [PATCH 03/24] Implemented Deoxys-I --- deoxys/src/lib.rs | 14 +- deoxys/src/modes.rs | 277 ++++++++++++++++++++++++++++++- deoxys/tests/deoxys_i_128.rs | 305 +++++++++++++++++++++++++++++++++++ deoxys/tests/deoxys_i_256.rs | 305 +++++++++++++++++++++++++++++++++++ 4 files changed, 893 insertions(+), 8 deletions(-) create mode 100644 deoxys/tests/deoxys_i_128.rs create mode 100644 deoxys/tests/deoxys_i_256.rs diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index f3b061b0..e4393e4d 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -17,25 +17,27 @@ use core::marker::PhantomData; pub use aead; use aead::{ - consts::{U0, U16, U8}, + consts::{U0, U16}, generic_array::{ArrayLength, GenericArray}, AeadCore, AeadInPlace, Error, NewAead, }; use zeroize::Zeroize; +pub type DeoxysI128 = Deoxys; +pub type DeoxysI256 = Deoxys; pub type DeoxysII128 = Deoxys; pub type DeoxysII256 = Deoxys; pub type Key = GenericArray; -pub type NonceDeoxysI = GenericArray; -pub type NonceDeoxysII = GenericArray; pub type Tag = GenericArray; pub trait DeoxysMode where B: DeoxysBcType, { + type NonceSize: ArrayLength; + fn encrypt_in_place( nonce: &[u8], associated_data: &[u8], @@ -89,7 +91,7 @@ where M: DeoxysMode, B: DeoxysBcType, { - type NonceSize = U16; + type NonceSize = M::NonceSize; type TagSize = U16; type CiphertextOverhead = U0; } @@ -101,7 +103,7 @@ where { fn encrypt_in_place_detached( &self, - nonce: &NonceDeoxysII, + nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], ) -> Result { @@ -115,7 +117,7 @@ where fn decrypt_in_place_detached( &self, - nonce: &NonceDeoxysII, + nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], tag: &Tag, diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index ce45166e..f20f0475 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -1,4 +1,7 @@ -use aead::generic_array::GenericArray; +use aead::{ + consts::{U16, U8}, + generic_array::GenericArray, +}; use subtle::ConstantTimeEq; use zeroize::Zeroize; @@ -18,10 +21,281 @@ pub struct DeoxysI; pub struct DeoxysII; +impl DeoxysMode for DeoxysI +where + B: DeoxysBcType, +{ + type NonceSize = U8; + + fn encrypt_in_place( + nonce: &[u8], + associated_data: &[u8], + buffer: &mut [u8], + key: &GenericArray, + ) -> [u8; 16] { + let mut tag = [0u8; 16]; + let mut checksum = [0u8; 16]; + let mut tweakey = GenericArray::::default(); + + tweakey[..key.len()].copy_from_slice(&key); + + // Associated Data + if associated_data.len() > 0 { + tweakey[key.len()] = TWEAK_AD; + + for (index, ad) in associated_data.chunks(16).enumerate() { + // Copy block number + tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + + if ad.len() == 16 { + let mut block = [0u8; 16]; + block.copy_from_slice(ad); + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } else { + // Last block + tweakey[key.len()] = TWEAK_AD_LAST; + + let mut block = [0u8; 16]; + block[0..ad.len()].copy_from_slice(ad); + + block[ad.len()] = 0x80; + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } + } + } + + // Add the nonce to the tweak + tweakey[key.len()] = nonce[0] >> 4; + for i in 1..nonce.len() { + tweakey[key.len() + i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); + } + + tweakey[key.len() + 8] = nonce[7] << 4; + + // Message authentication and encryption + if buffer.len() > 0 { + tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M; + + for (index, data) in buffer.chunks_mut(16).enumerate() { + // Copy block number + let tmp = tweakey[key.len() + 8] & 0xf0; + tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + + if data.len() == 16 { + for (c, d) in checksum.iter_mut().zip(data.iter()) { + *c = *c ^ d; + } + + B::encrypt_in_place(data, &tweakey); + } else { + // Last block checksum + tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M_LAST; + + let mut block = [0u8; 16]; + block[0..data.len()].copy_from_slice(data); + + block[data.len()] = 0x80; + + for (c, d) in checksum.iter_mut().zip(block.iter()) { + *c = *c ^ d; + } + + block.fill(0); + + // Last block encryption + B::encrypt_in_place(&mut block, &tweakey); + + for (d, b) in data.iter_mut().zip(block.iter()) { + *d = *d ^ b; + } + + // Tag computing. + tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_CHKSUM; + + let tmp = tweakey[key.len() + 8] & 0xf0; + tweakey[key.len() + 8..].copy_from_slice(&((index + 1) as u64).to_be_bytes()); + tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + + B::encrypt_in_place(&mut checksum, &tweakey); + + for (t, c) in tag.iter_mut().zip(checksum.iter()) { + *t = *t ^ c; + } + } + } + } + + if buffer.len() % 16 == 0 { + // Tag computing without last block + tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_TAG; + + let tmp = tweakey[key.len() + 8] & 0xf0; + tweakey[key.len() + 8..].copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); + tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + + B::encrypt_in_place(&mut checksum, &tweakey); + + for (t, c) in tag.iter_mut().zip(checksum.iter()) { + *t = *t ^ c; + } + } + + // Zeroize tweakey since it contains the key + tweakey.zeroize(); + tag + } + + fn decrypt_in_place( + nonce: &[u8], + associated_data: &[u8], + buffer: &mut [u8], + tag: &[u8], + key: &GenericArray, + ) -> Result<(), aead::Error> { + let mut computed_tag = [0u8; 16]; + let mut checksum = [0u8; 16]; + let mut tweakey = GenericArray::::default(); + + tweakey[..key.len()].copy_from_slice(&key); + + // Associated Data + if associated_data.len() > 0 { + tweakey[key.len()] = TWEAK_AD; + + for (index, ad) in associated_data.chunks(16).enumerate() { + // Copy block number + tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + + if ad.len() == 16 { + let mut block = [0u8; 16]; + block.copy_from_slice(ad); + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in computed_tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } else { + // Last block + tweakey[key.len()] = TWEAK_AD_LAST; + + let mut block = [0u8; 16]; + block[0..ad.len()].copy_from_slice(ad); + + block[ad.len()] = 0x80; + + B::encrypt_in_place(&mut block, &tweakey); + + for (t, b) in computed_tag.iter_mut().zip(block.iter()) { + *t = *t ^ b; + } + } + } + } + + // Add the nonce to the tweak + tweakey[key.len()] = nonce[0] >> 4; + for i in 1..nonce.len() { + tweakey[key.len() + i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); + } + + tweakey[key.len() + 8] = nonce[7] << 4; + + // Message authentication and encryption + if buffer.len() > 0 { + tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M; + + for (index, data) in buffer.chunks_mut(16).enumerate() { + // Copy block number + let tmp = tweakey[key.len() + 8] & 0xf0; + tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + + if data.len() == 16 { + B::decrypt_in_place(data, &tweakey); + + for (c, d) in checksum.iter_mut().zip(data.iter()) { + *c = *c ^ d; + } + } else { + // Last block checksum + tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M_LAST; + + let mut block = [0u8; 16]; + B::encrypt_in_place(&mut block, &tweakey); + + for (d, b) in data.iter_mut().zip(block.iter()) { + *d = *d ^ b; + } + + block.fill(0); + + block[0..data.len()].copy_from_slice(data); + block[data.len()] = 0x80; + + for (c, d) in checksum.iter_mut().zip(block.iter()) { + *c = *c ^ d; + } + + // Tag computing. + tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_CHKSUM; + + let tmp = tweakey[key.len() + 8] & 0xf0; + tweakey[key.len() + 8..].copy_from_slice(&((index + 1) as u64).to_be_bytes()); + tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + + B::encrypt_in_place(&mut checksum, &tweakey); + + for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) { + *t = *t ^ c; + } + } + } + } + + if buffer.len() % 16 == 0 { + // Tag computing without last block + tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_TAG; + + let tmp = tweakey[key.len() + 8] & 0xf0; + tweakey[key.len() + 8..].copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); + tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + + B::encrypt_in_place(&mut checksum, &tweakey); + + for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) { + *t = *t ^ c; + } + } + + // Zeroize tweakey since it contains the key + tweakey.zeroize(); + + if tag.ct_eq(&computed_tag).into() { + Ok(()) + } else { + Err(aead::Error) + } + } +} + impl DeoxysMode for DeoxysII where B: DeoxysBcType, { + type NonceSize = U16; + fn encrypt_in_place( nonce: &[u8], associated_data: &[u8], @@ -81,7 +355,6 @@ where let mut block = [0u8; 16]; block.copy_from_slice(data); - //panic!("{:x?}", &tweakey); B::encrypt_in_place(&mut block, &tweakey); for (t, b) in tag.iter_mut().zip(block.iter()) { diff --git a/deoxys/tests/deoxys_i_128.rs b/deoxys/tests/deoxys_i_128.rs new file mode 100644 index 00000000..2af8646c --- /dev/null +++ b/deoxys/tests/deoxys_i_128.rs @@ -0,0 +1,305 @@ +// Uses the official test vectors. +use deoxys::aead::generic_array::GenericArray; +use deoxys::aead::{Aead, NewAead, Payload}; +use deoxys::DeoxysI128; + +use hex_literal::hex; + +#[test] +fn test_deoxys_i_128_1() { + let plaintext = Vec::new(); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex!("eec87dce98d29d4078598abd16d550ff"); + + let encrypted = DeoxysI128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_i_128_2() { + let plaintext = Vec::new(); + + let aad = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex!("b507e4aee5f9d7cb9eaebd8370f25a98"); + + let encrypted = DeoxysI128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_i_128_3() { + let plaintext = Vec::new(); + + let aad = hex!("0429974cda6665fb9bb4b67d50859258dd69883d50c1eff4bd5962bf4038ad0497"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex!("fbb9c589e3a54df11e8573d94e6b1000"); + + let encrypted = DeoxysI128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_i_128_4() { + let plaintext = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext = hex!("4bf8c5ecec375b25acabd687aa605f1a8bb296face74f82527d4944dbb11b757"); + + let tag: [u8; 16] = hex!("f32754de1727da4909413815a64e6a69"); + + let encrypted = DeoxysI128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} + +#[test] +fn test_deoxys_i_128_5() { + let plaintext = hex!("5a4c652cb880808707230679224b11799b5883431292973215e9bd03cf3bc32fe4"); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext = hex!("cded5a43d3c76e942277c2a1517530ad66037897c985305ede345903ed7585a626"); + + let tag: [u8; 16] = hex!("cbf5faa6b8398c47f4278d2019161776"); + + let encrypted = DeoxysI128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} + +#[test] +fn test_deoxys_i_128_6() { + let plaintext = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + + let aad = hex!("000102030405060708090a0b0c0d0e0f"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: [u8; 32] = + hex!("4bf8c5ecec375b25acabd687aa605f1a8bb296face74f82527d4944dbb11b757"); + + let tag: [u8; 16] = hex!("a1b897f1901e5d98e17936ec1b4d85b3"); + + let encrypted = DeoxysI128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} + +#[test] +fn test_deoxys_i_128_7() { + let plaintext = hex!("ee8f487e01f5a101dee6cfd5915d6b5b2c5b6305c782bc7e727bd08096e4208216"); + + let aad = hex!("000102030405060708090a0b0c0d0e0f10"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: [u8; 33] = + hex!("09af865850abc0bce7d35f664a63e41b1475d0385e31a6551edf69ea9f2f8b8ed4"); + + let tag: [u8; 16] = hex!("9326c6c2a0b7f065e591eb9050169603"); + + let encrypted = DeoxysI128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} + +#[test] +fn test_deoxys_i_128_8() { + let plaintext = hex!("1857d4edf080e8e2c83aa9e794ebf90d1ea0ccb977287a019aca3daa7af2ad5709d63f05b5b00f4b004b56e802d298ea78afd5d21fd2619248a0897b8e141dc6e1f8b49056d570571a294152a7d7387dbac1ab9ff799dbe0e6c3ae23a14908a3e48eb224824eee8ea4ee3b4ab1bd12a81e3a393ca1344fd9ca5309b116ab2e49e12020f1d6d3bbf608c4e33472c33c6a8d088124c0de4161d94833d75a9bfde908d57d182675c992ad8545198ad2565bac43ce1786e92ec01961c424c1b4c23bc97959ed185193c08e49c6741061e300c94216e505569bcc528f4ced786d1939b4568be157a4b9231b1baf19fc90ee35e97dbfb2965468c2882f1706c6ccec31be7759640c4a2a8a22ecac433eba2223d9685215a8e12bf262f4a72a8bb85ef4181b1d513218a657a24f2903da166f06abd27fbd757ad87473deb844c24e7f7a9295299580bdb1a99acf53a2cc3b1234fb9b0976b6b0ae42605536f46239d1ebd1283adf41f250761d54280e65d79e16200b16d899702530314c6eb5bcb0f1de6d61eaa7ea4c097075ac691754cb1eebbe7ff8cfc39000d9eca154ea37a9d635385b1e132ac3a0d3ffdc362b4333db6b56960cd0d86d02f08ea6e6e1e20a12b7d0b0fe897ab2fcb43f44afb2d42326b2d8d0531e6c9c64aae896caa74299c6d8e10a45360d67373aae7326a1b0484aa42e970510ecb02ca739c38183a43881e6"); + + let aad = hex!("d4e7fc007c9f462d3c2f3ee1c2b92597a838be68930fcc770d3f4a6e8d3f245567c28772c7891c8a605e3f64dd584c264685794c23458c0faf8bbfc5925fe8278eaa1f35322b78c27fcfad42da7f1e9c4ab3aea98c236846690eeb63a26eb60f4cdaef83c3941b57b81529704e404444ed541269428baecd17f4e7f3bde62566b65b578eba069990e8fb10696d94e925ec41b9142de25cd30750cabd41d0a100bebe5eeada44caabff9ede3c251bb57bb48dfb90f7bb9f7d82f131ee20788ff3d9435f8c4f1590cd3cf2dbda143d8a6bcec5e95834578d46561ea209b4d29b1bb74c2c5d1f1bb765cd1d3a1e95984e7f257f4a8a91b3d3d587b43a4023593948d0a58fb1be920f493e5615abd2ecd38f45ed8c440c427a0d2eb76f91adee4c119ac980f28d87585a68039761dbea738a006ec0d9a7dde2ea873c4cf27c8b3565d776473f247b30198e62d4bc722b84d6260bb9e4b8c36dbf1ce6a2b91211bc25d1c0797c5b992920810e78ea6e474f69c9f14550eac375e896a2e5facebcf97bbf5bfdb547ef202222693b4c3120fe8a9559bee514e0b6d9a711a632a7d55398ddd8de66ef3b6f8dd8fa468d27ca455a5fcda20dd12aa426053e9f8454d9598e2d6a528aa4ffe272a4f1341e695dbb1b43bd720ab87ba62290e2d3f78a497a20d1bb0ed72430698b857774d6414ca856019660aba783ff9794d395c82de41a031a"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("202122232425262728292a2b2c2d2e2f"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext= + hex!("f86ecad0d69d2c573cdeee96c90f37ac3c861bd5f4d82ac7396dda102adfa7a94f1daab1e537f03b2a6665eaa8ee057eee403db7ced61adbd77b5c286b7afc5ec23f3f9333773f02d533b0c49ecfc6bcd359bc8a3db6ab16b423efc93e2591e5485a5b21a8cf9312a10d76c840bd1a7e9f5a9954cb636b01ebc8e91a550a0123a50883627d5535f0f6a7960f005d5f340e054ea145dd756e37efd91bc774f93d385da7135372bc51d0401e6499784618da55c31e0b7ad1aa09a3e002f3021ce02926c79741992d9d0252761a7ca6667a56f78e81eaf08cf36d4117d9b2349262d411bef955d7408562ed040e1ea85e3aa3dcf942ea5205edec164dbd6304f90da59b9fb4f8fdeb2c2df473f90494cf09c6af69d191abd7baf97058a3694872d01f63afc225e3796251375a7520a5f755b24b8fd153f362ff09c7e85f02e789ed8cf8adabfcde4c764ebdd703dee39b4e90a91ab0377e0bebc61b2ec9b3c4e3ac7fd893e13c5d0e303e7e625281c988a48dcfd9ee4b698a1c2a82927168e754c99338ea24d24b9bba11cdb4472badc038ab01f250d359c4ade703329062c6260d8fcfda3a6b50b641f9e1e5f2107fd6ca77140dba9048919cab4ea21e4178fde08e7213bf0b730c0415331775039e99f11146b0ebb99a8f5f2d2c4e1767b6fed9c7140dfcf01c793e88889cf34b4ecb044fc740f3d4a2cad1f93455cc36b9a0c6"); + + let tag: [u8; 16] = hex!("5c89d78dbef3d727013b59af859f17da"); + + let encrypted = DeoxysI128::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI128::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} diff --git a/deoxys/tests/deoxys_i_256.rs b/deoxys/tests/deoxys_i_256.rs new file mode 100644 index 00000000..fe453fdc --- /dev/null +++ b/deoxys/tests/deoxys_i_256.rs @@ -0,0 +1,305 @@ +// Uses the official test vectors. +use deoxys::aead::generic_array::GenericArray; +use deoxys::aead::{Aead, NewAead, Payload}; +use deoxys::DeoxysI256; + +use hex_literal::hex; + +#[test] +fn test_deoxys_i_256_1() { + let plaintext = Vec::new(); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("0001020304050607"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex!("50b0deaa3c3129d1ea1ef96b7c8db67f"); + + let encrypted = DeoxysI256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_i_256_2() { + let plaintext = Vec::new(); + + let aad = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("0001020304050607"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex!("0e641b45bcffb3c07fa7f7d31edc37d2"); + + let encrypted = DeoxysI256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_i_256_3() { + let plaintext = Vec::new(); + + let aad = hex!("52d15808134c3c2e8acbc154299df5c6f86f48ec5dafa5363989b33ba7e0299565"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("0001020304050607"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: Vec = Vec::new(); + + let tag: [u8; 16] = hex!("f343b91c303180ae2ae4f379022087fa"); + + let encrypted = DeoxysI256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(plaintext, decrypted); +} + +#[test] +fn test_deoxys_i_256_4() { + let plaintext = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("0001020304050607"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext = hex!("2c36c041fa3b1436c5153214131d493be9d014689a6a1e93e4a50989f0342941"); + + let tag: [u8; 16] = hex!("ae66f78a3abf1bb7608c6fe949effb57"); + + let encrypted = DeoxysI256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} + +#[test] +fn test_deoxys_i_256_5() { + let plaintext = hex!("9d63bc34aceebe70b21768e4f1cfd87bacbcae1e2577b6018de1d72707a42b2569"); + + let aad = Vec::new(); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("0001020304050607"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext = hex!("fd1ea6745fb5b435751d92be58f5973b84c7589501fcfaff6ce07e2a0e9a72c23e"); + + let tag: [u8; 16] = hex!("e957add57b7c5924d9a22db6fe03cce7"); + + let encrypted = DeoxysI256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} + +#[test] +fn test_deoxys_i_256_6() { + let plaintext = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + + let aad = hex!("000102030405060708090a0b0c0d0e0f"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("0001020304050607"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: [u8; 32] = + hex!("2c36c041fa3b1436c5153214131d493be9d014689a6a1e93e4a50989f0342941"); + + let tag: [u8; 16] = hex!("6da67607bad9cdd34d702325d52abcdd"); + + let encrypted = DeoxysI256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} + +#[test] +fn test_deoxys_i_256_7() { + let plaintext = hex!("8a968861ccb4aa1b7744ffff4812e001d1a749df3f66497c1c717681c43987b4eb"); + + let aad = hex!("000102030405060708090a0b0c0d0e0f10"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("0001020304050607"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext: [u8; 33] = + hex!("705f9db5d50ec6ff0ae28557a5640d32b19504833d5fc6de3baf638cef4cda50bc"); + + let tag: [u8; 16] = hex!("88f06bac360362824401c8f1385073a8"); + + let encrypted = DeoxysI256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} + +#[test] +fn test_deoxys_i_256_8() { + let plaintext = hex!("d18db1b44ad16fe5623ccd73c250c27240daf512e97de1ca770983f262d36e1c9eafdf925c9786aeb556c1d058e1d3d0d92b8a5fed45bff46204f7cc1db8b23e69f271593f4c8427ee5660fad6edf209f903921c1eba5c884777be45ca7875c72e5b44b550dc30ee875798a19a0d61965bf9ec6a17bdebb91b9e503dbf70e5ec314e67d199296cd6375c510b04dbe30ac3b6a083f655627ab3859c168263babfbd5ca2f9c33df7deefd46f37693ba4350b69e3ddbde6b0d5711c4a0a7c8dcadf8b2340ed7a0748c3e9ef6ae72022fd3799b0561f00b255cdde1199b1c2def3b6324508f28b1f1935aeb1083072598d8cea7e420ad8ce090922fca2be67b68e0b8fe5db2f06faca945480f4831a6fd9bbeb40084403a8a2617184f8c9d3340c2720b19f838d64a82eff4b2020ee92a72291102487788d8f774a32d5b1a6752cd80118f400806fe613d312d8d65cc21f4af83b50407fedec7ed4972a54b8d2260cb652f3d9f3868d3081b20a719a1ff8611fe19ec41dc92570b74688506746cf96c7f5db878446b0fdcc554a1c3e7fa62b611077a65e29bb460699a6187fa4c52b91f58cc103a7dce86d3feefd9dcbc86fa5bf67b13fc0157c6da22d5dda3f0443a05b2d7b286b5da2372013f18a361cab696219d84f8677588d8500b7ebb34b29b1520258bcaa19f77229ddab6fcba75faaf4e09ecaa590e77e027477f5399b47"); + + let aad = hex!("bbc9aa3017a7ee71293eb2ea451f2efa6794e41c55b7505df1f2073f5babe332a479619f855a39e45ef469b0c6329a786dbfc2b05b27983683d5edf26949cf964d75d7110bd4dba14a76f88353e3c652b46aca2f661d37dc7ffcf8da13c7aa48f25095ce16c8834c3d2c9c813197926d47c9f73895fdf70f2574d7f8539a9ef2aba78e80ec138ef1f702daf007ba337e1e0dfc49e6bd3f3eb4ff5a5c4e0ca2bdcf3e5b6fea5401dfaa40e66db6fc63a6e306755492684bbc6021e2a1bbf1245422377664475b22cdd83960e47852b474da196e67db018b87839966ffe52c665cabe0c021df68d0c1454505b0458fe3dc3acc6b8400ec04a3129266ae9368c15bbf13aabd05f859e2e9ea7cc937e899cc5c5bd72d2b72bd16d9024db4706fcf5195bbe25eb807fea01840f4b572f0fadb8a4246d6895547a37cd8a9b756425b31872a1d51c0ef2d53ca000711388228b76490780e3a10389c72ccc0deded32a5d9e723aa31dddd3344b068bcde9d483c9249375a88dce482a819361993fde555603cea01cede77fe64190906157ded418c3c21bc5274034b8d9edf09daf2aa90fb3b5f7d3b7da5c018144e54af9737227d2c13210c861fd5b4246d1a290fd054fd15d59d2e08894239d000b1076055771f7a7da54b2fcd7cd1f5a9e1da5a25a0ddbaa8d4397d74828a2b75a8da4730b87ac6c2fc5ef4985b9915320ea4942690df6"); + + let payload = Payload { + msg: &plaintext, + aad: &aad, + }; + + let key = hex!("101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"); + let key = GenericArray::from_slice(&key); + + let nonce = hex!("0001020304050607"); + let nonce = GenericArray::from_slice(&nonce[..8]); + + let ciphertext = + hex!("e94c5c6df7c19474bbdd292baa2555fdbd5e90a35fb94627cdd7dd3b424ca47d6779f3e6997809204263bdbd4825b7d6510995b1c371e582942bd7f6ab909f993cd5b7db5f95e8b8b56e4cdf016f5cab37f662329b32801fda4403f731fa61f7aa16b9a23f2637b1f75fa0b36ced90ce6a1f73aafbb5adca756e0d59b8ae6661f2d3fc409c88d8baf3836fac55df78b9ba522221345f42bd794c26d5d1a83fed0114d1d1b04d3c3b77ff0083647710b316e17896b2081d9375fde1f2fe063e66423a0d413919ffa6b5754d10de8de64d32ede0d02ebe8f8791d8e9f59462b615f4122dd8c3b97671a8c156eb32ebebb3fb91832fd01f6afee9d4ab045fea83ec87743823ea3bd18f7826229c312ad8a4bc9e2f6d1ad520e6d850bd189b4538d10005abf5a7c50f4f8ded6a62b18cd2a7e6bd3159edc3e9b553cbddd419af540da10576e9ea7d49e2fd0dc1c5ee7693504b63b928e4e23b1753147a3d0ad00cc2e6390fba10e925dc536db4eb30cf152ddb0420f8e8eaa8460feb9a7f0be589ccb877732d8d606085536c405c2ba6c03cb68e12f7d14609587a6c478e2a32794290ba35ce6dba21784d8f6faf401920bfc2aa172c3b4d9bea2eae8542b18410d3a40414247a406379855cb78c28e82ab67b62433a4016b15c4abf4f01c372ba4f1562596531cb0337117ad769eaa666b497b7822eba924e358693bc48cf555f70"); + + let tag: [u8; 16] = hex!("e404257c9cf7eb9774fc288a9ef1592e"); + + let encrypted = DeoxysI256::new(key).encrypt(nonce, payload).unwrap(); + + let tag_begins = encrypted.len() - 16; + assert_eq!(ciphertext, encrypted[..tag_begins]); + assert_eq!(tag, encrypted[tag_begins..]); + + let payload = Payload { + msg: &encrypted, + aad: &aad, + }; + + let decrypted = DeoxysI256::new(key).decrypt(nonce, payload).unwrap(); + + assert_eq!(&plaintext[..], &decrypted[..]); +} From c208bc6be36e331d31719c371f4a4c90643416bf Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Sat, 15 May 2021 20:51:59 -0400 Subject: [PATCH 04/24] Reduced Deoxys-II nonce size --- deoxys/src/modes.rs | 6 ++---- deoxys/tests/deoxys_ii_128.rs | 16 ++++++++-------- deoxys/tests/deoxys_ii_256.rs | 16 ++++++++-------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index f20f0475..ed21d29b 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -1,5 +1,5 @@ use aead::{ - consts::{U16, U8}, + consts::{U15, U8}, generic_array::GenericArray, }; use subtle::ConstantTimeEq; @@ -8,8 +8,6 @@ use zeroize::Zeroize; use super::DeoxysBcType; use super::DeoxysMode; -const TWEAK_AD_N1: u8 = 0x30; -const TWEAK_AD_N2: u8 = 0x70; const TWEAK_AD: u8 = 0x20; const TWEAK_AD_LAST: u8 = 0x60; const TWEAK_M: u8 = 0x00; @@ -294,7 +292,7 @@ impl DeoxysMode for DeoxysII where B: DeoxysBcType, { - type NonceSize = U16; + type NonceSize = U15; fn encrypt_in_place( nonce: &[u8], diff --git a/deoxys/tests/deoxys_ii_128.rs b/deoxys/tests/deoxys_ii_128.rs index 9ec38bce..4beea8ec 100644 --- a/deoxys/tests/deoxys_ii_128.rs +++ b/deoxys/tests/deoxys_ii_128.rs @@ -20,7 +20,7 @@ fn test_deoxys_ii_128_1() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: Vec = Vec::new(); @@ -57,7 +57,7 @@ fn test_deoxys_ii_128_2() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: Vec = Vec::new(); @@ -94,7 +94,7 @@ fn test_deoxys_ii_128_3() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: Vec = Vec::new(); @@ -131,7 +131,7 @@ fn test_deoxys_ii_128_4() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext = hex!("fa22f8eb84ee6d2388bdb16150232e856cd5fa3508bc589dad16d284208048c9"); @@ -168,7 +168,7 @@ fn test_deoxys_ii_128_5() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext = hex!("82bf241958b324ed053555d23315d3cc20935527fc970ff34a9f521a95e302136d"); @@ -205,7 +205,7 @@ fn test_deoxys_ii_128_6() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: [u8; 32] = hex!("9cdb554dfc03bff4feeb94df7736038361a76532b6b5a9c0bdb64a74dee983ff"); @@ -243,7 +243,7 @@ fn test_deoxys_ii_128_7() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: [u8; 33] = hex!("801f1b81878faca562c8c6c0859b166c2669fbc54b1784be637827b4905729bdf9"); @@ -282,7 +282,7 @@ fn test_deoxys_ii_128_8() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext= hex!("b8eddddb8d0042bb42fdf675bae285e504b90e4d73e02f99f790b2ffe7815dba40fe4c7bc886ce44505f6ac53d3bba5d3c73efd98daf4b7a5af250a5d100ff5558c211cb03a28d9519502d7d0fc85a6d73e618feb6b503af12cb0330bb9c5743b19996174a84dbf5bac38d10d207067e4ab211a62ad0f85dd8245dfb077443017b7847996fe7ed547b9e02051f1cbe39128e21486b4f73399d0a50d9a1111bed11ebb0547454d0a922633c83f0bba784571f63f55dc33f92e09862471945312d99e40b4ed739556f102afd43055497739a4b22d107e867cc652a5d96974ff785976c82bc1ff89731c780e84a257bb885cd23e00a7bdc7a68e0a1668516fb972721a777429c76cfd4adb45afa554d44a8932d133af8c9254fd3fef2bd0bb65801f2ffbf752f14eaa783e53c2342f021863598e88b20232a0c44e963dd8943e9a54213ffbb174b90e38b55aa9b223e9596acb1517ff21b7458b7694488047797c521883c00762e7227f1e8a5e3f11a43962bdccde8dc4009aef7628a96efa8793d6080982f9b00a7b97d93fd5928702e78427f34eb434e2286de00216b405c36105dc2e8dae68c3342a23274b32a6d2d8ac85239a8fa2947126f505a517fb18847104b21b0326b7fd67efb54f5d0b12b311ef998ebaf14939b7cdb44b35435eedf1ba5b07eea99533f1857b8cc1538290a8dbd44ca696c6bc2f1105451032a650c"); diff --git a/deoxys/tests/deoxys_ii_256.rs b/deoxys/tests/deoxys_ii_256.rs index bd7ad0ce..44aa46aa 100644 --- a/deoxys/tests/deoxys_ii_256.rs +++ b/deoxys/tests/deoxys_ii_256.rs @@ -20,7 +20,7 @@ fn test_deoxys_ii_256_1() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: Vec = Vec::new(); @@ -57,7 +57,7 @@ fn test_deoxys_ii_256_2() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: Vec = Vec::new(); @@ -94,7 +94,7 @@ fn test_deoxys_ii_256_3() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: Vec = Vec::new(); @@ -131,7 +131,7 @@ fn test_deoxys_ii_256_4() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext = hex!("9da20db1c2781f6669257d87e2a4d9be1970f7581bef2c995e1149331e5e8cc1"); @@ -168,7 +168,7 @@ fn test_deoxys_ii_256_5() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext = hex!("e5ffd2abc5b459a73667756eda6443ede86c0883fc51dd75d22bb14992c684618c"); @@ -205,7 +205,7 @@ fn test_deoxys_ii_256_6() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: [u8; 32] = hex!("109f8a168b36dfade02628a9e129d5257f03cc7912aefa79729b67b186a2b08f"); @@ -243,7 +243,7 @@ fn test_deoxys_ii_256_7() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext: [u8; 33] = hex!("7d772203fa38be296d8d20d805163130c69aba8cb16ed845c2296c61a8f34b394e"); @@ -282,7 +282,7 @@ fn test_deoxys_ii_256_8() { let key = GenericArray::from_slice(&key); let nonce = hex!("202122232425262728292a2b2c2d2e2f"); - let nonce = GenericArray::from_slice(&nonce); + let nonce = GenericArray::from_slice(&nonce[..15]); let ciphertext = hex!("88294fcef65a1bdfd7baaa472816c64ef5bef2622b88c1ec5a739396157ef4935f3aa76449e391c32da28ee2857f399ac3dd95aed30cfb26cc0063cd4cd8f7431108176fbf370123856662b000a8348e5925fbb97c9ec0c737758330a7983f06b51590c1d2f5e5faaf0eb58e34e19e5fc85cec03d3926dd46a79ba7026e83dec24e07484c9103dd0cdb0edb505500caca5e1d5dbc71348cf00648821488ebaab7f9d84bbbf91b3c521dbef30110e7bd94f8dad5ab8e0cc5411ca9682d210d5d80c0c4bdbba8181789a4273d6deb80899fdcd976ca6f3a9770b54305f586a04256cfbeb4c11254e88559f294db3b9a94b80ab9f9a02cb4c0748de0af7818685521691dba5738be546dba13a56016fb8635af9dff50f25d1b17ad21707db2640a76a741e65e559b2afaaec0f37e18436bf02008f84dbd7b2698687a22376b65dc7524fca8a28709eee3f3caee3b28ed1173d1e08ee849e2ca63d2c90d555755c8fbafd5d2f4b37f06a1dbd6852ee2ffcfe79d510152e98fc4f3094f740a4aede9ee378b606d34576776bf5f1269f5385a84b3928433bfca177550ccfcd22cd0331bbc595e38c2758b2662476fa66354c4e84c7b360405aa3f5b2a48621bdca1a90c69b21789c91b5b8c568e3c741d99e22f6d7e26f2abed045f1d578b782ab4a5cf2af636d842b3012e180e4b045d8d15b057b69c92398a517053daf9be7c2935e"); From e7b6235a52a9f316ae5dc1173690490096706942 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Mon, 17 May 2021 17:29:59 -0400 Subject: [PATCH 05/24] Added Deoxys documentation --- deoxys/src/deoxys_bc.rs | 3 + deoxys/src/lib.rs | 156 +++++++++++++++++++++++++++++++++++++++- deoxys/src/modes.rs | 2 + 3 files changed, 158 insertions(+), 3 deletions(-) diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index 4603ad41..7ac12ac6 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -14,7 +14,10 @@ const RCON: [u8; 17] = [ 0x72, ]; +/// Implementation of the Deoxys-BC256 block cipher pub struct DeoxysBc256; + +/// Implementation of the Deoxys-BC384 block cipher pub struct DeoxysBc384; impl DeoxysBc256 { diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index e4393e4d..e6d70f3e 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -1,4 +1,118 @@ -//! [`Deoxys`] TODO +//! The [Deoxys][2] [Authenticated Encryption and Associated Data (AEAD)][1]. +//! The Deoxys-II variant has been selected as the first choice for defense in-depth scenario during the [CAESAR competition][3]. +//! +//! ## Performance Notes +//! +//! By default this crate will use software implementations of AES. +//! +//! When targeting modern x86/x86_64 CPUs, use the following `RUSTFLAGS` to +//! take advantage of high performance AES-NI and CLMUL CPU intrinsics: +//! +//! ```text +//! RUSTFLAGS="-Ctarget-cpu=sandybridge -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3" +//! ``` +//! +//! ## Security Notes +//! +//! This crate has NOT received any security audit and is still in pretty early stage. +//! Although encryption and secryption passes the test vector, there is no guarantee that operations happens in constant time. +//! +//! **USE AT YOUR OWN RISK.** +//! +//! # Usage +//! ``` +//! use deoxys::{DeoxysII256, Key, Nonce}; // Can be `DeoxysI128`, `DeoxysI256`, `DeoxysII128` of `DeoxysII256` +//! use deoxys::aead::{Aead, NewAead}; +//! +//! let key = Key::from_slice(b"an example very very secret key."); +//! let cipher = DeoxysII256::new(key); +//! +//! let nonce = Nonce::from_slice(b"unique nonce123"); // 64-bits for Deoxys-I or 120-bits for Deoxys-II; unique per message +//! +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) +//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! +//! +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) +//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! +//! +//! assert_eq!(&plaintext, b"plaintext message"); +//! ``` +//! +//! ## Usage with AAD +//! Deoxys can authenticate additionnal data that is not encrypted alongside with the ciphertext. +//! ``` +//! use deoxys::{DeoxysII256, Key, Nonce}; // Can be `DeoxysI128`, `DeoxysI256`, `DeoxysII128` of `DeoxysII256` +//! use deoxys::aead::{Aead, NewAead, Payload}; +//! +//! let key = Key::from_slice(b"an example very very secret key."); +//! let cipher = DeoxysII256::new(key); +//! +//! let nonce = Nonce::from_slice(b"unique nonce123"); // 64-bits for Deoxys-I or 120-bits for Deoxys-II; unique per message +//! +//!let payload = Payload { +//! msg: &b"this will be encrypted".as_ref(), +//! aad: &b"this will NOT be encrypted, but will be authenticated".as_ref(), +//!}; +//! +//! let ciphertext = cipher.encrypt(nonce, payload) +//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! +//! +//!let payload = Payload { +//! msg: &ciphertext, +//! aad: &b"this will NOT be encrypted, but will be authenticated".as_ref(), +//!}; +//! +//! let plaintext = cipher.decrypt(nonce, payload) +//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! +//! +//! assert_eq!(&plaintext, b"this will be encrypted"); +//! ``` +//! +//! ## In-place Usage (eliminates `alloc` requirement) +//! +//! This crate has an optional `alloc` feature which can be disabled in e.g. +//! microcontroller environments that don't have a heap. +//! +//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! methods accept any type that impls the [`aead::Buffer`] trait which +//! contains the plaintext for encryption or ciphertext for decryption. +//! +//! Note that if you enable the `heapless` feature of this crate, +//! you will receive an impl of [`aead::Buffer`] for `heapless::Vec` +//! (re-exported from the [`aead`] crate as [`aead::heapless::Vec`]), +//! which can then be passed as the `buffer` parameter to the in-place encrypt +//! and decrypt methods: +//! +//! ``` +//! # #[cfg(feature = "heapless")] +//! # { +//! use deoxys::{DeoxysII256, Key, Nonce}; // Can be `DeoxysI128`, `DeoxysI256`, `DeoxysII128` of `DeoxysII256` +//! use deoxys::aead::{AeadInPlace, NewAead}; +//! use deoxys::aead::heapless::Vec; +//! +//! let key = Key::from_slice(b"an example very very secret key."); +//! let cipher = DeoxysII256::new(key); +//! +//! let nonce = Nonce::from_slice(b"unique nonce123"); // 64-bits for Deoxys-I or 120-bits for Deoxys-II; unique per message +//! +//! let mut buffer: Vec = Vec::new(); // Buffer needs 16-bytes overhead for tag +//! buffer.extend_from_slice(b"plaintext message"); +//! +//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext +//! cipher.encrypt_in_place(nonce, b"", &mut buffer).expect("encryption failure!"); +//! +//! // `buffer` now contains the message ciphertext +//! assert_ne!(&buffer, b"plaintext message"); +//! +//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext +//! cipher.decrypt_in_place(nonce, b"", &mut buffer).expect("decryption failure!"); +//! assert_eq!(&buffer, b"plaintext message"); +//! # } +//! ``` +//! +//! [1]: https://en.wikipedia.org/wiki/Authenticated_encryption +//! [2]: https://sites.google.com/view/deoxyscipher +//! [3]: https://competitions.cr.yp.to/caesar-submissions.html #![no_std] #![doc( @@ -7,7 +121,10 @@ )] #![warn(missing_docs, rust_2018_idioms)] +/// Deoxys-BC implementations. pub mod deoxys_bc; + +/// Operation modes for Deoxys. pub mod modes; mod aes_ref; @@ -24,20 +141,39 @@ use aead::{ use zeroize::Zeroize; +/// Deoxys-I with 128-bit keys pub type DeoxysI128 = Deoxys; + +/// Deoxys-I with 256-bit keys pub type DeoxysI256 = Deoxys; + +/// Deoxys-II with 128-bit keys pub type DeoxysII128 = Deoxys; + +/// Deoxys-II with 256-bit keys pub type DeoxysII256 = Deoxys; +/// Deoxys keys pub type Key = GenericArray; + +/// Deoxys nonces +pub type Nonce = GenericArray; + +/// Deoxys tags pub type Tag = GenericArray; +/// Deoxys encryption modes. +/// This type contains the public API for a Deoxys mode, like Deoxys-I and Deoxys-II. +/// Should not be used directly pub trait DeoxysMode where B: DeoxysBcType, { + /// The size of the required nonce type NonceSize: ArrayLength; + /// Encrypts the data in place with the specified parameters + /// Returns the tag fn encrypt_in_place( nonce: &[u8], associated_data: &[u8], @@ -45,6 +181,8 @@ where key: &GenericArray, ) -> [u8; 16]; + /// Decrypts the data in place with the specified parameters + /// Returns an error if the tag verification fails fn decrypt_in_place( nonce: &[u8], associated_data: &[u8], @@ -54,14 +192,26 @@ where ) -> Result<(), aead::Error>; } +/// Deoxys-BC trait. +/// This type contains the public API for Deoxys-BC implementations, which varies depending on the size of the key. +/// Should not be used directly. pub trait DeoxysBcType { + /// The size of the required key. type KeySize: ArrayLength; + + /// The size of the tweakey required for the block cipher. type TweakKeySize: ArrayLength; + /// Encrypts a block of data in place. fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray); + + /// Decrypts a block of data in place. fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray); } +/// Generic Deoxys implementation. +/// +/// This type is generic to support multiple Deoxys modes(namely Deoxys-I and Deoxys-II) and key size. pub struct Deoxys where M: DeoxysMode, @@ -103,7 +253,7 @@ where { fn encrypt_in_place_detached( &self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], ) -> Result { @@ -117,7 +267,7 @@ where fn decrypt_in_place_detached( &self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], tag: &Tag, diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index ed21d29b..da9fd89d 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -15,8 +15,10 @@ const TWEAK_TAG: u8 = 0x10; const TWEAK_M_LAST: u8 = 0x40; const TWEAK_CHKSUM: u8 = 0x50; +/// Implementation of the Deoxys-I mode of operation. pub struct DeoxysI; +/// Implementation of the Deoxys-II mode of operation. pub struct DeoxysII; impl DeoxysMode for DeoxysI From 6cefc22aa9a2c3fb8de72a2e6f29cd6c036f2881 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Mon, 17 May 2021 18:49:39 -0400 Subject: [PATCH 06/24] Generalized Deoxys-BC implementation --- deoxys/src/deoxys_bc.rs | 200 +++++++++++++++------------------------- deoxys/src/lib.rs | 31 +++++-- 2 files changed, 98 insertions(+), 133 deletions(-) diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index 7ac12ac6..fecb795d 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -1,10 +1,8 @@ use aead::{ - consts::{U16, U32, U48}, - generic_array::GenericArray, + consts::{U15, U16, U17, U32, U48}, + generic_array::{ArrayLength, GenericArray}, }; -use crate::aes_ref; - use crate::DeoxysBcType; const H_PERM: [u8; 16] = [1, 6, 11, 12, 5, 10, 15, 0, 9, 14, 3, 4, 13, 2, 7, 8]; @@ -20,160 +18,114 @@ pub struct DeoxysBc256; /// Implementation of the Deoxys-BC384 block cipher pub struct DeoxysBc384; -impl DeoxysBc256 { - fn key_schedule(tweakey: &[u8]) -> [[u8; 16]; 15] { - let mut subkeys: [[u8; 16]; 15] = Default::default(); - let mut tk1 = [0u8; 16]; - let mut tk2 = [0u8; 16]; +pub trait DeoxysBcInternal { + type SubkeysSize: ArrayLength<[u8; 16]>; + type TweakKeySize: ArrayLength; - tk2.copy_from_slice(&tweakey[..16]); - tk1.copy_from_slice(&tweakey[16..32]); + fn generate_subkey(subkey: &mut [u8], tweakey: &[u8], index: usize); - // First key - let rcon = [ - 1, 2, 4, 8, RCON[0], RCON[0], RCON[0], RCON[0], 0, 0, 0, 0, 0, 0, 0, 0, - ]; + fn shuffle_tweakey(tweakey: &mut [u8]); - for i in 0..16 { - subkeys[0][i] = tk1[i] ^ tk2[i] ^ rcon[i]; - } + fn key_schedule(tweakey: &[u8]) -> GenericArray<[u8; 16], Self::SubkeysSize> { + let mut subkeys: GenericArray<[u8; 16], Self::SubkeysSize> = Default::default(); + + let mut tk: GenericArray = Default::default(); + + tk.copy_from_slice(tweakey); + + // First key + Self::generate_subkey(&mut subkeys[0], &tk, 0); // Other keys for (index, subkey) in subkeys[1..].iter_mut().enumerate() { - let rcon = [ - 1, - 2, - 4, - 8, - RCON[index + 1], - RCON[index + 1], - RCON[index + 1], - RCON[index + 1], - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ]; - h_substitution(&mut tk1); - lfsr2(&mut tk2); - h_substitution(&mut tk2); - - for i in 0..16 { - subkey[i] = tk1[i] ^ tk2[i] ^ rcon[i]; - } + Self::shuffle_tweakey(&mut tk); + Self::generate_subkey(subkey, &tk, index + 1); } subkeys } } -impl DeoxysBcType for DeoxysBc256 { - type KeySize = U16; +impl DeoxysBcInternal for DeoxysBc256 { + type SubkeysSize = U15; type TweakKeySize = U32; - fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { - let keys: [[u8; 16]; 15] = Self::key_schedule(tweakey); - - aes_ref::add_round_key(block, &keys[0]); + fn generate_subkey(subkey: &mut [u8], tweakey: &[u8], index: usize) { + let rcon = [ + 1, + 2, + 4, + 8, + RCON[index], + RCON[index], + RCON[index], + RCON[index], + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; - for k in &keys[1..15] { - aes_ref::encrypt_round(block, k) + for i in 0..16 { + subkey[i] = tweakey[i] ^ tweakey[i + 16] ^ rcon[i]; } } - fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { - let keys: [[u8; 16]; 15] = Self::key_schedule(tweakey); - - for k in keys[1..15].iter().rev() { - aes_ref::decrypt_round(block, k) - } - - aes_ref::add_round_key(block, &keys[0]); + fn shuffle_tweakey(tweakey: &mut [u8]) { + h_substitution(&mut tweakey[16..]); + lfsr2(&mut tweakey[..16]); + h_substitution(&mut tweakey[..16]); } } -impl DeoxysBc384 { - fn key_schedule(tweakey: &[u8]) -> [[u8; 16]; 17] { - let mut subkeys: [[u8; 16]; 17] = Default::default(); - let mut tk1 = [0u8; 16]; - let mut tk2 = [0u8; 16]; - let mut tk3 = [0u8; 16]; +impl DeoxysBcType for DeoxysBc256 { + type KeySize = U16; +} - tk3.copy_from_slice(&tweakey[..16]); - tk2.copy_from_slice(&tweakey[16..32]); - tk1.copy_from_slice(&tweakey[32..]); +impl DeoxysBcInternal for DeoxysBc384 { + type SubkeysSize = U17; + type TweakKeySize = U48; - // First key + fn generate_subkey(subkey: &mut [u8], tweakey: &[u8], index: usize) { let rcon = [ - 1, 2, 4, 8, RCON[0], RCON[0], RCON[0], RCON[0], 0, 0, 0, 0, 0, 0, 0, 0, + 1, + 2, + 4, + 8, + RCON[index], + RCON[index], + RCON[index], + RCON[index], + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, ]; for i in 0..16 { - subkeys[0][i] = tk1[i] ^ tk2[i] ^ tk3[i] ^ rcon[i]; - } - - // Other keys - for (index, subkey) in subkeys[1..].iter_mut().enumerate() { - let rcon = [ - 1, - 2, - 4, - 8, - RCON[index + 1], - RCON[index + 1], - RCON[index + 1], - RCON[index + 1], - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ]; - h_substitution(&mut tk1); - lfsr2(&mut tk2); - h_substitution(&mut tk2); - lfsr3(&mut tk3); - h_substitution(&mut tk3); - - for i in 0..16 { - subkey[i] = tk1[i] ^ tk2[i] ^ tk3[i] ^ rcon[i]; - } + subkey[i] = tweakey[i] ^ tweakey[i + 16] ^ tweakey[i + 32] ^ rcon[i]; } + } - subkeys + fn shuffle_tweakey(tweakey: &mut [u8]) { + h_substitution(&mut tweakey[32..]); + lfsr2(&mut tweakey[16..32]); + h_substitution(&mut tweakey[16..32]); + lfsr3(&mut tweakey[..16]); + h_substitution(&mut tweakey[..16]); } } impl DeoxysBcType for DeoxysBc384 { type KeySize = U32; - type TweakKeySize = U48; - - fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { - let keys: [[u8; 16]; 17] = Self::key_schedule(tweakey); - - aes_ref::add_round_key(block, &keys[0]); - - for k in &keys[1..17] { - aes_ref::encrypt_round(block, k) - } - } - - fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { - let keys: [[u8; 16]; 17] = Self::key_schedule(tweakey); - - for k in keys[1..17].iter().rev() { - aes_ref::decrypt_round(block, k) - } - - aes_ref::add_round_key(block, &keys[0]); - } } fn h_substitution(tk: &mut [u8]) { diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index e6d70f3e..aa8f37d7 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -122,10 +122,10 @@ #![warn(missing_docs, rust_2018_idioms)] /// Deoxys-BC implementations. -pub mod deoxys_bc; +mod deoxys_bc; /// Operation modes for Deoxys. -pub mod modes; +mod modes; mod aes_ref; @@ -195,18 +195,31 @@ where /// Deoxys-BC trait. /// This type contains the public API for Deoxys-BC implementations, which varies depending on the size of the key. /// Should not be used directly. -pub trait DeoxysBcType { +pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { /// The size of the required key. type KeySize: ArrayLength; - /// The size of the tweakey required for the block cipher. - type TweakKeySize: ArrayLength; - /// Encrypts a block of data in place. - fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray); + fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { + let keys: GenericArray<[u8; 16], Self::SubkeysSize> = Self::key_schedule(tweakey); + + aes_ref::add_round_key(block, &keys[0]); + + for k in &keys[1..] { + aes_ref::encrypt_round(block, k) + } + } /// Decrypts a block of data in place. - fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray); + fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { + let keys: GenericArray<[u8; 16], Self::SubkeysSize> = Self::key_schedule(tweakey); + + for k in keys[1..].iter().rev() { + aes_ref::decrypt_round(block, k) + } + + aes_ref::add_round_key(block, &keys[0]); + } } /// Generic Deoxys implementation. @@ -217,7 +230,7 @@ where M: DeoxysMode, B: DeoxysBcType, { - key: GenericArray, + key: Key, mode: PhantomData, } From 0713a3c48f6b42ec7560874c5139fa4bdd3724e0 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Mon, 17 May 2021 18:58:50 -0400 Subject: [PATCH 07/24] Made slice size strict in deoxys_bc --- deoxys/src/deoxys_bc.rs | 24 ++++++++++++++++++------ deoxys/src/lib.rs | 5 ++--- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index fecb795d..a038bfcc 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -22,9 +22,13 @@ pub trait DeoxysBcInternal { type SubkeysSize: ArrayLength<[u8; 16]>; type TweakKeySize: ArrayLength; - fn generate_subkey(subkey: &mut [u8], tweakey: &[u8], index: usize); + fn generate_subkey( + subkey: &mut [u8; 16], + tweakey: &GenericArray, + index: usize, + ); - fn shuffle_tweakey(tweakey: &mut [u8]); + fn shuffle_tweakey(tweakey: &mut GenericArray); fn key_schedule(tweakey: &[u8]) -> GenericArray<[u8; 16], Self::SubkeysSize> { let mut subkeys: GenericArray<[u8; 16], Self::SubkeysSize> = Default::default(); @@ -50,7 +54,11 @@ impl DeoxysBcInternal for DeoxysBc256 { type SubkeysSize = U15; type TweakKeySize = U32; - fn generate_subkey(subkey: &mut [u8], tweakey: &[u8], index: usize) { + fn generate_subkey( + subkey: &mut [u8; 16], + tweakey: &GenericArray, + index: usize, + ) { let rcon = [ 1, 2, @@ -75,7 +83,7 @@ impl DeoxysBcInternal for DeoxysBc256 { } } - fn shuffle_tweakey(tweakey: &mut [u8]) { + fn shuffle_tweakey(tweakey: &mut GenericArray) { h_substitution(&mut tweakey[16..]); lfsr2(&mut tweakey[..16]); h_substitution(&mut tweakey[..16]); @@ -90,7 +98,11 @@ impl DeoxysBcInternal for DeoxysBc384 { type SubkeysSize = U17; type TweakKeySize = U48; - fn generate_subkey(subkey: &mut [u8], tweakey: &[u8], index: usize) { + fn generate_subkey( + subkey: &mut [u8; 16], + tweakey: &GenericArray, + index: usize, + ) { let rcon = [ 1, 2, @@ -115,7 +127,7 @@ impl DeoxysBcInternal for DeoxysBc384 { } } - fn shuffle_tweakey(tweakey: &mut [u8]) { + fn shuffle_tweakey(tweakey: &mut GenericArray) { h_substitution(&mut tweakey[32..]); lfsr2(&mut tweakey[16..32]); h_substitution(&mut tweakey[16..32]); diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index aa8f37d7..3111a26c 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -127,6 +127,7 @@ mod deoxys_bc; /// Operation modes for Deoxys. mod modes; +/// Reference implementation of AES. Should be replaced with the `aes` crate whenever it exposes its round function mod aes_ref; use core::marker::PhantomData; @@ -164,7 +165,6 @@ pub type Tag = GenericArray; /// Deoxys encryption modes. /// This type contains the public API for a Deoxys mode, like Deoxys-I and Deoxys-II. -/// Should not be used directly pub trait DeoxysMode where B: DeoxysBcType, @@ -194,9 +194,8 @@ where /// Deoxys-BC trait. /// This type contains the public API for Deoxys-BC implementations, which varies depending on the size of the key. -/// Should not be used directly. pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { - /// The size of the required key. + /// The size of the required tweakey. type KeySize: ArrayLength; /// Encrypts a block of data in place. From 2a0a715a0790491bc9c9d7644cf4758b608a54b1 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Mon, 17 May 2021 20:48:10 -0400 Subject: [PATCH 08/24] Fixed clippy warnings --- deoxys/src/aes_ref/gf256.rs | 2 +- deoxys/src/aes_ref/mod.rs | 48 +++++++++------------- deoxys/src/lib.rs | 2 + deoxys/src/modes.rs | 81 +++++++++++++++++++------------------ 4 files changed, 64 insertions(+), 69 deletions(-) diff --git a/deoxys/src/aes_ref/gf256.rs b/deoxys/src/aes_ref/gf256.rs index fd3be0c4..dadeb6b6 100644 --- a/deoxys/src/aes_ref/gf256.rs +++ b/deoxys/src/aes_ref/gf256.rs @@ -15,7 +15,7 @@ pub fn mul(a: u8, b: u8) -> u8 { for i in 0..8 { if (b >> i) & 1 == 1 { - result = result ^ a; + result ^= a; } a = mul_by_2(a); diff --git a/deoxys/src/aes_ref/mod.rs b/deoxys/src/aes_ref/mod.rs index 8327f3b4..17160820 100644 --- a/deoxys/src/aes_ref/mod.rs +++ b/deoxys/src/aes_ref/mod.rs @@ -51,7 +51,7 @@ const MIX_COLUMNS_MATRIX_INV: [[u8; 4]; 4] = [ pub fn add_round_key(block: &mut [u8], key: &[u8]) { for (x, k) in block.iter_mut().zip(key) { - *x = *x ^ k; + *x ^= k; } } @@ -76,43 +76,35 @@ fn sub_bytes(block: &mut [u8], sbox: &[u8; 256]) { } fn shift_rows_left(block: &mut [u8]) { - let tmp = block[0 * 4 + 1]; - block[0 * 4 + 1] = block[1 * 4 + 1]; - block[1 * 4 + 1] = block[2 * 4 + 1]; + let tmp = block[1]; + block[1] = block[4 + 1]; + block[4 + 1] = block[2 * 4 + 1]; block[2 * 4 + 1] = block[3 * 4 + 1]; block[3 * 4 + 1] = tmp; - let tmp = block[0 * 4 + 2]; - block[0 * 4 + 2] = block[2 * 4 + 2]; - block[2 * 4 + 2] = tmp; - let tmp = block[1 * 4 + 2]; - block[1 * 4 + 2] = block[3 * 4 + 2]; - block[3 * 4 + 2] = tmp; + block.swap(2, 2 * 4 + 2); + block.swap(4 + 2, 3 * 4 + 2); let tmp = block[3 * 4 + 3]; block[3 * 4 + 3] = block[2 * 4 + 3]; - block[2 * 4 + 3] = block[1 * 4 + 3]; - block[1 * 4 + 3] = block[0 * 4 + 3]; - block[0 * 4 + 3] = tmp; + block[2 * 4 + 3] = block[4 + 3]; + block[4 + 3] = block[3]; + block[3] = tmp; } fn shift_rows_right(block: &mut [u8]) { let tmp = block[3 * 4 + 1]; block[3 * 4 + 1] = block[2 * 4 + 1]; - block[2 * 4 + 1] = block[1 * 4 + 1]; - block[1 * 4 + 1] = block[0 * 4 + 1]; - block[0 * 4 + 1] = tmp; - - let tmp = block[0 * 4 + 2]; - block[0 * 4 + 2] = block[2 * 4 + 2]; - block[2 * 4 + 2] = tmp; - let tmp = block[1 * 4 + 2]; - block[1 * 4 + 2] = block[3 * 4 + 2]; - block[3 * 4 + 2] = tmp; - - let tmp = block[0 * 4 + 3]; - block[0 * 4 + 3] = block[1 * 4 + 3]; - block[1 * 4 + 3] = block[2 * 4 + 3]; + block[2 * 4 + 1] = block[4 + 1]; + block[4 + 1] = block[1]; + block[1] = tmp; + + block.swap(2, 2 * 4 + 2); + block.swap(4 + 2, 3 * 4 + 2); + + let tmp = block[3]; + block[3] = block[4 + 3]; + block[4 + 3] = block[2 * 4 + 3]; block[2 * 4 + 3] = block[3 * 4 + 3]; block[3 * 4 + 3] = tmp; } @@ -125,7 +117,7 @@ fn mix_columns(block: &mut [u8], matrix: &[[u8; 4]; 4]) { let mut value = 0; for k in 0..4 { - value = value ^ mul(block[i * 4 + k], matrix[j][k]) + value ^= mul(block[i * 4 + k], matrix[j][k]) } result[i * 4 + j] = value; } diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 3111a26c..6f1bd5d0 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -149,9 +149,11 @@ pub type DeoxysI128 = Deoxys; pub type DeoxysI256 = Deoxys; /// Deoxys-II with 128-bit keys +#[allow(clippy::upper_case_acronyms)] pub type DeoxysII128 = Deoxys; /// Deoxys-II with 256-bit keys +#[allow(clippy::upper_case_acronyms)] pub type DeoxysII256 = Deoxys; /// Deoxys keys diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index da9fd89d..b5396e74 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -19,6 +19,7 @@ const TWEAK_CHKSUM: u8 = 0x50; pub struct DeoxysI; /// Implementation of the Deoxys-II mode of operation. +#[allow(clippy::upper_case_acronyms)] pub struct DeoxysII; impl DeoxysMode for DeoxysI @@ -40,7 +41,7 @@ where tweakey[..key.len()].copy_from_slice(&key); // Associated Data - if associated_data.len() > 0 { + if !associated_data.is_empty() { tweakey[key.len()] = TWEAK_AD; for (index, ad) in associated_data.chunks(16).enumerate() { @@ -54,7 +55,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } else { // Last block @@ -68,7 +69,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } } @@ -83,7 +84,7 @@ where tweakey[key.len() + 8] = nonce[7] << 4; // Message authentication and encryption - if buffer.len() > 0 { + if !buffer.is_empty() { tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M; for (index, data) in buffer.chunks_mut(16).enumerate() { @@ -94,7 +95,7 @@ where if data.len() == 16 { for (c, d) in checksum.iter_mut().zip(data.iter()) { - *c = *c ^ d; + *c ^= d; } B::encrypt_in_place(data, &tweakey); @@ -108,7 +109,7 @@ where block[data.len()] = 0x80; for (c, d) in checksum.iter_mut().zip(block.iter()) { - *c = *c ^ d; + *c ^= d; } block.fill(0); @@ -117,7 +118,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (d, b) in data.iter_mut().zip(block.iter()) { - *d = *d ^ b; + *d ^= b; } // Tag computing. @@ -130,7 +131,7 @@ where B::encrypt_in_place(&mut checksum, &tweakey); for (t, c) in tag.iter_mut().zip(checksum.iter()) { - *t = *t ^ c; + *t ^= c; } } } @@ -147,7 +148,7 @@ where B::encrypt_in_place(&mut checksum, &tweakey); for (t, c) in tag.iter_mut().zip(checksum.iter()) { - *t = *t ^ c; + *t ^= c; } } @@ -170,7 +171,7 @@ where tweakey[..key.len()].copy_from_slice(&key); // Associated Data - if associated_data.len() > 0 { + if !associated_data.is_empty() { tweakey[key.len()] = TWEAK_AD; for (index, ad) in associated_data.chunks(16).enumerate() { @@ -184,7 +185,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } else { // Last block @@ -198,7 +199,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } } @@ -213,7 +214,7 @@ where tweakey[key.len() + 8] = nonce[7] << 4; // Message authentication and encryption - if buffer.len() > 0 { + if !buffer.is_empty() { tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M; for (index, data) in buffer.chunks_mut(16).enumerate() { @@ -226,7 +227,7 @@ where B::decrypt_in_place(data, &tweakey); for (c, d) in checksum.iter_mut().zip(data.iter()) { - *c = *c ^ d; + *c ^= d; } } else { // Last block checksum @@ -236,7 +237,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (d, b) in data.iter_mut().zip(block.iter()) { - *d = *d ^ b; + *d ^= b; } block.fill(0); @@ -245,7 +246,7 @@ where block[data.len()] = 0x80; for (c, d) in checksum.iter_mut().zip(block.iter()) { - *c = *c ^ d; + *c ^= d; } // Tag computing. @@ -258,7 +259,7 @@ where B::encrypt_in_place(&mut checksum, &tweakey); for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) { - *t = *t ^ c; + *t ^= c; } } } @@ -275,7 +276,7 @@ where B::encrypt_in_place(&mut checksum, &tweakey); for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) { - *t = *t ^ c; + *t ^= c; } } @@ -308,7 +309,7 @@ where tweakey[..key.len()].copy_from_slice(&key); // Associated Data - if associated_data.len() > 0 { + if !associated_data.is_empty() { tweakey[key.len()] = TWEAK_AD; for (index, ad) in associated_data.chunks(16).enumerate() { @@ -322,7 +323,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } else { // Last block @@ -336,7 +337,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } } @@ -344,7 +345,7 @@ where tweakey[key.len()..].fill(0); // Message authentication - if buffer.len() > 0 { + if !buffer.is_empty() { tweakey[key.len()] = TWEAK_M; for (index, data) in buffer.chunks(16).enumerate() { @@ -358,7 +359,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } else { // Last block @@ -372,7 +373,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } } @@ -383,7 +384,7 @@ where B::encrypt_in_place(&mut tag, &tweakey); // Message encryption - if buffer.len() > 0 { + if !buffer.is_empty() { tweakey[key.len()..].copy_from_slice(&tag); tweakey[key.len()] |= 0x80; @@ -392,7 +393,7 @@ where // XOR in block numbers for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { - *t = *t ^ i + *t ^= i } if data.len() == 16 { @@ -402,7 +403,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in data.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } else { // Last block @@ -412,13 +413,13 @@ where B::encrypt_in_place(&mut block, &tweakey); for (d, b) in data.iter_mut().zip(block.iter()) { - *d = *d ^ b; + *d ^= b; } } // XOR out block numbers for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { - *t = *t ^ i + *t ^= i } } } @@ -441,7 +442,7 @@ where tweakey[..key.len()].copy_from_slice(&key); // Message decryption - if buffer.len() > 0 { + if !buffer.is_empty() { tweakey[key.len()..].copy_from_slice(&tag); tweakey[key.len()] |= 0x80; @@ -450,7 +451,7 @@ where // XOR in block numbers for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { - *t = *t ^ i + *t ^= i } if data.len() == 16 { @@ -460,7 +461,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in data.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } else { // Last block @@ -470,20 +471,20 @@ where B::encrypt_in_place(&mut block, &tweakey); for (d, b) in data.iter_mut().zip(block.iter()) { - *d = *d ^ b; + *d ^= b; } } // XOR out block numbers for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { - *t = *t ^ i + *t ^= i } } } tweakey[key.len()..].fill(0); // Associated Data - if associated_data.len() > 0 { + if !associated_data.is_empty() { tweakey[key.len()] = TWEAK_AD; for (index, ad) in associated_data.chunks(16).enumerate() { @@ -497,7 +498,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } else { // Last block @@ -511,7 +512,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } } @@ -519,7 +520,7 @@ where tweakey[key.len()..].fill(0); // Message authentication - if buffer.len() > 0 { + if !buffer.is_empty() { tweakey[key.len()] = TWEAK_M; for (index, data) in buffer.chunks(16).enumerate() { @@ -533,7 +534,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } else { // Last block @@ -547,7 +548,7 @@ where B::encrypt_in_place(&mut block, &tweakey); for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t = *t ^ b; + *t ^= b; } } } From fe69b45cb3edfaf010cad729af88621ef9f57306 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Mon, 17 May 2021 22:17:16 -0400 Subject: [PATCH 09/24] Hardware acceleration for the AES round --- deoxys/Cargo.toml | 3 +++ deoxys/src/aes_ref/mod.rs | 7 ++--- deoxys/src/lib.rs | 56 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index ce1da1f5..0837c994 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -17,6 +17,9 @@ aead = { version = "0.4", default-features = false } subtle = "2.4.0" zeroize = { version = "1", default-features = false } +[target.'cfg(target_feature="aes")'.dependencies] +aes = {path = "./block-ciphers/aes", features = ["hazmat"]} + [dev-dependencies] aead = { version = "0.4", features = ["dev"], default-features = false } hex-literal = "0.3.1" diff --git a/deoxys/src/aes_ref/mod.rs b/deoxys/src/aes_ref/mod.rs index 17160820..5bc4312f 100644 --- a/deoxys/src/aes_ref/mod.rs +++ b/deoxys/src/aes_ref/mod.rs @@ -40,7 +40,8 @@ const RSBOX: [u8; 256] = [ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, ]; -const MIX_COLUMNS_MATRIX: [[u8; 4]; 4] = [[2, 3, 1, 1], [1, 2, 3, 1], [1, 1, 2, 3], [3, 1, 1, 2]]; +pub const MIX_COLUMNS_MATRIX: [[u8; 4]; 4] = + [[2, 3, 1, 1], [1, 2, 3, 1], [1, 1, 2, 3], [3, 1, 1, 2]]; const MIX_COLUMNS_MATRIX_INV: [[u8; 4]; 4] = [ [14, 11, 13, 9], @@ -49,7 +50,7 @@ const MIX_COLUMNS_MATRIX_INV: [[u8; 4]; 4] = [ [11, 13, 9, 14], ]; -pub fn add_round_key(block: &mut [u8], key: &[u8]) { +fn add_round_key(block: &mut [u8], key: &[u8]) { for (x, k) in block.iter_mut().zip(key) { *x ^= k; } @@ -109,7 +110,7 @@ fn shift_rows_right(block: &mut [u8]) { block[3 * 4 + 3] = tmp; } -fn mix_columns(block: &mut [u8], matrix: &[[u8; 4]; 4]) { +pub fn mix_columns(block: &mut [u8], matrix: &[[u8; 4]; 4]) { let mut result = [0u8; 16]; for i in 0..4 { diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 6f1bd5d0..2abe46d9 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -127,6 +127,9 @@ mod deoxys_bc; /// Operation modes for Deoxys. mod modes; +#[cfg(target_feature = "aes")] +use aes; + /// Reference implementation of AES. Should be replaced with the `aes` crate whenever it exposes its round function mod aes_ref; @@ -204,22 +207,67 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { let keys: GenericArray<[u8; 16], Self::SubkeysSize> = Self::key_schedule(tweakey); - aes_ref::add_round_key(block, &keys[0]); + for (b, k) in block.iter_mut().zip(keys[0].iter()) { + *b ^= k; + } for k in &keys[1..] { - aes_ref::encrypt_round(block, k) + #[cfg(target_feature = "aes")] + aes::round::cipher(block.into(), k.into()); + + #[cfg(not(target_feature = "aes"))] + aes_ref::encrypt_round(block, k); + } + } + + #[cfg(target_feature = "aes")] + /// Decrypts a block of data in place. + fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { + let mut keys: GenericArray<[u8; 16], Self::SubkeysSize> = Self::key_schedule(tweakey); + + let r = keys.len(); + + for (b, k) in block.iter_mut().zip(keys[r - 1].iter()) { + *b ^= k; + } + + // Will be replaced with the aes crate + unsafe { + use core::arch::x86_64::*; + let b = _mm_loadu_si128(block.as_ptr() as *const __m128i); + let out = _mm_aesimc_si128(b); + _mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, out); + } + + for k in keys[..r - 1].iter_mut() { + // Will be replaced with the aes crate + unsafe { + use core::arch::x86_64::*; + let k2 = _mm_loadu_si128(k.as_ptr() as *const __m128i); + let out = _mm_aesimc_si128(k2); + _mm_storeu_si128(k.as_mut_ptr() as *mut __m128i, out); + } } + + for k in keys[..r - 1].iter().rev() { + aes::round::equiv_inv_cipher(block.into(), k.into()); + } + + aes_ref::mix_columns(block, &aes_ref::MIX_COLUMNS_MATRIX); } + #[cfg(not(target_feature = "aes"))] /// Decrypts a block of data in place. fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { let keys: GenericArray<[u8; 16], Self::SubkeysSize> = Self::key_schedule(tweakey); for k in keys[1..].iter().rev() { - aes_ref::decrypt_round(block, k) + aes_ref::decrypt_round(block, k); } - aes_ref::add_round_key(block, &keys[0]); + for (b, k) in block.iter_mut().zip(keys[0].iter()) { + *b ^= k; + } } } From 7b00927f4f69c48678ede3ca876148511777ac71 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 18 May 2021 11:12:06 -0400 Subject: [PATCH 10/24] Deoxys: use aes inv_mix_collumns --- Cargo.lock | 647 ---------------------------------------------- deoxys/Cargo.toml | 2 +- deoxys/src/lib.rs | 19 +- 3 files changed, 5 insertions(+), 663 deletions(-) delete mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 2819a391..00000000 --- a/Cargo.lock +++ /dev/null @@ -1,647 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -# -version = 3 - -[[package]] -name = "aead" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922b33332f54fc0ad13fa3e514601e8d30fb54e1f3eadc36643f6526db645621" -dependencies = [ - "blobby", - "generic-array", - "heapless", - "rand_core 0.6.2", -] - -[[package]] -name = "aes" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2333ac5777aaa1beb8589f5374976ae7dc8aa4f09fd21ae3d8662ca97f5247d" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", - "opaque-debug", -] - -[[package]] -name = "aes-gcm" -version = "0.9.2" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "hex-literal 0.2.1", - "subtle", - "zeroize", -] - -[[package]] -name = "aes-gcm-siv" -version = "0.10.0" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "polyval", - "subtle", - "zeroize", -] - -[[package]] -name = "aes-siv" -version = "0.6.0" -dependencies = [ - "aead", - "aes", - "blobby", - "cipher", - "cmac", - "crypto-mac", - "ctr", - "dbl", - "hex-literal 0.2.1", - "pmac", - "zeroize", -] - -[[package]] -name = "atomic-polyfill" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30302dda7a66f8c55932ebf208f7def840743ff64d495e9ceffcd97c18f11d39" -dependencies = [ - "cortex-m", -] - -[[package]] -name = "bare-metal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" -dependencies = [ - "rustc_version", -] - -[[package]] -name = "bitfield" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" - -[[package]] -name = "blobby" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc52553543ecb104069b0ff9e0fcc5c739ad16202935528a112d974e8f1a4ee8" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "ccm" -version = "0.4.0" -dependencies = [ - "aead", - "aes", - "cipher", - "hex-literal 0.2.1", - "subtle", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chacha20" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee7ad89dc1128635074c268ee661f90c3f7e83d9fd12910608c36b47d6c3412" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", - "zeroize", -] - -[[package]] -name = "chacha20poly1305" -version = "0.8.0" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cmac" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b70e37282d9624283878ffda1d1e53883bcf868cf441bddda44127620b39572d" -dependencies = [ - "crypto-mac", - "dbl", -] - -[[package]] -name = "cortex-m" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643a210c1bdc23d0db511e2a576082f4ff4dcae9d0c37f50b431b8f8439d6d6b" -dependencies = [ - "bare-metal", - "bitfield", - "embedded-hal", - "volatile-register", -] - -[[package]] -name = "cpufeatures" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-mac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" -dependencies = [ - "cipher", - "generic-array", - "subtle", -] - -[[package]] -name = "crypto_box" -version = "0.6.0" -dependencies = [ - "chacha20", - "chacha20poly1305", - "rand_core 0.6.2", - "salsa20", - "x25519-dalek", - "xsalsa20poly1305", - "zeroize", -] - -[[package]] -name = "ctr" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" -dependencies = [ - "cipher", -] - -[[package]] -name = "curve25519-dalek" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "dbl" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e797687b5f09528a48fcb63b6914d0255b8a6c760699a919af37042f09d9b3" -dependencies = [ - "generic-array", -] - -[[package]] -name = "deoxys" -version = "0.1.0" -dependencies = [ - "aead", - "hex-literal 0.3.1", - "subtle", - "zeroize", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "eax" -version = "0.4.0" -dependencies = [ - "aead", - "aes", - "cipher", - "cmac", - "ctr", - "subtle", -] - -[[package]] -name = "embedded-hal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db184d3fa27bc7a2344250394c0264144dfe0bc81a4401801dcb964b8dd172ad" -dependencies = [ - "nb 0.1.3", - "void", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "ghash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bbd60caa311237d508927dbba7594b483db3ef05faa55172fcf89b1bcda7853" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - -[[package]] -name = "heapless" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94c13b78b595d2adbd708bce276664f1047f98fc32ddbf463b4c191158334a6" -dependencies = [ - "atomic-polyfill", - "hash32", - "stable_deref_trait", -] - -[[package]] -name = "hex-literal" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" -dependencies = [ - "hex-literal-impl", - "proc-macro-hack", -] - -[[package]] -name = "hex-literal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" - -[[package]] -name = "hex-literal-impl" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" -dependencies = [ - "proc-macro-hack", -] - -[[package]] -name = "kuznyechik" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1020a37e326b4033680520bf26d4ec7366f92827e5d2c5620a38511f2fd732c5" -dependencies = [ - "cipher", -] - -[[package]] -name = "libc" -version = "0.2.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" - -[[package]] -name = "mgm" -version = "0.4.1" -dependencies = [ - "aead", - "cipher", - "hex-literal 0.2.1", - "kuznyechik", - "subtle", -] - -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.0.0", -] - -[[package]] -name = "nb" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pmac" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d8c6aafab3b7131a8be27ae259e545c20c067163c39897419686684de0e013" -dependencies = [ - "crypto-mac", - "dbl", -] - -[[package]] -name = "poly1305" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe800695325da85083cd23b56826fccb2e2dc29b218e7811a6f33bc93f414be" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e597450cbf209787f0e6de80bf3795c6b2356a380ee87837b545aded8dbc1823" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "salsa20" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7c5f10864beba947e1a1b43f3ef46c8cc58d1c2ae549fa471713e8ff60787a" -dependencies = [ - "cipher", - "zeroize", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "subtle" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" - -[[package]] -name = "syn" -version = "1.0.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "synstructure" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - -[[package]] -name = "typenum" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "universal-hash" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "vcell" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "volatile-register" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" -dependencies = [ - "vcell", -] - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "x25519-dalek" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" -dependencies = [ - "curve25519-dalek", - "rand_core 0.5.1", - "zeroize", -] - -[[package]] -name = "xsalsa20poly1305" -version = "0.7.1" -dependencies = [ - "aead", - "poly1305", - "rand_core 0.6.2", - "salsa20", - "subtle", - "zeroize", -] - -[[package]] -name = "zeroize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index 0837c994..b963c56d 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -18,7 +18,7 @@ subtle = "2.4.0" zeroize = { version = "1", default-features = false } [target.'cfg(target_feature="aes")'.dependencies] -aes = {path = "./block-ciphers/aes", features = ["hazmat"]} +aes = { git = "https://github.com/RustCrypto/block-ciphers", rev="45061f3aafc97e082eb398b368d1f97453465ebd", features=["hazmat"]} [dev-dependencies] aead = { version = "0.4", features = ["dev"], default-features = false } diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 2abe46d9..880625ac 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -213,7 +213,7 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { for k in &keys[1..] { #[cfg(target_feature = "aes")] - aes::round::cipher(block.into(), k.into()); + aes::hazmat::cipher_round(block.into(), k.into()); #[cfg(not(target_feature = "aes"))] aes_ref::encrypt_round(block, k); @@ -231,26 +231,15 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { *b ^= k; } - // Will be replaced with the aes crate - unsafe { - use core::arch::x86_64::*; - let b = _mm_loadu_si128(block.as_ptr() as *const __m128i); - let out = _mm_aesimc_si128(b); - _mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, out); - } + aes::hazmat::inv_mix_columns(block.into()); for k in keys[..r - 1].iter_mut() { // Will be replaced with the aes crate - unsafe { - use core::arch::x86_64::*; - let k2 = _mm_loadu_si128(k.as_ptr() as *const __m128i); - let out = _mm_aesimc_si128(k2); - _mm_storeu_si128(k.as_mut_ptr() as *mut __m128i, out); - } + aes::hazmat::inv_mix_columns(k.into()); } for k in keys[..r - 1].iter().rev() { - aes::round::equiv_inv_cipher(block.into(), k.into()); + aes::hazmat::equiv_inv_cipher_round(block.into(), k.into()); } aes_ref::mix_columns(block, &aes_ref::MIX_COLUMNS_MATRIX); From 1b4992d905d26f5ec7ff28d73ce998e426f116dd Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 18 May 2021 11:56:48 -0400 Subject: [PATCH 11/24] Deoxys: use aes mix_collumns --- aes-gcm/Cargo.lock | 320 -------------------------------------- deoxys/Cargo.toml | 2 +- deoxys/src/aes_ref/mod.rs | 5 +- deoxys/src/lib.rs | 4 +- 4 files changed, 5 insertions(+), 326 deletions(-) delete mode 100644 aes-gcm/Cargo.lock diff --git a/aes-gcm/Cargo.lock b/aes-gcm/Cargo.lock deleted file mode 100644 index 625481c6..00000000 --- a/aes-gcm/Cargo.lock +++ /dev/null @@ -1,320 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aead" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922b33332f54fc0ad13fa3e514601e8d30fb54e1f3eadc36643f6526db645621" -dependencies = [ - "blobby", - "generic-array", - "heapless", -] - -[[package]] -name = "aes" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2333ac5777aaa1beb8589f5374976ae7dc8aa4f09fd21ae3d8662ca97f5247d" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", - "opaque-debug", -] - -[[package]] -name = "aes-gcm" -version = "0.9.1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "hex-literal", - "subtle", - "zeroize", -] - -[[package]] -name = "atomic-polyfill" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30302dda7a66f8c55932ebf208f7def840743ff64d495e9ceffcd97c18f11d39" -dependencies = [ - "cortex-m", -] - -[[package]] -name = "bare-metal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" -dependencies = [ - "rustc_version", -] - -[[package]] -name = "bitfield" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" - -[[package]] -name = "blobby" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc52553543ecb104069b0ff9e0fcc5c739ad16202935528a112d974e8f1a4ee8" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cortex-m" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643a210c1bdc23d0db511e2a576082f4ff4dcae9d0c37f50b431b8f8439d6d6b" -dependencies = [ - "bare-metal", - "bitfield", - "embedded-hal", - "volatile-register", -] - -[[package]] -name = "cpufeatures" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" -dependencies = [ - "libc", -] - -[[package]] -name = "ctr" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" -dependencies = [ - "cipher", -] - -[[package]] -name = "embedded-hal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db184d3fa27bc7a2344250394c0264144dfe0bc81a4401801dcb964b8dd172ad" -dependencies = [ - "nb 0.1.3", - "void", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "ghash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bbd60caa311237d508927dbba7594b483db3ef05faa55172fcf89b1bcda7853" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - -[[package]] -name = "heapless" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ee8a997d259962217f40279f34201fdf06e669bafa69d7c1f4c7ff1893b5f6" -dependencies = [ - "atomic-polyfill", - "hash32", - "stable_deref_trait", -] - -[[package]] -name = "hex-literal" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" -dependencies = [ - "hex-literal-impl", - "proc-macro-hack", -] - -[[package]] -name = "hex-literal-impl" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" -dependencies = [ - "proc-macro-hack", -] - -[[package]] -name = "libc" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" - -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.0.0", -] - -[[package]] -name = "nb" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "polyval" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e597450cbf209787f0e6de80bf3795c6b2356a380ee87837b545aded8dbc1823" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "subtle" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" - -[[package]] -name = "typenum" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" - -[[package]] -name = "universal-hash" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "vcell" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "volatile-register" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" -dependencies = [ - "vcell", -] - -[[package]] -name = "zeroize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index b963c56d..901d7342 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -18,7 +18,7 @@ subtle = "2.4.0" zeroize = { version = "1", default-features = false } [target.'cfg(target_feature="aes")'.dependencies] -aes = { git = "https://github.com/RustCrypto/block-ciphers", rev="45061f3aafc97e082eb398b368d1f97453465ebd", features=["hazmat"]} +aes = { git = "https://github.com/RustCrypto/block-ciphers", rev="5e020f14d5fbff531bb6f9f15e9b97c366b8919c", features=["hazmat"]} [dev-dependencies] aead = { version = "0.4", features = ["dev"], default-features = false } diff --git a/deoxys/src/aes_ref/mod.rs b/deoxys/src/aes_ref/mod.rs index 5bc4312f..77a49314 100644 --- a/deoxys/src/aes_ref/mod.rs +++ b/deoxys/src/aes_ref/mod.rs @@ -40,8 +40,7 @@ const RSBOX: [u8; 256] = [ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, ]; -pub const MIX_COLUMNS_MATRIX: [[u8; 4]; 4] = - [[2, 3, 1, 1], [1, 2, 3, 1], [1, 1, 2, 3], [3, 1, 1, 2]]; +const MIX_COLUMNS_MATRIX: [[u8; 4]; 4] = [[2, 3, 1, 1], [1, 2, 3, 1], [1, 1, 2, 3], [3, 1, 1, 2]]; const MIX_COLUMNS_MATRIX_INV: [[u8; 4]; 4] = [ [14, 11, 13, 9], @@ -110,7 +109,7 @@ fn shift_rows_right(block: &mut [u8]) { block[3 * 4 + 3] = tmp; } -pub fn mix_columns(block: &mut [u8], matrix: &[[u8; 4]; 4]) { +fn mix_columns(block: &mut [u8], matrix: &[[u8; 4]; 4]) { let mut result = [0u8; 16]; for i in 0..4 { diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 880625ac..4e0a8ed1 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -131,6 +131,7 @@ mod modes; use aes; /// Reference implementation of AES. Should be replaced with the `aes` crate whenever it exposes its round function +#[cfg(not(target_feature = "aes"))] mod aes_ref; use core::marker::PhantomData; @@ -234,7 +235,6 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { aes::hazmat::inv_mix_columns(block.into()); for k in keys[..r - 1].iter_mut() { - // Will be replaced with the aes crate aes::hazmat::inv_mix_columns(k.into()); } @@ -242,7 +242,7 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { aes::hazmat::equiv_inv_cipher_round(block.into(), k.into()); } - aes_ref::mix_columns(block, &aes_ref::MIX_COLUMNS_MATRIX); + aes::hazmat::mix_columns(block.into()); } #[cfg(not(target_feature = "aes"))] From 78a113961391aa8c1d149e387e89fbd323aba400 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 18 May 2021 12:04:48 -0400 Subject: [PATCH 12/24] Deoxys: small optimisation in deoxys-bc hardware decrypt --- deoxys/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 4e0a8ed1..31ec4019 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -234,12 +234,9 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { aes::hazmat::inv_mix_columns(block.into()); - for k in keys[..r - 1].iter_mut() { + for k in keys[..r - 1].iter_mut().rev() { aes::hazmat::inv_mix_columns(k.into()); - } - - for k in keys[..r - 1].iter().rev() { - aes::hazmat::equiv_inv_cipher_round(block.into(), k.into()); + aes::hazmat::equiv_inv_cipher_round(block.into(), (&*k).into()); } aes::hazmat::mix_columns(block.into()); From 54bb9f8cec58b98cb9112ee6f1ecf2525f8f6037 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 18 May 2021 18:14:36 -0400 Subject: [PATCH 13/24] Bench for Deoxys --- benches/Cargo.toml | 6 +++++ benches/src/deoxys.rs | 63 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 benches/src/deoxys.rs diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 02dc3dba..d364a11d 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -16,6 +16,7 @@ aes = "0.7.0-pre" aes-gcm = { path = "../aes-gcm/" } aes-gcm-siv = { path = "../aes-gcm-siv/" } chacha20poly1305 = { path = "../chacha20poly1305/" } +deoxys = { path = "../deoxys/" } eax = { path = "../eax/" } [[bench]] @@ -33,6 +34,11 @@ name = "chacha20poly1305" path = "src/chacha20poly1305.rs" harness = false +[[bench]] +name = "deoxys" +path = "src/deoxys.rs" +harness = false + [[bench]] name = "eax" path = "src/eax.rs" diff --git a/benches/src/deoxys.rs b/benches/src/deoxys.rs new file mode 100644 index 00000000..9b89f2ff --- /dev/null +++ b/benches/src/deoxys.rs @@ -0,0 +1,63 @@ +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use criterion_cycles_per_byte::CyclesPerByte; + +use deoxys::aead::{Aead, NewAead}; +use deoxys::{DeoxysI128, DeoxysI256, DeoxysII128, DeoxysII256}; + +const KB: usize = 1024; + +fn bench(c: &mut Criterion) { + let mut group = c.benchmark_group("deoxys"); + + for size in &[KB, 2 * KB, 4 * KB, 8 * KB, 16 * KB] { + let buf = vec![0u8; *size]; + + group.throughput(Throughput::Bytes(*size as u64)); + + group.bench_function(BenchmarkId::new("encrypt-I-128", size), |b| { + let cipher = DeoxysI128::new(&Default::default()); + b.iter(|| cipher.encrypt(&Default::default(), &*buf)) + }); + group.bench_function(BenchmarkId::new("decrypt-I-128", size), |b| { + let cipher = DeoxysI128::new(&Default::default()); + b.iter(|| cipher.decrypt(&Default::default(), &*buf)) + }); + + group.bench_function(BenchmarkId::new("encrypt-I-256", size), |b| { + let cipher = DeoxysI256::new(&Default::default()); + b.iter(|| cipher.encrypt(&Default::default(), &*buf)) + }); + group.bench_function(BenchmarkId::new("decrypt-I-256", size), |b| { + let cipher = DeoxysI256::new(&Default::default()); + b.iter(|| cipher.decrypt(&Default::default(), &*buf)) + }); + + + group.bench_function(BenchmarkId::new("encrypt-II-128", size), |b| { + let cipher = DeoxysII128::new(&Default::default()); + b.iter(|| cipher.encrypt(&Default::default(), &*buf)) + }); + group.bench_function(BenchmarkId::new("decrypt-II-128", size), |b| { + let cipher = DeoxysII128::new(&Default::default()); + b.iter(|| cipher.decrypt(&Default::default(), &*buf)) + }); + + group.bench_function(BenchmarkId::new("encrypt-II-256", size), |b| { + let cipher = DeoxysII256::new(&Default::default()); + b.iter(|| cipher.encrypt(&Default::default(), &*buf)) + }); + group.bench_function(BenchmarkId::new("decrypt-II-256", size), |b| { + let cipher = DeoxysII256::new(&Default::default()); + b.iter(|| cipher.decrypt(&Default::default(), &*buf)) + }); + } + + group.finish(); +} + +criterion_group!( + name = benches; + config = Criterion::default().with_measurement(CyclesPerByte); + targets = bench +); +criterion_main!(benches); From 5635f10a4108bdb594f570b8ab2da248e827cb12 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 18 May 2021 20:50:33 -0400 Subject: [PATCH 14/24] Deoxys modes cleanup part 1 --- deoxys/src/deoxys_bc.rs | 6 + deoxys/src/lib.rs | 2 +- deoxys/src/modes.rs | 354 ++++++++++++++++------------------------ 3 files changed, 152 insertions(+), 210 deletions(-) diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index a038bfcc..2ee7ed15 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -150,6 +150,9 @@ fn h_substitution(tk: &mut [u8]) { tk.copy_from_slice(&result[..16]); } +// TODO: This operation is very slow +// On Deoxys-II-256, shuffle_tweakey(), +// which consists of h_substitution and lfsr2 and lfsr3, takes up 65% of the encryption time fn lfsr2(tk: &mut [u8]) { for x in tk { let feedback = (*x >> 5) & 1; @@ -158,6 +161,9 @@ fn lfsr2(tk: &mut [u8]) { } } +// TODO: This operation is very slow +// On Deoxys-II-256, shuffle_tweakey(), +// which consists of h_substitution and lfsr2 and lfsr3, takes up 65% of the encryption time fn lfsr3(tk: &mut [u8]) { for x in tk { let feedback = (*x << 1) & 0x80; diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 31ec4019..809cf46a 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -171,7 +171,7 @@ pub type Tag = GenericArray; /// Deoxys encryption modes. /// This type contains the public API for a Deoxys mode, like Deoxys-I and Deoxys-II. -pub trait DeoxysMode +pub trait DeoxysMode: modes::DeoxysModeInternal where B: DeoxysBcType, { diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index b5396e74..5c22bdd5 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -1,5 +1,6 @@ use aead::{ consts::{U15, U8}, + generic_array::typenum::Unsigned, generic_array::GenericArray, }; use subtle::ConstantTimeEq; @@ -22,31 +23,22 @@ pub struct DeoxysI; #[allow(clippy::upper_case_acronyms)] pub struct DeoxysII; -impl DeoxysMode for DeoxysI +pub trait DeoxysModeInternal where B: DeoxysBcType, { - type NonceSize = U8; - - fn encrypt_in_place( - nonce: &[u8], + fn compute_ad_tag( associated_data: &[u8], - buffer: &mut [u8], - key: &GenericArray, - ) -> [u8; 16] { - let mut tag = [0u8; 16]; - let mut checksum = [0u8; 16]; - let mut tweakey = GenericArray::::default(); - - tweakey[..key.len()].copy_from_slice(&key); - - // Associated Data + tweakey: &mut GenericArray, + tag: &mut [u8], + ) { if !associated_data.is_empty() { - tweakey[key.len()] = TWEAK_AD; + tweakey[B::KeySize::to_usize()] = TWEAK_AD; for (index, ad) in associated_data.chunks(16).enumerate() { // Copy block number - tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&(index as u64).to_be_bytes()); if ad.len() == 16 { let mut block = [0u8; 16]; @@ -59,7 +51,7 @@ where } } else { // Last block - tweakey[key.len()] = TWEAK_AD_LAST; + tweakey[B::KeySize::to_usize()] = TWEAK_AD_LAST; let mut block = [0u8; 16]; block[0..ad.len()].copy_from_slice(ad); @@ -74,24 +66,53 @@ where } } } + } +} + +impl DeoxysModeInternal for DeoxysI where B: DeoxysBcType {} + +impl DeoxysModeInternal for DeoxysII where B: DeoxysBcType {} + +impl DeoxysMode for DeoxysI +where + B: DeoxysBcType, +{ + type NonceSize = U8; + + fn encrypt_in_place( + nonce: &[u8], + associated_data: &[u8], + buffer: &mut [u8], + key: &GenericArray, + ) -> [u8; 16] { + let mut tag = [0u8; 16]; + let mut checksum = [0u8; 16]; + let mut tweakey = GenericArray::::default(); + + tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); + + // Associated Data + >::compute_ad_tag(associated_data, &mut tweakey, &mut tag); // Add the nonce to the tweak - tweakey[key.len()] = nonce[0] >> 4; + tweakey[B::KeySize::to_usize()] = nonce[0] >> 4; for i in 1..nonce.len() { - tweakey[key.len() + i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); + tweakey[B::KeySize::to_usize() + i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); } - tweakey[key.len() + 8] = nonce[7] << 4; + tweakey[B::KeySize::to_usize() + 8] = nonce[7] << 4; // Message authentication and encryption if !buffer.is_empty() { - tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M; + tweakey[B::KeySize::to_usize()] = (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_M; for (index, data) in buffer.chunks_mut(16).enumerate() { // Copy block number - let tmp = tweakey[key.len() + 8] & 0xf0; - tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); - tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&(index as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8] = + (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; if data.len() == 16 { for (c, d) in checksum.iter_mut().zip(data.iter()) { @@ -101,7 +122,8 @@ where B::encrypt_in_place(data, &tweakey); } else { // Last block checksum - tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M_LAST; + tweakey[B::KeySize::to_usize()] = + (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_M_LAST; let mut block = [0u8; 16]; block[0..data.len()].copy_from_slice(data); @@ -122,11 +144,14 @@ where } // Tag computing. - tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_CHKSUM; + tweakey[B::KeySize::to_usize()] = + (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_CHKSUM; - let tmp = tweakey[key.len() + 8] & 0xf0; - tweakey[key.len() + 8..].copy_from_slice(&((index + 1) as u64).to_be_bytes()); - tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&((index + 1) as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8] = + (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; B::encrypt_in_place(&mut checksum, &tweakey); @@ -139,11 +164,12 @@ where if buffer.len() % 16 == 0 { // Tag computing without last block - tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_TAG; + tweakey[B::KeySize::to_usize()] = (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_TAG; - let tmp = tweakey[key.len() + 8] & 0xf0; - tweakey[key.len() + 8..].copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); - tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8] = (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; B::encrypt_in_place(&mut checksum, &tweakey); @@ -168,60 +194,34 @@ where let mut checksum = [0u8; 16]; let mut tweakey = GenericArray::::default(); - tweakey[..key.len()].copy_from_slice(&key); + tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); // Associated Data - if !associated_data.is_empty() { - tweakey[key.len()] = TWEAK_AD; - - for (index, ad) in associated_data.chunks(16).enumerate() { - // Copy block number - tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); - - if ad.len() == 16 { - let mut block = [0u8; 16]; - block.copy_from_slice(ad); - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t ^= b; - } - } else { - // Last block - tweakey[key.len()] = TWEAK_AD_LAST; - - let mut block = [0u8; 16]; - block[0..ad.len()].copy_from_slice(ad); - - block[ad.len()] = 0x80; - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t ^= b; - } - } - } - } + >::compute_ad_tag( + associated_data, + &mut tweakey, + &mut computed_tag, + ); // Add the nonce to the tweak - tweakey[key.len()] = nonce[0] >> 4; + tweakey[B::KeySize::to_usize()] = nonce[0] >> 4; for i in 1..nonce.len() { - tweakey[key.len() + i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); + tweakey[B::KeySize::to_usize() + i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); } - tweakey[key.len() + 8] = nonce[7] << 4; + tweakey[B::KeySize::to_usize() + 8] = nonce[7] << 4; // Message authentication and encryption if !buffer.is_empty() { - tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M; + tweakey[B::KeySize::to_usize()] = (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_M; for (index, data) in buffer.chunks_mut(16).enumerate() { // Copy block number - let tmp = tweakey[key.len() + 8] & 0xf0; - tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); - tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&(index as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8] = + (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; if data.len() == 16 { B::decrypt_in_place(data, &tweakey); @@ -231,7 +231,8 @@ where } } else { // Last block checksum - tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_M_LAST; + tweakey[B::KeySize::to_usize()] = + (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_M_LAST; let mut block = [0u8; 16]; B::encrypt_in_place(&mut block, &tweakey); @@ -250,11 +251,14 @@ where } // Tag computing. - tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_CHKSUM; + tweakey[B::KeySize::to_usize()] = + (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_CHKSUM; - let tmp = tweakey[key.len() + 8] & 0xf0; - tweakey[key.len() + 8..].copy_from_slice(&((index + 1) as u64).to_be_bytes()); - tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&((index + 1) as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8] = + (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; B::encrypt_in_place(&mut checksum, &tweakey); @@ -267,11 +271,12 @@ where if buffer.len() % 16 == 0 { // Tag computing without last block - tweakey[key.len()] = (tweakey[key.len()] & 0xf) | TWEAK_TAG; + tweakey[B::KeySize::to_usize()] = (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_TAG; - let tmp = tweakey[key.len() + 8] & 0xf0; - tweakey[key.len() + 8..].copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); - tweakey[key.len() + 8] = (tweakey[key.len() + 8] & 0xf) | tmp; + let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8] = (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; B::encrypt_in_place(&mut checksum, &tweakey); @@ -306,51 +311,20 @@ where let mut tag = [0u8; 16]; let mut tweakey = GenericArray::::default(); - tweakey[..key.len()].copy_from_slice(&key); + tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); // Associated Data - if !associated_data.is_empty() { - tweakey[key.len()] = TWEAK_AD; - - for (index, ad) in associated_data.chunks(16).enumerate() { - // Copy block number - tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); - - if ad.len() == 16 { - let mut block = [0u8; 16]; - block.copy_from_slice(ad); - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in tag.iter_mut().zip(block.iter()) { - *t ^= b; - } - } else { - // Last block - tweakey[key.len()] = TWEAK_AD_LAST; - - let mut block = [0u8; 16]; - block[0..ad.len()].copy_from_slice(ad); - - block[ad.len()] = 0x80; - - B::encrypt_in_place(&mut block, &tweakey); + >::compute_ad_tag(associated_data, &mut tweakey, &mut tag); - for (t, b) in tag.iter_mut().zip(block.iter()) { - *t ^= b; - } - } - } - } - - tweakey[key.len()..].fill(0); + tweakey[B::KeySize::to_usize()..].fill(0); // Message authentication if !buffer.is_empty() { - tweakey[key.len()] = TWEAK_M; + tweakey[B::KeySize::to_usize()] = TWEAK_M; for (index, data) in buffer.chunks(16).enumerate() { // Copy block number - tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&(index as u64).to_be_bytes()); if data.len() == 16 { let mut block = [0u8; 16]; @@ -363,7 +337,7 @@ where } } else { // Last block - tweakey[key.len()] = TWEAK_M_LAST; + tweakey[B::KeySize::to_usize()] = TWEAK_M_LAST; let mut block = [0u8; 16]; block[0..data.len()].copy_from_slice(data); @@ -379,46 +353,40 @@ where } } - tweakey[key.len()] = TWEAK_TAG; - tweakey[key.len() + 1..].copy_from_slice(&nonce[0..15]); + tweakey[B::KeySize::to_usize()] = TWEAK_TAG; + tweakey[B::KeySize::to_usize() + 1..].copy_from_slice(&nonce[0..15]); B::encrypt_in_place(&mut tag, &tweakey); // Message encryption if !buffer.is_empty() { - tweakey[key.len()..].copy_from_slice(&tag); - tweakey[key.len()] |= 0x80; + tweakey[B::KeySize::to_usize()..].copy_from_slice(&tag); + tweakey[B::KeySize::to_usize()] |= 0x80; for (index, data) in buffer.chunks_mut(16).enumerate() { let index_array = (index as u64).to_be_bytes(); // XOR in block numbers - for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { + for (t, i) in tweakey[B::KeySize::to_usize() + 8..] + .iter_mut() + .zip(&index_array) + { *t ^= i } - if data.len() == 16 { - let mut block = [0u8; 16]; - block[1..].copy_from_slice(&nonce[0..15]); - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in data.iter_mut().zip(block.iter()) { - *t ^= b; - } - } else { - // Last block - let mut block = [0u8; 16]; - block[1..].copy_from_slice(&nonce[0..15]); + let mut block = [0u8; 16]; + block[1..].copy_from_slice(&nonce[0..15]); - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, &tweakey); - for (d, b) in data.iter_mut().zip(block.iter()) { - *d ^= b; - } + for (t, b) in data.iter_mut().zip(block.iter()) { + *t ^= b; } // XOR out block numbers - for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { + for (t, i) in tweakey[B::KeySize::to_usize() + 8..] + .iter_mut() + .zip(&index_array) + { *t ^= i } } @@ -439,93 +407,61 @@ where let mut computed_tag = [0u8; 16]; let mut tweakey = GenericArray::::default(); - tweakey[..key.len()].copy_from_slice(&key); + tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); + + tweakey[B::KeySize::to_usize()..].fill(0); + + // Associated Data + >::compute_ad_tag( + associated_data, + &mut tweakey, + &mut computed_tag, + ); // Message decryption if !buffer.is_empty() { - tweakey[key.len()..].copy_from_slice(&tag); - tweakey[key.len()] |= 0x80; + tweakey[B::KeySize::to_usize()..].copy_from_slice(&tag); + tweakey[B::KeySize::to_usize()] |= 0x80; for (index, data) in buffer.chunks_mut(16).enumerate() { let index_array = (index as u64).to_be_bytes(); // XOR in block numbers - for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { + for (t, i) in tweakey[B::KeySize::to_usize() + 8..] + .iter_mut() + .zip(&index_array) + { *t ^= i } - if data.len() == 16 { - let mut block = [0u8; 16]; - block[1..].copy_from_slice(&nonce[0..15]); - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in data.iter_mut().zip(block.iter()) { - *t ^= b; - } - } else { - // Last block - let mut block = [0u8; 16]; - block[1..].copy_from_slice(&nonce[0..15]); + let mut block = [0u8; 16]; + block[1..].copy_from_slice(&nonce[0..15]); - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, &tweakey); - for (d, b) in data.iter_mut().zip(block.iter()) { - *d ^= b; - } + for (t, b) in data.iter_mut().zip(block.iter()) { + *t ^= b; } // XOR out block numbers - for (t, i) in tweakey[key.len() + 8..].iter_mut().zip(&index_array) { + for (t, i) in tweakey[B::KeySize::to_usize() + 8..] + .iter_mut() + .zip(&index_array) + { *t ^= i } } } - tweakey[key.len()..].fill(0); - // Associated Data - if !associated_data.is_empty() { - tweakey[key.len()] = TWEAK_AD; - - for (index, ad) in associated_data.chunks(16).enumerate() { - // Copy block number - tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); - - if ad.len() == 16 { - let mut block = [0u8; 16]; - block.copy_from_slice(ad); - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t ^= b; - } - } else { - // Last block - tweakey[key.len()] = TWEAK_AD_LAST; - - let mut block = [0u8; 16]; - block[0..ad.len()].copy_from_slice(ad); - - block[ad.len()] = 0x80; - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t ^= b; - } - } - } - } - - tweakey[key.len()..].fill(0); + tweakey[B::KeySize::to_usize()..].fill(0); // Message authentication if !buffer.is_empty() { - tweakey[key.len()] = TWEAK_M; + tweakey[B::KeySize::to_usize()] = TWEAK_M; for (index, data) in buffer.chunks(16).enumerate() { // Copy block number - tweakey[key.len() + 8..].copy_from_slice(&(index as u64).to_be_bytes()); + tweakey[B::KeySize::to_usize() + 8..] + .copy_from_slice(&(index as u64).to_be_bytes()); if data.len() == 16 { let mut block = [0u8; 16]; @@ -538,7 +474,7 @@ where } } else { // Last block - tweakey[key.len()] = TWEAK_M_LAST; + tweakey[B::KeySize::to_usize()] = TWEAK_M_LAST; let mut block = [0u8; 16]; block[0..data.len()].copy_from_slice(data); @@ -554,8 +490,8 @@ where } } - tweakey[key.len()] = TWEAK_TAG; - tweakey[key.len() + 1..].copy_from_slice(&nonce[0..15]); + tweakey[B::KeySize::to_usize()] = TWEAK_TAG; + tweakey[B::KeySize::to_usize() + 1..].copy_from_slice(&nonce[0..15]); B::encrypt_in_place(&mut computed_tag, &tweakey); // Zeroize tweakey since it contains the key From a2bccba784b307ad0adce99f3bf00648b7fd4fa8 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 18 May 2021 21:52:39 -0400 Subject: [PATCH 15/24] Deoxys-II cleanup --- deoxys/src/deoxys_bc.rs | 6 +- deoxys/src/lib.rs | 16 ++-- deoxys/src/modes.rs | 173 ++++++++++++++++------------------------ 3 files changed, 78 insertions(+), 117 deletions(-) diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index 2ee7ed15..c59e5770 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -84,7 +84,7 @@ impl DeoxysBcInternal for DeoxysBc256 { } fn shuffle_tweakey(tweakey: &mut GenericArray) { - h_substitution(&mut tweakey[16..]); + h_substitution(&mut tweakey[16..32]); lfsr2(&mut tweakey[..16]); h_substitution(&mut tweakey[..16]); } @@ -151,7 +151,7 @@ fn h_substitution(tk: &mut [u8]) { } // TODO: This operation is very slow -// On Deoxys-II-256, shuffle_tweakey(), +// On Deoxys-II-256, shuffle_tweakey(), // which consists of h_substitution and lfsr2 and lfsr3, takes up 65% of the encryption time fn lfsr2(tk: &mut [u8]) { for x in tk { @@ -162,7 +162,7 @@ fn lfsr2(tk: &mut [u8]) { } // TODO: This operation is very slow -// On Deoxys-II-256, shuffle_tweakey(), +// On Deoxys-II-256, shuffle_tweakey(), // which consists of h_substitution and lfsr2 and lfsr3, takes up 65% of the encryption time fn lfsr3(tk: &mut [u8]) { for x in tk { diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 809cf46a..1a50f496 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -147,18 +147,18 @@ use aead::{ use zeroize::Zeroize; /// Deoxys-I with 128-bit keys -pub type DeoxysI128 = Deoxys; +pub type DeoxysI128 = Deoxys, deoxys_bc::DeoxysBc256>; /// Deoxys-I with 256-bit keys -pub type DeoxysI256 = Deoxys; +pub type DeoxysI256 = Deoxys, deoxys_bc::DeoxysBc384>; /// Deoxys-II with 128-bit keys #[allow(clippy::upper_case_acronyms)] -pub type DeoxysII128 = Deoxys; +pub type DeoxysII128 = Deoxys, deoxys_bc::DeoxysBc256>; /// Deoxys-II with 256-bit keys #[allow(clippy::upper_case_acronyms)] -pub type DeoxysII256 = Deoxys; +pub type DeoxysII256 = Deoxys, deoxys_bc::DeoxysBc384>; /// Deoxys keys pub type Key = GenericArray; @@ -181,7 +181,7 @@ where /// Encrypts the data in place with the specified parameters /// Returns the tag fn encrypt_in_place( - nonce: &[u8], + nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], key: &GenericArray, @@ -190,10 +190,10 @@ where /// Decrypts the data in place with the specified parameters /// Returns an error if the tag verification fails fn decrypt_in_place( - nonce: &[u8], + nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], - tag: &[u8], + tag: &Tag, key: &GenericArray, ) -> Result<(), aead::Error>; } @@ -306,7 +306,7 @@ where buffer: &mut [u8], ) -> Result { Ok(Tag::from(M::encrypt_in_place( - nonce.as_slice(), + nonce, associated_data, buffer, &self.key, diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index 5c22bdd5..4d70df17 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -1,5 +1,7 @@ +use core::marker::PhantomData; + use aead::{ - consts::{U15, U8}, + consts::{U15, U16, U8}, generic_array::typenum::Unsigned, generic_array::GenericArray, }; @@ -17,11 +19,15 @@ const TWEAK_M_LAST: u8 = 0x40; const TWEAK_CHKSUM: u8 = 0x50; /// Implementation of the Deoxys-I mode of operation. -pub struct DeoxysI; +pub struct DeoxysI { + _ptr: PhantomData, +} /// Implementation of the Deoxys-II mode of operation. #[allow(clippy::upper_case_acronyms)] -pub struct DeoxysII; +pub struct DeoxysII { + _ptr: PhantomData, +} pub trait DeoxysModeInternal where @@ -69,18 +75,18 @@ where } } -impl DeoxysModeInternal for DeoxysI where B: DeoxysBcType {} +impl DeoxysModeInternal for DeoxysI where B: DeoxysBcType {} -impl DeoxysModeInternal for DeoxysII where B: DeoxysBcType {} +impl DeoxysModeInternal for DeoxysII where B: DeoxysBcType {} -impl DeoxysMode for DeoxysI +impl DeoxysMode for DeoxysI where B: DeoxysBcType, { type NonceSize = U8; fn encrypt_in_place( - nonce: &[u8], + nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], key: &GenericArray, @@ -184,10 +190,10 @@ where } fn decrypt_in_place( - nonce: &[u8], + nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], - tag: &[u8], + tag: &GenericArray, key: &GenericArray, ) -> Result<(), aead::Error> { let mut computed_tag = [0u8; 16]; @@ -296,28 +302,15 @@ where } } -impl DeoxysMode for DeoxysII +impl DeoxysII where B: DeoxysBcType, { - type NonceSize = U15; - - fn encrypt_in_place( - nonce: &[u8], - associated_data: &[u8], - buffer: &mut [u8], - key: &GenericArray, - ) -> [u8; 16] { - let mut tag = [0u8; 16]; - let mut tweakey = GenericArray::::default(); - - tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); - - // Associated Data - >::compute_ad_tag(associated_data, &mut tweakey, &mut tag); - - tweakey[B::KeySize::to_usize()..].fill(0); - // Message authentication + fn authenticate_message( + buffer: &[u8], + tweakey: &mut GenericArray, + tag: &mut [u8; 16], + ) { if !buffer.is_empty() { tweakey[B::KeySize::to_usize()] = TWEAK_M; @@ -352,14 +345,16 @@ where } } } + } - tweakey[B::KeySize::to_usize()] = TWEAK_TAG; - tweakey[B::KeySize::to_usize() + 1..].copy_from_slice(&nonce[0..15]); - B::encrypt_in_place(&mut tag, &tweakey); - - // Message encryption + fn encrypt_decrypt_message( + buffer: &mut [u8], + tweakey: &mut GenericArray, + tag: &GenericArray, + nonce: &GenericArray, + ) { if !buffer.is_empty() { - tweakey[B::KeySize::to_usize()..].copy_from_slice(&tag); + tweakey[B::KeySize::to_usize()..].copy_from_slice(tag); tweakey[B::KeySize::to_usize()] |= 0x80; for (index, data) in buffer.chunks_mut(16).enumerate() { @@ -374,7 +369,7 @@ where } let mut block = [0u8; 16]; - block[1..].copy_from_slice(&nonce[0..15]); + block[1..].copy_from_slice(nonce); B::encrypt_in_place(&mut block, &tweakey); @@ -391,6 +386,38 @@ where } } } + } +} + +impl DeoxysMode for DeoxysII +where + B: DeoxysBcType, +{ + type NonceSize = U15; + + fn encrypt_in_place( + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut [u8], + key: &GenericArray, + ) -> [u8; 16] { + let mut tag = [0u8; 16]; + let mut tweakey = GenericArray::::default(); + + tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); + + // Associated Data + >::compute_ad_tag(associated_data, &mut tweakey, &mut tag); + + // Message authentication + Self::authenticate_message(buffer, &mut tweakey, &mut tag); + + tweakey[B::KeySize::to_usize()] = TWEAK_TAG; + tweakey[B::KeySize::to_usize() + 1..].copy_from_slice(&nonce[0..15]); + B::encrypt_in_place(&mut tag, &tweakey); + + // Message encryption + Self::encrypt_decrypt_message(buffer, &mut tweakey, &tag.into(), nonce); // Zeroize tweakey since it contains the key tweakey.zeroize(); @@ -398,10 +425,10 @@ where } fn decrypt_in_place( - nonce: &[u8], + nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], - tag: &[u8], + tag: &GenericArray, key: &GenericArray, ) -> Result<(), aead::Error> { let mut computed_tag = [0u8; 16]; @@ -409,8 +436,6 @@ where tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); - tweakey[B::KeySize::to_usize()..].fill(0); - // Associated Data >::compute_ad_tag( associated_data, @@ -419,76 +444,12 @@ where ); // Message decryption - if !buffer.is_empty() { - tweakey[B::KeySize::to_usize()..].copy_from_slice(&tag); - tweakey[B::KeySize::to_usize()] |= 0x80; - - for (index, data) in buffer.chunks_mut(16).enumerate() { - let index_array = (index as u64).to_be_bytes(); - - // XOR in block numbers - for (t, i) in tweakey[B::KeySize::to_usize() + 8..] - .iter_mut() - .zip(&index_array) - { - *t ^= i - } - - let mut block = [0u8; 16]; - block[1..].copy_from_slice(&nonce[0..15]); - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in data.iter_mut().zip(block.iter()) { - *t ^= b; - } - - // XOR out block numbers - for (t, i) in tweakey[B::KeySize::to_usize() + 8..] - .iter_mut() - .zip(&index_array) - { - *t ^= i - } - } - } + Self::encrypt_decrypt_message(buffer, &mut tweakey, tag, nonce); tweakey[B::KeySize::to_usize()..].fill(0); - // Message authentication - if !buffer.is_empty() { - tweakey[B::KeySize::to_usize()] = TWEAK_M; - - for (index, data) in buffer.chunks(16).enumerate() { - // Copy block number - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&(index as u64).to_be_bytes()); - - if data.len() == 16 { - let mut block = [0u8; 16]; - block.copy_from_slice(data); - - B::encrypt_in_place(&mut block, &tweakey); - for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t ^= b; - } - } else { - // Last block - tweakey[B::KeySize::to_usize()] = TWEAK_M_LAST; - - let mut block = [0u8; 16]; - block[0..data.len()].copy_from_slice(data); - - block[data.len()] = 0x80; - - B::encrypt_in_place(&mut block, &tweakey); - - for (t, b) in computed_tag.iter_mut().zip(block.iter()) { - *t ^= b; - } - } - } - } + // Message authentication + Self::authenticate_message(buffer, &mut tweakey, &mut computed_tag); tweakey[B::KeySize::to_usize()] = TWEAK_TAG; tweakey[B::KeySize::to_usize() + 1..].copy_from_slice(&nonce[0..15]); From a9f894421dccbe23c5fa127857a073cf2d6bb93f Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Wed, 19 May 2021 23:08:56 -0400 Subject: [PATCH 16/24] Deoxys: Compute subkeys in new() --- deoxys/src/deoxys_bc.rs | 195 ++++++++++++++++++++--------------- deoxys/src/lib.rs | 43 +++++--- deoxys/src/modes.rs | 219 ++++++++++++++++++---------------------- 3 files changed, 237 insertions(+), 220 deletions(-) diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index c59e5770..2a227976 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -22,122 +22,149 @@ pub trait DeoxysBcInternal { type SubkeysSize: ArrayLength<[u8; 16]>; type TweakKeySize: ArrayLength; - fn generate_subkey( - subkey: &mut [u8; 16], - tweakey: &GenericArray, - index: usize, - ); - - fn shuffle_tweakey(tweakey: &mut GenericArray); - - fn key_schedule(tweakey: &[u8]) -> GenericArray<[u8; 16], Self::SubkeysSize> { - let mut subkeys: GenericArray<[u8; 16], Self::SubkeysSize> = Default::default(); - - let mut tk: GenericArray = Default::default(); - - tk.copy_from_slice(tweakey); + fn key_schedule( + tweak: &[u8; 16], + subkeys: &GenericArray<[u8; 16], Self::SubkeysSize>, + ) -> GenericArray<[u8; 16], Self::SubkeysSize> { + let mut subtweakeys: GenericArray<[u8; 16], Self::SubkeysSize> = Default::default(); + let mut tweak = *tweak; // First key - Self::generate_subkey(&mut subkeys[0], &tk, 0); + for (i, (s, t)) in tweak.iter().zip(subkeys[0].iter()).enumerate() { + subtweakeys[0][i] = s ^ t + } // Other keys - for (index, subkey) in subkeys[1..].iter_mut().enumerate() { - Self::shuffle_tweakey(&mut tk); - Self::generate_subkey(subkey, &tk, index + 1); + for (stk, sk) in subtweakeys[1..].iter_mut().zip(subkeys[1..].iter()) { + h_substitution(&mut tweak); + + for i in 0..16 { + stk[i] = sk[i] ^ tweak[i]; + } } - subkeys + subtweakeys } } impl DeoxysBcInternal for DeoxysBc256 { type SubkeysSize = U15; type TweakKeySize = U32; +} + +impl DeoxysBcType for DeoxysBc256 { + type KeySize = U16; + + fn precompute_subkeys( + key: &GenericArray, + ) -> GenericArray<[u8; 16], Self::SubkeysSize> { + let mut subkeys: GenericArray<[u8; 16], Self::SubkeysSize> = Default::default(); - fn generate_subkey( - subkey: &mut [u8; 16], - tweakey: &GenericArray, - index: usize, - ) { + let mut buffer: GenericArray = Default::default(); + + buffer.copy_from_slice(key); + + // First key let rcon = [ - 1, - 2, - 4, - 8, - RCON[index], - RCON[index], - RCON[index], - RCON[index], - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, 2, 4, 8, RCON[0], RCON[0], RCON[0], RCON[0], 0, 0, 0, 0, 0, 0, 0, 0, ]; for i in 0..16 { - subkey[i] = tweakey[i] ^ tweakey[i + 16] ^ rcon[i]; + subkeys[0][i] = buffer[i] ^ rcon[i]; } - } - fn shuffle_tweakey(tweakey: &mut GenericArray) { - h_substitution(&mut tweakey[16..32]); - lfsr2(&mut tweakey[..16]); - h_substitution(&mut tweakey[..16]); - } -} + // Other keys + for (index, subkey) in subkeys[1..].iter_mut().enumerate() { + h_substitution(&mut buffer); + lfsr2(&mut buffer); + + let rcon = [ + 1, + 2, + 4, + 8, + RCON[index + 1], + RCON[index + 1], + RCON[index + 1], + RCON[index + 1], + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + + for i in 0..16 { + subkey[i] = buffer[i] ^ rcon[i]; + } + } -impl DeoxysBcType for DeoxysBc256 { - type KeySize = U16; + subkeys + } } impl DeoxysBcInternal for DeoxysBc384 { type SubkeysSize = U17; type TweakKeySize = U48; +} + +impl DeoxysBcType for DeoxysBc384 { + type KeySize = U32; + + fn precompute_subkeys( + key: &GenericArray, + ) -> GenericArray<[u8; 16], Self::SubkeysSize> { + let mut subkeys: GenericArray<[u8; 16], Self::SubkeysSize> = Default::default(); + + let mut buffer: GenericArray = Default::default(); + + buffer.copy_from_slice(key); - fn generate_subkey( - subkey: &mut [u8; 16], - tweakey: &GenericArray, - index: usize, - ) { + // First key let rcon = [ - 1, - 2, - 4, - 8, - RCON[index], - RCON[index], - RCON[index], - RCON[index], - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, 2, 4, 8, RCON[0], RCON[0], RCON[0], RCON[0], 0, 0, 0, 0, 0, 0, 0, 0, ]; for i in 0..16 { - subkey[i] = tweakey[i] ^ tweakey[i + 16] ^ tweakey[i + 32] ^ rcon[i]; + subkeys[0][i] = buffer[i] ^ buffer[i + 16] ^ rcon[i]; } - } - fn shuffle_tweakey(tweakey: &mut GenericArray) { - h_substitution(&mut tweakey[32..]); - lfsr2(&mut tweakey[16..32]); - h_substitution(&mut tweakey[16..32]); - lfsr3(&mut tweakey[..16]); - h_substitution(&mut tweakey[..16]); - } -} + // Other keys + for (index, subkey) in subkeys[1..].iter_mut().enumerate() { + h_substitution(&mut buffer[16..]); + lfsr2(&mut buffer[16..]); + h_substitution(&mut buffer[..16]); + lfsr3(&mut buffer[..16]); + + let rcon = [ + 1, + 2, + 4, + 8, + RCON[index + 1], + RCON[index + 1], + RCON[index + 1], + RCON[index + 1], + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; + + for i in 0..16 { + subkey[i] = buffer[i] ^ buffer[i + 16] ^ rcon[i]; + } + } -impl DeoxysBcType for DeoxysBc384 { - type KeySize = U32; + subkeys + } } fn h_substitution(tk: &mut [u8]) { @@ -147,7 +174,7 @@ fn h_substitution(tk: &mut [u8]) { result[i] = tk[H_PERM[i] as usize]; } - tk.copy_from_slice(&result[..16]); + tk.copy_from_slice(&result); } // TODO: This operation is very slow diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 1a50f496..9ab5d7e3 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -184,7 +184,7 @@ where nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], - key: &GenericArray, + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, ) -> [u8; 16]; /// Decrypts the data in place with the specified parameters @@ -194,7 +194,7 @@ where associated_data: &[u8], buffer: &mut [u8], tag: &Tag, - key: &GenericArray, + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, ) -> Result<(), aead::Error>; } @@ -204,9 +204,16 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { /// The size of the required tweakey. type KeySize: ArrayLength; + /// Precompute the subkeys + fn precompute_subkeys(key: &Key) -> GenericArray<[u8; 16], Self::SubkeysSize>; + /// Encrypts a block of data in place. - fn encrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { - let keys: GenericArray<[u8; 16], Self::SubkeysSize> = Self::key_schedule(tweakey); + fn encrypt_in_place( + block: &mut [u8], + tweak: &[u8; 16], + subkeys: &GenericArray<[u8; 16], Self::SubkeysSize>, + ) { + let keys = Self::key_schedule(tweak, subkeys); for (b, k) in block.iter_mut().zip(keys[0].iter()) { *b ^= k; @@ -223,8 +230,12 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { #[cfg(target_feature = "aes")] /// Decrypts a block of data in place. - fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { - let mut keys: GenericArray<[u8; 16], Self::SubkeysSize> = Self::key_schedule(tweakey); + fn decrypt_in_place( + block: &mut [u8], + tweak: &[u8; 16], + subkeys: &GenericArray<[u8; 16], Self::SubkeysSize>, + ) { + let mut keys = Self::key_schedule(tweak, subkeys); let r = keys.len(); @@ -244,8 +255,12 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { #[cfg(not(target_feature = "aes"))] /// Decrypts a block of data in place. - fn decrypt_in_place(block: &mut [u8], tweakey: &GenericArray) { - let keys: GenericArray<[u8; 16], Self::SubkeysSize> = Self::key_schedule(tweakey); + fn decrypt_in_place( + block: &mut [u8], + tweak: &[u8; 16], + subkeys: &GenericArray<[u8; 16], Self::SubkeysSize>, + ) { + let keys = Self::key_schedule(tweak, subkeys); for k in keys[1..].iter().rev() { aes_ref::decrypt_round(block, k); @@ -265,7 +280,7 @@ where M: DeoxysMode, B: DeoxysBcType, { - key: Key, + subkeys: GenericArray<[u8; 16], B::SubkeysSize>, mode: PhantomData, } @@ -278,7 +293,7 @@ where fn new(key: &Key) -> Self { Self { - key: key.clone(), + subkeys: B::precompute_subkeys(key), mode: PhantomData, } } @@ -309,7 +324,7 @@ where nonce, associated_data, buffer, - &self.key, + &self.subkeys, ))) } @@ -320,7 +335,7 @@ where buffer: &mut [u8], tag: &Tag, ) -> Result<(), Error> { - M::decrypt_in_place(nonce, associated_data, buffer, tag, &self.key) + M::decrypt_in_place(nonce, associated_data, buffer, tag, &self.subkeys) } } @@ -330,6 +345,8 @@ where B: DeoxysBcType, { fn drop(&mut self) { - self.key.as_mut_slice().zeroize(); + for s in self.subkeys.iter_mut() { + s.zeroize(); + } } } diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index 4d70df17..f54a1447 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -2,11 +2,9 @@ use core::marker::PhantomData; use aead::{ consts::{U15, U16, U8}, - generic_array::typenum::Unsigned, generic_array::GenericArray, }; use subtle::ConstantTimeEq; -use zeroize::Zeroize; use super::DeoxysBcType; use super::DeoxysMode; @@ -35,36 +33,36 @@ where { fn compute_ad_tag( associated_data: &[u8], - tweakey: &mut GenericArray, + tweak: &mut [u8; 16], + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, tag: &mut [u8], ) { if !associated_data.is_empty() { - tweakey[B::KeySize::to_usize()] = TWEAK_AD; + tweak[0] = TWEAK_AD; for (index, ad) in associated_data.chunks(16).enumerate() { // Copy block number - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&(index as u64).to_be_bytes()); + tweak[8..].copy_from_slice(&(index as u64).to_be_bytes()); if ad.len() == 16 { let mut block = [0u8; 16]; block.copy_from_slice(ad); - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, tweak, subkeys); for (t, b) in tag.iter_mut().zip(block.iter()) { *t ^= b; } } else { // Last block - tweakey[B::KeySize::to_usize()] = TWEAK_AD_LAST; + tweak[0] = TWEAK_AD_LAST; let mut block = [0u8; 16]; block[0..ad.len()].copy_from_slice(ad); block[ad.len()] = 0x80; - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, tweak, subkeys); for (t, b) in tag.iter_mut().zip(block.iter()) { *t ^= b; @@ -89,47 +87,47 @@ where nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], - key: &GenericArray, + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, ) -> [u8; 16] { let mut tag = [0u8; 16]; let mut checksum = [0u8; 16]; - let mut tweakey = GenericArray::::default(); - - tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); + let mut tweak = [0u8; 16]; // Associated Data - >::compute_ad_tag(associated_data, &mut tweakey, &mut tag); + >::compute_ad_tag( + associated_data, + &mut tweak, + subkeys, + &mut tag, + ); // Add the nonce to the tweak - tweakey[B::KeySize::to_usize()] = nonce[0] >> 4; + tweak[0] = nonce[0] >> 4; for i in 1..nonce.len() { - tweakey[B::KeySize::to_usize() + i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); + tweak[i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); } - tweakey[B::KeySize::to_usize() + 8] = nonce[7] << 4; + tweak[8] = nonce[7] << 4; // Message authentication and encryption if !buffer.is_empty() { - tweakey[B::KeySize::to_usize()] = (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_M; + tweak[0] = (tweak[0] & 0xf) | TWEAK_M; for (index, data) in buffer.chunks_mut(16).enumerate() { // Copy block number - let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&(index as u64).to_be_bytes()); - tweakey[B::KeySize::to_usize() + 8] = - (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; + let tmp = tweak[8] & 0xf0; + tweak[8..].copy_from_slice(&(index as u64).to_be_bytes()); + tweak[8] = (tweak[8] & 0xf) | tmp; if data.len() == 16 { for (c, d) in checksum.iter_mut().zip(data.iter()) { *c ^= d; } - B::encrypt_in_place(data, &tweakey); + B::encrypt_in_place(data, &tweak, subkeys); } else { // Last block checksum - tweakey[B::KeySize::to_usize()] = - (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_M_LAST; + tweak[0] = (tweak[0] & 0xf) | TWEAK_M_LAST; let mut block = [0u8; 16]; block[0..data.len()].copy_from_slice(data); @@ -143,23 +141,20 @@ where block.fill(0); // Last block encryption - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, &tweak, subkeys); for (d, b) in data.iter_mut().zip(block.iter()) { *d ^= b; } // Tag computing. - tweakey[B::KeySize::to_usize()] = - (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_CHKSUM; + tweak[0] = (tweak[0] & 0xf) | TWEAK_CHKSUM; - let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&((index + 1) as u64).to_be_bytes()); - tweakey[B::KeySize::to_usize() + 8] = - (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; + let tmp = tweak[8] & 0xf0; + tweak[8..].copy_from_slice(&((index + 1) as u64).to_be_bytes()); + tweak[8] = (tweak[8] & 0xf) | tmp; - B::encrypt_in_place(&mut checksum, &tweakey); + B::encrypt_in_place(&mut checksum, &tweak, subkeys); for (t, c) in tag.iter_mut().zip(checksum.iter()) { *t ^= c; @@ -170,22 +165,19 @@ where if buffer.len() % 16 == 0 { // Tag computing without last block - tweakey[B::KeySize::to_usize()] = (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_TAG; + tweak[0] = (tweak[0] & 0xf) | TWEAK_TAG; - let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); - tweakey[B::KeySize::to_usize() + 8] = (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; + let tmp = tweak[8] & 0xf0; + tweak[8..].copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); + tweak[8] = (tweak[8] & 0xf) | tmp; - B::encrypt_in_place(&mut checksum, &tweakey); + B::encrypt_in_place(&mut checksum, &tweak, subkeys); for (t, c) in tag.iter_mut().zip(checksum.iter()) { *t ^= c; } } - // Zeroize tweakey since it contains the key - tweakey.zeroize(); tag } @@ -194,54 +186,50 @@ where associated_data: &[u8], buffer: &mut [u8], tag: &GenericArray, - key: &GenericArray, + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, ) -> Result<(), aead::Error> { let mut computed_tag = [0u8; 16]; let mut checksum = [0u8; 16]; - let mut tweakey = GenericArray::::default(); - - tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); + let mut tweak = [0u8; 16]; // Associated Data >::compute_ad_tag( associated_data, - &mut tweakey, + &mut tweak, + subkeys, &mut computed_tag, ); // Add the nonce to the tweak - tweakey[B::KeySize::to_usize()] = nonce[0] >> 4; + tweak[0] = nonce[0] >> 4; for i in 1..nonce.len() { - tweakey[B::KeySize::to_usize() + i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); + tweak[i] = (nonce[i - 1] << 4) | (nonce[i] >> 4); } - tweakey[B::KeySize::to_usize() + 8] = nonce[7] << 4; + tweak[8] = nonce[7] << 4; // Message authentication and encryption if !buffer.is_empty() { - tweakey[B::KeySize::to_usize()] = (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_M; + tweak[0] = (tweak[0] & 0xf) | TWEAK_M; for (index, data) in buffer.chunks_mut(16).enumerate() { // Copy block number - let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&(index as u64).to_be_bytes()); - tweakey[B::KeySize::to_usize() + 8] = - (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; + let tmp = tweak[8] & 0xf0; + tweak[8..].copy_from_slice(&(index as u64).to_be_bytes()); + tweak[8] = (tweak[8] & 0xf) | tmp; if data.len() == 16 { - B::decrypt_in_place(data, &tweakey); + B::decrypt_in_place(data, &tweak, subkeys); for (c, d) in checksum.iter_mut().zip(data.iter()) { *c ^= d; } } else { // Last block checksum - tweakey[B::KeySize::to_usize()] = - (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_M_LAST; + tweak[0] = (tweak[0] & 0xf) | TWEAK_M_LAST; let mut block = [0u8; 16]; - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, &tweak, subkeys); for (d, b) in data.iter_mut().zip(block.iter()) { *d ^= b; @@ -257,16 +245,13 @@ where } // Tag computing. - tweakey[B::KeySize::to_usize()] = - (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_CHKSUM; + tweak[0] = (tweak[0] & 0xf) | TWEAK_CHKSUM; - let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&((index + 1) as u64).to_be_bytes()); - tweakey[B::KeySize::to_usize() + 8] = - (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; + let tmp = tweak[8] & 0xf0; + tweak[8..].copy_from_slice(&((index + 1) as u64).to_be_bytes()); + tweak[8] = (tweak[8] & 0xf) | tmp; - B::encrypt_in_place(&mut checksum, &tweakey); + B::encrypt_in_place(&mut checksum, &tweak, subkeys); for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) { *t ^= c; @@ -277,23 +262,19 @@ where if buffer.len() % 16 == 0 { // Tag computing without last block - tweakey[B::KeySize::to_usize()] = (tweakey[B::KeySize::to_usize()] & 0xf) | TWEAK_TAG; + tweak[0] = (tweak[0] & 0xf) | TWEAK_TAG; - let tmp = tweakey[B::KeySize::to_usize() + 8] & 0xf0; - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); - tweakey[B::KeySize::to_usize() + 8] = (tweakey[B::KeySize::to_usize() + 8] & 0xf) | tmp; + let tmp = tweak[8] & 0xf0; + tweak[8..].copy_from_slice(&((buffer.len() / 16) as u64).to_be_bytes()); + tweak[8] = (tweak[8] & 0xf) | tmp; - B::encrypt_in_place(&mut checksum, &tweakey); + B::encrypt_in_place(&mut checksum, &tweak, subkeys); for (t, c) in computed_tag.iter_mut().zip(checksum.iter()) { *t ^= c; } } - // Zeroize tweakey since it contains the key - tweakey.zeroize(); - if tag.ct_eq(&computed_tag).into() { Ok(()) } else { @@ -308,36 +289,36 @@ where { fn authenticate_message( buffer: &[u8], - tweakey: &mut GenericArray, + tweak: &mut [u8; 16], + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, tag: &mut [u8; 16], ) { if !buffer.is_empty() { - tweakey[B::KeySize::to_usize()] = TWEAK_M; + tweak[0] = TWEAK_M; for (index, data) in buffer.chunks(16).enumerate() { // Copy block number - tweakey[B::KeySize::to_usize() + 8..] - .copy_from_slice(&(index as u64).to_be_bytes()); + tweak[8..].copy_from_slice(&(index as u64).to_be_bytes()); if data.len() == 16 { let mut block = [0u8; 16]; block.copy_from_slice(data); - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, &tweak, subkeys); for (t, b) in tag.iter_mut().zip(block.iter()) { *t ^= b; } } else { // Last block - tweakey[B::KeySize::to_usize()] = TWEAK_M_LAST; + tweak[0] = TWEAK_M_LAST; let mut block = [0u8; 16]; block[0..data.len()].copy_from_slice(data); block[data.len()] = 0x80; - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, &tweak, subkeys); for (t, b) in tag.iter_mut().zip(block.iter()) { *t ^= b; @@ -349,39 +330,34 @@ where fn encrypt_decrypt_message( buffer: &mut [u8], - tweakey: &mut GenericArray, + tweak: &mut [u8; 16], + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, tag: &GenericArray, nonce: &GenericArray, ) { if !buffer.is_empty() { - tweakey[B::KeySize::to_usize()..].copy_from_slice(tag); - tweakey[B::KeySize::to_usize()] |= 0x80; + tweak.copy_from_slice(tag); + tweak[0] |= 0x80; for (index, data) in buffer.chunks_mut(16).enumerate() { let index_array = (index as u64).to_be_bytes(); // XOR in block numbers - for (t, i) in tweakey[B::KeySize::to_usize() + 8..] - .iter_mut() - .zip(&index_array) - { + for (t, i) in tweak[8..].iter_mut().zip(&index_array) { *t ^= i } let mut block = [0u8; 16]; block[1..].copy_from_slice(nonce); - B::encrypt_in_place(&mut block, &tweakey); + B::encrypt_in_place(&mut block, &tweak, subkeys); for (t, b) in data.iter_mut().zip(block.iter()) { *t ^= b; } // XOR out block numbers - for (t, i) in tweakey[B::KeySize::to_usize() + 8..] - .iter_mut() - .zip(&index_array) - { + for (t, i) in tweak[8..].iter_mut().zip(&index_array) { *t ^= i } } @@ -399,28 +375,29 @@ where nonce: &GenericArray, associated_data: &[u8], buffer: &mut [u8], - key: &GenericArray, + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, ) -> [u8; 16] { let mut tag = [0u8; 16]; - let mut tweakey = GenericArray::::default(); - - tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); + let mut tweak = [0u8; 16]; // Associated Data - >::compute_ad_tag(associated_data, &mut tweakey, &mut tag); + >::compute_ad_tag( + associated_data, + &mut tweak, + subkeys, + &mut tag, + ); // Message authentication - Self::authenticate_message(buffer, &mut tweakey, &mut tag); + Self::authenticate_message(buffer, &mut tweak, subkeys, &mut tag); - tweakey[B::KeySize::to_usize()] = TWEAK_TAG; - tweakey[B::KeySize::to_usize() + 1..].copy_from_slice(&nonce[0..15]); - B::encrypt_in_place(&mut tag, &tweakey); + tweak[0] = TWEAK_TAG; + tweak[1..].copy_from_slice(&nonce); + B::encrypt_in_place(&mut tag, &tweak, subkeys); // Message encryption - Self::encrypt_decrypt_message(buffer, &mut tweakey, &tag.into(), nonce); + Self::encrypt_decrypt_message(buffer, &mut tweak, subkeys, &tag.into(), nonce); - // Zeroize tweakey since it contains the key - tweakey.zeroize(); tag } @@ -429,34 +406,30 @@ where associated_data: &[u8], buffer: &mut [u8], tag: &GenericArray, - key: &GenericArray, + subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, ) -> Result<(), aead::Error> { let mut computed_tag = [0u8; 16]; - let mut tweakey = GenericArray::::default(); - - tweakey[..B::KeySize::to_usize()].copy_from_slice(&key); + let mut tweak = [0u8; 16]; // Associated Data >::compute_ad_tag( associated_data, - &mut tweakey, + &mut tweak, + subkeys, &mut computed_tag, ); // Message decryption - Self::encrypt_decrypt_message(buffer, &mut tweakey, tag, nonce); + Self::encrypt_decrypt_message(buffer, &mut tweak, subkeys, tag, nonce); - tweakey[B::KeySize::to_usize()..].fill(0); + tweak.fill(0); // Message authentication - Self::authenticate_message(buffer, &mut tweakey, &mut computed_tag); - - tweakey[B::KeySize::to_usize()] = TWEAK_TAG; - tweakey[B::KeySize::to_usize() + 1..].copy_from_slice(&nonce[0..15]); - B::encrypt_in_place(&mut computed_tag, &tweakey); + Self::authenticate_message(buffer, &mut tweak, subkeys, &mut computed_tag); - // Zeroize tweakey since it contains the key - tweakey.zeroize(); + tweak[0] = TWEAK_TAG; + tweak[1..].copy_from_slice(&nonce); + B::encrypt_in_place(&mut computed_tag, &tweak, &subkeys); if tag.ct_eq(&computed_tag).into() { Ok(()) From 54ade2a33a353148cbfc2eed90f32522bd177ed2 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Thu, 20 May 2021 16:54:20 -0400 Subject: [PATCH 17/24] Deoxys: Helped auto-vectorization --- deoxys/src/aes_ref/mod.rs | 14 +++++++------- deoxys/src/deoxys_bc.rs | 20 +++++++++++--------- deoxys/src/lib.rs | 6 +++--- deoxys/src/modes.rs | 6 ++++-- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/deoxys/src/aes_ref/mod.rs b/deoxys/src/aes_ref/mod.rs index 77a49314..242164ef 100644 --- a/deoxys/src/aes_ref/mod.rs +++ b/deoxys/src/aes_ref/mod.rs @@ -49,33 +49,33 @@ const MIX_COLUMNS_MATRIX_INV: [[u8; 4]; 4] = [ [11, 13, 9, 14], ]; -fn add_round_key(block: &mut [u8], key: &[u8]) { +fn add_round_key(block: &mut [u8; 16], key: &[u8; 16]) { for (x, k) in block.iter_mut().zip(key) { *x ^= k; } } -pub fn encrypt_round(block: &mut [u8], round_key: &[u8]) { +pub fn encrypt_round(block: &mut [u8; 16], round_key: &[u8; 16]) { sub_bytes(block, &SBOX); shift_rows_left(block); mix_columns(block, &MIX_COLUMNS_MATRIX); add_round_key(block, round_key); } -pub fn decrypt_round(block: &mut [u8], round_key: &[u8]) { +pub fn decrypt_round(block: &mut [u8; 16], round_key: &[u8; 16]) { add_round_key(block, round_key); mix_columns(block, &MIX_COLUMNS_MATRIX_INV); shift_rows_right(block); sub_bytes(block, &RSBOX); } -fn sub_bytes(block: &mut [u8], sbox: &[u8; 256]) { +fn sub_bytes(block: &mut [u8; 16], sbox: &[u8; 256]) { for x in block.iter_mut() { *x = sbox[*x as usize]; } } -fn shift_rows_left(block: &mut [u8]) { +fn shift_rows_left(block: &mut [u8; 16]) { let tmp = block[1]; block[1] = block[4 + 1]; block[4 + 1] = block[2 * 4 + 1]; @@ -92,7 +92,7 @@ fn shift_rows_left(block: &mut [u8]) { block[3] = tmp; } -fn shift_rows_right(block: &mut [u8]) { +fn shift_rows_right(block: &mut [u8; 16]) { let tmp = block[3 * 4 + 1]; block[3 * 4 + 1] = block[2 * 4 + 1]; block[2 * 4 + 1] = block[4 + 1]; @@ -109,7 +109,7 @@ fn shift_rows_right(block: &mut [u8]) { block[3 * 4 + 3] = tmp; } -fn mix_columns(block: &mut [u8], matrix: &[[u8; 4]; 4]) { +fn mix_columns(block: &mut [u8; 16], matrix: &[[u8; 4]; 4]) { let mut result = [0u8; 16]; for i in 0..4 { diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index 2a227976..da732b0c 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -3,6 +3,8 @@ use aead::{ generic_array::{ArrayLength, GenericArray}, }; +use core::convert::TryFrom; + use crate::DeoxysBcType; const H_PERM: [u8; 16] = [1, 6, 11, 12, 5, 10, 15, 0, 9, 14, 3, 4, 13, 2, 7, 8]; @@ -75,8 +77,8 @@ impl DeoxysBcType for DeoxysBc256 { // Other keys for (index, subkey) in subkeys[1..].iter_mut().enumerate() { - h_substitution(&mut buffer); - lfsr2(&mut buffer); + h_substitution(<&mut [u8; 16]>::try_from(&mut buffer[0..16]).unwrap()); + lfsr2(<&mut [u8; 16]>::try_from(&mut buffer[0..16]).unwrap()); let rcon = [ 1, @@ -134,10 +136,10 @@ impl DeoxysBcType for DeoxysBc384 { // Other keys for (index, subkey) in subkeys[1..].iter_mut().enumerate() { - h_substitution(&mut buffer[16..]); - lfsr2(&mut buffer[16..]); - h_substitution(&mut buffer[..16]); - lfsr3(&mut buffer[..16]); + h_substitution(<&mut [u8; 16]>::try_from(&mut buffer[16..32]).unwrap()); + lfsr2(<&mut [u8; 16]>::try_from(&mut buffer[16..32]).unwrap()); + h_substitution(<&mut [u8; 16]>::try_from(&mut buffer[0..16]).unwrap()); + lfsr3(<&mut [u8; 16]>::try_from(&mut buffer[0..16]).unwrap()); let rcon = [ 1, @@ -167,7 +169,7 @@ impl DeoxysBcType for DeoxysBc384 { } } -fn h_substitution(tk: &mut [u8]) { +fn h_substitution(tk: &mut [u8; 16]) { let mut result = [0u8; 16]; for i in 0..16 { @@ -180,7 +182,7 @@ fn h_substitution(tk: &mut [u8]) { // TODO: This operation is very slow // On Deoxys-II-256, shuffle_tweakey(), // which consists of h_substitution and lfsr2 and lfsr3, takes up 65% of the encryption time -fn lfsr2(tk: &mut [u8]) { +fn lfsr2(tk: &mut [u8; 16]) { for x in tk { let feedback = (*x >> 5) & 1; *x = x.rotate_left(1); @@ -191,7 +193,7 @@ fn lfsr2(tk: &mut [u8]) { // TODO: This operation is very slow // On Deoxys-II-256, shuffle_tweakey(), // which consists of h_substitution and lfsr2 and lfsr3, takes up 65% of the encryption time -fn lfsr3(tk: &mut [u8]) { +fn lfsr3(tk: &mut [u8; 16]) { for x in tk { let feedback = (*x << 1) & 0x80; *x = x.rotate_right(1); diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 9ab5d7e3..ebd0d682 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -209,7 +209,7 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { /// Encrypts a block of data in place. fn encrypt_in_place( - block: &mut [u8], + block: &mut [u8; 16], tweak: &[u8; 16], subkeys: &GenericArray<[u8; 16], Self::SubkeysSize>, ) { @@ -231,7 +231,7 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { #[cfg(target_feature = "aes")] /// Decrypts a block of data in place. fn decrypt_in_place( - block: &mut [u8], + block: &mut [u8; 16], tweak: &[u8; 16], subkeys: &GenericArray<[u8; 16], Self::SubkeysSize>, ) { @@ -256,7 +256,7 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { #[cfg(not(target_feature = "aes"))] /// Decrypts a block of data in place. fn decrypt_in_place( - block: &mut [u8], + block: &mut [u8; 16], tweak: &[u8; 16], subkeys: &GenericArray<[u8; 16], Self::SubkeysSize>, ) { diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index f54a1447..098c4dee 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -1,3 +1,4 @@ +use core::convert::TryFrom; use core::marker::PhantomData; use aead::{ @@ -35,7 +36,7 @@ where associated_data: &[u8], tweak: &mut [u8; 16], subkeys: &GenericArray<[u8; 16], B::SubkeysSize>, - tag: &mut [u8], + tag: &mut [u8; 16], ) { if !associated_data.is_empty() { tweak[0] = TWEAK_AD; @@ -124,7 +125,7 @@ where *c ^= d; } - B::encrypt_in_place(data, &tweak, subkeys); + B::encrypt_in_place(<&mut [u8; 16]>::try_from(data).unwrap(), &tweak, subkeys); } else { // Last block checksum tweak[0] = (tweak[0] & 0xf) | TWEAK_M_LAST; @@ -219,6 +220,7 @@ where tweak[8] = (tweak[8] & 0xf) | tmp; if data.len() == 16 { + let data = <&mut [u8; 16]>::try_from(data).unwrap(); B::decrypt_in_place(data, &tweak, subkeys); for (c, d) in checksum.iter_mut().zip(data.iter()) { From 9921a726035570fd9c9706931e4fbc9b796d8229 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 25 May 2021 20:37:38 -0400 Subject: [PATCH 18/24] Deoxys: Made some compiler optimisations more explicit --- deoxys/src/deoxys_bc.rs | 135 +++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 77 deletions(-) diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index da732b0c..d945ba76 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -9,9 +9,32 @@ use crate::DeoxysBcType; const H_PERM: [u8; 16] = [1, 6, 11, 12, 5, 10, 15, 0, 9, 14, 3, 4, 13, 2, 7, 8]; -const RCON: [u8; 17] = [ - 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, - 0x72, +macro_rules! gen_rcon { + ($value:expr) => { + [ + 1, 2, 4, 8, $value, $value, $value, $value, 0, 0, 0, 0, 0, 0, 0, 0, + ] + }; +} + +const RCON: [[u8; 16]; 17] = [ + gen_rcon!(0x2f), + gen_rcon!(0x5e), + gen_rcon!(0xbc), + gen_rcon!(0x63), + gen_rcon!(0xc6), + gen_rcon!(0x97), + gen_rcon!(0x35), + gen_rcon!(0x6a), + gen_rcon!(0xd4), + gen_rcon!(0xb3), + gen_rcon!(0x7d), + gen_rcon!(0xfa), + gen_rcon!(0xef), + gen_rcon!(0xc5), + gen_rcon!(0x91), + gen_rcon!(0x39), + gen_rcon!(0x72), ]; /// Implementation of the Deoxys-BC256 block cipher @@ -62,45 +85,26 @@ impl DeoxysBcType for DeoxysBc256 { ) -> GenericArray<[u8; 16], Self::SubkeysSize> { let mut subkeys: GenericArray<[u8; 16], Self::SubkeysSize> = Default::default(); - let mut buffer: GenericArray = Default::default(); + let mut tk2 = [0u8; 16]; - buffer.copy_from_slice(key); + tk2.copy_from_slice(key); // First key - let rcon = [ - 1, 2, 4, 8, RCON[0], RCON[0], RCON[0], RCON[0], 0, 0, 0, 0, 0, 0, 0, 0, - ]; + let rcon = RCON[0]; for i in 0..16 { - subkeys[0][i] = buffer[i] ^ rcon[i]; + subkeys[0][i] = tk2[i] ^ rcon[i]; } // Other keys for (index, subkey) in subkeys[1..].iter_mut().enumerate() { - h_substitution(<&mut [u8; 16]>::try_from(&mut buffer[0..16]).unwrap()); - lfsr2(<&mut [u8; 16]>::try_from(&mut buffer[0..16]).unwrap()); - - let rcon = [ - 1, - 2, - 4, - 8, - RCON[index + 1], - RCON[index + 1], - RCON[index + 1], - RCON[index + 1], - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ]; + h_substitution(&mut tk2); + lfsr2(&mut tk2); + + let rcon = RCON[index + 1]; for i in 0..16 { - subkey[i] = buffer[i] ^ rcon[i]; + subkey[i] = tk2[i] ^ rcon[i]; } } @@ -121,47 +125,30 @@ impl DeoxysBcType for DeoxysBc384 { ) -> GenericArray<[u8; 16], Self::SubkeysSize> { let mut subkeys: GenericArray<[u8; 16], Self::SubkeysSize> = Default::default(); - let mut buffer: GenericArray = Default::default(); + let mut tk3 = [0u8; 16]; + let mut tk2 = [0u8; 16]; - buffer.copy_from_slice(key); + tk3.copy_from_slice(&key[..16]); + tk2.copy_from_slice(&key[16..]); // First key - let rcon = [ - 1, 2, 4, 8, RCON[0], RCON[0], RCON[0], RCON[0], 0, 0, 0, 0, 0, 0, 0, 0, - ]; + let rcon = RCON[0]; for i in 0..16 { - subkeys[0][i] = buffer[i] ^ buffer[i + 16] ^ rcon[i]; + subkeys[0][i] = tk3[i] ^ tk2[i] ^ rcon[i]; } // Other keys for (index, subkey) in subkeys[1..].iter_mut().enumerate() { - h_substitution(<&mut [u8; 16]>::try_from(&mut buffer[16..32]).unwrap()); - lfsr2(<&mut [u8; 16]>::try_from(&mut buffer[16..32]).unwrap()); - h_substitution(<&mut [u8; 16]>::try_from(&mut buffer[0..16]).unwrap()); - lfsr3(<&mut [u8; 16]>::try_from(&mut buffer[0..16]).unwrap()); - - let rcon = [ - 1, - 2, - 4, - 8, - RCON[index + 1], - RCON[index + 1], - RCON[index + 1], - RCON[index + 1], - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ]; + h_substitution(&mut tk2); + lfsr2(&mut tk2); + h_substitution(&mut tk3); + lfsr3(&mut tk3); + + let rcon = RCON[index + 1]; for i in 0..16 { - subkey[i] = buffer[i] ^ buffer[i + 16] ^ rcon[i]; + subkey[i] = tk3[i] ^ tk2[i] ^ rcon[i]; } } @@ -179,24 +166,18 @@ fn h_substitution(tk: &mut [u8; 16]) { tk.copy_from_slice(&result); } -// TODO: This operation is very slow -// On Deoxys-II-256, shuffle_tweakey(), -// which consists of h_substitution and lfsr2 and lfsr3, takes up 65% of the encryption time fn lfsr2(tk: &mut [u8; 16]) { - for x in tk { - let feedback = (*x >> 5) & 1; - *x = x.rotate_left(1); - *x ^= feedback; - } + let mut data = u128::from_ne_bytes(*tk); + data = ((data << 1) & 0xFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE) + | (((data >> 7) ^ (data >> 5)) & 0x01010101010101010101010101010101); + + tk.copy_from_slice(&data.to_ne_bytes()) } -// TODO: This operation is very slow -// On Deoxys-II-256, shuffle_tweakey(), -// which consists of h_substitution and lfsr2 and lfsr3, takes up 65% of the encryption time fn lfsr3(tk: &mut [u8; 16]) { - for x in tk { - let feedback = (*x << 1) & 0x80; - *x = x.rotate_right(1); - *x ^= feedback; - } + let mut data = u128::from_ne_bytes(*tk); + data = ((data >> 1) & 0x7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F) + | (((data << 7) ^ (data << 1)) & 0x80808080808080808080808080808080); + + tk.copy_from_slice(&data.to_ne_bytes()) } From 0380fafb459f1f34238c9b8d4ebfa9fbe3079575 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Wed, 26 May 2021 17:06:00 -0400 Subject: [PATCH 19/24] Deoxys: bumped aes version --- deoxys/Cargo.toml | 2 +- deoxys/src/deoxys_bc.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index 901d7342..398ab68e 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -18,7 +18,7 @@ subtle = "2.4.0" zeroize = { version = "1", default-features = false } [target.'cfg(target_feature="aes")'.dependencies] -aes = { git = "https://github.com/RustCrypto/block-ciphers", rev="5e020f14d5fbff531bb6f9f15e9b97c366b8919c", features=["hazmat"]} +aes = { version = "0.7.3", features=["hazmat"], default-features = false} [dev-dependencies] aead = { version = "0.4", features = ["dev"], default-features = false } diff --git a/deoxys/src/deoxys_bc.rs b/deoxys/src/deoxys_bc.rs index d945ba76..ff974edf 100644 --- a/deoxys/src/deoxys_bc.rs +++ b/deoxys/src/deoxys_bc.rs @@ -3,8 +3,6 @@ use aead::{ generic_array::{ArrayLength, GenericArray}, }; -use core::convert::TryFrom; - use crate::DeoxysBcType; const H_PERM: [u8; 16] = [1, 6, 11, 12, 5, 10, 15, 0, 9, 14, 3, 4, 13, 2, 7, 8]; From a29699902091c45d8f5f6bebf011cd6cdba08893 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Mon, 31 May 2021 20:45:53 -0400 Subject: [PATCH 20/24] Removed unsecure AES fallback --- Cargo.lock | 659 ++++++++++++++++++++++++++++++++++++ deoxys/Cargo.toml | 4 +- deoxys/src/aes_ref/gf256.rs | 25 -- deoxys/src/aes_ref/mod.rs | 230 ------------- deoxys/src/lib.rs | 30 -- 5 files changed, 660 insertions(+), 288 deletions(-) create mode 100644 Cargo.lock delete mode 100644 deoxys/src/aes_ref/gf256.rs delete mode 100644 deoxys/src/aes_ref/mod.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..3fe8f4cb --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,659 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "922b33332f54fc0ad13fa3e514601e8d30fb54e1f3eadc36643f6526db645621" +dependencies = [ + "blobby", + "generic-array", + "heapless", + "rand_core 0.6.2", +] + +[[package]] +name = "aes" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2333ac5777aaa1beb8589f5374976ae7dc8aa4f09fd21ae3d8662ca97f5247d" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes" +version = "0.7.3" +source = "git+https://github.com/RustCrypto/block-ciphers?rev=758169d#758169d470a7d376217f32e60d8a02a5235166ad" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm" +version = "0.9.2" +dependencies = [ + "aead", + "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher", + "ctr", + "ghash", + "hex-literal 0.2.1", + "subtle", + "zeroize", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.10.0" +dependencies = [ + "aead", + "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "aes-siv" +version = "0.6.0" +dependencies = [ + "aead", + "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "blobby", + "cipher", + "cmac", + "crypto-mac", + "ctr", + "dbl", + "hex-literal 0.2.1", + "pmac", + "zeroize", +] + +[[package]] +name = "atomic-polyfill" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30302dda7a66f8c55932ebf208f7def840743ff64d495e9ceffcd97c18f11d39" +dependencies = [ + "cortex-m", +] + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "blobby" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc52553543ecb104069b0ff9e0fcc5c739ad16202935528a112d974e8f1a4ee8" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "ccm" +version = "0.4.0" +dependencies = [ + "aead", + "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher", + "hex-literal 0.2.1", + "subtle", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee7ad89dc1128635074c268ee661f90c3f7e83d9fd12910608c36b47d6c3412" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.8.0" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cmac" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b70e37282d9624283878ffda1d1e53883bcf868cf441bddda44127620b39572d" +dependencies = [ + "crypto-mac", + "dbl", +] + +[[package]] +name = "cortex-m" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643a210c1bdc23d0db511e2a576082f4ff4dcae9d0c37f50b431b8f8439d6d6b" +dependencies = [ + "bare-metal", + "bitfield", + "embedded-hal", + "volatile-register", +] + +[[package]] +name = "cpufeatures" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-mac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" +dependencies = [ + "cipher", + "generic-array", + "subtle", +] + +[[package]] +name = "crypto_box" +version = "0.6.0" +dependencies = [ + "chacha20", + "chacha20poly1305", + "rand_core 0.6.2", + "salsa20", + "x25519-dalek", + "xsalsa20poly1305", + "zeroize", +] + +[[package]] +name = "ctr" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "dbl" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e797687b5f09528a48fcb63b6914d0255b8a6c760699a919af37042f09d9b3" +dependencies = [ + "generic-array", +] + +[[package]] +name = "deoxys" +version = "0.1.0" +dependencies = [ + "aead", + "aes 0.7.3 (git+https://github.com/RustCrypto/block-ciphers?rev=758169d)", + "hex-literal 0.3.1", + "subtle", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "eax" +version = "0.4.0" +dependencies = [ + "aead", + "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher", + "cmac", + "ctr", + "subtle", +] + +[[package]] +name = "embedded-hal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db184d3fa27bc7a2344250394c0264144dfe0bc81a4401801dcb964b8dd172ad" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "ghash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbd60caa311237d508927dbba7594b483db3ef05faa55172fcf89b1bcda7853" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94c13b78b595d2adbd708bce276664f1047f98fc32ddbf463b4c191158334a6" +dependencies = [ + "atomic-polyfill", + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "hex-literal" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +dependencies = [ + "hex-literal-impl", + "proc-macro-hack", +] + +[[package]] +name = "hex-literal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" + +[[package]] +name = "hex-literal-impl" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" +dependencies = [ + "proc-macro-hack", +] + +[[package]] +name = "kuznyechik" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0865d64349fd4b3aaf478b279af022717585d95780c038919c60fe042aff30b0" +dependencies = [ + "cipher", + "opaque-debug", +] + +[[package]] +name = "libc" +version = "0.2.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" + +[[package]] +name = "mgm" +version = "0.4.1" +dependencies = [ + "aead", + "cipher", + "hex-literal 0.2.1", + "kuznyechik", + "subtle", +] + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pmac" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d8c6aafab3b7131a8be27ae259e545c20c067163c39897419686684de0e013" +dependencies = [ + "crypto-mac", + "dbl", +] + +[[package]] +name = "poly1305" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe800695325da85083cd23b56826fccb2e2dc29b218e7811a6f33bc93f414be" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e597450cbf209787f0e6de80bf3795c6b2356a380ee87837b545aded8dbc1823" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "salsa20" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c7c5f10864beba947e1a1b43f3ef46c8cc58d1c2ae549fa471713e8ff60787a" +dependencies = [ + "cipher", + "zeroize", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "subtle" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" + +[[package]] +name = "syn" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "universal-hash" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" +dependencies = [ + "vcell", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "xsalsa20poly1305" +version = "0.7.1" +dependencies = [ + "aead", + "poly1305", + "rand_core 0.6.2", + "salsa20", + "subtle", + "zeroize", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index 398ab68e..bab4cb57 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -16,9 +16,7 @@ categories = ["cryptography", "no-std"] aead = { version = "0.4", default-features = false } subtle = "2.4.0" zeroize = { version = "1", default-features = false } - -[target.'cfg(target_feature="aes")'.dependencies] -aes = { version = "0.7.3", features=["hazmat"], default-features = false} +aes = { git = "https://github.com/RustCrypto/block-ciphers", rev = "758169d", features=["hazmat"], default-features = false} [dev-dependencies] aead = { version = "0.4", features = ["dev"], default-features = false } diff --git a/deoxys/src/aes_ref/gf256.rs b/deoxys/src/aes_ref/gf256.rs deleted file mode 100644 index dadeb6b6..00000000 --- a/deoxys/src/aes_ref/gf256.rs +++ /dev/null @@ -1,25 +0,0 @@ -const ROOT: u8 = 0x1b; - -fn mul_by_2(value: u8) -> u8 { - let multiplied_val = value << 1; - if (value >> 7) == 1 { - multiplied_val ^ ROOT - } else { - multiplied_val - } -} - -pub fn mul(a: u8, b: u8) -> u8 { - let mut a = a; - let mut result = 0; - - for i in 0..8 { - if (b >> i) & 1 == 1 { - result ^= a; - } - - a = mul_by_2(a); - } - - result -} diff --git a/deoxys/src/aes_ref/mod.rs b/deoxys/src/aes_ref/mod.rs deleted file mode 100644 index 242164ef..00000000 --- a/deoxys/src/aes_ref/mod.rs +++ /dev/null @@ -1,230 +0,0 @@ -mod gf256; - -use gf256::mul; - -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, -]; - -const RSBOX: [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, -]; - -const MIX_COLUMNS_MATRIX: [[u8; 4]; 4] = [[2, 3, 1, 1], [1, 2, 3, 1], [1, 1, 2, 3], [3, 1, 1, 2]]; - -const MIX_COLUMNS_MATRIX_INV: [[u8; 4]; 4] = [ - [14, 11, 13, 9], - [9, 14, 11, 13], - [13, 9, 14, 11], - [11, 13, 9, 14], -]; - -fn add_round_key(block: &mut [u8; 16], key: &[u8; 16]) { - for (x, k) in block.iter_mut().zip(key) { - *x ^= k; - } -} - -pub fn encrypt_round(block: &mut [u8; 16], round_key: &[u8; 16]) { - sub_bytes(block, &SBOX); - shift_rows_left(block); - mix_columns(block, &MIX_COLUMNS_MATRIX); - add_round_key(block, round_key); -} - -pub fn decrypt_round(block: &mut [u8; 16], round_key: &[u8; 16]) { - add_round_key(block, round_key); - mix_columns(block, &MIX_COLUMNS_MATRIX_INV); - shift_rows_right(block); - sub_bytes(block, &RSBOX); -} - -fn sub_bytes(block: &mut [u8; 16], sbox: &[u8; 256]) { - for x in block.iter_mut() { - *x = sbox[*x as usize]; - } -} - -fn shift_rows_left(block: &mut [u8; 16]) { - let tmp = block[1]; - block[1] = block[4 + 1]; - block[4 + 1] = block[2 * 4 + 1]; - block[2 * 4 + 1] = block[3 * 4 + 1]; - block[3 * 4 + 1] = tmp; - - block.swap(2, 2 * 4 + 2); - block.swap(4 + 2, 3 * 4 + 2); - - let tmp = block[3 * 4 + 3]; - block[3 * 4 + 3] = block[2 * 4 + 3]; - block[2 * 4 + 3] = block[4 + 3]; - block[4 + 3] = block[3]; - block[3] = tmp; -} - -fn shift_rows_right(block: &mut [u8; 16]) { - let tmp = block[3 * 4 + 1]; - block[3 * 4 + 1] = block[2 * 4 + 1]; - block[2 * 4 + 1] = block[4 + 1]; - block[4 + 1] = block[1]; - block[1] = tmp; - - block.swap(2, 2 * 4 + 2); - block.swap(4 + 2, 3 * 4 + 2); - - let tmp = block[3]; - block[3] = block[4 + 3]; - block[4 + 3] = block[2 * 4 + 3]; - block[2 * 4 + 3] = block[3 * 4 + 3]; - block[3 * 4 + 3] = tmp; -} - -fn mix_columns(block: &mut [u8; 16], matrix: &[[u8; 4]; 4]) { - let mut result = [0u8; 16]; - - for i in 0..4 { - for j in 0..4 { - let mut value = 0; - - for k in 0..4 { - value ^= mul(block[i * 4 + k], matrix[j][k]) - } - result[i * 4 + j] = value; - } - } - - block.copy_from_slice(&result); -} - -// Test data used comes from here: http://www.herongyang.com/Cryptography/AES-Example-Vector-of-AES-Encryption.html -#[test] -fn test_encrypt_round() { - use hex_literal::hex; - - let mut block: [u8; 16] = hex!("00102030405060708090a0b0c0d0e0f0"); - - let key: [u8; 16] = hex!("d6aa74fdd2af72fadaa678f1d6ab76fe"); - - let result: [u8; 16] = hex!("89d810e8855ace682d1843d8cb128fe4"); - - encrypt_round(&mut block, &key); - - assert_eq!(&block, &result) -} - -#[test] -fn test_decrypt_round() { - // This test is lazy and based on the assumption that it encryption is correct and you can decrypt, it's good - use hex_literal::hex; - - let mut block: [u8; 16] = hex!("00102030405060708090a0b0c0d0e0f0"); - - let key: [u8; 16] = hex!("d6aa74fdd2af72fadaa678f1d6ab76fe"); - - let result: [u8; 16] = hex!("89d810e8855ace682d1843d8cb128fe4"); - - let plaintext = block.clone(); - - encrypt_round(&mut block, &key); - - assert_eq!(&block, &result); - - decrypt_round(&mut block, &key); - - assert_eq!(&block, &plaintext); -} - -#[test] -fn test_add_round_key() { - use hex_literal::hex; - - let mut block: [u8; 16] = hex!("00112233445566778899aabbccddeeff"); - - let key: [u8; 16] = hex!("000102030405060708090a0b0c0d0e0f"); - - let result: [u8; 16] = hex!("00102030405060708090a0b0c0d0e0f0"); - - add_round_key(&mut block, &key); - - assert_eq!(&block, &result) -} - -#[test] -fn test_sub_bytes() { - use hex_literal::hex; - - let mut block: [u8; 16] = hex!("00102030405060708090a0b0c0d0e0f0"); - - let result: [u8; 16] = hex!("63cab7040953d051cd60e0e7ba70e18c"); - - let initial = block.clone(); - - sub_bytes(&mut block, &SBOX); - - assert_eq!(&block, &result); - - sub_bytes(&mut block, &RSBOX); - - assert_eq!(&block, &initial); -} - -#[test] -fn test_shift_rows() { - use hex_literal::hex; - - let mut block: [u8; 16] = hex!("63cab7040953d051cd60e0e7ba70e18c"); - - let result: [u8; 16] = hex!("6353e08c0960e104cd70b751bacad0e7"); - - let initial = block.clone(); - - shift_rows_left(&mut block); - - assert_eq!(&block, &result); - - shift_rows_right(&mut block); - - assert_eq!(&block, &initial); -} - -#[test] -fn test_mix_columns() { - use hex_literal::hex; - - let mut block: [u8; 16] = hex!("6353e08c0960e104cd70b751bacad0e7"); - let result: [u8; 16] = hex!("5f72641557f5bc92f7be3b291db9f91a"); - - mix_columns(&mut block, &MIX_COLUMNS_MATRIX); - - assert_eq!(&block, &result) -} diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index ebd0d682..6e4e9aaf 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -127,13 +127,6 @@ mod deoxys_bc; /// Operation modes for Deoxys. mod modes; -#[cfg(target_feature = "aes")] -use aes; - -/// Reference implementation of AES. Should be replaced with the `aes` crate whenever it exposes its round function -#[cfg(not(target_feature = "aes"))] -mod aes_ref; - use core::marker::PhantomData; pub use aead; @@ -220,15 +213,10 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { } for k in &keys[1..] { - #[cfg(target_feature = "aes")] aes::hazmat::cipher_round(block.into(), k.into()); - - #[cfg(not(target_feature = "aes"))] - aes_ref::encrypt_round(block, k); } } - #[cfg(target_feature = "aes")] /// Decrypts a block of data in place. fn decrypt_in_place( block: &mut [u8; 16], @@ -252,24 +240,6 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal { aes::hazmat::mix_columns(block.into()); } - - #[cfg(not(target_feature = "aes"))] - /// Decrypts a block of data in place. - fn decrypt_in_place( - block: &mut [u8; 16], - tweak: &[u8; 16], - subkeys: &GenericArray<[u8; 16], Self::SubkeysSize>, - ) { - let keys = Self::key_schedule(tweak, subkeys); - - for k in keys[1..].iter().rev() { - aes_ref::decrypt_round(block, k); - } - - for (b, k) in block.iter_mut().zip(keys[0].iter()) { - *b ^= k; - } - } } /// Generic Deoxys implementation. From d0e95dfbd6e683bdda0405fd5b4a7f7d7771e698 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 1 Jun 2021 14:54:28 -0400 Subject: [PATCH 21/24] Deoxys: Updated aes crate --- Cargo.lock | 27 ++++++++------------------- deoxys/Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fe8f4cb..6755e96e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,20 +16,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2333ac5777aaa1beb8589f5374976ae7dc8aa4f09fd21ae3d8662ca97f5247d" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", - "opaque-debug", -] - -[[package]] -name = "aes" -version = "0.7.3" -source = "git+https://github.com/RustCrypto/block-ciphers?rev=758169d#758169d470a7d376217f32e60d8a02a5235166ad" +checksum = "495ee669413bfbe9e8cace80f4d3d78e6d8c8d99579f97fb93bde351b185f2d4" dependencies = [ "cfg-if", "cipher", @@ -42,7 +31,7 @@ name = "aes-gcm" version = "0.9.2" dependencies = [ "aead", - "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aes", "cipher", "ctr", "ghash", @@ -56,7 +45,7 @@ name = "aes-gcm-siv" version = "0.10.0" dependencies = [ "aead", - "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aes", "cipher", "ctr", "polyval", @@ -69,7 +58,7 @@ name = "aes-siv" version = "0.6.0" dependencies = [ "aead", - "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aes", "blobby", "cipher", "cmac", @@ -122,7 +111,7 @@ name = "ccm" version = "0.4.0" dependencies = [ "aead", - "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aes", "cipher", "hex-literal 0.2.1", "subtle", @@ -257,7 +246,7 @@ name = "deoxys" version = "0.1.0" dependencies = [ "aead", - "aes 0.7.3 (git+https://github.com/RustCrypto/block-ciphers?rev=758169d)", + "aes", "hex-literal 0.3.1", "subtle", "zeroize", @@ -277,7 +266,7 @@ name = "eax" version = "0.4.0" dependencies = [ "aead", - "aes 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aes", "cipher", "cmac", "ctr", diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index bab4cb57..ea5aac6c 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] aead = { version = "0.4", default-features = false } subtle = "2.4.0" zeroize = { version = "1", default-features = false } -aes = { git = "https://github.com/RustCrypto/block-ciphers", rev = "758169d", features=["hazmat"], default-features = false} +aes = { version = "0.7.4", features=["hazmat"], default-features = false} [dev-dependencies] aead = { version = "0.4", features = ["dev"], default-features = false } From 44358f33479caac7af43af1de05a8148f5fd1055 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 1 Jun 2021 18:18:09 -0400 Subject: [PATCH 22/24] Updated licences --- deoxys/LICENSE-APACHE | 2 +- deoxys/LICENSE-MIT | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deoxys/LICENSE-APACHE b/deoxys/LICENSE-APACHE index 78173fa2..69d3d818 100644 --- a/deoxys/LICENSE-APACHE +++ b/deoxys/LICENSE-APACHE @@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work. same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright [yyyy] [name of copyright owner] +Copyright 2021 The RustCrypto Project Developers Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/deoxys/LICENSE-MIT b/deoxys/LICENSE-MIT index b7f57116..c869ada5 100644 --- a/deoxys/LICENSE-MIT +++ b/deoxys/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2019 The RustCrypto Project Developers +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 From b92c8da370eaffa4116398a696630eeffb3d52dd Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 1 Jun 2021 20:44:37 -0400 Subject: [PATCH 23/24] Added Deoxys to README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a0d3726f..35d4bea8 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ crate. | [`aes-gcm`] | [AES-GCM] | [![crates.io](https://img.shields.io/crates/v/aes-gcm.svg)](https://crates.io/crates/aes-gcm) | [![Documentation](https://docs.rs/aes-gcm/badge.svg)](https://docs.rs/aes-gcm) | ![aes-gcm](https://github.com/RustCrypto/AEADs/workflows/aes-gcm/badge.svg?branch=master&event=push) | | [`aes-siv`] | [AES-SIV] | [![crates.io](https://img.shields.io/crates/v/aes-siv.svg)](https://crates.io/crates/aes-siv) | [![Documentation](https://docs.rs/aes-siv/badge.svg)](https://docs.rs/aes-siv) | ![aes-siv](https://github.com/RustCrypto/AEADs/workflows/aes-siv/badge.svg?branch=master&event=push) | | [`ccm`] | [CCM] | [![crates.io](https://img.shields.io/crates/v/ccm.svg)](https://crates.io/crates/ccm) | [![Documentation](https://docs.rs/ccm/badge.svg)](https://docs.rs/ccm) | ![ccm](https://github.com/RustCrypto/AEADs/workflows/ccm/badge.svg?branch=master&event=push) | -| [`chacha20poly1305`] | [(X)ChaCha20Poly1305] | [![crates.io](https://img.shields.io/crates/v/chacha20poly1305.svg)](https://crates.io/crates/chacha20poly1305) | [![Documentation](https://docs.rs/chacha20poly1305/badge.svg)](https://docs.rs/chacha20poly1305) | ![chacha20poly1305](https://github.com/RustCrypto/AEADs/workflows/chacha20poly1305/badge.svg?branch=master&event=push) +| [`chacha20poly1305`] | [(X)ChaCha20Poly1305] | [![crates.io](https://img.shields.io/crates/v/chacha20poly1305.svg)](https://crates.io/crates/chacha20poly1305) | [![Documentation](https://docs.rs/chacha20poly1305/badge.svg)](https://docs.rs/chacha20poly1305) | ![chacha20poly1305](https://github.com/RustCrypto/AEADs/workflows/chacha20poly1305/badge.svg?branch=master&event=push) | +| [`deoxys`] | [Deoxys-I/II] | [![crates.io](https://img.shields.io/crates/v/deoxys.svg)](https://crates.io/crates/deoxys) | [![Documentation](https://docs.rs/deoxys/badge.svg)](https://docs.rs/deoxys) | ![deoxys](https://github.com/RustCrypto/AEADs/workflows/deoxys/badge.svg?branch=master&event=push) | | [`crypto_box`] | [Curve25519XSalsa20Poly1305] | [![crates.io](https://img.shields.io/crates/v/crypto_box.svg)](https://crates.io/crates/crypto_box) | [![Documentation](https://docs.rs/crypto_box/badge.svg)](https://docs.rs/crypto_box) | ![crypto_box](https://github.com/RustCrypto/AEADs/workflows/crypto_box/badge.svg?branch=master&event=push) | | [`eax`] | [EAX] | [![crates.io](https://img.shields.io/crates/v/eax.svg)](https://crates.io/crates/eax) | [![Documentation](https://docs.rs/eax/badge.svg)](https://docs.rs/eax) | ![eax](https://github.com/RustCrypto/AEADs/workflows/eax/badge.svg?branch=master&event=push) | | [`mgm`] | [MGM] | [![crates.io](https://img.shields.io/crates/v/mgm.svg)](https://crates.io/crates/mgm) | [![Documentation](https://docs.rs/mgm/badge.svg)](https://docs.rs/mgm) | ![mgm](https://github.com/RustCrypto/AEADs/workflows/mgm/badge.svg?branch=master&event=push) | @@ -72,6 +73,7 @@ dual licensed as above, without any additional terms or conditions. [`aes-siv`]: https://github.com/RustCrypto/AEADs/tree/master/aes-siv [`ccm`]: https://github.com/RustCrypto/AEADs/tree/master/ccm [`chacha20poly1305`]: https://github.com/RustCrypto/AEADs/tree/master/chacha20poly1305 +[`deoxys`]: https://github.com/RustCrypto/AEADs/tree/master/deoxys [`crypto_box`]: https://github.com/RustCrypto/AEADs/tree/master/crypto_box [`eax`]: https://github.com/RustCrypto/AEADs/tree/master/eax [`mgm`]: https://github.com/RustCrypto/AEADs/tree/master/mgm @@ -83,6 +85,7 @@ dual licensed as above, without any additional terms or conditions. [AES-GCM-SIV]: https://en.wikipedia.org/wiki/AES-GCM-SIV [AES-SIV]: https://github.com/miscreant/meta/wiki/AES-SIV [CCM]: https://en.wikipedia.org/wiki/CCM_mode +[Deoxys-I/II]: https://sites.google.com/view/deoxyscipher [EAX]: https://en.wikipedia.org/wiki/EAX_mode [MGM]: https://eprint.iacr.org/2019/123.pdf [(X)ChaCha20Poly1305]: https://tools.ietf.org/html/rfc8439 From 8ba77a37a939f15a0453137dd5a4b154260f5873 Mon Sep 17 00:00:00 2001 From: zer0x64 Date: Tue, 1 Jun 2021 20:48:57 -0400 Subject: [PATCH 24/24] Deoxys: updated performance and security notes --- deoxys/src/lib.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 6e4e9aaf..21441077 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -1,21 +1,10 @@ //! The [Deoxys][2] [Authenticated Encryption and Associated Data (AEAD)][1]. //! The Deoxys-II variant has been selected as the first choice for defense in-depth scenario during the [CAESAR competition][3]. //! -//! ## Performance Notes -//! -//! By default this crate will use software implementations of AES. -//! -//! When targeting modern x86/x86_64 CPUs, use the following `RUSTFLAGS` to -//! take advantage of high performance AES-NI and CLMUL CPU intrinsics: -//! -//! ```text -//! RUSTFLAGS="-Ctarget-cpu=sandybridge -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3" -//! ``` -//! //! ## Security Notes //! -//! This crate has NOT received any security audit and is still in pretty early stage. -//! Although encryption and secryption passes the test vector, there is no guarantee that operations happens in constant time. +//! This crate has NOT received any security audit. +//! Although encryption and decryption passes the test vector, there is no guarantee that operations happens in constant time. //! //! **USE AT YOUR OWN RISK.** //!