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;
359 typedef typename Keys::PrivateKey PrivateKey;
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);
828 if (FIPS_140_2_ComplianceEnabled())
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>
1274 typedef T3 KeyAgreementAlgorithm;
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>