~ubuntu-branches/debian/squeeze/pycryptopp/squeeze

« back to all changes in this revision

Viewing changes to cryptopp/mqv.h

  • Committer: Bazaar Package Importer
  • Author(s): Zooko O'Whielacronx
  • Date: 2009-06-22 22:20:50 UTC
  • Revision ID: james.westby@ubuntu.com-20090622222050-hbqmn50dt2kvoz5o
Tags: upstream-0.5.14
ImportĀ upstreamĀ versionĀ 0.5.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef CRYPTOPP_MQV_H
 
2
#define CRYPTOPP_MQV_H
 
3
 
 
4
/** \file
 
5
*/
 
6
 
 
7
#include "gfpcrypt.h"
 
8
 
 
9
NAMESPACE_BEGIN(CryptoPP)
 
10
 
 
11
//! _
 
12
template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
 
13
class MQV_Domain : public AuthenticatedKeyAgreementDomain
 
14
{
 
15
public:
 
16
        typedef GROUP_PARAMETERS GroupParameters;
 
17
        typedef typename GroupParameters::Element Element;
 
18
        typedef MQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
 
19
 
 
20
        MQV_Domain() {}
 
21
 
 
22
        MQV_Domain(const GroupParameters &params)
 
23
                : m_groupParameters(params) {}
 
24
 
 
25
        MQV_Domain(BufferedTransformation &bt)
 
26
                {m_groupParameters.BERDecode(bt);}
 
27
 
 
28
        template <class T1, class T2>
 
29
        MQV_Domain(T1 v1, T2 v2)
 
30
                {m_groupParameters.Initialize(v1, v2);}
 
31
        
 
32
        template <class T1, class T2, class T3>
 
33
        MQV_Domain(T1 v1, T2 v2, T3 v3)
 
34
                {m_groupParameters.Initialize(v1, v2, v3);}
 
35
        
 
36
        template <class T1, class T2, class T3, class T4>
 
37
        MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
 
38
                {m_groupParameters.Initialize(v1, v2, v3, v4);}
 
39
 
 
40
        const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
 
41
        GroupParameters & AccessGroupParameters() {return m_groupParameters;}
 
42
 
 
43
        CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
 
44
 
 
45
        unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
 
46
        unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
 
47
        unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
 
48
 
 
49
        void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
 
50
        {
 
51
                Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
 
52
                x.Encode(privateKey, StaticPrivateKeyLength());
 
53
        }
 
54
 
 
55
        void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
 
56
        {
 
57
                const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
 
58
                Integer x(privateKey, StaticPrivateKeyLength());
 
59
                Element y = params.ExponentiateBase(x);
 
60
                params.EncodeElement(true, y, publicKey);
 
61
        }
 
62
 
 
63
        unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
 
64
        unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
 
65
 
 
66
        void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
 
67
        {
 
68
                const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
 
69
                Integer x(rng, Integer::One(), params.GetMaxExponent());
 
70
                x.Encode(privateKey, StaticPrivateKeyLength());
 
71
                Element y = params.ExponentiateBase(x);
 
72
                params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
 
73
        }
 
74
 
 
75
        void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
 
76
        {
 
77
                memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
 
78
        }
 
79
 
 
80
        bool Agree(byte *agreedValue,
 
81
                const byte *staticPrivateKey, const byte *ephemeralPrivateKey, 
 
82
                const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
 
83
                bool validateStaticOtherPublicKey=true) const
 
84
        {
 
85
                try
 
86
                {
 
87
                        const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
 
88
                        Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
 
89
                        Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
 
90
 
 
91
                        Integer s(staticPrivateKey, StaticPrivateKeyLength());
 
92
                        Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
 
93
                        Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
 
94
 
 
95
                        const Integer &r = params.GetSubgroupOrder();
 
96
                        Integer h2 = Integer::Power2((r.BitCount()+1)/2);
 
97
                        Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
 
98
                        Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
 
99
 
 
100
                        if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
 
101
                        {
 
102
                                Element P = params.ExponentiateElement(WW, tt);
 
103
                                P = m_groupParameters.MultiplyElements(P, VV);
 
104
                                Element R[2];
 
105
                                const Integer e2[2] = {r, e};
 
106
                                params.SimultaneousExponentiate(R, P, e2, 2);
 
107
                                if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
 
108
                                        return false;
 
109
                                params.EncodeElement(false, R[1], agreedValue);
 
110
                        }
 
111
                        else
 
112
                        {
 
113
                                const Integer &k = params.GetCofactor();
 
114
                                if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
 
115
                                        e = ModularArithmetic(r).Divide(e, k);
 
116
                                Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
 
117
                                if (params.IsIdentity(P))
 
118
                                        return false;
 
119
                                params.EncodeElement(false, P, agreedValue);
 
120
                        }
 
121
                }
 
122
                catch (DL_BadElement &)
 
123
                {
 
124
                        return false;
 
125
                }
 
126
                return true;
 
127
        }
 
128
 
 
129
private:
 
130
        DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
 
131
        const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
 
132
 
 
133
        GroupParameters m_groupParameters;
 
134
};
 
135
 
 
136
//! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
 
137
typedef MQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> MQV;
 
138
 
 
139
NAMESPACE_END
 
140
 
 
141
#endif