Line data Source code
1 : /*
2 : This file is part of cpp-ethereum.
3 :
4 : cpp-ethereum is free software: you can redistribute it and/or modify
5 : it under the terms of the GNU General Public License as published by
6 : the Free Software Foundation, either version 3 of the License, or
7 : (at your option) any later version.
8 :
9 : cpp-ethereum is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : GNU General Public License for more details.
13 :
14 : You should have received a copy of the GNU General Public License
15 : along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 : /** @file Common.cpp
18 : * @author Alex Leverington <nessence@gmail.com>
19 : * @author Gav Wood <i@gavwood.com>
20 : * @date 2014
21 : */
22 :
23 : #include "Common.h"
24 : #include <secp256k1.h>
25 : #include <libdevcore/SHA3.h>
26 : #include <memory>
27 : using namespace std;
28 : using namespace dev;
29 : using namespace dev::crypto;
30 :
31 : namespace {
32 :
33 : secp256k1_context const*
34 1505 : getCtx()
35 : {
36 : struct secp256k1Deleter
37 : {
38 23 : void operator()(secp256k1_context* b) { secp256k1_context_destroy(b); }
39 : };
40 : static std::unique_ptr<secp256k1_context, secp256k1Deleter> s_ctx(
41 1505 : secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY));
42 1505 : return s_ctx.get();
43 : }
44 :
45 : } // namespace
46 :
47 : bool
48 0 : dev::SignatureStruct::isValid() const noexcept
49 : {
50 0 : static const h256 s_max {"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"};
51 0 : static const h256 s_zero;
52 :
53 0 : return (v <= 1 && r > s_zero && s > s_zero && r < s_max && s < s_max);
54 : }
55 :
56 : Public
57 1505 : dev::toPublic(Secret const& _secret)
58 : {
59 1505 : auto* ctx = getCtx();
60 : secp256k1_pubkey rawPubkey;
61 : // Creation will fail if the secret key is invalid.
62 1505 : if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.data()))
63 0 : return {};
64 : std::array<uint8_t, 65> serializedPubkey;
65 1505 : size_t serializedPubkeySize = serializedPubkey.size();
66 1505 : secp256k1_ec_pubkey_serialize(ctx,
67 : serializedPubkey.data(),
68 : &serializedPubkeySize,
69 : &rawPubkey,
70 : SECP256K1_EC_UNCOMPRESSED);
71 1505 : assert(serializedPubkeySize == serializedPubkey.size());
72 : // Expect single byte header of value 0x04 -- uncompressed public key.
73 1505 : assert(serializedPubkey[0] == 0x04);
74 : // Create the Public skipping the header.
75 1505 : return Public {&serializedPubkey[1], Public::ConstructFromPointer};
76 : }
77 :
78 : Address
79 1505 : dev::toAddress(Public const& _public)
80 : {
81 1505 : return right160(sha3(_public.ref()));
82 : }
83 :
84 : Address
85 0 : dev::toAddress(Secret const& _secret)
86 : {
87 0 : return toAddress(toPublic(_secret));
88 : }
89 :
90 1505 : KeyPair::KeyPair(Secret const& _sec)
91 1505 : : m_secret(_sec)
92 1505 : , m_public(toPublic(_sec))
93 : {
94 : // Assign address only if the secret key is valid.
95 1505 : if (m_public)
96 1505 : m_address = toAddress(m_public);
97 1505 : }
98 :
99 : KeyPair
100 729 : KeyPair::create()
101 : {
102 : while (true) {
103 729 : KeyPair keyPair(Secret::random());
104 729 : if (keyPair.address())
105 1458 : return keyPair;
106 729 : }
107 : }
|