summaryrefslogtreecommitdiff
path: root/pssr.h
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2003-03-20 01:24:12 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2003-03-20 01:24:12 +0000
commitd23a489940499bd6c634a1cb0a9875f094f8a850 (patch)
treef85b3bed971083e90e5f3dbb84539ea4ba0359e9 /pssr.h
parentb3517523a738277cfe22428bd757833e69abb66e (diff)
downloadcryptopp-d23a489940499bd6c634a1cb0a9875f094f8a850.tar.gz
various changes for 5.1
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@38 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'pssr.h')
-rw-r--r--pssr.h199
1 files changed, 58 insertions, 141 deletions
diff --git a/pssr.h b/pssr.h
index a17b56b..4ba2950 100644
--- a/pssr.h
+++ b/pssr.h
@@ -6,163 +6,80 @@
NAMESPACE_BEGIN(CryptoPP)
-// TODO: implement standard variant of PSSR
-template <class H, class MGF=P1363_MGF1<H> >
-class PSSR : public SignatureEncodingMethodWithRecovery
+class PSSR_MEM_Base : public PK_RecoverableSignatureMessageEncodingMethod
{
-public:
- PSSR(unsigned int representativeBitLen);
- PSSR(const byte *representative, unsigned int representativeBitLen);
- ~PSSR() {}
- void Update(const byte *input, unsigned int length);
- unsigned int DigestSize() const {return BitsToBytes(representativeBitLen);}
- void Restart() {h.Restart();}
- void Encode(RandomNumberGenerator &rng, byte *representative);
- bool Verify(const byte *representative);
- DecodingResult Decode(byte *message);
- unsigned int MaximumRecoverableLength() const {return MaximumRecoverableLength(representativeBitLen);}
- static unsigned int MaximumRecoverableLength(unsigned int representativeBitLen);
- static bool AllowLeftoverMessage() {return true;}
-
-protected:
- static void EncodeRepresentative(byte *representative, unsigned int representativeBitLen, const byte *w, const byte *seed, const byte *m1, unsigned int m1Len);
- static unsigned int DecodeRepresentative(const byte *representative, unsigned int representativeBitLen, byte *w, byte *seed, byte *m1);
+ virtual bool AllowRecovery() const =0;
+ virtual unsigned int SaltLen(unsigned int hashLen) const =0;
+ virtual unsigned int MinPadLen(unsigned int hashLen) const =0;
+ virtual const MaskGeneratingFunction & GetMGF() const =0;
- unsigned int representativeBitLen, m1Len;
- H h;
- SecByteBlock m1, w, seed;
+public:
+ unsigned int MaxRecoverableLength(unsigned int representativeBitLength, unsigned int hashIdentifierLength, unsigned int digestLength) const;
+ bool IsProbabilistic() const;
+ bool AllowNonrecoverablePart() const;
+ bool RecoverablePartFirst() const;
+ void ComputeMessageRepresentative(RandomNumberGenerator &rng,
+ const byte *recoverableMessage, unsigned int recoverableMessageLength,
+ HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
+ byte *representative, unsigned int representativeBitLength) const;
+ DecodingResult RecoverMessageFromRepresentative(
+ HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
+ byte *representative, unsigned int representativeBitLength,
+ byte *recoverableMessage) const;
};
-template <class H, class MGF>
-PSSR<H,MGF>::PSSR(unsigned int representativeBitLen)
- : representativeBitLen(representativeBitLen), m1Len(0)
- , m1(MaximumRecoverableLength()), w(H::DIGESTSIZE), seed(H::DIGESTSIZE)
-{
-}
-
-template <class H, class MGF>
-PSSR<H,MGF>::PSSR(const byte *representative, unsigned int representativeBitLen)
- : representativeBitLen(representativeBitLen), m1Len(0)
- , m1(MaximumRecoverableLength()), w(H::DIGESTSIZE), seed(H::DIGESTSIZE)
-{
- m1Len = DecodeRepresentative(representative, representativeBitLen, w, seed, m1);
- h.Update(m1, m1Len);
-}
-
-template <class H, class MGF>
-void PSSR<H,MGF>::Update(const byte *input, unsigned int length)
+template <class H> struct EMSA2HashId
{
- unsigned int m1LenInc = STDMIN(length, MaximumRecoverableLength() - m1Len);
- memcpy(m1+m1Len, input, m1LenInc);
- m1Len += m1LenInc;
- h.Update(input, length);
-}
-
-template <class H, class MGF>
-void PSSR<H,MGF>::Encode(RandomNumberGenerator &rng, byte *representative)
-{
- rng.GenerateBlock(seed, seed.size());
- h.Update(seed, seed.size());
- h.Final(w);
- EncodeRepresentative(representative, representativeBitLen, w, seed, m1, m1Len);
-}
+ static const byte id;
+};
-template <class H, class MGF>
-bool PSSR<H,MGF>::Verify(const byte *representative)
-{
- SecByteBlock m1r(MaximumRecoverableLength()), wr(H::DIGESTSIZE);
- unsigned int m1rLen = DecodeRepresentative(representative, representativeBitLen, wr, seed, m1r);
- h.Update(seed, seed.size());
- h.Final(w);
- return m1Len==m1rLen && memcmp(m1, m1r, m1Len)==0 && w==wr;
-}
+// EMSA2HashId can be instantiated with the following two classes.
+class SHA;
+class RIPEMD160;
-template <class H, class MGF>
-DecodingResult PSSR<H,MGF>::Decode(byte *message)
+template <class BASE>
+class EMSA2HashIdLookup : public BASE
{
- SecByteBlock wh(H::DIGESTSIZE);
- h.Update(seed, seed.size());
- h.Final(wh);
- if (wh == w)
+public:
+ struct HashIdentifierLookup
{
- memcpy(message, m1, m1Len);
- return DecodingResult(m1Len);
- }
- else
- return DecodingResult();
-}
+ template <class H> struct HashIdentifierLookup2
+ {
+ static HashIdentifier Lookup()
+ {
+ return HashIdentifier(&EMSA2HashId<H>::id, 1);
+ }
+ };
+ };
+};
-template <class H, class MGF>
-unsigned int PSSR<H,MGF>::MaximumRecoverableLength(unsigned int paddedLength)
-{
- return paddedLength/8 > 1+2*H::DIGESTSIZE ? paddedLength/8-1-2*H::DIGESTSIZE : 0;
-}
+template <bool USE_HASH_ID> class PSSR_MEM_BaseWithHashId;
+template<> class PSSR_MEM_BaseWithHashId<true> : public EMSA2HashIdLookup<PSSR_MEM_Base> {};
+template<> class PSSR_MEM_BaseWithHashId<false> : public PSSR_MEM_Base {};
-template <class H, class MGF>
-void PSSR<H,MGF>::EncodeRepresentative(byte *pssrBlock, unsigned int pssrBlockLen, const byte *w, const byte *seed, const byte *m1, unsigned int m1Len)
+template <bool ALLOW_RECOVERY, class MGF=P1363_MGF1, int SALT_LEN=-1, int MIN_PAD_LEN=0, bool USE_HASH_ID=false>
+class PSSR_MEM : public PSSR_MEM_BaseWithHashId<USE_HASH_ID>
{
- assert (m1Len <= MaximumRecoverableLength(pssrBlockLen));
-
- // convert from bit length to byte length
- if (pssrBlockLen % 8 != 0)
- {
- pssrBlock[0] = 0;
- pssrBlock++;
- }
- pssrBlockLen /= 8;
-
- const unsigned int hLen = H::DIGESTSIZE;
- const unsigned int wLen = hLen, seedLen = hLen, dbLen = pssrBlockLen-wLen-seedLen;
- byte *const maskedSeed = pssrBlock+wLen;
- byte *const maskedDB = pssrBlock+wLen+seedLen;
+ virtual bool AllowRecovery() const {return ALLOW_RECOVERY;}
+ virtual unsigned int SaltLen(unsigned int hashLen) const {return SALT_LEN < 0 ? hashLen : SALT_LEN;}
+ virtual unsigned int MinPadLen(unsigned int hashLen) const {return MIN_PAD_LEN < 0 ? hashLen : MIN_PAD_LEN;}
+ virtual const MaskGeneratingFunction & GetMGF() const {static MGF mgf; return mgf;}
- memcpy(pssrBlock, w, wLen);
- memcpy(maskedSeed, seed, seedLen);
- memset(maskedDB, 0, dbLen-m1Len-1);
- maskedDB[dbLen-m1Len-1] = 0x01;
- memcpy(maskedDB+dbLen-m1Len, m1, m1Len);
-
- MGF::GenerateAndMask(maskedSeed, seedLen+dbLen, w, wLen);
-}
+public:
+ static std::string StaticAlgorithmName() {return std::string(ALLOW_RECOVERY ? "PSSR-" : "PSS-") + MGF::StaticAlgorithmName();}
+};
-template <class H, class MGF>
-unsigned int PSSR<H,MGF>::DecodeRepresentative(const byte *pssrBlock, unsigned int pssrBlockLen, byte *w, byte *seed, byte *m1)
+//! <a href="http://www.weidai.com/scan-mirror/sig.html#sem_PSSR-MGF1">PSSR-MGF1</a>
+struct PSSR : public SignatureStandard
{
- // convert from bit length to byte length
- if (pssrBlockLen % 8 != 0)
- {
- if (pssrBlock[0] != 0)
- return 0;
- pssrBlock++;
- }
- pssrBlockLen /= 8;
-
- const unsigned int hLen = H::DIGESTSIZE;
- const unsigned int wLen = hLen, seedLen = hLen, dbLen = pssrBlockLen-wLen-seedLen;
-
- if (pssrBlockLen < 2*hLen+1)
- return 0;
-
- memcpy(w, pssrBlock, wLen);
- SecByteBlock t(pssrBlock+wLen, pssrBlockLen-wLen);
- byte *const maskedSeed = t;
- byte *const maskedDB = t+seedLen;
-
- MGF::GenerateAndMask(maskedSeed, seedLen+dbLen, w, wLen);
- memcpy(seed, maskedSeed, seedLen);
-
- // DB = 00 ... || 01 || M
+ typedef PSSR_MEM<true> SignatureMessageEncodingMethod;
+};
- byte *M = std::find_if(maskedDB, maskedDB+dbLen, std::bind2nd(std::not_equal_to<byte>(), 0));
- if (M!=maskedDB+dbLen && *M == 0x01)
- {
- M++;
- memcpy(m1, M, maskedDB+dbLen-M);
- return maskedDB+dbLen-M;
- }
- else
- return 0;
-}
+//! <a href="http://www.weidai.com/scan-mirror/sig.html#sem_PSS-MGF1">PSS-MGF1</a>
+struct PSS : public SignatureStandard
+{
+ typedef PSSR_MEM<false> SignatureMessageEncodingMethod;
+};
NAMESPACE_END