Skip to content

Instantly share code, notes, and snippets.

@onokatio
Last active February 28, 2018 07:54
Show Gist options
  • Save onokatio/e0c477637db9a3c482ed56013480f14a to your computer and use it in GitHub Desktop.
Save onokatio/e0c477637db9a3c482ed56013480f14a to your computer and use it in GitHub Desktop.
Bitcoinが楕円曲線暗号の公開鍵からアドレスを生成する流れをシェル芸だけで実装してみる ref: https://qiita.com/onokatio/items/d471a11e9894d01624df
p1="0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6"
p2=$(for i in `seq 1 2 129`;do echo $p1|cut -c$i-$((i+1));done|while read B;do printf "\x$B";done|sha256sum|cut -c-64)
p3=$(openssl rmd160 <(for i in `seq 1 2 63`;do echo $p2|cut -c$i-$((i+1));done|while read B;do printf "\x$B";done)|awk '{print $2}')
p4=$(echo 00$p3)
p5=$(for i in `seq 1 2 41`;do echo $p4|cut -c$i-$((i+1));done|while read B;do printf "\x$B";done|sha256sum|cut -c-64)
p6=$(for i in `seq 1 2 63`;do echo $p5|cut -c$i-$((i+1));done|while read B;do printf "\x$B";done|sha256sum|cut -c-64)
p7=$(echo $p6|cut -c-8)
p8=$(echo $p4$p7)
p91=$(echo "obase=10; ibase=16; $(echo $p8|tr 'abcdef' 'ABCDEF')"|bc)
ans=$p91 && p92=( $(while [[ "$ans" != "0" ]];do r=$(echo "$ans%58"|bc);ans=$(echo "$ans/58"|bc);echo $r;done|tac|tr '\n' ' ') )
i=0 && base58=(1 2 3 4 5 6 7 8 9 A B C D E F G H J K L M N P Q R S T U V W X Y Z a b c d e f g h i j k m n o p q r s t u v w x y z) && p93=$(for i in $p92;do echo $base58[(($i+1))];done|tr -d '\n')
num=$(( ($(echo $p8|sed -e 's/\(0*\).*/\1/'|wc -c)-1) / 2 )) && p94=$(echo $(yes 1|head -n$num|tr -d '\n')$p93)
echo $p94
0. 楕円曲線署名の秘密鍵を取得
1. 0x04,座標のx,yから公開鍵を取得
2. SHA256する
3. RIPEMD-160する
4. 先頭にアドレスプレフィックスを付ける
# ここで一旦止めて、5からはチェックサムを作っていきます。
5. 4をSHA256
6. 5をSHA256
7. 6の先頭4バイトを取る
8. 7を4の末尾に追加する。
9. 8をbase58check encodeする。
# 完成!
$ p1="0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6"
$ ans=$p91 && p92=( $(while [[ "$ans" != "0" ]];do r=$(echo "$ans%58"|bc);ans=$(echo "$ans/58"|bc);echo $r;done|tac|tr '\n' ' ') )
$ echo $p92
5 27 54 19 19 8 24 41 50 35 2 23 38 22 48 10 27 53 18 46 38 16 44 10 23 6 54 20 51 42 53 20
$ i=0 && base58=(1 2 3 4 5 6 7 8 9 A B C D E F G H J K L M N P Q R S T U V W X Y Z a b c d e f g h i j k m n o p q r s t u v w x y z) && p93=$(for i in $p92;do echo $base58[(($i+1))];done|tr -d '\n')
$ echo $p93
6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
$ num=$(( ($(echo $p8|sed -e 's/\(0*\).*/\1/'|wc -c)-1) / 2 )) && p94=$(echo $(yes 1|head -n$num|tr -d '\n')$p93)
$ echo $p94
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
$ p2=$(for i in `seq 1 2 129`;do echo $p1|cut -c$i-$((i+1));done|while read B;do printf "\x$B";done|sha256sum|cut -c-64)
$ echo $p2
600ffe422b4e00731a59557a5cca46cc183944191006324a447bdb2d98d4b408
$ p3=$(openssl rmd160 <(for i in `seq 1 2 63`;do echo $p2|cut -c$i-$((i+1));done|while read B;do printf "\x$B";done)|awk '{print $2}')
$ echo $p3
010966776006953d5567439e5e39f86a0d273bee
$ p4=$(echo 00$p3)
$ echo $p4
00010966776006953d5567439e5e39f86a0d273bee
$ p5=$(for i in `seq 1 2 41`;do echo $p4|cut -c$i-$((i+1));done|while read B;do printf "\x$B";done|sha256sum|cut -c-64)
$ echo $p5
445c7a8007a93d8733188288bb320a8fe2debd2ae1b47f0f50bc10bae845c094
$ p6=$(for i in `seq 1 2 63`;do echo $p5|cut -c$i-$((i+1));done|while read B;do printf "\x$B";done|sha256sum|cut -c-64)
$ echo $p6
d61967f63c7dd183914a4ae452c9f6ad5d462ce3d277798075b107615c1a8a30
$ p7=$(echo $p6|cut -c-8)
$ echo $p7
d61967f6
$ p8=$(echo $p4$p7)
$ echo $8
00010966776006953d5567439e5e39f86a0d273beed61967f6
$ p91=$(echo "obase=10; ibase=16; $(echo $p8|tr 'abcdef' 'ABCDEF')"|bc)
$ echo $p91
25420294593250030202636073700053352635053786165627414518
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment