Ecoer Logo

@icostan

25

Software developer, derivatives trader, crypto hodler.

steemit.com/@icostan
VOTING POWER100.00%
DOWNVOTE POWER100.00%
RESOURCE CREDITS100.00%
REPUTATION PROGRESS0.00%
Net Worth
0.037USD
STEEM
0.001STEEM
SBD
0.001SBD
Effective Power
5.009SP
├── Own SP
0.636SP
└── Incoming Deleg
+4.373SP

Detailed Balance

STEEM
balance
0.001STEEM
market_balance
0.000STEEM
savings_balance
0.000STEEM
reward_steem_balance
0.000STEEM
STEEM POWER
Own SP
0.636SP
Delegated Out
0.000SP
Delegation In
4.373SP
Effective Power
5.009SP
Reward SP (pending)
0.000SP
SBD
sbd_balance
0.001SBD
sbd_conversions
0.000SBD
sbd_market_balance
0.000SBD
savings_sbd_balance
0.000SBD
reward_sbd_balance
0.000SBD
{
  "balance": "0.001 STEEM",
  "savings_balance": "0.000 STEEM",
  "reward_steem_balance": "0.000 STEEM",
  "vesting_shares": "1033.711102 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "7109.948704 VESTS",
  "sbd_balance": "0.001 SBD",
  "savings_sbd_balance": "0.000 SBD",
  "reward_sbd_balance": "0.000 SBD",
  "conversions": []
}

Account Info

nameicostan
id258317
rank974,718
reputation41140234
created2017-07-13T20:36:27
recovery_accountsteem
proxyNone
post_count9
comment_count0
lifetime_vote_count0
witnesses_voted_for4
last_post2019-10-02T07:20:06
last_root_post2019-10-02T07:20:06
last_vote_time2017-08-12T14:08:39
proxied_vsf_votes0, 0, 0, 0
can_vote1
voting_power0
delayed_votes0
balance0.001 STEEM
savings_balance0.000 STEEM
sbd_balance0.001 SBD
savings_sbd_balance0.000 SBD
vesting_shares1033.711102 VESTS
delegated_vesting_shares0.000000 VESTS
received_vesting_shares7109.948704 VESTS
reward_vesting_balance0.000000 VESTS
vesting_balance0.000 STEEM
vesting_withdraw_rate0.000000 VESTS
next_vesting_withdrawal1969-12-31T23:59:59
withdrawn0
to_withdraw0
withdraw_routes0
savings_withdraw_requests0
last_account_recovery1970-01-01T00:00:00
reset_accountnull
last_owner_update1970-01-01T00:00:00
last_account_update2020-04-02T04:27:33
minedNo
sbd_seconds0
sbd_last_interest_payment1970-01-01T00:00:00
savings_sbd_last_interest_payment1970-01-01T00:00:00
{
  "id": 258317,
  "name": "icostan",
  "owner": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM8khvozYSgQesA4HfUsz977WkPUnBJbUxoboqqkSdSURZcgowCq",
        1
      ]
    ]
  },
  "active": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM7wXRVfSTGD8tos5uC444bf8FxeaZuXCmJjjSapRhEKBh2TbsQ3",
        1
      ]
    ]
  },
  "posting": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM6x1BPWfk5eFQg3cio62PoSkRYQCCzH99Eo3vXf68xVJSJ15zWB",
        1
      ]
    ]
  },
  "memo_key": "STM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa",
  "json_metadata": "{\"profile\":{\"name\":\"Iulian Costan\",\"about\":\"Computer geek, derivatives trader, crypto hodler.\",\"website\":\"http://iuliancostan.com\",\"location\":\"Romania\"}}",
  "posting_json_metadata": "{\"profile\":{\"name\":\"Iulian Costan\",\"about\":\"Software developer, derivatives trader, crypto hodler.\",\"website\":\"http://iuliancostan.com\",\"location\":\"Romania\",\"cover_image\":\"https://cdn.steemitimages.com/DQmRDebpsdxEV3eCyhwTw3yzSRVTmqU9nNP4WaxShFX3dmR/avatar-india.jpg\",\"version\":2}}",
  "proxy": "",
  "last_owner_update": "1970-01-01T00:00:00",
  "last_account_update": "2020-04-02T04:27:33",
  "created": "2017-07-13T20:36:27",
  "mined": false,
  "recovery_account": "steem",
  "last_account_recovery": "1970-01-01T00:00:00",
  "reset_account": "null",
  "comment_count": 0,
  "lifetime_vote_count": 0,
  "post_count": 9,
  "can_vote": true,
  "voting_manabar": {
    "current_mana": "8143659806",
    "last_update_time": 1779067239
  },
  "downvote_manabar": {
    "current_mana": 2035914951,
    "last_update_time": 1779067239
  },
  "voting_power": 0,
  "balance": "0.001 STEEM",
  "savings_balance": "0.000 STEEM",
  "sbd_balance": "0.001 SBD",
  "sbd_seconds": "0",
  "sbd_seconds_last_update": "2018-12-11T09:26:51",
  "sbd_last_interest_payment": "1970-01-01T00:00:00",
  "savings_sbd_balance": "0.000 SBD",
  "savings_sbd_seconds": "0",
  "savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
  "savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
  "savings_withdraw_requests": 0,
  "reward_sbd_balance": "0.000 SBD",
  "reward_steem_balance": "0.000 STEEM",
  "reward_vesting_balance": "0.000000 VESTS",
  "reward_vesting_steem": "0.000 STEEM",
  "vesting_shares": "1033.711102 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "7109.948704 VESTS",
  "vesting_withdraw_rate": "0.000000 VESTS",
  "next_vesting_withdrawal": "1969-12-31T23:59:59",
  "withdrawn": 0,
  "to_withdraw": 0,
  "withdraw_routes": 0,
  "curation_rewards": 0,
  "posting_rewards": 0,
  "proxied_vsf_votes": [
    0,
    0,
    0,
    0
  ],
  "witnesses_voted_for": 4,
  "last_post": "2019-10-02T07:20:06",
  "last_root_post": "2019-10-02T07:20:06",
  "last_vote_time": "2017-08-12T14:08:39",
  "post_bandwidth": 0,
  "pending_claimed_accounts": 0,
  "vesting_balance": "0.000 STEEM",
  "reputation": 41140234,
  "transfer_history": [],
  "market_history": [],
  "post_history": [],
  "vote_history": [],
  "other_history": [],
  "witness_votes": [
    "furion",
    "good-karma",
    "jerrybanfield",
    "steemitboard"
  ],
  "tags_usage": [],
  "guest_bloggers": [],
  "rank": 974718
}

Withdraw Routes

