source: git/src-cryptopp/pubkey.cpp

Last change on this file was e230cb0, checked in by David Stainton <dstainton415@…>, at 2016-10-12T13:27:29Z

Add cryptopp from tag CRYPTOPP_5_6_5

  • Property mode set to 100644
File size: 8.1 KB
Line 
1// pubkey.cpp - 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(), NULL, 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()))
54                throw PK_SignatureScheme::KeyTooShort();
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 messsage 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                NULL, 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()))
79                throw PK_SignatureScheme::KeyTooShort();
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()))
101                throw PK_SignatureScheme::KeyTooShort();
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()))
117                throw PK_SignatureScheme::KeyTooShort();
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()))
132                throw PK_SignatureScheme::KeyTooShort();
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
Note: See TracBrowser for help on using the repository browser.