Skip to content

Commit

Permalink
use xxd for pack/unpack
Browse files Browse the repository at this point in the history
  • Loading branch information
grondilu committed Feb 19, 2018
1 parent 0b055bb commit 4ace422
Showing 1 changed file with 66 additions and 54 deletions.
120 changes: 66 additions & 54 deletions bitcoin.sh
Expand Up @@ -8,19 +8,19 @@
#
# This script uses GNU tools. It is therefore not guaranted to work on a POSIX
# system.
#
#
# Copyright (C) 2013 Lucien Grondin (grondilu@yahoo.fr)
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -29,13 +29,22 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


if ((BASH_VERSINFO[0] < 4))
then
echo "This script requires bash version 4 or above." >&2
exit 1
fi

pack() {
echo -n "$1" |
xxd -r -p
}
unpack() {
local line
xxd -p |
while read line; do echo -n ${line/\\/}; done
}

declare -a 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
Expand All @@ -58,21 +67,24 @@ dSLxs#LPs#LQs#]sM[lpd1+4/r|]sR
';

decodeBase58() {
local line
echo -n "$1" | sed -e's/^\(1*\).*/\1/' -e's/1/00/g' | tr -d '\n'
dc -e "$dcr 16o0$(sed 's/./ 58*l&+/g' <<<$1)p" |
while read n; do echo -n ${n/\\/}; done
while read line; do echo -n ${line/\\/}; done
}
encodeBase58() {
local n
echo -n "$1" | sed -e's/^\(\(00\)*\).*/\1/' -e's/00/1/g' | tr -d '\n'
dc -e "16i ${1^^} [3A ~r d0<x]dsxx +f" |
while read -r n; do echo -n "${base58[n]}"; done
}

checksum() {
perl -we "print pack 'H*', '$1'" |
pack "$1" |
openssl dgst -sha256 -binary |
openssl dgst -sha256 -binary |
perl -we "print unpack 'H8', join '', <>"
unpack |
head -c 8
}

checkBitcoinAddress() {
Expand All @@ -87,7 +99,7 @@ checkBitcoinAddress() {
hash160() {
openssl dgst -sha256 -binary |
openssl dgst -rmd160 -binary |
perl -we "print unpack 'H*', join '', <>"
unpack
}

hexToAddress() {
Expand All @@ -99,69 +111,69 @@ hexToAddress() {
newBitcoinKey() {
if [[ "$1" =~ ^[5KL] ]] && checkBitcoinAddress "$1"
then
local decoded="$(decodeBase58 "$1")"
if [[ "$decoded" =~ ^80([0-9A-F]{64})(01)?[0-9A-F]{8}$ ]]
then $FUNCNAME "0x${BASH_REMATCH[1]}"
fi
local decoded="$(decodeBase58 "$1")"
if [[ "$decoded" =~ ^80([0-9A-F]{64})(01)?[0-9A-F]{8}$ ]]
then $FUNCNAME "0x${BASH_REMATCH[1]}"
fi
elif [[ "$1" =~ ^[0-9]+$ ]]
then $FUNCNAME "0x$(dc -e "16o$1p")"
elif [[ "${1^^}" =~ ^0X([0-9A-F]{1,64})$ ]]
then
local exponent="${BASH_REMATCH[1]}"
local uncompressed_wif="$(hexToAddress "$exponent" 80 64)"
local compressed_wif="$(hexToAddress "${exponent}01" 80 66)"
dc -e "$ec_dc lG I16i${exponent^^}ri lMx 16olm~ n[ ]nn" |
{
read y x
X="$(printf "%64s" $x| sed 's/ /0/g')"
Y="$(printf "%64s" $y| sed 's/ /0/g')"
if [[ "$y" =~ [02468ACE]$ ]]
then y_parity="02"
else y_parity="03"
fi
uncompressed_addr="$(hexToAddress "$(perl -e "print pack q(H*), q(04$X$Y)" | hash160)")"
compressed_addr="$(hexToAddress "$(perl -e "print pack q(H*), q($y_parity$X)" | hash160)")"
echo ---
then
local exponent="${BASH_REMATCH[1]}"
local uncompressed_wif="$(hexToAddress "$exponent" 80 64)"
local compressed_wif="$(hexToAddress "${exponent}01" 80 66)"
dc -e "$ec_dc lG I16i${exponent^^}ri lMx 16olm~ n[ ]nn" |
{
read y x
X="$(printf "%64s" $x| sed 's/ /0/g')"
Y="$(printf "%64s" $y| sed 's/ /0/g')"
if [[ "$y" =~ [02468ACE]$ ]]
then y_parity="02"
else y_parity="03"
fi
uncompressed_addr="$(hexToAddress "$(pack "04$X$Y" | hash160)")"
compressed_addr="$(hexToAddress "$(pack "$y_parity$X" | hash160)")"
echo ---
echo "secret exponent: 0x$exponent"
echo "public key:"
echo " X: $X"
echo " Y: $Y"
echo "public key:"
echo " X: $X"
echo " Y: $Y"
echo "compressed:"
echo " WIF: $compressed_wif"
echo " bitcoin address: $compressed_addr"
echo "uncompressed:"
echo " WIF: $uncompressed_wif"
echo " bitcoin address: $uncompressed_addr"
}
}
elif test -z "$1"
then $FUNCNAME "0x$(openssl rand -rand <(date +%s%N; ps -ef) -hex 32 2>&-)"
else
echo unknown key format "$1" >&2
return 2
echo unknown key format "$1" >&2
return 2
fi
}

vanityAddressFromPublicPoint() {
if [[ "$1" =~ ^04([0-9A-F]{64})([0-9A-F]{64})$ ]]
then
dc <<<"$ec_dc 16o
0 ${BASH_REMATCH[1]} ${BASH_REMATCH[2]} rlp*+
[lGlAxdlm~rn[ ]nn[ ]nr1+prlLx]dsLx
" |
while read -r x y n
do
local public_key="$(printf "04%64s%64s" $x $y | sed 's/ /0/g')"
local h="$(perl -e "print pack q(H*), q($public_key)" | hash160)"
local addr="$(hexToAddress "$h")"
if [[ "$addr" =~ "$2" ]]
then
echo "FOUND! $n: $addr"
return
else echo "$n: $addr"
fi
done
else
echo unexpected format for public point >&2
return 1
dc <<<"$ec_dc 16o
0 ${BASH_REMATCH[1]} ${BASH_REMATCH[2]} rlp*+
[lGlAxdlm~rn[ ]nn[ ]nr1+prlLx]dsLx
" |
while read -r x y n
do
local public_key="$(printf "04%64s%64s" $x $y | sed 's/ /0/g')"
local h="$(pack "$public_key" | hash160)"
local addr="$(hexToAddress "$h")"
if [[ "$addr" =~ "$2" ]]
then
echo "FOUND! $n: $addr"
return
else echo "$n: $addr"
fi
done
else
echo unexpected format for public point >&2
return 1
fi
}

0 comments on commit 4ace422

Please sign in to comment.