📄 pubkey.h
字号:
// pubkey.h - written and placed in the public domain by Wei Dai
#ifndef CRYPTOPP_PUBKEY_H
#define CRYPTOPP_PUBKEY_H
/** \file
This file contains helper classes/functions for implementing public key algorithms.
The class hierachies in this .h file tend to look like this:
<pre>
x1
/ \
y1 z1
| |
x2<y1> x2<z1>
| |
y2 z2
| |
x3<y2> x3<z2>
| |
y3 z3
</pre>
- x1, y1, z1 are abstract interface classes defined in cryptlib.h
- x2, y2, z2 are implementations of the interfaces using "abstract policies", which
are pure virtual functions that should return interfaces to interchangeable algorithms.
These classes have "Base" suffixes.
- x3, y3, z3 hold actual algorithms and implement those virtual functions.
These classes have "Impl" suffixes.
The "TF_" prefix means an implementation using trapdoor functions on integers.
The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard).
*/
#include "integer.h"
#include "filters.h"
#include "eprecomp.h"
#include "fips140.h"
#include "argnames.h"
#include <memory>
// VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file
#undef INTERFACE
NAMESPACE_BEGIN(CryptoPP)
Integer NR_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen);
Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen);
// ********************************************************
//! .
class TrapdoorFunctionBounds
{
public:
virtual ~TrapdoorFunctionBounds() {}
virtual Integer PreimageBound() const =0;
virtual Integer ImageBound() const =0;
virtual Integer MaxPreimage() const {return --PreimageBound();}
virtual Integer MaxImage() const {return --ImageBound();}
};
//! .
class RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
{
public:
virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
virtual bool IsRandomized() const {return true;}
};
//! .
class TrapdoorFunction : public RandomizedTrapdoorFunction
{
public:
Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
{return ApplyFunction(x);}
bool IsRandomized() const {return false;}
virtual Integer ApplyFunction(const Integer &x) const =0;
};
//! .
class RandomizedTrapdoorFunctionInverse
{
public:
virtual ~RandomizedTrapdoorFunctionInverse() {}
virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
virtual bool IsRandomized() const {return true;}
};
//! .
class TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
{
public:
virtual ~TrapdoorFunctionInverse() {}
Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
{return CalculateInverse(rng, x);}
bool IsRandomized() const {return false;}
virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
};
// ********************************************************
//! .
class PK_EncryptionMessageEncodingMethod
{
public:
virtual ~PK_EncryptionMessageEncodingMethod() {}
//! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
virtual unsigned int MaxUnpaddedLength(unsigned int paddedLength) const =0;
virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedBitLength) const =0;
virtual DecodingResult Unpad(const byte *padded, unsigned int paddedBitLength, byte *raw) const =0;
};
// ********************************************************
//! .
template <class TFI, class MEI>
class TF_Base
{
protected:
virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
typedef TFI TrapdoorFunctionInterface;
virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
typedef MEI MessageEncodingInterface;
virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
};
// ********************************************************
//! .
template <class INTERFACE, class BASE>
class TF_CryptoSystemBase : public INTERFACE, protected BASE
{
public:
unsigned int FixedMaxPlaintextLength() const {return GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
unsigned int FixedCiphertextLength() const {return GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
protected:
unsigned int PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
unsigned int PaddedBlockBitLength() const {return GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
};
//! .
class TF_DecryptorBase : public TF_CryptoSystemBase<PK_FixedLengthDecryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
{
public:
DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const;
};
//! .
class TF_EncryptorBase : public TF_CryptoSystemBase<PK_FixedLengthEncryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
{
public:
void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const;
};
// ********************************************************
typedef std::pair<const byte *, unsigned int> HashIdentifier;
//! .
class PK_SignatureMessageEncodingMethod
{
public:
virtual ~PK_SignatureMessageEncodingMethod() {}
virtual unsigned int MaxRecoverableLength(unsigned int representativeBitLength, unsigned int hashIdentifierLength, unsigned int digestLength) const
{return 0;}
bool IsProbabilistic() const
{return true;}
bool AllowNonrecoverablePart() const
{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
virtual bool RecoverablePartFirst() const
{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
// for verification, DL
virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, unsigned int semisignatureLength) const {}
// for signature
virtual void ProcessRecoverableMessage(HashTransformation &hash,
const byte *recoverableMessage, unsigned int recoverableMessageLength,
const byte *presignature, unsigned int presignatureLength,
SecByteBlock &semisignature) const
{
if (RecoverablePartFirst())
assert(!"ProcessRecoverableMessage() not implemented");
}
virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
const byte *recoverableMessage, unsigned int recoverableMessageLength,
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, unsigned int representativeBitLength) const =0;
virtual bool VerifyMessageRepresentative(
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, unsigned int representativeBitLength) const =0;
virtual DecodingResult RecoverMessageFromRepresentative( // for TF
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, unsigned int representativeBitLength,
byte *recoveredMessage) const
{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
virtual DecodingResult RecoverMessageFromSemisignature( // for DL
HashTransformation &hash, HashIdentifier hashIdentifier,
const byte *presignature, unsigned int presignatureLength,
const byte *semisignature, unsigned int semisignatureLength,
byte *recoveredMessage) const
{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
// VC60 workaround
struct HashIdentifierLookup
{
template <class H> struct HashIdentifierLookup2
{
static HashIdentifier Lookup()
{
return HashIdentifier(NULL, 0);
}
};
};
};
class PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
{
public:
bool VerifyMessageRepresentative(
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, unsigned int representativeBitLength) const;
};
class PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
{
public:
bool VerifyMessageRepresentative(
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, unsigned int representativeBitLength) const;
};
class DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
{
public:
void ComputeMessageRepresentative(RandomNumberGenerator &rng,
const byte *recoverableMessage, unsigned int recoverableMessageLength,
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, unsigned int representativeBitLength) const;
};
class DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
{
public:
void ComputeMessageRepresentative(RandomNumberGenerator &rng,
const byte *recoverableMessage, unsigned int recoverableMessageLength,
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, unsigned int representativeBitLength) const;
};
class PK_MessageAccumulatorBase : public PK_MessageAccumulator
{
public:
PK_MessageAccumulatorBase() : m_empty(true) {}
virtual HashTransformation & AccessHash() =0;
void Update(const byte *input, unsigned int length)
{
AccessHash().Update(input, length);
m_empty = m_empty && length == 0;
}
SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
Integer m_k, m_s;
bool m_empty;
};
template <class HASH_ALGORITHM>
class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
{
public:
HashTransformation & AccessHash() {return m_object;}
};
//! .
template <class INTERFACE, class BASE>
class TF_SignatureSchemeBase : public INTERFACE, protected BASE
{
public:
unsigned int SignatureLength() const
{return GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
unsigned int MaxRecoverableLength() const
{return GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
unsigned int MaxRecoverableLengthFromSignatureLength(unsigned int signatureLength) const
{return MaxRecoverableLength();}
bool IsProbabilistic() const
{return GetTrapdoorFunctionInterface().IsRandomized() || GetMessageEncodingInterface().IsProbabilistic();}
bool AllowNonrecoverablePart() const
{return GetMessageEncodingInterface().AllowNonrecoverablePart();}
bool RecoverablePartFirst() const
{return GetMessageEncodingInterface().RecoverablePartFirst();}
protected:
unsigned int MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
unsigned int MessageRepresentativeBitLength() const {return GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
virtual HashIdentifier GetHashIdentifier() const =0;
virtual unsigned int GetDigestSize() const =0;
};
//! .
class TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
{
public:
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const;
unsigned int SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
};
//! .
class TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
{
public:
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const;
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
};
// ********************************************************
//! .
template <class T1, class T2, class T3>
struct TF_CryptoSchemeOptions
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -