changeset 5:cff9960a019c

Removed update(ubyte x) from Hash class. Rewrote hash function padding. Updated hash functions to use ulong counter for bytes (was previously uint).
author Thomas Dixon <reikon@reikon.us>
date Thu, 14 Aug 2008 23:51:56 -0400
parents 3de3a2de13a0
children 5cb17e09d685
files dcrypt/crypto/Hash.d
diffstat 1 files changed, 68 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/dcrypt/crypto/Hash.d	Thu Aug 14 01:45:24 2008 -0400
+++ b/dcrypt/crypto/Hash.d	Thu Aug 14 23:51:56 2008 -0400
@@ -12,84 +12,88 @@
 
 /** Base class for all cryptographic hash functions */
 class Hash {
-	private const enum {
-		MODE_MD=0, // MDx, RipeMD, etc
-		MODE_SHA,
-		MODE_TIGER
-	}
+    private const enum {
+        MODE_MD=0, // MDx, RipeMD, etc
+        MODE_SHA,
+        MODE_TIGER
+    }
     
-	protected {
+    protected {
         ubyte[] buffer;
-        uint bytes,
-             index;
+        ulong bytes;
+        uint index;
     }
         
-	this (void[] input_=null) {
-		buffer = new ubyte[blockSize];
+    this (void[] input_=null) {
+        buffer = new ubyte[blockSize];
         ubyte[] input = cast(ubyte[]) input_;
         if (input)
             update(input);
-	}
+    }
+    
+    /** Returns: The block size of the hash function in bytes. */
+    abstract uint blockSize();
     
-	/** Returns: The block size of the hash function in bytes. */
-	abstract uint blockSize();
-	
-	/** Returns: The output size of the hash function in bytes. */
-	abstract uint digestSize();
-	
-	/** Returns: The name of the algorithm we're implementing. */
-	abstract char[] name();
+    /** Returns: The output size of the hash function in bytes. */
+    abstract uint digestSize();
+    
+    /** Returns: The name of the algorithm we're implementing. */
+    abstract char[] name();
     
     /** Returns: A copy of this hash object. */
     abstract Hash copy();
 
-	/**
-	 * Introduce data into the hash function.
-	 * 
-	 * Params:
-	 *     input_ = Data to be processed.
-	 */
-	void update(void[] input_) {
-		ubyte[] input = cast(ubyte[]) input_;
-		foreach (ubyte i; input)
-			update(i);
-	}
-	
-	void update(ubyte input) {
-		bytes++;
-		buffer[index++] = input;
-		if (index == blockSize) {
-			transform(buffer);
-			index = 0;
-		}
-	}
-	
-	/** Hash function's internal transformation. */
-	protected abstract void transform(ubyte[] input);
+    /**
+     * Introduce data into the hash function.
+     * 
+     * Params:
+     *     input_ = Data to be processed.
+     */
+    void update(void[] input_) {
+        ubyte[] input = cast(ubyte[]) input_;
+        foreach (ubyte i; input) {
+            bytes++;
+            buffer[index++] = i;
+            if (index == blockSize) {
+                transform(buffer);
+                index = 0;
+            }   
+        }
+            
+    }
+    
+    /** Hash function's internal transformation. */
+    protected abstract void transform(ubyte[] input);
     
-	/** 
-	 * Pad message in the respective manner.
-	 * 
-	 * Params:
-	 *     mode = Mode constant dictating in which manner
-	 *            to pad the message.
-	 */
-	protected void padMessage(uint mode) {
-		ulong length = bytes << 3;
-		
-		update(((mode == MODE_TIGER) ? 0x01 : 0x80));
-        uint count = (blockSize-(blockSize >> 3));
-        if (index > count)
-            while (index != 0)
-                    update(0);
-        while (index < (count + ((blockSize == 128) ? 8 : 0)))
-            update(0);
+    /** 
+     * Pad message in the respective manner.
+     * 
+     * Params:
+     *     mode = Mode constant dictating in which manner
+     *            to pad the message.
+     */
+    protected void padMessage(uint mode) {
+        ulong bits = bytes << 3;
+        
+        // Add the pad marker
+        buffer[index++] = ((mode == MODE_TIGER) ? 0x01 : 0x80);
+        if (index == blockSize) {
+            transform(buffer);
+            index = 0;
+        }
+        
+        // Pad with null bytes
+        if (index >= (blockSize-(blockSize >> 3)))
+            update(new ubyte[blockSize-index]);
+        update(new ubyte[(blockSize-ulong.sizeof)-index]);
+        
+        // Length padding
+        ubyte[] length = new ubyte[ulong.sizeof];
+        for (int i = 0, j = 0; i < 64; i+=8) // little endian
+                length[j++] = bits >> i;
         if (mode == MODE_SHA)
-            for (int i = 56; i >= 0; i-=8) // big endian
-                update(length >> i);
-        else
-            for (int i = 0; i < 64; i+=8) // little endian
-                update(length >> i);
+            length.reverse; // big endian
+        update(length);
     }
     
     /**