diff -uw rainbowcrack-1.2-src/src/HashAlgorithm.cpp rainbowcrack-1.2-src/src-padlock/HashAlgorithm.cpp
--- rainbowcrack-1.2-src/src/HashAlgorithm.cpp	2003-11-23 00:33:22.000000000 +0100
+++ rainbowcrack-1.2-src/src-padlock/HashAlgorithm.cpp	2007-02-10 18:41:11.000000000 +0100
@@ -12,6 +12,8 @@
 #ifdef _WIN32
 	#pragma comment(lib, "libeay32.lib")
 #endif
+#include <cstring> /* for memcpy() */
+#include <byteswap.h> /* for bswap_32() used in bswap_shabuffer */
 
 void setup_des_key(unsigned char key_56[], des_key_schedule &ks)
 {
@@ -57,3 +59,81 @@
 {
 	SHA1(pPlain, nPlainLen, pHash);
 }
+
+/*
+   Preliminary direct implementation of VIA PadLock Hardware SHA1/SHA256 by eddy at klopper net
+
+   Sample benchmark numbers:
+     sha1 hash speed:  292397/s           sha1 step speed: 248015/s
+         sha1padlock: 1953125/s    sha1padlock step speed: 912408/s
+
+   Extra speed can be achieved by aligning the m_Hash[] member in ChainWalkContext.h
+   and removing the bswap operations, but then the input must be pre-processed instead.
+*/
+struct sha_t
+{
+   char   output[128];
+} __attribute__((aligned(16)));
+
+inline void padlock_xsha1(unsigned char *pPlain, char *pHash, int nPlainLen)
+{
+  asm volatile
+  (
+    "xsha1" : "+S"(pPlain), "+D"(pHash) : "c"(nPlainLen), "a"(0) : "memory"
+  );
+}
+
+
+inline void padlock_xsha256(unsigned char *pPlain, char *pHash, int nPlainLen)
+{
+  asm volatile
+  (
+    "xsha256" : "+S"(pPlain), "+D"(pHash) : "c"(nPlainLen), "a"(0) : "memory"
+  );
+}
+
+inline void bswap_shabuffer(char* src, unsigned char* dest, int len)
+{
+  int i;
+  for(i = 0 ; i<len ; ++i )
+  {
+    ((int*)dest)[i] = bswap_32( ((int*)src)[i] );
+  }
+}
+
+void HashSHA1padlock(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
+{
+  struct sha_t sha;
+
+  /* Initialize output buffer with SHA-1 hash constants */
+  ((int*)&sha.output)[0] = 0x67452301;
+  ((int*)&sha.output)[1] = 0xEFCDAB89;
+  ((int*)&sha.output)[2] = 0x98BADCFE;
+  ((int*)&sha.output)[3] = 0x10325476;
+  ((int*)&sha.output)[4] = 0xC3D2E1F0;
+
+  /* Perform encryption using xsha1 */
+  padlock_xsha1(pPlain, (char*)&sha.output, nPlainLen);
+  /* Copy out result and transform from little-endian to big-endian */
+  bswap_shabuffer(&sha.output[0], pHash, 20/4);
+}
+
+void HashSHA256padlock(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
+{
+  struct sha_t sha;
+
+  /* Initialize output buffer with SHA-256 hash constants */
+  ((int*)&sha.output)[0] = 0x6A09E667;
+  ((int*)&sha.output)[1] = 0xBB67AE85;
+  ((int*)&sha.output)[2] = 0x3C6EF372;
+  ((int*)&sha.output)[3] = 0xA54FF53A;
+  ((int*)&sha.output)[4] = 0x510E527F;
+  ((int*)&sha.output)[5] = 0x9B05688C;
+  ((int*)&sha.output)[6] = 0x1F83D9AB;
+  ((int*)&sha.output)[7] = 0x5BE0CD19;
+
+  /* Perform encryption using xsha256 */
+  padlock_xsha256(pPlain, (char*)&sha.output, nPlainLen);
+  /* Copy out result and transform from little-endian to big-endian */
+  bswap_shabuffer(&sha.output[0], pHash, 32/4);
+}
diff -uw rainbowcrack-1.2-src/src/HashAlgorithm.h rainbowcrack-1.2-src/src-padlock/HashAlgorithm.h
--- rainbowcrack-1.2-src/src/HashAlgorithm.h	2003-11-23 00:33:18.000000000 +0100
+++ rainbowcrack-1.2-src/src-padlock/HashAlgorithm.h	2007-02-04 19:48:26.000000000 +0100
@@ -9,6 +9,8 @@

 void HashLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash);
 void HashMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash);
+void HashSHA1padlock(unsigned char* pPlain, int nPlainLen, unsigned char* pHash);
+void HashSHA256padlock(unsigned char* pPlain, int nPlainLen, unsigned char* pHash);
 void HashSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash);

 #endif
diff -uw rainbowcrack-1.2-src/src/HashRoutine.cpp rainbowcrack-1.2-src/src-padlock/HashRoutine.cpp
--- rainbowcrack-1.2-src/src/HashRoutine.cpp	2003-11-23 00:33:16.000000000 +0100
+++ rainbowcrack-1.2-src/src-padlock/HashRoutine.cpp	2007-02-10 18:30:18.000000000 +0100
@@ -19,6 +19,8 @@

 	AddHashRoutine("lm",   HashLM,   8);
 	AddHashRoutine("md5",  HashMD5,  16);
+	AddHashRoutine("sha1padlock", HashSHA1padlock, 20);
+	AddHashRoutine("sha256padlock", HashSHA256padlock, 32);
 	AddHashRoutine("sha1", HashSHA1, 20);
 }

