[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: SHA1Digest and SHA256Digest
From: |
Elizabeth Barham |
Subject: |
Re: SHA1Digest and SHA256Digest |
Date: |
20 Nov 2002 14:22:35 -0600 |
Federico Montesino Pouzols <address@hidden> writes:
> Good. I think these classes fit perfectly with cc++.
Great!
> Personally, I think that adding the two exception cases is ok.
Done.
Here is the diff from anonymous CVS. Following that will be the two
files:
src/sha.cpp
demo/shadigest.cpp
Note that I did make some adjustments to some of the files in order to
build, most notably socket.h.
Thank you, Elizabeth
# ###################################################################### #
# diff file
? include
? lib
? demo/shadigest
? demo/shadigest.cpp
? src/sha.cpp
? tests/Makefile
? tests/Makefile.in
Index: demo/Makefile.am
===================================================================
RCS file: /cvsroot/commoncpp/commoncpp/demo/Makefile.am,v
retrieving revision 1.20
diff -u -p -3 -r1.20 Makefile.am
--- demo/Makefile.am 3 Feb 2002 14:04:37 -0000 1.20
+++ demo/Makefile.am 20 Nov 2002 20:15:25 -0000
@@ -17,7 +17,7 @@ LDADD = $(top_srcdir)/src/libccgnu.la $(
Z_LIBS = -lz
noinst_PROGRAMS = tcp tcpthread tcpservice serial cmdlineopt \
- urlfetch xmlfetch portsample slogTest
+ urlfetch xmlfetch portsample slogTest shadigest
noinst_HEADERS = serialecho.h SampleSocketPort.h
urlfetch_SOURCES = urlfetch.cpp
@@ -41,3 +41,7 @@ serial_LDADD = $(top_srcdir)/src/libccex
cmdlineopt_SOURCES = cmdlineopt.cpp
cmdlineopt_LDADD = $(top_srcdir)/src/libccext.la $(XML_LIBS) $(Z_LIBS) $(LDADD)
+
+shadigest_SOURCES = shadigest.cpp
+shadigest_LDADD = $(top_srcdir)/src/libccext.la $(XML_LIBS) $(Z_LIBS) $(LDADD)
+
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/commoncpp/commoncpp/src/Makefile.am,v
retrieving revision 1.8
diff -u -p -3 -r1.8 Makefile.am
--- src/Makefile.am 4 Dec 2001 19:03:24 -0000 1.8
+++ src/Makefile.am 20 Nov 2002 20:15:25 -0000
@@ -31,7 +31,7 @@ libccgnu_la_SOURCES = thread.cpp mutex.c
libccext_la_SOURCES = buffer.cpp fifo.cpp pipe.cpp numbers.cpp \
cmdoptns.cpp url.cpp xml.cpp persist.cpp engine.cpp digest.cpp \
- date.cpp groups.cpp md5.cpp
+ date.cpp groups.cpp md5.cpp sha.cpp
# private.h are internal headers
# export.h are used by other library
Index: src/digest.h
===================================================================
RCS file: /cvsroot/commoncpp/commoncpp/src/digest.h,v
retrieving revision 1.10
diff -u -p -3 -r1.10 digest.h
--- src/digest.h 2 Jun 2002 08:02:31 -0000 1.10
+++ src/digest.h 20 Nov 2002 20:15:26 -0000
@@ -62,6 +62,8 @@ class CCXX_CLASS_EXPORT Digest;
class CCXX_CLASS_EXPORT ChecksumDigest;
class CCXX_CLASS_EXPORT CRC16Digest;
class CCXX_CLASS_EXPORT MD5Digest;
+class CCXX_CLASS_EXPORT SHA1Digest;
+class CCXX_CLASS_EXPORT SHA256Digest;
#endif
/**
@@ -245,6 +247,214 @@ public:
void putDigest(const unsigned char *buffer, unsigned len);
};
+
+/**
+ * DigestException
+ *
+ * Exception classes that pertain to errors when making or otherwise
+ * working with digests.
+ *
+ * @author Elizabeth Barham <address@hidden>
+ * @short Exceptions involving digests.
+ */
+
+class DigestException : public Exception {
+public:
+ DigestException(const std::string & what_arg) throw();
+ virtual ~DigestException() throw();
+};
+
+
+/**
+ * SHATumbler
+ *
+ * Class used by the SHA Digest Classes.
+ *
+ * Represents a "tumbler" group, similar to a row in a combination
+ * lock. Each part is made to roll-over, its size dependent upon
+ * int_type.
+ *
+ * @author Elizabeth Barham <address@hidden>
+ * @short SHA Helper Class */
+
+template <class int_type>
+class SHATumbler {
+
+public:
+ SHATumbler(int);
+
+ SHATumbler(const SHATumbler&);
+ SHATumbler& operator=(const SHATumbler&);
+
+ int_type& operator[](int);
+
+ ~SHATumbler();
+
+ SHATumbler operator+(const SHATumbler& addend) const;
+ SHATumbler& operator+=(const SHATumbler& addend);
+ std::ostream & toString(std::ostream & os);
+
+ friend std::ostream &operator<<(std::ostream &os, SHATumbler<int_type>& ia)
+ {return ia.toString(os);};
+
+ unsigned getSize();
+ unsigned placeInBuffer(unsigned char *);
+
+private:
+ int_type * h;
+ int size;
+};
+
+/**
+ * SHAConstant
+ *
+ * Note that this constant is set in sha.cpp and that each constant in
+ * the array is 64 bits wide. The constants themselves pertain to both
+ * SHA-256 and SHA-512, the only difference is that SHA-256 expects
+ * her constants to be 32 bits wide and only 64 are needed.
+ *
+ * @auther Elizabeth Barham <address@hidden>
+ * @short Contains SHA constants
+ */
+
+class SHAConstant {
+protected:
+ const static uint64_t K[];
+};
+
+/**
+ * SHADigest
+ *
+ * Generic Class that is the base class of the various SHA*Digest
+ * classes.
+ *
+ * uint_type == The "Unsigned Integer Type" which is large enough to
+ * hold the total length of a given message in bits. For SHA1 and
+ * SHA256, this is 64 bits, so we use "uint64_t";
+ *
+ * "blockSizeInBytes" == various SHA digests use different message
+ * size blocks - the basic units in which to split a message up in.
+ * For example, SHA1 and SHA256 use 512 bit blocks, and so in
+ * bytes this is 64.
+ *
+ * @author Elizabeth Barham <address@hidden>
+ * @short Base class for the SHA*Digests
+ */
+
+template <class uint_type, unsigned blockSizeInBytes>
+class SHADigest : public Digest {
+private:
+ uint_type totalLengthInBits;
+
+ void copyTempBlock(const SHADigest &);
+
+protected:
+ unsigned char tempBlock[blockSizeInBytes];
+ void initDigest(void);
+
+ virtual void processBlock(const unsigned char * buffer) = 0;
+ void padBuffer(unsigned char * buffer);
+
+ bool completed;
+
+ SHADigest();
+ SHADigest(const SHADigest & other);
+ SHADigest & operator=(const SHADigest & other);
+
+public:
+ unsigned getSize(void) = 0;
+ void putDigest(const unsigned char * buffer, unsigned length)
throw(DigestException);
+ std::ostream & strDigest(std::ostream &os) = 0;
+
+};
+
+#define S(n,X) ( ( ( X ) << ( n ) ) | ( ( X ) >> ( 32 - n ) ) )
+
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+/* RR == "right rotation by n bits" (Sn) */
+/* RS == "right shift by n byts" (Rn) */
+/* (see p. 2, "Descriptions of SHA-256, SHA-384, SHA-512" */
+/* <http://csrc.nist.gov/encryption/shs/sha256-384-512.pdf>) */
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+#define RR(n,X) ( ( ( X ) >> n ) | ( ( X ) << ( 32 - n ) ) )
+#define RS(n,X) ( ( ( X ) >> n ) )
+
+/**
+ * SHA64DigestHelper
+ *
+ * Simply a base class for the SHA*Digest classes that share
+ * functionality after their "unsigned int" type and block size are
+ * known (uint64_t and 64)
+ *
+ * @author Elizabeth Barham <address@hidden>
+ * @short Base class for the 64-bit wide SHA*Digests.
+ */
+
+class SHA64DigestHelper: public SHADigest<uint64_t, 64> {
+protected:
+ SHATumbler<uint32_t> h;
+ SHATumbler<uint32_t> a;
+
+ SHA64DigestHelper(unsigned);
+ SHATumbler<uint32_t> getDigest();
+
+public:
+ unsigned getDigest(unsigned char * buffer) { return
getDigest().placeInBuffer(buffer); }
+ std::ostream & strDigest(std::ostream & os);
+
+ SHA64DigestHelper(const SHA64DigestHelper & other);
+ SHA64DigestHelper & operator=(const SHA64DigestHelper & other);
+};
+
+/**
+ * SHA1Digest
+ *
+ * SHA1Digest proper.
+ *
+ * @author Elizabeth Barham <address@hidden>
+ * @short SHA-1 Digest Implementation
+ */
+
+class SHA1Digest : public SHA64DigestHelper {
+protected:
+ void processBlock(const unsigned char * buffer);
+
+public:
+ SHA1Digest();
+ void initDigest();
+ unsigned getSize() { return 20; }
+ SHA1Digest(const SHA1Digest & other);
+};
+
+/**
+ * SHA256Digest
+ * @author Elizabeth Barham <address@hidden>
+ * @short SHA-256 Digest Implementation
+ */
+
+class SHA256Digest : public SHA64DigestHelper, public SHAConstant {
+protected:
+ void processBlock(const unsigned char * buffer);
+
+public:
+ SHA256Digest();
+ SHA256Digest(const SHA256Digest &);
+ void initDigest();
+ unsigned getSize() { return 32; }
+};
+
+/* In case anyone is wondering why SHA-512 and SHA-384 are not
+ * implemented, it is the better way to make them is to use an 128-bit
+ * unsigned integer. To my understanding, the gcc 3.* has either
+ * introduced uint128_t or shall introduce it. When it does, something
+ * similar to SHA64DigestHelper can easily be made, perhaps:
+ *
+ * "class SHA128DigestHelper : public SHADigest<uint128_t, 128>"
+ *
+ * -- Elizabeth Barham, November 20, 2002, Fort Worth, TX, USA
+ */
+
#ifdef CCXX_NAMESPACES
};
Index: src/socket.cpp
===================================================================
RCS file: /cvsroot/commoncpp/commoncpp/src/socket.cpp,v
retrieving revision 1.19
diff -u -p -3 -r1.19 socket.cpp
--- src/socket.cpp 2 Jun 2002 08:50:19 -0000 1.19
+++ src/socket.cpp 20 Nov 2002 20:15:26 -0000
@@ -73,7 +73,7 @@ using namespace std;
#endif
#ifdef WIN32
-static SOCKET dupSocket(SOCKET so,enum Socket::State state)
+static SOCKET dupSocket(SOCKET so, sockstate_t state)
{
if (state == Socket::STREAM)
return dup(so);
Index: src/socket.h
===================================================================
RCS file: /cvsroot/commoncpp/commoncpp/src/socket.h,v
retrieving revision 1.15
diff -u -p -3 -r1.15 socket.h
--- src/socket.h 2 Jun 2002 08:50:19 -0000 1.15
+++ src/socket.h 20 Nov 2002 20:15:27 -0000
@@ -569,7 +569,7 @@ private:
mutable const char *errstr;
void setSocket(void);
- friend SOCKET dupSocket(SOCKET s,Socket::State state);
+ friend SOCKET dupSocket(SOCKET s, sockstate_t state);
protected:
mutable struct
Index: src/xml.cpp
===================================================================
RCS file: /cvsroot/commoncpp/commoncpp/src/xml.cpp,v
retrieving revision 1.8
diff -u -p -3 -r1.8 xml.cpp
--- src/xml.cpp 29 May 2002 08:55:40 -0000 1.8
+++ src/xml.cpp 20 Nov 2002 20:15:28 -0000
@@ -51,9 +51,9 @@
#ifdef HAVE_LIBXML
-#include <parser.h>
-#include <parserInternals.h>
-#include <xmlIO.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlIO.h>
#include <cstdarg>
#ifdef CCXX_NAMESPACES
# ################################################################## #
# src/sha.cpp
/* -*- C++ -*- */
// Copyright (C) 1999-2002 Open Source Telecom Corporation.
//
// This program 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.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// As a special exception to the GNU General Public License, permission is
// granted for additional uses of the text contained in its release
// of Common C++.
//
// The exception is that, if you link the Common C++ library with other files
// to produce an executable, this does not by itself cause the
// resulting executable to be covered by the GNU General Public License.
// Your use of that executable is in no way restricted on account of
// linking the Common C++ library code into it.
//
// This exception does not however invalidate any other reasons why
// the executable file might be covered by the GNU General Public License.
//
// This exception applies only to the code released under the
// name Common C++. If you copy code from other releases into a copy of
// Common C++, as the General Public License permits, the exception does
// not apply to the code that you add in this way. To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own for Common C++, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice.
#include "config.h"
#include "export.h"
#include "strchar.h"
#include "exception.h"
#include "thread.h"
#include "digest.h"
#include <cstdio>
#include <iomanip>
#ifdef WIN32
#include <io.h>
#endif
#ifdef CCXX_NAMESPACES
namespace ost {
using namespace std;
#endif
/**
* DigestException
*/
DigestException::DigestException(const std::string & what_arg) throw() :
Exception(what_arg)
{ }
DigestException::~DigestException() throw()
{ }
/**
* SHAConstant::K
*/
/* note to use K32_ADJUST when attempting to access K with a 32 bit
* integer.
*/
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define K32_ADJUST 1
#else
#define K32_ADJUST 0
#endif
const uint64_t SHAConstant::K[] = {
0x428a2f98d728ae22LL,
0x7137449123ef65cdLL,
0xb5c0fbcfec4d3b2fLL,
0xe9b5dba58189dbbcLL,
0x3956c25bf348b538LL,
0x59f111f1b605d019LL,
0x923f82a4af194f9bLL,
0xab1c5ed5da6d8118LL,
0xd807aa98a3030242LL,
0x12835b0145706fbeLL,
0x243185be4ee4b28cLL,
0x550c7dc3d5ffb4e2LL,
0x72be5d74f27b896fLL,
0x80deb1fe3b1696b1LL,
0x9bdc06a725c71235LL,
0xc19bf174cf692694LL,
0xe49b69c19ef14ad2LL,
0xefbe4786384f25e3LL,
0x0fc19dc68b8cd5b5LL,
0x240ca1cc77ac9c65LL,
0x2de92c6f592b0275LL,
0x4a7484aa6ea6e483LL,
0x5cb0a9dcbd41fbd4LL,
0x76f988da831153b5LL,
0x983e5152ee66dfabLL,
0xa831c66d2db43210LL,
0xb00327c898fb213fLL,
0xbf597fc7beef0ee4LL,
0xc6e00bf33da88fc2LL,
0xd5a79147930aa725LL,
0x06ca6351e003826fLL,
0x142929670a0e6e70LL,
0x27b70a8546d22ffcLL,
0x2e1b21385c26c926LL,
0x4d2c6dfc5ac42aedLL,
0x53380d139d95b3dfLL,
0x650a73548baf63deLL,
0x766a0abb3c77b2a8LL,
0x81c2c92e47edaee6LL,
0x92722c851482353bLL,
0xa2bfe8a14cf10364LL,
0xa81a664bbc423001LL,
0xc24b8b70d0f89791LL,
0xc76c51a30654be30LL,
0xd192e819d6ef5218LL,
0xd69906245565a910LL,
0xf40e35855771202aLL,
0x106aa07032bbd1b8LL,
0x19a4c116b8d2d0c8LL,
0x1e376c085141ab53LL,
0x2748774cdf8eeb99LL,
0x34b0bcb5e19b48a8LL,
0x391c0cb3c5c95a63LL,
0x4ed8aa4ae3418acbLL,
0x5b9cca4f7763e373LL,
0x682e6ff3d6b2b8a3LL,
0x748f82ee5defb2fcLL,
0x78a5636f43172f60LL,
0x84c87814a1f0ab72LL,
0x8cc702081a6439ecLL,
0x90befffa23631e28LL,
0xa4506cebde82bde9LL,
0xbef9a3f7b2c67915LL,
0xc67178f2e372532bLL,
0xca273eceea26619cLL,
0xd186b8c721c0c207LL,
0xeada7dd6cde0eb1eLL,
0xf57d4f7fee6ed178LL,
0x06f067aa72176fbaLL,
0x0a637dc5a2c898a6LL,
0x113f9804bef90daeLL,
0x1b710b35131c471bLL,
0x28db77f523047d84LL,
0x32caab7b40c72493LL,
0x3c9ebe0a15c9bebcLL,
0x431d67c49c100d4cLL,
0x4cc5d4becb3e42b6LL,
0x597f299cfc657e2aLL,
0x5fcb6fab3ad6faecLL,
0x6c44198c4a475817LL
};
/* *********************************************************************
SHATumbler
********************************************************************* */
template <class int_type>
SHATumbler<int_type>::SHATumbler(int s): size(s) {
h = new int_type[size];
}
template <class int_type>
SHATumbler<int_type>::SHATumbler(const SHATumbler<int_type>& copy) {
size = copy.size;
h = new int_type[size];
memcpy((void*)h,(void*)copy.h,sizeof(int_type) * size);
}
template <class int_type>
SHATumbler<int_type> & SHATumbler<int_type>::operator=(const
SHATumbler<int_type> & assign) {
memcpy((void*)h,(void*)assign.h,sizeof(int_type) * size);
return *this;
}
template <class int_type>
int_type & SHATumbler<int_type>::operator[](int x) {
return h[x];
}
template <class int_type>
SHATumbler<int_type>::~SHATumbler() {
delete[] h;
}
template <class int_type>
SHATumbler<int_type> SHATumbler<int_type>::operator+(const
SHATumbler<int_type>& addend) const {
SHATumbler<int_type> rv = *this;
rv += addend;
return(rv);
}
template <class int_type>
SHATumbler<int_type>& SHATumbler<int_type>::operator+=(const
SHATumbler<int_type>& addend) {
for(int i = 0; i < size; i++) {
h[i] += addend.h[i];
}
return(*this);
}
template <class int_type>
std::ostream & SHATumbler<int_type>::toString(std::ostream & os) {
for(int i = 0 ; i < size ; i++) {
#ifdef DEBUG_SHATUMBLER
if(i != 0)
os << " ";
#endif
os << std::hex << std::setw(sizeof(h[i]) * 2) << std::setfill('0') << h[i];
}
return(os);
}
template <class int_type>
unsigned SHATumbler<int_type>::placeInBuffer(unsigned char * buffer) {
unsigned memsize = getSize();
memcpy((void*) buffer, (void*) h, memsize);
return(memsize);
}
template <class int_type>
unsigned SHATumbler<int_type>::getSize() {
unsigned memsize = sizeof(int_type) * size;
return(memsize);
}
/* *********************************************************************
SHADigest
********************************************************************* */
template <class uint_type, unsigned blockSizeInBytes>
SHADigest<uint_type, blockSizeInBytes>::SHADigest() {
initDigest();
}
template <class uint_type, unsigned blockSizeInBytes>
void SHADigest<uint_type, blockSizeInBytes>::padBuffer(unsigned char * buffer) {
int lengthOfTotalLength = blockSizeInBytes / 8;
uint_type totalLengthInBytes = totalLengthInBits / 8;
int remainder = totalLengthInBytes % blockSizeInBytes;
int fillTo;
if( (blockSizeInBytes - ( remainder + 1 )) >= lengthOfTotalLength ) {
fillTo = (blockSizeInBytes - lengthOfTotalLength);
} else {
fillTo = blockSizeInBytes;
}
buffer[remainder++] = 0x80;
do {
bzero(buffer + remainder, fillTo - remainder);
if(fillTo != blockSizeInBytes) {
*((uint_type*)(buffer + fillTo)) = totalLengthInBits;
}
processBlock(buffer);
remainder = 0;
fillTo -= lengthOfTotalLength;
} while(fillTo >= (blockSizeInBytes - lengthOfTotalLength));
completed = true;
}
template <class uint_type, unsigned blockSizeInBytes>
void SHADigest<uint_type, blockSizeInBytes>::initDigest() {
totalLengthInBits = 0;
completed = false;
}
template <class uint_type, unsigned blockSizeInBytes>
void SHADigest<uint_type, blockSizeInBytes>::putDigest(const unsigned char *
buffer, unsigned length)
throw(DigestException)
{
if(completed) {
throw(DigestException("Corrupted Digest!"));
}
if( length > (totalLengthInBits / 8) + length ) {
throw(DigestException("Digest Length Overflow!"));
}
// fill in tempBlock if necessarry, then process it...
uint_type bytesInTempBlock;
if(bytesInTempBlock = (totalLengthInBits/8) % blockSizeInBytes) {
unsigned bytesLeftInTempBlock = blockSizeInBytes - bytesInTempBlock;
unsigned numToCopy;
if(length < bytesLeftInTempBlock) {
numToCopy = length;
} else {
numToCopy = bytesLeftInTempBlock;
}
memcpy(tempBlock + bytesInTempBlock, buffer, numToCopy);
length -= numToCopy;
}
unsigned numBlocksToProcess = length / blockSizeInBytes;
unsigned numBytesToStore = length % blockSizeInBytes;
// process incoming stream
for(unsigned i = 0; i < numBlocksToProcess; i++) {
processBlock(buffer + (i * blockSizeInBytes));
}
// place any data that could not be processed into tempBlock
for(unsigned i = 0; i < numBytesToStore; i++) {
tempBlock[i] = (buffer + (numBlocksToProcess * blockSizeInBytes))[i];
}
totalLengthInBits += 8 * (bytesInTempBlock + (numBlocksToProcess *
blockSizeInBytes) + numBytesToStore);
}
template <class uint_type, unsigned blockSizeInBytes>
SHADigest<uint_type, blockSizeInBytes>::SHADigest(const SHADigest<uint_type,
blockSizeInBytes> & other) :
totalLengthInBits(other.totalLengthInBits),
completed(other.completed)
{
copyTempBlock(other);
}
template <class uint_type, unsigned blockSizeInBytes>
SHADigest<uint_type, blockSizeInBytes> & SHADigest<uint_type,
blockSizeInBytes>::operator=(const SHADigest & other) {
if(this == &other) {
return *this;
}
this->completed = other.completed;
this->totalLengthInBits = other.totalLengthInBits;
copyTempBlock(other);
}
template <class uint_type, unsigned blockSizeInBytes>
void SHADigest<uint_type, blockSizeInBytes>::copyTempBlock(const SHADigest &
other) {
if(uint_type remainder = ( (totalLengthInBits / 8) % blockSizeInBytes)) {
memcpy( (void*)tempBlock, (void*)other.tempBlock, remainder *
(sizeof(unsigned char)));
}
}
/* *********************************************************************
SHA64DigestHelper
********************************************************************* */
SHA64DigestHelper::SHA64DigestHelper(unsigned tumblerSize):
h(SHATumbler<uint32_t>(tumblerSize)),
a(SHATumbler<uint32_t>(tumblerSize))
{ }
SHATumbler<uint32_t> SHA64DigestHelper::getDigest() {
if(!completed) {
padBuffer(tempBlock);
}
return h;
}
std::ostream & SHA64DigestHelper::strDigest(std::ostream & os) {
SHATumbler<uint32_t> hCopy = getDigest();
os << hCopy;
return(os);
}
SHA64DigestHelper::SHA64DigestHelper(const SHA64DigestHelper & other) :
SHADigest<uint64_t, 64>(other),
h(other.h),
a(other.a)
{ }
SHA64DigestHelper & SHA64DigestHelper::operator=(const SHA64DigestHelper &
other)
{
if(this == &other) {
return(*this);
}
SHADigest<uint64_t, 64>::operator=(other);
this->h = other.h;
this->a = other.a;
return *this;
}
/* *********************************************************************
SHA1Digest
********************************************************************* */
SHA1Digest::SHA1Digest(): SHA64DigestHelper(5) {
initDigest();
}
void SHA1Digest::initDigest() {
h[0] = 0x67452301;
h[1] = 0xefcdab89;
h[2] = 0x98badcfe;
h[3] = 0x10325476;
h[4] = 0xc3d2e1f0;
SHADigest<uint64_t, 64>::initDigest();
}
SHA1Digest::SHA1Digest(const SHA1Digest & other): SHA64DigestHelper(other)
{ }
void SHA1Digest::processBlock(const unsigned char * buffer) {
uint32_t W[80];
memcpy((void*)W, (void*)buffer, sizeof(uint32_t) * 16);
for(int t = 16; t < 80; t++) {
W[t] = S(1,(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]));
}
a = h;
uint32_t temp;
for(int t = 0; t < 80; t++) {
switch(t/20) {
case(0):
temp = ((a[1] & a[2]) | (~a[1] & a[3])) + 0x5a827999;
break;
case(1):
temp = ((a[1] ^ a[2] ^ a[3]) + 0x6ed9eba1);
break;
case(2):
temp = ((a[1] & a[2]) | (a[1] & a[3]) | (a[2] & a[3])) + 0x8f1bbcdc;
break;
default:
temp = (a[1] ^ a[2] ^ a[3]) + 0xca62c1d6;
}
temp += S(5,a[0]) + a[4] + W[t];
a[4] = a[3];
a[3] = a[2];
a[2] = S(30,a[1]);
a[1] = a[0];
a[0] = temp;
#ifdef DEBUG_SHA1
std::cerr << std::setw(2) << std::dec << t << ": " << a << std::endl;
#endif
}
h += a;
}
/* *********************************************************************
SHA256Digest
********************************************************************* */
SHA256Digest::SHA256Digest(): SHA64DigestHelper(8) {
initDigest();
}
SHA256Digest::SHA256Digest(const SHA256Digest & other):
SHA64DigestHelper(other)
{ }
void SHA256Digest::initDigest() {
h[0] = 0x6a09e667;
h[1] = 0xbb67ae85;
h[2] = 0x3c6ef372;
h[3] = 0xa54ff53a;
h[4] = 0x510e527f;
h[5] = 0x9b05688c;
h[6] = 0x1f83d9ab;
h[7] = 0x5be0cd19;
SHADigest<uint64_t, 64>::initDigest();
}
#define Ch(x,y,z) ( ( ( x ) & ( y ) ) ^ ( ( ~ x ) & ( z ) ) )
#define Maj(x,y,z) ( ( ( x ) & ( y ) ) ^ ( ( x ) & ( z ) ) ^ ( ( y ) & ( z ) ) )
#define E0(x) ( RR(2,x) ^ RR(13,x) ^ RR(22,x) )
#define E1(x) ( RR(6,x) ^ RR(11,x) ^ RR(25,x) )
#define o0(x) ( RR(7,x) ^ RR(18,x) ^ RS(3,x) )
#define o1(x) ( RR(17,x) ^ RR(19,x) ^ RS(10,x) )
void SHA256Digest::processBlock(const unsigned char * buffer) {
uint32_t t1, t2;
uint32_t W[64];
uint32_t * M = (uint32_t*)buffer;
uint32_t * K32 = (uint32_t*)SHAConstant::K;
a = h;
for(int j = 0; j < 64 ; j++) {
if(j < 16) {
W[j] = M[j];
} else {
W[j] = o1(W[j-2]) + W[j-7] + o0(W[j-15]) + W[j-16];
}
t1 = a[7] + E1(a[4]) + Ch(a[4],a[5],a[6]) + K32[(j * 2) + K32_ADJUST] +
W[j];
t2 = E0(a[0]) + Maj(a[0],a[1],a[2]);
a[7] = a[6];
a[6] = a[5];
a[5] = a[4];
a[4] = a[3] + t1;
a[3] = a[2];
a[2] = a[1];
a[1] = a[0];
a[0] = t1 + t2;
#ifdef DEBUG_SHA256
std::cerr << std::setw(2) << std::dec << j << std::hex << ": " << a <<
std::endl;
#endif
}
h += a;
}
#ifdef CCXX_NAMESPACES
};
#endif
#ifdef TEST_SHA
#define BUFF_SIZE 1024
#include <stdio.h>
int main(int argc, char * argv[]) {
unsigned char buff[1024];
SHA256Digest d256;
unsigned length;
for(int i = 1 ; i < argc; i++) {
FILE * fp = fopen(argv[i], "rb");
d256.initDigest();
if(fp) {
while(length = fread(buff, sizeof(unsigned char), BUFF_SIZE, fp)) {
try {
d256.putDigest(buff, length);
} catch(DigestException & d) {
std::cerr << "Digest Exception: " << d.getString() << std::endl;
fclose(fp);
break;
}
}
std::cout << d256 << " " << argv[i] << std::endl;
fclose(fp);
}
}
}
#endif
# ###################################################################### #
# demo/shadigest.cpp
#include "config.h"
#include "strchar.h"
#include "exception.h"
#include "thread.h"
#include "digest.h"
#include <stdio.h>
#define BUFF_SIZE 1024
int main(int argc, char * argv[]) {
unsigned char buff[1024];
ost::SHA256Digest d256;
unsigned length;
for(int i = 1 ; i < argc; i++) {
FILE * fp = fopen(argv[i], "rb");
d256.initDigest();
if(fp) {
while(length = fread(buff, sizeof(unsigned char), BUFF_SIZE, fp)) {
d256.putDigest(buff, length);
}
std::cout << d256 << " " << argv[i] << std::endl;
fclose(fp);
}
}
}
# ##################################################################### #