diff options
author | Jeffrey Walton <noloader@gmail.com> | 2015-11-05 01:59:46 -0500 |
---|---|---|
committer | Jeffrey Walton <noloader@gmail.com> | 2015-11-05 01:59:46 -0500 |
commit | 48809d4e85c125814425c621d8d0d89f95405924 (patch) | |
tree | 1010fd16c4b1199f3d27dd726dda241a2bd29f83 /pssr.cpp | |
parent | 025337a94aceb75d188149db70c2094673772816 (diff) | |
download | cryptopp-git-48809d4e85c125814425c621d8d0d89f95405924.tar.gz |
CRYPTOPP 5.6.3 RC6 checkin
Diffstat (limited to 'pssr.cpp')
-rw-r--r-- | pssr.cpp | 309 |
1 files changed, 158 insertions, 151 deletions
@@ -1,151 +1,158 @@ -// pssr.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "pssr.h" -#include "trap.h" - -#include <functional> - -NAMESPACE_BEGIN(CryptoPP) - -// more in dll.cpp -template<> const byte EMSA2HashId<RIPEMD160>::id = 0x31; -template<> const byte EMSA2HashId<RIPEMD128>::id = 0x32; -template<> const byte EMSA2HashId<Whirlpool>::id = 0x37; - -#ifndef CRYPTOPP_IMPORTS - -size_t PSSR_MEM_Base::MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const -{ - size_t saltLen = SaltLen(digestLength); - size_t minPadLen = MinPadLen(digestLength); - return 9 + 8*(minPadLen + saltLen + digestLength + hashIdentifierLength); -} - -size_t PSSR_MEM_Base::MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const -{ - if (AllowRecovery()) - return SaturatingSubtract(representativeBitLength, MinRepresentativeBitLength(hashIdentifierLength, digestLength)) / 8; - return 0; -} - -bool PSSR_MEM_Base::IsProbabilistic() const -{ - return SaltLen(1) > 0; -} - -bool PSSR_MEM_Base::AllowNonrecoverablePart() const -{ - return true; -} - -bool PSSR_MEM_Base::RecoverablePartFirst() const -{ - return false; -} - -void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const -{ - CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); - - const size_t u = hashIdentifier.second + 1; - const size_t representativeByteLength = BitsToBytes(representativeBitLength); - const size_t digestSize = hash.DigestSize(); - const size_t saltSize = SaltLen(digestSize); - byte *const h = representative + representativeByteLength - u - digestSize; - - SecByteBlock digest(digestSize), salt(saltSize); - hash.Final(digest); - rng.GenerateBlock(salt, saltSize); - - // compute H = hash of M' - byte c[8]; - PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength)); - PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3)); - hash.Update(c, 8); - hash.Update(recoverableMessage, recoverableMessageLength); - hash.Update(digest, digestSize); - hash.Update(salt, saltSize); - hash.Final(h); - - // compute representative - GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false); - byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1; - xorStart[0] ^= 1; - xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength); - xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size()); - - if (representative && hashIdentifier.first) - memcpy(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second); - representative[representativeByteLength - 1] = hashIdentifier.second ? 0xcc : 0xbc; - - if (representativeBitLength % 8 != 0) - representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); -} - -DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative( - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength, - byte *recoverableMessage) const -{ - CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); - - const size_t u = hashIdentifier.second + 1; - const size_t representativeByteLength = BitsToBytes(representativeBitLength); - const size_t digestSize = hash.DigestSize(); - const size_t saltSize = SaltLen(digestSize); - const byte *const h = representative + representativeByteLength - u - digestSize; - - SecByteBlock digest(digestSize); - hash.Final(digest); - - DecodingResult result(0); - bool &valid = result.isValidCoding; - size_t &recoverableMessageLength = result.messageLength; - - valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid; - valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid; - - GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize); - if (representativeBitLength % 8 != 0) - representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); - - // extract salt and recoverableMessage from DB = 00 ... || 01 || M || salt - byte *salt = representative + representativeByteLength - u - digestSize - saltSize; - byte *M = std::find_if (representative, salt-1, std::bind2nd(std::not_equal_to<byte>(), byte(0))); - recoverableMessageLength = salt-M-1; - if (*M == 0x01 - && (size_t)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize) - && recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize)) - { - if (recoverableMessage && M && recoverableMessageLength) - memcpy(recoverableMessage, M+1, recoverableMessageLength); - } - else - { - recoverableMessageLength = 0; - valid = false; - } - - // verify H = hash of M' - byte c[8]; - PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength)); - PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3)); - hash.Update(c, 8); - hash.Update(recoverableMessage, recoverableMessageLength); - hash.Update(digest, digestSize); - hash.Update(salt, saltSize); - valid = hash.Verify(h) && valid; - - if (!AllowRecovery() && valid && recoverableMessageLength != 0) - {throw NotImplemented("PSSR_MEM: message recovery disabled");} - - return result; -} - -#endif - -NAMESPACE_END +// pssr.cpp - written and placed in the public domain by Wei Dai
+
+#include "pch.h"
+#include "pssr.h"
+#include "misc.h"
+
+#include <functional>
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// more in dll.cpp
+template<> const byte EMSA2HashId<RIPEMD160>::id = 0x31;
+template<> const byte EMSA2HashId<RIPEMD128>::id = 0x32;
+template<> const byte EMSA2HashId<Whirlpool>::id = 0x37;
+
+#ifndef CRYPTOPP_IMPORTS
+
+size_t PSSR_MEM_Base::MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
+{
+ size_t saltLen = SaltLen(digestLength);
+ size_t minPadLen = MinPadLen(digestLength);
+ return 9 + 8*(minPadLen + saltLen + digestLength + hashIdentifierLength);
+}
+
+size_t PSSR_MEM_Base::MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
+{
+ if (AllowRecovery())
+ return SaturatingSubtract(representativeBitLength, MinRepresentativeBitLength(hashIdentifierLength, digestLength)) / 8;
+ return 0;
+}
+
+bool PSSR_MEM_Base::IsProbabilistic() const
+{
+ return SaltLen(1) > 0;
+}
+
+bool PSSR_MEM_Base::AllowNonrecoverablePart() const
+{
+ return true;
+}
+
+bool PSSR_MEM_Base::RecoverablePartFirst() const
+{
+ return false;
+}
+
+void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng,
+ const byte *recoverableMessage, size_t recoverableMessageLength,
+ HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
+ byte *representative, size_t representativeBitLength) const
+{
+ CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
+ CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
+ assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize()));
+
+ const size_t u = hashIdentifier.second + 1;
+ const size_t representativeByteLength = BitsToBytes(representativeBitLength);
+ const size_t digestSize = hash.DigestSize();
+ const size_t saltSize = SaltLen(digestSize);
+ byte *const h = representative + representativeByteLength - u - digestSize;
+
+ SecByteBlock digest(digestSize), salt(saltSize);
+ hash.Final(digest);
+ rng.GenerateBlock(salt, saltSize);
+
+ // compute H = hash of M'
+ byte c[8];
+ PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength));
+ PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3));
+ hash.Update(c, 8);
+ hash.Update(recoverableMessage, recoverableMessageLength);
+ hash.Update(digest, digestSize);
+ hash.Update(salt, saltSize);
+ hash.Final(h);
+
+ // compute representative
+ GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false);
+ byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1;
+ xorStart[0] ^= 1;
+ xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength);
+ xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size());
+ if (hashIdentifier.first && hashIdentifier.second)
+ {
+ memcpy(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second);
+ representative[representativeByteLength - 1] = 0xcc;
+ }
+ else
+ {
+ representative[representativeByteLength - 1] = 0xbc;
+ }
+ if (representativeBitLength % 8 != 0)
+ representative[0] = (byte)Crop(representative[0], representativeBitLength % 8);
+}
+
+DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative(
+ HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
+ byte *representative, size_t representativeBitLength,
+ byte *recoverableMessage) const
+{
+ CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
+ assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize()));
+
+ const size_t u = hashIdentifier.second + 1;
+ const size_t representativeByteLength = BitsToBytes(representativeBitLength);
+ const size_t digestSize = hash.DigestSize();
+ const size_t saltSize = SaltLen(digestSize);
+ const byte *const h = representative + representativeByteLength - u - digestSize;
+
+ SecByteBlock digest(digestSize);
+ hash.Final(digest);
+
+ DecodingResult result(0);
+ bool &valid = result.isValidCoding;
+ size_t &recoverableMessageLength = result.messageLength;
+
+ valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid;
+ valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;
+
+ GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize);
+ if (representativeBitLength % 8 != 0)
+ representative[0] = (byte)Crop(representative[0], representativeBitLength % 8);
+
+ // extract salt and recoverableMessage from DB = 00 ... || 01 || M || salt
+ byte *salt = representative + representativeByteLength - u - digestSize - saltSize;
+ byte *M = std::find_if(representative, salt-1, std::bind2nd(std::not_equal_to<byte>(), byte(0)));
+ recoverableMessageLength = salt-M-1;
+ if (*M == 0x01 &&
+ (size_t)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize) &&
+ recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize))
+ {
+ if (recoverableMessage)
+ memcpy(recoverableMessage, M+1, recoverableMessageLength);
+ }
+ else
+ {
+ recoverableMessageLength = 0;
+ valid = false;
+ }
+
+ // verify H = hash of M'
+ byte c[8];
+ PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength));
+ PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3));
+ hash.Update(c, 8);
+ hash.Update(recoverableMessage, recoverableMessageLength);
+ hash.Update(digest, digestSize);
+ hash.Update(salt, saltSize);
+ valid = hash.Verify(h) && valid;
+
+ if (!AllowRecovery() && valid && recoverableMessageLength != 0)
+ {throw NotImplemented("PSSR_MEM: message recovery disabled");}
+
+ return result;
+}
+
+#endif
+
+NAMESPACE_END
|