JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

公鑰與私鑰:讓你證明身分的數學

私鑰只是一個巨大的祕密數字;公鑰則是把它推過一道沒人能逆向運算的陷門後得到的結果。本篇把那套橢圓曲線數學講清楚——就用 Bitcoin 與 Ethereum 實際採用的曲線——讓你在沒有任何銀行的情況下證明「你就是你」。

一把你可以隨手交給陌生人的鎖

想像你開了一間店,希望全世界任何人都能寄一個密封的箱子給你——包括你從未見過、也無法事先約定通關密語的陌生人。於是你做了一件聰明的事:大量生產上千把「開著的」掛鎖,到處撒。任何人都能撿一把、扣在箱子上、寄給你。但只有握著家裡那把唯一配對鑰匙的你,能把它打開。那把掛鎖是公開的——可以發給全世界;那把鑰匙是私密的——永遠不離身。

這種不對稱——人人都能拿來上鎖、卻只有你能開鎖的東西——正是公開金鑰密碼學的核心構想。在本階前面,你已認識了密碼雜湊這枚單向的指紋。公開金鑰密碼學再加上第二種、更豐富的單向數學:一在數學上彼此綁定的金鑰,你可以把其中一半公開給全世界,同時把另一半保密——而沒有人能從公開的那一半反推出私密的那一半。

區塊鏈為什麼需要它?因為鏈上沒有帳戶資料庫、沒有銀行替你背書,也沒有「忘記密碼」按鈕。你的金鑰對就是你的帳戶。這正是無信任性的密碼學根基:你用數學證明自己掌控某個帳戶,而不是靠任何人的許可。

兩把鑰匙,一條單行道

具體來說,你的加密錢包裡裝著兩個數字。私鑰只是一個巨大的祕密整數——把它想成介於 1 到大約 10⁷⁷ 之間的某個隨機數。公鑰則是依一條固定的數學規則、由私鑰計算出來。關鍵在於難度的方向性:正向走(私鑰 → 公鑰)又快又便宜,瞬間完成;逆向走(公鑰 → 私鑰)卻是——以目前全人類所知——在運算上不可能的,你得試的數字比可觀測宇宙裡的原子還多。

一個正向容易、逆向卻不可行的函數,叫做陷門函數(或單向函數)。雜湊也是單向的,但它會主動丟掉資訊,因此根本沒有反函數。金鑰對更微妙:公鑰在原理上確實唯一對應到一個私鑰——答案是唯一且確定的——但要找出那個答案,所需時間比宇宙的年齡還長。正因如此,你才能安心地把公鑰廣播出去。貼在看板上、刻在石頭上都行:你的祕密依然是祕密。

為什麼用橢圓曲線?

橢圓曲線密碼學(ECC)聽起來嚇人,但它本身很簡單:一條橢圓曲線不過是滿足 y² = x³ + ax + b 這類方程式的所有點 (x, y) 的集合。畫在實數上,它是一條平滑起伏的曲線。它的神奇之處在於:你可以把曲線上的兩個點「相加」,得到第三個也落在曲線上的點,靠的是一條乾淨的幾何規則——通過那兩點畫一條直線,找出這條線第三次與曲線相交的位置,再對 x 軸鏡射。那個鏡射後的點,就是它們的「和」。

現在取一個固定的起點 G,把它一次又一次地加到自己身上:G、2G、3G、……一路加到 kG。反覆把一個點加到自己身上,稱為純量乘法,而陷門就藏在這一句話裡。給定公開的起點 G 與一個祕密的次數 k,計算終點 P = k·G 很快;但只給定 G 和終點 P,要還原出次數 k——這個問題叫做橢圓曲線離散對數——卻被認為是不可行的。於是你已能看清那兩把鑰匙到底是什麼:

那個祕密的次數 k,就是你的私鑰;得到的點 P = k·G,就是你的公鑰。正向相乘,是你的錢包在百萬分之一秒內算出你的公鑰;那不可能的逆向,則是握有你公鑰的攻擊者盯著曲線,數不出回到你祕密的步數。

把純量乘法算給你看

你可能會合理地反問:如果 k 是個 256 位元的數字——約莫 10⁷⁷——錢包總不可能真的把 G 加到自己身上那麼多次吧?沒錯。它改用倍加法(double-and-add),跟快速冪是同一個捷徑。把 k 寫成二進位,再從左到右掃過每一位:每一位都把當前的點加倍,每當該位是 1,就再加上一個 G。一把 256 位元的金鑰只需約 256 次加倍加上少數幾次相加——是毫秒,而非永恆。

# Compute P = k * G on an elliptic curve, by double-and-add.
# k is read most-significant-bit first.
function scalar_mult(k, G):
    R = O                       # O = the "point at infinity", the identity
    for bit in bits_of(k):      # walk k's binary digits, MSB -> LSB
        R = point_double(R)     # R = 2 * R   (one geometric doubling)
        if bit == 1:
            R = point_add(R, G) # R = R + G   (one geometric addition)
    return R                    # R is now exactly k * G
