diff options
Diffstat (limited to 'src/lib/block/des/des_bmi2/des_bmi2.cpp')
-rw-r--r-- | src/lib/block/des/des_bmi2/des_bmi2.cpp | 292 |
1 files changed, 0 insertions, 292 deletions
diff --git a/src/lib/block/des/des_bmi2/des_bmi2.cpp b/src/lib/block/des/des_bmi2/des_bmi2.cpp deleted file mode 100644 index da3f5bd6d..000000000 --- a/src/lib/block/des/des_bmi2/des_bmi2.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* -* (C) 2020 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include <botan/internal/des.h> -#include <botan/internal/rotate.h> -#include <botan/internal/loadstor.h> -#include <immintrin.h> - -namespace Botan { - -namespace { - -namespace DES_BMI2_fn { - -alignas(64) const uint8_t SPBOX_CAT_0[64] = { - 0xE, 0x0, 0x4, 0xF, 0xD, 0x7, 0x1, 0x4, 0x2, 0xE, 0xF, 0x2, 0xB, 0xD, 0x8, 0x1, - 0x3, 0xA, 0xA, 0x6, 0x6, 0xC, 0xC, 0xB, 0x5, 0x9, 0x9, 0x5, 0x0, 0x3, 0x7, 0x8, - 0x4, 0xF, 0x1, 0xC, 0xE, 0x8, 0x8, 0x2, 0xD, 0x4, 0x6, 0x9, 0x2, 0x1, 0xB, 0x7, - 0xF, 0x5, 0xC, 0xB, 0x9, 0x3, 0x7, 0xE, 0x3, 0xA, 0xA, 0x0, 0x5, 0x6, 0x0, 0xD, -}; - -alignas(64) const uint8_t SPBOX_CAT_1[64] = { - 0xF, 0xA, 0x2, 0x7, 0x4, 0x1, 0xD, 0xB, 0x9, 0xF, 0xE, 0x8, 0xA, 0x4, 0x1, 0xD, - 0x6, 0x5, 0xB, 0x0, 0x8, 0x2, 0x7, 0xC, 0x5, 0x9, 0x0, 0x6, 0x3, 0xE, 0xC, 0x3, - 0x0, 0x7, 0xD, 0x4, 0xB, 0xC, 0xE, 0x2, 0xC, 0xA, 0x1, 0xF, 0x7, 0x1, 0x2, 0x8, - 0x3, 0xE, 0x4, 0x9, 0x5, 0xB, 0x9, 0x5, 0x6, 0x0, 0xA, 0x3, 0x8, 0xD, 0xF, 0x6, -}; - -alignas(64) const uint8_t SPBOX_CAT_2[64] = { - 0x3, 0xE, 0x0, 0xD, 0xA, 0x0, 0x7, 0xA, 0x5, 0x9, 0x9, 0x4, 0xF, 0x5, 0xC, 0x3, - 0x8, 0x1, 0xE, 0x2, 0x6, 0xC, 0xD, 0x7, 0xB, 0x6, 0x4, 0xB, 0x1, 0xF, 0x2, 0x8, - 0xE, 0x8, 0x5, 0x3, 0x4, 0xE, 0xA, 0x0, 0x2, 0x5, 0xF, 0xA, 0x9, 0x2, 0x0, 0xD, - 0xB, 0x4, 0x8, 0xF, 0x1, 0x7, 0x6, 0x9, 0xC, 0xB, 0x3, 0xC, 0x7, 0x1, 0xD, 0x6, -}; - -alignas(64) const uint8_t SPBOX_CAT_3[64] = { - 0xD, 0x7, 0x7, 0x2, 0xE, 0xB, 0x9, 0x5, 0x0, 0xC, 0xC, 0xF, 0x3, 0x0, 0xA, 0x9, - 0x1, 0x4, 0x8, 0xD, 0x2, 0x8, 0x5, 0x6, 0xB, 0x1, 0x6, 0xA, 0x4, 0xE, 0xF, 0x3, - 0xA, 0x9, 0xC, 0xF, 0x3, 0x0, 0x0, 0xC, 0x6, 0xA, 0xB, 0x1, 0xD, 0x7, 0x7, 0x2, - 0xF, 0x3, 0x1, 0x4, 0x9, 0x5, 0xE, 0xB, 0x5, 0x6, 0x8, 0xD, 0x2, 0x8, 0x4, 0xE, -}; - -alignas(64) const uint8_t SPBOX_CAT_4[64] = { - 0x1, 0x7, 0x6, 0xD, 0x2, 0x1, 0x8, 0x6, 0xB, 0x2, 0x5, 0xB, 0xD, 0xE, 0x3, 0x8, - 0x4, 0xA, 0xA, 0x0, 0x9, 0xF, 0xF, 0x5, 0xE, 0x9, 0x0, 0xC, 0x7, 0x4, 0xC, 0x3, - 0x2, 0xD, 0x1, 0x4, 0x8, 0x6, 0xD, 0xB, 0x5, 0x8, 0xE, 0x7, 0xB, 0x1, 0x4, 0xE, - 0xF, 0x3, 0xC, 0xF, 0x6, 0x0, 0xA, 0xC, 0x3, 0x5, 0x9, 0x2, 0x0, 0xA, 0x7, 0x9, -}; - -alignas(64) const uint8_t SPBOX_CAT_5[64] = { - 0x9, 0xC, 0x2, 0xF, 0xC, 0x1, 0xF, 0x4, 0xA, 0x7, 0x4, 0x9, 0x5, 0xA, 0x8, 0x3, - 0x0, 0x5, 0xB, 0x2, 0x6, 0xB, 0x1, 0xD, 0xD, 0x0, 0x7, 0xE, 0x3, 0x6, 0xE, 0x8, - 0xA, 0x1, 0xD, 0x6, 0xF, 0x4, 0x3, 0x9, 0x4, 0xA, 0x8, 0x3, 0x9, 0xF, 0x6, 0xC, - 0x7, 0xE, 0x0, 0xD, 0x1, 0x2, 0xC, 0x7, 0x2, 0x5, 0xB, 0x0, 0xE, 0x8, 0x5, 0xB, -}; - -alignas(64) const uint8_t SPBOX_CAT_6[64] = { - 0x4, 0xD, 0xB, 0x0, 0x2, 0xB, 0x7, 0xE, 0xF, 0x4, 0x0, 0x9, 0x1, 0x8, 0xD, 0x3, - 0xA, 0x7, 0x5, 0xA, 0x9, 0xC, 0xE, 0x5, 0xC, 0x2, 0x3, 0xF, 0x6, 0x1, 0x8, 0x6, - 0x8, 0x6, 0x4, 0xB, 0xB, 0xD, 0xD, 0x1, 0x5, 0x8, 0xA, 0x4, 0xE, 0x3, 0x7, 0xE, - 0x3, 0x9, 0xF, 0xC, 0x6, 0x0, 0x1, 0xF, 0x0, 0x7, 0xC, 0x2, 0x9, 0xA, 0x2, 0x5, -}; - -alignas(64) const uint8_t SPBOX_CAT_7[64] = { - 0xB, 0x2, 0x4, 0xF, 0x8, 0xB, 0x1, 0x8, 0x5, 0xC, 0xF, 0x6, 0xE, 0x7, 0x2, 0x1, - 0xC, 0x9, 0xA, 0x3, 0x6, 0x5, 0xD, 0xE, 0x3, 0x0, 0x0, 0xD, 0x9, 0xA, 0x7, 0x4, - 0x7, 0x4, 0xE, 0x2, 0x1, 0xD, 0x2, 0x7, 0xA, 0x1, 0x9, 0xC, 0xD, 0x8, 0x4, 0xB, - 0x0, 0xF, 0x5, 0x9, 0xC, 0xA, 0xB, 0x0, 0xF, 0x6, 0x6, 0x3, 0x3, 0x5, 0x8, 0xE, -}; - -inline uint32_t spbox(uint32_t T0, uint32_t T1) - { - return - _pdep_u32(SPBOX_CAT_0[get_byte(0, T0) % 64], 0x01010404) ^ - _pdep_u32(SPBOX_CAT_1[get_byte(0, T1) % 64], 0x80108020) ^ - _pdep_u32(SPBOX_CAT_2[get_byte(1, T0) % 64], 0x08020208) ^ - _pdep_u32(SPBOX_CAT_3[get_byte(1, T1) % 64], 0x00802081) ^ - _pdep_u32(SPBOX_CAT_4[get_byte(2, T0) % 64], 0x42080100) ^ - _pdep_u32(SPBOX_CAT_5[get_byte(2, T1) % 64], 0x20404010) ^ - _pdep_u32(SPBOX_CAT_6[get_byte(3, T0) % 64], 0x04200802) ^ - _pdep_u32(SPBOX_CAT_7[get_byte(3, T1) % 64], 0x10041040); - } - -inline void des_encrypt(uint32_t& Lr, uint32_t& Rr, - const uint32_t round_key[32]) - { - uint32_t L = Lr; - uint32_t R = Rr; - for(size_t i = 0; i != 16; i += 2) - { - L ^= spbox(rotr<4>(R) ^ round_key[2*i ], R ^ round_key[2*i+1]); - R ^= spbox(rotr<4>(L) ^ round_key[2*i+2], L ^ round_key[2*i+3]); - } - - Lr = L; - Rr = R; - } - -inline void des_encrypt_x2(uint32_t& L0r, uint32_t& R0r, - uint32_t& L1r, uint32_t& R1r, - const uint32_t round_key[32]) - { - uint32_t L0 = L0r; - uint32_t R0 = R0r; - uint32_t L1 = L1r; - uint32_t R1 = R1r; - - for(size_t i = 0; i != 16; i += 2) - { - L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i ], R0 ^ round_key[2*i+1]); - L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i ], R1 ^ round_key[2*i+1]); - - R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i+2], L0 ^ round_key[2*i+3]); - R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i+2], L1 ^ round_key[2*i+3]); - } - - L0r = L0; - R0r = R0; - L1r = L1; - R1r = R1; - } - -inline void des_decrypt(uint32_t& Lr, uint32_t& Rr, - const uint32_t round_key[32]) - { - uint32_t L = Lr; - uint32_t R = Rr; - for(size_t i = 16; i != 0; i -= 2) - { - L ^= spbox(rotr<4>(R) ^ round_key[2*i - 2], R ^ round_key[2*i - 1]); - R ^= spbox(rotr<4>(L) ^ round_key[2*i - 4], L ^ round_key[2*i - 3]); - } - Lr = L; - Rr = R; - } - -inline void des_decrypt_x2(uint32_t& L0r, uint32_t& R0r, - uint32_t& L1r, uint32_t& R1r, - const uint32_t round_key[32]) - { - uint32_t L0 = L0r; - uint32_t R0 = R0r; - uint32_t L1 = L1r; - uint32_t R1 = R1r; - - for(size_t i = 16; i != 0; i -= 2) - { - L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i - 2], R0 ^ round_key[2*i - 1]); - L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i - 2], R1 ^ round_key[2*i - 1]); - - R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i - 4], L0 ^ round_key[2*i - 3]); - R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i - 4], L1 ^ round_key[2*i - 3]); - } - - L0r = L0; - R0r = R0; - L1r = L1; - R1r = R1; - } - -inline void des_IP(uint32_t& L, uint32_t& R, const uint8_t block[]) - { - // IP sequence by Wei Dai, taken from public domain Crypto++ - L = load_be<uint32_t>(block, 0); - R = load_be<uint32_t>(block, 1); - - uint32_t T; - R = rotl<4>(R); - T = (L ^ R) & 0xF0F0F0F0; - L ^= T; - R = rotr<20>(R ^ T); - T = (L ^ R) & 0xFFFF0000; - L ^= T; - R = rotr<18>(R ^ T); - T = (L ^ R) & 0x33333333; - L ^= T; - R = rotr<6>(R ^ T); - T = (L ^ R) & 0x00FF00FF; - L ^= T; - R = rotl<9>(R ^ T); - T = (L ^ R) & 0xAAAAAAAA; - L = rotl<1>(L ^ T); - R ^= T; - } - -inline void des_FP(uint32_t L, uint32_t R, uint8_t out[]) - { - // FP sequence by Wei Dai, taken from public domain Crypto++ - uint32_t T; - - R = rotr<1>(R); - T = (L ^ R) & 0xAAAAAAAA; - R ^= T; - L = rotr<9>(L ^ T); - T = (L ^ R) & 0x00FF00FF; - R ^= T; - L = rotl<6>(L ^ T); - T = (L ^ R) & 0x33333333; - R ^= T; - L = rotl<18>(L ^ T); - T = (L ^ R) & 0xFFFF0000; - R ^= T; - L = rotl<20>(L ^ T); - T = (L ^ R) & 0xF0F0F0F0; - R ^= T; - L = rotr<4>(L ^ T); - store_be(out, R, L); - } - -} - -} - -//static -void TripleDES::bmi2_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const uint32_t key[]) - { - using namespace DES_BMI2_fn; - while(blocks >= 2) - { - uint32_t L0, R0; - uint32_t L1, R1; - - des_IP(L0, R0, in); - des_IP(L1, R1, in + BLOCK_SIZE); - - des_encrypt_x2(L0, R0, L1, R1, &key[0]); - des_decrypt_x2(R0, L0, R1, L1, &key[32]); - des_encrypt_x2(L0, R0, L1, R1, &key[64]); - - des_FP(L0, R0, out); - des_FP(L1, R1, out + BLOCK_SIZE); - - in += 2*BLOCK_SIZE; - out += 2*BLOCK_SIZE; - blocks -= 2; - } - - for(size_t i = 0; i != blocks; ++i) - { - uint32_t L, R; - des_IP(L, R, in + BLOCK_SIZE*i); - - des_encrypt(L, R, &key[0]); - des_decrypt(R, L, &key[32]); - des_encrypt(L, R, &key[64]); - - des_FP(L, R, out + BLOCK_SIZE*i); - } - } - -//static -void TripleDES::bmi2_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const uint32_t key[]) - { - using namespace DES_BMI2_fn; - - while(blocks >= 2) - { - uint32_t L0, R0; - uint32_t L1, R1; - - des_IP(L0, R0, in); - des_IP(L1, R1, in + BLOCK_SIZE); - - des_decrypt_x2(L0, R0, L1, R1, &key[64]); - des_encrypt_x2(R0, L0, R1, L1, &key[32]); - des_decrypt_x2(L0, R0, L1, R1, &key[0]); - - des_FP(L0, R0, out); - des_FP(L1, R1, out + BLOCK_SIZE); - - in += 2*BLOCK_SIZE; - out += 2*BLOCK_SIZE; - blocks -= 2; - } - - for(size_t i = 0; i != blocks; ++i) - { - uint32_t L, R; - des_IP(L, R, in + BLOCK_SIZE*i); - - des_decrypt(L, R, &key[64]); - des_encrypt(R, L, &key[32]); - des_decrypt(L, R, &key[0]); - - des_FP(L, R, out + BLOCK_SIZE*i); - } - } - -} |