source: trunk/src-cryptopp/mqv.h

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

Add cryptopp from tag CRYPTOPP_5_6_5

  • Property mode set to 100644
File size: 9.6 KB
Line 
1// mqv.h - written and placed in the public domain by Wei Dai
2
3//! \file mqv.h
4//! \brief Classes for Menezes–Qu–Vanstone (MQV) key agreement
5
6#ifndef CRYPTOPP_MQV_H
7#define CRYPTOPP_MQV_H
8
9#include "cryptlib.h"
10#include "gfpcrypt.h"
11#include "modarith.h"
12#include "integer.h"
13#include "algebra.h"
14#include "misc.h"
15
16NAMESPACE_BEGIN(CryptoPP)
17
18//! \class MQV_Domain
19//! \brief MQV domain for performing authenticated key agreement
20//! \tparam GROUP_PARAMETERS doamin parameters
21//! \tparam COFACTOR_OPTION cofactor option
22//! \details GROUP_PARAMETERS paramters include the curve coefcients and the base point.
23//!   Binary curves use a polynomial to represent its characteristic, while prime curves
24//!   use a prime number.
25//! \sa MQV, HMQV, FHMQV, and AuthenticatedKeyAgreementDomain
26template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
27class MQV_Domain : public AuthenticatedKeyAgreementDomain
28{
29public:
30        typedef GROUP_PARAMETERS GroupParameters;
31        typedef typename GroupParameters::Element Element;
32        typedef MQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
33
34        //! \brief Construct a MQV domain
35        MQV_Domain() {}
36
37        //! \brief Construct a MQV domain
38        //! \param params group parameters and options
39        MQV_Domain(const GroupParameters &params)
40                : m_groupParameters(params) {}
41
42        //! \brief Construct a MQV domain
43        //! \param bt BufferedTransformation with group parameters and options
44        MQV_Domain(BufferedTransformation &bt)
45                {m_groupParameters.BERDecode(bt);}
46
47        //! \brief Construct a MQV domain
48        //! \tparam T1 template parameter used as a constructor parameter
49        //! \tparam T2 template parameter used as a constructor parameter
50        //! \param v1 first parameter
51        //! \param v2 second parameter
52        //! \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
53        template <class T1, class T2>
54        MQV_Domain(T1 v1, T2 v2)
55                {m_groupParameters.Initialize(v1, v2);}
56
57        //! \brief Construct a MQV domain
58        //! \tparam T1 template parameter used as a constructor parameter
59        //! \tparam T2 template parameter used as a constructor parameter
60        //! \tparam T3 template parameter used as a constructor parameter
61        //! \param v1 first parameter
62        //! \param v2 second parameter
63        //! \param v3 third parameter
64        //! \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
65        template <class T1, class T2, class T3>
66        MQV_Domain(T1 v1, T2 v2, T3 v3)
67                {m_groupParameters.Initialize(v1, v2, v3);}
68
69        //! \brief Construct a MQV domain
70        //! \tparam T1 template parameter used as a constructor parameter
71        //! \tparam T2 template parameter used as a constructor parameter
72        //! \tparam T3 template parameter used as a constructor parameter
73        //! \tparam T4 template parameter used as a constructor parameter
74        //! \param v1 first parameter
75        //! \param v2 second parameter
76        //! \param v3 third parameter
77        //! \param v4 third parameter
78        //! \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
79        template <class T1, class T2, class T3, class T4>
80        MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
81                {m_groupParameters.Initialize(v1, v2, v3, v4);}
82
83        //! \brief Retrieves the group parameters for this domain
84        //! \return the group parameters for this domain as a const reference
85        const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
86
87        //! \brief Retrieves the group parameters for this domain
88        //! \return the group parameters for this domain as a non-const reference
89        GroupParameters & AccessGroupParameters() {return m_groupParameters;}
90
91        //! \brief Retrieves the crypto parameters for this domain
92        //! \return the crypto parameters for this domain as a non-const reference
93        CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
94
95        //! \brief Provides the size of the agreed value
96        //! \return size of agreed value produced  in this domain
97        //! \details The length is calculated using <tt>GetEncodedElementSize(false)</tt>, which means the
98        //!   element is encoded in a non-reversible format. A non-reversible format means its a raw byte array,
99        //!   and it lacks presentation format like an ASN.1 BIT_STRING or OCTET_STRING.
100        unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
101
102        //! \brief Provides the size of the static private key
103        //! \return size of static private keys in this domain
104        //! \details The length is calculated using the byte count of the subgroup order.
105        unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
106
107        //! \brief Provides the size of the static public key
108        //! \return size of static public keys in this domain
109        //! \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>, which means the
110        //!   element is encoded in a reversible format. A reversible format means it has a presentation format,
111        //!   and its an ANS.1 encoded element or point.
112        unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
113
114        //! \brief Generate static private key in this domain
115        //! \param rng a RandomNumberGenerator derived class
116        //! \param privateKey a byte buffer for the generated private key in this domain
117        //! \details The private key is a random scalar used as an exponent in the range <tt>[1,MaxExponent()]</tt>.
118        //! \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
119        void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
120        {
121                Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
122                x.Encode(privateKey, StaticPrivateKeyLength());
123        }
124
125        //! \brief Generate a static public key from a private key in this domain
126        //! \param rng a RandomNumberGenerator derived class
127        //! \param privateKey a byte buffer with the previously generated private key
128        //! \param publicKey a byte buffer for the generated public key in this domain
129        //! \details The public key is an element or point on the curve, and its stored in a revrsible format.
130        //!    A reversible format means it has a presentation format, and its an ANS.1 encoded element or point.
131        //! \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
132        void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
133        {
134                CRYPTOPP_UNUSED(rng);
135                const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
136                Integer x(privateKey, StaticPrivateKeyLength());
137                Element y = params.ExponentiateBase(x);
138                params.EncodeElement(true, y, publicKey);
139        }
140
141        unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
142        unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
143
144        void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
145        {
146                const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
147                Integer x(rng, Integer::One(), params.GetMaxExponent());
148                x.Encode(privateKey, StaticPrivateKeyLength());
149                Element y = params.ExponentiateBase(x);
150                params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
151        }
152
153        void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
154        {
155                CRYPTOPP_UNUSED(rng);
156                memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
157        }
158
159        bool Agree(byte *agreedValue,
160                const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
161                const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
162                bool validateStaticOtherPublicKey=true) const
163        {
164                try
165                {
166                        const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
167                        Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
168                        Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
169
170                        Integer s(staticPrivateKey, StaticPrivateKeyLength());
171                        Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
172                        Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
173
174                        const Integer &r = params.GetSubgroupOrder();
175                        Integer h2 = Integer::Power2((r.BitCount()+1)/2);
176                        Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
177                        Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
178
179                        if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
180                        {
181                                Element P = params.ExponentiateElement(WW, tt);
182                                P = m_groupParameters.MultiplyElements(P, VV);
183                                Element R[2];
184                                const Integer e2[2] = {r, e};
185                                params.SimultaneousExponentiate(R, P, e2, 2);
186                                if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
187                                        return false;
188                                params.EncodeElement(false, R[1], agreedValue);
189                        }
190                        else
191                        {
192                                const Integer &k = params.GetCofactor();
193                                if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
194                                        e = ModularArithmetic(r).Divide(e, k);
195                                Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
196                                if (params.IsIdentity(P))
197                                        return false;
198                                params.EncodeElement(false, P, agreedValue);
199                        }
200                }
201                catch (DL_BadElement &)
202                {
203                        return false;
204                }
205                return true;
206        }
207
208private:
209        DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
210        const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
211
212        GroupParameters m_groupParameters;
213};
214
215//! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
216//! \sa MQV, HMQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
217typedef MQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> MQV;
218
219NAMESPACE_END
220
221#endif
Note: See TracBrowser for help on using the repository browser.