aboutsummaryrefslogtreecommitdiffstats
path: root/src/pubkey/eckaeg/eckaeg.cpp
blob: 424715ad8072377175176bbb2edd19b12f8fd197 (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
/*************************************************
* ECKAEG implemenation                           *
* (C) 2007 Manuel Hartl, FlexSecure GmbH         *
*     2007 Falko Strenzke, FlexSecure GmbH       *
*     2008 Jack Lloyd                            *
*************************************************/

#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;
   }

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

   const EC_PublicKey * p_ec_pk = dynamic_cast<const EC_PublicKey*>(&key);
   if(!p_ec_pk)
      {
      throw Invalid_Argument("ECKAEG_PrivateKey::derive_key(): argument must be an EC_PublicKey");
      }
   p_ec_pk->affirm_init();
   return m_eckaeg_core.agree ( p_ec_pk->public_point() );
   }

}