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
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
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
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