@@ -72,6 +72,7 @@ decodeBase58() {
7272 dc -e " $dcr 16o0$( sed ' s/./ 58*l&+/g' <<< $1 ) p" |
7373 while read line; do echo -n ${line/ \\ / } ; done
7474}
75+
7576encodeBase58 () {
7677 local n
7778 echo -n " $1 " | sed -e' s/^\(\(00\)*\).*/\1/' -e' s/00/1/g' | tr -d ' \n'
@@ -87,6 +88,20 @@ checksum() {
8788 head -c 8
8889}
8990
91+ toEthereumAddressWithChecksum () {
92+ local addrLower=$( sed -r -e ' s/[[:upper:]]/\l&/g' <<< " $1" )
93+ local addrHash=$( echo -n " $addrLower " | sha3-256 | xxd -p -c32)
94+ local addrChecksum=" "
95+ local i c x
96+ for i in {0..39}; do
97+ c=${addrLower: i: 1}
98+ x=${addrHash: i: 1}
99+ [[ $c =~ [a-f] ]] && [[ $x =~ [89a-f] ]] && c=${c^^}
100+ addrChecksum+=$c
101+ done
102+ echo -n $addrChecksum
103+ }
104+
90105checkBitcoinAddress () {
91106 if [[ " $1 " =~ ^[$( IFS= ; echo " ${base58[*]} " ) ]+$ ]]
92107 then
@@ -102,6 +117,16 @@ hash160() {
102117 unpack
103118}
104119
120+ sha3-256 () {
121+ python3 -c "
122+ import sys
123+ from Crypto.Hash import keccak
124+ data = sys.stdin.buffer.read()
125+ hash = keccak.new(digest_bits=256).update(data)
126+ sys.stdout.buffer.write(hash.digest())
127+ "
128+ }
129+
105130hexToAddress () {
106131 local x=" $( printf " %2s%${3:- 40} s" ${2:- 00} $1 | sed ' s/ /0/g' ) "
107132 encodeBase58 " $x $( checksum " $x " ) "
@@ -117,33 +142,54 @@ newBitcoinKey() {
117142 fi
118143 elif [[ " $1 " =~ ^[0-9]+$ ]]
119144 then $FUNCNAME " 0x$( dc -e " 16o$1 p" ) "
120- elif [[ " ${1^^} " =~ ^0X([0-9A-F]{1,64 })$ ]]
145+ elif [[ " ${1^^} " =~ ^0X([0-9A-F]{1,})$ ]]
121146 then
122147 local exponent=" ${BASH_REMATCH[1]} "
123- local uncompressed_wif =" $( hexToAddress " $exponent " 80 64) "
124- local compressed_wif =" $( hexToAddress " ${exponent} 01" 80 66) "
148+ local full_wif =" $( hexToAddress " $exponent " 80 64) "
149+ local comp_wif =" $( hexToAddress " ${exponent} 01" 80 66) "
125150 dc -e " $ec_dc lG I16i${exponent^^} ri lMx 16olm~ n[ ]nn" |
126151 {
127152 read y x
128- X=" $( printf " %64s" $x | sed ' s/ /0/g' ) "
129- Y=" $( printf " %64s" $y | sed ' s/ /0/g' ) "
130- if [[ " $y " =~ [02468ACE]$ ]]
131- then y_parity=" 02"
132- else y_parity=" 03"
133- fi
134- uncompressed_addr=" $( hexToAddress " $( pack " 04$X$Y " | hash160) " ) "
135- compressed_addr=" $( hexToAddress " $( pack " $y_parity$X " | hash160) " ) "
153+ X=" $( printf " %64s" $x | sed ' s/ /0/g' ) "
154+ Y=" $( printf " %64s" $y | sed ' s/ /0/g' ) "
155+ [[ " $y " =~ [02468ACE]$ ]] && y_parity=" 02" || y_parity=" 03"
156+ full_pubkey=" 04${X}${Y} "
157+ comp_pubkey=" ${y_parity}${X} "
158+ full_p2pkh_addr=" $( hexToAddress " $( pack " $full_pubkey " | hash160) " ) "
159+ comp_p2pkh_addr=" $( hexToAddress " $( pack " $comp_pubkey " | hash160) " ) "
160+ full_p2sh_addr=" $( hexToAddress " $( pack " 41${full_pubkey} AC" | hash160) " 05) "
161+ comp_p2sh_addr=" $( hexToAddress " $( pack " 21${comp_pubkey} AC" | hash160) " 05) "
162+ # Note: Witness uses only compressed public key
163+ comp_p2wpkh_addr=" $( hexToAddress " $( pack " 0014$( pack " $comp_pubkey " | hash160) " | hash160) " 05) "
164+ full_multisig_1_of_1_addr=" $( hexToAddress " $( pack " 5141${full_pubkey} 51AE" | hash160) " 05) "
165+ comp_multisig_1_of_1_addr=" $( hexToAddress " $( pack " 5121${comp_pubkey} 51AE" | hash160) " 05) "
166+ qtum_addr=" $( hexToAddress " $( pack " ${comp_pubkey} " | hash160) " 3a) "
167+ ethereum_addr=" $( pack " $X$Y " | sha3-256 | unpack | tail -c 40) "
168+ tron_addr=" $( hexToAddress " $ethereum_addr " 41) "
136169 echo ---
137170 echo " secret exponent: 0x$exponent "
138171 echo " public key:"
139172 echo " X: $X "
140173 echo " Y: $Y "
141- echo " compressed:"
142- echo " WIF: $compressed_wif "
143- echo " bitcoin address: $compressed_addr "
144- echo " uncompressed:"
145- echo " WIF: $uncompressed_wif "
146- echo " bitcoin address: $uncompressed_addr "
174+ echo
175+ echo " compressed addresses:"
176+ echo " WIF: $comp_wif "
177+ echo " Bitcoin (P2PKH): $comp_p2pkh_addr "
178+ echo " Bitcoin (P2SH [PKH]): $comp_p2sh_addr "
179+ echo " Bitcoin (P2WPKH): $comp_p2wpkh_addr "
180+ echo " Bitcoin (1-of-1): $comp_multisig_1_of_1_addr "
181+ echo " ---- other networks ----"
182+ echo " Qtum: $qtum_addr "
183+ echo
184+ echo " uncompressed addresses:"
185+ echo " WIF: $full_wif "
186+ echo " Bitcoin (P2PKH): $full_p2pkh_addr "
187+ echo " Bitcoin (P2SH [PKH]): $full_p2sh_addr "
188+ echo " Bitcoin (1-of-1): $full_multisig_1_of_1_addr "
189+ echo " ---- other networks ----"
190+ echo " Ethereum: 0x$( toEthereumAddressWithChecksum $ethereum_addr ) "
191+ echo " Tron: $tron_addr "
192+ echo
147193 }
148194 elif test -z " $1 "
149195 then $FUNCNAME " 0x$( openssl rand -rand <( date +%s%N; ps -ef) -hex 32 2>& -) "
0 commit comments