/* * This Source Code Form is subject to the terms of the Mozilla Public * 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 2018 Danny Robson */ #include "speck.hpp" #include using cruft::crypto::block::speck; /////////////////////////////////////////////////////////////////////////////// /// The round function for the encryption direction. /// /// Mutates the x and y values. /// /// \param x first data word /// \param y second data word /// \param k key word static void round_enc (u64 &x, u64 &y, u64 const &k) { x = cruft::rotater (x, 8); x += y; x ^= k; y = cruft::rotatel (y, 3); y ^= x; } ///---------------------------------------------------------------------------- /// The round function for the decryption direction /// /// Mutates the x and y values. /// /// \param x /// \param y /// \param k static void round_dec (u64 &x, u64 &y, u64 const &k) { y ^= x; y = cruft::rotater (y, 3); x ^= k; x -= y; x = cruft::rotatel (x, 8); } /////////////////////////////////////////////////////////////////////////////// /// Initialise the key schedule speck::speck (std::array _key) { auto &x = _key[0]; auto &y = _key[1]; // Allocate a space to store the schedule as it's computed std::array schedule; schedule[0] = y; // Initialise the key to be indices 0..31 std::iota (std::begin (m_key), std::end (m_key), 0); // 'encrypt' the key using the index schedule for (int i = 0; i < 31; ++i) { round_enc (x, y, m_key[i]); schedule[i + 1] = y; } // Copy the computed schedule back out m_key = schedule; } /////////////////////////////////////////////////////////////////////////////// speck::block_t speck::encrypt (block_t plaintext) const { u64 &x = plaintext[0]; u64 &y = plaintext[1]; for (int i = 0; i < 32; i++) round_enc (x, y, m_key[i]); return { x, y }; } //----------------------------------------------------------------------------- std::array speck::decrypt (block_t plaintext) const { u64 &x = plaintext[0]; u64 &y = plaintext[1]; for (int i = 0; i < 32; i++) round_dec (x, y, m_key[31 - i]); return { x, y }; }