Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pssr.h

00001 #ifndef CRYPTOPP_PSSR_H
00002 #define CRYPTOPP_PSSR_H
00003 
00004 #include "pubkey.h"
00005 #include <functional>
00006 
00007 NAMESPACE_BEGIN(CryptoPP)
00008 
00010 template <class H, class MGF=P1363_MGF1<H> >
00011 class PSSR : public SignatureEncodingMethodWithRecovery
00012 {
00013 public:
00014         PSSR(unsigned int representativeBitLen);
00015         PSSR(const byte *representative, unsigned int representativeBitLen);
00016         ~PSSR() {}
00017         void Update(const byte *input, unsigned int length);
00018         unsigned int DigestSize() const {return bitsToBytes(representativeBitLen);}
00019         void Encode(RandomNumberGenerator &rng, byte *representative);
00020         bool Verify(const byte *representative);
00021         unsigned int Decode(byte *message);
00022         unsigned int MaximumRecoverableLength() const {return MaximumRecoverableLength(representativeBitLen);}
00023         static unsigned int MaximumRecoverableLength(unsigned int representativeBitLen);
00024         static bool AllowLeftoverMessage() {return true;}
00025 
00026 protected:
00027         static void EncodeRepresentative(byte *representative, unsigned int representativeBitLen, const byte *w, const byte *seed, const byte *m1, unsigned int m1Len);
00028         static unsigned int DecodeRepresentative(const byte *representative, unsigned int representativeBitLen, byte *w, byte *seed, byte *m1);
00029 
00030         unsigned int representativeBitLen, m1Len;
00031         H h;
00032         SecByteBlock m1, w, seed;
00033 };
00034 
00035 template <class H, class MGF>
00036 PSSR<H,MGF>::PSSR(unsigned int representativeBitLen)
00037         : representativeBitLen(representativeBitLen), m1Len(0)
00038         , m1(MaximumRecoverableLength()), w(H::DIGESTSIZE), seed(H::DIGESTSIZE)
00039 {
00040 }
00041 
00042 template <class H, class MGF>
00043 PSSR<H,MGF>::PSSR(const byte *representative, unsigned int representativeBitLen)
00044         : representativeBitLen(representativeBitLen), m1Len(0)
00045         , m1(MaximumRecoverableLength()), w(H::DIGESTSIZE), seed(H::DIGESTSIZE)
00046 {
00047         m1Len = DecodeRepresentative(representative, representativeBitLen, w, seed, m1);
00048         h.Update(m1, m1Len);
00049 }
00050 
00051 template <class H, class MGF>
00052 void PSSR<H,MGF>::Update(const byte *input, unsigned int length)
00053 {
00054         unsigned int m1LenInc = STDMIN(length, MaximumRecoverableLength() - m1Len);
00055         memcpy(m1+m1Len, input, m1LenInc);
00056         m1Len += m1LenInc;
00057         h.Update(input, length);
00058 }
00059 
00060 template <class H, class MGF>
00061 void PSSR<H,MGF>::Encode(RandomNumberGenerator &rng, byte *representative)
00062 {
00063         rng.GetBlock(seed, seed.size);
00064         h.Update(seed, seed.size);
00065         h.Final(w);
00066         EncodeRepresentative(representative, representativeBitLen, w, seed, m1, m1Len);
00067 }
00068 
00069 template <class H, class MGF>
00070 bool PSSR<H,MGF>::Verify(const byte *representative)
00071 {
00072         SecByteBlock m1r(MaximumRecoverableLength()), wr(H::DIGESTSIZE);
00073         unsigned int m1rLen = DecodeRepresentative(representative, representativeBitLen, wr, seed, m1r);
00074         h.Update(seed, seed.size);
00075         h.Final(w);
00076         return m1Len==m1rLen && memcmp(m1, m1r, m1Len)==0 && w==wr;
00077 }
00078 
00079 template <class H, class MGF>
00080 unsigned int PSSR<H,MGF>::Decode(byte *message)
00081 {
00082         SecByteBlock wh(H::DIGESTSIZE);
00083         h.Update(seed, seed.size);
00084         h.Final(wh);
00085         if (wh == w)
00086         {
00087                 memcpy(message, m1, m1Len);
00088                 return m1Len;
00089         }
00090         else
00091                 return 0;
00092 }
00093 
00094 template <class H, class MGF>
00095 unsigned int PSSR<H,MGF>::MaximumRecoverableLength(unsigned int paddedLength)
00096 {
00097         return paddedLength/8 > 1+2*H::DIGESTSIZE ? paddedLength/8-1-2*H::DIGESTSIZE : 0;
00098 }
00099 
00100 template <class H, class MGF>
00101 void PSSR<H,MGF>::EncodeRepresentative(byte *pssrBlock, unsigned int pssrBlockLen, const byte *w, const byte *seed, const byte *m1, unsigned int m1Len)
00102 {
00103         assert (m1Len <= MaximumRecoverableLength(pssrBlockLen));
00104 
00105         // convert from bit length to byte length
00106         if (pssrBlockLen % 8 != 0)
00107         {
00108                 pssrBlock[0] = 0;
00109                 pssrBlock++;
00110         }
00111         pssrBlockLen /= 8;
00112 
00113         const unsigned int hLen = H::DIGESTSIZE;
00114         const unsigned int wLen = hLen, seedLen = hLen, dbLen = pssrBlockLen-wLen-seedLen;
00115         byte *const maskedSeed = pssrBlock+wLen;
00116         byte *const maskedDB = pssrBlock+wLen+seedLen;
00117 
00118         memcpy(pssrBlock, w, wLen);
00119         memcpy(maskedSeed, seed, seedLen);
00120         memset(maskedDB, 0, dbLen-m1Len-1);
00121         maskedDB[dbLen-m1Len-1] = 0x01;
00122         memcpy(maskedDB+dbLen-m1Len, m1, m1Len);
00123 
00124         MGF::GenerateAndMask(maskedSeed, seedLen+dbLen, w, wLen);
00125 }
00126 
00127 template <class H, class MGF>
00128 unsigned int PSSR<H,MGF>::DecodeRepresentative(const byte *pssrBlock, unsigned int pssrBlockLen, byte *w, byte *seed, byte *m1)
00129 {
00130         // convert from bit length to byte length
00131         if (pssrBlockLen % 8 != 0)
00132         {
00133                 if (pssrBlock[0] != 0)
00134                         return 0;
00135                 pssrBlock++;
00136         }
00137         pssrBlockLen /= 8;
00138 
00139         const unsigned int hLen = H::DIGESTSIZE;
00140         const unsigned int wLen = hLen, seedLen = hLen, dbLen = pssrBlockLen-wLen-seedLen;
00141 
00142         if (pssrBlockLen < 2*hLen+1)
00143                 return 0;
00144 
00145         memcpy(w, pssrBlock, wLen);
00146         SecByteBlock t(pssrBlock+wLen, pssrBlockLen-wLen);
00147         byte *const maskedSeed = t;
00148         byte *const maskedDB = t+seedLen;
00149 
00150         MGF::GenerateAndMask(maskedSeed, seedLen+dbLen, w, wLen);
00151         memcpy(seed, maskedSeed, seedLen);
00152 
00153         // DB = 00 ... || 01 || M
00154 
00155         byte *M = std::find_if(maskedDB, maskedDB+dbLen, std::bind2nd(std::not_equal_to<byte>(), 0));
00156         if (M!=maskedDB+dbLen && *M == 0x01)
00157         {
00158                 M++;
00159                 memcpy(m1, M, maskedDB+dbLen-M);
00160                 return maskedDB+dbLen-M;
00161         }
00162         else
00163                 return 0;
00164 }
00165 
00166 NAMESPACE_END
00167 
00168 #endif

Generated at Mon Jan 15 01:16:35 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000