Skip to content
This repository has been archived by the owner on Feb 17, 2025. It is now read-only.

Commit

Permalink
Streebog basic implementation added #51
Browse files Browse the repository at this point in the history
  • Loading branch information
nkaskov committed Jun 18, 2020
1 parent adbe1c8 commit d493af1
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,15 @@ if(CRYPTO3_HASH_SHA3)
${${CURRENT_PROJECT_NAME}_SHA3_HEADERS})
endif()

if(CRYPTO3_HASH_STREEBOG)
list(APPEND ${CURRENT_PROJECT_NAME}_STREEBOG_HEADERS
include/nil/crypto3/hash/streebog.hpp)

add_definitions(-D${CMAKE_UPPER_WORKSPACE_NAME}_HAS_STREEBOG)
list(APPEND ${CURRENT_PROJECT_NAME}_PUBLIC_HEADERS
${${CURRENT_PROJECT_NAME}_STREEBOG_HEADERS})
endif()

list(APPEND ${CURRENT_PROJECT_NAME}_HEADERS
${${CURRENT_PROJECT_NAME}_PUBLIC_HEADERS})

Expand Down
74 changes: 74 additions & 0 deletions include/nil/crypto3/hash/detail/streebog.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//---------------------------------------------------------------------------//
// 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_STREEBOG_HASH_HPP
#define CRYPTO3_STREEBOG_HASH_HPP

#include <nil/crypto3/hash/detail/state_adder.hpp>
#include <nil/crypto3/hash/detail/miyaguchi_preneel_compressor.hpp>
#include <nil/crypto3/hash/detail/block_stream_processor.hpp>
#include <nil/crypto3/hash/detail/merkle_damgard_construction.hpp>
#include <nil/crypto3/hash/detail/merkle_damgard_padding.hpp>

#include <nil/crypto3/hash/detail/streebog/streebog_functions.hpp>

namespace nil {
namespace crypto3 {
namespace hash {
template<std::size_t DigestBits>
class streebog_key_converter { };

/*!
* @brief Streebog (GOST R 34.11-2012). RFC 6986. Newly designed Russian
* national hash function. Due to use of input-dependent table lookups,
* it is vulnerable to side channels. There is no reason to use it unless
* compatibility is needed.
*
* @ingroup hash
*/
template<std::size_t DigestBits>
class streebog {
typedef detail::streebog_policy<DigestBits> policy_type;
typedef block::streebog<DigestBits, DigestBits> block_cipher_type;

public:
struct construction {
struct params_type {
typedef typename policy_type::digest_endian digest_endian;

constexpr static const std::size_t length_bits = 0;
constexpr static const std::size_t digest_bits = policy_type::digest_bits;
};

typedef merkle_damgard_construction<
params_type, typename policy_type::iv_generator,
miyaguchi_preneel_compressor<block_cipher_type, detail::state_adder,
streebog_key_converter<DigestBits>>,
detail::merkle_damgard_padding<policy_type>>
type;
};

template<typename StateAccumulator, std::size_t ValueBits>
struct stream_processor {
struct params_type {
typedef typename policy_type::digest_endian digest_endian;

constexpr static const std::size_t value_bits = ValueBits;
};

typedef block_stream_processor<construction, StateAccumulator, params_type> type;
};

constexpr static const std::size_t digest_bits = policy_type::digest_bits;
typedef typename policy_type::digest_type digest_type;
};
} // namespace hash
} // namespace crypto3
} // namespace nil

#endif
66 changes: 66 additions & 0 deletions include/nil/crypto3/hash/detail/streebog/streebog_functions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//---------------------------------------------------------------------------//
// 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_STREEBOG_FUNCTIONS_HPP
#define CRYPTO3_STREEBOG_FUNCTIONS_HPP

#include <nil/crypto3/hash/detail/streebog/streebog_policy.hpp>

