Crypto++ 8.9
Free C++ class library of cryptographic schemes
pubkey.cpp
1// pubkey.cpp - originally written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "config.h"
5
6#ifndef CRYPTOPP_IMPORTS
7
8#include "pubkey.h"
9#include "integer.h"
10#include "filters.h"
11
12NAMESPACE_BEGIN(CryptoPP)
13
14void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart)
15{
16 ArraySink *sink;
17 HashFilter filter(hash, sink = mask ? new ArrayXorSink(output, outputLength) : new ArraySink(output, outputLength));
18 word32 counter = counterStart;
19 while (sink->AvailableSize() > 0)
20 {
21 filter.Put(input, inputLength);
22 filter.PutWord32(counter++);
23 filter.Put(derivationParams, derivationParamsLength);
24 filter.MessageEnd();
25 }
26}
27
28bool PK_DeterministicSignatureMessageEncodingMethod::VerifyMessageRepresentative(
29 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
30 byte *representative, size_t representativeBitLength) const
31{
32 SecByteBlock computedRepresentative(BitsToBytes(representativeBitLength));
33 ComputeMessageRepresentative(NullRNG(), NULLPTR, 0, hash, hashIdentifier, messageEmpty, computedRepresentative, representativeBitLength);
34 return VerifyBufsEqual(representative, computedRepresentative, computedRepresentative.size());
35}
36
37bool PK_RecoverableSignatureMessageEncodingMethod::VerifyMessageRepresentative(
38 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
39 byte *representative, size_t representativeBitLength) const
40{
41 SecByteBlock recoveredMessage(MaxRecoverableLength(representativeBitLength, hashIdentifier.second, hash.DigestSize()));
42 DecodingResult result = RecoverMessageFromRepresentative(
43 hash, hashIdentifier, messageEmpty, representative, representativeBitLength, recoveredMessage);
44 return result.isValidCoding && result.messageLength == 0;
45}
46
47void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
48{
49 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
50 HashIdentifier id = GetHashIdentifier();
51 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
52
53 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
55
56 size_t maxRecoverableLength = encoding.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize());
57
58 if (maxRecoverableLength == 0)
59 {throw NotImplemented("TF_SignerBase: this algorithm does not support message recovery or the key is too short");}
60 if (recoverableMessageLength > maxRecoverableLength)
61 throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm");
62
63 ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
64 encoding.ProcessRecoverableMessage(
65 ma.AccessHash(),
66 recoverableMessage, recoverableMessageLength,
67 NULLPTR, 0, ma.m_semisignature);
68}
69
70size_t TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
71{
72 CRYPTOPP_UNUSED(restart);
73
74 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
75 HashIdentifier id = GetHashIdentifier();
76 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
77
78 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
80
81 SecByteBlock representative(MessageRepresentativeLength());
82 encoding.ComputeMessageRepresentative(rng,
83 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
84 ma.AccessHash(), id, ma.m_empty,
85 representative, MessageRepresentativeBitLength());
86 ma.m_empty = true;
87
88 Integer r(representative, representative.size());
89 size_t signatureLength = SignatureLength();
90 GetTrapdoorFunctionInterface().CalculateRandomizedInverse(rng, r).Encode(signature, signatureLength);
91 return signatureLength;
92}
93
94void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
95{
96 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
97 HashIdentifier id = GetHashIdentifier();
98 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
99
100 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
102
103 ma.m_representative.New(MessageRepresentativeLength());
104 Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength));
105 if (x.BitCount() > MessageRepresentativeBitLength())
106 x = Integer::Zero(); // don't return false here to prevent timing attack
107 x.Encode(ma.m_representative, ma.m_representative.size());
108}
109
110bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
111{
112 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
113 HashIdentifier id = GetHashIdentifier();
114 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
115
116 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
118
119 bool result = encoding.VerifyMessageRepresentative(
120 ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength());
121 ma.m_empty = true;
122 return result;
123}
124
125DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
126{
127 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
128 HashIdentifier id = GetHashIdentifier();
129 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
130
131 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
133
134 DecodingResult result = encoding.RecoverMessageFromRepresentative(
135 ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage);
136 ma.m_empty = true;
137 return result;
138}
139
140DecodingResult TF_DecryptorBase::Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
141{
142 if (ciphertextLength != FixedCiphertextLength())
143 throw InvalidArgument(AlgorithmName() + ": ciphertext length of " + IntToString(ciphertextLength) + " doesn't match the required length of " + IntToString(FixedCiphertextLength()) + " for this key");
144
145 SecByteBlock paddedBlock(PaddedBlockByteLength());
146 Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, ciphertextLength));
147 if (x.ByteCount() > paddedBlock.size())
148 x = Integer::Zero(); // don't return false here to prevent timing attack
149 x.Encode(paddedBlock, paddedBlock.size());
150 return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters);
151}
152
153void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
154{
155 if (plaintextLength > FixedMaxPlaintextLength())
156 {
157 if (FixedMaxPlaintextLength() < 1)
158 throw InvalidArgument(AlgorithmName() + ": this key is too short to encrypt any messages");
159 else
160 throw InvalidArgument(AlgorithmName() + ": message length of " + IntToString(plaintextLength) + " exceeds the maximum of " + IntToString(FixedMaxPlaintextLength()) + " for this public key");
161 }
162
163 SecByteBlock paddedBlock(PaddedBlockByteLength());
164 GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters);
165 GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength());
166}
167
168NAMESPACE_END
169
170#endif
Copy input to a memory buffer.
Definition filters.h:1200
size_t AvailableSize()
Provides the size remaining in the Sink.
Definition filters.h:1218
Xor input to a memory buffer.
Definition filters.h:1242
bool MessageEnd(int propagation=-1, bool blocking=true)
Signals the end of messages to the object.
Definition cryptlib.h:1748
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition cryptlib.h:1678
size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true)
Input a 32-bit word for processing.
Filter wrapper for HashTransformation.
Definition filters.h:582
Interface for hash functions and data processing part of MACs.
Definition cryptlib.h:1118
virtual unsigned int DigestSize() const =0
Provides the digest size of the hash.
Multiple precision integer with arithmetic operations.
Definition integer.h:50
static const Integer & Zero()
Integer representing 0.
An invalid argument was detected.
Definition cryptlib.h:208
Interface for retrieving values given their names.
Definition cryptlib.h:327
A method was called which was not implemented.
Definition cryptlib.h:238
Interface for message encoding method for public key signature schemes.
Definition pubkey.h:452
Interface for accumulating messages to be signed or verified.
Definition cryptlib.h:2866
Exception throw when the private or public key is too short to sign or verify.
Definition cryptlib.h:2805
Interface for random number generators.
Definition cryptlib.h:1440
void New(size_type newSize)
Change size without preserving contents.
Definition secblock.h:1126
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
Definition secblock.h:898
size_type size() const
Provides the count of elements in the SecBlock.
Definition secblock.h:867
SecBlock typedef.
Definition secblock.h:1226
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const
Sign and restart messageAccumulator.
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
Input a recoverable message to an accumulator.
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
Input signature into a message accumulator.
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const
Recover a message from its signature.
Library configuration file.
unsigned int word32
32-bit unsigned datatype
Definition config_int.h:72
CRYPTOPP_DLL RandomNumberGenerator & NullRNG()
Random Number Generator that does not produce random numbers.
Implementation of BufferedTransformation's attachment interface.
Multiple precision integer with arithmetic operations.
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition misc.h:929
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
Definition misc.h:1143
CRYPTOPP_DLL 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.
Precompiled header file.
This file contains helper classes/functions for implementing public key algorithms.
Returns a decoding results.
Definition cryptlib.h:283
bool isValidCoding
Flag to indicate the decoding is valid.
Definition cryptlib.h:306
size_t messageLength
Recovered message length if isValidCoding is true, undefined otherwise.
Definition cryptlib.h:308