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

Generated on Tue Jul 8 23:34:22 2003 for Crypto++ by doxygen 1.3.2