namespace nil {
namespace crypto3 {
namespace hash {
namespace detail {
template<std::size_t DigestBits>
struct streebog_functions : public streebog_policy<DigestBits> {
typedef streebog_policy<DigestBits> policy_type;
typedef typename policy_type::block_cipher_type block_cipher_type;

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 state_bits = policy_type::state_bits;
constexpr static const std::size_t state_words = policy_type::state_words;
typedef typename policy_type::state_type state_type;

inline static void addm(const uint8_t *m, word_type *h) {
word_type carry = 0;
for (int i = 0; i < block_words; i++) {
const word_type m64 = boost::endian::native_to_little(m[i]);
const word_type hi = boost::endian::native_to_little(reinterpret_cast<uint8_t *>(h)[i]);
const word_type t = hi + m64;

const word_type overflow = (t < hi ? 1 : 0) | (t < m64 ? 1 : 0);
store_le(t + carry, reinterpret_cast<uint8_t *>(&h[i]));
carry = overflow;
}
}

inline static void g(state_type &state, const uint8_t *m, word_type N) {
block_type hN = state;

hN[0] ^= boost::endian::native_to_little(N);
lps(hN);
const word_type *m64 = reinterpret_cast<const word_type *>(m);

block_cipher_type::encrypt(hN, m64);

for (size_t i = 0; i != block_words; ++i) {
state[i] ^= hN[i] ^ m64[i];
}
}
};
} // namespace detail
} // namespace hash
} // namespace crypto3
} // namespace nil

#endif // CRYPTO3_STREEBOG_FUNCTIONS_HPP
66 changes: 66 additions & 0 deletions include/nil/crypto3/hash/detail/streebog/streebog_policy.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//---------------------------------------------------------------------------//
// 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_STREEBOG_POLICY_HPP
#define CRYPTO3_STREEBOG_POLICY_HPP

#include <nil/crypto3/block/streebog.hpp>

#include <nil/crypto3/detail/basic_functions.hpp>

namespace nil {
namespace crypto3 {
namespace hash {
namespace detail {
template<std::size_t DigestBits>
struct streebog_policy : public ::nil::crypto3::detail::basic_functions<64> {
typedef block::streebog<DigestBits, DigestBits> block_cipher_type;

typedef typename stream_endian::little_octet_big_bit digest_endian;

constexpr static const std::size_t digest_bits = DigestBits;
typedef static_digest<DigestBits> digest_type;

constexpr static const std::size_t state_bits = block_cipher_type::block_bits;
constexpr static const std::size_t state_words = block_cipher_type::block_words;
typedef typename block_cipher_type::block_type state_type;

struct iv_generator {
state_type const &operator()() const {
constexpr static const state_type H0 = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
return H0;
}
};
};

template<>
struct streebog_policy<512> : public ::nil::crypto3::detail::basic_functions<64> {
typedef block::streebog<512, 512> block_cipher_type;

constexpr static const std::size_t digest_bits = block_cipher_type::block_bits;
typedef static_digest<digest_bits> digest_type;

constexpr static const std::size_t state_bits = block_cipher_type::block_bits;
constexpr static const std::size_t state_words = block_cipher_type::block_words;
typedef typename block_cipher_type::block_type state_type;

struct iv_generator {
state_type const &operator()() const {
constexpr static const state_type H0 = {
{0x0101010101010101, 0x0101010101010101, 0x0101010101010101, 0x0101010101010101,
0x0101010101010101, 0x0101010101010101, 0x0101010101010101, 0x0101010101010101}};
return H0;
}
};
};
} // namespace detail
} // namespace hash
} // namespace crypto3
} // namespace nil

#endif // CRYPTO3_STREEBOG_POLICY_HPP
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ set(TESTS_NAMES
"sha2"
"sha3"
"static_digest"
"streebog"
)

foreach(TEST_NAME ${TESTS_NAMES})
Expand Down
48 changes: 48 additions & 0 deletions test/streebog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//---------------------------------------------------------------------------//
// 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
//---------------------------------------------------------------------------//

#define BOOST_TEST_MODULE streebog_test

#include <nil/crypto3/hash/algorithm/hash.hpp>

#include <nil/crypto3/hash/streebog.hpp>
#include <nil/crypto3/hash/hash_state.hpp>

#include <boost/test/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/monomorphic.hpp>

#include <boost/static_assert.hpp>

#include <iostream>
#include <string>
#include <unordered_map>

#include <cstdio>
#include <cstring>

using namespace nil::crypto3::hash;

namespace boost {
namespace test_tools {
namespace tt_detail {
template<template<typename, typename> class P, typename K, typename V>
struct print_log_value<P<K, V>> {
void operator()(std::ostream&, P<K, V> const&) {
}
};
} // namespace tt_detail
} // namespace test_tools
} // namespace boost

BOOST_AUTO_TEST_SUITE(streebog_test_suite)

BOOST_AUTO_TEST_CASE(streebog_range_hash) {
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit d493af1

Please sign in to comment.