/* * 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/. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright 2017-2018 Danny Robson */ #ifndef CRUFT_CRYPTO_STREAM_SALSA_HPP #define CRUFT_CRYPTO_STREAM_SALSA_HPP #include #include #include #include namespace cruft::crypto::stream::salsa { /////////////////////////////////////////////////////////////////////////// constexpr uint32_t R (uint32_t a, uint32_t b, uint32_t c, uint32_t k) { return b ^ util::rotatel (a + c, k); } /////////////////////////////////////////////////////////////////////////// constexpr std::array quarter (std::array y) noexcept { std::array z {}; z[1] = R (y[0], y[1], y[3], 7); z[2] = R (z[1], y[2], y[0], 9); z[3] = R (z[2], y[3], z[1], 13); z[0] = R (z[3], y[0], z[2], 18); return z; } /////////////////////////////////////////////////////////////////////////// constexpr std::array row (const std::array y) noexcept { const auto &[z00, z01, z02, z03] = quarter ({y[ 0], y[ 1], y[ 2], y[ 3]}); const auto &[z05, z06, z07, z04] = quarter ({y[ 5], y[ 6], y[ 7], y[ 4]}); const auto &[z10, z11, z08, z09] = quarter ({y[10], y[11], y[ 8], y[ 9]}); const auto &[z15, z12, z13, z14] = quarter ({y[15], y[12], y[13], y[14]}); return { z00, z01, z02, z03, z04, z05, z06, z07, z08, z09, z10, z11, z12, z13, z14, z15 }; } /////////////////////////////////////////////////////////////////////////// constexpr std::array col (const std::array x) noexcept { const auto &[y00, y04, y08, y12] = quarter ({x[ 0], x[ 4], x[ 8], x[12]}); const auto &[y05, y09, y13, y01] = quarter ({x[ 5], x[ 9], x[13], x[ 1]}); const auto &[y10, y14, y02, y06] = quarter ({x[10], x[14], x[ 2], x[ 6]}); const auto &[y15, y03, y07, y11] = quarter ({x[15], x[ 3], x[ 7], x[11]}); return { y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y10, y11, y12, y13, y14, y15, }; } /////////////////////////////////////////////////////////////////////////// constexpr std::array doubleround (const std::array x) noexcept { return row (col (x)); } } namespace cruft::crypto::stream { /////////////////////////////////////////////////////////////////////////// std::array salsa20 (const std::array) noexcept; } #endif