Kode di dalam artikel ini hanya untuk belajar — jangan memakai private key contoh untuk menyimpan dana sungguhan.
Di Bitcoin, kepemilikan sebuah koin pada dasarnya hanyalah pengetahuan atas sebuah angka rahasia. Angka itu disebut private key. Dari private key inilah diturunkan public key, lalu alamat (address) yang kita bagikan untuk menerima transfer.
Yang menarik, hubungan ini bersifat satu arah: dari private key sangat mudah menghitung public key, tetapi dari public key secara praktis mustahil kembali ke private key. Sifat inilah yang menjaga uang kita. Mari kita bedah bagaimana tepatnya proses itu terjadi.
1. Private key hanyalah sebuah angka
Private key Bitcoin adalah bilangan bulat acak sepanjang 256 bit. Besarnya kira-kira antara 1 sampai sedikit di bawah angka yang disebut order kurva (kita lambangkan n):
Karena 256 bit, jumlah kemungkinannya sekitar — angka yang begitu besar sehingga menebaknya dengan cara mencoba satu per satu mustahil dilakukan oleh komputer mana pun yang ada maupun yang terbayangkan.
Bitcoin tidak memakai sembarang matematika. Ia memakai sebuah kurva eliptik bernama secp256k1, yaitu himpunan semua titik (x, y) yang memenuhi persamaan berikut, dihitung modulo sebuah bilangan prima raksasa p:
Beberapa angka tetap (parameter) yang mendefinisikan kurva ini:
p — bilangan prima besar, menentukan “ukuran lapangan” tempat semua hitungan dilakukan.
G — sebuah titik istimewa yang disebut generator point. Ia adalah titik awal yang disepakati semua orang.
n — order dari G, yaitu banyaknya titik berbeda yang bisa dihasilkan dari G.
# Parameter resmi kurva secp256k1
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
a = 0
b = 7
Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
G = (Gx, Gy)
3. Operasi inti: perkalian titik
Public key dihitung dengan satu rumus yang sangat ringkas:
Di sini k adalah private key (sebuah angka), G adalah generator point, dan K adalah public key — yang ternyata juga sebuah titik(x, y) di atas kurva.
Tapi hati-hati: k × Gbukan perkalian biasa. Yang dimaksud adalah menjumlahkan titik G dengan dirinya sendiri sebanyak k kali, memakai aturan penjumlahan khusus pada kurva eliptik:
Penjumlahan titik di kurva eliptik punya aturan geometris tersendiri. Secara aljabar, untuk menjumlahkan dua titik kita menghitung kemiringan garis m yang menghubungkannya, lalu memakainya untuk mencari titik hasil. Semua pembagian dilakukan dengan invers modular terhadap p (bukan pembagian desimal biasa).
Dari private key k, kalikan dengan titik G untuk mendapat public key K, lalu hash untuk mendapat address. Arah majunya mudah; arah baliknya praktis mustahil.
4. Mengapa ini satu arah?
Menghitung maju (k → K) itu cepat, karena kita tidak benar-benar menjumlahkan sebanyak k kali. Ada trik double-and-add yang membuatnya hanya butuh sekitar 256 langkah, bukan langkah.
Tetapi arah sebaliknya — diberi K, cari k — adalah persoalan yang dikenal sebagai Elliptic Curve Discrete Logarithm Problem (ECDLP). Tidak ada algoritma efisien yang diketahui untuk memecahkannya. Inilah fondasi keamanan Bitcoin: public key boleh dilihat siapa saja, tapi private key di baliknya tetap aman.
5. Membuat public key dari nol dengan Python
Mari kita buktikan semuanya dengan kode. Berikut implementasi penjumlahan titik dan perkalian skalar di secp256k1 memakai bilangan bulat Python biasa:
definverse_mod(k, m):
# Invers modular: pow dengan eksponen -1 (Python 3.8+)returnpow(k, -1, m)
defpoint_add(P, Q):
# Penjumlahan dua titik pada kurva. None = titik tak hingga (identitas).if P isNone:
return Q
if Q isNone:
return P
(x1, y1), (x2, y2) = P, Q
if x1 == x2 and (y1 + y2) % p == 0:
returnNone# P + (-P) = tak hinggaif P == Q:
# penggandaan titik (doubling)
m = (3 * x1 * x1 + a) * inverse_mod(2 * y1, p) % p
else:
m = (y2 - y1) * inverse_mod(x2 - x1, p) % p
x3 = (m * m - x1 - x2) % p
y3 = (m * (x1 - x3) - y1) % p
return (x3, y3)
defscalar_mult(k, P):
# Hitung k * P dengan metode double-and-add
R = None# mulai dari titik tak hinggawhile k:
if k & 1:
R = point_add(R, P)
P = point_add(P, P)
k >>= 1return R
private_key = 0x1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
public_key = scalar_mult(private_key, G)
print("x:", hex(public_key[0]))
print("y:", hex(public_key[1]))
Dua angka x dan y itulah public key kita — sebuah titik di atas kurva secp256k1.
6. Format public key: uncompressed vs compressed
Satu titik (x, y) bisa dikemas menjadi deretan byte dengan dua cara:
Uncompressed — awalan 0x04 diikuti x (32 byte) lalu y (32 byte), total 65 byte.
Compressed — karena y bisa dihitung ulang dari x, kita cukup menyimpan x dan satu petunjuk apakah y genap atau ganjil. Awalannya 0x02 (bila y genap) atau 0x03 (bila y ganjil), diikuti x saja, total 33 byte.
defpublic_key_compressed(pub):
x, y = pub
prefix = b"\x02"if y % 2 == 0elseb"\x03"return prefix + x.to_bytes(32, "big")
print(public_key_compressed(public_key).hex())
# 03f028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f159c2e2fff579dc341a
Format compressed-lah yang dipakai hampir di semua dompet modern karena lebih hemat tempat.
7. Dari public key ke alamat
Public key belum sama dengan address yang biasa kita tempel saat menerima Bitcoin. Alamat diturunkan satu langkah lagi dengan proses hashing:
Hasilnya kemudian dibungkus (dengan Base58Check atau Bech32) menjadi alamat yang kita kenal. Tapi itu cerita untuk artikel lain — inti yang penting di sini adalah tahap k × G.
Penutup
Seluruh keamanan kepemilikan Bitcoin berpijak pada satu operasi matematika yang elegan:
Mudah dihitung maju, berkat trik double-and-add.
Praktis mustahil dibalik, karena ECDLP.
Jadi “membuat public key” sesungguhnya hanyalah menjumlahkan satu titik tetap G dengan dirinya sendiri sebanyak nilai private key — sebuah perhitungan yang bisa kita lakukan sendiri hanya dengan beberapa baris Python, persis seperti yang dilakukan dompet Anda setiap hari.