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