Refactored keccak constants initialization
This commit is contained in:
@@ -162,7 +162,7 @@ struct alignas(uint64_t) hash
|
||||
{
|
||||
uint8_t h[HASH_SIZE];
|
||||
|
||||
FORCEINLINE hash() : h{} {}
|
||||
FORCEINLINE constexpr hash() : h{} {}
|
||||
|
||||
constexpr hash(std::initializer_list<uint8_t> l) : h{} {
|
||||
auto it = l.begin();
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "keccak_constexpr.h"
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
enum KeccakParams {
|
||||
@@ -26,12 +28,6 @@ enum KeccakParams {
|
||||
|
||||
extern const uint64_t keccakf_rndc[24];
|
||||
|
||||
// keccak hash of a single 0x00 byte
|
||||
constexpr hash keccak_0x00{ 0xbc, 0x36, 0x78, 0x9e, 0x7a, 0x1e, 0x28, 0x14, 0x36, 0x46, 0x42, 0x29, 0x82, 0x8f, 0x81, 0x7d, 0x66, 0x12, 0xf7, 0xb4, 0x77, 0xd6, 0x65, 0x91, 0xff, 0x96, 0xa9, 0xe0, 0x64, 0xbc, 0xc9, 0x8a };
|
||||
|
||||
// keccak hash of "subaddress_viewpub"
|
||||
constexpr hash keccak_subaddress_viewpub{ 0x40, 0xb2, 0x0e, 0x14, 0xc5, 0x9e, 0xdc, 0x32, 0x57, 0xb1, 0x71, 0xb0, 0xf3, 0x76, 0x27, 0x01, 0x8e, 0x92, 0x45, 0xed, 0xd5, 0x2a, 0x69, 0x0b, 0xf6, 0xd9, 0xe6, 0x21, 0xa0, 0x98, 0xb9, 0x6a };
|
||||
|
||||
typedef void (*keccakf_func)(std::array<uint64_t, 25>&);
|
||||
extern keccakf_func keccakf;
|
||||
|
||||
|
||||
144
src/keccak_constexpr.h
Normal file
144
src/keccak_constexpr.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
|
||||
* Copyright (c) 2021-2025 SChernykh <https://github.com/SChernykh>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
namespace ConstexprKeccak
|
||||
{
|
||||
|
||||
template<int y>
|
||||
static FORCEINLINE constexpr uint64_t rotl64(uint64_t x) { return (x << y) | (x >> (64 - y)); }
|
||||
|
||||
template<int ROUNDS>
|
||||
static FORCEINLINE constexpr void keccakf(std::array<uint64_t, 25>& st)
|
||||
{
|
||||
constexpr uint64_t keccakf_rndc[24] =
|
||||
{
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
|
||||
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
|
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
|
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
|
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
|
||||
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
|
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
|
||||
};
|
||||
|
||||
for (int round = 0; round < ROUNDS; ++round) {
|
||||
uint64_t bc[5] = {};
|
||||
|
||||
// Theta
|
||||
for (int i = 0; i < 5; ++i) bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
const uint64_t t = bc[(i + 4) % 5] ^ rotl64<1>(bc[(i + 1) % 5]);
|
||||
for (int j = 0; j < 25; j += 5) st[i + j] ^= t;
|
||||
}
|
||||
|
||||
// Rho Pi
|
||||
const uint64_t st1 = st[1];
|
||||
st[ 1] = rotl64<44>(st[ 6]);
|
||||
st[ 6] = rotl64<20>(st[ 9]);
|
||||
st[ 9] = rotl64<61>(st[22]);
|
||||
st[22] = rotl64<39>(st[14]);
|
||||
st[14] = rotl64<18>(st[20]);
|
||||
st[20] = rotl64<62>(st[ 2]);
|
||||
st[ 2] = rotl64<43>(st[12]);
|
||||
st[12] = rotl64<25>(st[13]);
|
||||
st[13] = rotl64< 8>(st[19]);
|
||||
st[19] = rotl64<56>(st[23]);
|
||||
st[23] = rotl64<41>(st[15]);
|
||||
st[15] = rotl64<27>(st[ 4]);
|
||||
st[ 4] = rotl64<14>(st[24]);
|
||||
st[24] = rotl64< 2>(st[21]);
|
||||
st[21] = rotl64<55>(st[ 8]);
|
||||
st[ 8] = rotl64<45>(st[16]);
|
||||
st[16] = rotl64<36>(st[ 5]);
|
||||
st[ 5] = rotl64<28>(st[ 3]);
|
||||
st[ 3] = rotl64<21>(st[18]);
|
||||
st[18] = rotl64<15>(st[17]);
|
||||
st[17] = rotl64<10>(st[11]);
|
||||
st[11] = rotl64< 6>(st[ 7]);
|
||||
st[ 7] = rotl64< 3>(st[10]);
|
||||
st[10] = rotl64< 1>(st1);
|
||||
|
||||
// Chi
|
||||
for (int i = 0; i < 25; i += 5) {
|
||||
const uint64_t t[5] = { st[i], st[i + 1], st[i + 2], st[i + 3], st[i + 4] };
|
||||
for (int j = 0; j < 5; ++j) st[i + j] ^= ~t[(j + 1) % 5] & t[(j + 2) % 5];
|
||||
}
|
||||
|
||||
// Iota
|
||||
st[0] ^= keccakf_rndc[round];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ConstexprKeccak
|
||||
|
||||
template<int len>
|
||||
static constexpr hash keccak(const char (&input)[len])
|
||||
{
|
||||
hash result{};
|
||||
|
||||
if constexpr (len <= 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr int inlen = len - 1;
|
||||
|
||||
constexpr int rsiz = 136;
|
||||
constexpr int rsizw = rsiz / 8;
|
||||
|
||||
static_assert(inlen < rsiz, "Too long input");
|
||||
|
||||
uint8_t temp[144] = {};
|
||||
|
||||
for (int i = 0; i < inlen; ++i) {
|
||||
temp[i] = static_cast<uint8_t>(input[i]);
|
||||
}
|
||||
|
||||
temp[inlen] = 1;
|
||||
temp[rsiz - 1] |= 0x80;
|
||||
|
||||
std::array<uint64_t, 25> st = {};
|
||||
|
||||
for (int i = 0; i < rsizw; i++) {
|
||||
uint64_t k = 0;
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
k |= static_cast<uint64_t>(temp[i * 8 + j]) << (j * 8);
|
||||
}
|
||||
st[i] ^= k;
|
||||
}
|
||||
|
||||
ConstexprKeccak::keccakf<24>(st);
|
||||
|
||||
for (size_t i = 0; i < HASH_SIZE; ++i) {
|
||||
result.h[i] = static_cast<uint8_t>(st[i / 8] >> ((i % 8) * 8));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr hash keccak_0x00 = keccak("\0");
|
||||
constexpr hash keccak_subaddress_viewpub = keccak("subaddress_viewpub");
|
||||
constexpr hash keccak_onion_address_v3 = keccak("onion_address_v3");
|
||||
|
||||
static_assert((keccak_0x00.h[0] == 0xBC) && (keccak_0x00.h[1] == 0x36) && (keccak_0x00.h[2] == 0x78) && (keccak_0x00.h[3] == 0x9E), "constexpr keccak code check failed");
|
||||
|
||||
} // namespace p2pool
|
||||
@@ -240,7 +240,8 @@ void MergeMiningClientTari::on_external_block(const PoolBlock& block)
|
||||
|
||||
// Filter aux chain data only
|
||||
for (const auto& i : block.m_mergeMiningExtra) {
|
||||
if (i.first != keccak_subaddress_viewpub) {
|
||||
if ((i.first != keccak_subaddress_viewpub) &&
|
||||
(i.first != keccak_onion_address_v3)) {
|
||||
mm_extra.emplace_back(i.first, i.second);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user