Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Nethermind/Nethermind.Core.Test/KeccakTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using FluentAssertions;
using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
using Nethermind.Evm.Tracing.GethStyle.Custom.JavaScript;
using NUnit.Framework;

namespace Nethermind.Core.Test
Expand Down Expand Up @@ -110,5 +111,13 @@ public void Span()

Assert.That(Keccak.Compute(byteArray.AsSpan()), Is.EqualTo(Keccak.Compute(byteArray)));
}

[TestCase("0xAAAAAAAAAAAA", "f8e06bc47a06f221f1523d3b646226e6cdb322619be1da7bafd113e459bf4140")]
public void Sanity_check(string hexString, string expected)
{
byte[] bytes = Bytes.FromHexString(hexString);
ValueHash256 h = ValueKeccak.Compute(bytes);
h.Bytes.ToHexString().Should().Be(expected);
}
}
}
266 changes: 105 additions & 161 deletions src/Nethermind/Nethermind.Core/Crypto/KeccakHash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,36 +104,31 @@ private static void KeccakF(Span<ulong> st)
ulong ema, eme, emi, emo, emu;
ulong esa, ese, esi, eso, esu;

{
// Access last element to perform range check once
// and not for every ascending access
_ = st[24];
}
aba = st[0];
abe = st[1];
abi = st[2];
abo = st[3];
abu = st[4];
aga = st[5];
age = st[6];
agi = st[7];
ago = st[8];
agu = st[9];
aka = st[10];
ake = st[11];
aki = st[12];
ako = st[13];
aku = st[14];
ama = st[15];
ame = st[16];
ami = st[17];
amo = st[18];
amu = st[19];
asa = st[20];
ase = st[21];
asi = st[22];
aso = st[23];
asu = st[24];
aso = st[23];
asi = st[22];
ase = st[21];
asa = st[20];
amu = st[19];
amo = st[18];
ami = st[17];
ame = st[16];
ama = st[15];
aku = st[14];
ako = st[13];
aki = st[12];
ake = st[11];
aka = st[10];
agu = st[9];
ago = st[8];
agi = st[7];
age = st[6];
aga = st[5];
abu = st[4];
abo = st[3];
abi = st[2];
abe = st[1];
aba = st[0];

