Flavio Sousa / Mar 23 2023
Mastering Bitcoin chapter 4 - 05 private key to bitcoin address
{:deps {org.clojure/clojure {:mvn/version "1.11.1"} base58 {:git/url "https://github.com/fjsousa/base58" :sha "807fba7f9f38175531be81c4f4c4a682fc380433"} buddy/buddy-core {:mvn/version "1.10.413"} org.bouncycastle/bcprov-jdk15on {:mvn/version "1.70"} ;; complient is used for autocompletion ;; add your libs here (and restart the runtime to pick up changes) compliment/compliment {:mvn/version "0.3.9"}}}Extensible Data Notation
(ns play-with-points (:require [buddy.core.hash :as hash] [buddy.core.codecs :as codecs] [base58.core :as base58]) (:import java.math.BigInteger java.security.SecureRandom [org.bouncycastle.jce ECNamedCurveTable]))0.1s
Based on this python script example from Mastering Bitcoin.
1 - 256 random int is the private key
;; (def random (SecureRandom.));; (def private-key (BigInteger/probablePrime 256 random));; Using the reference integer from Mastering Bitcoin to ;; verify that we didn't mess things allong the way.(def private-key (BigInteger. "26563230048437957592232553826663696440606756685920117476832299673293013768870"))0.0s
2. Private key as hex
(def private-key-hex (-> private-key (.toString 16)))0.0s
3. Private key WIF

(def version-hex "80")(def checksum-bytes (->> (str version-hex private-key-hex) codecs/hex->bytes hash/sha256 hash/sha256 (take 4)))(def private-key-wif (base58/encode (concat (codecs/hex->bytes version-hex) (codecs/hex->bytes private-key-hex) checksum-bytes)))0.0s
4. Private key Compressed WIF
;; hex of a "compressed" private key - appending 01 to the Hex of the private key above;; "The term "compressed private key" really means "private key from which only compressed ;; public keys should be derived";; "version prefix is the same (0x80) for both WIF and WIF-compressed formats"(def version-hex "80")(def suffix-hex "01")(def private-key-compressed-hex (str private-key-hex suffix-hex))0.0s
(def checksum-bytes (->> (str version-hex private-key-compressed-hex) codecs/hex->bytes hash/sha256 hash/sha256 (take 4)))(def private-key-wif (base58/encode (concat (codecs/hex->bytes (str version-hex private-key-hex suffix-hex)) checksum-bytes)))0.0s
5. Public key compressed
(def spec (ECNamedCurveTable/getParameterSpec "secp256k1"))(def G (.getG spec))(def P (.normalize (.multiply G private-key)))(def x (str (.getRawXCoord P)))(def y (str (.getRawYCoord P)))(def public-key (str "04" (format "%064X" (BigInteger. x 16)) (format "%064X" (BigInteger. y 16))))0.3s
6. Public key compressed hex
(def compressed-public-key-hex (str (if (even? (BigInteger. y 16)) "02" "03") x))0.0s
7. Bitcoin Address

(def public-key-hash (->> public-key codecs/hex->bytes hash/sha256 hash/ripemd160 codecs/bytes->hex))(def version-hex "00");;base 58check encode(def checksum-bytes (->> (str version-hex public-key-hash) codecs/hex->bytes hash/sha256 hash/sha256 (take 4)))(def bitcoin-address (base58/encode (concat (codecs/hex->bytes version-hex) (codecs/hex->bytes public-key-hash) checksum-bytes)))0.0s
8. Compressed bitcoin address
(def public-key-hash (->> compressed-publick-key-hex codecs/hex->bytes hash/sha256 hash/ripemd160 codecs/bytes->hex))(def version-hex "00")(def checksum-bytes (->> (str version-hex public-key-hash) codecs/hex->bytes hash/sha256 hash/sha256 (take 4)))(def bitcoin-address (base58/encode (concat (codecs/hex->bytes version-hex) (codecs/hex->bytes public-key-hash) checksum-bytes)))0.0s