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