diff --git a/applications/test/sha1/Make/files b/applications/test/sha1/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..2da85a30dd748d9320273e20d5e8d596c1296d71
--- /dev/null
+++ b/applications/test/sha1/Make/files
@@ -0,0 +1,3 @@
+testSHA1.C
+
+EXE = $(FOAM_USER_APPBIN)/testSHA1
diff --git a/applications/test/sha1/Make/options b/applications/test/sha1/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/applications/test/sha1/testSHA1.C b/applications/test/sha1/testSHA1.C
new file mode 100644
index 0000000000000000000000000000000000000000..4022237574fc237e51ec6063fa1577c48d8dc583
--- /dev/null
+++ b/applications/test/sha1/testSHA1.C
@@ -0,0 +1,85 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Application
+    testSHA1
+
+Description
+
+
+\*---------------------------------------------------------------------------*/
+
+#include "SHA1.H"
+#include "IOstreams.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+int main(int argc, char * argv[])
+{
+    SHA1 sha;
+    SHA1::Digest shaDig;
+
+    std::string str("The quick brown fox jumps over the lazy dog");
+    Info<< shaDig << nl;
+    Info<< SHA1("The quick brown fox jumps over the lazy dog") << nl;
+
+    sha.append("The quick brown fox jumps over the lazy dog");
+    Info<< sha << nl;
+
+    sha.clear();
+    sha.append("The quick brown fox jumps over the lazy dog");
+    shaDig = sha;
+
+    sha.append("\n");
+    Info<< sha << nl;
+    Info<< shaDig << nl;
+
+    if (sha == shaDig)
+    {
+        Info<<"SHA1 digests are identical\n";
+    }
+    else
+    {
+        Info<<"SHA1 digests are different\n";
+    }
+    Info<<"lhs:" << sha << " rhs:" << shaDig << endl;
+    
+    // start over:
+    sha.clear();
+    sha.append(str);
+
+    SHA1::Digest shaDig_A = sha;
+
+    SHA1 sha_A = sha;
+
+    sha.append("\n");
+
+    Info<< "digest1: " << sha_A << nl;
+    Info<< "digest2: " << sha << nl;
+
+    
+    return 0;
+}
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 2c4bfce8d7e03e04ec054014785255989ee50d7f..92c81085ab93aad0624f2bd3ba873d54dcd9dd9d 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -45,6 +45,10 @@ $(strings)/fileName/fileNameIO.C
 $(strings)/keyType/keyTypeIO.C
 $(strings)/wordRe/wordReIO.C
 
+sha1 = primitives/hashes/SHA1
+$(sha1)/SHA1.C
+$(sha1)/SHA1Digest.C
+
 primitives/random/Random.C
 
 containers/HashTables/HashTable/HashTableName.C
