OpenCores
URL https://opencores.org/ocsvn/sha_core/sha_core/trunk

Subversion Repositories sha_core

[/] [sha_core/] [trunk/] [src/] [mrshs.c] - Blame information for rev 5

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 marsgod
/*
2
 * Implementation of the Secure Hashing Standard (SHS)
3
 * specified for use with the NIST Digital Signature Standard (DSS)
4
 *
5
 * Generates a 160 bit message digest. It should be impossible to come
6
 * come up with two messages that hash to the same value ("collision free").
7
 *
8
 * For use with byte-oriented messages only. Could/Should be speeded
9
 * up by unwinding loops in shs_transform(), and assembly patches.
10
 */
11
 
12
#include <stdio.h>
13
#include "miracl.h"
14
                /* for definition of mr_unsign32 & prototypes */
15
#define FIX
16
 
17
/* Include this #define in order to implement the
18
   rather mysterious 'fix' to SHS
19
 
20
   With this definition in, SHA-1 is implemented
21
   Without this definition, SHA-0 is implemented
22
*/
23
 
24
 
25
#define H0 0x67452301L
26
#define H1 0xefcdab89L
27
#define H2 0x98badcfeL
28
#define H3 0x10325476L
29
#define H4 0xc3d2e1f0L
30
 
31
#define K0 0x5a827999L
32
#define K1 0x6ed9eba1L
33
#define K2 0x8f1bbcdcL
34
#define K3 0xca62c1d6L
35
 
36
#define PAD  0x80
37
#define ZERO 0
38
 
39
/* functions */
40
 
41
#define S(n,x) (((x)<<n) | ((x)>>(32-n)))
42
 
43
#define F0(x,y,z) (z^(x&(y^z)))
44
#define F1(x,y,z) (x^y^z)
45
#define F2(x,y,z) ((x&y) | (z&(x|y))) 
46
#define F3(x,y,z) (x^y^z)
47
 
48
static void shs_transform(sha *sh)
49
{ /* basic transformation step */
50
    mr_unsign32 a,b,c,d,e,temp;
51
    int t;
52
#ifdef FIX
53
    for (t=16;t<80;t++) sh->w[t]=S(1,sh->w[t-3]^sh->w[t-8]^sh->w[t-14]^sh->w[t-16]);
54
#else
55
    for (t=16;t<80;t++) sh->w[t]=sh->w[t-3]^sh->w[t-8]^sh->w[t-14]^sh->w[t-16];
56
#endif
57
    a=sh->h[0]; b=sh->h[1]; c=sh->h[2]; d=sh->h[3]; e=sh->h[4];
58
    for (t=0;t<20;t++)
59
    { /* 20 times - mush it up */
60
        temp=K0+F0(b,c,d)+S(5,a)+e+sh->w[t];
61
        e=d; d=c;
62
        c=S(30,b);
63
        b=a; a=temp;
64
    }
65
    for (t=20;t<40;t++)
66
    { /* 20 more times - mush it up */
67
        temp=K1+F1(b,c,d)+S(5,a)+e+sh->w[t];
68
        e=d; d=c;
69
        c=S(30,b);
70
        b=a; a=temp;
71
    }
72
    for (t=40;t<60;t++)
73
    { /* 20 more times - mush it up */
74
        temp=K2+F2(b,c,d)+S(5,a)+e+sh->w[t];
75
        e=d; d=c;
76
        c=S(30,b);
77
        b=a; a=temp;
78
    }
79
    for (t=60;t<80;t++)
80
    { /* 20 more times - mush it up */
81
        temp=K3+F3(b,c,d)+S(5,a)+e+sh->w[t];
82
        e=d; d=c;
83
        c=S(30,b);
84
        b=a; a=temp;
85
    }
86
    sh->h[0]+=a; sh->h[1]+=b; sh->h[2]+=c;
87
    sh->h[3]+=d; sh->h[4]+=e;
88
}
89
 
90
void shs_init(sha *sh)
91
{ /* re-initialise */
92
    int i;
93
    for (i=0;i<80;i++) sh->w[i]=0L;
94
    sh->length[0]=sh->length[1]=0L;
95
    sh->h[0]=H0;
96
    sh->h[1]=H1;
97
    sh->h[2]=H2;
98
    sh->h[3]=H3;
99
    sh->h[4]=H4;
100
}
101
 
102
void shs_process(sha *sh,int byte)
103
{ /* process the next message byte */
104
    int cnt;
105
 
106
    cnt=(int)((sh->length[0]/32)%16);
107
 
108
    sh->w[cnt]<<=8;
109
    sh->w[cnt]|=(mr_unsign32)(byte&0xFF);
110
 
111
    sh->length[0]+=8;
112
    if (sh->length[0]==0L) { sh->length[1]++; sh->length[0]=0L; }
113
    if ((sh->length[0]%512)==0) shs_transform(sh);
114
}
115
 
116
void shs_hash(sha *sh,char hash[20])
117
{ /* pad message and finish - supply digest */
118
    int i;
119
    mr_unsign32 len0,len1;
120
    len0=sh->length[0];
121
    len1=sh->length[1];
122
    shs_process(sh,PAD);
123
    while ((sh->length[0]%512)!=448) shs_process(sh,ZERO);
124
    sh->w[14]=len1;
125
    sh->w[15]=len0;
126
    shs_transform(sh);
127
    for (i=0;i<20;i++)
128
    { /* convert to bytes */
129
        hash[i]=((sh->h[i/4]>>(8*(3-i%4))) & 0xffL);
130
    }
131
    shs_init(sh);
132
}
133
 
134
/* test program: should produce digest
135
 
136
   84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1
137
 
138
#include <stdio.h>
139
#include "miracl.h"
140
 
141
char test[]="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
142
 
143
int main()
144
{
145
    char hash[20];
146
    int i;
147
    sha sh;
148
    shs_init(&sh);
149
    for (i=0;test[i]!=0;i++) shs_process(&sh,test[i]);
150
    shs_hash(&sh,hash);
151
    for (i=0;i<20;i++) printf("%02x",(unsigned char)hash[i]);
152
    printf("\n");
153
    return 0;
154
}
155
 
156
*/
157
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.