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 1523 : getCtx() 35 : { 36 : struct secp256k1Deleter { 37 24 : void operator()(secp256k1_context* b) { secp256k1_context_destroy(b); } 38 : }; 39 : static std::unique_ptr<secp256k1_context, secp256k1Deleter> 40 1523 : s_ctx(secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); 41 1523 : return s_ctx.get(); 42 : } 43 : 44 : } // namespace 45 : 46 : bool 47 0 : dev::SignatureStruct::isValid() const noexcept 48 : { 49 0 : static const h256 s_max {"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"}; 50 0 : static const h256 s_zero; 51 : 52 0 : return (v <= 1 && r > s_zero && s > s_zero && r < s_max && s < s_max); 53 : } 54 : 55 : Public 56 1523 : dev::toPublic(Secret const& _secret) 57 : { 58 1523 : auto* ctx = getCtx(); 59 : secp256k1_pubkey rawPubkey; 60 : // Creation will fail if the secret key is invalid. 61 1523 : if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.data())) 62 0 : return {}; 63 : std::array<uint8_t, 65> serializedPubkey; 64 1523 : size_t serializedPubkeySize = serializedPubkey.size(); 65 1523 : secp256k1_ec_pubkey_serialize(ctx, 66 : serializedPubkey.data(), 67 : &serializedPubkeySize, 68 : &rawPubkey, 69 : SECP256K1_EC_UNCOMPRESSED); 70 1523 : assert(serializedPubkeySize == serializedPubkey.size()); 71 : // Expect single byte header of value 0x04 -- uncompressed public key. 72 1523 : assert(serializedPubkey[0] == 0x04); 73 : // Create the Public skipping the header. 74 1523 : return Public {&serializedPubkey[1], Public::ConstructFromPointer}; 75 : } 76 : 77 : Address 78 1523 : dev::toAddress(Public const& _public) 79 : { 80 1523 : return right160(sha3(_public.ref())); 81 : } 82 : 83 : Address 84 0 : dev::toAddress(Secret const& _secret) 85 : { 86 0 : return toAddress(toPublic(_secret)); 87 : } 88 : 89 1523 : KeyPair::KeyPair(Secret const& _sec) 90 1523 : : m_secret(_sec) 91 1523 : , m_public(toPublic(_sec)) 92 : { 93 : // Assign address only if the secret key is valid. 94 1523 : if (m_public) 95 1523 : m_address = toAddress(m_public); 96 1523 : } 97 : 98 : KeyPair 99 739 : KeyPair::create() 100 : { 101 : while (true) { 102 739 : KeyPair keyPair(Secret::random()); 103 739 : if (keyPair.address()) 104 1478 : return keyPair; 105 739 : } 106 : }