倍加法把約 10⁷⁷ 次相加壓縮成約 256 步。point_double 與 point_add 就是上一節那套幾何規則。

我們親手追一個小例子,取 k = 13,其二進位為 1101。看四次加倍與三次相加如何把我們不多不少地送到 13·G:

  1. 從 R = O(單位元)開始,把 13 讀成由左到右的位元 1、1、0、1。
  2. 第 1 位:把 O 加倍(仍是 O),該位為 1,故加上 G → R = G(即 1·G)。
  3. 第 2 位:把 G 加倍成 2G,該位為 1,故加上 G → R = 3G。
  4. 第 3 位:把 3G 加倍成 6G,該位為 0,不加 → R = 6G。
  5. 第 4 位:把 6G 加倍成 12G,該位為 1,故加上 G → R = 13G。完成——四次加倍、三次相加,取代了十二次相加。

錢包究竟如何生出一對金鑰

現在來看實務上的步驟。當一個錢包要鑄出一個全新帳戶時,本質上只做三件事:

  1. 從安全來源蒐集 256 位元的真隨機(熵)——作業系統的密碼學安全亂數產生器,或專用的硬體雜訊。這是一切的源頭;此處的隨機性一旦薄弱便是致命的,稍後就會看到。
  2. 把那些位元解讀為整數 k,也就是你的私鑰,並檢查它落在合法範圍 1 ≤ k < n 內(n 是曲線的階)。那種天文數字般罕見的超出範圍值,直接被拒絕、重抽即可。
  3. 用上面的倍加純量乘法算出公鑰 P = k·G。就這樣:k 永遠保密,P 可以自由分享。

幾乎每一條主要的鏈——包括 Bitcoin 與 Ethereum——都在同一條特定曲線 secp256k1 上做這件事。它的方程式是 y² = x³ + 7(亦即 a = 0、b = 7),但不是在實數上計算,而是在一個對 256 位元質數 p 取模的有限整數體上。它固定了一個公開的生成點 G,以及一個階 n ≈ 1.158 × 10⁷⁷,那就是合法私鑰的總數。你的金鑰只是那個驚人總數裡的某一個——這正是為什麼兩個誠實的錢包永遠不會湊巧產生同一把金鑰。

secp256k1 domain parameters  (the curve Bitcoin & Ethereum sign with)

  equation : y^2 = x^3 + 7   (mod p)            # a = 0, b = 7
  p (field): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
             = 2^256 - 2^32 - 977
  G.x      : 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
  G.y      : 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
  n (order): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

  private key  k : a random integer in [1, n-1]
  public  key  P : the point  k * G   (an (x, y) pair; 65 bytes raw, 33 compressed)
secp256k1 真實且固定的常數。所有人共用同一條曲線、同一個 G;只有你的私鑰 k 才是你自己的。

那你看過錢包顯示的十二個英文單字又是怎麼回事?那是助記詞。比起存一把原始私鑰,現代的階層式確定性錢包會把單一一組人類可讀的助記詞轉成一個主種子,再由它確定性地衍生出一整棵金鑰對的「樹」。把那十二個字備份一次,就等於一次備份了所有帳戶。我們會在後面的階段拆解那套衍生機制;現在你只要記住一件事:助記詞就是你的那些私鑰,只是換上了更親切的外衣。

守住祕密:這套數學給了你什麼、又沒給你什麼

整套機制在實務上唯一會崩潰的地方,是糟糕的隨機性。如果錢包的熵是可預測的,攻擊者只要重新算出你的私鑰即可——曲線本身根本沒被碰到。這不是假設。2013 年,Android SecureRandom 的一個缺陷讓竊賊重算出 Bitcoin 私鑰、把受影響的錢包一掃而空。2023 年,「Milk Sad」漏洞揭露:熱門工具 Libbitcoin Explorer 竟用一個區區 32 位元的梅森旋轉演算法來產生金鑰種子,真實資金因此被盜走。每一次曲線運算都是健全的;薄弱的環節是餵給它的亂數產生器。

對於未來,有一句誠實的提醒。secp256k1 的安全性建立在「離散對數問題對古典電腦而言很難」之上。一台夠大的量子電腦執行 Shor 演算法,原則上能從公鑰還原出私鑰。如今並不存在任何接近所需規模的量子電腦,研究者也正積極設計後量子簽章方案——但這是一個貨真價實的長期考量,而非「可被證明永遠安全」的魔法。

退一步看看你現在握有什麼:一個只有你知道的祕密數字,與一個任何人都能看見的公開點,由一道無人能逆轉的陷門焊接在一起。接下來顯而易見的問題是——你究竟能拿它們什麼?下一篇裡,你會在同一條曲線上用私鑰、以 ECDSA 產生一段數位簽章,讓任何握有你公鑰的人都能驗證「這筆交易是你授權的」,而你的祕密一次都不必離開你的裝置。那,就是一筆交易證明「你就是你」的方式。