An attempt to implement HIVE/STEEM node protocol in Rust

in HiveDevs5 years ago

The inter-node communication protocol of HIVE/STEEM is encrypted. Now there's only a C++ implementation.

After look into the code, I found that:

  • random secp256k1 pubkey is exchanged first
  • secp256k1_ec_pubkey_tweak_mul is used to generate a shared key
  • Google's city hash is used, but due to the endianness change, The Hive's is not the same as Google's original implementation

I attempted to implement the protocol ( at a very early stage ), wrote a small tool to parse hello_message.

https://github.com/andelf/rust-steem

ᐅ cargo run -- api.hive.blog:2001
    Finished dev [unoptimized + debuginfo] target(s) in 0.22s
     Running `target/debug/rust-steem 'api.hive.blog:2001'`
! => 0263e86b82fd60e1....................................43fce4
! <= 02049935b4ac8e4d57b13f14e4c43370461222e9ac73f343cab7e51467c8031805
! remote pub key => PublicKey(051803c86714e5b7ca43f373ace92212467033c4e4143fb1574d8eacb4359904c4123fa5062e56c8cf5daef14070e58c800862cc74be034939d97a91bd495aa0)
! tweak pub key  => PublicKey(188e48b6b354543016d9cb......................................58eb8d42942467d37df83)
! shared_key => "5368371fdf6da6bfb........................c64af3bb"
! aes key => "f992eb05b9743e594059e0..............afde2862aa4ac9d9f76102dcf"
! aes iv  => "17e74c33aa253e..........a00af56d"
! decrypted <= 380200008e1300001e537465656d205265666572656e636520496d706c656d656e746174696f6e6a000000cf43fe33d107d10703b32bbd902a92a619a32672a36de171cbb24a724b6ff6afb423c923566da629801f16169a3da42fed6c6bb7e425c9b7fb42e8fe6c76f6fe58b044df547d3d120afd41dfa32db98a05e6042a80c31760a3db2bb79fa75bc232f327dfaa0e8e51e110091366635f6769745f7265766973696f6e5f7368610528626337336535343537383834366661323466363861373638616531643865626262383265653230351e66635f6769745f7265766973696f6e5f756e69785f74696d657374616d7002c80e745e0000000008706c6174666f726d05056c696e7578076269746e657373024000000000000000076e6f64655f69640542346166636264656231656436373864396337623566333231666631633135653837316336383137656236356230316663383065616639633765626435333566313934156c6173745f6b6e6f776e5f626c6f636b5f68617368052830323833343335656337646466633364383665343838373865643662636365613533636437643661176c6173745f6b6e6f776e5f626c6f636b5f6e756d626572025e43830200000000156c6173745f6b6e6f776e5f626c6f636b5f74696d650513323032302d30342d30315430393a34303a323408636861696e5f6964054030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030
! header <= 380200008e130000
! packet payload size = 568
! packet message type = 5006
user_agent: "Steem Reference Implementation"
core_protocol_version: 106
inbound_address: [51, 254, 67, 207]
inbound_port: 2001
outbound_port: 2001
node_public_key: "03b32bbd902a9....................b6ff6afb423c923566da62980"
signed_shared_secret: "1f16169a3da42fed6c6...................db98a05e6042a80c31760a3db2bb79fa75bc232f327dfaa0e8e51e110"
user_data =>
{
  "bitness": 64,
  "chain_id": "0000000000000000000000000000000000000000000000000000000000000000",
  "fc_git_revision_sha": "bc73e54578846fa24f68a768ae1d8ebbb82ee205",
  "fc_git_revision_unix_timestamp": 1584664264,
  "last_known_block_hash": "0283435ec7ddfc3d86e48878ed6bccea53cd7d6a",
  "last_known_block_number": 42156894,
  "last_known_block_time": "2020-04-01T09:40:24",
  "node_id": "4afcbdeb1ed678d9c7b5f321..............b01fc80eaf9c7ebd535f194",
  "platform": "linux"
}