diff --git a/src/OpenFOAM/primitives/Hash/Hash.H b/src/OpenFOAM/primitives/hashes/Hash/Hash.H
similarity index 100%
rename from src/OpenFOAM/primitives/Hash/Hash.H
rename to src/OpenFOAM/primitives/hashes/Hash/Hash.H
diff --git a/src/OpenFOAM/primitives/hashes/SHA1/SHA1.C b/src/OpenFOAM/primitives/hashes/SHA1/SHA1.C
new file mode 100644
index 0000000000000000000000000000000000000000..56373824f65536e1526c721852d809a6e2eba189
--- /dev/null
+++ b/src/OpenFOAM/primitives/hashes/SHA1/SHA1.C
@@ -0,0 +1,455 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Description
+    Functions to compute SHA1 message digest of files or memory blocks
+    according to the NIST specification FIPS-180-1.
+
+    Adapted from the gnulib implementation written by Scott G. Miller with
+    credits to Robert Klep <robert@ilse.nl> -- Expansion function fix
+
+    Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2008 Free Software
+    Foundation, Inc.
+
+\*---------------------------------------------------------------------------*/
+
+#include "SHA1.H"
+#include "IOstreams.H"
+
+#include <cstring>
+
+#if defined (__GLIBC__)
+#  include <endian.h>
+#endif
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+//! @cond fileScope
+// The bytes used to pad buffer to the next 64-byte boundary.
+// (RFC 1321, 3.1: Step 1)
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
+//! @endcond fileScope
+
+
+// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
+
+inline uint32_t Foam::SHA1::swapBytes(uint32_t n)
+{
+#ifdef __BYTE_ORDER
+# if (__BYTE_ORDER == __BIG_ENDIAN)
+    return n;
+# else
+    return (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24));
+# endif
+
+#else
+
+    const short x = 0x0100;
+
+    // yields 0x01 for big endian
+    if (*(reinterpret_cast<const char *>(&x)))
+    {
+        return n;
+    }
+    else
+    {
+        return (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24));
+    }
+#endif
+}
+
+
+inline void
+Foam::SHA1::set_uint32(unsigned char *cp, uint32_t v)
+{
+    memcpy(cp, &v, sizeof(uint32_t));
+}
+
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+
+void Foam::SHA1::processBytes(const void *data, size_t len)
+{
+    // already finalized, thus need to restart from nothing
+    if (finalized_)
+    {
+        clear();
+    }
+
+    // complete filling of internal buffer
+    if (bufLen_)
+    {
+        size_t remaining = bufLen_;
+        size_t add =
+        (
+            sizeof(buffer_) - remaining > len
+          ? len
+          : sizeof(buffer_) - remaining
+        );
+
+        unsigned char* bufp = reinterpret_cast<unsigned char*>(buffer_);
+
+        memcpy(&bufp[remaining], data, add);
+        bufLen_ += add;
+
+        if (bufLen_ > 64)
+        {
+            processBlock(buffer_, bufLen_ & ~63);
+
+            bufLen_ &= 63;
+            // The regions in the following copy operation do not (cannot) overlap
+            memcpy(buffer_, &bufp[(remaining + add) & ~63], bufLen_);
+        }
+
+        data = reinterpret_cast<const unsigned char*>(data) + add;
+        len -= add;
+    }
+
+    // Process available complete blocks
+    if (len >= 64)
+    {
+#if !_STRING_ARCH_unaligned
+# define alignof(type) offsetof (struct { char c; type x; }, x)
+# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0)
+        if (UNALIGNED_P (data))
+        {
+            while (len > 64)
+            {
+                processBlock(memcpy (buffer_, data, 64), 64);
+                data = reinterpret_cast<const unsigned char*>(data) + 64;
+                len -= 64;
+            }
+        }
+        else
+#endif
+        {
+            processBlock(data, len & ~63);
+            data = reinterpret_cast<const unsigned char*>(data) + (len & ~63);
+            len &= 63;
+        }
+    }
+
+    // Move remaining bytes in internal buffer.
+    if (len > 0)
+    {
+        unsigned char* bufp = reinterpret_cast<unsigned char*>(buffer_);
+        size_t remaining = bufLen_;
+
+        memcpy (&bufp[remaining], data, len);
+        remaining += len;
+        if (remaining >= 64)
+        {
+            processBlock(buffer_, 64);
+            remaining -= 64;
+            memcpy (buffer_, &buffer_[16], remaining);
+        }
+        bufLen_ = remaining;
+    }
+}
+
+
+// SHA1 round constants
+#define K1 0x5a827999
+#define K2 0x6ed9eba1
+#define K3 0x8f1bbcdc
+#define K4 0xca62c1d6
+
+// Round functions.  Note that F2 is the same as F4.
+#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
+#define F2(B,C,D) (B ^ C ^ D)
+#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
+#define F4(B,C,D) (B ^ C ^ D)
+
+// Process LEN bytes of BUFFER, it is assumed that LEN % 64 == 0.
+// Most of this code comes from GnuPG's cipher/sha1.c
+
+void
+Foam::SHA1::processBlock(const void *data, size_t len)
+{
+    const uint32_t *words = reinterpret_cast<const uint32_t*>(data);
+    size_t nwords = len / sizeof(uint32_t);
+    const uint32_t *endp = words + nwords;
+
+    // calculate with sixteen words of 32-bits
+    uint32_t x[16];
+    uint32_t a = hashsumA_;
+    uint32_t b = hashsumB_;
+    uint32_t c = hashsumC_;
+    uint32_t d = hashsumD_;
+    uint32_t e = hashsumE_;
+
+    // First increment the byte count.
+    // RFC 1321 specifies the possible length of the file up to 2^64 bits.
+    // Here we only compute the number of bytes.  Do a double word increment.
+    bufTotal_[0] += len;
+    if (bufTotal_[0] < len)
+    {
+        ++bufTotal_[1];
+    }
+
+    // rotate left uint32_t by n bits
+#define rol_uint32(x, nbits)  (((x) << (nbits)) | ((x) >> (32 - (nbits))))
+
+#define M(I) ( tm = x[I & 0x0F] ^ x[(I-14) & 0x0F]                            \
+               ^ x[(I-8) & 0x0F] ^ x[(I-3) & 0x0F]                            \
+               , (x[I & 0x0F] = rol_uint32(tm, 1)) )
+
+
+#define R(A,B,C,D,E,F,K,M)                                                    \
+    do                                                                        \
+    {                                                                         \
+        E += rol_uint32(A, 5) + F(B, C, D) + K + M;                           \
+        B = rol_uint32(B, 30);                                                \
+    } while(0)
+
+    while (words < endp)
+    {
+        uint32_t tm;
+        for (int t = 0; t < 16; t++)
+        {
+            x[t] = swapBytes (*words);
+            words++;
+        }
+
+        R( a, b, c, d, e, F1, K1, x[ 0] );
+        R( e, a, b, c, d, F1, K1, x[ 1] );
+        R( d, e, a, b, c, F1, K1, x[ 2] );
+        R( c, d, e, a, b, F1, K1, x[ 3] );
+        R( b, c, d, e, a, F1, K1, x[ 4] );
+        R( a, b, c, d, e, F1, K1, x[ 5] );
+        R( e, a, b, c, d, F1, K1, x[ 6] );
+        R( d, e, a, b, c, F1, K1, x[ 7] );
+        R( c, d, e, a, b, F1, K1, x[ 8] );
+        R( b, c, d, e, a, F1, K1, x[ 9] );
+        R( a, b, c, d, e, F1, K1, x[10] );
+        R( e, a, b, c, d, F1, K1, x[11] );
+        R( d, e, a, b, c, F1, K1, x[12] );
+        R( c, d, e, a, b, F1, K1, x[13] );
+        R( b, c, d, e, a, F1, K1, x[14] );
+        R( a, b, c, d, e, F1, K1, x[15] );
+        R( e, a, b, c, d, F1, K1, M(16) );
+        R( d, e, a, b, c, F1, K1, M(17) );
+        R( c, d, e, a, b, F1, K1, M(18) );
+        R( b, c, d, e, a, F1, K1, M(19) );
+        R( a, b, c, d, e, F2, K2, M(20) );
+        R( e, a, b, c, d, F2, K2, M(21) );
+        R( d, e, a, b, c, F2, K2, M(22) );
+        R( c, d, e, a, b, F2, K2, M(23) );
+        R( b, c, d, e, a, F2, K2, M(24) );
+        R( a, b, c, d, e, F2, K2, M(25) );
+        R( e, a, b, c, d, F2, K2, M(26) );
+        R( d, e, a, b, c, F2, K2, M(27) );
+        R( c, d, e, a, b, F2, K2, M(28) );
+        R( b, c, d, e, a, F2, K2, M(29) );
+        R( a, b, c, d, e, F2, K2, M(30) );
+        R( e, a, b, c, d, F2, K2, M(31) );
+        R( d, e, a, b, c, F2, K2, M(32) );
+        R( c, d, e, a, b, F2, K2, M(33) );
+        R( b, c, d, e, a, F2, K2, M(34) );
+        R( a, b, c, d, e, F2, K2, M(35) );
+        R( e, a, b, c, d, F2, K2, M(36) );
+        R( d, e, a, b, c, F2, K2, M(37) );
+        R( c, d, e, a, b, F2, K2, M(38) );
+        R( b, c, d, e, a, F2, K2, M(39) );
+        R( a, b, c, d, e, F3, K3, M(40) );
+        R( e, a, b, c, d, F3, K3, M(41) );
+        R( d, e, a, b, c, F3, K3, M(42) );
+        R( c, d, e, a, b, F3, K3, M(43) );
+        R( b, c, d, e, a, F3, K3, M(44) );
+        R( a, b, c, d, e, F3, K3, M(45) );
+        R( e, a, b, c, d, F3, K3, M(46) );
+        R( d, e, a, b, c, F3, K3, M(47) );
+        R( c, d, e, a, b, F3, K3, M(48) );
+        R( b, c, d, e, a, F3, K3, M(49) );
+        R( a, b, c, d, e, F3, K3, M(50) );
+        R( e, a, b, c, d, F3, K3, M(51) );
+        R( d, e, a, b, c, F3, K3, M(52) );
+        R( c, d, e, a, b, F3, K3, M(53) );
+        R( b, c, d, e, a, F3, K3, M(54) );
+        R( a, b, c, d, e, F3, K3, M(55) );
+        R( e, a, b, c, d, F3, K3, M(56) );
+        R( d, e, a, b, c, F3, K3, M(57) );
+        R( c, d, e, a, b, F3, K3, M(58) );
+        R( b, c, d, e, a, F3, K3, M(59) );
+        R( a, b, c, d, e, F4, K4, M(60) );
+        R( e, a, b, c, d, F4, K4, M(61) );
+        R( d, e, a, b, c, F4, K4, M(62) );
+        R( c, d, e, a, b, F4, K4, M(63) );
+        R( b, c, d, e, a, F4, K4, M(64) );
+        R( a, b, c, d, e, F4, K4, M(65) );
+        R( e, a, b, c, d, F4, K4, M(66) );
+        R( d, e, a, b, c, F4, K4, M(67) );
+        R( c, d, e, a, b, F4, K4, M(68) );
+        R( b, c, d, e, a, F4, K4, M(69) );
+        R( a, b, c, d, e, F4, K4, M(70) );
+        R( e, a, b, c, d, F4, K4, M(71) );
+        R( d, e, a, b, c, F4, K4, M(72) );
+        R( c, d, e, a, b, F4, K4, M(73) );
+        R( b, c, d, e, a, F4, K4, M(74) );
+        R( a, b, c, d, e, F4, K4, M(75) );
+        R( e, a, b, c, d, F4, K4, M(76) );
+        R( d, e, a, b, c, F4, K4, M(77) );
+        R( c, d, e, a, b, F4, K4, M(78) );
+        R( b, c, d, e, a, F4, K4, M(79) );
+
+        a = hashsumA_ += a;
+        b = hashsumB_ += b;
+        c = hashsumC_ += c;
+        d = hashsumD_ += d;
+        e = hashsumE_ += e;
+    }
+}
+
+
+void Foam::SHA1::calcDigest(SHA1::Digest& dig) const
+{
+    if (bufTotal_[0] || bufTotal_[1])
+    {
+        unsigned char *r = dig.v_;
+
+        set_uint32 (r + 0 * sizeof(uint32_t), swapBytes(hashsumA_));
+        set_uint32 (r + 1 * sizeof(uint32_t), swapBytes(hashsumB_));
+        set_uint32 (r + 2 * sizeof(uint32_t), swapBytes(hashsumC_));
+        set_uint32 (r + 3 * sizeof(uint32_t), swapBytes(hashsumD_));
+        set_uint32 (r + 4 * sizeof(uint32_t), swapBytes(hashsumE_));
+    }
+    else
+    {
+        // no data!
+        dig.clear();
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+
+void Foam::SHA1::clear()
+{
+    hashsumA_ = 0x67452301;
+    hashsumB_ = 0xefcdab89;
+    hashsumC_ = 0x98badcfe;
+    hashsumD_ = 0x10325476;
+    hashsumE_ = 0xc3d2e1f0;
+
+    bufTotal_[0] = bufTotal_[1] = 0;
+    bufLen_ = 0;
+
+    finalized_ = false;
+}
+
+
+bool Foam::SHA1::finalize()
+{
+    if (!finalized_)
+    {
+        finalized_ = true;
+
+        // account for unprocessed bytes
+        uint32_t bytes = bufLen_;
+        size_t size = (bytes < 56 ? 64 : 128) / sizeof(uint32_t);
+
+        // count remaining bytes.
+        bufTotal_[0] += bytes;
+        if (bufTotal_[0] < bytes)
+        {
+            ++bufTotal_[1];
+        }
+
+        // finalized, but no data!
+        if (!bufTotal_[0] && !bufTotal_[1])
+        {
+            return false;
+        }
+
+        // place the 64-bit file length in *bits* at the end of the buffer.
+        buffer_[size-2] = swapBytes((bufTotal_[1] << 3) | (bufTotal_[0] >> 29));
+        buffer_[size-1] = swapBytes(bufTotal_[0] << 3);
+
+        unsigned char* bufp = reinterpret_cast<unsigned char *>(buffer_);
+
+        memcpy(&bufp[bytes], fillbuf, (size-2) * sizeof(uint32_t) - bytes);
+
+        // Process remaining bytes
+        processBlock(buffer_, size * sizeof(uint32_t));
+    }
+
+    return true;
+}
+
+
+Foam::SHA1::Digest Foam::SHA1::digest() const
+{
+    SHA1::Digest dig;
+
+    if (finalized_)
+    {
+        calcDigest(dig);
+    }
+    else
+    {
+        // avoid disturbing our data - use a copy
+        SHA1 sha(*this);
+        if (sha.finalize())
+        {
+            sha.calcDigest(dig);
+        }
+    }
+
+    return dig;
+}
+
+
+// * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * * //
+
+// void Foam::SHA1::operator=(const SHA1& rhs)
+// {
+//     // Check for assignment to self
+//     if (this == &rhs)
+//     {
+//         FatalErrorIn("Foam::SHA1::operator=(const Foam::SHA1&)")
+//             << "Attempted assignment to self"
+//             << abort(FatalError);
+//     }
+// }
+
+// * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/hashes/SHA1/SHA1.H b/src/OpenFOAM/primitives/hashes/SHA1/SHA1.H
new file mode 100644
index 0000000000000000000000000000000000000000..55ed2eed70e349e47cd186c819bb8a556e607103
--- /dev/null
+++ b/src/OpenFOAM/primitives/hashes/SHA1/SHA1.H
@@ -0,0 +1,217 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::SHA1
+
+Description
+    Functions to compute SHA1 message digest according to the NIST
+    specification FIPS-180-1.
+
+    Adapted from the gnulib implementation.
+
+SourceFiles
+    SHA1I.H
+    SHA1.C
+    SHA1Digest.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef SHA1_H
+#define SHA1_H
+
+#include <string>
+#include <cstddef>
+#include <stdint.h>    // C++0x uses <cstdint>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class Ostream;
+
+// Forward declaration of friend functions and operators
+class SHA1;
+Ostream& operator<<(Ostream&, const SHA1&);
+
+
+/*---------------------------------------------------------------------------*\
+                            Class SHA1 Declaration
+\*---------------------------------------------------------------------------*/
+
+class SHA1
+{
+public:
+
+    // Public classes
+
+        //- The SHA1 digest itself
+        class Digest
+        {
+        public:
+            friend class SHA1;
+
+            //- The length of the digest contents
+            static const unsigned length = 20;
+
+            //- Construct null
+            Digest();
+
+            //- Reset the digest to zero
+            void clear();
+
+            //- Equality operator
+            bool operator==(const Digest&) const;
+
+            //- Inequality operator
+            bool operator!=(const Digest&) const;
+
+            friend Ostream& operator<<(Ostream&, const SHA1::Digest&);
+
+        private:
+
+            //- The digest contents
+            unsigned char v_[length];
+        };
+
+
+private:
+
+    // Private data
+
+        //- Track if the hashsum has been finalized (added count, etc)
+        bool finalized_;
+
+        //- The hash sums
+        uint32_t hashsumA_;
+        uint32_t hashsumB_;
+        uint32_t hashsumC_;
+        uint32_t hashsumD_;
+        uint32_t hashsumE_;
+
+        //- The total number processed, saved as 64-bit
+        uint32_t bufTotal_[2];
+
+        //- The number of elements pending in the buffer
+        uint32_t bufLen_;
+
+        //- The input processing buffer
+        uint32_t buffer_[32];
+
+    // Private Member Functions
+
+        //- Swap bytes from internal to network (big-endian) order
+        static inline uint32_t swapBytes(uint32_t);
+
+        //- Copy the 4-byte value into the memory location pointed to by *dst.
+        //  If the architecture allows unaligned access this is equivalent to
+        //  *(uint32_t *) cp = val
+        static inline void set_uint32(unsigned char *cp, uint32_t);
+
+        //- Process data block-wise, LEN must be a multiple of 64!
+        void processBlock(const void *data, size_t len);
+
+        //- Process for the next LEN bytes, LEN need not be a multiple of 64.
+        void processBytes(const void *data, size_t len);
+
+        //- Calculate current digest from appended data.
+        void calcDigest(SHA1::Digest&) const;
+
+public:
+
+    // Constructors
+
+        //- Construct null
+	inline SHA1();
+
+        //- Construct and append initial std::string
+        explicit inline SHA1(const std::string&);
+
+        //- Construct and append initial string
+        explicit inline SHA1(const char*);
+
+    // Member Functions
+
+	//- Reset the hashed data before appending more
+	void clear();
+
+	//- Append data for processing
+	inline SHA1& append(const char* data, size_t len);
+
+	//- Append string for processing
+        inline SHA1& append(const std::string&);
+
+	//- Append string for processing
+	inline SHA1& append(const char* str);
+
+	//- Finalized the calculations (normally not needed directly).
+        //  Returns false if no bytes were passed for processing
+	bool finalize();
+
+        //- Calculate current digest from appended data.
+	Digest digest() const;
+
+
+    // Member Operators
+
+        //- Equality operator
+        inline bool operator==(const SHA1::Digest&) const;
+
+        //- Inequality operator
+        inline bool operator!=(const SHA1::Digest&) const;
+
+        //- Equality operator
+        inline bool operator==(const SHA1&) const;
+
+        //- Inequality operator
+        inline bool operator!=(const SHA1&) const;
+
+        //- Convert to a digest, calculate current digest from appended data.
+        inline operator SHA1::Digest() const;
+
+
+    // Friend Functions
+
+    // Friend Operators
+
+        inline friend Ostream& operator<<(Ostream&, const SHA1&);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "SHA1I.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.C b/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.C
new file mode 100644
index 0000000000000000000000000000000000000000..d87035b0049bb3ebd5b1db9ae060303053c048e7
--- /dev/null
+++ b/src/OpenFOAM/primitives/hashes/SHA1/SHA1Digest.C
@@ -0,0 +1,105 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "SHA1.H"
+#include "IOstreams.H"
+
+#include <cstring>
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::SHA1::Digest::Digest()
+{
+    clear();
+}
+
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::SHA1::Digest::clear()
+{
+    memset(v_, '\0', length);
+}
+
+
+// * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * * //
+
+bool Foam::SHA1::Digest::operator==(const SHA1::Digest& rhs) const
+{
+    for (size_t i = 0; i < length; ++i)
+    {
+        if (v_[i] != rhs.v_[i])
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+
+bool Foam::SHA1::Digest::operator!=(const SHA1::Digest& rhs) const
+{
+    return !operator==(rhs);
+}
+
+
+// * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const SHA1::Digest& dig)
+{
+    const char hexChars[] = "0123456789abcdef";
+
+    const unsigned char *v = dig.v_;
+    for (size_t i=0; i < dig.length; i++)
+    {
+        os.write(hexChars[((v[i] >> 4) & 0xF)]);
+        os.write(hexChars[(v[i] & 0xF)]);
+    }
+
+    os.check("Ostream& operator<<(Ostream&, const SHA1::Digest&)");
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/hashes/SHA1/SHA1I.H b/src/OpenFOAM/primitives/hashes/SHA1/SHA1I.H
new file mode 100644
index 0000000000000000000000000000000000000000..d0fce820b49a38a733c7736477f942e557a90195
--- /dev/null
+++ b/src/OpenFOAM/primitives/hashes/SHA1/SHA1I.H
@@ -0,0 +1,134 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "SHA1.H"
+#include <cstring>
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+inline Foam::SHA1::SHA1()
+{
+    clear();
+}
+
+
+inline Foam::SHA1::SHA1(const std::string& str)
+{
+    clear();
+    append(str);
+}
+
+
+inline Foam::SHA1::SHA1(const char* str)
+{
+    clear();
+    append(str);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+inline Foam::SHA1& Foam::SHA1::append(const char* data, size_t len)
+{
+    processBytes(data, len);
+    return *this;
+}
+
+
+inline Foam::SHA1& Foam::SHA1::append(const std::string& str)
+{
+    processBytes(str.data(), str.size());
+    return *this;
+}
+
+
+inline Foam::SHA1& Foam::SHA1::append(const char* str)
+{
+    if (str)
+    {
+        processBytes(str, strlen(str));
+    }
+    return *this;
+}
+
+
+// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
+
+inline bool Foam::SHA1::operator==(const SHA1::Digest& rhs) const
+{
+    return this->digest() == rhs;
+}
+
+
+inline bool Foam::SHA1::operator!=(const SHA1::Digest& rhs) const
+{
+    return this->digest() != rhs;
+}
+
+
+inline bool Foam::SHA1::operator==(const SHA1& rhs) const
+{
+    return digest() == rhs.digest();
+}
+
+
+inline bool Foam::SHA1::operator!=(const SHA1& rhs) const
+{
+    return digest() != rhs.digest();
+}
+
+
+inline Foam::SHA1::operator
+Foam::SHA1::Digest () const
+{
+    return digest();
+}
+
+
+// * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //
+
+inline Foam::Ostream& Foam::operator<<(Ostream& os, const SHA1& sha)
+{
+    return os << sha.digest();
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+// ************************************************************************* //