Botan  2.1.0
Crypto and TLS for C++11
ec_group.cpp
Go to the documentation of this file.
1 /*
2 * ECC Domain Parameters
3 *
4 * (C) 2007 Falko Strenzke, FlexSecure GmbH
5 * 2008 Jack Lloyd
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9 
10 #include <botan/ec_group.h>
11 #include <botan/ber_dec.h>
12 #include <botan/der_enc.h>
13 #include <botan/oids.h>
14 #include <botan/pem.h>
15 #include <botan/reducer.h>
16 
17 namespace Botan {
18 
19 EC_Group::EC_Group(const OID& domain_oid)
20  {
21  const std::string pem = PEM_for_named_group(OIDS::lookup(domain_oid));
22 
23  if(pem == "")
24  throw Lookup_Error("No ECC domain data for " + domain_oid.as_string());
25 
26  *this = EC_Group(pem);
27  m_oid = domain_oid.as_string();
28  }
29 
30 EC_Group::EC_Group(const std::string& str)
31  {
32  if(str == "")
33  return; // no initialization / uninitialized
34 
35  try
36  {
37  std::vector<uint8_t> ber =
38  unlock(PEM_Code::decode_check_label(str, "EC PARAMETERS"));
39 
40  *this = EC_Group(ber);
41  }
42  catch(Decoding_Error) // hmm, not PEM?
43  {
44  *this = EC_Group(OIDS::lookup(str));
45  }
46  }
47 
48 EC_Group::EC_Group(const std::vector<uint8_t>& ber_data)
49  {
50  BER_Decoder ber(ber_data);
51  BER_Object obj = ber.get_next_object();
52 
53  if(obj.type_tag == NULL_TAG)
54  throw Decoding_Error("Cannot handle ImplicitCA ECDSA parameters");
55  else if(obj.type_tag == OBJECT_ID)
56  {
57  OID dom_par_oid;
58  BER_Decoder(ber_data).decode(dom_par_oid);
59  *this = EC_Group(dom_par_oid);
60  }
61  else if(obj.type_tag == SEQUENCE)
62  {
63  BigInt p, a, b;
64  std::vector<uint8_t> sv_base_point;
65 
66  BER_Decoder(ber_data)
68  .decode_and_check<size_t>(1, "Unknown ECC param version code")
69  .start_cons(SEQUENCE)
70  .decode_and_check(OID("1.2.840.10045.1.1"),
71  "Only prime ECC fields supported")
72  .decode(p)
73  .end_cons()
77  .end_cons()
78  .decode(sv_base_point, OCTET_STRING)
79  .decode(m_order)
80  .decode(m_cofactor)
81  .end_cons()
82  .verify_end();
83 
84  m_curve = CurveGFp(p, a, b);
85  m_base_point = OS2ECP(sv_base_point, m_curve);
86  }
87  else
88  throw Decoding_Error("Unexpected tag while decoding ECC domain params");
89  }
90 
91 std::vector<uint8_t>
93  {
94  if(form == EC_DOMPAR_ENC_EXPLICIT)
95  {
96  const size_t ecpVers1 = 1;
97  OID curve_type("1.2.840.10045.1.1");
98 
99  const size_t p_bytes = m_curve.get_p().bytes();
100 
101  return DER_Encoder()
103  .encode(ecpVers1)
105  .encode(curve_type)
106  .encode(m_curve.get_p())
107  .end_cons()
109  .encode(BigInt::encode_1363(m_curve.get_a(), p_bytes),
110  OCTET_STRING)
111  .encode(BigInt::encode_1363(m_curve.get_b(), p_bytes),
112  OCTET_STRING)
113  .end_cons()
115  .encode(m_order)
116  .encode(m_cofactor)
117  .end_cons()
119  }
120  else if(form == EC_DOMPAR_ENC_OID)
122  else if(form == EC_DOMPAR_ENC_IMPLICITCA)
124  else
125  throw Internal_Error("EC_Group::DER_encode: Unknown encoding");
126  }
127 
128 std::string EC_Group::PEM_encode() const
129  {
130  const std::vector<uint8_t> der = DER_encode(EC_DOMPAR_ENC_EXPLICIT);
131  return PEM_Code::encode(der, "EC PARAMETERS");
132  }
133 
135  bool) const
136  {
137  //compute the discriminant
138  Modular_Reducer p(m_curve.get_p());
139  BigInt discriminant = p.multiply(4, m_curve.get_a());
140  discriminant += p.multiply(27, m_curve.get_b());
141  discriminant = p.reduce(discriminant);
142  //check the discriminant
143  if(discriminant == 0)
144  {
145  return false;
146  }
147  //check for valid cofactor
148  if(m_cofactor < 1)
149  {
150  return false;
151  }
152  //check if the base point is on the curve
153  if(!m_base_point.on_the_curve())
154  {
155  return false;
156  }
157  if((m_base_point * m_cofactor).is_zero())
158  {
159  return false;
160  }
161  //check if order is prime
162  if(!is_prime(m_order, rng, 128))
163  {
164  return false;
165  }
166  //check if order of the base point is correct
167  if(!(m_base_point * m_order).is_zero())
168  {
169  return false;
170  }
171  return true;
172  }
173 
174 }
const BigInt & get_a() const
Definition: curve_gfp.h:80
std::string get_oid() const
Definition: ec_group.h:115
std::vector< uint8_t > get_contents_unlocked()
Definition: der_enc.h:27
secure_vector< uint8_t > EC2OSP(const PointGFp &point, uint8_t format)
Definition: point_gfp.cpp:470
const BigInt & get_b() const
Definition: curve_gfp.h:85
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
BER_Decoder & decode_and_check(const T &expected, const std::string &error_msg)
Definition: ber_dec.h:146
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition: numthry.cpp:441
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:376
BER_Decoder & decode_octet_string_bigint(class BigInt &b)
Definition: ber_dec.cpp:397
DER_Encoder & end_cons()
Definition: der_enc.cpp:147
static std::string PEM_for_named_group(const std::string &name)
Definition: ec_named.cpp:13
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:216
BER_Decoder & end_cons()
Definition: ber_dec.cpp:272
std::string lookup(const OID &oid)
Definition: oids.cpp:18
std::string PEM_encode() const
Definition: ec_group.cpp:128
PointGFp OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
Definition: point_gfp.cpp:544
DER_Encoder & encode_null()
Definition: der_enc.cpp:208
std::vector< uint8_t > DER_encode(EC_Group_Encoding form) const
Definition: ec_group.cpp:92
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:258
EC_Group(const CurveGFp &curve, const PointGFp &base_point, const BigInt &order, const BigInt &cofactor)
Definition: ec_group.h:42
Definition: alg_id.cpp:13
BER_Object get_next_object()
Definition: ber_dec.cpp:210
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
EC_Group_Encoding
Definition: ec_group.h:22
const BigInt & get_p() const
Definition: curve_gfp.h:91
secure_vector< uint8_t > decode_check_label(DataSource &source, const std::string &label_want)
Definition: pem.cpp:54
ASN1_Tag type_tag
Definition: asn1_obj.h:91
BER_Decoder & verify_end()
Definition: ber_dec.cpp:168
bool on_the_curve() const
Definition: point_gfp.cpp:414
std::string as_string() const
Definition: asn1_oid.cpp:50
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:137
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:82
bool verify_group(RandomNumberGenerator &rng, bool strong=false) const
Definition: ec_group.cpp:134
size_t bytes() const
Definition: bigint.cpp:176