Дополнение 1: ещё один обнаруженный способ
Всякие интересные решения часто приходят перед сном и это не исключение. Кто-то пытаясь заснуть считает овец. Я же думал об алгоритме хэширования. И обнаружил ещё один интересующий меня участок кода. Функция SHA_second_hashing рассчитывает второй хэш из первого и, как мы ранее обсуждали, в ней нет смысла делать рассчет хэша до кноца. В CUDA свою окончательную форму принимают лишь последние 2 32-битных элемента хэша. У меня же проводится тестирование последнего элемента на равенство 0 и вылету из функции при не соблюдение данного условия.. Но в процессе 64 раундов хэширования очереди сообщений так сильно необходимый в состояние 0 последний элемент не меняет своё состояние в последних 3-ех раундах. Он лишь меняет свою позицию.
Посмотрите сюда:
Код:
for i:=0 to 63 do
begin
S1 := rightrotate(e,6) xor rightrotate(e,11) xor rightrotate(e,25);
ch := (e and f) xor ((not e) and g);
temp1 := h + S1 + ch + k[i] + w[i];
S0 := rightrotate(a,2) xor rightrotate(a,13) xor rightrotate(a,22);
maj := (a and b) xor (a and c) xor (b and c);
temp2 := S0 + maj;
h := g;
g := f;
f := e;
e := d + temp1;
d := c;
c := b;
b := a;
a := temp1 + temp2;
end;
w[7]:=h7+h;
if w[7]<>0 then
begin
result:=false;
Exit;
end;
На последнем 64-ом раунде h принимает свое окончательное значение, затем уже вне цикла складывается с изначальным состоянием h7 и тестируется на соответствие нулю. Но посмотрите что же такое h на последнем раунде на самом деле. Это состояние g на предпоследнем раунде. Т.е. h по факту не изменился, но изменилось его положение в памяти. Последнее фактическое изменение h происходит на 60-ом раунде. Тогда зачем нам нужно ещё 3 раунда хэширования если на 60-ом раунде сравнение с целью не даст нужный результат? Добавим в функцию тест на достижение цели после 60-ого раунда учитывая тот факт, что реальное местоположение h находится в области памяти выделенной под e.
Внесем изменения в исследуемую функцию:
Код:
function SHA_second_hashing(var w:array of Cardinal):boolean;
var
h0,h1,h2,h3,h4,h5,h6,h7:Cardinal;
i:integer;
s0,s1,ch,temp1,temp2,maj:Cardinal;
a,b,c,d,e,f,g,h:Cardinal;
begin
h0 := $6a09e667;
h1 := $bb67ae85;
h2 := $3c6ef372;
h3 := $a54ff53a;
h4 := $510e527f;
h5 := $9b05688c;
h6 := $1f83d9ab;
h7 := $5be0cd19;
for i:=16 to 63 do
begin
s0 := rightrotate(w[i-15],7) xor rightrotate(w[i-15],18) xor (w[i-15] shr 3);
s1 := rightrotate(w[i-2],17) xor rightrotate(w[i-2],19) xor (w[i-2] shr 10);
w[i] := w[i-16] + s0 + w[i-7] + s1;
end;
a:=h0;
b:=h1;
c:=h2;
d:=h3;
e:=h4;
f:=h5;
g:=h6;
h:=h7;
for i:=0 to 60 do
begin
S1 := rightrotate(e,6) xor rightrotate(e,11) xor rightrotate(e,25);
ch := (e and f) xor ((not e) and g);
temp1 := h + S1 + ch + k[i] + w[i];
S0 := rightrotate(a,2) xor rightrotate(a,13) xor rightrotate(a,22);
maj := (a and b) xor (a and c) xor (b and c);
temp2 := S0 + maj;
h := g;
g := f;
f := e;
e := d + temp1;
d := c;
c := b;
b := a;
a := temp1 + temp2;
end;
if h7+e<>0 then
begin
result:=false;
Exit;
end;
for i:=61 to 63 do
begin
S1 := rightrotate(e,6) xor rightrotate(e,11) xor rightrotate(e,25);
ch := (e and f) xor ((not e) and g);
temp1 := h + S1 + ch + k[i] + w[i];
S0 := rightrotate(a,2) xor rightrotate(a,13) xor rightrotate(a,22);
maj := (a and b) xor (a and c) xor (b and c);
temp2 := S0 + maj;
h := g;
g := f;
f := e;
e := d + temp1;
d := c;
c := b;
b := a;
a := temp1 + temp2;
end;
w[7]:=h7+h;
if w[7]<>0 then
begin
result:=false;
Exit;
end;
w[6]:=h6+g;
w[5]:=h6+f;
w[4]:=h6+e;
w[3]:=h6+d;
w[2]:=h6+c;
w[1]:=h6+b;
w[0]:=h6+a;
result:=true;
end;
Делаем замер и получаем прирост к хэшрейту до состояния 147058 х/с. Коэффициент увеличения хэшрейта х1.3676