00001
#ifndef CRYPTOPP_MQV_H
00002
#define CRYPTOPP_MQV_H
00003
00004
00005
00006
00007
#include "gfpcrypt.h"
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010
00011
00012 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
00013 class
MQV_Domain : public
AuthenticatedKeyAgreementDomain
00014 {
00015
public:
00016
typedef GROUP_PARAMETERS GroupParameters;
00017
typedef typename GroupParameters::Element Element;
00018
typedef MQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
00019
00020
MQV_Domain() {}
00021
00022
MQV_Domain(
const GroupParameters ¶ms)
00023 : m_groupParameters(params) {}
00024
00025
MQV_Domain(
BufferedTransformation &bt)
00026 {m_groupParameters.BERDecode(bt);}
00027
00028
template <
class T1,
class T2>
00029
MQV_Domain(T1 v1, T2 v2)
00030 {m_groupParameters.Initialize(v1, v2);}
00031
00032
template <
class T1,
class T2,
class T3>
00033
MQV_Domain(T1 v1, T2 v2, T3 v3)
00034 {m_groupParameters.Initialize(v1, v2, v3);}
00035
00036
template <
class T1,
class T2,
class T3,
class T4>
00037
MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
00038 {m_groupParameters.Initialize(v1, v2, v3, v4);}
00039
00040
const GroupParameters & GetGroupParameters()
const {
return m_groupParameters;}
00041 GroupParameters & AccessGroupParameters() {
return m_groupParameters;}
00042
00043
CryptoParameters & AccessCryptoParameters() {
return AccessAbstractGroupParameters();}
00044
00045 unsigned int AgreedValueLength()
const {
return GetAbstractGroupParameters().GetEncodedElementSize(
false);}
00046 unsigned int StaticPrivateKeyLength()
const {
return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
00047 unsigned int StaticPublicKeyLength()
const {
return GetAbstractGroupParameters().GetEncodedElementSize(
true);}
00048
00049 void GenerateStaticPrivateKey(
RandomNumberGenerator &rng, byte *privateKey)
const
00050
{
00051
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
00052 x.Encode(privateKey, StaticPrivateKeyLength());
00053 }
00054
00055 void GenerateStaticPublicKey(
RandomNumberGenerator &rng,
const byte *privateKey, byte *publicKey)
const
00056
{
00057
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
00058
Integer x(privateKey, StaticPrivateKeyLength());
00059 Element y = params.
ExponentiateBase(x);
00060 params.
EncodeElement(
true, y, publicKey);
00061 }
00062
00063 unsigned int EphemeralPrivateKeyLength()
const {
return StaticPrivateKeyLength() + StaticPublicKeyLength();}
00064 unsigned int EphemeralPublicKeyLength()
const {
return StaticPublicKeyLength();}
00065
00066 void GenerateEphemeralPrivateKey(
RandomNumberGenerator &rng, byte *privateKey)
const
00067
{
00068
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
00069
Integer x(rng, Integer::One(), params.
GetMaxExponent());
00070 x.Encode(privateKey, StaticPrivateKeyLength());
00071 Element y = params.
ExponentiateBase(x);
00072 params.
EncodeElement(
true, y, privateKey+StaticPrivateKeyLength());
00073 }
00074
00075 void GenerateEphemeralPublicKey(
RandomNumberGenerator &rng,
const byte *privateKey, byte *publicKey)
const
00076
{
00077 memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
00078 }
00079
00080 bool Agree(byte *agreedValue,
00081
const byte *staticPrivateKey,
const byte *ephemeralPrivateKey,
00082
const byte *staticOtherPublicKey,
const byte *ephemeralOtherPublicKey,
00083
bool validateStaticOtherPublicKey=
true)
const
00084
{
00085
try
00086 {
00087
const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters();
00088 Element WW = params.
DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
00089 Element VV = params.
DecodeElement(ephemeralOtherPublicKey,
true);
00090
00091
Integer s(staticPrivateKey, StaticPrivateKeyLength());
00092
Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
00093 Element V = params.
DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(),
false);
00094
00095
const Integer &r = params.
GetSubgroupOrder();
00096
Integer h2 = Integer::Power2((r.
BitCount()+1)/2);
00097
Integer e = ((h2+params.
ConvertElementToInteger(V)%h2)*s+u) % r;
00098
Integer tt = h2 + params.
ConvertElementToInteger(VV) % h2;
00099
00100
if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
00101 {
00102 Element P = params.
ExponentiateElement(WW, tt);
00103 P = m_groupParameters.MultiplyElements(P, VV);
00104 Element R[2];
00105
const Integer e2[2] = {r, e};
00106 params.
SimultaneousExponentiate(R, P, e2, 2);
00107
if (!params.
IsIdentity(R[0]) || params.
IsIdentity(R[1]))
00108
return false;
00109 params.
EncodeElement(
false, R[1], agreedValue);
00110 }
00111
else
00112 {
00113
const Integer &k = params.
GetCofactor();
00114
if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
00115 e =
ModularArithmetic(r).Divide(e, k);
00116 Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
00117
if (params.
IsIdentity(P))
00118
return false;
00119 params.
EncodeElement(
false, P, agreedValue);
00120 }
00121 }
00122
catch (DL_BadElement &)
00123 {
00124
return false;
00125 }
00126
return true;
00127 }
00128
00129
private:
00130
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {
return m_groupParameters;}
00131
const DL_GroupParameters<Element> & GetAbstractGroupParameters()
const {
return m_groupParameters;}
00132
00133 GroupParameters m_groupParameters;
00134 };
00135
00136
00137 typedef MQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> MQV;
00138
00139 NAMESPACE_END
00140
00141
#endif