summaryrefslogtreecommitdiffstats
path: root/botan/src/pubkey/eckaeg/eckaeg.cpp
blob: b8ff75d89fa26464142e845d2d3ebb1fa9d87b50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* ECKAEG implemenation
* (C) 2007 Manuel Hartl, FlexSecure GmbH
*     2007 Falko Strenzke, FlexSecure GmbH
*     2008 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/eckaeg.h>
#include <botan/numthry.h>
#include <botan/util.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/secmem.h>
#include <botan/point_gfp.h>

namespace Botan {

/*********************************
* ECKAEG_PublicKey
*********************************/

void ECKAEG_PublicKey::affirm_init() const // virtual
   {
   EC_PublicKey::affirm_init();
   }

void ECKAEG_PublicKey::set_all_values(ECKAEG_PublicKey const& other)
   {
   m_param_enc = other.m_param_enc;
   m_eckaeg_core = other.m_eckaeg_core;
   m_enc_public_point = other.m_enc_public_point;
   if(other.mp_dom_pars.get())
      {
      mp_dom_pars.reset(new EC_Domain_Params(*(other.mp_dom_pars)));
      }
   if(other.mp_public_point.get())
      {
      mp_public_point.reset(new PointGFp(*(other.mp_public_point)));
      }
   }

ECKAEG_PublicKey::ECKAEG_PublicKey(ECKAEG_PublicKey const& other)
   : Public_Key(),
     EC_PublicKey()
   {
   set_all_values(other);
   }

ECKAEG_PublicKey const& ECKAEG_PublicKey::operator=(ECKAEG_PublicKey const& rhs)
   {
   set_all_values(rhs);
   return *this;
   }

void ECKAEG_PublicKey::X509_load_hook()
   {
   EC_PublicKey::X509_load_hook();
   EC_PublicKey::affirm_init();
   m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, BigInt(0), *mp_public_point);
   }

ECKAEG_PublicKey::ECKAEG_PublicKey(EC_Domain_Params const& dom_par, PointGFp const& public_point)
   {
   mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par));
   mp_public_point = std::auto_ptr<PointGFp>(new PointGFp(public_point));
   if(mp_public_point->get_curve() != mp_dom_pars->get_curve())
      {
      throw Invalid_Argument("ECKAEG_PublicKey(): curve of arg. point and curve of arg. domain parameters are different");
      }
   EC_PublicKey::affirm_init();
   m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, BigInt(0), *mp_public_point);
   }

/*********************************
* ECKAEG_PrivateKey
*********************************/
void ECKAEG_PrivateKey::affirm_init() const // virtual
   {
   EC_PrivateKey::affirm_init();
   }

void ECKAEG_PrivateKey::PKCS8_load_hook(bool generated)
   {
   EC_PrivateKey::PKCS8_load_hook(generated);
   EC_PrivateKey::affirm_init();
   m_eckaeg_core = ECKAEG_Core(*mp_dom_pars, m_private_value, *mp_public_point);
   }

void ECKAEG_PrivateKey::set_all_values(ECKAEG_PrivateKey const& other)
   {
   m_private_value = other.m_private_value;
   m_param_enc = other.m_param_enc;
   m_eckaeg_core = other.m_eckaeg_core;
   m_enc_public_point = other.m_enc_public_point;
   if(other.mp_dom_pars.get())
      {
      mp_dom_pars.reset(new EC_Domain_Params(*(other.mp_dom_pars)));
      }
   if(other.mp_public_point.get())
      {
      mp_public_point.reset(new PointGFp(*(other.mp_public_point)));
      }
   }

ECKAEG_PrivateKey::ECKAEG_PrivateKey(ECKAEG_PrivateKey const& other)
   : Public_Key(),
     EC_PublicKey(),
     Private_Key(),
     ECKAEG_PublicKey(),
     EC_PrivateKey(),
     PK_Key_Agreement_Key()
   {
   set_all_values(other);
   }

ECKAEG_PrivateKey const& ECKAEG_PrivateKey::operator= (ECKAEG_PrivateKey const& rhs)
   {
   set_all_values(rhs);
   return *this;
   }

MemoryVector<byte> ECKAEG_PrivateKey::public_value() const
   {
   return EC2OSP(public_point(), PointGFp::UNCOMPRESSED);
   }

/**
* Derive a key
*/
SecureVector<byte> ECKAEG_PrivateKey::derive_key(const byte key[],
                                                 u32bit key_len) const
   {
   MemoryVector<byte> key_x(key, key_len); // FIXME: nasty/slow
   PointGFp point = OS2ECP(key_x, public_point().get_curve());

   return m_eckaeg_core.agree(point);
   }

/**
* Derive a key
*/
SecureVector<byte> ECKAEG_PrivateKey::derive_key(const ECKAEG_PublicKey& key) const
   {
   affirm_init();
   key.affirm_init();

   return m_eckaeg_core.agree(key.public_point());
   }

}