github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/gc/md5.c (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // 64-bit MD5 (does full MD5 but returns 64 bits only).
     6  // Translation of ../../pkg/crypto/md5/md5*.go.
     7  
     8  #include <u.h>
     9  #include <libc.h>
    10  #include "go.h"
    11  #include "md5.h"
    12  
    13  static int md5block(MD5 *dig, uchar *p, int nn);
    14  
    15  enum {
    16  	_Chunk = 64
    17  };
    18  
    19  #define _Init0 0x67452301
    20  #define _Init1 0xEFCDAB89
    21  #define _Init2 0x98BADCFE
    22  #define _Init3 0x10325476
    23  
    24  void
    25  md5reset(MD5 *d)
    26  {
    27  	d->s[0] = _Init0;
    28  	d->s[1] = _Init1;
    29  	d->s[2] = _Init2;
    30  	d->s[3] = _Init3;
    31  	d->nx = 0;
    32  	d->len = 0;
    33  }
    34  
    35  void
    36  md5write(MD5 *d, uchar *p, int nn)
    37  {
    38  	int i, n;
    39  
    40  	d->len += nn;
    41  	if(d->nx > 0) {
    42  		n = nn;
    43  		if(n > _Chunk - d->nx)
    44  			n = _Chunk - d->nx;
    45  		for(i=0; i<n; i++)
    46  			d->x[d->nx+i] = p[i];
    47  		d->nx += n;
    48  		if(d->nx == _Chunk) {
    49  			md5block(d, d->x, _Chunk);
    50  			d->nx = 0;
    51  		}
    52  		p += n;
    53  		nn -= n;
    54  	}
    55  	n = md5block(d, p, nn);
    56  	p += n;
    57  	nn -= n;
    58  	if(nn > 0) {
    59  		for(i=0; i<nn; i++)
    60  			d->x[i] = p[i];
    61  		d->nx = nn;
    62  	}
    63  }
    64  
    65  uint64
    66  md5sum(MD5 *d)
    67  {
    68  	uchar tmp[64];
    69  	int i;
    70  	uint64 len;
    71  
    72  	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
    73  	len = d->len;
    74  	memset(tmp, 0, sizeof tmp);
    75  	tmp[0] = 0x80;
    76  	if(len%64 < 56)
    77  		md5write(d, tmp, 56-len%64);
    78  	else
    79  		md5write(d, tmp, 64+56-len%64);
    80  
    81  	// Length in bits.
    82  	len <<= 3;
    83  	for(i=0; i<8; i++)
    84  		tmp[i] = len>>(8*i);
    85  	md5write(d, tmp, 8);
    86  
    87  	if(d->nx != 0)
    88  		fatal("md5sum");
    89  
    90  	return d->s[0] | ((uint64)d->s[1]<<32);
    91  }
    92  
    93  
    94  // MD5 block step.
    95  // In its own file so that a faster assembly or C version
    96  // can be substituted easily.
    97  
    98  // table[i] = int((1<<32) * abs(sin(i+1 radians))).
    99  static uint32 table[64] = {
   100  	// round 1
   101  	0xd76aa478,
   102  	0xe8c7b756,
   103  	0x242070db,
   104  	0xc1bdceee,
   105  	0xf57c0faf,
   106  	0x4787c62a,
   107  	0xa8304613,
   108  	0xfd469501,
   109  	0x698098d8,
   110  	0x8b44f7af,
   111  	0xffff5bb1,
   112  	0x895cd7be,
   113  	0x6b901122,
   114  	0xfd987193,
   115  	0xa679438e,
   116  	0x49b40821,
   117  
   118  	// round 2
   119  	0xf61e2562,
   120  	0xc040b340,
   121  	0x265e5a51,
   122  	0xe9b6c7aa,
   123  	0xd62f105d,
   124  	0x2441453,
   125  	0xd8a1e681,
   126  	0xe7d3fbc8,
   127  	0x21e1cde6,
   128  	0xc33707d6,
   129  	0xf4d50d87,
   130  	0x455a14ed,
   131  	0xa9e3e905,
   132  	0xfcefa3f8,
   133  	0x676f02d9,
   134  	0x8d2a4c8a,
   135  
   136  	// round3
   137  	0xfffa3942,
   138  	0x8771f681,
   139  	0x6d9d6122,
   140  	0xfde5380c,
   141  	0xa4beea44,
   142  	0x4bdecfa9,
   143  	0xf6bb4b60,
   144  	0xbebfbc70,
   145  	0x289b7ec6,
   146  	0xeaa127fa,
   147  	0xd4ef3085,
   148  	0x4881d05,
   149  	0xd9d4d039,
   150  	0xe6db99e5,
   151  	0x1fa27cf8,
   152  	0xc4ac5665,
   153  
   154  	// round 4
   155  	0xf4292244,
   156  	0x432aff97,
   157  	0xab9423a7,
   158  	0xfc93a039,
   159  	0x655b59c3,
   160  	0x8f0ccc92,
   161  	0xffeff47d,
   162  	0x85845dd1,
   163  	0x6fa87e4f,
   164  	0xfe2ce6e0,
   165  	0xa3014314,
   166  	0x4e0811a1,
   167  	0xf7537e82,
   168  	0xbd3af235,
   169  	0x2ad7d2bb,
   170  	0xeb86d391,
   171  };
   172  
   173  static uint32 shift1[] = { 7, 12, 17, 22 };
   174  static uint32 shift2[] = { 5, 9, 14, 20 };
   175  static uint32 shift3[] = { 4, 11, 16, 23 };
   176  static uint32 shift4[] = { 6, 10, 15, 21 };
   177  
   178  static int
   179  md5block(MD5 *dig, uchar *p, int nn)
   180  {
   181  	uint32 a, b, c, d, aa, bb, cc, dd;
   182  	int i, j, n;
   183  	uint32 X[16];
   184  
   185  	a = dig->s[0];
   186  	b = dig->s[1];
   187  	c = dig->s[2];
   188  	d = dig->s[3];
   189  	n = 0;
   190  
   191  	while(nn >= _Chunk) {
   192  		aa = a;
   193  		bb = b;
   194  		cc = c;
   195  		dd = d;
   196  
   197  		for(i=0; i<16; i++) {
   198  			j = i*4;
   199  			X[i] = p[j] | (p[j+1]<<8) | (p[j+2]<<16) | (p[j+3]<<24);
   200  		}
   201  
   202  		// Round 1.
   203  		for(i=0; i<16; i++) {
   204  			uint32 x, t, s, f;
   205  			x = i;
   206  			t = i;
   207  			s = shift1[i%4];
   208  			f = ((c ^ d) & b) ^ d;
   209  			a += f + X[x] + table[t];
   210  			a = a<<s | a>>(32-s);
   211  			a += b;
   212  
   213  			t = d;
   214  			d = c;
   215  			c = b;
   216  			b = a;
   217  			a = t;
   218  		}
   219  
   220  		// Round 2.
   221  		for(i=0; i<16; i++) {
   222  			uint32 x, t, s, g;
   223  
   224  			x = (1+5*i)%16;
   225  			t = 16+i;
   226  			s = shift2[i%4];
   227  			g = ((b ^ c) & d) ^ c;
   228  			a += g + X[x] + table[t];
   229  			a = a<<s | a>>(32-s);
   230  			a += b;
   231  
   232  			t = d;
   233  			d = c;
   234  			c = b;
   235  			b = a;
   236  			a = t;
   237  		}
   238  
   239  		// Round 3.
   240  		for(i=0; i<16; i++) {
   241  			uint32 x, t, s, h;
   242  
   243  			x = (5+3*i)%16;
   244  			t = 32+i;
   245  			s = shift3[i%4];
   246  			h = b ^ c ^ d;
   247  			a += h + X[x] + table[t];
   248  			a = a<<s | a>>(32-s);
   249  			a += b;
   250  
   251  			t = d;
   252  			d = c;
   253  			c = b;
   254  			b = a;
   255  			a = t;
   256  		}
   257  
   258  		// Round 4.
   259  		for(i=0; i<16; i++) {
   260  			uint32 x, s, t, ii;
   261  
   262  			x = (7*i)%16;
   263  			s = shift4[i%4];
   264  			t = 48+i;
   265  			ii = c ^ (b | ~d);
   266  			a += ii + X[x] + table[t];
   267  			a = a<<s | a>>(32-s);
   268  			a += b;
   269  
   270  			t = d;
   271  			d = c;
   272  			c = b;
   273  			b = a;
   274  			a = t;
   275  		}
   276  
   277  		a += aa;
   278  		b += bb;
   279  		c += cc;
   280  		d += dd;
   281  
   282  		p += _Chunk;
   283  		n += _Chunk;
   284  		nn -= _Chunk;
   285  	}
   286  
   287  	dig->s[0] = a;
   288  	dig->s[1] = b;
   289  	dig->s[2] = c;
   290  	dig->s[3] = d;
   291  	return n;
   292  }