Commits

Jonathan Simms committed 32ff761

closer

Comments (0)

Files changed (5)

 _obj
 digest-md5
 *.o
+_cgo*
-
 include $(GOROOT)/src/Make.inc
 
 TARG=slyphon.com/md5_gs
 
 include $(GOROOT)/src/Make.pkg
 
-# md5.o: md5.c md5.h
-#         gcc -o md5.o -fno-common -pipe -I. -dynamic -bundle md5.c
-
-
 #  define BYTE_ORDER 0
 #endif
 
-#define T_MASK ((gs_md5_word_t)~0)
+#define T_MASK ((unsigned int)~0)
 #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
 #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
 #define T3    0x242070db
 
 
 static void
-gs_md5_process(gs_md5_state_t *pms, const gs_md5_byte_t *data /*[64]*/)
+gs_md5_process(gs_md5_state_t *pms, const unsigned char *data /*[64]*/)
 {
-    gs_md5_word_t
+    unsigned int
 	a = pms->abcd[0], b = pms->abcd[1],
 	c = pms->abcd[2], d = pms->abcd[3];
-    gs_md5_word_t t;
+    unsigned int t;
 #if BYTE_ORDER > 0
     /* Define storage only for big-endian CPUs. */
-    gs_md5_word_t X[16];
+    unsigned int X[16];
 #else
     /* Define storage for little-endian or both types of CPUs. */
-    gs_md5_word_t xbuf[16];
-    const gs_md5_word_t *X;
+    unsigned int xbuf[16];
+    const unsigned int *X;
 #endif
 
     {
 	 */
 	static const int w = 1;
 
-	if (*((const gs_md5_byte_t *)&w)) /* dynamic little-endian */
+	if (*((const unsigned char *)&w)) /* dynamic little-endian */
 #endif
 #if BYTE_ORDER <= 0		/* little-endian */
 	{
 	     * On little-endian machines, we can process properly aligned
 	     * data without copying it.
 	     */
-	    if (!((data - (const gs_md5_byte_t *)0) & 3)) {
+	    if (!((data - (const unsigned char *)0) & 3)) {
 		/* data are properly aligned */
-		X = (const gs_md5_word_t *)data;
+		X = (const unsigned int *)data;
 	    } else {
 		/* not aligned */
 		memcpy(xbuf, data, 64);
 	     * On big-endian machines, we must arrange the bytes in the
 	     * right order.
 	     */
-	    const gs_md5_byte_t *xp = data;
+	    const unsigned char *xp = data;
 	    int i;
 
 #  if BYTE_ORDER == 0
 }
 
 void
-gs_md5_append(gs_md5_state_t *pms, const gs_md5_byte_t *data, int nbytes)
+gs_md5_append(gs_md5_state_t *pms, const unsigned char *data, int nbytes)
 {
-    const gs_md5_byte_t *p = data;
+    const unsigned char *p = data;
     int left = nbytes;
     int offset = (pms->count[0] >> 3) & 63;
-    gs_md5_word_t nbits = (gs_md5_word_t)(nbytes << 3);
+    unsigned int nbits = (unsigned int)(nbytes << 3);
 
     if (nbytes <= 0)
 	return;
 }
 
 void
-gs_md5_finish(gs_md5_state_t *pms, gs_md5_byte_t digest[16])
+gs_md5_finish(gs_md5_state_t *pms, unsigned char digest[16])
 {
-    static const gs_md5_byte_t pad[64] = {
+    static const unsigned char pad[64] = {
 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
     };
-    gs_md5_byte_t data[8];
+    unsigned char data[8];
     int i;
 
     /* Save the length before padding. */
     for (i = 0; i < 8; ++i)
-	data[i] = (gs_md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+	data[i] = (unsigned char)(pms->count[i >> 2] >> ((i & 3) << 3));
     /* Pad to 56 bytes mod 64. */
     gs_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
     /* Append the length. */
     gs_md5_append(pms, data, 8);
     for (i = 0; i < 16; ++i)
-	digest[i] = (gs_md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+	digest[i] = (unsigned char)(pms->abcd[i >> 2] >> ((i & 3) << 3));
 }
 
 /* Define the state of the MD5 Algorithm. */
 typedef struct gs_md5_state_s {
-    gs_md5_word_t count[2];	/* message length in bits, lsw first */
-    gs_md5_word_t abcd[4];		/* digest buffer */
-    gs_md5_byte_t buf[64];		/* accumulate block */
+    unsigned int count[2];	/* message length in bits, lsw first */
+    unsigned int abcd[4];		/* digest buffer */
+    unsigned char buf[64];		/* accumulate block */
 } gs_md5_state_t;
 
 #ifdef __cplusplus
 void gs_md5_init(gs_md5_state_t *pms);
 
 /* Append a string to the message. */
-void gs_md5_append(gs_md5_state_t *pms, const gs_md5_byte_t *data, int nbytes);
+void gs_md5_append(gs_md5_state_t *pms, const unsigned char *data, int nbytes);
 
 /* Finish the message and return the digest. */
-void gs_md5_finish(gs_md5_state_t *pms, gs_md5_byte_t digest[16]);
+void gs_md5_finish(gs_md5_state_t *pms, unsigned char digest[16]);
 
 #ifdef __cplusplus
 }  /* end extern "C" */
 package md5_gs
 
-/*
-#cgo CFLAGS -dynamic -bundle
-#include "../md5.h"
-*/
-
+//#cgo CFLAGS: -dynamic -bundle
+//#include "md5.h"
 import (
     "C"
-//    "unsafe"
 )
 
-type MD5State C.gs_md5_state_t
+import (
+    "unsafe"
+	"hash"
+	"os"
+)
+
+type digest struct {
+	state   C.gs_md5_state_t
+}
+
+func Init() hash.Hash {
+	d := new(digest)
+	d.Reset()
+	return d
+}
+
+func (d *digest) Size() int { return 32; }
+
+func (d *digest) Reset() {
+	C.gs_md5_init(&d.state)
+}
+
+func (d *digest) Write(p []byte) (nn int, err os.Error) {
+	// have to worry about overflows here? blah!
+	data := (*C.uchar)(unsafe.Pointer(&p[0]))
+	C.gs_md5_append(&d.state, data, C.int(len(p)))
+	return len(p), nil
+}
 
+func (d *digest) Sum() []byte {
+	var result [16]byte
+	C.gs_md5_finish(&d.state, (*C.uchar)(unsafe.Pointer(&result[0])))
+	return result[:]
+}