16 #ifndef CRYPTOPP_IMPORTS 18 size_t PSSR_MEM_Base::MinRepresentativeBitLength(
size_t hashIdentifierLength,
size_t digestLength)
const 20 size_t saltLen = SaltLen(digestLength);
21 size_t minPadLen = MinPadLen(digestLength);
22 return 9 + 8*(minPadLen + saltLen + digestLength + hashIdentifierLength);
25 size_t PSSR_MEM_Base::MaxRecoverableLength(
size_t representativeBitLength,
size_t hashIdentifierLength,
size_t digestLength)
const 28 return SaturatingSubtract(representativeBitLength, MinRepresentativeBitLength(hashIdentifierLength, digestLength)) / 8;
32 bool PSSR_MEM_Base::IsProbabilistic()
const 34 return SaltLen(1) > 0;
37 bool PSSR_MEM_Base::AllowNonrecoverablePart()
const 42 bool PSSR_MEM_Base::RecoverablePartFirst()
const 48 const byte *recoverableMessage,
size_t recoverableMessageLength,
50 byte *representative,
size_t representativeBitLength)
const 52 CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
53 CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
54 assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.
DigestSize()));
56 const size_t u = hashIdentifier.second + 1;
57 const size_t representativeByteLength =
BitsToBytes(representativeBitLength);
59 const size_t saltSize = SaltLen(digestSize);
60 byte *
const h = representative + representativeByteLength - u - digestSize;
68 PutWord(
false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength));
69 PutWord(
false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3));
71 hash.
Update(recoverableMessage, recoverableMessageLength);
72 hash.
Update(digest, digestSize);
73 hash.
Update(salt, saltSize);
77 GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize,
false);
78 byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1;
80 if (recoverableMessage && recoverableMessageLength)
81 xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength);
82 xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size());
83 if (hashIdentifier.first && hashIdentifier.second)
85 memcpy(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second);
86 representative[representativeByteLength - 1] = 0xcc;
90 representative[representativeByteLength - 1] = 0xbc;
92 if (representativeBitLength % 8 != 0)
93 representative[0] = (byte)
Crop(representative[0], representativeBitLength % 8);
98 byte *representative,
size_t representativeBitLength,
99 byte *recoverableMessage)
const 101 CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
102 assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.
DigestSize()));
104 const size_t u = hashIdentifier.second + 1;
105 const size_t representativeByteLength =
BitsToBytes(representativeBitLength);
107 const size_t saltSize = SaltLen(digestSize);
108 const byte *
const h = representative + representativeByteLength - u - digestSize;
114 bool &valid = result.isValidCoding;
115 size_t &recoverableMessageLength = result.messageLength;
117 valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid;
119 if (hashIdentifier.first && hashIdentifier.second)
120 valid =
VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;
122 GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize);
123 if (representativeBitLength % 8 != 0)
124 representative[0] = (byte)
Crop(representative[0], representativeBitLength % 8);
127 byte *salt = representative + representativeByteLength - u - digestSize - saltSize;
128 byte *M = std::find_if(representative, salt-1, std::bind2nd(std::not_equal_to<byte>(), byte(0)));
129 recoverableMessageLength = salt-M-1;
131 (
size_t)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize) &&
132 recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize))
134 if (recoverableMessage)
135 memcpy(recoverableMessage, M+1, recoverableMessageLength);
139 recoverableMessageLength = 0;
145 PutWord(
false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength));
146 PutWord(
false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3));
148 hash.
Update(recoverableMessage, recoverableMessageLength);
149 hash.
Update(digest, digestSize);
150 hash.
Update(salt, saltSize);
151 valid = hash.
Verify(h) && valid;
153 if (!AllowRecovery() && valid && recoverableMessageLength != 0)
Utility functions for the Crypto++ library.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
Interface for random number generators.
SecByteBlock is a SecBlock<byte> typedef.
Returns a decoding results.
A method was called which was not implemented.
T Crop(T value, size_t bits)
Truncates the value to the specified number of bits.
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
Crypto++ library namespace.
Classes for probablistic signature schemes.