IncomingOutgoing
Empty
Empty
{
  "incoming": [],
  "outgoing": []
}
From Date
To Date
steemdelegated 4.373 SP to @icostan
2026/05/18 01:20:39
delegateeicostan
delegatorsteem
vesting shares7109.948704 VESTS
Transaction InfoBlock #106144750/Trx fbd01f9c3a782816d79e44041d682a0d443404f5
View Raw JSON Data
{
  "block": 106144750,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "7109.948704 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-05-18T01:20:39",
  "trx_id": "fbd01f9c3a782816d79e44041d682a0d443404f5",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 2.705 SP to @icostan
2026/05/12 08:15:57
delegateeicostan
delegatorsteem
vesting shares4397.738299 VESTS
Transaction InfoBlock #105981009/Trx 9e7c0409594b840285e5f30a0ba4438fcbf982b9
View Raw JSON Data
{
  "block": 105981009,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "4397.738299 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-05-12T08:15:57",
  "trx_id": "9e7c0409594b840285e5f30a0ba4438fcbf982b9",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 4.381 SP to @icostan
2026/04/26 00:39:42
delegateeicostan
delegatorsteem
vesting shares7122.464460 VESTS
Transaction InfoBlock #105512370/Trx 89413f0c2bc15922383a616f58d9a5faff6746f0
View Raw JSON Data
{
  "block": 105512370,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "7122.464460 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-04-26T00:39:42",
  "trx_id": "89413f0c2bc15922383a616f58d9a5faff6746f0",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 2.730 SP to @icostan
2026/01/23 10:44:00
delegateeicostan
delegatorsteem
vesting shares4439.285118 VESTS
Transaction InfoBlock #102855325/Trx f4b258f40a488a80a4e4f46ccf7a9534a380120d
View Raw JSON Data
{
  "block": 102855325,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "4439.285118 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-01-23T10:44:00",
  "trx_id": "f4b258f40a488a80a4e4f46ccf7a9534a380120d",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 2.831 SP to @icostan
2024/12/17 06:01:15
delegateeicostan
delegatorsteem
vesting shares4603.504315 VESTS
Transaction InfoBlock #91301685/Trx ae565da12b2fa6d901ccfe06a74e36009d3fce59
View Raw JSON Data
{
  "block": 91301685,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "4603.504315 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2024-12-17T06:01:15",
  "trx_id": "ae565da12b2fa6d901ccfe06a74e36009d3fce59",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 2.936 SP to @icostan
2023/11/13 21:43:33
delegateeicostan
delegatorsteem
vesting shares4772.637847 VESTS
Transaction InfoBlock #79855876/Trx 8bb209fe2f0b2c624abc086fe963dbb2f6fba58a
View Raw JSON Data
{
  "block": 79855876,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "4772.637847 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-11-13T21:43:33",
  "trx_id": "8bb209fe2f0b2c624abc086fe963dbb2f6fba58a",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 4.742 SP to @icostan
2023/09/21 23:07:03
delegateeicostan
delegatorsteem
vesting shares7709.916633 VESTS
Transaction InfoBlock #78349370/Trx eb985618efabd58611f6fdf729057427290f516b
View Raw JSON Data
{
  "block": 78349370,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "7709.916633 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-09-21T23:07:03",
  "trx_id": "eb985618efabd58611f6fdf729057427290f516b",
  "trx_in_block": 11,
  "virtual_op": 0
}
steemdelegated 4.879 SP to @icostan
2022/11/03 12:44:33
delegateeicostan
delegatorsteem
vesting shares7931.598071 VESTS
Transaction InfoBlock #69114502/Trx ec8f6ab9b77beb28c67df632f1ffddd435724867
View Raw JSON Data
{
  "block": 69114502,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "7931.598071 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-11-03T12:44:33",
  "trx_id": "ec8f6ab9b77beb28c67df632f1ffddd435724867",
  "trx_in_block": 4,
  "virtual_op": 0
}
steemdelegated 5.014 SP to @icostan
2022/01/17 11:55:18
delegateeicostan
delegatorsteem
vesting shares8152.131302 VESTS
Transaction InfoBlock #60810567/Trx d0573691e6718110f86c9d9f8d56fde5c325526b
View Raw JSON Data
{
  "block": 60810567,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "8152.131302 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-01-17T11:55:18",
  "trx_id": "d0573691e6718110f86c9d9f8d56fde5c325526b",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 5.127 SP to @icostan
2021/06/14 01:47:54
delegateeicostan
delegatorsteem
vesting shares8335.899960 VESTS
Transaction InfoBlock #54608898/Trx c7ae47ae36f06d6ed4f130fbe2f1fc9e8a6c6a70
View Raw JSON Data
{
  "block": 54608898,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "8335.899960 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2021-06-14T01:47:54",
  "trx_id": "c7ae47ae36f06d6ed4f130fbe2f1fc9e8a6c6a70",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 5.242 SP to @icostan
2020/12/11 12:05:15
delegateeicostan
delegatorsteem
vesting shares8523.321934 VESTS
Transaction InfoBlock #49356311/Trx 8bcde9c434e60b237df4e1d1c4fa130cc840f192
View Raw JSON Data
{
  "block": 49356311,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "8523.321934 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-11T12:05:15",
  "trx_id": "8bcde9c434e60b237df4e1d1c4fa130cc840f192",
  "trx_in_block": 4,
  "virtual_op": 0
}
steemdelegated 1.176 SP to @icostan
2020/12/06 05:42:15
delegateeicostan
delegatorsteem
vesting shares1912.543513 VESTS
Transaction InfoBlock #49207872/Trx 42ad2630d4e16e6e70e845b172e73ad447688bb0
View Raw JSON Data
{
  "block": 49207872,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "1912.543513 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-06T05:42:15",
  "trx_id": "42ad2630d4e16e6e70e845b172e73ad447688bb0",
  "trx_in_block": 2,
  "virtual_op": 0
}
steemdelegated 5.246 SP to @icostan
2020/12/05 15:43:06
delegateeicostan
delegatorsteem
vesting shares8529.529788 VESTS
Transaction InfoBlock #49191405/Trx 81d514310a7e6c084ba44b8235fc62905ec2a095
View Raw JSON Data
{
  "block": 49191405,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "8529.529788 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-05T15:43:06",
  "trx_id": "81d514310a7e6c084ba44b8235fc62905ec2a095",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 1.181 SP to @icostan
2020/11/02 17:40:30
delegateeicostan
delegatorsteem
vesting shares1920.017158 VESTS
Transaction InfoBlock #48260200/Trx c6312a02cdb05f355084d57948335d02e92ad7a3
View Raw JSON Data
{
  "block": 48260200,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "1920.017158 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-11-02T17:40:30",
  "trx_id": "c6312a02cdb05f355084d57948335d02e92ad7a3",
  "trx_in_block": 4,
  "virtual_op": 0
}
steemdelegated 5.371 SP to @icostan
2020/05/09 06:40:30
delegateeicostan
delegatorsteem
vesting shares8732.335147 VESTS
Transaction InfoBlock #43218134/Trx c1ad3dca06e95d47057e6475d12f149f389e58b0
View Raw JSON Data
{
  "block": 43218134,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "8732.335147 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-05-09T06:40:30",
  "trx_id": "c1ad3dca06e95d47057e6475d12f149f389e58b0",
  "trx_in_block": 7,
  "virtual_op": 0
}
steemdelegated 1.201 SP to @icostan
2020/05/08 10:25:24
delegateeicostan
delegatorsteem
vesting shares1953.311140 VESTS
Transaction InfoBlock #43194400/Trx ac20e33fbf7c894daa9e2ada7fa737eb16ef8ff4
View Raw JSON Data
{
  "block": 43194400,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "1953.311140 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-05-08T10:25:24",
  "trx_id": "ac20e33fbf7c894daa9e2ada7fa737eb16ef8ff4",
  "trx_in_block": 10,
  "virtual_op": 0
}
icostanupdated their account properties
2020/04/02 04:27:33
accounticostan
extensions[]
json metadata
posting json metadata{"profile":{"name":"Iulian Costan","about":"Software developer, derivatives trader, crypto hodler.","website":"http://iuliancostan.com","location":"Romania","cover_image":"https://cdn.steemitimages.com/DQmRDebpsdxEV3eCyhwTw3yzSRVTmqU9nNP4WaxShFX3dmR/avatar-india.jpg","version":2}}
Transaction InfoBlock #42176514/Trx d9520a989fb3a727cc23f6e4687d95746152e96f
View Raw JSON Data
{
  "block": 42176514,
  "op": [
    "account_update2",
    {
      "account": "icostan",
      "extensions": [],
      "json_metadata": "",
      "posting_json_metadata": "{\"profile\":{\"name\":\"Iulian Costan\",\"about\":\"Software developer, derivatives trader, crypto hodler.\",\"website\":\"http://iuliancostan.com\",\"location\":\"Romania\",\"cover_image\":\"https://cdn.steemitimages.com/DQmRDebpsdxEV3eCyhwTw3yzSRVTmqU9nNP4WaxShFX3dmR/avatar-india.jpg\",\"version\":2}}"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-04-02T04:27:33",
  "trx_id": "d9520a989fb3a727cc23f6e4687d95746152e96f",
  "trx_in_block": 29,
  "virtual_op": 0
}
steemdelegated 5.414 SP to @icostan
2020/01/01 08:51:03
delegateeicostan
delegatorsteem
vesting shares8802.734898 VESTS
Transaction InfoBlock #39542925/Trx f15b2441f619685e3ebac34fb26dd9137bbe6ee8
View Raw JSON Data
{
  "block": 39542925,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "8802.734898 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-01-01T08:51:03",
  "trx_id": "f15b2441f619685e3ebac34fb26dd9137bbe6ee8",
  "trx_in_block": 5,
  "virtual_op": 0
}
2019/10/06 17:54:36
authorshtabnoy
bodyNice article, very clear
json metadata{"app":"steemit/0.1"}
parent authoricostan
parent permlinkanimated-elliptic-curve-cryptography
permlinkpyysey
title
Transaction InfoBlock #37052957/Trx dbc5bdcb47eb9f1a57ed2b8d03c4bc61ca9d8210
View Raw JSON Data
{
  "block": 37052957,
  "op": [
    "comment",
    {
      "author": "shtabnoy",
      "body": "Nice article, very clear",
      "json_metadata": "{\"app\":\"steemit/0.1\"}",
      "parent_author": "icostan",
      "parent_permlink": "animated-elliptic-curve-cryptography",
      "permlink": "pyysey",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-10-06T17:54:36",
  "trx_id": "dbc5bdcb47eb9f1a57ed2b8d03c4bc61ca9d8210",
  "trx_in_block": 10,
  "virtual_op": 0
}
2019/10/06 17:54:06
authoricostan
permlinkanimated-elliptic-curve-cryptography
votershtabnoy
weight10000 (100.00%)
Transaction InfoBlock #37052947/Trx b249e42af25d18db9c3ee73d828ab7451576a9a4
View Raw JSON Data
{
  "block": 37052947,
  "op": [
    "vote",
    {
      "author": "icostan",
      "permlink": "animated-elliptic-curve-cryptography",
      "voter": "shtabnoy",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-10-06T17:54:06",
  "trx_id": "b249e42af25d18db9c3ee73d828ab7451576a9a4",
  "trx_in_block": 13,
  "virtual_op": 0
}
steemdelegated 17.932 SP to @icostan
2019/10/02 07:45:42
delegateeicostan
delegatorsteem
vesting shares29153.734298 VESTS
Transaction InfoBlock #36925839/Trx 89ee156ff73f86d7c1799fdeffc12cb75dfa6330
View Raw JSON Data
{
  "block": 36925839,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "29153.734298 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-10-02T07:45:42",
  "trx_id": "89ee156ff73f86d7c1799fdeffc12cb75dfa6330",
  "trx_in_block": 20,
  "virtual_op": 0
}
2019/10/02 07:43:27
authoricostan
body@@ -800,17 +800,17 @@ point i -f +s the res
json metadata{"tags":["elliptic-curves","sagemath","animation"],"image":["https://cdn.steemitimages.com/DQmeaftKeUgnvojjuNFV6xHeX2mV4S33otD5rPumc78JxnU/ec11-animate.gif"],"links":["https://blog.iuliancostan.com/post/2019-09-25-elliptic-curves/"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptography
permlinkanimated-elliptic-curve-cryptography
titleAnimated Elliptic Curve cryptography
Transaction InfoBlock #36925794/Trx 43ba672527881c58b92f334f64496b9808f3d35d
View Raw JSON Data
{
  "block": 36925794,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -800,17 +800,17 @@\n  point i\n-f\n+s\n  the res\n",
      "json_metadata": "{\"tags\":[\"elliptic-curves\",\"sagemath\",\"animation\"],\"image\":[\"https://cdn.steemitimages.com/DQmeaftKeUgnvojjuNFV6xHeX2mV4S33otD5rPumc78JxnU/ec11-animate.gif\"],\"links\":[\"https://blog.iuliancostan.com/post/2019-09-25-elliptic-curves/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptography",
      "permlink": "animated-elliptic-curve-cryptography",
      "title": "Animated Elliptic Curve cryptography"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-10-02T07:43:27",
  "trx_id": "43ba672527881c58b92f334f64496b9808f3d35d",
  "trx_in_block": 7,
  "virtual_op": 0
}
2019/10/02 07:20:06
authoricostan
bodyThe easiest way to understand Elliptic Curve (EC), point addition, scalar multiplication and trapdoor function; explained with simple graphs and animations. # 1. Abstract - What the heck is an elliptic curve? - A plane algebraic curve defined by an equation of this form: ***y<sup>2</sup> = x<sup>3</sup> + a\*x + b*** - Why are elliptic curves important in cryptography? - Because elliptic curve scalar multiplication is a trapdoor function - How does scalar multiplication works? - Scalar/point multiplication is defined as repeated addition of a point to itself - How does point addition works then? - If we draw a line passing thru elliptic curve points (or draw a tangent to a single point) it will intersect another point on the curve and the inverse of this intersection point if the result of point addition Since a picture is worth a thousand words then the following elliptic curve point addition/multiplication animation has 33 frames and is worth a lot more, do the math. ![ec11-animate.gif](https://cdn.steemitimages.com/DQmeaftKeUgnvojjuNFV6xHeX2mV4S33otD5rPumc78JxnU/ec11-animate.gif) Given an elliptic curve ***E*** a point on elliptic curve ***G*** (called the generator) and a private key ***k*** we can calculate the public key ***P*** where ***P = k \* G***. The whole idea behind elliptic curves cryptography is that point addition (multiplication) is a trapdoor function which means that given ***G*** and ***P*** points it is infeasible to find the private key ***k***. [Read the blog post](https://blog.iuliancostan.com/post/2019-09-25-elliptic-curves/) for more details.
json metadata{"tags":["cryptography","elliptic-curves","sagemath","animation"],"image":["https://cdn.steemitimages.com/DQmeaftKeUgnvojjuNFV6xHeX2mV4S33otD5rPumc78JxnU/ec11-animate.gif"],"links":["https://blog.iuliancostan.com/post/2019-09-25-elliptic-curves/"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptography
permlinkanimated-elliptic-curve-cryptography
titleAnimated Elliptic Curve cryptography
Transaction InfoBlock #36925327/Trx 981ed93f58da6cd9c6bc72313d57ae1d04ba7819
View Raw JSON Data
{
  "block": 36925327,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "The easiest way to understand Elliptic Curve (EC), point addition, scalar multiplication and trapdoor function; explained with simple graphs and animations.\n\n\n# 1. Abstract\n\n-   What the heck is an elliptic curve?\n-   A plane algebraic curve defined by an equation of this form: ***y<sup>2</sup> = x<sup>3</sup> + a\\*x + b***\n\n-   Why are elliptic curves important in cryptography?\n-   Because elliptic curve scalar multiplication is a trapdoor function\n\n-   How does scalar multiplication works?\n-   Scalar/point multiplication is defined as repeated addition of a point to itself\n\n-   How does point addition works then?\n-   If we draw a line passing thru elliptic curve points (or draw a tangent to a single point) it will intersect another point on the curve and the inverse of this intersection point if the result of point addition\n\nSince a picture is worth a thousand words then the following elliptic curve point addition/multiplication animation has 33 frames and is worth a lot more, do the math.\n\n![ec11-animate.gif](https://cdn.steemitimages.com/DQmeaftKeUgnvojjuNFV6xHeX2mV4S33otD5rPumc78JxnU/ec11-animate.gif)\n\nGiven an elliptic curve ***E*** a point on elliptic curve ***G*** (called the generator) and a private key ***k*** we can calculate the public key ***P*** where ***P = k \\* G***.\n\nThe whole idea behind elliptic curves cryptography is that point addition (multiplication) is a trapdoor function which means that given ***G*** and ***P*** points it is infeasible to find the private key ***k***.\n\n[Read the blog post](https://blog.iuliancostan.com/post/2019-09-25-elliptic-curves/) for more details.",
      "json_metadata": "{\"tags\":[\"cryptography\",\"elliptic-curves\",\"sagemath\",\"animation\"],\"image\":[\"https://cdn.steemitimages.com/DQmeaftKeUgnvojjuNFV6xHeX2mV4S33otD5rPumc78JxnU/ec11-animate.gif\"],\"links\":[\"https://blog.iuliancostan.com/post/2019-09-25-elliptic-curves/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptography",
      "permlink": "animated-elliptic-curve-cryptography",
      "title": "Animated Elliptic Curve cryptography"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-10-02T07:20:06",
  "trx_id": "981ed93f58da6cd9c6bc72313d57ae1d04ba7819",
  "trx_in_block": 2,
  "virtual_op": 0
}
icostanupdated their account properties
2019/10/01 19:17:18
accounticostan
json metadata{"profile":{"name":"Iulian Costan","about":"Computer geek, derivatives trader, crypto hodler.","website":"http://iuliancostan.com","location":"Romania"}}
memo keySTM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa
Transaction InfoBlock #36910901/Trx 4f997334884fc80d747648ca940bad998c6f1989
View Raw JSON Data
{
  "block": 36910901,
  "op": [
    "account_update",
    {
      "account": "icostan",
      "json_metadata": "{\"profile\":{\"name\":\"Iulian Costan\",\"about\":\"Computer geek, derivatives trader, crypto hodler.\",\"website\":\"http://iuliancostan.com\",\"location\":\"Romania\"}}",
      "memo_key": "STM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-10-01T19:17:18",
  "trx_id": "4f997334884fc80d747648ca940bad998c6f1989",
  "trx_in_block": 6,
  "virtual_op": 0
}
icostanupdated their account properties
2019/10/01 19:17:06
accounticostan
json metadata{"profile":{"name":"Iulian Costan","about":"Computer geek, derivatives trader, crypto hodler.","website":"http://iuliancostan.com"}}
memo keySTM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa
Transaction InfoBlock #36910897/Trx 6635ed8a425fca74232a11eca8603cbfbfe93e32
View Raw JSON Data
{
  "block": 36910897,
  "op": [
    "account_update",
    {
      "account": "icostan",
      "json_metadata": "{\"profile\":{\"name\":\"Iulian Costan\",\"about\":\"Computer geek, derivatives trader, crypto hodler.\",\"website\":\"http://iuliancostan.com\"}}",
      "memo_key": "STM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-10-01T19:17:06",
  "trx_id": "6635ed8a425fca74232a11eca8603cbfbfe93e32",
  "trx_in_block": 30,
  "virtual_op": 0
}
dtubesent 0.001 STEEM to @icostan- "Time is running out, claim your DTube account now before anyone else can! Login at https://d.tube"
2019/08/22 17:00:03
amount0.001 STEEM
fromdtube
memoTime is running out, claim your DTube account now before anyone else can! Login at https://d.tube
toicostan
Transaction InfoBlock #35780410/Trx cb772d3bbec3755241820bb4cd7e5554c5b8760c
View Raw JSON Data
{
  "block": 35780410,
  "op": [
    "transfer",
    {
      "amount": "0.001 STEEM",
      "from": "dtube",
      "memo": "Time is running out, claim your DTube account now before anyone else can! Login at https://d.tube",
      "to": "icostan"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-08-22T17:00:03",
  "trx_id": "cb772d3bbec3755241820bb4cd7e5554c5b8760c",
  "trx_in_block": 26,
  "virtual_op": 0
}
2019/07/13 22:21:45
authorsteemitboard
bodyCongratulations @icostan! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@icostan/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@icostan) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=icostan)_</sub> > You can upvote this notification to help all Steem users. Learn how [here](https://steemit.com/steemitboard/@steemitboard/http-i-cubeupload-com-7ciqeo-png)!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
parent authoricostan
parent permlinkcryptography-ecdsa
permlinksteemitboard-notify-icostan-20190713t222144000z
title
Transaction InfoBlock #34637890/Trx ab7540f837d96615d1d8fc332584bc9e844036e2
View Raw JSON Data
{
  "block": 34637890,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @icostan! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@icostan/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@icostan) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=icostan)_</sub>\n\n\n> You can upvote this notification to help all Steem users. Learn how [here](https://steemit.com/steemitboard/@steemitboard/http-i-cubeupload-com-7ciqeo-png)!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
      "parent_author": "icostan",
      "parent_permlink": "cryptography-ecdsa",
      "permlink": "steemitboard-notify-icostan-20190713t222144000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T22:21:45",
  "trx_id": "ab7540f837d96615d1d8fc332584bc9e844036e2",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 5.477 SP to @icostan
2019/07/13 13:28:51
delegateeicostan
delegatorsteem
vesting shares8904.899509 VESTS
Transaction InfoBlock #34627241/Trx 645ad8516606a7748c958afff3fbad6f9562fa20
View Raw JSON Data
{
  "block": 34627241,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "8904.899509 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-07-13T13:28:51",
  "trx_id": "645ad8516606a7748c958afff3fbad6f9562fa20",
  "trx_in_block": 26,
  "virtual_op": 0
}
steemdelegated 17.748 SP to @icostan
2019/06/02 00:01:18
delegateeicostan
delegatorsteem
vesting shares28854.534201 VESTS
Transaction InfoBlock #33431975/Trx 3b73f4617fad11d97ebf6f5eb391db5ffbf6495c
View Raw JSON Data
{
  "block": 33431975,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "28854.534201 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-06-02T00:01:18",
  "trx_id": "3b73f4617fad11d97ebf6f5eb391db5ffbf6495c",
  "trx_in_block": 27,
  "virtual_op": 0
}
2019/04/13 13:20:09
authorresteemsupport
bodyHello icostan! Congratulations! This post has been randomly Resteemed! For a chance to get more of your content resteemed join the [Steem Engine Team](https://steemit.com/steemit/@steemengineteam/more-followers-more-votes-steemengine)
json metadata
parent authoricostan
parent permlinkeli5-cryptography-elgamal
permlinkre-eli5-cryptography-elgamal-20190413t132006
title
Transaction InfoBlock #32008862/Trx 30ca621925910a808c10ada642361674e250a481
View Raw JSON Data
{
  "block": 32008862,
  "op": [
    "comment",
    {
      "author": "resteemsupport",
      "body": "Hello icostan!\n\nCongratulations! This post has been randomly Resteemed! For a chance to get more of your content resteemed join the [Steem Engine Team](https://steemit.com/steemit/@steemengineteam/more-followers-more-votes-steemengine)",
      "json_metadata": "",
      "parent_author": "icostan",
      "parent_permlink": "eli5-cryptography-elgamal",
      "permlink": "re-eli5-cryptography-elgamal-20190413t132006",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:20:09",
  "trx_id": "30ca621925910a808c10ada642361674e250a481",
  "trx_in_block": 7,
  "virtual_op": 0
}
icostanpublished a new post: cryptography-ecdsa
2019/04/13 13:19:51
authoricostan
body@@ -1612,16 +1612,19 @@ Basics%0A +--- %0A- Wha @@ -3752,16 +3752,19 @@ gnature%0A +--- %0ALet's s @@ -4383,16 +4383,19 @@ ication%0A +--- %0AGiven t @@ -4930,16 +4930,19 @@ tuition%0A +--- %0ARemembe
json metadata{"tags":["ecdsa","cryptography","discrete","logarithm"],"links":["https://en.wikipedia.org/wiki/Elliptic-curve_cryptography","https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm","http://www.sagemath.org","https://en.wikipedia.org/wiki/Multiplicative_inverse","https://en.wikipedia.org/wiki/Trapdoor_function"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkecdsa
permlinkcryptography-ecdsa
titleCryptography: ECDSA
Transaction InfoBlock #32008856/Trx 465fb3219587d8040e51f81e2d48d1f52b2ad510
View Raw JSON Data
{
  "block": 32008856,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -1612,16 +1612,19 @@\n  Basics%0A\n+---\n %0A-   Wha\n@@ -3752,16 +3752,19 @@\n gnature%0A\n+---\n %0ALet's s\n@@ -4383,16 +4383,19 @@\n ication%0A\n+---\n %0AGiven t\n@@ -4930,16 +4930,19 @@\n tuition%0A\n+---\n %0ARemembe\n",
      "json_metadata": "{\"tags\":[\"ecdsa\",\"cryptography\",\"discrete\",\"logarithm\"],\"links\":[\"https://en.wikipedia.org/wiki/Elliptic-curve_cryptography\",\"https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm\",\"http://www.sagemath.org\",\"https://en.wikipedia.org/wiki/Multiplicative_inverse\",\"https://en.wikipedia.org/wiki/Trapdoor_function\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "ecdsa",
      "permlink": "cryptography-ecdsa",
      "title": "Cryptography: ECDSA"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:19:51",
  "trx_id": "465fb3219587d8040e51f81e2d48d1f52b2ad510",
  "trx_in_block": 14,
  "virtual_op": 0
}
icostanpublished a new post: eli5-cryptography-elgamal
2019/04/13 13:19:06
authoricostan
body@@ -1133,16 +1133,19 @@ rapdoor%0A +--- %0AFirst t @@ -2751,16 +2751,19 @@ ryption%0A +--- %0A%5C%60m%5C%60 i @@ -3085,16 +3085,19 @@ ryption%0A +--- %0ATo decr @@ -3981,16 +3981,19 @@ tuition%0A +--- %0AWhy thi
json metadata{"tags":["cryptography","elgamal","discrete","logarithm","eli5"],"links":["https://en.wikipedia.org/wiki/ElGamal_encryption","https://en.wikipedia.org/wiki/ElGamal_signature_scheme","https://en.wikipedia.org/wiki/Cyclic_group","https://en.wikipedia.org/wiki/Discrete_logarithm","https://en.wikipedia.org/wiki/Additive_inverse","https://en.wikipedia.org/wiki/Finite_field","https://en.wikipedia.org/wiki/Euler%2527s_theorem","https://en.wikipedia.org/wiki/Lagrange%2527s_theorem_(group_theory)"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptography
permlinkeli5-cryptography-elgamal
titleCryptography: ElGamal
Transaction InfoBlock #32008841/Trx bdeeb12143ceba12d919d28819c28a26271ee0b8
View Raw JSON Data
{
  "block": 32008841,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -1133,16 +1133,19 @@\n rapdoor%0A\n+---\n %0AFirst t\n@@ -2751,16 +2751,19 @@\n ryption%0A\n+---\n %0A%5C%60m%5C%60 i\n@@ -3085,16 +3085,19 @@\n ryption%0A\n+---\n %0ATo decr\n@@ -3981,16 +3981,19 @@\n tuition%0A\n+---\n %0AWhy thi\n",
      "json_metadata": "{\"tags\":[\"cryptography\",\"elgamal\",\"discrete\",\"logarithm\",\"eli5\"],\"links\":[\"https://en.wikipedia.org/wiki/ElGamal_encryption\",\"https://en.wikipedia.org/wiki/ElGamal_signature_scheme\",\"https://en.wikipedia.org/wiki/Cyclic_group\",\"https://en.wikipedia.org/wiki/Discrete_logarithm\",\"https://en.wikipedia.org/wiki/Additive_inverse\",\"https://en.wikipedia.org/wiki/Finite_field\",\"https://en.wikipedia.org/wiki/Euler%2527s_theorem\",\"https://en.wikipedia.org/wiki/Lagrange%2527s_theorem_(group_theory)\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptography",
      "permlink": "eli5-cryptography-elgamal",
      "title": "Cryptography: ElGamal"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:19:06",
  "trx_id": "bdeeb12143ceba12d919d28819c28a26271ee0b8",
  "trx_in_block": 0,
  "virtual_op": 0
}
icostanpublished a new post: eli5-cryptography-rsa
2019/04/13 13:18:00
authoricostan
body@@ -1077,17 +1077,20 @@ rapdoor%0A +--- %0A - The very @@ -2324,17 +2324,20 @@ ryption%0A +--- %0A - Now it's @@ -3364,17 +3364,20 @@ ryption%0A +--- %0A - The %5C%60d%5C @@ -4098,16 +4098,19 @@ tuition%0A +--- %0AAt firs
json metadata{"tags":["cryptography","rsa","primes","factorization","eli5"],"links":["https://en.wikipedia.org/wiki/RSA_(cryptosystem)","https://en.wikipedia.org/wiki/Euler's_totient_function","https://en.wikipedia.org/wiki/Coprime_integers","https://en.wikipedia.org/wiki/Trapdoor_function","https://en.wikipedia.org/wiki/Integer_factorization","https://en.wikipedia.org/wiki/Greatest_common_divisor","https://en.wikipedia.org/wiki/Euclidean_algorithm","https://en.wikipedia.org/wiki/Multiplicative_inverse","https://en.wikipedia.org/wiki/Finite_field","https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptography
permlinkeli5-cryptography-rsa
titleCryptography: RSA
Transaction InfoBlock #32008819/Trx 95c0ac96e6bf66ea3f1340e49da10f6952227a98
View Raw JSON Data
{
  "block": 32008819,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -1077,17 +1077,20 @@\n rapdoor%0A\n+---\n %0A\n-\n The very\n@@ -2324,17 +2324,20 @@\n ryption%0A\n+---\n %0A\n-\n Now it's\n@@ -3364,17 +3364,20 @@\n ryption%0A\n+---\n %0A\n-\n The %5C%60d%5C\n@@ -4098,16 +4098,19 @@\n tuition%0A\n+---\n %0AAt firs\n",
      "json_metadata": "{\"tags\":[\"cryptography\",\"rsa\",\"primes\",\"factorization\",\"eli5\"],\"links\":[\"https://en.wikipedia.org/wiki/RSA_(cryptosystem)\",\"https://en.wikipedia.org/wiki/Euler's_totient_function\",\"https://en.wikipedia.org/wiki/Coprime_integers\",\"https://en.wikipedia.org/wiki/Trapdoor_function\",\"https://en.wikipedia.org/wiki/Integer_factorization\",\"https://en.wikipedia.org/wiki/Greatest_common_divisor\",\"https://en.wikipedia.org/wiki/Euclidean_algorithm\",\"https://en.wikipedia.org/wiki/Multiplicative_inverse\",\"https://en.wikipedia.org/wiki/Finite_field\",\"https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptography",
      "permlink": "eli5-cryptography-rsa",
      "title": "Cryptography: RSA"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:18:00",
  "trx_id": "95c0ac96e6bf66ea3f1340e49da10f6952227a98",
  "trx_in_block": 11,
  "virtual_op": 0
}
icostanpublished a new post: cryptography-ecdsa
2019/04/13 13:16:36
authoricostan
body@@ -2303,33 +2303,8 @@ ()%0A%0A -!%5Bimg%5D(/assets/ec1.png)%0A%0A Not @@ -2461,34 +2461,8 @@ ()%0A%0A -!%5Bimg%5D(/assets/ec2.png)%0A%0A%0A # El
json metadata{"tags":["ecdsa","cryptography","discrete","logarithm"],"links":["https://en.wikipedia.org/wiki/Elliptic-curve_cryptography","https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm","http://www.sagemath.org","https://en.wikipedia.org/wiki/Multiplicative_inverse","https://en.wikipedia.org/wiki/Trapdoor_function"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkecdsa
permlinkcryptography-ecdsa
titleCryptography: ECDSA
Transaction InfoBlock #32008791/Trx b4154570b0007f5f7c6d269ad4571f1f4ddc9f45
View Raw JSON Data
{
  "block": 32008791,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -2303,33 +2303,8 @@\n ()%0A%0A\n-!%5Bimg%5D(/assets/ec1.png)%0A%0A\n Not \n@@ -2461,34 +2461,8 @@\n ()%0A%0A\n-!%5Bimg%5D(/assets/ec2.png)%0A%0A%0A\n # El\n",
      "json_metadata": "{\"tags\":[\"ecdsa\",\"cryptography\",\"discrete\",\"logarithm\"],\"links\":[\"https://en.wikipedia.org/wiki/Elliptic-curve_cryptography\",\"https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm\",\"http://www.sagemath.org\",\"https://en.wikipedia.org/wiki/Multiplicative_inverse\",\"https://en.wikipedia.org/wiki/Trapdoor_function\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "ecdsa",
      "permlink": "cryptography-ecdsa",
      "title": "Cryptography: ECDSA"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:16:36",
  "trx_id": "b4154570b0007f5f7c6d269ad4571f1f4ddc9f45",
  "trx_in_block": 8,
  "virtual_op": 0
}
icostanpublished a new post: cryptography-ecdsa
2019/04/13 13:12:15
authoricostan
body# Overview --- "If you can't explain it simply, you don't understand it well enough" - Einstein --- Elliptic curve cryptography ([ECC](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)) and digital signature algorithm ([ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)) are more complex than RSA or ElGamal but I will try my best to hide the hairy math and the implementation details. Here is the ELI5 version in 18 lines of [SageMath](http://www.sagemath.org) / Python code. I use Sage because it provides elliptic curves as first-class citizens (\`FiniteField\` and \`EllipticCurve\`) and we can take multiplication operation for granted. 1 p = 103 2 F = FiniteField(p) 3 E = EllipticCurve(F, [0, 7]) 4 G = E([97, 10]) 5 n = G.order() 6 k = randint(2, n) 7 P = k * G 8 m = 6 9 t = randint(2, n) 10 R = t * G 11 r = mod(R[0], n) 12 s = mod(inverse_mod(t, n) * (m + r * k), n) 13 inv_s = inverse_mod(int(s), n) 14 u = mod(m * inv_s, n) 15 v = mod(r * inv_s, n) 16 F = int(u) * G + int(v) * P 17 f = mod(F[0], n) 18 print "YOU ARE A CRYPTOSTAR!" if r == f else "YOU SUCK!" YOU ARE A CRYPTOSTAR! Besides lines #7, #10 and #16 that involves multiplication between a scalar and a point on elliptic curve, everything else is just modular arithmetic and two [multiplicative inverse](https://en.wikipedia.org/wiki/Multiplicative_inverse) calculations (line #12 and #13) Please keep reading if you want line by line explanations and a few elliptic curve graphs. # Basics - What the heck is an elliptic curve? - It is just a simple equation of this form \`y2 = x3 + ax + b\`. - Why it is so special? - Because it has one interesting operation: addition. Adding two points on the curve will result a third point also on the curve (aka closure). Multiplication is particular case of addition, adding the same point to itself \`k\` times. - And how does it looks like? - Well, I am afraid you won't like the graph because elliptic curves defined over finite fields get cut off and are not intelligible to humans eye But here it is anyway: \`a = 0; b = 7\` and prime number is \`103\`. E = EllipticCurve(FiniteField(103), [0, 7]) E.plot() ![img](/assets/ec1.png) Not pretty huh? lets define the same elliptic curve over real numbers and the graph starts to make little sense. E = EllipticCurve([0, 7]) E.plot() ![img](/assets/ec2.png) # Elliptic curve multiplication trapdoor First thing first, let's define the elliptic curve parameters and notations: 1 p = 103 2 F = FiniteField(p) 3 E = EllipticCurve(F, [0, 7]) 4 G = E([97, 10]) 5 n = G.order() Variable notations: - uppercase letter - elements of the elliptic curve like finite fields (F), elliptic curve itself (E) or point on elliptic curve (G) - lowercase letter - scalar value like the secret key (k) Domain parameters: - p - prime number - F - finite field - 0,7 - coefficients for elliptic curve - E - elliptic curve - G - point generator - n - order (the number of points) of the cyclic subgroup generated by \`G\` Now, it's time to generate the secret key \`k\` and calculate the public key \`P\` using the trapdoor function called Elliptic Curve Discrete Logarithm Problem (ECDLP). This is the bread and the butter of elliptic curve cryptography, given the generator \`G\` and public key \`P' it is infeasible to calculate the secret key \`k\`, hence the [trapdoor](https://en.wikipedia.org/wiki/Trapdoor_function) 6 k = randint(2, n) 7 P = k * G If you are curious how elliptic curve point \`P\` looks like then it is nothing than a Cartesian (x,y) coordinate: P (65 : 31 : 1) # Signature Let's sign the message \`m\` and for this we need to generate a random integer \`t\` of order \`n\` and calculate the \`R\` point on elliptic curve. 8 m = 6 9 t = randint(2, n) 10 R = t * G 11 r = mod(R[0], n) 12 s = mod(inverse_mod(t, n) * (m + r * k), n) The signature itself has two numbers \`r\` and \`s\` that are sent to third-party for verification: - r - the \`x\` coordinate of point \`R\` - s - is calculated with \`s = (m + r\*k) / t\` but we use multiplication with inverse instead of division. And this is how our signature looks like: [r, s] [66, 51] # Verification Given the signature \`r, s\` above and \`G, P, r and n\` that are public information we need to calculate the equation \`F = u\*G + v\*P\` where \`u = m/s\` and \`v = r/s\`. The signature is valid if \`R.x == F.x\` is true, in other words the \`x\` coordinates are the same. 13 inv_s = inverse_mod(int(s), n) 14 u = mod(m * inv_s, n) 15 v = mod(r * inv_s, n) 16 F = int(u) * G + int(v) * P 17 f = mod(F[0], n) 18 print "YOU ARE A CRYPTOSTAR!" if r == f else "YOU SUCK!" YOU ARE A CRYPTOSTAR! # Intuition Remember that uppercase letters are points on elliptic curve, lowercase are scalars: 1 R == u*G + v*P 2 R == u*G + v*k*P 3 R == m/s * G + r/s * k*G 4 R == m/s * G + r*k/s * G 5 R == (m + r*k)/s * G 6 R == (m + r*k)/((m + r*k)/t) * G As always we will do the math backwards: 1. start with the equation of signature verification and substitute public key \`P\` 2. substitute \`u\` and \`v\` 3. multiplication is commutative and we can put \`r\` and \`k\` together 4. extract \`G\` and \`s\` as factors 5. substitute \`s\` 6. after reduction we are left with \`t\*G\` And the intuition is valid if the \`x\` coordinates on both sides of the equation are equal. print "MAGIC" if R[0] == (int((m + r*k)*t/(m + r*k)) * G)[0] else "ERROR" MAGIC
json metadata{"tags":["cryptography","ecdsa","discrete","logarithm"],"links":["https://en.wikipedia.org/wiki/Elliptic-curve_cryptography","https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm","http://www.sagemath.org","https://en.wikipedia.org/wiki/Multiplicative_inverse","https://en.wikipedia.org/wiki/Trapdoor_function"],"app":"steemit/0.1","format":"markdown","image":["/assets/ec1.png","/assets/ec2.png"]}
parent author
parent permlinkecdsa
permlinkcryptography-ecdsa
titleCryptography: ECDSA
Transaction InfoBlock #32008705/Trx 24e20a1bb7d8ca417bcec8a50f797012fa039eaf
View Raw JSON Data
{
  "block": 32008705,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "# Overview\n---\n\n    \"If you can't explain it simply, you don't understand it well enough\" - Einstein\n---\nElliptic curve cryptography ([ECC](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)) and digital signature algorithm ([ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)) are more complex than RSA or ElGamal but I will try my best to hide the hairy math and the implementation details.\n\nHere is the ELI5 version in 18 lines of [SageMath](http://www.sagemath.org) / Python code. I use Sage because it provides elliptic curves as first-class citizens (\\`FiniteField\\` and \\`EllipticCurve\\`) and we can take multiplication operation for granted.\n\n     1  p = 103\n     2  F = FiniteField(p)\n     3  E = EllipticCurve(F, [0, 7])\n     4  G = E([97, 10])\n     5  n = G.order()\n     6  k = randint(2, n)\n     7  P = k * G\n     8  m = 6\n     9  t = randint(2, n)\n    10  R = t * G\n    11  r = mod(R[0], n)\n    12  s = mod(inverse_mod(t, n) * (m + r * k), n)\n    13  inv_s = inverse_mod(int(s), n)\n    14  u = mod(m * inv_s, n)\n    15  v = mod(r * inv_s, n)\n    16  F = int(u) * G + int(v) * P\n    17  f = mod(F[0], n)\n    18  print \"YOU ARE A CRYPTOSTAR!\" if r == f else \"YOU SUCK!\"\n\n    YOU ARE A CRYPTOSTAR!\n\nBesides lines #7, #10 and #16 that involves multiplication between a scalar and a point on elliptic curve, everything else is just modular arithmetic and two [multiplicative inverse](https://en.wikipedia.org/wiki/Multiplicative_inverse) calculations (line #12 and #13)\n\nPlease keep reading if you want line by line explanations and a few elliptic curve graphs.\n\n\n# Basics\n\n-   What the heck is an elliptic curve?\n-   It is just a simple equation of this form \\`y2 = x3 + ax + b\\`.\n-   Why it is so special?\n-   Because it has one interesting operation: addition. Adding two points on the curve will result a third point also on the curve (aka closure). Multiplication is particular case of addition, adding the same point to itself \\`k\\` times.\n-   And how does it looks like?\n-   Well, I am afraid you won't like the graph because elliptic curves defined over finite fields get cut off and are not intelligible to humans eye\n\nBut here it is anyway: \\`a = 0; b = 7\\` and prime number is \\`103\\`.\n\n    E = EllipticCurve(FiniteField(103), [0, 7])\n    E.plot()\n\n![img](/assets/ec1.png)\n\nNot pretty huh? lets define the same elliptic curve over real numbers and the graph starts to make little sense.\n\n    E = EllipticCurve([0, 7])\n    E.plot()\n\n![img](/assets/ec2.png)\n\n\n# Elliptic curve multiplication trapdoor\n\nFirst thing first, let's define the elliptic curve parameters and notations:\n\n    1  p = 103\n    2  F = FiniteField(p)\n    3  E = EllipticCurve(F, [0, 7])\n    4  G = E([97, 10])\n    5  n = G.order()\n\nVariable notations:\n\n-   uppercase letter - elements of the elliptic curve like finite fields (F), elliptic curve itself (E) or point on elliptic curve (G)\n-   lowercase letter - scalar value like the secret key (k)\n\nDomain parameters:\n\n-   p - prime number\n-   F - finite field\n-   0,7 - coefficients for elliptic curve\n-   E - elliptic curve\n-   G - point generator\n-   n - order (the number of points) of the cyclic subgroup generated by \\`G\\`\n\nNow, it's time to generate the secret key \\`k\\` and calculate the public key \\`P\\` using the trapdoor function called Elliptic Curve Discrete Logarithm Problem (ECDLP).\n\nThis is the bread and the butter of elliptic curve cryptography, given the generator \\`G\\` and public key \\`P' it is infeasible to calculate the secret key \\`k\\`, hence the [trapdoor](https://en.wikipedia.org/wiki/Trapdoor_function)\n\n    6  k = randint(2, n)\n    7  P = k * G\n\nIf you are curious how elliptic curve point \\`P\\` looks like then it is nothing than a Cartesian (x,y) coordinate:\n\n    P\n\n    (65 : 31 : 1)\n\n\n# Signature\n\nLet's sign the message \\`m\\` and for this we need to generate a random integer \\`t\\` of order \\`n\\` and calculate the \\`R\\` point on elliptic curve.\n\n     8  m = 6\n     9  t = randint(2, n)\n    10  R = t * G\n    11  r = mod(R[0], n)\n    12  s = mod(inverse_mod(t, n) * (m + r * k), n)\n\nThe signature itself has two numbers \\`r\\` and \\`s\\` that are sent to third-party for verification:\n\n-   r - the \\`x\\` coordinate of point \\`R\\`\n-   s - is calculated with \\`s = (m + r\\*k) / t\\` but we use multiplication with inverse instead of division.\n\nAnd this is how our signature looks like:\n\n    [r, s]\n\n    [66, 51]\n\n\n# Verification\n\nGiven the signature \\`r, s\\` above and \\`G, P, r and n\\` that are public information we need to calculate the equation \\`F = u\\*G + v\\*P\\` where \\`u = m/s\\` and \\`v = r/s\\`.\n\nThe signature is valid if \\`R.x == F.x\\` is true, in other words the \\`x\\` coordinates are the same.\n\n    13  inv_s = inverse_mod(int(s), n)\n    14  u = mod(m * inv_s, n)\n    15  v = mod(r * inv_s, n)\n    16  F = int(u) * G + int(v) * P\n    17  f = mod(F[0], n)\n    18  print \"YOU ARE A CRYPTOSTAR!\" if r == f else \"YOU SUCK!\"\n\n    YOU ARE A CRYPTOSTAR!\n\n\n# Intuition\n\nRemember that uppercase letters are points on elliptic curve, lowercase are scalars:\n\n    1  R == u*G + v*P\n    2  R == u*G + v*k*P\n    3  R == m/s * G + r/s * k*G\n    4  R == m/s * G + r*k/s * G\n    5  R == (m + r*k)/s * G\n    6  R == (m + r*k)/((m + r*k)/t) * G\n\nAs always we will do the math backwards:\n\n1.  start with the equation of signature verification and substitute public key \\`P\\`\n2.  substitute \\`u\\` and \\`v\\`\n3.  multiplication is commutative and we can put \\`r\\` and \\`k\\` together\n4.  extract \\`G\\` and \\`s\\` as factors\n5.  substitute \\`s\\`\n6.  after reduction we are left with \\`t\\*G\\`\n\nAnd the intuition is valid if the \\`x\\` coordinates on both sides of the equation are equal.\n\n    print \"MAGIC\" if R[0] == (int((m + r*k)*t/(m + r*k)) * G)[0] else \"ERROR\"\n\n    MAGIC",
      "json_metadata": "{\"tags\":[\"cryptography\",\"ecdsa\",\"discrete\",\"logarithm\"],\"links\":[\"https://en.wikipedia.org/wiki/Elliptic-curve_cryptography\",\"https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm\",\"http://www.sagemath.org\",\"https://en.wikipedia.org/wiki/Multiplicative_inverse\",\"https://en.wikipedia.org/wiki/Trapdoor_function\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\",\"image\":[\"/assets/ec1.png\",\"/assets/ec2.png\"]}",
      "parent_author": "",
      "parent_permlink": "ecdsa",
      "permlink": "cryptography-ecdsa",
      "title": "Cryptography: ECDSA"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:12:15",
  "trx_id": "24e20a1bb7d8ca417bcec8a50f797012fa039eaf",
  "trx_in_block": 18,
  "virtual_op": 0
}
icostanpublished a new post: eli5-cryptography-rsa
2019/04/13 13:11:24
authoricostan
body@@ -4,16 +4,19 @@ verview%0A +--- %0A %22If
json metadata{"tags":["cryptography","rsa","primes","factorization","eli5"],"links":["https://en.wikipedia.org/wiki/RSA_(cryptosystem)","https://en.wikipedia.org/wiki/Euler's_totient_function","https://en.wikipedia.org/wiki/Coprime_integers","https://en.wikipedia.org/wiki/Trapdoor_function","https://en.wikipedia.org/wiki/Integer_factorization","https://en.wikipedia.org/wiki/Greatest_common_divisor","https://en.wikipedia.org/wiki/Euclidean_algorithm","https://en.wikipedia.org/wiki/Multiplicative_inverse","https://en.wikipedia.org/wiki/Finite_field","https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptography
permlinkeli5-cryptography-rsa
titleCryptography: RSA
Transaction InfoBlock #32008688/Trx 71b22b4eb83e9e8b4ae54278b0b4632ea272e69e
View Raw JSON Data
{
  "block": 32008688,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -4,16 +4,19 @@\n verview%0A\n+---\n %0A    %22If\n",
      "json_metadata": "{\"tags\":[\"cryptography\",\"rsa\",\"primes\",\"factorization\",\"eli5\"],\"links\":[\"https://en.wikipedia.org/wiki/RSA_(cryptosystem)\",\"https://en.wikipedia.org/wiki/Euler's_totient_function\",\"https://en.wikipedia.org/wiki/Coprime_integers\",\"https://en.wikipedia.org/wiki/Trapdoor_function\",\"https://en.wikipedia.org/wiki/Integer_factorization\",\"https://en.wikipedia.org/wiki/Greatest_common_divisor\",\"https://en.wikipedia.org/wiki/Euclidean_algorithm\",\"https://en.wikipedia.org/wiki/Multiplicative_inverse\",\"https://en.wikipedia.org/wiki/Finite_field\",\"https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptography",
      "permlink": "eli5-cryptography-rsa",
      "title": "Cryptography: RSA"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:11:24",
  "trx_id": "71b22b4eb83e9e8b4ae54278b0b4632ea272e69e",
  "trx_in_block": 5,
  "virtual_op": 0
}
icostanpublished a new post: eli5-cryptography-elgamal
2019/04/13 13:10:48
authoricostan
body@@ -4,16 +4,19 @@ verview%0A +--- %0A %22If @@ -92,16 +92,20 @@ Einstein +%0A--- %0A%0AElGama
json metadata{"tags":["cryptography","elgamal","discrete","logarithm","eli5"],"links":["https://en.wikipedia.org/wiki/ElGamal_encryption","https://en.wikipedia.org/wiki/ElGamal_signature_scheme","https://en.wikipedia.org/wiki/Cyclic_group","https://en.wikipedia.org/wiki/Discrete_logarithm","https://en.wikipedia.org/wiki/Additive_inverse","https://en.wikipedia.org/wiki/Finite_field","https://en.wikipedia.org/wiki/Euler%2527s_theorem","https://en.wikipedia.org/wiki/Lagrange%2527s_theorem_(group_theory)"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptography
permlinkeli5-cryptography-elgamal
titleCryptography: ElGamal
Transaction InfoBlock #32008676/Trx cc641331f751126d3f588cec2ac1ea401e6d2545
View Raw JSON Data
{
  "block": 32008676,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -4,16 +4,19 @@\n verview%0A\n+---\n %0A    %22If\n@@ -92,16 +92,20 @@\n Einstein\n+%0A---\n %0A%0AElGama\n",
      "json_metadata": "{\"tags\":[\"cryptography\",\"elgamal\",\"discrete\",\"logarithm\",\"eli5\"],\"links\":[\"https://en.wikipedia.org/wiki/ElGamal_encryption\",\"https://en.wikipedia.org/wiki/ElGamal_signature_scheme\",\"https://en.wikipedia.org/wiki/Cyclic_group\",\"https://en.wikipedia.org/wiki/Discrete_logarithm\",\"https://en.wikipedia.org/wiki/Additive_inverse\",\"https://en.wikipedia.org/wiki/Finite_field\",\"https://en.wikipedia.org/wiki/Euler%2527s_theorem\",\"https://en.wikipedia.org/wiki/Lagrange%2527s_theorem_(group_theory)\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptography",
      "permlink": "eli5-cryptography-elgamal",
      "title": "Cryptography: ElGamal"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:10:48",
  "trx_id": "cc641331f751126d3f588cec2ac1ea401e6d2545",
  "trx_in_block": 2,
  "virtual_op": 0
}
icostanpublished a new post: cryptography-ecdsa
2019/04/13 13:09:42
authoricostan
body# Overview --- "If you can't explain it simply, you don't understand it well enough" - Einstein --- Elliptic curve cryptography ([ECC](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)) and digital signature algorithm ([ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)) are more complex than RSA or ElGamal but I will try my best to hide the hairy math and the implementation details. Here is the ELI5 version in 18 lines of [SageMath](http://www.sagemath.org) / Python code. I use Sage because it provides elliptic curves as first-class citizens (\`FiniteField\` and \`EllipticCurve\`) and we can take multiplication operation for granted. 1 p = 103 2 F = FiniteField(p) 3 E = EllipticCurve(F, [0, 7]) 4 G = E([97, 10]) 5 n = G.order() 6 k = randint(2, n) 7 P = k * G 8 m = 6 9 t = randint(2, n) 10 R = t * G 11 r = mod(R[0], n) 12 s = mod(inverse_mod(t, n) * (m + r * k), n) 13 inv_s = inverse_mod(int(s), n) 14 u = mod(m * inv_s, n) 15 v = mod(r * inv_s, n) 16 F = int(u) * G + int(v) * P 17 f = mod(F[0], n) 18 print "YOU ARE A CRYPTOSTAR!" if r == f else "YOU SUCK!" YOU ARE A CRYPTOSTAR! Besides lines #7, #10 and #16 that involves multiplication between a scalar and a point on elliptic curve, everything else is just modular arithmetic and two [multiplicative inverse](https://en.wikipedia.org/wiki/Multiplicative_inverse) calculations (line #12 and #13) Please keep reading if you want line by line explanations and a few elliptic curve graphs. # Basics - What the heck is an elliptic curve? - It is just a simple equation of this form \`y2 = x3 + ax + b\`. - Why it is so special? - Because it has one interesting operation: addition. Adding two points on the curve will result a third point also on the curve (aka closure). Multiplication is particular case of addition, adding the same point to itself \`k\` times. - And how does it looks like? - Well, I am afraid you won't like the graph because elliptic curves defined over finite fields get cut off and are not intelligible to humans eye But here it is anyway: \`a = 0; b = 7\` and prime number is \`103\`. E = EllipticCurve(FiniteField(103), [0, 7]) E.plot() ![img](/assets/ec1.png) Not pretty huh? lets define the same elliptic curve over real numbers and the graph starts to make little sense. E = EllipticCurve([0, 7]) E.plot() ![img](/assets/ec2.png) # Elliptic curve multiplication trapdoor First thing first, let's define the elliptic curve parameters and notations: 1 p = 103 2 F = FiniteField(p) 3 E = EllipticCurve(F, [0, 7]) 4 G = E([97, 10]) 5 n = G.order() Variable notations: - uppercase letter - elements of the elliptic curve like finite fields (F), elliptic curve itself (E) or point on elliptic curve (G) - lowercase letter - scalar value like the secret key (k) Domain parameters: - p - prime number - F - finite field - 0,7 - coefficients for elliptic curve - E - elliptic curve - G - point generator - n - order (the number of points) of the cyclic subgroup generated by \`G\` Now, it's time to generate the secret key \`k\` and calculate the public key \`P\` using the trapdoor function called Elliptic Curve Discrete Logarithm Problem (ECDLP). This is the bread and the butter of elliptic curve cryptography, given the generator \`G\` and public key \`P' it is infeasible to calculate the secret key \`k\`, hence the [trapdoor](https://en.wikipedia.org/wiki/Trapdoor_function) 6 k = randint(2, n) 7 P = k * G If you are curious how elliptic curve point \`P\` looks like then it is nothing than a Cartesian (x,y) coordinate: P (65 : 31 : 1) # Signature Let's sign the message \`m\` and for this we need to generate a random integer \`t\` of order \`n\` and calculate the \`R\` point on elliptic curve. 8 m = 6 9 t = randint(2, n) 10 R = t * G 11 r = mod(R[0], n) 12 s = mod(inverse_mod(t, n) * (m + r * k), n) The signature itself has two numbers \`r\` and \`s\` that are sent to third-party for verification: - r - the \`x\` coordinate of point \`R\` - s - is calculated with \`s = (m + r\*k) / t\` but we use multiplication with inverse instead of division. And this is how our signature looks like: [r, s] [66, 51] # Verification Given the signature \`r, s\` above and \`G, P, r and n\` that are public information we need to calculate the equation \`F = u\*G + v\*P\` where \`u = m/s\` and \`v = r/s\`. The signature is valid if \`R.x == F.x\` is true, in other words the \`x\` coordinates are the same. 13 inv_s = inverse_mod(int(s), n) 14 u = mod(m * inv_s, n) 15 v = mod(r * inv_s, n) 16 F = int(u) * G + int(v) * P 17 f = mod(F[0], n) 18 print "YOU ARE A CRYPTOSTAR!" if r == f else "YOU SUCK!" YOU ARE A CRYPTOSTAR! # Intuition Remember that uppercase letters are points on elliptic curve, lowercase are scalars: 1 R == u*G + v*P 2 R == u*G + v*k*P 3 R == m/s * G + r/s * k*G 4 R == m/s * G + r*k/s * G 5 R == (m + r*k)/s * G 6 R == (m + r*k)/((m + r*k)/t) * G As always we will do the math backwards: 1. start with the equation of signature verification and substitute public key \`P\` 2. substitute \`u\` and \`v\` 3. multiplication is commutative and we can put \`r\` and \`k\` together 4. extract \`G\` and \`s\` as factors 5. substitute \`s\` 6. after reduction we are left with \`t\*G\` And the intuition is valid if the \`x\` coordinates on both sides of the equation are equal. print "MAGIC" if R[0] == (int((m + r*k)*t/(m + r*k)) * G)[0] else "ERROR" MAGIC
json metadata{"tags":["ecdsa","cryptography","python","ecc"],"image":["/assets/ec1.png","/assets/ec2.png"],"links":["https://en.wikipedia.org/wiki/Elliptic-curve_cryptography","https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm","http://www.sagemath.org","https://en.wikipedia.org/wiki/Multiplicative_inverse","https://en.wikipedia.org/wiki/Trapdoor_function"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkecdsa
permlinkcryptography-ecdsa
titleCryptography: ECDSA
Transaction InfoBlock #32008654/Trx ad5c64ceb30d7f8615a6e50baab933220cd14116
View Raw JSON Data
{
  "block": 32008654,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "# Overview\n---\n\n    \"If you can't explain it simply, you don't understand it well enough\" - Einstein\n---\nElliptic curve cryptography ([ECC](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)) and digital signature algorithm ([ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)) are more complex than RSA or ElGamal but I will try my best to hide the hairy math and the implementation details.\n\nHere is the ELI5 version in 18 lines of [SageMath](http://www.sagemath.org) / Python code. I use Sage because it provides elliptic curves as first-class citizens (\\`FiniteField\\` and \\`EllipticCurve\\`) and we can take multiplication operation for granted.\n\n     1  p = 103\n     2  F = FiniteField(p)\n     3  E = EllipticCurve(F, [0, 7])\n     4  G = E([97, 10])\n     5  n = G.order()\n     6  k = randint(2, n)\n     7  P = k * G\n     8  m = 6\n     9  t = randint(2, n)\n    10  R = t * G\n    11  r = mod(R[0], n)\n    12  s = mod(inverse_mod(t, n) * (m + r * k), n)\n    13  inv_s = inverse_mod(int(s), n)\n    14  u = mod(m * inv_s, n)\n    15  v = mod(r * inv_s, n)\n    16  F = int(u) * G + int(v) * P\n    17  f = mod(F[0], n)\n    18  print \"YOU ARE A CRYPTOSTAR!\" if r == f else \"YOU SUCK!\"\n\n    YOU ARE A CRYPTOSTAR!\n\nBesides lines #7, #10 and #16 that involves multiplication between a scalar and a point on elliptic curve, everything else is just modular arithmetic and two [multiplicative inverse](https://en.wikipedia.org/wiki/Multiplicative_inverse) calculations (line #12 and #13)\n\nPlease keep reading if you want line by line explanations and a few elliptic curve graphs.\n\n\n# Basics\n\n-   What the heck is an elliptic curve?\n-   It is just a simple equation of this form \\`y2 = x3 + ax + b\\`.\n-   Why it is so special?\n-   Because it has one interesting operation: addition. Adding two points on the curve will result a third point also on the curve (aka closure). Multiplication is particular case of addition, adding the same point to itself \\`k\\` times.\n-   And how does it looks like?\n-   Well, I am afraid you won't like the graph because elliptic curves defined over finite fields get cut off and are not intelligible to humans eye\n\nBut here it is anyway: \\`a = 0; b = 7\\` and prime number is \\`103\\`.\n\n    E = EllipticCurve(FiniteField(103), [0, 7])\n    E.plot()\n\n![img](/assets/ec1.png)\n\nNot pretty huh? lets define the same elliptic curve over real numbers and the graph starts to make little sense.\n\n    E = EllipticCurve([0, 7])\n    E.plot()\n\n![img](/assets/ec2.png)\n\n\n# Elliptic curve multiplication trapdoor\n\nFirst thing first, let's define the elliptic curve parameters and notations:\n\n    1  p = 103\n    2  F = FiniteField(p)\n    3  E = EllipticCurve(F, [0, 7])\n    4  G = E([97, 10])\n    5  n = G.order()\n\nVariable notations:\n\n-   uppercase letter - elements of the elliptic curve like finite fields (F), elliptic curve itself (E) or point on elliptic curve (G)\n-   lowercase letter - scalar value like the secret key (k)\n\nDomain parameters:\n\n-   p - prime number\n-   F - finite field\n-   0,7 - coefficients for elliptic curve\n-   E - elliptic curve\n-   G - point generator\n-   n - order (the number of points) of the cyclic subgroup generated by \\`G\\`\n\nNow, it's time to generate the secret key \\`k\\` and calculate the public key \\`P\\` using the trapdoor function called Elliptic Curve Discrete Logarithm Problem (ECDLP).\n\nThis is the bread and the butter of elliptic curve cryptography, given the generator \\`G\\` and public key \\`P' it is infeasible to calculate the secret key \\`k\\`, hence the [trapdoor](https://en.wikipedia.org/wiki/Trapdoor_function)\n\n    6  k = randint(2, n)\n    7  P = k * G\n\nIf you are curious how elliptic curve point \\`P\\` looks like then it is nothing than a Cartesian (x,y) coordinate:\n\n    P\n\n    (65 : 31 : 1)\n\n\n# Signature\n\nLet's sign the message \\`m\\` and for this we need to generate a random integer \\`t\\` of order \\`n\\` and calculate the \\`R\\` point on elliptic curve.\n\n     8  m = 6\n     9  t = randint(2, n)\n    10  R = t * G\n    11  r = mod(R[0], n)\n    12  s = mod(inverse_mod(t, n) * (m + r * k), n)\n\nThe signature itself has two numbers \\`r\\` and \\`s\\` that are sent to third-party for verification:\n\n-   r - the \\`x\\` coordinate of point \\`R\\`\n-   s - is calculated with \\`s = (m + r\\*k) / t\\` but we use multiplication with inverse instead of division.\n\nAnd this is how our signature looks like:\n\n    [r, s]\n\n    [66, 51]\n\n\n# Verification\n\nGiven the signature \\`r, s\\` above and \\`G, P, r and n\\` that are public information we need to calculate the equation \\`F = u\\*G + v\\*P\\` where \\`u = m/s\\` and \\`v = r/s\\`.\n\nThe signature is valid if \\`R.x == F.x\\` is true, in other words the \\`x\\` coordinates are the same.\n\n    13  inv_s = inverse_mod(int(s), n)\n    14  u = mod(m * inv_s, n)\n    15  v = mod(r * inv_s, n)\n    16  F = int(u) * G + int(v) * P\n    17  f = mod(F[0], n)\n    18  print \"YOU ARE A CRYPTOSTAR!\" if r == f else \"YOU SUCK!\"\n\n    YOU ARE A CRYPTOSTAR!\n\n\n# Intuition\n\nRemember that uppercase letters are points on elliptic curve, lowercase are scalars:\n\n    1  R == u*G + v*P\n    2  R == u*G + v*k*P\n    3  R == m/s * G + r/s * k*G\n    4  R == m/s * G + r*k/s * G\n    5  R == (m + r*k)/s * G\n    6  R == (m + r*k)/((m + r*k)/t) * G\n\nAs always we will do the math backwards:\n\n1.  start with the equation of signature verification and substitute public key \\`P\\`\n2.  substitute \\`u\\` and \\`v\\`\n3.  multiplication is commutative and we can put \\`r\\` and \\`k\\` together\n4.  extract \\`G\\` and \\`s\\` as factors\n5.  substitute \\`s\\`\n6.  after reduction we are left with \\`t\\*G\\`\n\nAnd the intuition is valid if the \\`x\\` coordinates on both sides of the equation are equal.\n\n    print \"MAGIC\" if R[0] == (int((m + r*k)*t/(m + r*k)) * G)[0] else \"ERROR\"\n\n    MAGIC",
      "json_metadata": "{\"tags\":[\"ecdsa\",\"cryptography\",\"python\",\"ecc\"],\"image\":[\"/assets/ec1.png\",\"/assets/ec2.png\"],\"links\":[\"https://en.wikipedia.org/wiki/Elliptic-curve_cryptography\",\"https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm\",\"http://www.sagemath.org\",\"https://en.wikipedia.org/wiki/Multiplicative_inverse\",\"https://en.wikipedia.org/wiki/Trapdoor_function\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "ecdsa",
      "permlink": "cryptography-ecdsa",
      "title": "Cryptography: ECDSA"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-04-13T13:09:42",
  "trx_id": "ad5c64ceb30d7f8615a6e50baab933220cd14116",
  "trx_in_block": 12,
  "virtual_op": 0
}
icostanpublished a new post: eli5-cryptography-elgamal
2019/03/27 13:27:09
authoricostan
body# Overview "If you can't explain it simply, you don't understand it well enough" - Einstein ElGamal is a public key cryptosystem that is used in [encryption](https://en.wikipedia.org/wiki/ElGamal_encryption) , [digital signature](https://en.wikipedia.org/wiki/ElGamal_signature_scheme) and homomorphic cryptography. Here is my take in 12 lines of Python code: 1 p = 7 2 g = [x for x in range(1, p) if len(set([x**i % p for i in range(1, p)])) == p-1][0] 3 k = 4 4 t = g**k % p 5 m = 6 6 import random 7 r = random.randint(1, p-1) 8 c1 = g**r % p 9 c2 = (t**r * m) % p 10 inv_k = p - 1 - k 11 inv_c1 = c1**inv_k % p 12 message = c2 * inv_c1 % p 13 print "YOU ARE A CRYPTOSTAR!" if message == m else "ERROR" YOU ARE A CRYPTOSTAR! Besides line #2 that involves an algorithm to find the generator \`g\` and line #10 that calculates the additive inverse of private key \`k\`, everything else is just modular multiplication and exponentiation. Interested in more details and line by line explanations? please read on. # Discrete logarithm trapdoor First thing first, lets pick a prime number: 1 p = 7 For the prime number above we need to find the generator \`g\` that defines a [cyclic group](https://en.wikipedia.org/wiki/Cyclic_group) which in theory is a little bit involved but in simple terms the generator is a specific number that returns unique values for each exponent between \`1\` and \`p-1\` where \`p-1\` is called the order of the cyclic group. Lets take a few examples and see how it looks like: pick \`2\` as generator: print [2**i % p for i in range(1, p)] [2, 4, 1, 2, 4, 1] We can easily see that returning values are not unique, lets pick \`3\` as generator: print [3**i % p for i in range(1, p)] [3, 2, 6, 4, 5, 1] BINGO! returning values are unique and we've found our generator. The line below is just a brute force algorithm that finds multiple generators of order \`p-1\` but only takes the first one that is found. 2 g = [x for x in range(1, p) if len(set([x**i % p for i in range(1, p)])) == p-1][0] Now is time to pick a private key \`k\` between \`1\` and \`p-1\`, execute the trapdoor function and calculate \`t\` value: 3 k = 4 4 t = g**k % p The line #4 is the secret sauce of ElGamal cryptography, the trapdoor function called [**the discrete logarithm**](https://en.wikipedia.org/wiki/Discrete_logarithm) which says that for given \`g\` and \`t\` values it is **infeasible** to calculate the private key \`k\` when working with very large numbers. The \`p, g and t\` form the public key and will be used in encryption below, while \`k\` is kept secret. # Message encryption \`m\` is the message that we want to encrypt and \`r\` is a random number between \`1\` and \`p-1\`: 5 m = 6 6 import random 7 r = random.randint(1, p-1) 8 c1 = g**r % p 9 c2 = (t**r * m) % p \`c1, c2\` are the encrypted ciphers that will be used to decrypt the original message. # Message decryption To decrypt the original message we need apply the following formula: \`message = c2 / c1<sup>k</sup> mod p\` The problem is that division is not an operation defined for finite fields but multiplication is and we can re-write it using multiplication / exponentiation operations only: \`message = c2 \* c1<sup>inv</sup><sub>k</sub> mod p\` \`inv<sub>k</sub>\` is called [additive inverse](https://en.wikipedia.org/wiki/Additive_inverse) of \`k\` over [finite field](https://en.wikipedia.org/wiki/Finite_field) 'p' where \`k + inv<sub>k</sub> mod p = 0\` is valid. We can brute force and find it but there is a simpler way: if \`k < p\` (which it is) then \`inv<sub>k</sub> = p - 1 - k\`. 10 inv_k = p - 1 - k 11 inv_c1 = c1**inv_k % p 12 message = c2 * inv_c1 % p 13 print "YOU ARE A CRYPTOSTAR!" if message == m else "ERROR" YOU ARE A CRYPTOSTAR! # Intuition Why this magic works the way it works? 1 message == (c2 * inv_c1) % p 2 message == (c2 * c1**(p-1-k)) % p 3 message == (t**r * m * (g**r)**(p-1-k)) % p 4 message == ((g**k)**r * m * (g**r)**(p-1-k)) % p 5 message == (g**(k*r) * m * (g**(r*(p-1-k)))) % p 6 message == (g**(k*r) * m * g**(r*(p-1)) * g**(-r*k)) % p Lets do the math backwards: 1. start with last decryption formula and substitute inverses \`inv<sub>c1</sub>\` and \`inv<sub>k</sub>\` 2. substitute ciphers \`c1\` and \`c2\` 3. substitute trapdoor \`t\` 4. apply exponentiation power rule \`(a<sup>b</sup>)<sup>c</sup> = a<sup>(b\*c)</sup>\` 5. distribute the exponent \`r\` 6. - \`g\*\*(r\*(p-1))\` is 1 because of [Euler's theorem](https://en.wikipedia.org/wiki/Euler%2527s_theorem) and [Lagrange's theorem](https://en.wikipedia.org/wiki/Lagrange%2527s_theorem_(group_theory)) - \`g\*\*(k\*r)\` terms reduces each other Check if the intuition is valid by substituting with numbers: generator \`g\` is 3, private key \`k\` is 4, random number \`r\` is 5 and message \`m\` is 6: print "MAGIC" if 6 == (3**(4*5) * 6 * 3**(5*(7-1)) * 3**(-5*4)) % 7 else "ERROR" MAGIC
json metadata{"tags":["cryptography","elgamal","discrete","logarithm","eli5"],"links":["https://en.wikipedia.org/wiki/ElGamal_encryption","https://en.wikipedia.org/wiki/ElGamal_signature_scheme","https://en.wikipedia.org/wiki/Cyclic_group","https://en.wikipedia.org/wiki/Discrete_logarithm","https://en.wikipedia.org/wiki/Additive_inverse","https://en.wikipedia.org/wiki/Finite_field","https://en.wikipedia.org/wiki/Euler%2527s_theorem","https://en.wikipedia.org/wiki/Lagrange%2527s_theorem_(group_theory)"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptography
permlinkeli5-cryptography-elgamal
titleELI5: Cryptography - ElGamal
Transaction InfoBlock #31521289/Trx c7450e9258272e819fb52141040f589b74abc18c
View Raw JSON Data
{
  "block": 31521289,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "# Overview\n\n    \"If you can't explain it simply, you don't understand it well enough\" - Einstein\n\nElGamal is a public key cryptosystem that is used in [encryption](https://en.wikipedia.org/wiki/ElGamal_encryption) , [digital signature](https://en.wikipedia.org/wiki/ElGamal_signature_scheme) and homomorphic cryptography.\n\nHere is my take in 12 lines of Python code:\n\n     1  p = 7\n     2  g = [x for x in range(1, p) if len(set([x**i % p for i in range(1, p)])) == p-1][0]\n     3  k = 4\n     4  t = g**k % p\n     5  m = 6\n     6  import random\n     7  r = random.randint(1, p-1)\n     8  c1 = g**r % p\n     9  c2 = (t**r * m) % p\n    10  inv_k = p - 1 - k\n    11  inv_c1 = c1**inv_k % p\n    12  message = c2 * inv_c1 % p\n    13  print \"YOU ARE A CRYPTOSTAR!\" if message == m else \"ERROR\"\n\n    YOU ARE A CRYPTOSTAR!\n\nBesides line #2 that involves an algorithm to find the generator \\`g\\` and line #10 that calculates the additive inverse of private key \\`k\\`, everything else is just modular multiplication and exponentiation.\n\nInterested in more details and line by line explanations? please read on.\n\n\n# Discrete logarithm trapdoor\n\nFirst thing first, lets pick a prime number:\n\n    1  p = 7\n\nFor the prime number above we need to find the generator \\`g\\` that defines a [cyclic group](https://en.wikipedia.org/wiki/Cyclic_group) which in theory is a little bit involved but in simple terms the generator is a specific number that returns unique values for each exponent between \\`1\\` and \\`p-1\\` where \\`p-1\\` is called the order of the cyclic group.\n\nLets take a few examples and see how it looks like: pick \\`2\\` as generator:\n\n    print [2**i % p for i in range(1, p)]\n\n    [2, 4, 1, 2, 4, 1]\n\nWe can easily see that returning values are not unique, lets pick \\`3\\` as generator:\n\n    print [3**i % p for i in range(1, p)]\n\n    [3, 2, 6, 4, 5, 1]\n\nBINGO! returning values are unique and we've found our generator.\n\nThe line below is just a brute force algorithm that finds multiple generators of order \\`p-1\\` but only takes the first one that is found.\n\n    2  g = [x for x in range(1, p) if len(set([x**i % p for i in range(1, p)])) == p-1][0]\n\nNow is time to pick a private key \\`k\\` between \\`1\\` and \\`p-1\\`, execute the trapdoor function and calculate \\`t\\` value:\n\n    3  k = 4\n    4  t = g**k % p\n\nThe line #4 is the secret sauce of ElGamal cryptography, the trapdoor function called [**the discrete logarithm**](https://en.wikipedia.org/wiki/Discrete_logarithm) which says that for given \\`g\\` and \\`t\\` values it is **infeasible** to calculate the private key \\`k\\` when working with very large numbers.\n\nThe \\`p, g and t\\` form the public key and will be used in encryption below, while \\`k\\` is kept secret.\n\n\n# Message encryption\n\n\\`m\\` is the message that we want to encrypt and \\`r\\` is a random number between \\`1\\` and \\`p-1\\`:\n\n    5  m = 6\n    6  import random\n    7  r = random.randint(1, p-1)\n    8  c1 = g**r % p\n    9  c2 = (t**r * m) % p\n\n\\`c1, c2\\` are the encrypted ciphers that will be used to decrypt the original message.\n\n\n# Message decryption\n\nTo decrypt the original message we need apply the following formula:\n\n\\`message = c2 / c1<sup>k</sup> mod p\\`\n\nThe problem is that division is not an operation defined for finite fields but multiplication is and we can re-write it using multiplication / exponentiation operations only:\n\n\\`message = c2 \\* c1<sup>inv</sup><sub>k</sub> mod p\\`\n\n\\`inv<sub>k</sub>\\` is called [additive inverse](https://en.wikipedia.org/wiki/Additive_inverse)  of \\`k\\` over [finite field](https://en.wikipedia.org/wiki/Finite_field) 'p' where \\`k + inv<sub>k</sub> mod p = 0\\` is valid.\nWe can brute force and find it but there is a simpler way: if \\`k < p\\` (which it is) then \\`inv<sub>k</sub> = p - 1 - k\\`.\n\n    10  inv_k = p - 1 - k\n    11  inv_c1 = c1**inv_k % p\n    12  message = c2 * inv_c1 % p\n    13  print \"YOU ARE A CRYPTOSTAR!\" if message == m else \"ERROR\"\n\n    YOU ARE A CRYPTOSTAR!\n\n\n# Intuition\n\nWhy this magic works the way it works?\n\n    1  message == (c2 * inv_c1) % p\n    2  message == (c2 * c1**(p-1-k)) % p\n    3  message == (t**r * m * (g**r)**(p-1-k)) % p\n    4  message == ((g**k)**r * m * (g**r)**(p-1-k)) % p\n    5  message == (g**(k*r) * m * (g**(r*(p-1-k)))) % p\n    6  message == (g**(k*r) * m * g**(r*(p-1)) * g**(-r*k)) % p\n\nLets do the math backwards:\n\n1.  start with last decryption formula and substitute inverses \\`inv<sub>c1</sub>\\` and \\`inv<sub>k</sub>\\`\n2.  substitute ciphers \\`c1\\` and \\`c2\\`\n3.  substitute trapdoor \\`t\\`\n4.  apply exponentiation power rule \\`(a<sup>b</sup>)<sup>c</sup> = a<sup>(b\\*c)</sup>\\`\n5.  distribute the exponent \\`r\\`\n6.  - \\`g\\*\\*(r\\*(p-1))\\` is 1 because of [Euler's theorem](https://en.wikipedia.org/wiki/Euler%2527s_theorem) and [Lagrange's theorem](https://en.wikipedia.org/wiki/Lagrange%2527s_theorem_(group_theory))\n    -   \\`g\\*\\*(k\\*r)\\` terms reduces each other\n\nCheck if the intuition is valid by substituting with numbers: generator \\`g\\` is 3, private key \\`k\\` is 4, random number \\`r\\` is 5 and message \\`m\\` is 6:\n\n    print \"MAGIC\" if 6 == (3**(4*5) * 6 * 3**(5*(7-1)) * 3**(-5*4)) % 7 else \"ERROR\"\n\n    MAGIC",
      "json_metadata": "{\"tags\":[\"cryptography\",\"elgamal\",\"discrete\",\"logarithm\",\"eli5\"],\"links\":[\"https://en.wikipedia.org/wiki/ElGamal_encryption\",\"https://en.wikipedia.org/wiki/ElGamal_signature_scheme\",\"https://en.wikipedia.org/wiki/Cyclic_group\",\"https://en.wikipedia.org/wiki/Discrete_logarithm\",\"https://en.wikipedia.org/wiki/Additive_inverse\",\"https://en.wikipedia.org/wiki/Finite_field\",\"https://en.wikipedia.org/wiki/Euler%2527s_theorem\",\"https://en.wikipedia.org/wiki/Lagrange%2527s_theorem_(group_theory)\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptography",
      "permlink": "eli5-cryptography-elgamal",
      "title": "ELI5: Cryptography - ElGamal"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-03-27T13:27:09",
  "trx_id": "c7450e9258272e819fb52141040f589b74abc18c",
  "trx_in_block": 13,
  "virtual_op": 0
}
2019/03/23 13:41:36
authoricostan
permlinkeli5-cryptography-rsa
votersteffenix
weight10000 (100.00%)
Transaction InfoBlock #31406442/Trx 8ed47132be8f40a869b012cb3d0f346f9a5a9a1f
View Raw JSON Data
{
  "block": 31406442,
  "op": [
    "vote",
    {
      "author": "icostan",
      "permlink": "eli5-cryptography-rsa",
      "voter": "steffenix",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-03-23T13:41:36",
  "trx_id": "8ed47132be8f40a869b012cb3d0f346f9a5a9a1f",
  "trx_in_block": 21,
  "virtual_op": 0
}
2019/03/23 13:38:57
authoricostan
permlinkeli5-cryptography-rsa
votertaijos
weight10000 (100.00%)
Transaction InfoBlock #31406389/Trx 6f1b68d77fb68d8ad7f2342ba79d8ed887a6cbd9
View Raw JSON Data
{
  "block": 31406389,
  "op": [
    "vote",
    {
      "author": "icostan",
      "permlink": "eli5-cryptography-rsa",
      "voter": "taijos",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-03-23T13:38:57",
  "trx_id": "6f1b68d77fb68d8ad7f2342ba79d8ed887a6cbd9",
  "trx_in_block": 0,
  "virtual_op": 0
}
icostanpublished a new post: eli5-cryptography-rsa
2019/03/23 13:30:15
authoricostan
body# Overview "If you can't explain it simply, you don't understand it well enough" - Einstein --- [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) (Rivest-Shamir-Adleman) needs no introduction, it is well known and most used public-key cryptosystem that governs our digital lives. Here is my take, a simple implementation in 10 lines of Ruby code that is neither the best implementation nor the most efficient one but is enough for the purpose of this article. 1 p = 7 2 q = 11 3 n = p * q 4 phi = (p-1) * (q-1) 5 gcd = ->(a, b) { while(b != 0) do r, a = a % b, b; b = r end; a } 6 e = (2..phi).find{|i| gcd.call(i, phi) == 1 } 7 d = (2..phi).find{|i| (i * e) % phi == 1 } 8 m = 6 9 c = m**e % n 10 message = c**d % n 11 "Decrypted message: #{message}" if m == message Except lines #5 that involves an algorithm and a while loop, everything else is mid-school math and \`\*\*\` is the exponentiation operator. The curious minds please read simple explanations below. # Integer factorization trapdoor The very first thing to do is to choose 2 prime numbers, \`p\` and \`q\`: 1 p = 7 2 q = 11 Next, let's multiply the two numbers: 3 n = p * q Now it's time to define our first function \`phi\`: 4 phi = (p-1) * (q-1) Which is [Euler's totient function](<https://en.wikipedia.org/wiki/Euler%27s_totient_function>) defined as number of integers less than \`n\` that are [coprime](https://en.wikipedia.org/wiki/Coprime_integers) with \`n\` and has two interesting properties: - the function is multiplicative and \`phi(a\*b) = phi(a) \* phi(b)\` - if \`n\` is a prime number then \`phi(n) = n - 1\` And finally we have the [cryptographic trapdoor](https://en.wikipedia.org/wiki/Trapdoor_function) which is the most important primitive to understand. Trapdoors are based on asymmetric computation that is easy to do in one direction but it is very difficult to calculate in the opposite direction. In our case, if one (an attacker) does not know the initial \`p\` and \`q\` prime numbers it will be very hard to calculate the \`phi\` because [integer factorization](https://en.wikipedia.org/wiki/Integer_factorization) of \`n\` is known to be infeasible to calculate for very large numbers. # Message encryption Now it's time to define our first algorithm, \`gcd\` which is the [greatest common divisor](<https://en.wikipedia.org/wiki/Greatest_common_divisor>) and is defined as the largest positive integer that divides both \`a\` and \`b\`. If single-liner GCD looks scary then here is the formatted version of the [Euclid's algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm). def gcd(a, b) while(b != 0) do r = a % b a = b b = r end a end The \`e\` key below is the encryption key and is defined as the smallest value for which \`gcd(e, phi) == 1\` is true. To keep things simple we will just brute-force and find \`e\` but keep in mind that this will be very inefficient for large numbers. 5 gcd = ->(a, b) { while(b != 0) do r, a = a % b, b; b = r end; a } (gcd) 6 e = (2..phi).find{|i| gcd.call(i, phi) == 1} Message encryption is modulo exponentiation of the message \`m\` and the encryption key \`e\`. 7 m = 6 8 c = m**e % n # Message decryption The \`d\` key below is the decryption key and is defined as [multiplicative inverse](https://en.wikipedia.org/wiki/Multiplicative_inverse) of \`e\` over [finite field](https://en.wikipedia.org/wiki/Finite_field) \`phi\`. Simply put \`e \* d mod phi = 1\`. Again we will just brute-force and calculate the inverse but there are better algorithms to do this, like [Extended Euclidean algorithm](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm). 9 d = (2..phi).find{|i| (e * i) % phi == 1} Message decryption is another modulo exponentiation using the encrypted cipher \`c\` and decryption key \`d\`: 10 message = c**d % n BINGO! You can try it yourself but I can bet that \`m = message = 6\` # Intuition At first sight it looks like magic right? but if you reason about it, it's very easy. Starting backwards, with the decryption/encryption formulas: 1 m = c^d mod n 2 c = m^e mod n Let's substitute #2 in #1: m = (m^e)^d mod n Exponentials Power Rule says that \`(a<sup>b</sup>)<sup>c</sup> == a<sup>(b\*c)</sup>\` and we also know that \`d\` is the multiplicative inverse of \`e\`, guess what is the value of the resulting exponent? :) m = m^(e*d mod phi) mod p If the intuition is valid then the following expression stands true, where 7 is \`e\` and 43 is \`d\` in our little example: 'YOU ARE A CRYPTOSTAR!!!' if 6 == 6**(7 * 43 % 60) % 77
json metadata{"tags":["cryptography","rsa","primes","factorization","eli5"],"links":["https://en.wikipedia.org/wiki/RSA_(cryptosystem)","https://en.wikipedia.org/wiki/Euler's_totient_function","https://en.wikipedia.org/wiki/Coprime_integers","https://en.wikipedia.org/wiki/Trapdoor_function","https://en.wikipedia.org/wiki/Integer_factorization","https://en.wikipedia.org/wiki/Greatest_common_divisor","https://en.wikipedia.org/wiki/Euclidean_algorithm","https://en.wikipedia.org/wiki/Multiplicative_inverse","https://en.wikipedia.org/wiki/Finite_field","https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcryptography
permlinkeli5-cryptography-rsa
titleELI5 Cryptography: RSA
Transaction InfoBlock #31406215/Trx 26d641da6f108d903477e97ca55524a006fc89cd
View Raw JSON Data
{
  "block": 31406215,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "# Overview\n\n    \"If you can't explain it simply, you don't understand it well enough\" - Einstein\n---\n\n[RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) (Rivest-Shamir-Adleman) needs no introduction, it is well known and most used public-key cryptosystem that governs our digital lives.\n\nHere is my take, a simple implementation in 10 lines of Ruby code that is neither the best implementation nor the most efficient one but is enough for the purpose of this article.\n\n     1  p = 7\n     2  q = 11\n     3  n = p * q\n     4  phi = (p-1) * (q-1)\n     5  gcd = ->(a, b) { while(b != 0) do r, a = a % b, b; b = r end; a }\n     6  e = (2..phi).find{|i| gcd.call(i, phi) == 1 }\n     7  d = (2..phi).find{|i| (i * e) % phi == 1 }\n     8  m = 6\n     9  c = m**e % n\n    10  message = c**d % n\n    11  \"Decrypted message: #{message}\" if m == message\n\nExcept lines #5 that involves an algorithm and a while loop, everything else is mid-school math and \\`\\*\\*\\` is the exponentiation operator.\n\nThe curious minds please read simple explanations below.\n\n\n# Integer factorization trapdoor\n\nThe very first thing to do is to choose 2 prime numbers, \\`p\\` and \\`q\\`:\n\n    1  p = 7\n\n    2  q = 11\n\nNext, let's multiply the two numbers:\n\n    3  n = p * q\n\nNow it's time to define our first function \\`phi\\`:\n\n    4  phi = (p-1) * (q-1)\n\nWhich is [Euler's totient function](<https://en.wikipedia.org/wiki/Euler%27s_totient_function>) defined as number of integers less than \\`n\\` that are [coprime](https://en.wikipedia.org/wiki/Coprime_integers) with \\`n\\` and has two interesting properties:\n\n-   the function is multiplicative and \\`phi(a\\*b) = phi(a) \\* phi(b)\\`\n-   if \\`n\\` is a prime number then \\`phi(n) = n - 1\\`\n\nAnd finally we have the [cryptographic trapdoor](https://en.wikipedia.org/wiki/Trapdoor_function) which is the most important primitive to understand. Trapdoors are based on asymmetric computation that is easy to do in one direction but it is very difficult to calculate in the opposite direction.\n\nIn our case, if one (an attacker) does not know the initial \\`p\\` and \\`q\\` prime numbers it will be very hard to calculate the \\`phi\\` because [integer factorization](https://en.wikipedia.org/wiki/Integer_factorization)  of \\`n\\` is known to be infeasible to calculate for very large numbers.\n\n\n# Message encryption\n\nNow it's time to define our first algorithm, \\`gcd\\` which is the [greatest common divisor](<https://en.wikipedia.org/wiki/Greatest_common_divisor>) and is defined as the largest positive integer that divides both \\`a\\` and \\`b\\`.\n\nIf single-liner GCD looks scary then here is the formatted version of the [Euclid's algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm).\n\n    def gcd(a, b)\n      while(b != 0) do\n        r = a % b\n        a = b\n        b = r\n      end\n      a\n    end\n\nThe \\`e\\` key below is the encryption key and is defined as the smallest value for which \\`gcd(e, phi) == 1\\` is true.\nTo keep things simple we will just brute-force and find \\`e\\` but keep in mind that this will be very inefficient for large numbers.\n\n    5  gcd = ->(a, b) { while(b != 0) do r, a = a % b, b; b = r end; a }      (gcd)\n    6  e = (2..phi).find{|i| gcd.call(i, phi) == 1}\n\nMessage encryption is modulo exponentiation of the message \\`m\\` and the encryption key \\`e\\`.\n\n    7  m = 6\n    8  c = m**e % n\n\n\n# Message decryption\n\nThe \\`d\\` key below is the decryption key and is defined as [multiplicative inverse](https://en.wikipedia.org/wiki/Multiplicative_inverse) of \\`e\\` over [finite field](https://en.wikipedia.org/wiki/Finite_field) \\`phi\\`. Simply put \\`e \\* d mod phi = 1\\`.\n\nAgain we will just brute-force and calculate the inverse but there are better algorithms to do this, like [Extended Euclidean algorithm](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm).\n\n    9  d = (2..phi).find{|i| (e * i) % phi == 1}\n\nMessage decryption is another modulo exponentiation using the encrypted cipher \\`c\\` and decryption key \\`d\\`:\n\n    10  message = c**d % n\n\nBINGO! You can try it yourself but I can bet that \\`m = message = 6\\`\n\n\n# Intuition\n\nAt first sight it looks like magic right? but if you reason about it, it's very easy.\n\nStarting backwards, with the decryption/encryption formulas:\n\n    1  m = c^d mod n\n    2  c = m^e mod n\n\nLet's substitute #2 in #1:\n\n    m = (m^e)^d mod n\n\nExponentials Power Rule says that \\`(a<sup>b</sup>)<sup>c</sup> == a<sup>(b\\*c)</sup>\\` and we also know that \\`d\\` is the multiplicative inverse of \\`e\\`, guess what is the value of the resulting exponent? :)\n\n    m = m^(e*d mod phi) mod p\n\nIf the intuition is valid then the following expression stands true, where 7 is \\`e\\` and 43 is \\`d\\` in our little example:\n\n    'YOU ARE A CRYPTOSTAR!!!' if 6 == 6**(7 * 43 % 60) % 77",
      "json_metadata": "{\"tags\":[\"cryptography\",\"rsa\",\"primes\",\"factorization\",\"eli5\"],\"links\":[\"https://en.wikipedia.org/wiki/RSA_(cryptosystem)\",\"https://en.wikipedia.org/wiki/Euler's_totient_function\",\"https://en.wikipedia.org/wiki/Coprime_integers\",\"https://en.wikipedia.org/wiki/Trapdoor_function\",\"https://en.wikipedia.org/wiki/Integer_factorization\",\"https://en.wikipedia.org/wiki/Greatest_common_divisor\",\"https://en.wikipedia.org/wiki/Euclidean_algorithm\",\"https://en.wikipedia.org/wiki/Multiplicative_inverse\",\"https://en.wikipedia.org/wiki/Finite_field\",\"https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cryptography",
      "permlink": "eli5-cryptography-rsa",
      "title": "ELI5 Cryptography: RSA"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-03-23T13:30:15",
  "trx_id": "26d641da6f108d903477e97ca55524a006fc89cd",
  "trx_in_block": 13,
  "virtual_op": 0
}
2019/02/07 14:03:27
idfollow
json["follow",{"follower":"icostan","following":"luigi1111","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #30140588/Trx 68e0b372067c2838d7aa63f432a65d15f2c97285
View Raw JSON Data
{
  "block": 30140588,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"luigi1111\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-02-07T14:03:27",
  "trx_id": "68e0b372067c2838d7aa63f432a65d15f2c97285",
  "trx_in_block": 5,
  "virtual_op": 0
}
steemdelegated 17.870 SP to @icostan
2019/02/07 02:56:48
delegateeicostan
delegatorsteem
vesting shares29053.803726 VESTS
Transaction InfoBlock #30127263/Trx 6851f8d148247f481b212d07799006a3627197f8
View Raw JSON Data
{
  "block": 30127263,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "29053.803726 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-02-07T02:56:48",
  "trx_id": "6851f8d148247f481b212d07799006a3627197f8",
  "trx_in_block": 32,
  "virtual_op": 0
}
2019/02/02 13:03:27
authoricostan
body# Bitmex-api-ruby Fully featured, idiomatic Ruby library for BitMEX API. Support for both REST and Websocket APIs as described in [API Overview](https://www.bitmex.com/app/apiOverview). ## Installation ```shell gem install bitmex-api ``` ## Usage Listen for live trades in 3 lines of code: ```ruby # Importing library... 2.5.3 :001 > require 'bitmex-api' => true # Create client... 2.5.3 :002 > client = Bitmex::Client.new => #<Bitmex::Client:0x00007fae7a569598 @host="www.bitmex.com", @api_key=nil, @api_secret=nil> # Spit out live trades as they happen... 2.5.3 :003 > client.trades.all symbol: 'XBTUSD' do |trade| puts "#{trade.side} #{trade.homeNotional} #{trade.symbol} @ #{trade.price}" end 2.5.3 :004 > 2.5.3 :005?> ==> {"info":"Welcome to the BitMEX Realtime API.","version":"2019-01-31T23:25:34.000Z","timestamp":"2019-02-02T12:35:05.892Z","docs":"https://www.bitmex.com/app/wsAPI","limit":{"remaining":37}} ==> {"success":true,"subscribe":"trade:XBTUSD","request":{"op":"subscribe","args":["trade:XBTUSD"]}} Buy 0.2924442 XBTUSD @ 3440 Sell 0.0305277 XBTUSD @ 3439.5 Buy 0.2907 XBTUSD @ 3440 Sell 0.18810878 XBTUSD @ 3439.5 Sell 0.14537 XBTUSD @ 3439.5 Buy 0.17442 XBTUSD @ 3440 Buy 0.05814 XBTUSD @ 3440 Sell 0.014537 XBTUSD @ 3439.5 ``` Or fetch trade history: ```ruby # get first 10 trades of the year 2.5.3 :006 > trades = client.trades.all symbol: 'XBTUSD', startTime: '2019-01-01', count: 10 => [...] 2.5.3 :007 > trades.size => 10 # the very first trade in 2019 2.5.3 :008 > trades.first => #<Bitmex::Mash foreignNotional=10 grossValue=270780 homeNotional=0.0027078 price=3693 side="Sell" size=10 symbol="XBTUSD" tickDirection="ZeroMinusTick" timestamp="2019-01-01T00:00:03.904Z" trdMatchID="2bd201ae-3b79-0908-293e-d9bd1cc489f2"> ``` This post is just a teaser, if you want to find out more info please see [source code](https://github.com/icostan/bitmex-api-ruby) and [documentation](https://www.rubydoc.info/gems/bitmex-api). Enjoy futures trading!
json metadata{"tags":["bitmex","ruby","library","json","websocket"],"links":["https://www.bitmex.com/app/apiOverview","https://github.com/icostan/bitmex-api-ruby","https://www.rubydoc.info/gems/bitmex-api"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitmex
permlinkidiomatic-ruby-library-for-bitmex-api
titleIdiomatic Ruby library for BitMEX API
Transaction InfoBlock #29995542/Trx 022c57bb018022bea1920181579a795b159aee8d
View Raw JSON Data
{
  "block": 29995542,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "# Bitmex-api-ruby\n\nFully featured, idiomatic Ruby library for BitMEX API. Support for both REST and Websocket APIs as described in [API Overview](https://www.bitmex.com/app/apiOverview).\n\n## Installation\n\n```shell\ngem install bitmex-api\n```\n\n## Usage\n\nListen for live trades in 3 lines of code:\n\n```ruby\n# Importing library...\n2.5.3 :001 > require 'bitmex-api'\n => true\n\n# Create client...\n2.5.3 :002 > client = Bitmex::Client.new\n => #<Bitmex::Client:0x00007fae7a569598 @host=\"www.bitmex.com\", @api_key=nil, @api_secret=nil>\n\n# Spit out live trades as they happen...\n2.5.3 :003 > client.trades.all symbol: 'XBTUSD' do |trade|\n  puts \"#{trade.side} #{trade.homeNotional} #{trade.symbol} @ #{trade.price}\"\nend\n2.5.3 :004 >\n2.5.3 :005?>\n==> {\"info\":\"Welcome to the BitMEX Realtime API.\",\"version\":\"2019-01-31T23:25:34.000Z\",\"timestamp\":\"2019-02-02T12:35:05.892Z\",\"docs\":\"https://www.bitmex.com/app/wsAPI\",\"limit\":{\"remaining\":37}}\n==> {\"success\":true,\"subscribe\":\"trade:XBTUSD\",\"request\":{\"op\":\"subscribe\",\"args\":[\"trade:XBTUSD\"]}}\nBuy 0.2924442 XBTUSD @ 3440\nSell 0.0305277 XBTUSD @ 3439.5\nBuy 0.2907 XBTUSD @ 3440\nSell 0.18810878 XBTUSD @ 3439.5\nSell 0.14537 XBTUSD @ 3439.5\nBuy 0.17442 XBTUSD @ 3440\nBuy 0.05814 XBTUSD @ 3440\nSell 0.014537 XBTUSD @ 3439.5\n```\n\nOr fetch trade history:\n\n```ruby\n# get first 10 trades of the year\n2.5.3 :006 > trades = client.trades.all symbol: 'XBTUSD', startTime: '2019-01-01', count: 10\n => [...]\n\n2.5.3 :007 > trades.size\n => 10\n\n# the very first trade in 2019\n2.5.3 :008 > trades.first\n => #<Bitmex::Mash foreignNotional=10 grossValue=270780 homeNotional=0.0027078 price=3693 side=\"Sell\" size=10 symbol=\"XBTUSD\" tickDirection=\"ZeroMinusTick\" timestamp=\"2019-01-01T00:00:03.904Z\" trdMatchID=\"2bd201ae-3b79-0908-293e-d9bd1cc489f2\">\n```\n\nThis post is just a teaser, if you want to find out more info please see [source code](https://github.com/icostan/bitmex-api-ruby) and [documentation](https://www.rubydoc.info/gems/bitmex-api).\n\nEnjoy futures trading!",
      "json_metadata": "{\"tags\":[\"bitmex\",\"ruby\",\"library\",\"json\",\"websocket\"],\"links\":[\"https://www.bitmex.com/app/apiOverview\",\"https://github.com/icostan/bitmex-api-ruby\",\"https://www.rubydoc.info/gems/bitmex-api\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitmex",
      "permlink": "idiomatic-ruby-library-for-bitmex-api",
      "title": "Idiomatic Ruby library for BitMEX API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-02-02T13:03:27",
  "trx_id": "022c57bb018022bea1920181579a795b159aee8d",
  "trx_in_block": 7,
  "virtual_op": 0
}
2019/01/18 09:22:18
authorpartiko
bodyThank you so much for sharing this amazing post with us! Have you heard about Partiko? It’s a really convenient mobile app for Steem! With Partiko, you can easily see what’s going on in the Steem community, make posts and comments (no beneficiary cut forever!), and always stayed connected with your followers via push notification! Partiko also rewards you with Partiko Points (3000 Partiko Point bonus when you first use it!), and Partiko Points can be converted into Steem tokens. You can earn Partiko Points easily by making posts and comments using Partiko. We also noticed that your Steem Power is low. We will be very happy to delegate 15 Steem Power to you once you have made a post using Partiko! With more Steem Power, you can make more posts and comments, and earn more rewards! If that all sounds interesting, you can: - Download Partiko Android at [Google Play](http://bit.ly/2SRFIta) - Or Download Partiko iOS on the [App Store](https://apple.co/2PcXkSd) Thank you so much for reading this message!
json metadata{"app":"partiko"}
parent authoricostan
parent permlinkrelease-cryptos-ruby-project
permlinkpartiko-re-icostan-release-cryptos-ruby-project-20190118t092218331z
title
Transaction InfoBlock #29559550/Trx 9c5a859a044787eb870467f025b509c5daa84364
View Raw JSON Data
{
  "block": 29559550,
  "op": [
    "comment",
    {
      "author": "partiko",
      "body": "Thank you so much for sharing this amazing post with us!\n\nHave you heard about Partiko? It’s a really convenient mobile app for Steem! With Partiko, you can easily see what’s going on in the Steem community, make posts and comments (no beneficiary cut forever!), and always stayed connected with your followers via push notification!\n\nPartiko also rewards you with Partiko Points (3000 Partiko Point bonus when you first use it!), and Partiko Points can be converted into Steem tokens. You can earn Partiko Points easily by making posts and comments using Partiko.\n\nWe also noticed that your Steem Power is low. We will be very happy to delegate 15 Steem Power to you once you have made a post using Partiko! With more Steem Power, you can make more posts and comments, and earn more rewards!\n\nIf that all sounds interesting, you can: \n\n- Download Partiko Android at [Google Play](http://bit.ly/2SRFIta)\n- Or Download Partiko iOS on the [App Store](https://apple.co/2PcXkSd)\n\nThank you so much for reading this message!",
      "json_metadata": "{\"app\":\"partiko\"}",
      "parent_author": "icostan",
      "parent_permlink": "release-cryptos-ruby-project",
      "permlink": "partiko-re-icostan-release-cryptos-ruby-project-20190118t092218331z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-01-18T09:22:18",
  "trx_id": "9c5a859a044787eb870467f025b509c5daa84364",
  "trx_in_block": 14,
  "virtual_op": 0
}
2018/12/13 07:25:27
authoricostan
bodyI just want to announce the very first release [v0.0.3] of Cryptos-ruby project, a simple and very easy to use Ruby API to manipulate multiple crypto coins. For more information please check [Github project page](https://github.com/icostan/cryptos-ruby). ## Features * Generate private/public keys * Generate Bitcoin/Litecoin addresses (more to come) * Create Bitcoin/Litecoin transactions * Execute atomic swaps between Bitcoin and Litecoin ## Installation ```shell gem install cryptos ``` ## Usage ```ruby # Importing library... 2.5.1 :001 > require 'cryptos' # Generating private key... 2.5.1 :003 > private_key = Cryptos::PrivateKey.generate => #<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337> # Generating public key... 2.5.1 :004 > public_key = Cryptos::PublicKey.new private_key => #<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541> # Generating Bitcoin address for testnet 2.5.1 :005 > address = Cryptos::Bitcoin::Address.new public_key => #<Cryptos::Bitcoin::Address:0x00007fc9d18a29b8 @public_key=#<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>, @testnet=true> 2.5.1 :006 > address.to_s => "n37t517bJymxg3YftzqyVTAnjg4wKb3Tth" # Generating Litecoin address for mainnet 2.5.1 :007 > address = Cryptos::Litecoin::Address.new public_key, testnet: false => #<Cryptos::Litecoin::Address:0x00007fc9d119a1e8 @public_key=#<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>, @testnet=false> 2.5.1 :008 > address.to_s => "Lgpt3ALSacam9jmDMZrtwZ2E5tqWVYzEkH" ``` ## Todos * Work in progress: Zcash and Ethereum support * Add more and more coins, cool crypto tech
json metadata{"tags":["crypto","bitcoin","litecoin","transaction","atomicswaps"],"links":["https://github.com/icostan/cryptos-ruby"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcrypto
permlinkrelease-cryptos-ruby-project
titleIntroducing Cryptos-ruby: The easiest way to craft your own transactions
Transaction InfoBlock #28521203/Trx 0d6de8f50b2bf982713df05f53f711cbd0489cdf
View Raw JSON Data
{
  "block": 28521203,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "I just want to announce the very first release [v0.0.3] of Cryptos-ruby project, a simple and very easy to use Ruby API to  manipulate multiple crypto coins.\n\nFor more information please check [Github project page](https://github.com/icostan/cryptos-ruby).\n\n## Features\n  * Generate private/public keys\n  * Generate Bitcoin/Litecoin addresses (more to come)\n  * Create Bitcoin/Litecoin transactions\n  * Execute atomic swaps between Bitcoin and Litecoin\n\n## Installation\n```shell\ngem install cryptos\n```\n## Usage\n\n```ruby\n# Importing library...\n2.5.1 :001 > require 'cryptos'\n\n# Generating private key...\n2.5.1 :003 > private_key = Cryptos::PrivateKey.generate\n => #<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>\n\n# Generating public key...\n2.5.1 :004 > public_key = Cryptos::PublicKey.new private_key\n => #<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>\n\n# Generating Bitcoin address for testnet\n2.5.1 :005 > address = Cryptos::Bitcoin::Address.new public_key\n => #<Cryptos::Bitcoin::Address:0x00007fc9d18a29b8 @public_key=#<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>, @testnet=true>\n2.5.1 :006 > address.to_s\n => \"n37t517bJymxg3YftzqyVTAnjg4wKb3Tth\"\n\n# Generating Litecoin address for mainnet\n2.5.1 :007 > address = Cryptos::Litecoin::Address.new public_key, testnet: false\n => #<Cryptos::Litecoin::Address:0x00007fc9d119a1e8 @public_key=#<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>, @testnet=false>\n2.5.1 :008 > address.to_s\n => \"Lgpt3ALSacam9jmDMZrtwZ2E5tqWVYzEkH\"\n```\n\n## Todos\n  * Work in progress: Zcash and Ethereum support\n  * Add more and more coins, cool crypto tech",
      "json_metadata": "{\"tags\":[\"crypto\",\"bitcoin\",\"litecoin\",\"transaction\",\"atomicswaps\"],\"links\":[\"https://github.com/icostan/cryptos-ruby\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "crypto",
      "permlink": "release-cryptos-ruby-project",
      "title": "Introducing  Cryptos-ruby: The easiest way to craft your own transactions"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-12-13T07:25:27",
  "trx_id": "0d6de8f50b2bf982713df05f53f711cbd0489cdf",
  "trx_in_block": 2,
  "virtual_op": 0
}
allazsent 0.001 SBD to @icostan- "Promote your post. Your post will be min. 10 resteemed with over 13000 followers and min. 25 Upvote Different account (5000 STEEM POWER). Your post will be more popular and you will find new frien..."
2018/12/11 09:26:51
amount0.001 SBD
fromallaz
memoPromote your post. Your post will be min. 10 resteemed with over 13000 followers and min. 25 Upvote Different account (5000 STEEM POWER). Your post will be more popular and you will find new friends. Send 0.5 SBD or STEEM to @allaz (post URL as memo ) Service Active.
toicostan
Transaction InfoBlock #28466082/Trx 1e16bf0a26371fd2ef5dbbae4fbe1b67a6ae1999
View Raw JSON Data
{
  "block": 28466082,
  "op": [
    "transfer",
    {
      "amount": "0.001 SBD",
      "from": "allaz",
      "memo": "Promote your post. Your post will be min. 10  resteemed with over 13000  followers and min. 25  Upvote Different account (5000  STEEM POWER). Your post will be more popular and you will find new friends. Send 0.5 SBD or STEEM to @allaz (post URL as memo ) Service Active.",
      "to": "icostan"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-12-11T09:26:51",
  "trx_id": "1e16bf0a26371fd2ef5dbbae4fbe1b67a6ae1999",
  "trx_in_block": 0,
  "virtual_op": 0
}
2018/12/11 09:25:27
authoricostan
body@@ -1,37 +1,4 @@ -# Release: Cryptos-ruby project%0A%0A I ju
json metadata{"tags":["crypto","bitcoin","litecoin","transaction","atomicswaps"],"links":["https://github.com/icostan/cryptos-ruby"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcrypto
permlinkrelease-cryptos-ruby-project
titleRelease: Cryptos-ruby project
Transaction InfoBlock #28466054/Trx 50e311b5989627231103dc0e6858bbf544f88a41
View Raw JSON Data
{
  "block": 28466054,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -1,37 +1,4 @@\n-# Release: Cryptos-ruby project%0A%0A\n I ju\n",
      "json_metadata": "{\"tags\":[\"crypto\",\"bitcoin\",\"litecoin\",\"transaction\",\"atomicswaps\"],\"links\":[\"https://github.com/icostan/cryptos-ruby\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "crypto",
      "permlink": "release-cryptos-ruby-project",
      "title": "Release: Cryptos-ruby project"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-12-11T09:25:27",
  "trx_id": "50e311b5989627231103dc0e6858bbf544f88a41",
  "trx_in_block": 2,
  "virtual_op": 0
}
2018/12/11 09:24:36
authoricostan
body# Release: Cryptos-ruby project I just want to announce the very first release [v0.0.3] of Cryptos-ruby project, a simple and very easy to use Ruby API to manipulate multiple crypto coins. For more information please check [Github project page](https://github.com/icostan/cryptos-ruby). ## Features * Generate private/public keys * Generate Bitcoin/Litecoin addresses (more to come) * Create Bitcoin/Litecoin transactions * Execute atomic swaps between Bitcoin and Litecoin ## Installation ```shell gem install cryptos ``` ## Usage ```ruby # Importing library... 2.5.1 :001 > require 'cryptos' # Generating private key... 2.5.1 :003 > private_key = Cryptos::PrivateKey.generate => #<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337> # Generating public key... 2.5.1 :004 > public_key = Cryptos::PublicKey.new private_key => #<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541> # Generating Bitcoin address for testnet 2.5.1 :005 > address = Cryptos::Bitcoin::Address.new public_key => #<Cryptos::Bitcoin::Address:0x00007fc9d18a29b8 @public_key=#<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>, @testnet=true> 2.5.1 :006 > address.to_s => "n37t517bJymxg3YftzqyVTAnjg4wKb3Tth" # Generating Litecoin address for mainnet 2.5.1 :007 > address = Cryptos::Litecoin::Address.new public_key, testnet: false => #<Cryptos::Litecoin::Address:0x00007fc9d119a1e8 @public_key=#<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>, @testnet=false> 2.5.1 :008 > address.to_s => "Lgpt3ALSacam9jmDMZrtwZ2E5tqWVYzEkH" ``` ## Todos * Work in progress: Zcash and Ethereum support * Add more and more coins, cool crypto tech
json metadata{"tags":["crypto","bitcoin","litecoin","transaction","atomicswaps"],"links":["https://github.com/icostan/cryptos-ruby"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcrypto
permlinkrelease-cryptos-ruby-project
titleRelease: Cryptos-ruby project
Transaction InfoBlock #28466037/Trx 241d8dae108f73798bfd4100c7d8826847618d42
View Raw JSON Data
{
  "block": 28466037,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "# Release: Cryptos-ruby project\n\nI just want to announce the very first release [v0.0.3] of Cryptos-ruby project, a simple and very easy to use Ruby API to  manipulate multiple crypto coins.\n\nFor more information please check [Github project page](https://github.com/icostan/cryptos-ruby).\n\n## Features\n  * Generate private/public keys\n  * Generate Bitcoin/Litecoin addresses (more to come)\n  * Create Bitcoin/Litecoin transactions\n  * Execute atomic swaps between Bitcoin and Litecoin\n\n## Installation\n```shell\ngem install cryptos\n```\n## Usage\n\n```ruby\n# Importing library...\n2.5.1 :001 > require 'cryptos'\n\n# Generating private key...\n2.5.1 :003 > private_key = Cryptos::PrivateKey.generate\n => #<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>\n\n# Generating public key...\n2.5.1 :004 > public_key = Cryptos::PublicKey.new private_key\n => #<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>\n\n# Generating Bitcoin address for testnet\n2.5.1 :005 > address = Cryptos::Bitcoin::Address.new public_key\n => #<Cryptos::Bitcoin::Address:0x00007fc9d18a29b8 @public_key=#<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>, @testnet=true>\n2.5.1 :006 > address.to_s\n => \"n37t517bJymxg3YftzqyVTAnjg4wKb3Tth\"\n\n# Generating Litecoin address for mainnet\n2.5.1 :007 > address = Cryptos::Litecoin::Address.new public_key, testnet: false\n => #<Cryptos::Litecoin::Address:0x00007fc9d119a1e8 @public_key=#<Cryptos::PublicKey:0x00007fc9d122fc48 @private_key=#<Cryptos::PrivateKey:0x00007fc9d123e2e8 @value=47930083789607287790662857866073624449854924554643360243140359905082181414216, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337>, @x=37935518911551901189910488779135983333966395037400135768523765072809885233888, @y=60841756395196742058661917858407687798753194961782162321894682162865330386541>, @testnet=false>\n2.5.1 :008 > address.to_s\n => \"Lgpt3ALSacam9jmDMZrtwZ2E5tqWVYzEkH\"\n```\n\n## Todos\n  * Work in progress: Zcash and Ethereum support\n  * Add more and more coins, cool crypto tech",
      "json_metadata": "{\"tags\":[\"crypto\",\"bitcoin\",\"litecoin\",\"transaction\",\"atomicswaps\"],\"links\":[\"https://github.com/icostan/cryptos-ruby\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "crypto",
      "permlink": "release-cryptos-ruby-project",
      "title": "Release: Cryptos-ruby project"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-12-11T09:24:36",
  "trx_id": "241d8dae108f73798bfd4100c7d8826847618d42",
  "trx_in_block": 11,
  "virtual_op": 0
}
2018/11/11 12:47:57
authoricostan
permlinkthe-hard-way-bitcoin-transactions
votermrbean1
weight10000 (100.00%)
Transaction InfoBlock #27606565/Trx 44b02e6526ea83b83e8ae841415827277e2b0318
View Raw JSON Data
{
  "block": 27606565,
  "op": [
    "vote",
    {
      "author": "icostan",
      "permlink": "the-hard-way-bitcoin-transactions",
      "voter": "mrbean1",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-11-11T12:47:57",
  "trx_id": "44b02e6526ea83b83e8ae841415827277e2b0318",
  "trx_in_block": 33,
  "virtual_op": 0
}
2018/11/11 12:40:57
authoricostan
body# The hard way - Bitcoin: Transaction This is Part 2 of 'The hard way - Bitcoin' series and I will start with 'the easy way' section first because even this gets a bit complex, then will continue with the hard stuff, crafting a Bitcoin transaction from scratch using basic math and cryptography. ## A. The easy way ### Create private key, public key and address We are going to generate private key, public key and Bitcoin testnet address to be used in this article. ```shell shell> bx seed # generate seed 27634686aa8838acaa68e27aea6c072534394ce411cb7d75 shell> echo 27634686aa8838acaa68e27aea6c072534394ce411cb7d75 | bx ec-new # generate private key 79020296790075fc8e36835e045c513df8b20d3b3b9dbff4d043be84ae488f8d shell> echo 79020296790075fc8e36835e045c513df8b20d3b3b9dbff4d043be84ae488f8d | bx ec-to-public # generate public key 03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1 shell> echo 03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1 | bx ec-to-address # generate address n1C8nsmi4sc4hMBGgVZrnhxeFtk1sTbMZ4 ``` ### Previous transaction to be spent In Bitcoin we have this concept called UTXO (Unspent Transaction Output) which is the unspent output of a previous transaction. ```shell shell> bx fetch-tx d30de2a476060e08f4761ad99993ea1f7387bfcb3385f0d604a36a04676cdf93 transaction { hash d30de2a476060e08f4761ad99993ea1f7387bfcb3385f0d604a36a04676cdf93 inputs { input { address_hash 10924d4f0aefd6dc652ce1fe906694eba4dfc8ae previous_output { hash 264d0f5be4ebdd1102e23c4b440955b04b291c654323bdd33cd51d8989e3d54f index 1 } script "[30450221009553c91c4aaf5ab137d5ed77cbc94a2c0511461f0de51b83fc2f00202f6a6beb022029a691221e1f664fa268524565d44f9e8a5387c5c091ec55f98ad12705720e7201] [02a46fc215bb6899814dc5bd026d815017784a2c4ceb78e7befdab1d5dfd51ef1a]" sequence 4294967294 } } lock_time 1384777 outputs { output { address_hash de69e4fc748732103653236dcc31c79e87422925 script "dup hash160 [de69e4fc748732103653236dcc31c79e87422925] equalverify checksig" value 3625875580 } output { address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a script "dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig" value 65000000 } } version 2 } ``` ### Create transaction Create transaction with two parameters: input (previous transaction hash and previous transaction output index) and output (receiving address and amount to send in Satoshi). ```shell shell> bx tx-encode -i d30de2a476060e08f4761ad99993ea1f7387bfcb3385f0d604a36a04676cdf93:1 -o 2NFrxEjw5v2i7L8pm9dWjWSFpDRXmj8dBTn:64000000 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd30100000000ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000 ``` ### Sign transaction Sign the input to be spent using private key and lock script. ```shell shell> bx input-sign 79020296790075fc8e36835e045c513df8b20d3b3b9dbff4d043be84ae488f8d "dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig" 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd30100000000ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000 3045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e1367451101 ``` Create unlock script using signed endorsement and the public key then set it as transaction's input. ```shell shell> bx input-set "[3045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e1367451101] [03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1]" 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd30100000000ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd3010000006b483045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e13674511012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000 ``` ### Validate transaction Validate input with public key, lock script and signed endorsement. ```shell shell> bx input-validate 03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1 "dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig" 3045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e1367451101 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd3010000006b483045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e13674511012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000 The endorsement is valid. ``` Validate encoded transaction as a whole. ```shell shell> bx validate-tx 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd3010000006b483045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e13674511012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000 The transaction is valid. ``` ### Broadcast transaction Broadcast the transaction to network. ```shell bx send-tx 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd3010000006b483045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e13674511012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000 Sent transaction. ``` Check address and transaction history. ```shell shell> bx fetch-history n1C8nsmi4sc4hMBGgVZrnhxeFtk1sTbMZ4 transfers { transfer { received { hash d30de2a476060e08f4761ad99993ea1f7387bfcb3385f0d604a36a04676cdf93 height 1384780 index 1 } spent { hash fb8c52b201eb474ea3b2cb1f482cf4f774f710c711267818fbdd4763a5ca38b9 height 1384802 index 0 } value 65000000 } } ``` ## B. The hard way Now lets get down to real business and craft our own transaction starting with a few utility methods that we are going to use along the way. Two methods to convert big numbers to bytes string and vice-versa, padding with `0x00` to satisfy the required length if any. ```ruby def bytes_to_bignum(bytes_string) bytes_string.bytes.reduce { |n, b| (n << 8) + b } end def bignum_to_bytes(n, length=nil) a = [] while n > 0 a << (n & 0xFF) n >>= 8 end a.fill 0x00, a.length, length - a.length if length a.reverse.pack('C*') end ``` Base58 encoding / decoding methods, Bitcoin address decoding to Hash160 (hashing twice with sha256 then ripe160) and build Bitcoin script based on destination address that can be Pay-to-PublicKey-Hash or Pay-to-Script-hash. ```ruby def bitcoin_base58_encode(ripe160_hash) alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' value = ripe160_hash.to_i 16 output = '' while value > 0 remainder = value % 58 value /= 58 output += alphabet[remainder] end output += alphabet[0] * [ripe160_hash].pack('H*').bytes.find_index{|b| b != 0} output.reverse end def bitcoin_base58_decode(address) alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' int_val = 0 address.reverse.chars.each_with_index do |char, index| char_index = alphabet.index(char) int_val += char_index * 58**index end bignum_to_bytes(int_val, 25).unpack('H*').first end def bitcoin_address_decode(address) wrap_encode = bitcoin_base58_decode address wrap_encode[2, 40] end def bitcoin_script(address) hash160 = bitcoin_address_decode address if address.start_with? '2' "OP_HASH160 #{hash160} OP_EQUAL" else "OP_DUP OP_HASH160 #{hash160} OP_EQUALVERIFY OP_CHECKSIG" end end ``` Multiple utility methods to transform different data types into hex string. ```ruby class Struct OPCODES = { 'OP_DUP' => 0x76, 'OP_HASH160' => 0xA9, 'OP_EQUAL' => 0x87, 'OP_EQUALVERIFY' => 0x88, 'OP_CHECKSIG' => 0xAC }.freeze def opcode(token) raise "opcode #{token} not found" unless OPCODES.include?(token) OPCODES[token].to_s 16 end def data(token) bin_size = hex_size token byte_to_hex(bin_size) + token end def hex_size(hex) [hex].pack('H*').size end def to_hex(binary_bytes) binary_bytes.unpack('H*').first end def hash_to_hex(value) to_hex [value].pack('H*').reverse end def int_to_hex(value) to_hex [value].pack('V') end def byte_to_hex(value) to_hex [value].pack('C') end def long_to_hex(value) to_hex [value].pack('Q<') end def script_to_hex(script_string) script_string.split.map { |token| token.start_with?('OP') ? opcode(token) : data(token) }.join end def sha256(hex) Digest::SHA256.hexdigest([hex].pack('H*')) end end ``` Now, lets check the previous transaction that we want to spend. ```shell shell> bx fetch-transaction ea8a64e122304637e8da016836e9afd59fc1179dfa15affc40d63b34e7db0cec transaction { hash ea8a64e122304637e8da016836e9afd59fc1179dfa15affc40d63b34e7db0cec inputs { input { address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a previous_output { hash 6b22d8a69432774ebbc00566755ff8da241be83c1b364ca177e241e23a0e111c index 0 } script "[3045022100e4c449be7643140b9a62635afe8f99406311372f6ad4215d19a6d0b0ea306c7902203c6966502dba43b86d34d9252adb7632632bce1cf83ed721b5a1ac00e9e0f48a01] [03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1]" sequence 4294967295 } } lock_time 0 outputs { output { address_hash ad99d5964d9180d501c8863f4bcd7b04f0766787 script "dup hash160 [ad99d5964d9180d501c8863f4bcd7b04f0766787] equalverify checksig" value 1000000 } output { address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a script "dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig" value 23990000 } } version 1 } ``` Build transaction input from previous UTXO (Unspent Transaction Output): value, tx hash and output index. ```ruby Input = Struct.new :value, :tx_hash, :index, :unlock_script, :sequence do def initialize(value, tx_hash, index, unlock_script: '', sequence: 0xfffffffff) super value, tx_hash, index, unlock_script, sequence end def serialize script_hex = script_to_hex(unlock_script) hash_to_hex(tx_hash) + int_to_hex(index) + byte_to_hex(hex_size(script_hex)) + script_hex + int_to_hex(sequence) end end input = Input.new 23_990_000, 'ea8a64e122304637e8da016836e9afd59fc1179dfa15affc40d63b34e7db0cec', 1 ``` Build transaction output with output value and lock script. ```ruby Output = Struct.new :value, :lock_script do def serialize script_hex = script_to_hex(lock_script) long_to_hex(value) + byte_to_hex(hex_size(script_hex)) + script_hex end end output_script = bitcoin_script '2N959B4qEPkce8jbzQC7EQaS6uaEBB9YTgQ' output = Output.new 1_000_000, output_script ``` Build the second output which is the 'change' transaction. ```ruby change_value = input.value - output.value - 10_000 change_script = bitcoin_script 'n1C8nsmi4sc4hMBGgVZrnhxeFtk1sTbMZ4' change = Output.new change_value, change_script ``` Before creating the actual transction lets introduce a few elliptic curve methods methods and parameters that we all know and love already. ```ruby EC_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 EC_Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 EC_p = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1 EC_n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 def extended_euclidean_algorithm(a, b) s, old_s = 0, 1 t, old_t = 1, 0 r, old_r = b, a while r != 0 quotient = old_r / r old_r, r = r, old_r - quotient * r old_s, s = s, old_s - quotient * s old_t, t = t, old_t - quotient * t end [old_r, old_s, old_t] end def inverse(n, p) gcd, x, y = extended_euclidean_algorithm(n, p) (n * x + p * y) % p == gcd || raise('invalid gcd') gcd == 1 || raise('no multiplicative inverse') x % p end def ec_double(px, py, pn) i_2y = inverse(2 * py, pn) slope = (3 * px**2 * i_2y) % pn x = (slope**2 - 2 * px) % pn y = (slope*(px - x) - py) % pn [x, y] end def ec_add(ax, ay, bx, by, pn) return [ax, ay] if bx == 0 && by == 0 return [bx, by] if ax == 0 && ay == 0 return ec_double(ax, ay, pn) if ax == bx && ay == by i_bax = inverse(ax - bx, pn) slope = ((ay - by) * i_bax) % pn x = (slope**2 - ax - bx) % pn y = (slope*(ax - x) - ay) % pn [x, y] end def ec_multiply(m, px, py, pn) nx, ny = px, py qx, qy = 0, 0 while m > 0 qx, qy = ec_add qx, qy, nx, ny, pn if m&1 == 1 nx, ny = ec_double nx, ny, pn m >>= 1 end [qx, qy] end ``` And these are the core methods of Elliptic Curve Digital Signature Algorithm (ECDSA), the sign/verify methods with DER signature encoding. ```ruby def ecdsa_sign(private_key, digest, temp_key = nil) temp_key ||= 1 + SecureRandom.random_number(EC_n - 1) rx, _ry = ec_multiply(temp_key, EC_Gx, EC_Gy, EC_p) r = rx % EC_n r > 0 || raise('r is zero, try again new temp key') i_tk = inverse temp_key, EC_n m = bytes_to_bignum digest s = (i_tk * (m + r * private_key)) % EC_n s > 0 || raise('s is zero, try again new temp key') [r, s] end def ecdsa_verify?(px, py, digest, signature) r, s = signature i_s = inverse s, EC_n m = bytes_to_bignum digest u1 = i_s * m % EC_n u2 = i_s * r % EC_n u1Gx, u1Gy = ec_multiply u1, EC_Gx, EC_Gy, EC_p u2Px, u2Py = ec_multiply u2, px, py, EC_p rx, _ry = ec_add u1Gx, u1Gy, u2Px, u2Py, EC_p r == rx end Der = Struct.new :der, :length, :ri, :rl, :r, :si, :sl, :s, :sighash_type do def initialize(der: 0x30, length: 0x45, ri: 0x02, rl: 0x21, r: nil, si: 0x02, sl: 0x20, s: nil, sighash_type: 0x01) super der, length, ri, rl, r, si, sl, s, sighash_type end def serialize byte_to_hex(der) + byte_to_hex(length) + byte_to_hex(ri) + byte_to_hex(rl) + to_hex(bignum_to_bytes(r, 33)) + byte_to_hex(si) + byte_to_hex(sl) + to_hex(bignum_to_bytes(s, 32)) + byte_to_hex(sighash_type) end def self.parse(signature) fields = *[signature].pack('H*').unpack('CCCCH66CCH64C') Der.new r: fields[4], s: fields[7], sighash_type: fields[8] end end ``` We are getting there, build Bitcoin transaction passing in the input and the two outputs. ```ruby Transaction = Struct.new :version, :inputs, :outputs, :locktime do def serialize inputs_hex = inputs.map(&:serialize).join outputs_hex = outputs.map(&:serialize).join int_to_hex(version) + byte_to_hex(inputs.size) + inputs_hex + byte_to_hex(outputs.size) + outputs_hex + int_to_hex(locktime) end def hash hash_to_hex sha256(sha256(serialize)) end def signature_hash(lock_script = nil, sighash_type = 0x1) inputs.first.unlock_script = lock_script if lock_script hash = sha256(sha256(serialize + int_to_hex(sighash_type))) [hash].pack('H*') end def sign(private_key, public_key, lock_script, sighash_type = 0x01) bytes_string = signature_hash lock_script, sighash_type r, s = ecdsa_sign private_key, bytes_string der = Der.new r: r, s: s inputs.first.unlock_script = "#{der.serialize} #{public_key}" serialize end end transaction = Transaction.new 1, [input], [output, change], 0 ``` Finally, to sign the transaction we need 3 things: private key, public key and the lock script of previous UTXO to spend. ```ruby private_key = 0x79020296790075fc8e36835e045c513df8b20d3b3b9dbff4d043be84ae488f8d public_key = '03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1' lock_script = bitcoin_script 'n1C8nsmi4sc4hMBGgVZrnhxeFtk1sTbMZ4' tx_hex = transaction.sign private_key, public_key, lock_script puts "TX hash: #{transaction.hash}" puts "TX hex: #{tx_hex}" ``` And VOILA! take the returned transaction hex and decode/validate it: ```shell shell> bx tx-decode 0100000001ec0cdbe7343bd640fcaf15fa9d17c19fd5afe9366801dae837463022e1648aea010000006b483045022100c1c85b5865f64f8f18c54f028a50942cd21cbda9c4a5f9296132defe51017c640220304793e361e71b3bae812923ca4aa5481a2fead05a73583ad5d930e7229f562f012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff0240420f000000000017a914ad99d5964d9180d501c8863f4bcd7b04f076678787a0a55e01000000001976a914d7d35ff2ed9cbc95e689338af8cd1db133be6a4a88ac00000000 transaction { hash c218dc394fef23ab9652ed6fd49539aa5dfb4f0153127b5c433032918948e60b inputs { input { address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a previous_output { hash ea8a64e122304637e8da016836e9afd59fc1179dfa15affc40d63b34e7db0cec index 1 } script "[3045022100c1c85b5865f64f8f18c54f028a50942cd21cbda9c4a5f9296132defe51017c640220304793e361e71b3bae812923ca4aa5481a2fead05a73583ad5d930e7229f562f01] [03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1]" sequence 4294967295 } } lock_time 0 outputs { output { address_hash ad99d5964d9180d501c8863f4bcd7b04f0766787 script "hash160 [ad99d5964d9180d501c8863f4bcd7b04f0766787] equal" value 1000000 } output { address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a script "dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig" value 22980000 } } version 1 } ``` then submit it to Bitcoin testnet network via: - [Broadcast TX](https://testnet.blockchain.info/pushtx) - or using `bitcoin-cli` command line tool ```shell shell> bitcoin-cli -testnet sendrawtransaction 0100000001ec0cdbe7343bd640fcaf15fa9d17c19fd5afe9366801dae837463022e1648aea010000006b483045022100c1c85b5865f64f8f18c54f028a50942cd21cbda9c4a5f9296132defe51017c640220304793e361e71b3bae812923ca4aa5481a2fead05a73583ad5d930e7229f562f012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff0240420f000000000017a914ad99d5964d9180d501c8863f4bcd7b04f076678787a0a55e01000000001976a914d7d35ff2ed9cbc95e689338af8cd1db133be6a4a88ac00000000 ``` ## C. Conclusions Creating transaction is a bit more difficult than generating a Bitcoin address that we saw in Part 1 but it is all possible once you understand the basics of Bitcoin like UTXOs, script and transactions. ## D. References Here are the most important references but feel free to get in touch for more information. * [OP_CHECKSIG](https://en.bitcoin.it/wiki/OP_CHECKSIG) * [Bitcoin Script](https://en.bitcoin.it/wiki/Script) * [Address prefixes](https://en.bitcoin.it/wiki/List_of_address_prefixes) * [Libbitcoin-explorer](https://github.com/libbitcoin/libbitcoin-explorer/wiki) The very end.
json metadata{"tags":["bitcoin","cryptography","ecdsa","utxo","transaction"],"links":["https://testnet.blockchain.info/pushtx","https://en.bitcoin.it/wiki/OP_CHECKSIG","https://en.bitcoin.it/wiki/Script","https://en.bitcoin.it/wiki/List_of_address_prefixes","https://github.com/libbitcoin/libbitcoin-explorer/wiki"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitcoin
permlinkthe-hard-way-bitcoin-transactions
titleThe hard way - Bitcoin: transactions
Transaction InfoBlock #27606425/Trx 50830e572d20a3511dcd7b863daaee39d77d99b9
View Raw JSON Data
{
  "block": 27606425,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "# The hard way - Bitcoin: Transaction\n\n\nThis is Part 2 of 'The hard way - Bitcoin' series and I will start with 'the easy way' section first because even this gets a bit complex, then will continue with the hard stuff, crafting a Bitcoin transaction from scratch using basic math and cryptography.\n\n## A. The easy way\n\n### Create private key, public key and address\n\nWe are going to generate private key, public key and Bitcoin testnet address to be used in this article.\n\n```shell\nshell> bx seed # generate seed\n27634686aa8838acaa68e27aea6c072534394ce411cb7d75\n\nshell> echo 27634686aa8838acaa68e27aea6c072534394ce411cb7d75 | bx ec-new # generate private key\n79020296790075fc8e36835e045c513df8b20d3b3b9dbff4d043be84ae488f8d\n\nshell> echo 79020296790075fc8e36835e045c513df8b20d3b3b9dbff4d043be84ae488f8d | bx ec-to-public # generate public key\n03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1\n\nshell> echo 03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1 | bx ec-to-address # generate address\nn1C8nsmi4sc4hMBGgVZrnhxeFtk1sTbMZ4\n```\n### Previous transaction to be spent\n\nIn Bitcoin we have this concept called UTXO (Unspent Transaction Output) which is the unspent output of a previous transaction.\n\n```shell\nshell> bx fetch-tx d30de2a476060e08f4761ad99993ea1f7387bfcb3385f0d604a36a04676cdf93\ntransaction\n{\n    hash d30de2a476060e08f4761ad99993ea1f7387bfcb3385f0d604a36a04676cdf93\n    inputs\n    {\n        input\n        {\n            address_hash 10924d4f0aefd6dc652ce1fe906694eba4dfc8ae\n            previous_output\n            {\n                hash 264d0f5be4ebdd1102e23c4b440955b04b291c654323bdd33cd51d8989e3d54f\n                index 1\n            }\n            script \"[30450221009553c91c4aaf5ab137d5ed77cbc94a2c0511461f0de51b83fc2f00202f6a6beb022029a691221e1f664fa268524565d44f9e8a5387c5c091ec55f98ad12705720e7201] [02a46fc215bb6899814dc5bd026d815017784a2c4ceb78e7befdab1d5dfd51ef1a]\"\n            sequence 4294967294\n        }\n    }\n    lock_time 1384777\n    outputs\n    {\n        output\n        {\n            address_hash de69e4fc748732103653236dcc31c79e87422925\n            script \"dup hash160 [de69e4fc748732103653236dcc31c79e87422925] equalverify checksig\"\n            value 3625875580\n        }\n        output\n        {\n            address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a\n            script \"dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig\"\n            value 65000000\n        }\n    }\n    version 2\n}\n```\n\n### Create transaction\n\nCreate transaction with two parameters: input (previous transaction hash and previous transaction output index) and output (receiving address and amount to send in Satoshi).\n\n```shell\nshell> bx tx-encode -i d30de2a476060e08f4761ad99993ea1f7387bfcb3385f0d604a36a04676cdf93:1 -o 2NFrxEjw5v2i7L8pm9dWjWSFpDRXmj8dBTn:64000000\n010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd30100000000ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000\n```\n\n### Sign transaction\n\nSign the input to be spent using private key and lock script.\n\n```shell\nshell> bx input-sign 79020296790075fc8e36835e045c513df8b20d3b3b9dbff4d043be84ae488f8d \"dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig\" 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd30100000000ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000\n3045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e1367451101\n```\n\nCreate unlock script using signed endorsement and the public key then set it as transaction's input.\n\n```shell\nshell> bx input-set \"[3045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e1367451101] [03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1]\" 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd30100000000ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000\n010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd3010000006b483045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e13674511012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000\n```\n\n### Validate transaction\n\nValidate input with public key, lock script and signed endorsement.\n\n```shell\nshell> bx input-validate 03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1 \"dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig\" 3045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e1367451101 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd3010000006b483045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e13674511012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000\nThe endorsement is valid.\n```\n\nValidate encoded transaction as a whole.\n\n```shell\nshell> bx validate-tx 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd3010000006b483045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e13674511012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000\nThe transaction is valid.\n```\n\n### Broadcast transaction\n\nBroadcast the transaction to network.\n\n```shell\nbx send-tx 010000000193df6c67046aa304d6f08533cbbf87731fea9399d91a76f4080e0676a4e20dd3010000006b483045022100b290086350a59ce28dd80cc89eac80eac097c20a50ed8c4f35b1ecbed789b65c02200129f4c34a9b05705d4f5e55acff0ce44b5565ab4a8c7faa4a74cf5e13674511012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff010090d0030000000017a914f81498040e79014455a5e8f7bd39bce5428121d38700000000\nSent transaction.\n```\n\nCheck address and transaction history.\n\n```shell\nshell> bx fetch-history n1C8nsmi4sc4hMBGgVZrnhxeFtk1sTbMZ4\ntransfers\n{\n    transfer\n    {\n        received\n        {\n            hash d30de2a476060e08f4761ad99993ea1f7387bfcb3385f0d604a36a04676cdf93\n            height 1384780\n            index 1\n        }\n        spent\n        {\n            hash fb8c52b201eb474ea3b2cb1f482cf4f774f710c711267818fbdd4763a5ca38b9\n            height 1384802\n            index 0\n        }\n        value 65000000\n    }\n}\n```\n\n## B. The hard way\n\nNow lets get down to real business and craft our own transaction starting with a few utility methods that we are going to use along the way.\n\nTwo methods to convert big numbers to bytes string and vice-versa, padding with `0x00` to satisfy the required length if any.\n\n```ruby\ndef bytes_to_bignum(bytes_string)\n  bytes_string.bytes.reduce { |n, b| (n << 8) + b }\nend\ndef bignum_to_bytes(n, length=nil)\n  a = []\n  while n > 0\n    a << (n & 0xFF)\n    n >>= 8\n  end\n  a.fill 0x00, a.length, length - a.length if length\n  a.reverse.pack('C*')\nend\n```\n\nBase58 encoding / decoding methods, Bitcoin address decoding to Hash160 (hashing twice with sha256 then ripe160) and build Bitcoin script based on destination address that can be Pay-to-PublicKey-Hash or Pay-to-Script-hash.\n\n```ruby\ndef bitcoin_base58_encode(ripe160_hash)\n  alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'\n  value = ripe160_hash.to_i 16\n  output = ''\n  while value > 0\n    remainder = value % 58\n    value /= 58\n    output += alphabet[remainder]\n  end\n  output += alphabet[0] * [ripe160_hash].pack('H*').bytes.find_index{|b| b != 0}\n  output.reverse\nend\ndef bitcoin_base58_decode(address)\n  alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'\n  int_val = 0\n  address.reverse.chars.each_with_index do |char, index|\n    char_index = alphabet.index(char)\n    int_val += char_index * 58**index\n  end\n  bignum_to_bytes(int_val, 25).unpack('H*').first\nend\ndef bitcoin_address_decode(address)\n  wrap_encode = bitcoin_base58_decode address\n  wrap_encode[2, 40]\nend\ndef bitcoin_script(address)\n  hash160 = bitcoin_address_decode address\n  if address.start_with? '2'\n    \"OP_HASH160 #{hash160} OP_EQUAL\"\n  else\n    \"OP_DUP OP_HASH160 #{hash160} OP_EQUALVERIFY OP_CHECKSIG\"\n  end\nend\n```\n\nMultiple utility methods to transform different data types into hex string.\n\n```ruby\nclass Struct\n  OPCODES = {\n    'OP_DUP' =>  0x76,\n    'OP_HASH160' =>  0xA9,\n    'OP_EQUAL' =>  0x87,\n    'OP_EQUALVERIFY' =>  0x88,\n    'OP_CHECKSIG' =>  0xAC\n  }.freeze\n  def opcode(token)\n    raise \"opcode #{token} not found\" unless OPCODES.include?(token)\n    OPCODES[token].to_s 16\n  end\n  def data(token)\n    bin_size = hex_size token\n    byte_to_hex(bin_size) + token\n  end\n  def hex_size(hex)\n    [hex].pack('H*').size\n  end\n  def to_hex(binary_bytes)\n    binary_bytes.unpack('H*').first\n  end\n  def hash_to_hex(value)\n    to_hex [value].pack('H*').reverse\n  end\n  def int_to_hex(value)\n    to_hex [value].pack('V')\n  end\n  def byte_to_hex(value)\n    to_hex [value].pack('C')\n  end\n  def long_to_hex(value)\n    to_hex [value].pack('Q<')\n  end\n  def script_to_hex(script_string)\n    script_string.split.map { |token| token.start_with?('OP') ? opcode(token) : data(token) }.join\n  end\n  def sha256(hex)\n    Digest::SHA256.hexdigest([hex].pack('H*'))\n  end\nend\n```\n\nNow, lets check the previous transaction that we want to spend.\n\n```shell\nshell> bx fetch-transaction ea8a64e122304637e8da016836e9afd59fc1179dfa15affc40d63b34e7db0cec\n\ntransaction\n{\n    hash ea8a64e122304637e8da016836e9afd59fc1179dfa15affc40d63b34e7db0cec\n    inputs\n    {\n        input\n        {\n            address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a\n            previous_output\n            {\n                hash 6b22d8a69432774ebbc00566755ff8da241be83c1b364ca177e241e23a0e111c\n                index 0\n            }\n            script \"[3045022100e4c449be7643140b9a62635afe8f99406311372f6ad4215d19a6d0b0ea306c7902203c6966502dba43b86d34d9252adb7632632bce1cf83ed721b5a1ac00e9e0f48a01] [03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1]\"\n            sequence 4294967295\n        }\n    }\n    lock_time 0\n    outputs\n    {\n        output\n        {\n            address_hash ad99d5964d9180d501c8863f4bcd7b04f0766787\n            script \"dup hash160 [ad99d5964d9180d501c8863f4bcd7b04f0766787] equalverify checksig\"\n            value 1000000\n        }\n        output\n        {\n            address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a\n            script \"dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig\"\n            value 23990000\n        }\n    }\n    version 1\n}\n```\n\nBuild transaction input from previous UTXO (Unspent Transaction Output): value, tx hash and output index.\n\n```ruby\nInput = Struct.new :value, :tx_hash, :index, :unlock_script, :sequence do\n  def initialize(value, tx_hash, index, unlock_script: '', sequence: 0xfffffffff)\n    super value, tx_hash, index, unlock_script, sequence\n  end\n  def serialize\n    script_hex = script_to_hex(unlock_script)\n    hash_to_hex(tx_hash) + int_to_hex(index) +\n      byte_to_hex(hex_size(script_hex)) + script_hex + int_to_hex(sequence)\n  end\nend\ninput = Input.new 23_990_000, 'ea8a64e122304637e8da016836e9afd59fc1179dfa15affc40d63b34e7db0cec', 1\n```\n\nBuild transaction output with output value and lock script.\n\n```ruby\nOutput = Struct.new :value, :lock_script do\n  def serialize\n    script_hex = script_to_hex(lock_script)\n    long_to_hex(value) + byte_to_hex(hex_size(script_hex)) + script_hex\n  end\nend\noutput_script = bitcoin_script '2N959B4qEPkce8jbzQC7EQaS6uaEBB9YTgQ'\noutput = Output.new 1_000_000, output_script\n```\n\nBuild the second output which is the 'change' transaction.\n\n```ruby\nchange_value = input.value - output.value - 10_000\nchange_script = bitcoin_script 'n1C8nsmi4sc4hMBGgVZrnhxeFtk1sTbMZ4'\nchange = Output.new change_value, change_script\n```\n\nBefore creating the actual transction lets introduce a few elliptic curve methods methods and parameters that we all know and love already.\n\n```ruby\nEC_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\nEC_Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\nEC_p = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1\nEC_n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\n\ndef extended_euclidean_algorithm(a, b)\n  s, old_s = 0, 1\n  t, old_t = 1, 0\n  r, old_r = b, a\n  while r != 0\n    quotient = old_r / r\n    old_r, r = r, old_r - quotient * r\n    old_s, s = s, old_s - quotient * s\n    old_t, t = t, old_t - quotient * t\n  end\n  [old_r, old_s, old_t]\nend\ndef inverse(n, p)\n  gcd, x, y = extended_euclidean_algorithm(n, p)\n  (n * x + p * y) % p == gcd || raise('invalid gcd')\n  gcd == 1 || raise('no multiplicative inverse')\n  x % p\nend\ndef ec_double(px, py, pn)\n  i_2y = inverse(2 * py, pn)\n  slope = (3 * px**2 * i_2y) % pn\n  x = (slope**2 - 2 * px) % pn\n  y = (slope*(px - x) - py) % pn\n  [x, y]\nend\ndef ec_add(ax, ay, bx, by, pn)\n  return [ax, ay] if bx == 0 && by == 0\n  return [bx, by] if ax == 0 && ay == 0\n  return ec_double(ax, ay, pn) if ax == bx && ay == by\n\n  i_bax = inverse(ax - bx, pn)\n  slope = ((ay - by) * i_bax) % pn\n  x = (slope**2 - ax - bx) % pn\n  y = (slope*(ax - x) - ay) % pn\n  [x, y]\nend\ndef ec_multiply(m, px, py, pn)\n  nx, ny = px, py\n  qx, qy = 0, 0\n  while m > 0\n    qx, qy = ec_add qx, qy, nx, ny, pn if m&1 == 1\n    nx, ny = ec_double nx, ny, pn\n    m >>= 1\n  end\n  [qx, qy]\nend\n```\n\nAnd these are the core methods of Elliptic Curve Digital Signature Algorithm (ECDSA), the sign/verify methods with DER signature encoding.\n\n```ruby\ndef ecdsa_sign(private_key, digest, temp_key = nil)\n  temp_key ||= 1 + SecureRandom.random_number(EC_n - 1)\n  rx, _ry = ec_multiply(temp_key, EC_Gx, EC_Gy, EC_p)\n  r = rx % EC_n\n  r > 0 || raise('r is zero, try again new temp key')\n  i_tk = inverse temp_key, EC_n\n  m = bytes_to_bignum digest\n  s = (i_tk * (m + r * private_key)) % EC_n\n  s > 0 || raise('s is zero, try again new temp key')\n  [r, s]\nend\ndef ecdsa_verify?(px, py, digest, signature)\n  r, s = signature\n  i_s = inverse s, EC_n\n  m = bytes_to_bignum digest\n  u1 = i_s * m % EC_n\n  u2 = i_s * r % EC_n\n  u1Gx, u1Gy = ec_multiply u1, EC_Gx, EC_Gy, EC_p\n  u2Px, u2Py = ec_multiply u2, px, py, EC_p\n  rx, _ry = ec_add u1Gx, u1Gy, u2Px, u2Py, EC_p\n  r == rx\nend\nDer = Struct.new :der, :length, :ri, :rl, :r, :si, :sl, :s, :sighash_type do\n  def initialize(der: 0x30, length: 0x45, ri: 0x02, rl: 0x21, r: nil, si: 0x02, sl: 0x20, s: nil, sighash_type: 0x01)\n    super der, length, ri, rl, r, si, sl, s, sighash_type\n  end\n  def serialize\n    byte_to_hex(der) + byte_to_hex(length) +\n      byte_to_hex(ri) + byte_to_hex(rl) + to_hex(bignum_to_bytes(r, 33)) +\n      byte_to_hex(si) + byte_to_hex(sl) + to_hex(bignum_to_bytes(s, 32)) +\n      byte_to_hex(sighash_type)\n  end\n  def self.parse(signature)\n    fields = *[signature].pack('H*').unpack('CCCCH66CCH64C')\n    Der.new r: fields[4], s: fields[7], sighash_type: fields[8]\n  end\nend\n```\n\nWe are getting there, build Bitcoin transaction passing in the input and the two outputs.\n\n```ruby\nTransaction = Struct.new :version, :inputs, :outputs, :locktime do\n  def serialize\n    inputs_hex = inputs.map(&:serialize).join\n    outputs_hex = outputs.map(&:serialize).join\n    int_to_hex(version) + byte_to_hex(inputs.size) + inputs_hex +\n      byte_to_hex(outputs.size) + outputs_hex + int_to_hex(locktime)\n  end\n  def hash\n    hash_to_hex sha256(sha256(serialize))\n  end\n  def signature_hash(lock_script = nil, sighash_type = 0x1)\n    inputs.first.unlock_script = lock_script if lock_script\n    hash = sha256(sha256(serialize + int_to_hex(sighash_type)))\n    [hash].pack('H*')\n  end\n  def sign(private_key, public_key, lock_script, sighash_type = 0x01)\n    bytes_string = signature_hash lock_script, sighash_type\n    r, s = ecdsa_sign private_key, bytes_string\n    der = Der.new r: r, s: s\n    inputs.first.unlock_script = \"#{der.serialize} #{public_key}\"\n    serialize\n  end\nend\ntransaction = Transaction.new 1, [input], [output, change], 0\n```\n\nFinally, to sign the transaction we need 3 things: private key, public key and the lock script of previous UTXO to spend.\n\n```ruby\nprivate_key = 0x79020296790075fc8e36835e045c513df8b20d3b3b9dbff4d043be84ae488f8d\npublic_key = '03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1'\nlock_script = bitcoin_script 'n1C8nsmi4sc4hMBGgVZrnhxeFtk1sTbMZ4'\n\ntx_hex = transaction.sign private_key, public_key, lock_script\nputs \"TX hash: #{transaction.hash}\"\nputs \"TX hex: #{tx_hex}\"\n```\n\nAnd VOILA! take the returned transaction hex and decode/validate it:\n\n```shell\nshell> bx tx-decode 0100000001ec0cdbe7343bd640fcaf15fa9d17c19fd5afe9366801dae837463022e1648aea010000006b483045022100c1c85b5865f64f8f18c54f028a50942cd21cbda9c4a5f9296132defe51017c640220304793e361e71b3bae812923ca4aa5481a2fead05a73583ad5d930e7229f562f012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff0240420f000000000017a914ad99d5964d9180d501c8863f4bcd7b04f076678787a0a55e01000000001976a914d7d35ff2ed9cbc95e689338af8cd1db133be6a4a88ac00000000\n\ntransaction\n{\n    hash c218dc394fef23ab9652ed6fd49539aa5dfb4f0153127b5c433032918948e60b\n    inputs\n    {\n        input\n        {\n            address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a\n            previous_output\n            {\n                hash ea8a64e122304637e8da016836e9afd59fc1179dfa15affc40d63b34e7db0cec\n                index 1\n            }\n            script \"[3045022100c1c85b5865f64f8f18c54f028a50942cd21cbda9c4a5f9296132defe51017c640220304793e361e71b3bae812923ca4aa5481a2fead05a73583ad5d930e7229f562f01] [03996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1]\"\n            sequence 4294967295\n        }\n    }\n    lock_time 0\n    outputs\n    {\n        output\n        {\n            address_hash ad99d5964d9180d501c8863f4bcd7b04f0766787\n            script \"hash160 [ad99d5964d9180d501c8863f4bcd7b04f0766787] equal\"\n            value 1000000\n        }\n        output\n        {\n            address_hash d7d35ff2ed9cbc95e689338af8cd1db133be6a4a\n            script \"dup hash160 [d7d35ff2ed9cbc95e689338af8cd1db133be6a4a] equalverify checksig\"\n            value 22980000\n        }\n    }\n    version 1\n}\n\n```\n\nthen submit it to Bitcoin testnet network via:\n\n- [Broadcast TX](https://testnet.blockchain.info/pushtx)\n- or using `bitcoin-cli` command line tool\n\n```shell\nshell> bitcoin-cli -testnet sendrawtransaction 0100000001ec0cdbe7343bd640fcaf15fa9d17c19fd5afe9366801dae837463022e1648aea010000006b483045022100c1c85b5865f64f8f18c54f028a50942cd21cbda9c4a5f9296132defe51017c640220304793e361e71b3bae812923ca4aa5481a2fead05a73583ad5d930e7229f562f012103996c918f74f0a6f1aeed99ebd81ab8eed8df99bc96fc082b20839259d332bad1ffffffff0240420f000000000017a914ad99d5964d9180d501c8863f4bcd7b04f076678787a0a55e01000000001976a914d7d35ff2ed9cbc95e689338af8cd1db133be6a4a88ac00000000\n```\n\n## C. Conclusions\n\nCreating transaction is a bit more difficult than generating a Bitcoin address that we saw in Part 1 but it is all possible once you understand the basics of Bitcoin like UTXOs, script and transactions.\n\n## D. References\n\nHere are the most important references but feel free to get in touch for more information.\n\n  * [OP_CHECKSIG](https://en.bitcoin.it/wiki/OP_CHECKSIG)\n  * [Bitcoin Script](https://en.bitcoin.it/wiki/Script)\n  * [Address prefixes](https://en.bitcoin.it/wiki/List_of_address_prefixes)\n  * [Libbitcoin-explorer](https://github.com/libbitcoin/libbitcoin-explorer/wiki)\n\nThe very end.",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"cryptography\",\"ecdsa\",\"utxo\",\"transaction\"],\"links\":[\"https://testnet.blockchain.info/pushtx\",\"https://en.bitcoin.it/wiki/OP_CHECKSIG\",\"https://en.bitcoin.it/wiki/Script\",\"https://en.bitcoin.it/wiki/List_of_address_prefixes\",\"https://github.com/libbitcoin/libbitcoin-explorer/wiki\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "the-hard-way-bitcoin-transactions",
      "title": "The hard way - Bitcoin: transactions"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-11-11T12:40:57",
  "trx_id": "50830e572d20a3511dcd7b863daaee39d77d99b9",
  "trx_in_block": 6,
  "virtual_op": 0
}
icostanupdated their account properties
2018/11/03 07:36:00
accounticostan
json metadata{"profile":{"name":"Iulian Costan","about":"Computer geek, derivatives trader, crypto enthusiast.","website":"http://iuliancostan.com"}}
memo keySTM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa
Transaction InfoBlock #27370103/Trx e2b2a631efd58a7019b54d36516e6f88f665ce60
View Raw JSON Data
{
  "block": 27370103,
  "op": [
    "account_update",
    {
      "account": "icostan",
      "json_metadata": "{\"profile\":{\"name\":\"Iulian Costan\",\"about\":\"Computer geek, derivatives trader, crypto enthusiast.\",\"website\":\"http://iuliancostan.com\"}}",
      "memo_key": "STM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-11-03T07:36:00",
  "trx_id": "e2b2a631efd58a7019b54d36516e6f88f665ce60",
  "trx_in_block": 3,
  "virtual_op": 0
}
2018/10/11 18:29:18
authoricostan
body@@ -1,64 +1,4 @@ -# The hard way - Bitcoin: private key, public key, address%0A%0A This
json metadata{"tags":["bitcoin","cryptography","elliptic-curve","math","crypto"],"links":["https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e","https://en.bitcoin.it/wiki/Secp256k1","https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored","https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication","https://en.bitcoin.it/wiki/List_of_address_prefixes","https://en.bitcoin.it/wiki/Base58Check_encoding","https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence","https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses","https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs","http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/","https://blockgeeks.com/guides/cryptocurrencies-cryptography/","https://www.coindesk.com/math-behind-bitcoin/"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitcoin
permlinkthe-hard-way-bitcoin-private-key-public-key-address
titleThe hard way - Bitcoin: private key, public key, address
Transaction InfoBlock #26721246/Trx f3e12ef05f3010c4cbfceafceca9964e7a94589d
View Raw JSON Data
{
  "block": 26721246,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -1,64 +1,4 @@\n-# The hard way - Bitcoin: private key, public key, address%0A%0A\n This\n",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"cryptography\",\"elliptic-curve\",\"math\",\"crypto\"],\"links\":[\"https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e\",\"https://en.bitcoin.it/wiki/Secp256k1\",\"https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored\",\"https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication\",\"https://en.bitcoin.it/wiki/List_of_address_prefixes\",\"https://en.bitcoin.it/wiki/Base58Check_encoding\",\"https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence\",\"https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses\",\"https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\",\"http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/\",\"https://blockgeeks.com/guides/cryptocurrencies-cryptography/\",\"https://www.coindesk.com/math-behind-bitcoin/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "the-hard-way-bitcoin-private-key-public-key-address",
      "title": "The hard way - Bitcoin: private key, public key, address"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-11T18:29:18",
  "trx_id": "f3e12ef05f3010c4cbfceafceca9964e7a94589d",
  "trx_in_block": 6,
  "virtual_op": 0
}
2018/10/11 18:25:15
authoricostan
body@@ -9665,17 +9665,18 @@ fo on th -e +is subject
json metadata{"tags":["bitcoin","cryptography","elliptic-curve","math","crypto"],"links":["https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e","https://en.bitcoin.it/wiki/Secp256k1","https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored","https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication","https://en.bitcoin.it/wiki/List_of_address_prefixes","https://en.bitcoin.it/wiki/Base58Check_encoding","https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence","https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses","https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs","http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/","https://blockgeeks.com/guides/cryptocurrencies-cryptography/","https://www.coindesk.com/math-behind-bitcoin/"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitcoin
permlinkthe-hard-way-bitcoin-private-key-public-key-address
titleThe hard way - Bitcoin: private key, public key, address
Transaction InfoBlock #26721165/Trx ea841f8f6d2a2bc5b3a92e8b7cb59ea684f82cc8
View Raw JSON Data
{
  "block": 26721165,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -9665,17 +9665,18 @@\n fo on th\n-e\n+is\n  subject\n",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"cryptography\",\"elliptic-curve\",\"math\",\"crypto\"],\"links\":[\"https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e\",\"https://en.bitcoin.it/wiki/Secp256k1\",\"https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored\",\"https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication\",\"https://en.bitcoin.it/wiki/List_of_address_prefixes\",\"https://en.bitcoin.it/wiki/Base58Check_encoding\",\"https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence\",\"https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses\",\"https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\",\"http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/\",\"https://blockgeeks.com/guides/cryptocurrencies-cryptography/\",\"https://www.coindesk.com/math-behind-bitcoin/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "the-hard-way-bitcoin-private-key-public-key-address",
      "title": "The hard way - Bitcoin: private key, public key, address"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-11T18:25:15",
  "trx_id": "ea841f8f6d2a2bc5b3a92e8b7cb59ea684f82cc8",
  "trx_in_block": 3,
  "virtual_op": 0
}
2018/10/11 18:24:54
authoricostan
body@@ -9570,16 +9570,123 @@ rences%0A%0A +See the most important references below and feel free to contact me if you need more info on the subject.%0A%0A * %5BBit
json metadata{"tags":["bitcoin","cryptography","elliptic-curve","math","crypto"],"links":["https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e","https://en.bitcoin.it/wiki/Secp256k1","https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored","https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication","https://en.bitcoin.it/wiki/List_of_address_prefixes","https://en.bitcoin.it/wiki/Base58Check_encoding","https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence","https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses","https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs","http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/","https://blockgeeks.com/guides/cryptocurrencies-cryptography/","https://www.coindesk.com/math-behind-bitcoin/"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitcoin
permlinkthe-hard-way-bitcoin-private-key-public-key-address
titleThe hard way - Bitcoin: private key, public key, address
Transaction InfoBlock #26721158/Trx 8bea3ddc7e96863e534d0156006ff1bccfb8f583
View Raw JSON Data
{
  "block": 26721158,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -9570,16 +9570,123 @@\n rences%0A%0A\n+See the most important references below and feel free to contact me if you need more info on the subject.%0A%0A\n   * %5BBit\n",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"cryptography\",\"elliptic-curve\",\"math\",\"crypto\"],\"links\":[\"https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e\",\"https://en.bitcoin.it/wiki/Secp256k1\",\"https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored\",\"https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication\",\"https://en.bitcoin.it/wiki/List_of_address_prefixes\",\"https://en.bitcoin.it/wiki/Base58Check_encoding\",\"https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence\",\"https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses\",\"https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\",\"http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/\",\"https://blockgeeks.com/guides/cryptocurrencies-cryptography/\",\"https://www.coindesk.com/math-behind-bitcoin/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "the-hard-way-bitcoin-private-key-public-key-address",
      "title": "The hard way - Bitcoin: private key, public key, address"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-11T18:24:54",
  "trx_id": "8bea3ddc7e96863e534d0156006ff1bccfb8f583",
  "trx_in_block": 1,
  "virtual_op": 0
}
2018/10/11 18:23:42
authoricostan
body@@ -233,16 +233,22 @@ In this +first section
json metadata{"tags":["bitcoin","cryptography","elliptic-curve","math","crypto"],"links":["https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e","https://en.bitcoin.it/wiki/Secp256k1","https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored","https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication","https://en.bitcoin.it/wiki/List_of_address_prefixes","https://en.bitcoin.it/wiki/Base58Check_encoding","https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence","https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses","https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs","http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/","https://blockgeeks.com/guides/cryptocurrencies-cryptography/","https://www.coindesk.com/math-behind-bitcoin/"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitcoin
permlinkthe-hard-way-bitcoin-private-key-public-key-address
titleThe hard way - Bitcoin: private key, public key, address
Transaction InfoBlock #26721134/Trx 476c413e08c40905bcffa7a15d4ec03f4f6bcbfe
View Raw JSON Data
{
  "block": 26721134,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -233,16 +233,22 @@\n In this \n+first \n section \n",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"cryptography\",\"elliptic-curve\",\"math\",\"crypto\"],\"links\":[\"https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e\",\"https://en.bitcoin.it/wiki/Secp256k1\",\"https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored\",\"https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication\",\"https://en.bitcoin.it/wiki/List_of_address_prefixes\",\"https://en.bitcoin.it/wiki/Base58Check_encoding\",\"https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence\",\"https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses\",\"https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\",\"http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/\",\"https://blockgeeks.com/guides/cryptocurrencies-cryptography/\",\"https://www.coindesk.com/math-behind-bitcoin/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "the-hard-way-bitcoin-private-key-public-key-address",
      "title": "The hard way - Bitcoin: private key, public key, address"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-11T18:23:42",
  "trx_id": "476c413e08c40905bcffa7a15d4ec03f4f6bcbfe",
  "trx_in_block": 23,
  "virtual_op": 0
}
2018/10/11 18:23:18
authoricostan
body@@ -57,26 +57,427 @@ ss%0A%0A -## A. The hard way +This article is all about two ways of generating a Bitcoin address: the hard way using simple math and the easy way using an existing Bitcoin library.%0A%0A## A. The hard way%0A%0AIn this section I am going to use simple math functions like addition and multiplication to generate a valid Bitcoin address starting from a number, the private key and calculating everything all the way up to public key and final Bitcoin address. %0A%0A##
json metadata{"tags":["bitcoin","cryptography","elliptic-curve","math","crypto"],"links":["https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e","https://en.bitcoin.it/wiki/Secp256k1","https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored","https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication","https://en.bitcoin.it/wiki/List_of_address_prefixes","https://en.bitcoin.it/wiki/Base58Check_encoding","https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence","https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses","https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs","http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/","https://blockgeeks.com/guides/cryptocurrencies-cryptography/","https://www.coindesk.com/math-behind-bitcoin/"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitcoin
permlinkthe-hard-way-bitcoin-private-key-public-key-address
titleThe hard way - Bitcoin: private key, public key, address
Transaction InfoBlock #26721126/Trx 5923410c86041713dfc50be9b3267bae0591abdf
View Raw JSON Data
{
  "block": 26721126,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "@@ -57,26 +57,427 @@\n ss%0A%0A\n-## A. The hard way\n+This article is all about two ways of generating a Bitcoin address: the hard way using simple math and the easy way using an existing Bitcoin library.%0A%0A## A. The hard way%0A%0AIn this section I am going to use simple math functions like addition and multiplication to generate a valid Bitcoin address starting from a number, the private key and calculating everything all the way up to public key and final Bitcoin address.\n %0A%0A##\n",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"cryptography\",\"elliptic-curve\",\"math\",\"crypto\"],\"links\":[\"https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e\",\"https://en.bitcoin.it/wiki/Secp256k1\",\"https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored\",\"https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication\",\"https://en.bitcoin.it/wiki/List_of_address_prefixes\",\"https://en.bitcoin.it/wiki/Base58Check_encoding\",\"https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence\",\"https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses\",\"https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\",\"http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/\",\"https://blockgeeks.com/guides/cryptocurrencies-cryptography/\",\"https://www.coindesk.com/math-behind-bitcoin/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "the-hard-way-bitcoin-private-key-public-key-address",
      "title": "The hard way - Bitcoin: private key, public key, address"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-11T18:23:18",
  "trx_id": "5923410c86041713dfc50be9b3267bae0591abdf",
  "trx_in_block": 20,
  "virtual_op": 0
}
steemdelegated 17.994 SP to @icostan
2018/10/09 11:44:06
delegateeicostan
delegatorsteem
vesting shares29254.963518 VESTS
Transaction InfoBlock #26655592/Trx f56e6681254948040d01deaf9b69b41dca772ad5
View Raw JSON Data
{
  "block": 26655592,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "29254.963518 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-09T11:44:06",
  "trx_id": "f56e6681254948040d01deaf9b69b41dca772ad5",
  "trx_in_block": 3,
  "virtual_op": 0
}
2018/10/09 10:45:00
authoricostan
body# The hard way - Bitcoin: private key, public key, address ## A. The hard way ### TL;DR; * private key is just a number (like a PIN code) but a very very large one, `10^77` order of magnitude (put this in context of number of atoms in the known, observable universe which is `10^80`) * public key is the result of scalar multiplication of private key and a point on Elliptic curve * Bitcoin address is derived from public key by doing SHA256 / RIPE160 hashing and adding network prefix and checksum suffix * we will generate valid Bitcoin address using two hash functions and simple math operations like addition, multiplication * copy / paste Ruby code snippets below or get the[gist](https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e) ### Elliptic Curve domain parameters First of all let's talk about the 6 domain parameters that are defined in [secp256k1](https://en.bitcoin.it/wiki/Secp256k1): p,a,b,G,n,h. Read [this Slashdot thread](https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored) if you want to dive into a little bit of conspiracy theory. #### Prime number - p The migthy prime number itself. ``` ruby ruby> p = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1 => 115792089237316195423570985008687907853269984665640564039457584007908834671663 ``` #### Elliptic Curve (EC) - a, b In general elliptic curves are defined as `y^2 = x^3 + ax + b` equation but since `a = 0` and `b = 7` it becomes `y^2 = x^3 + 7` which is the elliptic curve used in Bitcoin. #### Generator point, order and cofactor - G, n and h These 3 are all related and together they define a cyclic subgroup of elliptic curve where: * `G` is a point on EC, also called the generator or base point, `(x,y)` coordinates represented in uncompressed format as a concatenation of `x` and `y` prefixed with `04` or in compressed format as `x` coordinate prefix with `02`. * `n` is the order of subgroup generated by point `G`; in other words it is the number of points that belong to this subgroup * `h` is called cofactor and can be calculated as `N/n` where `N` is the order of the entire elliptic curve group. In this case cofactor is 1 so the order of the subgroup is equal to the order of the entire elliptic curve. ``` ruby ruby> G = '0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8' => "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" ruby> Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 => 55066263022277343669578718895168534326250603453777594175500187360389116729240 ruby> Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 => 32670510020758816978083085130507043184471273380659243275938904335757337482424 ruby> n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 ruby> h = 1 ``` ### 0. Private key We all know that Bitcoin's private key is 256 bits long that has to be an integer between `1` and `n`, the order of subgroup. Here is my take in binary representation. ``` ruby ruby> k = 0b1100011100001010010100111101101101010001100000111111101000010011010101001010011111000000100010100011100000001111001111100100011100111011101001110011111111001101001000111111000101100001000000011010111011011001010011010001000000110001100100001011100100101 => 11253563012059685825953619222107823549092147699031672238385790369351542642469 ruby> k.to_s 16 => "18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725" ``` ### 1. Public key Now, public key is just a scalar multiplication of private key (k) and elliptic curve generator point (G) as `P = k * G`. The result is another point `(x, y)` on elliptic curve, we take that `x` coordinate, prefix it with `02` if `y` is positive or `03` if `y` is negative and there it is, the public key in compressed format. A little bit of math and a few [algorithms](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication) that we need to use for this calculation. For scalar multiplication you can add `G` to itself `k` number of times but this will be very inefficient so we are going to use "double and add" algorithm implemented in `ec_multiply` that in turn uses `ec_add` and `ec_double`, addition and doubling operations on elliptic curves. And last, since division is not defined over finite fields we need to multiply by the `multiplicative inverse` and use `extended_euclidean_algorithm` to find the greatest common divisor. ```ruby def ec_multiply(m, px, py, pn) nx, ny = px, py qx, qy = 0, 0 while m > 0 qx, qy = ec_add qx, qy, nx, ny, pn if m&1 == 1 nx, ny = ec_double nx, ny, pn m >>= 1 end [qx, qy] end def ec_add(ax, ay, bx, by, pn) return [ax, ay] if bx == 0 && by == 0 return [bx, by] if ax == 0 && ay == 0 return ec_double(ax, ay, pn) if ax == bx && ay == by i_bax = inverse(ax - bx, pn) slope = ((ay - by) * i_bax) % pn x = (slope**2 - ax - bx) % pn y = (slope*(ax - x) - ay) % pn [x, y] end def ec_double(px, py, pn) i_2y = inverse(2 * py, pn) slope = (3 * px**2 * i_2y) % pn x = (slope**2 - 2 * px) % pn y = (slope*(px - x) - py) % pn [x, y] end def inverse(n, p) gcd, x, y = extended_euclidean_algorithm(n, p) (n * x + p * y) % p == gcd || raise('invalid gcd') gcd == 1 || raise('no multiplicative inverse') x % p end def extended_euclidean_algorithm(a, b) s, old_s = 0, 1 t, old_t = 1, 0 r, old_r = b, a while r != 0 quotient = old_r / r old_r, r = r, old_r - quotient * r old_s, s = s, old_s - quotient * s old_t, t = t, old_t - quotient * t end [old_r, old_s, old_t] end ``` And here it is, point on elliptic curve and scalar multiplication. ```ruby ruby> Px, Py = ec_multiply(k, Gx, Gy, p) => [36422191471907241029883925342251831624200921388586025344128047678873736520530, 20277110887056303803699431755396003735040374760118964734768299847012543114150] ruby> P = "#{Py > 0 ? '02' : '03'}#{Px.to_s(16)}" => "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352" ``` We can easily check if resulting point is still on elliptic curve. ```ruby ((Px**3 + 7 - Py**2) % p == 0) || raise('public key point is not on the curve') ``` ### 2. SHA256 hashing Standard SHA256 hashing here, I am going to use the implementation provided in Ruby. ``` ruby ruby> require 'digest' ruby> sha256 = Digest::SHA256.hexdigest([P].pack('H*')) => "0b7c28c9b7290c98d7438e70b3d3f7c848fbd7d1dc194ff83f4f7cc9b1378e98" ``` ### 3. RIPEMD160 hashing Same here, nothing new, standard RIPEMD160 hashing, no point reinventing the wheel. ``` ruby ruby> ripemd160 = Digest::RMD160.hexdigest([sha256].pack('H*')) => "f54a5851e9372b87810a8e60cdd2e7cfd80b6e31" ``` ### 4. Add version byte Here are a few but see [Bitcoin address prefixes](https://en.bitcoin.it/wiki/List_of_address_prefixes) for a complete list of all supported prefixes and resulting Base58 encodings: * 0x00 - Bitcoin address - result prefix is 1 * 0x05 - Pay-to-Script-Hash address - result prefix is 3 * 0x6F - Testnet address - resulting prefix is either m or n ``` ruby ruby> with_version = "00#{ripemd160}" => "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31" ``` ### 5.6.7. Calculate checksum Double SHA256 of previously calculated RIPEMD160 prefixed with version byte: ``` ruby ruby> checksum = Digest::SHA256.hexdigest(Digest::SHA256.digest([with_version].pack('H*')))[0, 8] => "c7f18fe8" ``` ### 8. Wrap encoding ``` ruby ruby> wrap_encode = "#{with_version}#{checksum}" => "00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31c7f18fe8" ``` ### 9. Bitcoin address The [Base58](https://en.bitcoin.it/wiki/Base58Check_encoding) algorithm removes confusing characters like "oOiI" and also "+/" signs to make entire address selectable on double click. ```ruby def base58(binary_hash) alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' value = binary_hash.unpack('H*')[0].to_i 16 output = '' while value > 0 remainder = value % 58 value /= 58 output += alphabet[remainder] end output += alphabet[0] * binary_hash.bytes.find_index{|b| b != 0} output.reverse end ``` Base58 encoding and the final Bitcoin address: ``` ruby ruby> base58([wrap_encode].pack('H*')) => "1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs" ``` ## B. The easy way All the steps above can be done 'the easy way', as one-liner, using excellent [Libbitcoin Explorer](https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence) tool: ```shell shell> echo 18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725 | bx ec-to-public | bx sha256 | bx ripemd160 | bx wrap-encode | bx base58-encode 1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs ``` ## C. Conclusions And here we are, the exact same Bitcoin address used in [Bitcoin address generation](https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses) tutorial is generated the hard way and the easy way. You can [check the address](https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs). # References * [Bitcoin address generation](https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses) * [Elliptic curve point multiplication](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication) * [Elliptic Curve Cryptography](http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/) * [The Science Behind Cryptocurrencies Cryptography](https://blockgeeks.com/guides/cryptocurrencies-cryptography/) * [Math behind Bitcoin](https://www.coindesk.com/math-behind-bitcoin/)
json metadata{"tags":["bitcoin","cryptography","elliptic-curve","math","crypto"],"links":["https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e","https://en.bitcoin.it/wiki/Secp256k1","https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored","https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication","https://en.bitcoin.it/wiki/List_of_address_prefixes","https://en.bitcoin.it/wiki/Base58Check_encoding","https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence","https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses","https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs","http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/","https://blockgeeks.com/guides/cryptocurrencies-cryptography/","https://www.coindesk.com/math-behind-bitcoin/"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkbitcoin
permlinkthe-hard-way-bitcoin-private-key-public-key-address
titleThe hard way - Bitcoin: private key, public key, address
Transaction InfoBlock #26654411/Trx 585e22ba0f45dbf220e41b7256edff595b37eaf4
View Raw JSON Data
{
  "block": 26654411,
  "op": [
    "comment",
    {
      "author": "icostan",
      "body": "# The hard way - Bitcoin: private key, public key, address\n\n## A. The hard way\n\n### TL;DR;\n\n  * private key is just a number (like a PIN code) but a very very large one, `10^77` order of magnitude (put this in context of number of atoms in the known, observable universe which is `10^80`)\n  * public key is the result of scalar multiplication of private key and a point on Elliptic curve\n  * Bitcoin address is derived from public key by doing SHA256 / RIPE160 hashing and adding network prefix and checksum suffix\n  * we will generate valid Bitcoin address using two hash functions and simple math operations like addition, multiplication\n  * copy / paste Ruby code snippets below or get the[gist](https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e)\n\n### Elliptic Curve domain parameters\n\nFirst of all let's talk about the 6 domain parameters that are defined in [secp256k1](https://en.bitcoin.it/wiki/Secp256k1): p,a,b,G,n,h. Read [this Slashdot thread](https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored) if you want to dive into a little bit of conspiracy theory.\n\n#### Prime number - p\n\nThe migthy prime number itself.\n\n``` ruby\nruby> p = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1\n => 115792089237316195423570985008687907853269984665640564039457584007908834671663\n```\n\n#### Elliptic Curve (EC) - a, b\n\nIn general elliptic curves are defined as `y^2 = x^3 + ax + b` equation but since `a = 0` and `b = 7` it becomes `y^2 = x^3 + 7` which is the elliptic curve used in Bitcoin.\n\n#### Generator point, order and cofactor - G, n and h\n\nThese 3 are all related and together they define a cyclic subgroup of elliptic curve where:\n\n  * `G` is a point on EC, also called the generator or base point, `(x,y)` coordinates represented in uncompressed format as a concatenation of `x` and `y` prefixed with `04` or in compressed format as `x` coordinate prefix with `02`.\n  * `n` is the order of subgroup generated by point `G`; in other words it is the number of points that belong to this subgroup\n  * `h` is called cofactor and can be calculated as `N/n` where `N` is the order of the entire elliptic curve group. In this case cofactor is 1 so the order of the subgroup is equal to the order of the entire elliptic curve.\n\n``` ruby\nruby> G = '0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8'\n => \"0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\"\nruby> Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\n => 55066263022277343669578718895168534326250603453777594175500187360389116729240\nruby> Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\n => 32670510020758816978083085130507043184471273380659243275938904335757337482424\nruby> n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\nruby> h = 1\n```\n\n### 0. Private key\n\nWe all know that Bitcoin's private key is 256 bits long that has to be an integer between `1` and `n`, the order of subgroup. Here is my take in binary representation.\n\n``` ruby\nruby> k = 0b1100011100001010010100111101101101010001100000111111101000010011010101001010011111000000100010100011100000001111001111100100011100111011101001110011111111001101001000111111000101100001000000011010111011011001010011010001000000110001100100001011100100101\n => 11253563012059685825953619222107823549092147699031672238385790369351542642469\nruby> k.to_s 16\n => \"18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725\"\n```\n\n### 1. Public key\n\nNow, public key is just a scalar multiplication of private key (k) and elliptic curve generator point (G) as `P = k * G`. The result is another point `(x, y)` on elliptic curve, we take that `x` coordinate, prefix it with `02` if `y` is positive or `03` if `y` is negative and there it is, the public key in compressed format.\n\nA little bit of math and a few [algorithms](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication) that we need to use for this calculation. For scalar multiplication you can add `G` to itself `k` number of times but this will be very inefficient so we are going to use \"double and add\" algorithm implemented in `ec_multiply` that in turn uses `ec_add` and `ec_double`, addition and doubling operations on elliptic curves. And last, since division is not defined over finite fields we need to multiply by the `multiplicative inverse` and use `extended_euclidean_algorithm` to find the greatest common divisor.\n\n```ruby\ndef ec_multiply(m, px, py, pn)\n  nx, ny = px, py\n  qx, qy = 0, 0\n  while m > 0\n    qx, qy = ec_add qx, qy, nx, ny, pn if m&1 == 1\n    nx, ny = ec_double nx, ny, pn\n    m >>= 1\n  end\n  [qx, qy]\nend\n\ndef ec_add(ax, ay, bx, by, pn)\n  return [ax, ay] if bx == 0 && by == 0\n  return [bx, by] if ax == 0 && ay == 0\n  return ec_double(ax, ay, pn) if ax == bx && ay == by\n\n  i_bax = inverse(ax - bx, pn)\n  slope = ((ay - by) * i_bax) % pn\n  x = (slope**2 - ax - bx) % pn\n  y = (slope*(ax - x) - ay) % pn\n  [x, y]\nend\n\ndef ec_double(px, py, pn)\n  i_2y = inverse(2 * py, pn)\n  slope = (3 * px**2 * i_2y) % pn\n  x = (slope**2 - 2 * px) % pn\n  y = (slope*(px - x) - py) % pn\n  [x, y]\nend\n\ndef inverse(n, p)\n  gcd, x, y = extended_euclidean_algorithm(n, p)\n  (n * x + p * y) % p == gcd || raise('invalid gcd')\n  gcd == 1 || raise('no multiplicative inverse')\n  x % p\nend\n\ndef extended_euclidean_algorithm(a, b)\n  s, old_s = 0, 1\n  t, old_t = 1, 0\n  r, old_r = b, a\n  while r != 0\n    quotient = old_r / r\n    old_r, r = r, old_r - quotient * r\n    old_s, s = s, old_s - quotient * s\n    old_t, t = t, old_t - quotient * t\n  end\n  [old_r, old_s, old_t]\nend\n```\n\n And here it is, point on elliptic curve and scalar multiplication.\n\n```ruby\nruby> Px, Py = ec_multiply(k, Gx, Gy, p)\n => [36422191471907241029883925342251831624200921388586025344128047678873736520530, 20277110887056303803699431755396003735040374760118964734768299847012543114150]\nruby> P = \"#{Py > 0 ? '02' : '03'}#{Px.to_s(16)}\"\n => \"0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352\"\n```\n\nWe can easily check if resulting point is still on elliptic curve.\n\n```ruby\n((Px**3 + 7 - Py**2) % p == 0) || raise('public key point is not on the curve')\n```\n\n### 2. SHA256 hashing\n\nStandard SHA256 hashing here, I am going to use the implementation provided in Ruby.\n\n``` ruby\nruby> require 'digest'\nruby> sha256 = Digest::SHA256.hexdigest([P].pack('H*'))\n => \"0b7c28c9b7290c98d7438e70b3d3f7c848fbd7d1dc194ff83f4f7cc9b1378e98\"\n```\n\n### 3. RIPEMD160 hashing\n\nSame here, nothing new, standard RIPEMD160 hashing, no point reinventing the wheel.\n\n``` ruby\nruby> ripemd160 = Digest::RMD160.hexdigest([sha256].pack('H*'))\n => \"f54a5851e9372b87810a8e60cdd2e7cfd80b6e31\"\n```\n\n### 4. Add version byte\n\nHere are a few but see [Bitcoin address prefixes](https://en.bitcoin.it/wiki/List_of_address_prefixes) for a complete list of all supported prefixes and resulting Base58 encodings:\n  * 0x00 - Bitcoin address - result prefix is 1\n  * 0x05 - Pay-to-Script-Hash address - result prefix is 3\n  * 0x6F - Testnet address - resulting prefix is either m or n\n\n``` ruby\nruby> with_version = \"00#{ripemd160}\"\n => \"00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31\"\n```\n\n### 5.6.7. Calculate checksum\n\nDouble SHA256 of previously calculated RIPEMD160 prefixed with version byte:\n\n``` ruby\nruby> checksum = Digest::SHA256.hexdigest(Digest::SHA256.digest([with_version].pack('H*')))[0, 8]\n => \"c7f18fe8\"\n```\n\n### 8. Wrap encoding\n\n``` ruby\nruby> wrap_encode = \"#{with_version}#{checksum}\"\n => \"00f54a5851e9372b87810a8e60cdd2e7cfd80b6e31c7f18fe8\"\n```\n\n### 9. Bitcoin address\n\nThe [Base58](https://en.bitcoin.it/wiki/Base58Check_encoding) algorithm removes confusing characters like \"oOiI\" and also \"+/\" signs to make entire address selectable on double click.\n\n```ruby\ndef base58(binary_hash)\n  alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'\n  value = binary_hash.unpack('H*')[0].to_i 16\n  output = ''\n  while value > 0\n    remainder = value % 58\n    value /= 58\n    output += alphabet[remainder]\n  end\n  output += alphabet[0] * binary_hash.bytes.find_index{|b| b != 0}\n  output.reverse\nend\n```\n\nBase58 encoding and the final Bitcoin address:\n\n``` ruby\nruby> base58([wrap_encode].pack('H*'))\n => \"1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\"\n```\n\n## B. The easy way\n\nAll the steps above can be done 'the easy way', as one-liner, using excellent [Libbitcoin Explorer](https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence) tool:\n\n```shell\nshell> echo 18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725 | bx ec-to-public | bx sha256 | bx ripemd160 | bx wrap-encode | bx base58-encode\n1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\n```\n\n## C. Conclusions\n\nAnd here we are, the exact same Bitcoin address used in [Bitcoin address generation](https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses) tutorial is generated the hard way and the easy way. You can [check the address](https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs).\n\n# References\n\n  * [Bitcoin address generation](https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses)\n  * [Elliptic curve point multiplication](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication)\n  * [Elliptic Curve Cryptography](http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/)\n  * [The Science Behind Cryptocurrencies Cryptography](https://blockgeeks.com/guides/cryptocurrencies-cryptography/)\n  * [Math behind Bitcoin](https://www.coindesk.com/math-behind-bitcoin/)",
      "json_metadata": "{\"tags\":[\"bitcoin\",\"cryptography\",\"elliptic-curve\",\"math\",\"crypto\"],\"links\":[\"https://gist.github.com/icostan/231b459f610e025d31e99b0bcbd8f90e\",\"https://en.bitcoin.it/wiki/Secp256k1\",\"https://it.slashdot.org/story/13/09/11/1224252/are-the-nist-standard-elliptic-curves-back-doored\",\"https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication\",\"https://en.bitcoin.it/wiki/List_of_address_prefixes\",\"https://en.bitcoin.it/wiki/Base58Check_encoding\",\"https://github.com/libbitcoin/libbitcoin-explorer/wiki/Command-Equivalence\",\"https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses\",\"https://www.blockchain.com/btc/address/1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\",\"http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/\",\"https://blockgeeks.com/guides/cryptocurrencies-cryptography/\",\"https://www.coindesk.com/math-behind-bitcoin/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "bitcoin",
      "permlink": "the-hard-way-bitcoin-private-key-public-key-address",
      "title": "The hard way - Bitcoin: private key, public key, address"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-10-09T10:45:00",
  "trx_id": "585e22ba0f45dbf220e41b7256edff595b37eaf4",
  "trx_in_block": 7,
  "virtual_op": 0
}
steemdelegated 5.622 SP to @icostan
2018/05/16 20:21:18
delegateeicostan
delegatorsteem
vesting shares9140.487806 VESTS
Transaction InfoBlock #22489927/Trx d04d8910bfc9ee4b5fc8d58de66cca0a929b47f8
View Raw JSON Data
{
  "block": 22489927,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "9140.487806 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-05-16T20:21:18",
  "trx_id": "d04d8910bfc9ee4b5fc8d58de66cca0a929b47f8",
  "trx_in_block": 8,
  "virtual_op": 0
}
steemdelegated 18.262 SP to @icostan
2018/01/09 06:39:33
delegateeicostan
delegatorsteem
vesting shares29691.478190 VESTS
Transaction InfoBlock #18819590/Trx 682d5d33dba2261e16345b5ec212023ee98e4731
View Raw JSON Data
{
  "block": 18819590,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "icostan",
      "delegator": "steem",
      "vesting_shares": "29691.478190 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-09T06:39:33",
  "trx_id": "682d5d33dba2261e16345b5ec212023ee98e4731",
  "trx_in_block": 13,
  "virtual_op": 0
}
2017/11/07 12:11:48
idfollow
json["follow",{"follower":"icostan","following":"chesatochi","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #17012931/Trx e65f2cd60068110afa1501f4985f7187bc8ee822
View Raw JSON Data
{
  "block": 17012931,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"chesatochi\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-11-07T12:11:48",
  "trx_id": "e65f2cd60068110afa1501f4985f7187bc8ee822",
  "trx_in_block": 17,
  "virtual_op": 0
}
icostanvoted for witness @jerrybanfield
2017/10/29 08:07:33
accounticostan
approvetrue
witnessjerrybanfield
Transaction InfoBlock #16748911/Trx fee0b7d41d055216b50ef2a0233287944dc837c0
View Raw JSON Data
{
  "block": 16748911,
  "op": [
    "account_witness_vote",
    {
      "account": "icostan",
      "approve": true,
      "witness": "jerrybanfield"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-10-29T08:07:33",
  "trx_id": "fee0b7d41d055216b50ef2a0233287944dc837c0",
  "trx_in_block": 16,
  "virtual_op": 0
}
icostanvoted for witness @good-karma
2017/10/29 08:07:15
accounticostan
approvetrue
witnessgood-karma
Transaction InfoBlock #16748905/Trx 582c5a87370f77091e413122402de47d24bf5206
View Raw JSON Data
{
  "block": 16748905,
  "op": [
    "account_witness_vote",
    {
      "account": "icostan",
      "approve": true,
      "witness": "good-karma"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-10-29T08:07:15",
  "trx_id": "582c5a87370f77091e413122402de47d24bf5206",
  "trx_in_block": 16,
  "virtual_op": 0
}
2017/10/29 08:05:30
idfollow
json["follow",{"follower":"icostan","following":"edwardthomson","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #16748870/Trx 06ae72d2c05ed6a4f7c257b63a5c94aa03d6a297
View Raw JSON Data
{
  "block": 16748870,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"edwardthomson\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-10-29T08:05:30",
  "trx_id": "06ae72d2c05ed6a4f7c257b63a5c94aa03d6a297",
  "trx_in_block": 2,
  "virtual_op": 0
}
2017/10/08 23:03:03
idfollow
json["follow",{"follower":"icostan","following":"wolfofpoloniex","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #16162737/Trx c2471d81bb900d57d1e6370437a33af79ecf0406
View Raw JSON Data
{
  "block": 16162737,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"wolfofpoloniex\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-10-08T23:03:03",
  "trx_id": "c2471d81bb900d57d1e6370437a33af79ecf0406",
  "trx_in_block": 14,
  "virtual_op": 0
}
icostanvoted for witness @furion
2017/10/07 11:18:33
accounticostan
approvetrue
witnessfurion
Transaction InfoBlock #16119850/Trx a7749d6cc015093cbae1d9742ef34fbfac10770c
View Raw JSON Data
{
  "block": 16119850,
  "op": [
    "account_witness_vote",
    {
      "account": "icostan",
      "approve": true,
      "witness": "furion"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-10-07T11:18:33",
  "trx_id": "a7749d6cc015093cbae1d9742ef34fbfac10770c",
  "trx_in_block": 21,
  "virtual_op": 0
}
2017/10/07 11:17:48
idfollow
json["follow",{"follower":"icostan","following":"furion","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #16119835/Trx a7b66acd589c7d04616a4183aea471832ee24936
View Raw JSON Data
{
  "block": 16119835,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"furion\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-10-07T11:17:48",
  "trx_id": "a7b66acd589c7d04616a4183aea471832ee24936",
  "trx_in_block": 13,
  "virtual_op": 0
}
2017/08/23 10:22:18
idfollow
json["follow",{"follower":"icostan","following":"chris83","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #14823432/Trx f001d6e1cfde1ce205470237ee34ea6d1e312c30
View Raw JSON Data
{
  "block": 14823432,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"chris83\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-08-23T10:22:18",
  "trx_id": "f001d6e1cfde1ce205470237ee34ea6d1e312c30",
  "trx_in_block": 10,
  "virtual_op": 0
}
2017/08/15 17:44:54
idfollow
json["follow",{"follower":"icostan","following":"jerrybanfield","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #14602042/Trx ceb36839af1d5a1d5831934cc06e293a3029e8d6
View Raw JSON Data
{
  "block": 14602042,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"jerrybanfield\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-08-15T17:44:54",
  "trx_id": "ceb36839af1d5a1d5831934cc06e293a3029e8d6",
  "trx_in_block": 6,
  "virtual_op": 0
}
2017/08/12 14:16:27
idfollow
json["follow",{"follower":"icostan","following":"thekyle","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #14512178/Trx c0ce410282bcd28a237389a9a75f62246a209a73
View Raw JSON Data
{
  "block": 14512178,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"thekyle\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-08-12T14:16:27",
  "trx_id": "c0ce410282bcd28a237389a9a75f62246a209a73",
  "trx_in_block": 1,
  "virtual_op": 0
}
icostanfollowed @dtube
2017/08/12 14:14:57
idfollow
json["follow",{"follower":"icostan","following":"dtube","what":["blog"]}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #14512148/Trx 839b08f54ecd15a65e9310a2820a1b821e841797
View Raw JSON Data
{
  "block": 14512148,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"icostan\",\"following\":\"dtube\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-08-12T14:14:57",
  "trx_id": "839b08f54ecd15a65e9310a2820a1b821e841797",
  "trx_in_block": 15,
  "virtual_op": 0
}
icostancustom json: follow
2017/08/12 14:11:21
idfollow
json["reblog",{"account":"icostan","author":"heimindanger","permlink":"introducing-dtube-a-decentralized-video-platform-using-steem-and-ipfs"}]
required auths[]
required posting auths["icostan"]
Transaction InfoBlock #14512076/Trx ad9fd22a53eebccbb983e7fcd0e57b98b3ca629f
View Raw JSON Data
{
  "block": 14512076,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"reblog\",{\"account\":\"icostan\",\"author\":\"heimindanger\",\"permlink\":\"introducing-dtube-a-decentralized-video-platform-using-steem-and-ipfs\"}]",
      "required_auths": [],
      "required_posting_auths": [
        "icostan"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-08-12T14:11:21",
  "trx_id": "ad9fd22a53eebccbb983e7fcd0e57b98b3ca629f",
  "trx_in_block": 4,
  "virtual_op": 0
}
2017/08/12 14:08:39
authorheimindanger
permlinkintroducing-dtube-a-decentralized-video-platform-using-steem-and-ipfs
votericostan
weight10000 (100.00%)
Transaction InfoBlock #14512022/Trx 566b53ea9e464ef630369d9d08997ae6c5db9d10
View Raw JSON Data
{
  "block": 14512022,
  "op": [
    "vote",
    {
      "author": "heimindanger",
      "permlink": "introducing-dtube-a-decentralized-video-platform-using-steem-and-ipfs",
      "voter": "icostan",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2017-08-12T14:08:39",
  "trx_id": "566b53ea9e464ef630369d9d08997ae6c5db9d10",
  "trx_in_block": 2,
  "virtual_op": 0
}

Account Metadata

POSTING JSON METADATA
profile{"name":"Iulian Costan","about":"Software developer, derivatives trader, crypto hodler.","website":"http://iuliancostan.com","location":"Romania","cover_image":"https://cdn.steemitimages.com/DQmRDebpsdxEV3eCyhwTw3yzSRVTmqU9nNP4WaxShFX3dmR/avatar-india.jpg","version":2}
JSON METADATA
profile{"name":"Iulian Costan","about":"Computer geek, derivatives trader, crypto hodler.","website":"http://iuliancostan.com","location":"Romania"}
{
  "posting_json_metadata": {
    "profile": {
      "name": "Iulian Costan",
      "about": "Software developer, derivatives trader, crypto hodler.",
      "website": "http://iuliancostan.com",
      "location": "Romania",
      "cover_image": "https://cdn.steemitimages.com/DQmRDebpsdxEV3eCyhwTw3yzSRVTmqU9nNP4WaxShFX3dmR/avatar-india.jpg",
      "version": 2
    }
  },
  "json_metadata": {
    "profile": {
      "name": "Iulian Costan",
      "about": "Computer geek, derivatives trader, crypto hodler.",
      "website": "http://iuliancostan.com",
      "location": "Romania"
    }
  }
}

Auth Keys

Owner
Single Signature
Public Keys
STM8khvozYSgQesA4HfUsz977WkPUnBJbUxoboqqkSdSURZcgowCq1/1
Active
Single Signature
Public Keys
STM7wXRVfSTGD8tos5uC444bf8FxeaZuXCmJjjSapRhEKBh2TbsQ31/1
Posting
Single Signature
Public Keys
STM6x1BPWfk5eFQg3cio62PoSkRYQCCzH99Eo3vXf68xVJSJ15zWB1/1
Memo
STM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa
{
  "owner": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM8khvozYSgQesA4HfUsz977WkPUnBJbUxoboqqkSdSURZcgowCq",
        1
      ]
    ]
  },
  "active": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM7wXRVfSTGD8tos5uC444bf8FxeaZuXCmJjjSapRhEKBh2TbsQ3",
        1
      ]
    ]
  },
  "posting": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM6x1BPWfk5eFQg3cio62PoSkRYQCCzH99Eo3vXf68xVJSJ15zWB",
        1
      ]
    ]
  },
  "memo": "STM6V2Sxgmf78xZgXczvitZXYQLZCq1ihi5xNCKej5KCiWoyWXQBa"
}

Witness Votes

4 / 30
[
  "furion",
  "good-karma",
  "jerrybanfield",
  "steemitboard"
]