18#ifndef CRYPTOPP_IMPORTS
20size_t PSSR_MEM_Base::MinRepresentativeBitLength(
size_t hashIdentifierLength,
size_t digestLength)
const
22 size_t saltLen = SaltLen(digestLength);
23 size_t minPadLen = MinPadLen(digestLength);
24 return 9 + 8*(minPadLen + saltLen + digestLength + hashIdentifierLength);
27size_t PSSR_MEM_Base::MaxRecoverableLength(
size_t representativeBitLength,
size_t hashIdentifierLength,
size_t digestLength)
const
30 return SaturatingSubtract(representativeBitLength, MinRepresentativeBitLength(hashIdentifierLength, digestLength)) / 8;
34bool PSSR_MEM_Base::IsProbabilistic()
const
36 return SaltLen(1) > 0;
39bool PSSR_MEM_Base::AllowNonrecoverablePart()
const
44bool PSSR_MEM_Base::RecoverablePartFirst()
const
50 const byte *recoverableMessage,
size_t recoverableMessageLength,
52 byte *representative,
size_t representativeBitLength)
const
54 CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
55 CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
58 const size_t u = hashIdentifier.second + 1;
59 const size_t representativeByteLength =
BitsToBytes(representativeBitLength);
61 const size_t saltSize = SaltLen(digestSize);
62 byte *
const h = representative + representativeByteLength - u - digestSize;
73 hash.
Update(recoverableMessage, recoverableMessageLength);
74 hash.
Update(digest, digestSize);
75 hash.
Update(salt, saltSize);
79 GetMGF().
GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize,
false);
80 byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1;
82 if (recoverableMessage && recoverableMessageLength)
83 xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength);
84 xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size());
85 if (hashIdentifier.first && hashIdentifier.second)
87 memcpy(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second);
88 representative[representativeByteLength - 1] = 0xcc;
92 representative[representativeByteLength - 1] = 0xbc;
94 if (representativeBitLength % 8 != 0)
95 representative[0] = (
byte)
Crop(representative[0], representativeBitLength % 8);
100 byte *representative,
size_t representativeBitLength,
101 byte *recoverableMessage)
const
103 CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
106 const size_t u = hashIdentifier.second + 1;
107 const size_t representativeByteLength =
BitsToBytes(representativeBitLength);
109 const size_t saltSize = SaltLen(digestSize);
110 const byte *
const h = representative + representativeByteLength - u - digestSize;
116 bool &valid = result.isValidCoding;
117 size_t &recoverableMessageLength = result.messageLength;
119 valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid;
121 if (hashIdentifier.first && hashIdentifier.second)
122 valid =
VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;
124 GetMGF().
GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize);
125 if (representativeBitLength % 8 != 0)
126 representative[0] = (
byte)
Crop(representative[0], representativeBitLength % 8);
129 byte *salt = representative + representativeByteLength - u - digestSize - saltSize;
130 byte *M =
FindIfNot(representative, salt-1,
byte(0));
131 recoverableMessageLength = salt-M-1;
133 (
size_t)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize) &&
134 recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize))
136 if (recoverableMessage)
137 memcpy(recoverableMessage, M+1, recoverableMessageLength);
141 recoverableMessageLength = 0;
150 hash.
Update(recoverableMessage, recoverableMessageLength);
151 hash.
Update(digest, digestSize);
152 hash.
Update(salt, saltSize);
153 valid = hash.
Verify(h) && valid;
155 if (!AllowRecovery() && valid && recoverableMessageLength != 0)
virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask=true) const =0
Generate and apply mask.
A method was called which was not implemented.
Interface for random number generators.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
unsigned char byte
8-bit unsigned datatype
unsigned int word32
32-bit unsigned datatype
@ BIG_ENDIAN_ORDER
byte order is big-endian
Classes and functions for various padding schemes used in public key algorithms.
Utility functions for the Crypto++ library.
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
T Crop(T value, size_t bits)
Truncates the value to the specified number of bits.
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
InputIt FindIfNot(InputIt first, InputIt last, const T &value)
Finds first element not in a range.
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
CRYPTOPP_DLL bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Crypto++ library namespace.
Classes for probabilistic signature schemes.
Classes for RIPEMD message digest.
Returns a decoding results.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Classes for the Whirlpool message digest.