Алгоритм построения цифрового дайджеста MD5 [Ло Шу] (pdf) читать постранично, страница - 2

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

реализацию WinForth32. Вот как выглядят приведенные выше логические операции
на Форте с выводом промежуточных результатов
\
:
\
:

-------------------------------------------------------------------------.= ( x -- x ) ?PRINT IF DUP SPACE ." = " 8 HEX U.R THEN ;
-------------------------------------------------------------------------D-FF-BC ( c b -- x )
?PRINT IF 2DUP CR ." X & Y = " 8 HEX U.R SPACE ." & " 8 HEX U.R THEN
AND .=
;
: D-FF-~B ( b -- ~b )
?PRINT IF DUP CR ." ~X = ~" 8 HEX U.R THEN
INVERT .=
;
: D-FF-~BD ( ~b d -- x )
?PRINT IF 2DUP SWAP CR ." ~X & Z = " 8 HEX U.R SPACE ." & " 8 HEX U.R
THEN
AND .=
;
: D-FF-F ( x1 x2 -- x3 )
?PRINT IF 2DUP SWAP CR ." . | .. = " 8 HEX U.R SPACE ." | " 8 HEX U.R
THEN
OR .=
;
: D-FF ( b-addr c-addr d-addr -- f )
@ ROT @ ROT @ ( d b c )
OVER
( d b c b )
D-FF-BC ( d b xi )
SWAP
( d xi b )
D-FF-~B ( d xi ~b )

\
:

:

:

:

:

\
:

:

:

\
:

:

:

:

\

ROT
( xi ~b d )
D-FF-~BD ( xi xii )
D-FF-F
( f )
;
-------------------------------------------------------------------------D-FG-~D ( d -- ~d )
?PRINT IF DUP CR ." ~Z = ~" 8 HEX U.R THEN
INVERT .=
;
D-FG-~DC ( ~d c -- x )
?PRINT IF 2DUP CR ." Y & ~Z = " 8 U.R SPACE ." & " 8 U.R THEN
AND .=
;
D-FG-BD ( b d -- x )
?PRINT IF 2DUP CR ." X & Z = " SWAP 8 U.R SPACE ." & " 8 U.R THEN
AND .=
;
D-FG-BDv~DC ( bd ~dc -- x )
?PRINT IF 2DUP CR ." XZ | ~ZY = " SWAP 8 U.R SPACE ." | " 8 U.R THEN
OR .=
;
D-FG ( b-addr c-addr d-addr -- g )
@ ROT @ ROT @ ROT ( b c d )
DUP
( b c d d )
D-FG-~D
( b c d xi )
ROT
( b d xi c )
D-FG-~DC
( b d xii )
-ROT
( xii b d )
D-FG-BD
( xii xiii )
D-FG-BDv~DC ( g )
;
-------------------------------------------------------------------------D-FH-B^C ( b c -- x )
?PRINT IF 2DUP CR ." X ^ Y = " SWAP 8 U.R SPACE ." ^ " 8 U.R THEN
XOR .=
;
D-FH-^D ( d x1 -- x2 )
?PRINT IF 2DUP CR ." . ^ Z = " 8 U.R SPACE ." ^ " 8 U.R THEN
XOR .=
;
D-FH ( b-addr c-addr d-addr -- h )
@ ROT @ ROT @ ( d b c )
D-FH-B^C ( d xi )
D-FH-^D ( h )
;
-------------------------------------------------------------------------D-FI-~D ( d -- ~d )
?PRINT IF DUP CR ." ~Z = ~" 8 HEX U.R THEN
INVERT .=
;
D-FI-Bv~D ( ~d b -- x )
?PRINT IF 2DUP CR ." X | ~Z = " 8 HEX U.R SPACE ." | " 8 HEX U.R THEN
OR .=
;
D-FI-^C ( c x1 -- x2 )
?PRINT IF 2DUP SWAP CR ." C ^ . = " 8 U.R SPACE ." ^ " 8 U.R THEN
XOR .=
;
D-FI ( b-addr c-addr d-addr -- i )
@ ROT @ ROT @ ROT ( b c d )
D-FI-~D
( b c xi )
ROT
( c xi b )
D-FI-Bv~D ( c xii )
D-FI-^C
( i )
;
--------------------------------------------------------------------------

И оптимизированная версия
: FF (
AND OR
: FG (
AND OR
: FH (
: FI (

b-addr
;
b-addr
;
b-addr
b-addr

c-addr d-addr -- f ) @ ROT @ ROT @ OVER AND SWAP INVERT ROT
c-addr d-addr -- g ) @ ROT @ ROT @ ROT DUP INVERT ROT AND -ROT
c-addr d-addr -- h ) @ ROT @ ROT @ XOR XOR ;
c-addr d-addr -- i ) @ ROT @ ROT @ ROT INVERT ROT OR XOR ;

В Форте очень удобно проверять как работает та или иная операция, например можно
выполнить в интерактивном режиме такой запрос:
A B C D-FF
И в результате на экране будет выведена полная трассировка операции.
Если вы пожелаете вывести результат не в шестнадцатеричном, а в двоичном виде, то
нужно везде заменить слово HEX на слово BINARY.

