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