From 38e8aa70d630af9f2955a4cf411754cd026bde7f Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Sun, 2 Dec 2018 13:45:26 +1100 Subject: [PATCH] block: update block concept to take a data view --- block/tea.cpp | 46 +++++++++++++++++++++----------------------- block/tea.hpp | 24 +++++++++++++---------- block/xtea.cpp | 36 +++++++++++++++------------------- block/xtea.hpp | 22 ++++++++++++--------- block/xxtea.cpp | 36 ++++++++++++++++++---------------- block/xxtea.hpp | 24 ++++++++++++----------- test/block/tea.cpp | 4 ++-- test/block/xtea.cpp | 4 ++-- test/block/xxtea.cpp | 4 ++-- 9 files changed, 103 insertions(+), 97 deletions(-) diff --git a/block/tea.cpp b/block/tea.cpp index 457b2ed..b93926d 100644 --- a/block/tea.cpp +++ b/block/tea.cpp @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015 Danny Robson + * Copyright 2015-2018 Danny Robson */ #include "tea.hpp" @@ -15,30 +15,30 @@ using cruft::crypto::block::TEA; /////////////////////////////////////////////////////////////////////////////// -static const std::uint32_t MAGIC = 0x9E3779B9; +static const u32 MAGIC = 0x9E3779B9; + // each iteration performs two feistel rounds, for a total of 64 static const unsigned ITERATIONS = 32; /////////////////////////////////////////////////////////////////////////////// -TEA::TEA (key_t _key): - m_key (_key) +TEA::TEA (key_t _key) + : m_key (_key) { ; } -//----------------------------------------------------------------------------- +/////////////////////////////////////////////////////////////////////////////// void -TEA::encrypt (uint32_t *restrict data, size_t count) +TEA::encrypt (cruft::view data) { - if (count % 2) + if (data.size () % 2) throw std::invalid_argument ("TEA requires even data count"); - auto last = data + count; - while (data < last) { - uint32_t sum = 0; - uint32_t v0 = data[0]; - uint32_t v1 = data[1]; + for (auto cursor = data.begin (), last = data.end (); cursor < last; ) { + word_t sum = 0; + word_t v0 = cursor[0]; + word_t v1 = cursor[1]; for (unsigned i = 0; i < ITERATIONS; ++i) { sum += MAGIC; @@ -46,25 +46,23 @@ TEA::encrypt (uint32_t *restrict data, size_t count) v1 += ((v0 << 4) + m_key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + m_key[3]); } - *data++ = v0; - *data++ = v1; + *cursor++ = v0; + *cursor++ = v1; } } //----------------------------------------------------------------------------- void -TEA::decrypt (uint32_t *restrict data, size_t count) +TEA::decrypt (cruft::view data) { - if (count % 2) + if (data.size () % 2) throw std::invalid_argument ("TEA requires even data count"); - auto last = data + count; - - while (data < last) { - uint32_t sum = MAGIC << 5; - uint32_t v0 = data[0]; - uint32_t v1 = data[1]; + for (auto cursor = data.begin (), last = data.end (); cursor < last; ) { + word_t sum = MAGIC << 5; + word_t v0 = cursor[0]; + word_t v1 = cursor[1]; for (unsigned i = 0; i < ITERATIONS; ++i) { v1 -= ((v0 << 4) + m_key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + m_key[3]); @@ -72,7 +70,7 @@ TEA::decrypt (uint32_t *restrict data, size_t count) sum -= MAGIC; } - *data++ = v0; - *data++ = v1; + *cursor++ = v0; + *cursor++ = v1; } } diff --git a/block/tea.hpp b/block/tea.hpp index 088f09b..8dd4853 100644 --- a/block/tea.hpp +++ b/block/tea.hpp @@ -3,30 +3,34 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015 Danny Robson + * Copyright 2015-2018 Danny Robson */ -#ifndef CRUFT_CRYPTO_BLOCK_TEA_HPP -#define CRUFT_CRYPTO_BLOCK_TEA_HPP +#pragma once #include #include #include +#include +#include + + namespace cruft::crypto::block { - // http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm + /// An implementation of the "Tiny Encryption Algorithm" block cipher. + /// + /// ref: http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm class TEA { public: - using key_t = std::array; + using key_t = std::array; + using word_t = u32; explicit TEA (key_t); - void encrypt (uint32_t *restrict data, size_t count); - void decrypt (uint32_t *restrict data, size_t count); + void encrypt (cruft::view data); + void decrypt (cruft::view data); private: - key_t m_key; + key_t const m_key; }; } - -#endif diff --git a/block/xtea.cpp b/block/xtea.cpp index 5cf7142..8d369b5 100644 --- a/block/xtea.cpp +++ b/block/xtea.cpp @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015 Danny Robson + * Copyright 2015-2018 Danny Robson */ #include "xtea.hpp" @@ -12,7 +12,7 @@ using cruft::crypto::block::XTEA; /////////////////////////////////////////////////////////////////////////////// -static const uint32_t MAGIC = 0x9E3779B9; +static const u32 MAGIC = 0x9E3779B9; // each iteration performs two feistel rounds, for a total of 64 static const unsigned ITERATIONS = 32; @@ -26,17 +26,15 @@ XTEA::XTEA (key_t _key): //----------------------------------------------------------------------------- void -XTEA::encrypt (uint32_t *restrict data, size_t count) +XTEA::encrypt (cruft::view data) { - if (count % 2) + if (data.size () % 2) throw std::invalid_argument ("XTEA requires even data count"); - auto last = data + count; - - while (data < last) { + for (auto cursor = data.begin (), last = data.end (); cursor < last; ) { uint32_t sum = 0; - uint32_t v0 = data[0]; - uint32_t v1 = data[1]; + uint32_t v0 = cursor[0]; + uint32_t v1 = cursor[1]; for (unsigned i = 0; i < ITERATIONS; ++i) { v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + m_key[sum & 3]); @@ -44,25 +42,23 @@ XTEA::encrypt (uint32_t *restrict data, size_t count) v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + m_key[(sum >> 11) & 3]); } - *data++ = v0; - *data++ = v1; + *cursor++ = v0; + *cursor++ = v1; } } //----------------------------------------------------------------------------- void -XTEA::decrypt (uint32_t *restrict data, size_t count) +XTEA::decrypt (cruft::view data) { - if (count % 2) + if (data.size () % 2) throw std::invalid_argument ("XTEA requires even data count"); - auto last = data + count; - - while (data < last) { + for (auto cursor = data.begin (), last = data.end (); cursor < last; ) { uint32_t sum = ITERATIONS * MAGIC; - uint32_t v0 = data[0]; - uint32_t v1 = data[1]; + uint32_t v0 = cursor[0]; + uint32_t v1 = cursor[1]; for (unsigned i = 0; i < ITERATIONS; ++i) { v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + m_key[(sum >> 11) & 3]); @@ -70,7 +66,7 @@ XTEA::decrypt (uint32_t *restrict data, size_t count) v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + m_key[sum & 3]); } - *data++ = v0; - *data++ = v1; + *cursor++ = v0; + *cursor++ = v1; } } diff --git a/block/xtea.hpp b/block/xtea.hpp index 54d761c..fe51be3 100644 --- a/block/xtea.hpp +++ b/block/xtea.hpp @@ -3,30 +3,34 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015 Danny Robson + * Copyright 2015-2018 Danny Robson */ -#ifndef CRUFT_CRYPTO_BLOCK_XTEA_HPP -#define CRUFT_CRYPTO_BLOCK_XTEA_HPP +#pragma once #include #include #include +#include +#include + + namespace cruft::crypto::block { - // http://en.wikipedia.org/wiki/XTEA + /// An implementation of the "eXtended TEA" block cipher. + /// + /// ref: http://en.wikipedia.org/wiki/XTEA class XTEA { public: - using key_t = std::array; + using key_t = std::array; + using word_t = u32; explicit XTEA (key_t); - void encrypt (uint32_t *restrict data, size_t count); - void decrypt (uint32_t *restrict data, size_t count); + void encrypt (cruft::view data); + void decrypt (cruft::view data); private: key_t m_key; }; } - -#endif diff --git a/block/xxtea.cpp b/block/xxtea.cpp index 027d984..3711a1a 100644 --- a/block/xxtea.cpp +++ b/block/xxtea.cpp @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015 Danny Robson + * Copyright 2015-2018 Danny Robson */ #include "xxtea.hpp" @@ -16,18 +16,18 @@ using cruft::crypto::block::XXTEA; //----------------------------------------------------------------------------- -static const uint32_t MAGIC = 0x9E3779B9; +static const u32 MAGIC = 0x9E3779B9; //----------------------------------------------------------------------------- static constexpr -uint32_t -mix (uint32_t Z, - uint32_t Y, - uint32_t S, - size_t E, - size_t P, - const uint32_t *restrict K) +u32 +mix (u32 Z, + u32 Y, + u32 S, + std::size_t E, + std::size_t P, + const u32 *restrict K) { return ((Z >> 5 ^ Y << 2) + (Y >> 3 ^ Z << 4)) ^ ((S ^ Y) + (K[(P & 3) ^ E] ^ Z)); } @@ -41,11 +41,12 @@ XXTEA::XXTEA (key_t _key): //----------------------------------------------------------------------------- void -XXTEA::encrypt (uint32_t *restrict data, size_t count) +XXTEA::encrypt (cruft::view data) { - if (count < 2) + if (data.size () < 2) throw std::invalid_argument ("minimum blocksize is 64 bits"); + auto const count = data.size (); uint32_t sum = 0; uint32_t z = data[count - 1]; uint32_t y, p; @@ -58,22 +59,23 @@ XXTEA::encrypt (uint32_t *restrict data, size_t count) for (p = 0; p < count - 1; p++) { y = data[p + 1]; - z = data[p] += mix (z, y, sum, e, p, m_key.data ()); + z = data[p] += ::mix (z, y, sum, e, p, m_key.data ()); } y = data[0]; - z = data[count - 1] += mix (z, y, sum, e, p, m_key.data ()); + z = data[count - 1] += ::mix (z, y, sum, e, p, m_key.data ()); } while (--rounds); } //----------------------------------------------------------------------------- void -XXTEA::decrypt (uint32_t *restrict data, size_t count) +XXTEA::decrypt (cruft::view data) { - if (count < 2) + if (data.size () < 2) throw std::invalid_argument ("minimum blocksize is 64 bits"); + auto const count = data.size (); uint32_t y, z, sum; uint32_t rounds; size_t p; @@ -87,11 +89,11 @@ XXTEA::decrypt (uint32_t *restrict data, size_t count) for (p = count - 1; p > 0; p--) { z = data[p - 1]; - y = data[p ] -= mix (z, y, sum, e, p, m_key.data ()); + y = data[p ] -= ::mix (z, y, sum, e, p, m_key.data ()); } z = data[count - 1]; - y = data[ 0] -= mix (z, y, sum, e, p, m_key.data ()); + y = data[ 0] -= ::mix (z, y, sum, e, p, m_key.data ()); sum -= MAGIC; } while (--rounds); diff --git a/block/xxtea.hpp b/block/xxtea.hpp index 924c9e5..94c8925 100644 --- a/block/xxtea.hpp +++ b/block/xxtea.hpp @@ -3,32 +3,34 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015 Danny Robson + * Copyright 2015-2018 Danny Robson */ -#ifndef CRUFT_CRYPTO_BLOCKXXTEA_HPP -#define CRUFT_CRYPTO_BLOCKXXTEA_HPP +#pragma once #include #include #include +#include +#include + + namespace cruft::crypto::block { - // http://en.wikipedia.org/wiki/XXTEA - // 'corrected' block TEA + /// An implementation of the "Corrected Block TEA" block cipher. + /// + /// ref: http://en.wikipedia.org/wiki/XXTEA class XXTEA { public: - using key_t = std::array; + using key_t = std::array; + using word_t = u32; explicit XXTEA (key_t); - void encrypt (uint32_t *restrict data, size_t count); - void decrypt (uint32_t *restrict data, size_t count); + void encrypt (cruft::view data); + void decrypt (cruft::view data); private: key_t m_key; }; } - -#endif - diff --git a/test/block/tea.cpp b/test/block/tea.cpp index cf14f38..35a6173 100644 --- a/test/block/tea.cpp +++ b/test/block/tea.cpp @@ -48,10 +48,10 @@ main () TEA gen (t.key); std::array enc (t.dec); - gen.encrypt (enc.data (), enc.size ()); + gen.encrypt (cruft::view (enc)); std::array dec (t.enc); - gen.decrypt (dec.data (), dec.size ()); + gen.decrypt (cruft::view (dec)); tap.expect (enc == t.enc, "TEA_enc %zu", i); tap.expect (dec == t.dec, "TEA_dec %zu", i); diff --git a/test/block/xtea.cpp b/test/block/xtea.cpp index 4a23ca8..3ba7cb9 100644 --- a/test/block/xtea.cpp +++ b/test/block/xtea.cpp @@ -46,10 +46,10 @@ main () cruft::crypto::block::XTEA gen (t.key); std::array enc (t.dec); - gen.encrypt (enc.data (), enc.size ()); + gen.encrypt (cruft::view (enc)); std::array dec (t.enc); - gen.decrypt (dec.data (), dec.size ()); + gen.decrypt (cruft::view (dec)); tap.expect (enc == t.enc, "XTEA_enc %zu", i); tap.expect (dec == t.dec, "XTEA_dec %zu", i); diff --git a/test/block/xxtea.cpp b/test/block/xxtea.cpp index e6acca3..0f9c9fa 100644 --- a/test/block/xxtea.cpp +++ b/test/block/xxtea.cpp @@ -104,10 +104,10 @@ main () XXTEA gen (t.key); std::vector enc (t.dec); - gen.encrypt (enc.data (), enc.size ()); + gen.encrypt (cruft::view (enc)); std::vector dec (enc); - gen.decrypt (dec.data (), dec.size ()); + gen.decrypt (cruft::view (dec)); tap.expect (enc == t.enc, "XXTEA_enc %zu", i); tap.expect (dec == t.dec, "XXTEA_dec %zu", i);