3 #ifndef CRYPTOPP_PUBKEY_H
4 #define CRYPTOPP_PUBKEY_H
45 NAMESPACE_BEGIN(CryptoPP)
51 virtual ~TrapdoorFunctionBounds() {}
53 virtual Integer PreimageBound()
const =0;
54 virtual Integer ImageBound()
const =0;
55 virtual Integer MaxPreimage()
const {
return --PreimageBound();}
56 virtual Integer MaxImage()
const {
return --ImageBound();}
64 virtual bool IsRandomized()
const {
return true;}
72 {
return ApplyFunction(x);}
73 bool IsRandomized()
const {
return false;}
85 virtual bool IsRandomized()
const {
return true;}
95 {
return CalculateInverse(rng, x);}
96 bool IsRandomized()
const {
return false;}
109 virtual bool ParameterSupported(
const char *name)
const {
return false;}
112 virtual size_t MaxUnpaddedLength(
size_t paddedLength)
const =0;
122 template <
class TFI,
class MEI>
128 typedef TFI TrapdoorFunctionInterface;
129 virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface()
const =0;
131 typedef MEI MessageEncodingInterface;
132 virtual const MessageEncodingInterface & GetMessageEncodingInterface()
const =0;
138 template <
class BASE>
142 size_t MaxPlaintextLength(
size_t ciphertextLength)
const
143 {
return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
144 size_t CiphertextLength(
size_t plaintextLength)
const
145 {
return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
147 virtual size_t FixedMaxPlaintextLength()
const =0;
148 virtual size_t FixedCiphertextLength()
const =0;
152 template <
class INTERFACE,
class BASE>
156 bool ParameterSupported(
const char *name)
const {
return this->GetMessageEncodingInterface().ParameterSupported(name);}
157 size_t FixedMaxPlaintextLength()
const {
return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
158 size_t FixedCiphertextLength()
const {
return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
161 size_t PaddedBlockByteLength()
const {
return BitsToBytes(PaddedBlockBitLength());}
162 size_t PaddedBlockBitLength()
const {
return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
181 typedef std::pair<const byte *, size_t> HashIdentifier;
189 virtual size_t MinRepresentativeBitLength(
size_t hashIdentifierLength,
size_t digestLength)
const
191 virtual size_t MaxRecoverableLength(
size_t representativeBitLength,
size_t hashIdentifierLength,
size_t digestLength)
const
194 bool IsProbabilistic()
const
196 bool AllowNonrecoverablePart()
const
197 {
throw NotImplemented(
"PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
198 virtual bool RecoverablePartFirst()
const
199 {
throw NotImplemented(
"PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
202 virtual void ProcessSemisignature(
HashTransformation &hash,
const byte *semisignature,
size_t semisignatureLength)
const {}
206 const byte *recoverableMessage,
size_t recoverableMessageLength,
207 const byte *presignature,
size_t presignatureLength,
210 if (RecoverablePartFirst())
211 assert(!
"ProcessRecoverableMessage() not implemented");
215 const byte *recoverableMessage,
size_t recoverableMessageLength,
217 byte *representative,
size_t representativeBitLength)
const =0;
219 virtual bool VerifyMessageRepresentative(
221 byte *representative,
size_t representativeBitLength)
const =0;
225 byte *representative,
size_t representativeBitLength,
226 byte *recoveredMessage)
const
227 {
throw NotImplemented(
"PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
231 const byte *presignature,
size_t presignatureLength,
232 const byte *semisignature,
size_t semisignatureLength,
233 byte *recoveredMessage)
const
234 {
throw NotImplemented(
"PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
241 static HashIdentifier CRYPTOPP_API Lookup()
243 return HashIdentifier((
const byte *)NULL, 0);
252 bool VerifyMessageRepresentative(
254 byte *representative,
size_t representativeBitLength)
const;
260 bool VerifyMessageRepresentative(
262 byte *representative,
size_t representativeBitLength)
const;
269 const byte *recoverableMessage,
size_t recoverableMessageLength,
271 byte *representative,
size_t representativeBitLength)
const;
278 const byte *recoverableMessage,
size_t recoverableMessageLength,
280 byte *representative,
size_t representativeBitLength)
const;
290 void Update(
const byte *input,
size_t length)
292 AccessHash().Update(input, length);
293 m_empty = m_empty && length == 0;
296 SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
301 template <
class HASH_ALGORITHM>
309 template <
class INTERFACE,
class BASE>
313 size_t SignatureLength()
const
314 {
return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
315 size_t MaxRecoverableLength()
const
316 {
return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
317 size_t MaxRecoverableLengthFromSignatureLength(
size_t signatureLength)
const
318 {
return this->MaxRecoverableLength();}
320 bool IsProbabilistic()
const
321 {
return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
322 bool AllowNonrecoverablePart()
const
323 {
return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
324 bool RecoverablePartFirst()
const
325 {
return this->GetMessageEncodingInterface().RecoverablePartFirst();}
328 size_t MessageRepresentativeLength()
const {
return BitsToBytes(MessageRepresentativeBitLength());}
329 size_t MessageRepresentativeBitLength()
const {
return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
330 virtual HashIdentifier GetHashIdentifier()
const =0;
331 virtual size_t GetDigestSize()
const =0;
338 void InputRecoverableMessage(
PK_MessageAccumulator &messageAccumulator,
const byte *recoverableMessage,
size_t recoverableMessageLength)
const;
346 void InputSignature(
PK_MessageAccumulator &messageAccumulator,
const byte *signature,
size_t signatureLength)
const;
354 template <
class T1,
class T2,
class T3>
357 typedef T1 AlgorithmInfo;
360 typedef typename Keys::PublicKey
PublicKey;
361 typedef T3 MessageEncodingMethod;
365 template <
class T1,
class T2,
class T3,
class T4>
368 typedef T4 HashFunction;
372 template <
class BASE,
class SCHEME_OPTIONS,
class KEY_CLASS>
376 typedef SCHEME_OPTIONS SchemeOptions;
377 typedef KEY_CLASS KeyClass;
379 PublicKey & AccessPublicKey() {
return AccessKey();}
380 const PublicKey & GetPublicKey()
const {
return GetKey();}
382 PrivateKey & AccessPrivateKey() {
return AccessKey();}
383 const PrivateKey & GetPrivateKey()
const {
return GetKey();}
385 virtual const KeyClass & GetKey()
const =0;
386 virtual KeyClass & AccessKey() =0;
388 const KeyClass & GetTrapdoorFunction()
const {
return GetKey();}
400 const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface()
const
404 const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface()
const
408 HashIdentifier GetHashIdentifier()
const
410 typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
413 size_t GetDigestSize()
const
415 typedef CPP_TYPENAME SchemeOptions::HashFunction H;
416 return H::DIGESTSIZE;
421 template <
class BASE,
class SCHEME_OPTIONS,
class KEY>
426 void SetKeyPtr(
const KEY *pKey) {m_pKey = pKey;}
428 const KEY & GetKey()
const {
return *m_pKey;}
429 KEY & AccessKey() {
throw NotImplemented(
"TF_ObjectImplExtRef: cannot modify refererenced key");}
436 template <
class BASE,
class SCHEME_OPTIONS,
class KEY_CLASS>
440 typedef KEY_CLASS KeyClass;
442 const KeyClass & GetKey()
const {
return m_trapdoorFunction;}
443 KeyClass & AccessKey() {
return m_trapdoorFunction;}
446 KeyClass m_trapdoorFunction;
450 template <
class SCHEME_OPTIONS>
456 template <
class SCHEME_OPTIONS>
462 template <
class SCHEME_OPTIONS>
468 template <
class SCHEME_OPTIONS>
480 virtual void GenerateAndMask(
HashTransformation &hash, byte *output,
size_t outputLength,
const byte *input,
size_t inputLength,
bool mask =
true)
const =0;
483 CRYPTOPP_DLL
void CRYPTOPP_API 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);
489 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "MGF1";}
490 void GenerateAndMask(
HashTransformation &hash, byte *output,
size_t outputLength,
const byte *input,
size_t inputLength,
bool mask =
true)
const
492 P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
503 static void CRYPTOPP_API DeriveKey(byte *output,
size_t outputLength,
const byte *input,
size_t inputLength,
const byte *derivationParams,
size_t derivationParamsLength)
506 P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength,
false, 1);
533 if (!GetBasePrecomputation().IsInitialized())
536 if (m_validationLevel > level)
539 bool pass = ValidateGroup(rng, level);
540 pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
542 m_validationLevel = pass ? level+1 : 0;
547 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
549 return GetValueHelper(
this, name, valueType, pValue)
550 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
551 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
559 AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
564 AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
565 m_validationLevel = 0;
570 GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
574 virtual const Element & GetSubgroupGenerator()
const {
return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
575 virtual void SetSubgroupGenerator(
const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
576 virtual Element ExponentiateBase(
const Integer &exponent)
const
578 return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
580 virtual Element ExponentiateElement(
const Element &base,
const Integer &exponent)
const
583 SimultaneousExponentiate(&result, base, &exponent, 1);
590 virtual const Integer & GetSubgroupOrder()
const =0;
591 virtual Integer GetMaxExponent()
const =0;
592 virtual Integer GetGroupOrder()
const {
return GetSubgroupOrder()*GetCofactor();}
593 virtual Integer GetCofactor()
const {
return GetGroupOrder()/GetSubgroupOrder();}
594 virtual unsigned int GetEncodedElementSize(
bool reversible)
const =0;
595 virtual void EncodeElement(
bool reversible,
const Element &element, byte *encoded)
const =0;
596 virtual Element DecodeElement(
const byte *encoded,
bool checkForGroupMembership)
const =0;
597 virtual Integer ConvertElementToInteger(
const Element &element)
const =0;
600 virtual bool FastSubgroupCheckAvailable()
const =0;
601 virtual bool IsIdentity(
const Element &element)
const =0;
602 virtual void SimultaneousExponentiate(Element *results,
const Element &base,
const Integer *exponents,
unsigned int exponentsCount)
const =0;
605 void ParametersChanged() {m_validationLevel = 0;}
608 mutable unsigned int m_validationLevel;
612 template <
class GROUP_PRECOMP,
class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element>,
class BASE = DL_GroupParameters<CPP_TYPENAME GROUP_PRECOMP::Element> >
616 typedef GROUP_PRECOMP GroupPrecomputation;
617 typedef typename GROUP_PRECOMP::Element Element;
618 typedef BASE_PRECOMP BasePrecomputation;
625 GROUP_PRECOMP m_groupPrecomputation;
647 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
649 return GetValueHelper(
this, name, valueType, pValue, &this->GetAbstractGroupParameters())
650 CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
656 virtual const Element & GetPublicElement()
const {
return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
657 virtual void SetPublicElement(
const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
658 virtual Element ExponentiatePublicElement(
const Integer &exponent)
const
661 return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
663 virtual Element CascadeExponentiateBaseAndPublicElement(
const Integer &baseExp,
const Integer &publicExp)
const
666 return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
684 pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
685 pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
688 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
690 return GetValueHelper(
this, name, valueType, pValue, &this->GetAbstractGroupParameters())
691 CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
696 this->AccessAbstractGroupParameters().AssignFrom(source);
697 AssignFromHelper(
this, source)
698 CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
701 virtual const Integer & GetPrivateExponent()
const =0;
702 virtual void SetPrivateExponent(
const Integer &x) =0;
710 pPrivateKey->MakePublicKey(*
this);
713 this->AccessAbstractGroupParameters().AssignFrom(source);
714 AssignFromHelper(
this, source)
715 CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
722 template <class PK, class GP, class O = OID>
726 typedef GP GroupParameters;
728 O GetAlgorithmID()
const {
return GetGroupParameters().GetAlgorithmID();}
734 {AccessGroupParameters().BERDecode(bt);
return true;}
736 {GetGroupParameters().DEREncode(bt);
return true;}
738 const GP & GetGroupParameters()
const {
return m_groupParameters;}
739 GP & AccessGroupParameters() {
return m_groupParameters;}
742 GP m_groupParameters;
753 typedef typename GP::Element Element;
758 bool pass = GetAbstractGroupParameters().Validate(rng, level);
760 const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
761 const Integer &x = GetPrivateExponent();
763 pass = pass && x.IsPositive() && x < q;
769 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
771 return GetValueHelper<DL_PrivateKey<Element> >(
this, name, valueType, pValue).Assignable();
776 AssignFromHelper<DL_PrivateKey<Element> >(
this, source);
782 this->AccessGroupParameters().GenerateRandom(rng, params);
787 SetPrivateExponent(x);
793 {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
796 {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
799 {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
806 const Integer & GetPrivateExponent()
const {
return m_x;}
807 void SetPrivateExponent(
const Integer &x) {m_x = x;}
820 template <
class BASE,
class SIGNATURE_SCHEME>
826 BASE::GenerateRandom(rng, params);
830 typename SIGNATURE_SCHEME::Signer signer(*
this);
831 typename SIGNATURE_SCHEME::Verifier verifier(signer);
832 SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
842 typedef typename GP::Element Element;
847 bool pass = GetAbstractGroupParameters().Validate(rng, level);
848 pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
852 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
854 return GetValueHelper<DL_PublicKey<Element> >(
this, name, valueType, pValue).Assignable();
859 AssignFromHelper<DL_PublicKey<Element> >(
this, source);
866 AccessAbstractGroupParameters().Precompute(precomputationStorage);
867 AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
872 AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
873 AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
878 GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
879 GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
892 {
return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
895 typename GP::BasePrecomputation m_ypc;
906 {
throw NotImplemented(
"DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");}
908 {
return params.GetSubgroupOrder().
ByteCount();}
910 {
return params.GetSubgroupOrder().
ByteCount();}
921 virtual Element AgreeWithStaticPrivateKey(
const DL_GroupParameters<Element> ¶ms,
const Element &publicElement,
bool validateOtherPublicKey,
const Integer &privateExponent)
const =0;
929 virtual bool ParameterSupported(
const char *name)
const {
return false;}
930 virtual void Derive(
const DL_GroupParameters<T> &groupParams, byte *derivedKey,
size_t derivedLength,
const T &agreedElement,
const T &ephemeralPublicKey,
const NameValuePairs &derivationParams)
const =0;
937 virtual bool ParameterSupported(
const char *name)
const {
return false;}
938 virtual size_t GetSymmetricKeyLength(
size_t plaintextLength)
const =0;
939 virtual size_t GetSymmetricCiphertextLength(
size_t plaintextLength)
const =0;
940 virtual size_t GetMaxSymmetricPlaintextLength(
size_t ciphertextLength)
const =0;
941 virtual void SymmetricEncrypt(
RandomNumberGenerator &rng,
const byte *key,
const byte *plaintext,
size_t plaintextLength, byte *ciphertext,
const NameValuePairs ¶meters)
const =0;
942 virtual DecodingResult SymmetricDecrypt(
const byte *key,
const byte *ciphertext,
size_t ciphertextLength, byte *plaintext,
const NameValuePairs ¶meters)
const =0;
950 typedef KI KeyInterface;
951 typedef typename KI::Element Element;
956 virtual KeyInterface & AccessKeyInterface() =0;
957 virtual const KeyInterface & GetKeyInterface()
const =0;
961 template <
class INTERFACE,
class KEY_INTERFACE>
965 size_t SignatureLength()
const
967 return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
968 + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
970 size_t MaxRecoverableLength()
const
971 {
return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
972 size_t MaxRecoverableLengthFromSignatureLength(
size_t signatureLength)
const
973 {assert(
false);
return 0;}
975 bool IsProbabilistic()
const
977 bool AllowNonrecoverablePart()
const
978 {
return GetMessageEncodingInterface().AllowNonrecoverablePart();}
979 bool RecoverablePartFirst()
const
980 {
return GetMessageEncodingInterface().RecoverablePartFirst();}
983 size_t MessageRepresentativeLength()
const {
return BitsToBytes(MessageRepresentativeBitLength());}
984 size_t MessageRepresentativeBitLength()
const {
return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
988 virtual HashIdentifier GetHashIdentifier()
const =0;
989 virtual size_t GetDigestSize()
const =0;
1004 r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1005 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1008 void InputRecoverableMessage(
PK_MessageAccumulator &messageAccumulator,
const byte *recoverableMessage,
size_t recoverableMessageLength)
const
1011 ma.m_recoverableMessage.
Assign(recoverableMessage, recoverableMessageLength);
1012 this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
1013 recoverableMessage, recoverableMessageLength,
1014 ma.m_presignature, ma.m_presignature.size(),
1015 ma.m_semisignature);
1020 this->GetMaterial().DoQuickSanityCheck();
1027 SecByteBlock representative(this->MessageRepresentativeLength());
1028 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1030 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1031 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1032 representative, this->MessageRepresentativeBitLength());
1034 Integer e(representative, representative.size());
1040 Integer k(rng, 1, params.GetSubgroupOrder()-1);
1042 r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1043 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1054 size_t rLen = alg.RLen(params);
1055 r.Encode(signature, rLen);
1056 s.Encode(signature+rLen, alg.SLen(params));
1059 RestartMessageAccumulator(rng, ma);
1061 return this->SignatureLength();
1092 size_t rLen = alg.RLen(params);
1093 ma.m_semisignature.
Assign(signature, rLen);
1094 ma.m_s.Decode(signature+rLen, alg.SLen(params));
1096 this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
1101 this->GetMaterial().DoQuickSanityCheck();
1108 SecByteBlock representative(this->MessageRepresentativeLength());
1109 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1110 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1111 representative, this->MessageRepresentativeBitLength());
1113 Integer e(representative, representative.size());
1115 Integer r(ma.m_semisignature, ma.m_semisignature.size());
1116 return alg.Verify(params, key, e, r, ma.m_s);
1121 this->GetMaterial().DoQuickSanityCheck();
1128 SecByteBlock representative(this->MessageRepresentativeLength());
1129 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1131 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1132 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1133 representative, this->MessageRepresentativeBitLength());
1135 Integer e(representative, representative.size());
1137 ma.m_presignature.
New(params.GetEncodedElementSize(
false));
1138 Integer r(ma.m_semisignature, ma.m_semisignature.size());
1139 alg.RecoverPresignature(params, key, r, ma.m_s).
Encode(ma.m_presignature, ma.m_presignature.size());
1141 return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
1142 ma.AccessHash(), this->GetHashIdentifier(),
1143 ma.m_presignature, ma.m_presignature.size(),
1144 ma.m_semisignature, ma.m_semisignature.size(),
1150 template <
class PK,
class KI>
1154 typedef typename DL_Base<KI>::Element Element;
1156 size_t MaxPlaintextLength(
size_t ciphertextLength)
const
1158 unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(
true);
1159 return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
1162 size_t CiphertextLength(
size_t plaintextLength)
const
1164 size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
1165 return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(
true) + len;
1168 bool ParameterSupported(
const char *name)
const
1169 {
return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
1194 Element q = params.DecodeElement(ciphertext,
true);
1195 size_t elementSize = params.GetEncodedElementSize(
true);
1196 ciphertext += elementSize;
1197 ciphertextLength -= elementSize;
1199 Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q,
true, key.GetPrivateExponent());
1201 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
1202 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1204 return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
1229 Element q = params.ExponentiateBase(x);
1230 params.EncodeElement(
true, q, ciphertext);
1231 unsigned int elementSize = params.GetEncodedElementSize(
true);
1232 ciphertext += elementSize;
1234 Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
1236 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
1237 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1239 encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
1244 template <
class T1,
class T2>
1247 typedef T1 AlgorithmInfo;
1248 typedef T2 GroupParameters;
1249 typedef typename GroupParameters::Element Element;
1253 template <
class T1,
class T2>
1257 typedef typename Keys::PrivateKey
PrivateKey;
1258 typedef typename Keys::PublicKey
PublicKey;
1262 template <
class T1,
class T2,
class T3,
class T4,
class T5>
1265 typedef T3 SignatureAlgorithm;
1266 typedef T4 MessageEncodingMethod;
1267 typedef T5 HashFunction;
1271 template <
class T1,
class T2,
class T3,
class T4,
class T5>
1275 typedef T4 KeyDerivationAlgorithm;
1276 typedef T5 SymmetricEncryptionAlgorithm;
1280 template <
class BASE,
class SCHEME_OPTIONS,
class KEY>
1284 typedef SCHEME_OPTIONS SchemeOptions;
1285 typedef typename KEY::Element Element;
1287 PrivateKey & AccessPrivateKey() {
return m_key;}
1288 PublicKey & AccessPublicKey() {
return m_key;}
1291 const KEY & GetKey()
const {
return m_key;}
1292 KEY & AccessKey() {
return m_key;}
1295 typename BASE::KeyInterface & AccessKeyInterface() {
return m_key;}
1296 const typename BASE::KeyInterface & GetKeyInterface()
const {
return m_key;}
1299 HashIdentifier GetHashIdentifier()
const
1301 typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
1302 return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
1304 size_t GetDigestSize()
const
1306 typedef CPP_TYPENAME SchemeOptions::HashFunction H;
1307 return H::DIGESTSIZE;
1315 template <
class BASE,
class SCHEME_OPTIONS,
class KEY>
1319 typedef typename KEY::Element Element;
1330 HashIdentifier GetHashIdentifier()
const
1331 {
return HashIdentifier();}
1337 template <
class SCHEME_OPTIONS>
1344 this->RestartMessageAccumulator(rng, *p);
1350 template <
class SCHEME_OPTIONS>
1361 template <
class SCHEME_OPTIONS>
1367 template <
class SCHEME_OPTIONS>
1381 CryptoParameters & AccessCryptoParameters() {
return AccessAbstractGroupParameters();}
1382 unsigned int AgreedValueLength()
const {
return GetAbstractGroupParameters().GetEncodedElementSize(
false);}
1383 unsigned int PrivateKeyLength()
const {
return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
1384 unsigned int PublicKeyLength()
const {
return GetAbstractGroupParameters().GetEncodedElementSize(
true);}
1396 Element y = params.ExponentiateBase(x);
1397 params.EncodeElement(
true, y, publicKey);
1400 bool Agree(byte *agreedValue,
const byte *privateKey,
const byte *otherPublicKey,
bool validateOtherPublicKey=
true)
const
1406 Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
1408 Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
1409 GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
1410 params.EncodeElement(
false, z, agreedValue);
1419 const Element &GetGenerator()
const {
return GetAbstractGroupParameters().GetSubgroupGenerator();}
1427 enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
1433 template <
class ELEMENT,
class COFACTOR_OPTION>
1437 typedef ELEMENT Element;
1439 static const char * CRYPTOPP_API StaticAlgorithmName()
1440 {
return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ?
"DHC" :
"DH";}
1444 return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
1445 COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
1448 Element AgreeWithStaticPrivateKey(
const DL_GroupParameters<Element> ¶ms,
const Element &publicElement,
bool validateOtherPublicKey,
const Integer &privateExponent)
const
1450 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
1452 const Integer &k = params.GetCofactor();
1453 return params.ExponentiateElement(publicElement,
1456 else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
1457 return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
1460 assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
1462 if (!validateOtherPublicKey)
1463 return params.ExponentiateElement(publicElement, privateExponent);
1465 if (params.FastSubgroupCheckAvailable())
1467 if (!params.ValidateElement(2, publicElement, NULL))
1469 return params.ExponentiateElement(publicElement, privateExponent);
1473 const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
1475 params.SimultaneousExponentiate(r, publicElement, e, 2);
1476 if (!params.IsIdentity(r[0]))
1487 template <
class BASE>
1494 {this->AccessKey().AssignFrom(key);}
1497 {this->AccessKey().BERDecode(bt);}
1500 {this->AccessKey().AssignFrom(algorithm.
GetMaterial());}
1503 {this->AccessKey().Initialize(v1);}
1505 #if (defined(_MSC_VER) && _MSC_VER < 1300)
1507 template <
class T1,
class T2>
1509 {this->AccessKey().Initialize(v1, v2);}
1511 template <
class T1,
class T2,
class T3>
1513 {this->AccessKey().Initialize(v1, v2, v3);}
1515 template <
class T1,
class T2,
class T3,
class T4>
1517 {this->AccessKey().Initialize(v1, v2, v3, v4);}
1519 template <
class T1,
class T2,
class T3,
class T4,
class T5>
1521 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1523 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
1525 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1527 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
1529 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1531 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8>
1532 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
1533 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1537 template <
class T1,
class T2>
1539 {this->AccessKey().Initialize(v1, v2);}
1541 template <
class T1,
class T2,
class T3>
1543 {this->AccessKey().Initialize(v1, v2, v3);}
1545 template <
class T1,
class T2,
class T3,
class T4>
1547 {this->AccessKey().Initialize(v1, v2, v3, v4);}
1549 template <
class T1,
class T2,
class T3,
class T4,
class T5>
1550 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5)
1551 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1553 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
1554 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6)
1555 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1557 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
1558 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6,
const T7 &v7)
1559 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1561 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8>
1562 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6,
const T7 &v7,
const T8 &v8)
1563 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1565 template <
class T1,
class T2>
1567 {this->AccessKey().Initialize(v1, v2);}
1569 template <
class T1,
class T2,
class T3>
1571 {this->AccessKey().Initialize(v1, v2, v3);}
1573 template <
class T1,
class T2,
class T3,
class T4>
1575 {this->AccessKey().Initialize(v1, v2, v3, v4);}
1577 template <
class T1,
class T2,
class T3,
class T4,
class T5>
1578 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5)
1579 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1581 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
1582 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6)
1583 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1585 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
1586 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6,
const T7 &v7)
1587 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1589 template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8>
1590 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6,
const T7 &v7,
const T8 &v8)
1591 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1602 template <
class STANDARD,
class KEYS,
class ALG_INFO>
1606 template <
class STANDARD,
class KEYS,
class ALG_INFO = TF_ES<STANDARD, KEYS,
int> >
1607 class TF_ES :
public KEYS
1609 typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
1616 static std::string CRYPTOPP_API StaticAlgorithmName() {
return std::string(KEYS::StaticAlgorithmName()) +
"/" + MessageEncodingMethod::StaticAlgorithmName();}
1624 template <
class STANDARD,
class H,
class KEYS,
class ALG_INFO>
1628 template <
class STANDARD,
class H,
class KEYS,
class ALG_INFO = TF_SS<STANDARD, H, KEYS,
int> >
1629 class TF_SS :
public KEYS
1634 typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
1637 static std::string CRYPTOPP_API StaticAlgorithmName() {
return std::string(KEYS::StaticAlgorithmName()) +
"/" + MessageEncodingMethod::StaticAlgorithmName() +
"(" + H::StaticAlgorithmName() +
")";}
1645 template <
class KEYS,
class SA,
class MEM,
class H,
class ALG_INFO>
1649 template <
class KEYS,
class SA,
class MEM,
class H,
class ALG_INFO = DL_SS<KEYS, SA, MEM, H,
int> >
1650 class DL_SS :
public KEYS
1655 static std::string StaticAlgorithmName() {
return SA::StaticAlgorithmName() + std::string(
"/EMSA1(") + H::StaticAlgorithmName() +
")";}
1664 template <
class KEYS,
class AA,
class DA,
class EA,
class ALG_INFO>
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
virtual const CryptoMaterial & GetMaterial() const =0
returns a const reference to the crypto material used by this object
bool GetThisObject(T &object) const
get a copy of this object or a subobject of it
PK_FinalTemplate< DL_DecryptorImpl< SchemeOptions > > Decryptor
implements PK_Decryptor interface
void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters=g_nullNameValuePairs) const
encrypt a byte string
bool SupportsPrecomputation() const
interface for asymmetric algorithms
DH key agreement algorithm.
static const Integer & One()
avoid calling constructors for these frequently used integers
Discrete Log Based Signature Scheme.
void AssignFrom(const NameValuePairs &source)
assign values from source to this object
PK_MessageAccumulator * NewVerificationAccumulator() const
create a new HashTransformation to accumulate the message to be verified
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters=g_nullNameValuePairs) const
decrypt a byte string, and return the length of plaintext
encodes/decodes privateKeyInfo
void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
interface for DL group parameters
static Integer Gcd(const Integer &a, const Integer &n)
greatest common divisor
interface for message encoding method for public key signature schemes
virtual unsigned int PrivateKeyLength() const =0
return length of private keys in this domain
message encoding method for public key encryption
interface for key derivation algorithms used in DL cryptosystems
PK_FinalTemplate< DL_SignerImpl< SchemeOptions > > Signer
implements PK_Signer interface
interface for DL private keys
virtual bool CanIncorporateEntropy() const
returns true if IncorporateEntropy is implemented
ring of congruence classes modulo n
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
sign and restart messageAccumulator
interface for random number generators
PK_FinalTemplate< TF_EncryptorImpl< SchemeOptions > > Encryptor
implements PK_Encryptor interface
void New(size_type newSize)
change size, without preserving contents
Discrete Log Based Encryption Scheme.
interface for private keys
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
recover a message from its signature
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
bool GetThisPointer(T *&p) const
get a pointer to this object, as a pointer to T
interface for DL public keys
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
generate private key
Base class for public key signature standard classes. These classes are used to select from variants ...
void Precompute(unsigned int precomputationStorage=16)
do precomputation
unsigned int PublicKeyLength() const
return length of public keys in this domain
unsigned int AgreedValueLength() const
return length of agreed value produced
interface for domains of simple key agreement protocols
bool FIPS_140_2_ComplianceEnabled()
returns whether FIPS 140-2 compliance features were enabled at compile time
used to return decoding results
PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
create a new HashTransformation to accumulate the message to be signed
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
retrieve previously saved precomputation
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
exception thrown by a class if a non-implemented method is called
bool SupportsPrecomputation() const
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
interface for Elgamal-like signature algorithms
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
derive agreed value from your private key and couterparty's public key, return false in case of failu...
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
check this object for errors
Base class for public key encryption standard classes. These classes are used to select from variants...
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
retrieve previously saved precomputation
multiple precision integer and basic arithmetics
void Assign(const T *t, size_type len)
set contents and size
void Precompute(unsigned int precomputationStorage=16)
do precomputation
const NameValuePairs & g_nullNameValuePairs
empty set of name-value pairs
unsigned int PrivateKeyLength() const
return length of private keys in this domain
void Precompute(unsigned int precomputationStorage=16)
do precomputation
PK_FinalTemplate< TF_DecryptorImpl< SchemeOptions > > Decryptor
implements PK_Decryptor interface
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
check this object for errors
PK_FinalTemplate< DL_EncryptorImpl< SchemeOptions > > Encryptor
implements PK_Encryptor interface
to be thrown by DecodeElement and AgreeWithStaticPrivateKey
RandomNumberGenerator & NullRNG()
returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it ...
STANDARD Standard
see EncryptionStandard for a list of standards
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const
encode in big-endian format
void Update(const byte *input, size_t length)
process more input
interface for accumulating messages to be signed or verified
interface for key agreement algorithms
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
void DEREncode(BufferedTransformation &bt) const
encode using Distinguished Encoding Rules, put result into a BufferedTransformation object ...
PK_FinalTemplate< TF_SignerImpl< SchemeOptions > > Signer
implements PK_Signer interface
void AssignFrom(const NameValuePairs &source)
assign values from source to this object
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
save precomputation for later use
PK_FinalTemplate< DL_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
generate public key
interface for crypto material, such as public and private keys, and crypto parameters ...
Trapdoor Function Based Signature Scheme.
PK_FinalTemplate< TF_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
interface for crypto prameters
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
save precomputation for later use
interface for public keys
Trapdoor Function Based Encryption Scheme.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
check this object for errors
interface for symmetric encryption algorithms used in DL cryptosystems
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
generate a random key or crypto parameters
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
save precomputation for later use
encodes/decodes subjectPublicKeyInfo
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
retrieve previously saved precomputation
bool SupportsPrecomputation() const
interface for DL key agreement algorithms
unsigned int ByteCount() const
number of significant bytes = ceiling(BitCount()/8)
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
input signature into a message accumulator
virtual void IncorporateEntropy(const byte *input, size_t length)
update RNG state with additional unpredictable values
STANDARD Standard
see SignatureStandard for a list of standards
interface for retrieving values given their names
A template implementing constructors for public key algorithm classes.