-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic Noekeon implementation added #35
- Loading branch information
Showing
5 changed files
with
346 additions
and
0 deletions.
There are no files selected for viewing
81 changes: 81 additions & 0 deletions
81
include/nil/crypto3/block/detail/noekeon/noekeon_functions.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
//---------------------------------------------------------------------------// | ||
// Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0 | ||
// See accompanying file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt | ||
//---------------------------------------------------------------------------// | ||
|
||
#ifndef CRYPTO3_NOEKEON_FUNCTIONS_CPP_HPP | ||
#define CRYPTO3_NOEKEON_FUNCTIONS_CPP_HPP | ||
|
||
#include <nil/crypto3/detail/basic_functions.hpp> | ||
|
||
namespace nil { | ||
namespace crypto3 { | ||
namespace block { | ||
namespace detail { | ||
template<std::size_t WordBits> | ||
struct noekeon_functions : public ::nil::crypto3::detail::basic_functions<WordBits> { | ||
typedef ::nil::crypto3::detail::basic_functions<WordBits> policy_type; | ||
typedef typename policy_type::word_type word_type; | ||
|
||
/* | ||
* Noekeon's Theta Operation | ||
*/ | ||
inline static void theta(word_type &A0, word_type &A1, word_type &A2, word_type &A3, | ||
const word_type *EK) { | ||
word_type T = A0 ^ A2; | ||
T ^= policy_type::template rotl<8>(T) ^ policy_type::template rotr<8>(T); | ||
A1 ^= T; | ||
A3 ^= T; | ||
|
||
A0 ^= EK[0]; | ||
A1 ^= EK[1]; | ||
A2 ^= EK[2]; | ||
A3 ^= EK[3]; | ||
|
||
T = A1 ^ A3; | ||
T ^= policy_type::template rotl<8>(T) ^ policy_type::template rotr<8>(T); | ||
A0 ^= T; | ||
A2 ^= T; | ||
} | ||
|
||
/* | ||
* Theta With Null Key | ||
*/ | ||
inline static void theta(word_type &A0, word_type &A1, word_type &A2, word_type &A3) { | ||
word_type T = A0 ^ A2; | ||
T ^= policy_type::template rotl<8>(T) ^ policy_type::template rotr<8>(T); | ||
A1 ^= T; | ||
A3 ^= T; | ||
|
||
T = A1 ^ A3; | ||
T ^= policy_type::template rotl<8>(T) ^ policy_type::template rotr<8>(T); | ||
A0 ^= T; | ||
A2 ^= T; | ||
} | ||
|
||
/* | ||
* Noekeon's Gamma S-Box Layer | ||
*/ | ||
inline static void gamma(word_type &A0, word_type &A1, word_type &A2, word_type &A3) { | ||
A1 ^= ~A3 & ~A2; | ||
A0 ^= A2 & A1; | ||
|
||
word_type T = A3; | ||
A3 = A0; | ||
A0 = T; | ||
|
||
A2 ^= A0 ^ A1 ^ A3; | ||
|
||
A1 ^= ~A3 & ~A2; | ||
A0 ^= A2 & A1; | ||
} | ||
}; | ||
} // namespace detail | ||
} // namespace block | ||
} // namespace crypto3 | ||
} // namespace nil | ||
|
||
#endif // CRYPTO3_NOEKEON_FUNCTIONS_CPP_HPP |
46 changes: 46 additions & 0 deletions
46
include/nil/crypto3/block/detail/noekeon/noekeon_policy.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
//---------------------------------------------------------------------------// | ||
// Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0 | ||
// See accompanying file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt | ||
//---------------------------------------------------------------------------// | ||
|
||
#ifndef CRYPTO3_NOEKEON_POLICY_HPP | ||
#define CRYPTO3_NOEKEON_POLICY_HPP | ||
|
||
#include <array> | ||
|
||
#include <nil/crypto3/block/detail/noekeon/noekeon_functions.hpp> | ||
|
||
namespace nil { | ||
namespace crypto3 { | ||
namespace block { | ||
namespace detail { | ||
struct noekeon_policy : noekeon_functions<32> { | ||
constexpr static const std::size_t rounds = 16; | ||
|
||
constexpr static const std::size_t block_bits = 128; | ||
constexpr static const std::size_t block_words = block_bits / word_bits; | ||
typedef std::array<word_type, block_words> block_type; | ||
|
||
constexpr static const std::size_t key_bits = 128; | ||
constexpr static const std::size_t key_words = block_bits / word_bits; | ||
typedef std::array<word_type, key_words> key_type; | ||
|
||
constexpr static const std::size_t key_schedule_size = 4; | ||
typedef std::array<word_type, key_schedule_size> key_schedule_type; | ||
|
||
typedef std::array<byte_type, rounds + 1> constants_type; | ||
constexpr static const constants_type round_constants = {0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, | ||
0x4D, 0x9A, 0x2F, 0x5E, 0xBC, 0x63, | ||
0xC6, 0x97, 0x35, 0x6A, 0xD4}; | ||
}; | ||
|
||
constexpr typename noekeon_policy::constants_type const noekeon_policy::round_constants; | ||
} // namespace detail | ||
} // namespace block | ||
} // namespace crypto3 | ||
} // namespace nil | ||
|
||
#endif // CRYPTO3_NOEKEON_POLICY_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
//---------------------------------------------------------------------------// | ||
// Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation> | ||
// Copyright (c) 2020 Nikita Kaskov <nbering@nil.foundation> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0 | ||
// See accompanying file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt | ||
//---------------------------------------------------------------------------// | ||
|
||
#ifndef CRYPTO3_BLOCK_NOEKEON_HPP | ||
#define CRYPTO3_BLOCK_NOEKEON_HPP | ||
|
||
#include <boost/endian/arithmetic.hpp> | ||
#include <boost/endian/conversion.hpp> | ||
|
||
#include <nil/crypto3/block/detail/noekeon/noekeon_policy.hpp> | ||
|
||
#include <nil/crypto3/block/detail/block_stream_processor.hpp> | ||
#include <nil/crypto3/block/detail/cipher_modes.hpp> | ||
|
||
namespace nil { | ||
namespace crypto3 { | ||
namespace block { | ||
/*! | ||
* @brief Noekeon. A fast 128-bit cipher by the designers of AES. | ||
* Easily secured against side channels. | ||
* | ||
* @ingroup block | ||
*/ | ||
class noekeon { | ||
protected: | ||
typedef detail::noekeon_policy policy_type; | ||
|
||
constexpr static const std::size_t key_schedule_size = policy_type::key_schedule_size; | ||
typedef typename policy_type::key_schedule_type key_schedule_type; | ||
|
||
public: | ||
constexpr static const std::size_t rounds = policy_type::rounds; | ||
|
||
constexpr static const std::size_t word_bits = policy_type::word_bits; | ||
typedef typename policy_type::word_type word_type; | ||
|
||
constexpr static const std::size_t block_bits = policy_type::block_bits; | ||
constexpr static const std::size_t block_words = policy_type::block_words; | ||
typedef typename policy_type::block_type block_type; | ||
|
||
constexpr static const std::size_t key_bits = policy_type::key_bits; | ||
constexpr static const std::size_t key_words = policy_type::key_words; | ||
typedef typename policy_type::key_type key_type; | ||
|
||
template<class Mode, typename StateAccumulator, std::size_t ValueBits> | ||
struct stream_processor { | ||
struct params_type { | ||
|
||
constexpr static const std::size_t value_bits = ValueBits; | ||
constexpr static const std::size_t length_bits = policy_type::word_bits * 2; | ||
}; | ||
|
||
typedef block_stream_processor<Mode, StateAccumulator, params_type> type; | ||
}; | ||
|
||
typedef typename stream_endian::little_octet_big_bit endian_type; | ||
|
||
noekeon(const key_type &key) { | ||
schedule_key(key); | ||
} | ||
|
||
~noekeon() { | ||
encryption_key.fill(0); | ||
decryption_key.fill(0); | ||
} | ||
|
||
inline block_type encrypt(const block_type &plaintext) const { | ||
return encrypt_block(plaintext); | ||
} | ||
|
||
inline block_type decrypt(const block_type &ciphertext) const { | ||
return decrypt_block(ciphertext); | ||
} | ||
|
||
protected: | ||
key_schedule_type encryption_key, decryption_key; | ||
|
||
inline block_type encrypt_block(const block_type &plaintext) const { | ||
word_type A0 = boost::endian::native_to_big(plaintext[0]); | ||
word_type A1 = boost::endian::native_to_big(plaintext[1]); | ||
word_type A2 = boost::endian::native_to_big(plaintext[2]); | ||
word_type A3 = boost::endian::native_to_big(plaintext[3]); | ||
|
||
for (size_t j = 0; j != 16; ++j) { | ||
A0 ^= policy_type::round_constants[j]; | ||
policy_type::theta(A0, A1, A2, A3, encryption_key.data()); | ||
|
||
A1 = policy_type::template rotl<1>(A1); | ||
A2 = policy_type::template rotl<5>(A2); | ||
A3 = policy_type::template rotl<2>(A3); | ||
|
||
policy_type::gamma(A0, A1, A2, A3); | ||
|
||
A1 = policy_type::template rotr<1>(A1); | ||
A2 = policy_type::template rotr<5>(A2); | ||
A3 = policy_type::template rotr<2>(A3); | ||
} | ||
|
||
A0 ^= policy_type::round_constants[16]; | ||
policy_type::theta(A0, A1, A2, A3, encryption_key.data()); | ||
|
||
return {boost::endian::big_to_native(A0), boost::endian::big_to_native(A1), | ||
boost::endian::big_to_native(A2), boost::endian::big_to_native(A3)}; | ||
} | ||
|
||
inline block_type decrypt_block(const block_type &ciphertext) const { | ||
word_type A0 = boost::endian::native_to_big(ciphertext[0]); | ||
word_type A1 = boost::endian::native_to_big(ciphertext[1]); | ||
word_type A2 = boost::endian::native_to_big(ciphertext[2]); | ||
word_type A3 = boost::endian::native_to_big(ciphertext[3]); | ||
|
||
for (size_t j = 16; j != 0; --j) { | ||
policy_type::theta(A0, A1, A2, A3, decryption_key.data()); | ||
A0 ^= policy_type::round_constants[j]; | ||
|
||
A1 = policy_type::template rotl<1>(A1); | ||
A2 = policy_type::template rotl<5>(A2); | ||
A3 = policy_type::template rotl<2>(A3); | ||
|
||
policy_type::gamma(A0, A1, A2, A3); | ||
|
||
A1 = policy_type::template rotr<1>(A1); | ||
A2 = policy_type::template rotr<5>(A2); | ||
A3 = policy_type::template rotr<2>(A3); | ||
} | ||
|
||
policy_type::theta(A0, A1, A2, A3, decryption_key.data()); | ||
A0 ^= policy_type::round_constants[0]; | ||
|
||
return {boost::endian::big_to_native(A0), boost::endian::big_to_native(A1), | ||
boost::endian::big_to_native(A2), boost::endian::big_to_native(A3)}; | ||
} | ||
|
||
inline void schedule_key(const key_type &key) { | ||
word_type A0 = boost::endian::native_to_big(key[0]); | ||
word_type A1 = boost::endian::native_to_big(key[1]); | ||
word_type A2 = boost::endian::native_to_big(key[2]); | ||
word_type A3 = boost::endian::native_to_big(key[3]); | ||
|
||
for (size_t i = 0; i != 16; ++i) { | ||
A0 ^= policy_type::round_constants[i]; | ||
policy_type::theta(A0, A1, A2, A3); | ||
|
||
A1 = policy_type::template rotl<1>(A1); | ||
A2 = policy_type::template rotl<5>(A2); | ||
A3 = policy_type::template rotl<2>(A3); | ||
|
||
policy_type::gamma(A0, A1, A2, A3); | ||
|
||
A1 = policy_type::template rotr<1>(A1); | ||
A2 = policy_type::template rotr<5>(A2); | ||
A3 = policy_type::template rotr<2>(A3); | ||
} | ||
|
||
A0 ^= policy_type::round_constants[16]; | ||
|
||
decryption_key[0] = A0; | ||
decryption_key[1] = A1; | ||
decryption_key[2] = A2; | ||
decryption_key[3] = A3; | ||
|
||
policy_type::theta(A0, A1, A2, A3); | ||
|
||
encryption_key[0] = A0; | ||
encryption_key[1] = A1; | ||
encryption_key[2] = A2; | ||
encryption_key[3] = A3; | ||
} | ||
}; | ||
} // namespace block | ||
} // namespace crypto3 | ||
} // namespace nil | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,7 @@ set(TESTS_NAMES | |
"rijndael" | ||
"md4" | ||
"md5" | ||
"noekeon" | ||
"shacal" | ||
"shacal2" | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
//---------------------------------------------------------------------------// | ||
// Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation> | ||
// Copyright (c) 2020 Nikita Kaskov <nbering@nil.foundation> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0 | ||
// See accompanying file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt | ||
//---------------------------------------------------------------------------// | ||
|
||
#define BOOST_TEST_MODULE noekeon_cipher_test | ||
|
||
#include <iostream> | ||
#include <unordered_map> | ||
|
||
#include <boost/test/unit_test.hpp> | ||
#include <boost/test/data/test_case.hpp> | ||
#include <boost/test/data/monomorphic.hpp> | ||
|
||
#include <nil/crypto3/block/algorithm/encrypt.hpp> | ||
#include <nil/crypto3/block/algorithm/decrypt.hpp> | ||
|
||
#include <nil/crypto3/block/noekeon.hpp> | ||
|
||
using namespace nil::crypto3; | ||
|
||
BOOST_AUTO_TEST_SUITE(noekeon_test_suite) | ||
|
||
BOOST_AUTO_TEST_CASE(noekeon_1) { | ||
|
||
std::vector<char> input = {'\xea', '\x02', '\x47', '\x14', '\xad', '\x5c', '\x4d', '\x84'}; | ||
std::vector<char> key = {'\xba', '\x69', '\x33', '\x81', '\x92', '\x99', '\xc7', '\x16', | ||
'\x99', '\xa9', '\x9f', '\x08', '\xf6', '\x78', '\x17', '\x8b'}; | ||
|
||
std::string out = encrypt<block::noekeon>(input, key); | ||
|
||
BOOST_CHECK_EQUAL(out, "df1f9b251c0bf45f"); | ||
} | ||
|
||
BOOST_AUTO_TEST_SUITE_END() |