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 1503 : 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 1503 : secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); 42 1503 : 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 1503 : dev::toPublic(Secret const& _secret) 58 : { 59 1503 : auto* ctx = getCtx(); 60 : secp256k1_pubkey rawPubkey; 61 : // Creation will fail if the secret key is invalid. 62 1503 : if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.data())) 63 0 : return {}; 64 : std::array<uint8_t, 65> serializedPubkey; 65 1503 : size_t serializedPubkeySize = serializedPubkey.size(); 66 1503 : secp256k1_ec_pubkey_serialize(ctx, 67 : serializedPubkey.data(), 68 : &serializedPubkeySize, 69 : &rawPubkey, 70 : SECP256K1_EC_UNCOMPRESSED); 71 1503 : assert(serializedPubkeySize == serializedPubkey.size()); 72 : // Expect single byte header of value 0x04 -- uncompressed public key. 73 1503 : assert(serializedPubkey[0] == 0x04); 74 : // Create the Public skipping the header. 75 1503 : return Public {&serializedPubkey[1], Public::ConstructFromPointer}; 76 : } 77 : 78 : Address 79 1503 : dev::toAddress(Public const& _public) 80 : { 81 1503 : 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 1503 : KeyPair::KeyPair(Secret const& _sec) 91 1503 : : m_secret(_sec) 92 1503 : , m_public(toPublic(_sec)) 93 : { 94 : // Assign address only if the secret key is valid. 95 1503 : if (m_public) 96 1503 : m_address = toAddress(m_public); 97 1503 : } 98 : 99 : KeyPair 100 728 : KeyPair::create() 101 : { 102 : while (true) { 103 728 : KeyPair keyPair(Secret::random()); 104 728 : if (keyPair.address()) 105 1456 : return keyPair; 106 728 : } 107 : }