void dev::writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename) { namespace fs = boost::filesystem; if (_writeDeleteRename) { fs::path tempPath = fs::unique_path(_file + "-%%%%%%"); writeFile(tempPath.string(), _data, false); // will delete _file if it exists fs::rename(tempPath, _file); } else { // create directory if not existent fs::path p(_file); if (!fs::exists(p.parent_path())) { fs::create_directories(p.parent_path()); DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all)); } ofstream s(_file, ios::trunc | ios::binary); s.write(reinterpret_cast<char const*>(_data.data()), _data.size()); if (!s) BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not write to file: " + _file)); DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read|fs::owner_write)); } }
std::string hexPrefixEncode(bytesConstRef _d1, unsigned _o1, bytesConstRef _d2, unsigned _o2, bool _leaf) { unsigned begin1 = _o1; unsigned end1 = _d1.size() * 2; unsigned begin2 = _o2; unsigned end2 = _d2.size() * 2; bool odd = (end1 - begin1 + end2 - begin2) & 1; std::string ret(1, ((_leaf ? 2 : 0) | (odd ? 1 : 0)) * 16); ret.reserve((end1 - begin1 + end2 - begin2) / 2 + 1); unsigned d = odd ? 1 : 2; for (auto i = begin1; i < end1; ++i, ++d) { byte n = nibble(_d1, i); if (d & 1) // odd ret.back() |= n; // or the nibble onto the back else ret.push_back(n << 4); // push the nibble on to the back << 4 } for (auto i = begin2; i < end2; ++i, ++d) { byte n = nibble(_d2, i); if (d & 1) // odd ret.back() |= n; // or the nibble onto the back else ret.push_back(n << 4); // push the nibble on to the back << 4 } return ret; }
void eth::sha3(bytesConstRef _input, bytesRef _output) { CryptoPP::SHA3_256 ctx; ctx.Update((byte*)_input.data(), _input.size()); assert(_output.size() >= 32); ctx.Final(_output.data()); }
bytes dev::aesDecrypt(bytesConstRef _ivCipher, std::string const& _password, unsigned _rounds, bytesConstRef _salt) { bytes pw = asBytes(_password); if (!_salt.size()) _salt = &pw; bytes target(64); CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256>().DeriveKey(target.data(), target.size(), 0, pw.data(), pw.size(), _salt.data(), _salt.size(), _rounds); try { CryptoPP::AES::Decryption aesDecryption(target.data(), 16); auto cipher = _ivCipher.cropped(16); auto iv = _ivCipher.cropped(0, 16); CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data()); std::string decrypted; CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decrypted)); stfDecryptor.Put(cipher.data(), cipher.size()); stfDecryptor.MessageEnd(); return asBytes(decrypted); } catch (exception const& e) { cerr << e.what() << endl; return bytes(); } }
void Secp256k1PP::encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytes& io_cipher) { // interop w/go ecies implementation auto r = KeyPair::create(); Secret z; ecdh::agree(r.sec(), _k, z); auto key = eciesKDF(z, bytes(), 32); bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); CryptoPP::SHA256 ctx; ctx.Update(mKeyMaterial.data(), mKeyMaterial.size()); bytes mKey(32); ctx.Final(mKey.data()); bytes cipherText = encryptSymNoAuth(SecureFixedHash<16>(eKey), h128(), bytesConstRef(&io_cipher)); if (cipherText.empty()) return; bytes msg(1 + Public::size + h128::size + cipherText.size() + 32); msg[0] = 0x04; r.pub().ref().copyTo(bytesRef(&msg).cropped(1, Public::size)); bytesRef msgCipherRef = bytesRef(&msg).cropped(1 + Public::size + h128::size, cipherText.size()); bytesConstRef(&cipherText).copyTo(msgCipherRef); // tag message CryptoPP::HMAC<SHA256> hmacctx(mKey.data(), mKey.size()); bytesConstRef cipherWithIV = bytesRef(&msg).cropped(1 + Public::size, h128::size + cipherText.size()); hmacctx.Update(cipherWithIV.data(), cipherWithIV.size()); hmacctx.Update(_sharedMacData.data(), _sharedMacData.size()); hmacctx.Final(msg.data() + 1 + Public::size + cipherWithIV.size()); io_cipher.resize(msg.size()); io_cipher.swap(msg); }
bool Session::checkPacket(bytesConstRef _msg) { if (_msg[0] > 0x7f || _msg.size() < 2) return false; if (RLP(_msg.cropped(1)).actualSize() + 1 != _msg.size()) return false; return true; }
static void exec(string const& _args, bytesConstRef _in) { try { exec_stream_t es("ipfs", _args); es.in() << string(_in.begin(), _in.end()); } catch (exception const &e) { throw IPFSCommunicationError(e.what()); } }
bool Secp256k1PP::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytes& io_text) { // interop w/go ecies implementation // io_cipher[0] must be 2, 3, or 4, else invalidpublickey if (io_text.empty() || io_text[0] < 2 || io_text[0] > 4) // invalid message: publickey return false; if (io_text.size() < (1 + Public::size + h128::size + 1 + h256::size)) // invalid message: length return false; Secret z; if (!ecdh::agree(_k, *(Public*)(io_text.data() + 1), z)) return false; // Invalid pubkey or seckey. auto key = ecies::kdf(z, bytes(), 64); bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); bytes mKey(32); CryptoPP::SHA256 ctx; ctx.Update(mKeyMaterial.data(), mKeyMaterial.size()); ctx.Final(mKey.data()); bytes plain; size_t cipherLen = io_text.size() - 1 - Public::size - h128::size - h256::size; bytesConstRef cipherWithIV(io_text.data() + 1 + Public::size, h128::size + cipherLen); bytesConstRef cipherIV = cipherWithIV.cropped(0, h128::size); bytesConstRef cipherNoIV = cipherWithIV.cropped(h128::size, cipherLen); bytesConstRef msgMac(cipherNoIV.data() + cipherLen, h256::size); h128 iv(cipherIV.toBytes()); // verify tag CryptoPP::HMAC<CryptoPP::SHA256> hmacctx(mKey.data(), mKey.size()); hmacctx.Update(cipherWithIV.data(), cipherWithIV.size()); hmacctx.Update(_sharedMacData.data(), _sharedMacData.size()); h256 mac; hmacctx.Final(mac.data()); for (unsigned i = 0; i < h256::size; i++) if (mac[i] != msgMac[i]) return false; plain = decryptSymNoAuth(SecureFixedHash<16>(eKey), iv, cipherNoIV).makeInsecure(); io_text.resize(plain.size()); io_text.swap(plain); return true; }
bool TransactionQueue::import(bytesConstRef _block) { // Check if we already know this transaction. h256 h = sha3(_block); if (m_data.count(h)) return false; try { // Check validity of _block as a transaction. To do this we just deserialise and attempt to determine the sender. If it doesn't work, the signature is bad. // The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction). Transaction t(_block); auto s = t.sender(); if (m_interest.count(s)) m_interestQueue.push_back(t); // If valid, append to blocks. m_data[h] = _block.toBytes(); } catch (InvalidTransactionFormat const& _e) { cwarn << "Ignoring invalid transaction: " << _e.description(); return false; } catch (std::exception const& _e) { cwarn << "Ignoring invalid transaction: " << _e.what(); return false; } return true; }
void MemoryDB::insertAux(h256 const& _h, bytesConstRef _v) { #if DEV_GUARDED_DB WriteGuard l(x_this); #endif m_aux[_h] = make_pair(_v.toBytes(), true); }
AddressState::AddressState(u256 _balance, u256 _nonce, bytesConstRef _code): m_type(AddressType::Contract), m_balance(_balance), m_nonce(_nonce), m_isComplete(true), m_code(_code.toBytes()) {}
h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&) { Address na = right160(sha3(rlpList(myAddress, get<1>(addresses[myAddress])))); Transaction t(_endowment, gasPrice, io_gas, _init.toBytes()); callcreates.push_back(t); return na; }
void MemoryDB::insert(h256 const& _h, bytesConstRef _v) { #if DEV_GUARDED_DB WriteGuard l(x_this); #endif auto it = m_main.find(_h); if (it != m_main.end()) { it->second.first = _v.toString(); it->second.second++; } else m_main[_h] = make_pair(_v.toString(), 1); #if ETH_PARANOIA dbdebug << "INST" << _h << "=>" << m_main[_h].second; #endif }
bool dev::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytesConstRef _cipher, bytes& o_plaintext) { bytes io = _cipher.toBytes(); if (!Secp256k1PP::get()->decryptECIES(_k, _sharedMacData, io)) return false; o_plaintext = std::move(io); return true; }
bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext) { bytes io = _cipher.toBytes(); if (!s_secp256k1pp.decryptECIES(_k, io)) return false; o_plaintext = std::move(io); return true; }
bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256& io_gas, bytesRef _out, OnOpFunc const&, Address _myAddressOverride, Address _codeAddressOverride) { Transaction t(_value, gasPrice, io_gas, _receiveAddress, _data.toVector()); callcreates.push_back(t); (void)_out; (void)_myAddressOverride; (void)_codeAddressOverride; return true; }
bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext) { bytes io = _cipher.toBytes(); Secp256k1PP::get()->decrypt(_k, io); if (io.empty()) return false; o_plaintext = std::move(io); return true; }
RLP::RLP(bytesConstRef _d, Strictness _s): m_data(_d) { if ((_s & FailIfTooBig) && actualSize() < _d.size()) { if (_s & ThrowOnFail) BOOST_THROW_EXCEPTION(OversizeRLP()); else m_data.reset(); } if ((_s & FailIfTooSmall) && actualSize() > _d.size()) { if (_s & ThrowOnFail) BOOST_THROW_EXCEPTION(UndersizeRLP()); else m_data.reset(); } }
//追加内容到文件 void dev::appendFile(std::string const& _file, bytesConstRef _data) { namespace fs = boost::filesystem; // create directory if not existent fs::path p(_file); if (!fs::exists(p.parent_path())) { fs::create_directories(p.parent_path()); DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all)); } ofstream s(_file, ios::app | ios::binary); s.write(reinterpret_cast<char const*>(_data.data()), _data.size()); if (!s) BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not append write to file: " + _file)); DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read|fs::owner_write)); }
static bytes randomWord(bytesConstRef _alphabet, unsigned _min, unsigned _diff, h256* _seed) { assert(_min + _diff < 33); *_seed = sha3(*_seed); unsigned l = _min + (*_seed)[31] % (_diff + 1); bytes ret; for (unsigned i = 0; i < l; ++i) ret.push_back(_alphabet[(*_seed)[i] % _alphabet.size()]); return ret; }
string dev::toBase58(bytesConstRef _d, string const& _alphabet) { auto begin = _d.data(); auto end = _d.data() + _d.size(); // Skip & count leading zeroes. int zeroes = 0; for (; begin != end && !*begin; begin++, zeroes++) {} // Allocate enough space in big-endian base58 representation. // log(256) / log(58), rounded up. std::vector<unsigned char> b58((end - begin) * 138 / 100 + 1); // Process the bytes. while (begin != end) { int carry = *begin; // Apply "b58 = b58 * 256 + ch". for (auto it = b58.rbegin(); it != b58.rend(); it++) { carry += 256 * (*it); *it = carry % 58; carry /= 58; } assert(!carry); begin++; } // Skip leading zeroes in base58 result. auto it = b58.begin(); while (it != b58.end() && !*it) it++; // Translate the result into a string. std::string ret; ret.reserve(zeroes + (b58.end() - it)); ret.assign(zeroes, '1'); while (it != b58.end()) ret += _alphabet[*(it++)]; return ret; }
bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin) { m_isCreation = true; // We can allow for the reverted state (i.e. that with which m_ext is constructed) to contain the m_newAddress, since // we delete it explicitly if we decide we need to revert. m_newAddress = right160(sha3(rlpList(_sender, m_s.transactionsFrom(_sender) - 1))); m_gas = _gas; // Execute _init. if (!_init.empty()) m_ext = make_shared<ExtVM>(m_s, m_envInfo, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, sha3(_init), m_depth); m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress), Account::ContractConception); m_s.transferBalance(_sender, m_newAddress, _endowment); if (_init.empty()) m_s.m_cache[m_newAddress].setCode({}); return !m_ext; }
bytes dev::encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _plain) { if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32) return bytes(); SecByteBlock key(_k.data(), _k.size()); try { CTR_Mode<AES>::Encryption e; e.SetKeyWithIV(key, key.size(), _iv.data()); bytes ret(_plain.size()); e.ProcessData(ret.data(), _plain.data(), _plain.size()); return ret; } catch (CryptoPP::Exception& _e) { cerr << _e.what() << endl; return bytes(); } }
bytesSec dev::decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher) { if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32) return bytesSec(); SecByteBlock key(_k.data(), _k.size()); try { CTR_Mode<AES>::Decryption d; d.SetKeyWithIV(key, key.size(), _iv.data()); bytesSec ret(_cipher.size()); d.ProcessData(ret.writable().data(), _cipher.data(), _cipher.size()); return ret; } catch (CryptoPP::Exception& _e) { cerr << _e.what() << endl; return bytesSec(); } }
unique_ptr<DiscoveryDatagram> DiscoveryDatagram::interpretUDP(bi::udp::endpoint const& _from, bytesConstRef _packet) { unique_ptr<DiscoveryDatagram> decoded; // h256 + Signature + type + RLP (smallest possible packet is empty neighbours packet which is 3 bytes) if (_packet.size() < h256::size + Signature::size + 1 + 3) { LOG(g_discoveryWarnLogger::get()) << "Invalid packet (too small) from " << _from.address().to_string() << ":" << _from.port(); return decoded; } bytesConstRef hashedBytes(_packet.cropped(h256::size, _packet.size() - h256::size)); bytesConstRef signedBytes(hashedBytes.cropped(Signature::size, hashedBytes.size() - Signature::size)); bytesConstRef signatureBytes(_packet.cropped(h256::size, Signature::size)); bytesConstRef bodyBytes(_packet.cropped(h256::size + Signature::size + 1)); h256 echo(sha3(hashedBytes)); if (!_packet.cropped(0, h256::size).contentsEqual(echo.asBytes())) { LOG(g_discoveryWarnLogger::get()) << "Invalid packet (bad hash) from " << _from.address().to_string() << ":" << _from.port(); return decoded; } Public sourceid(dev::recover(*(Signature const*)signatureBytes.data(), sha3(signedBytes))); if (!sourceid) { LOG(g_discoveryWarnLogger::get()) << "Invalid packet (bad signature) from " << _from.address().to_string() << ":" << _from.port(); return decoded; } switch (signedBytes[0]) { case PingNode::type: decoded.reset(new PingNode(_from, sourceid, echo)); break; case Pong::type: decoded.reset(new Pong(_from, sourceid, echo)); break; case FindNode::type: decoded.reset(new FindNode(_from, sourceid, echo)); break; case Neighbours::type: decoded.reset(new Neighbours(_from, sourceid, echo)); break; default: LOG(g_discoveryWarnLogger::get()) << "Invalid packet (unknown packet type) from " << _from.address().to_string() << ":" << _from.port(); return decoded; } decoded->interpretRLP(bodyBytes); return decoded; }
Public Secp256k1PP::recover(Signature _signature, bytesConstRef _message) { Public recovered; Integer r(_signature.data(), 32); Integer s(_signature.data()+32, 32); // cryptopp encodes sign of y as 0x02/0x03 instead of 0/1 or 27/28 byte encodedpoint[33]; encodedpoint[0] = _signature[64] | 2; memcpy(&encodedpoint[1], _signature.data(), 32); ECP::Element x; { m_curve.DecodePoint(x, encodedpoint, 33); if (!m_curve.VerifyPoint(x)) return recovered; } // if (_signature[64] & 2) // { // r += m_q; // Guard l(x_params); // if (r >= m_params.GetMaxExponent()) // return recovered; // } Integer z(_message.data(), 32); Integer rn = r.InverseMod(m_q); Integer u1 = m_q - (rn.Times(z)).Modulo(m_q); Integer u2 = (rn.Times(s)).Modulo(m_q); ECP::Point p; byte recoveredbytes[65]; { // todo: make generator member p = m_curve.CascadeMultiply(u2, x, u1, m_params.GetSubgroupGenerator()); if (p.identity) return Public(); m_curve.EncodePoint(recoveredbytes, p, false); } memcpy(recovered.data(), &recoveredbytes[1], 64); return recovered; }
std::string hexPrefixEncode(bytesConstRef _data, bool _leaf, int _beginNibble, int _endNibble, unsigned _offset) { unsigned begin = _beginNibble + _offset; unsigned end = (_endNibble < 0 ? ((int)(_data.size() * 2 - _offset) + 1) + _endNibble : _endNibble) + _offset; bool odd = (end - begin) & 1; std::string ret(1, ((_leaf ? 2 : 0) | (odd ? 1 : 0)) * 16); ret.reserve((end - begin) / 2 + 1); unsigned d = odd ? 1 : 2; for (auto i = begin; i < end; ++i, ++d) { byte n = nibble(_data, i); if (d & 1) // odd ret.back() |= n; // or the nibble onto the back else ret.push_back(n << 4); // push the nibble on to the back << 4 } return ret; }
void dev::encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytesConstRef _plain, bytes& o_cipher) { bytes io = _plain.toBytes(); Secp256k1PP::get()->encryptECIES(_k, _sharedMacData, io); o_cipher = std::move(io); }
RLP BlockHeader::extractHeader(bytesConstRef _block) { RLP root(_block); if (!root.isList()) BOOST_THROW_EXCEPTION( InvalidBlockFormat() << errinfo_comment("Block must be a list") << BadFieldError(0, _block.toString())); RLP header = root[0]; if (!header.isList()) BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block header must be a list") << BadFieldError(0, header.data().toString())); if (!root[1].isList()) BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block transactions must be a list") << BadFieldError(1, root[1].data().toString())); if (!root[2].isList()) BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block uncles must be a list") << BadFieldError(2, root[2].data().toString())); return header; }
void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher) { bytes io = _plain.toBytes(); s_secp256k1pp.encryptECIES(_k, io); o_cipher = std::move(io); }