Преобразование блока данных
Для преобразования блока данных мы определим четыре базовых команды, которые
будет выполнять MD5 процессор. Эти четыре базовые команды производят обработку и
обновление регистров процессора на основании их предыдущего содержимого и на
основании данных из БЛОЧНОГО БУФЕРА.
Эти операции описываются следующим выражением:
a = b + ((a + F(b,c,d) + X[k] + T[i]) num&0x03);
l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
for (; sw < ew; sw++)
{
HOST_c2l(data,l); p[sw]=l;
}
if (ec)
{
HOST_c2l_p(data,l,ec); p[sw]=l;
}
}
return;
}
}
sw=len/HASH_CBLOCK;
if (sw > 0)
{
#if defined(HASH_BLOCK_DATA_ORDER)
{
HASH_BLOCK_DATA_ORDER(c,data,sw);
sw*=HASH_CBLOCK;
data+=sw;

len-=sw;
}
#endif

}
if (len!=0)
{
p = c->data;
c->num = len;
ew=len>>2;
/* слов для копирования */
ec=len&0x03;
for (; ew; ew--,p++)
{
HOST_c2l(data,l); *p=l;
}
HOST_c2l_p(data,l,ec);
*p=l;
}
}

- обработка последнего блока и получение цифрового дайджеста
void MD5_Final(unsigned char *md, MD5_CTX *c)
{
register HASH_LONG *p;
register unsigned long l;
register int i,j;
static const unsigned char end[4]={0x80,0x00,0x00,0x00};
const unsigned char *cp=end;
/* c->num определенно должен иметь место по крайней мере
* еще для одного байта. */
p=c->data;
i=c->num>>2;
j=c->num&0x03;
l = (j==0) ? 0 : p[i];
HOST_p_c2l(cp,l,j); p[i++]=l;
/* i это следующее 'неопределенное слово' */
if (i>(HASH_LBLOCK-2)) /* оставить место для Nl и Nh */
{
if (iNl;
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
p[HASH_LBLOCK-2]=c->Nl;
p[HASH_LBLOCK-1]=c->Nh;
#endif
HASH_BLOCK_HOST_ORDER (c,p,1);
#ifndef HASH_MAKE_STRING
#error "HASH_MAKE_STRING must be defined!"
#else
HASH_MAKE_STRING(c,md);
#endif
c->num=0;

/* очистить все, HASH_BLOCK может оставить некоторую информацию
* на стеке, но меня это не беспокоит
memset((void *)c,0,sizeof(HASH_CTX));
*/
}

А функция преобразования одного 16-байтового блока данных, использующая
рассмотренные выше операции преобразования регистров процессора выглядит так:
void md5_block_host_order(MD5_CTX *c, const void *data, int num)
{
const MD5_LONG *X=data;
register unsigned long A,B,C,D;
A=c->A;
B=c->B;
C=c->C;
D=c->D;
for (;num--;X+=HASH_LBLOCK)
{
/* Раунд 0 */
R0(A,B,C,D,X[ 0], 7,0xd76aa478L);
R0(D,A,B,C,X[ 1],12,0xe8c7b756L);
R0(C,D,A,B,X[ 2],17,0x242070dbL);
R0(B,C,D,A,X[ 3],22,0xc1bdceeeL);
R0(A,B,C,D,X[ 4], 7,0xf57c0fafL);
R0(D,A,B,C,X[ 5],12,0x4787c62aL);
R0(C,D,A,B,X[ 6],17,0xa8304613L);
R0(B,C,D,A,X[ 7],22,0xfd469501L);
R0(A,B,C,D,X[ 8], 7,0x698098d8L);
R0(D,A,B,C,X[ 9],12,0x8b44f7afL);
R0(C,D,A,B,X[10],17,0xffff5bb1L);
R0(B,C,D,A,X[11],22,0x895cd7beL);
R0(A,B,C,D,X[12], 7,0x6b901122L);
R0(D,A,B,C,X[13],12,0xfd987193L);
R0(C,D,A,B,X[14],17,0xa679438eL);
R0(B,C,D,A,X[15],22,0x49b40821L);
/* Раунд 1 */
R1(A,B,C,D,X[ 1], 5,0xf61e2562L);
R1(D,A,B,C,X[ 6], 9,0xc040b340L);
R1(C,D,A,B,X[11],14,0x265e5a51L);
R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL);
R1(A,B,C,D,X[ 5], 5,0xd62f105dL);
R1(D,A,B,C,X[10], 9,0x02441453L);
R1(C,D,A,B,X[15],14,0xd8a1e681L);
R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L);
R1(A,B,C,D,X[ 9], 5,0x21e1cde6L);
R1(D,A,B,C,X[14], 9,0xc33707d6L);
R1(C,D,A,B,X[ 3],14,0xf4d50d87L);
R1(B,C,D,A,X[ 8],20,0x455a14edL);
R1(A,B,C,D,X[13], 5,0xa9e3e905L);
R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L);
R1(C,D,A,B,X[