for (int round = 0; round < ROUNDS; round += 2)
{
Expand All @@ -151,209 +146,158 @@ private static void KeccakF(Span<ulong> st)
@do = bCi ^ RotateLeft(bCu, 1);
du = bCo ^ RotateLeft(bCa, 1);

aba ^= da;
bCa = aba;
age ^= de;
bCe = RotateLeft(age, 44);
aki ^= di;
bCi = RotateLeft(aki, 43);
amo ^= @do;
bCo = RotateLeft(amo, 21);
asu ^= du;
bCu = RotateLeft(asu, 14);
eba = bCa ^ ((~bCe) & bCi);
eba ^= RoundConstants[round];
bCa = aba ^ da;
bCe = RotateLeft(age ^ de, 44);
bCi = RotateLeft(aki ^ di, 43);
eba = bCa ^ ((~bCe) & bCi) ^ RoundConstants[round];
bCo = RotateLeft(amo ^ @do, 21);
ebe = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(asu ^ du, 14);
ebi = bCi ^ ((~bCo) & bCu);
ebo = bCo ^ ((~bCu) & bCa);
ebu = bCu ^ ((~bCa) & bCe);

abo ^= @do;
bCa = RotateLeft(abo, 28);
agu ^= du;
bCe = RotateLeft(agu, 20);
aka ^= da;
bCi = RotateLeft(aka, 3);
ame ^= de;
bCo = RotateLeft(ame, 45);
asi ^= di;
bCu = RotateLeft(asi, 61);
bCa = RotateLeft(abo ^ @do, 28);
bCe = RotateLeft(agu ^ du, 20);
bCi = RotateLeft(aka ^ da, 3);
ega = bCa ^ ((~bCe) & bCi);
bCo = RotateLeft(ame ^ de, 45);
ege = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(asi ^ di, 61);
egi = bCi ^ ((~bCo) & bCu);
ego = bCo ^ ((~bCu) & bCa);
egu = bCu ^ ((~bCa) & bCe);

abe ^= de;
bCa = RotateLeft(abe, 1);
agi ^= di;
bCe = RotateLeft(agi, 6);
ako ^= @do;
bCi = RotateLeft(ako, 25);
amu ^= du;
bCo = RotateLeft(amu, 8);
asa ^= da;
bCu = RotateLeft(asa, 18);
bCa = RotateLeft(abe ^ de, 1);
bCe = RotateLeft(agi ^ di, 6);
bCi = RotateLeft(ako ^ @do, 25);
eka = bCa ^ ((~bCe) & bCi);
bCo = RotateLeft(amu ^ du, 8);
eke = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(asa ^ da, 18);
eki = bCi ^ ((~bCo) & bCu);
eko = bCo ^ ((~bCu) & bCa);
eku = bCu ^ ((~bCa) & bCe);

abu ^= du;
bCa = RotateLeft(abu, 27);
aga ^= da;
bCe = RotateLeft(aga, 36);
ake ^= de;
bCi = RotateLeft(ake, 10);
ami ^= di;
bCo = RotateLeft(ami, 15);
aso ^= @do;
bCu = RotateLeft(aso, 56);
bCa = RotateLeft(abu ^ du, 27);
bCe = RotateLeft(aga ^ da, 36);
bCi = RotateLeft(ake ^ de, 10);
ema = bCa ^ ((~bCe) & bCi);
bCo = RotateLeft(ami ^ di, 15);
eme = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(aso ^ @do, 56);
emi = bCi ^ ((~bCo) & bCu);
emo = bCo ^ ((~bCu) & bCa);
emu = bCu ^ ((~bCa) & bCe);

abi ^= di;
bCa = RotateLeft(abi, 62);
ago ^= @do;
bCe = RotateLeft(ago, 55);
aku ^= du;
bCi = RotateLeft(aku, 39);
ama ^= da;
bCo = RotateLeft(ama, 41);
ase ^= de;
bCu = RotateLeft(ase, 2);
bCa = RotateLeft(abi ^ di, 62);
bCe = RotateLeft(ago ^ @do, 55);
bCi = RotateLeft(aku ^ du, 39);
esa = bCa ^ ((~bCe) & bCi);
bCo = RotateLeft(ama ^ da, 41);
ese = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(ase ^ de, 2);
esi = bCi ^ ((~bCo) & bCu);
eso = bCo ^ ((~bCu) & bCa);
esu = bCu ^ ((~bCa) & bCe);

// prepareTheta
bCa = eba ^ ega ^ eka ^ ema ^ esa;

bCe = ebe ^ ege ^ eke ^ eme ^ ese;
bCi = ebi ^ egi ^ eki ^ emi ^ esi;
bCo = ebo ^ ego ^ eko ^ emo ^ eso;
bCu = ebu ^ egu ^ eku ^ emu ^ esu;

//thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
da = bCu ^ RotateLeft(bCe, 1);
bCa = eba ^ ega ^ eka ^ ema ^ esa;
bCi = ebi ^ egi ^ eki ^ emi ^ esi;
de = bCa ^ RotateLeft(bCi, 1);
bCo = ebo ^ ego ^ eko ^ emo ^ eso;
di = bCe ^ RotateLeft(bCo, 1);
@do = bCi ^ RotateLeft(bCu, 1);
du = bCo ^ RotateLeft(bCa, 1);

eba ^= da;
bCa = eba;
ege ^= de;
bCe = RotateLeft(ege, 44);
eki ^= di;
bCi = RotateLeft(eki, 43);
emo ^= @do;
bCo = RotateLeft(emo, 21);
esu ^= du;
bCu = RotateLeft(esu, 14);
aba = bCa ^ ((~bCe) & bCi);
aba ^= RoundConstants[round + 1];

bCi = RotateLeft(eki ^ di, 43);
bCe = RotateLeft(ege ^ de, 44);
bCa = eba ^ da;
aba = bCa ^ ((~bCe) & bCi) ^ RoundConstants[round + 1];
bCo = RotateLeft(emo ^ @do, 21);
abe = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(esu ^ du, 14);
abi = bCi ^ ((~bCo) & bCu);
abo = bCo ^ ((~bCu) & bCa);
abu = bCu ^ ((~bCa) & bCe);

ebo ^= @do;
bCa = RotateLeft(ebo, 28);
egu ^= du;
bCe = RotateLeft(egu, 20);
eka ^= da;
bCi = RotateLeft(eka, 3);
eme ^= de;
bCo = RotateLeft(eme, 45);
esi ^= di;
bCu = RotateLeft(esi, 61);
bCa = RotateLeft(ebo ^ @do, 28);
bCe = RotateLeft(egu ^ du, 20);
bCi = RotateLeft(eka ^ da, 3);
aga = bCa ^ ((~bCe) & bCi);
bCo = RotateLeft(eme ^ de, 45);
age = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(esi ^ di, 61);
agi = bCi ^ ((~bCo) & bCu);
ago = bCo ^ ((~bCu) & bCa);
agu = bCu ^ ((~bCa) & bCe);

ebe ^= de;
bCa = RotateLeft(ebe, 1);
egi ^= di;
bCe = RotateLeft(egi, 6);
eko ^= @do;
bCi = RotateLeft(eko, 25);
emu ^= du;
bCo = RotateLeft(emu, 8);
esa ^= da;
bCu = RotateLeft(esa, 18);
bCa = RotateLeft(ebe ^ de, 1);
bCe = RotateLeft(egi ^ di, 6);
bCi = RotateLeft(eko ^ @do, 25);
aka = bCa ^ ((~bCe) & bCi);
bCo = RotateLeft(emu ^ du, 8);
ake = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(esa ^ da, 18);
aki = bCi ^ ((~bCo) & bCu);
ako = bCo ^ ((~bCu) & bCa);
aku = bCu ^ ((~bCa) & bCe);

ebu ^= du;
bCa = RotateLeft(ebu, 27);
ega ^= da;
bCe = RotateLeft(ega, 36);
eke ^= de;
bCi = RotateLeft(eke, 10);
emi ^= di;
bCo = RotateLeft(emi, 15);
eso ^= @do;
bCu = RotateLeft(eso, 56);
bCa = RotateLeft(ebu ^ du, 27);
bCe = RotateLeft(ega ^ da, 36);
bCi = RotateLeft(eke ^ de, 10);
ama = bCa ^ ((~bCe) & bCi);
bCo = RotateLeft(emi ^ di, 15);
ame = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(eso ^ @do, 56);
ami = bCi ^ ((~bCo) & bCu);
amo = bCo ^ ((~bCu) & bCa);
amu = bCu ^ ((~bCa) & bCe);

ebi ^= di;
bCa = RotateLeft(ebi, 62);
ego ^= @do;
bCe = RotateLeft(ego, 55);
eku ^= du;
bCi = RotateLeft(eku, 39);
ema ^= da;
bCo = RotateLeft(ema, 41);
ese ^= de;
bCu = RotateLeft(ese, 2);
bCa = RotateLeft(ebi ^ di, 62);
bCe = RotateLeft(ego ^ @do, 55);
bCi = RotateLeft(eku ^ du, 39);
asa = bCa ^ ((~bCe) & bCi);
bCo = RotateLeft(ema ^ da, 41);
ase = bCe ^ ((~bCi) & bCo);
bCu = RotateLeft(ese ^ de, 2);
asi = bCi ^ ((~bCo) & bCu);
aso = bCo ^ ((~bCu) & bCa);
asu = bCu ^ ((~bCa) & bCe);
}

//copyToState(state, A)
st[0] = aba;
st[1] = abe;
st[2] = abi;
st[3] = abo;
st[4] = abu;
st[5] = aga;
st[6] = age;
st[7] = agi;
st[8] = ago;
st[9] = agu;
st[10] = aka;
st[11] = ake;
st[12] = aki;
st[13] = ako;
st[14] = aku;
st[15] = ama;
st[16] = ame;
st[17] = ami;
st[18] = amo;
st[19] = amu;
st[20] = asa;
st[21] = ase;
st[22] = asi;
st[23] = aso;
st[24] = asu;
st[23] = aso;
st[22] = asi;
st[21] = ase;
st[20] = asa;
st[19] = amu;
st[18] = amo;
st[17] = ami;
st[16] = ame;
st[15] = ama;
st[14] = aku;
st[13] = ako;
st[12] = aki;
st[11] = ake;
st[10] = aka;
st[9] = agu;
st[8] = ago;
st[7] = agi;
st[6] = age;
st[5] = aga;
st[4] = abu;
st[3] = abo;
st[2] = abi;
st[1] = abe;
st[0] = aba;
}

public static Span<byte> ComputeHash(ReadOnlySpan<byte> input, int size = HASH_SIZE)
Expand Down