Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/releaseWindowsTestOne
  • release/windowsReleaseTest
  • release/releaseTest
  • release/releaseWindowsTest
  • release/201910
  • release/qt/201910
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • 4.0.0
  • 2.2.0
  • 2.1.0
  • 2.0.1
  • 2.0.0
  • 1.4.1
  • 1.4.0
  • 1.3.0
  • 1.2.0
  • 1.1.0
30 results

Common.cpp

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Common.cpp 3.52 KiB
    /*
        This file is part of cpp-ethereum.
    
        cpp-ethereum is free software: you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.
    
        cpp-ethereum is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
    
        You should have received a copy of the GNU General Public License
        along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
    */
    /** @file Common.cpp
     * @author Alex Leverington <nessence@gmail.com>
     * @author Gav Wood <i@gavwood.com>
     * @date 2014
     */
    
    #include "Common.h"
    #include <secp256k1.h>
    #include <libdevcore/SHA3.h>
    #include <memory>
    using namespace std;
    using namespace dev;
    using namespace dev::crypto;
    
    namespace {
    
    secp256k1_context const*
    getCtx()
    {
        struct secp256k1Deleter {
            void operator()(secp256k1_context* b) { secp256k1_context_destroy(b); }
        };
        static std::unique_ptr<secp256k1_context, secp256k1Deleter>
            s_ctx(secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY));
        return s_ctx.get();
    }
    
    } // namespace
    
    bool
    dev::SignatureStruct::isValid() const noexcept
    {
        static const h256 s_max {"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"};
        static const h256 s_zero;
    
        return (v <= 1 && r > s_zero && s > s_zero && r < s_max && s < s_max);
    }
    
    Public
    dev::toPublic(Secret const& _secret)
    {
        auto* ctx = getCtx();
        secp256k1_pubkey rawPubkey;
        // Creation will fail if the secret key is invalid.
        if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.data()))
            return {};
        std::array<uint8_t, 65> serializedPubkey;
        size_t serializedPubkeySize = serializedPubkey.size();
        secp256k1_ec_pubkey_serialize(ctx,
                                      serializedPubkey.data(),
                                      &serializedPubkeySize,
                                      &rawPubkey,
                                      SECP256K1_EC_UNCOMPRESSED);
        assert(serializedPubkeySize == serializedPubkey.size());
        // Expect single byte header of value 0x04 -- uncompressed public key.
        assert(serializedPubkey[0] == 0x04);
        // Create the Public skipping the header.
        return Public {&serializedPubkey[1], Public::ConstructFromPointer};
    }
    
    Address
    dev::toAddress(Public const& _public)
    {
        return right160(sha3(_public.ref()));
    }
    
    Address
    dev::toAddress(Secret const& _secret)
    {
        return toAddress(toPublic(_secret));
    }
    
    KeyPair::KeyPair(Secret const& _sec)
        : m_secret(_sec)
        , m_public(toPublic(_sec))
    {
        // Assign address only if the secret key is valid.
        if (m_public)
            m_address = toAddress(m_public);
    }
    
    KeyPair
    KeyPair::create()
    {
        while (true) {
            KeyPair keyPair(Secret::random());
            if (keyPair.address())
                return keyPair;
        }
    }
    
    h256
    crypto::kdf(Secret const& _priv, h256 const& _hash)
    {
        // H(H(r||k)^h)
        h256 s;
        sha3mac(Secret::random().ref(), _priv.ref(), s.ref());
        s ^= _hash;
        sha3(s.ref(), s.ref());
    
        if (!s || !_hash || !_priv)
            throw InvalidState();
        return s;
    }
    
    Secret
    Nonce::next()
    {
        std::lock_guard<std::mutex> l(x_value);
        if (!m_value) {
            m_value = Secret::random();
            if (!m_value)
                throw InvalidState();
        }
        m_value = sha3Secure(m_value.ref());
        return sha3(~m_value);
    }