Cryptography
====
這個文件將整理流行的加密演算法與其背後的數學。
[TOC]
密碼學概念
--------
### 對稱與非對稱式加密
這兩者的差別在於:加密時使用的key相不相同。想像使用對稱式密碼,對於多組伺服器你必須有多組不同的密碼,這使得管理上非常困難。並且,若是伺服器被入侵密鑰被取得,攻擊者能夠輕易解開儲存的密文。非對稱式為較晚發展的加密方式,加密用的叫做公鑰(public key),解密用的是私鑰(private key)。可以把公鑰想成一把鎖,私鑰是這把鎖對應的鑰匙:任何人都可以很容易地把文件上鎖,但是只有握有鑰匙的人可以打開。
### 同態加密(Homomorphic Encryption)
與數學上的同態意思相同,即下列等式為真
$$ dec(enc(m1) \oplus enc(m2)) = m1 \diamond m2 $$
這是近年來又活熱的研究主題,開始漸漸有科學家提出新加密方式支援部分的運算子做同態運算,一直到2009年的Craig Gentry才提出完整的同態加密方式。
RSA
--------
這節將介紹RSA,一種非對稱式加密法。最早由英國數學家Clifford Cocks發明並被列為機密存入文檔案直到1997年才被公布。在此之前的1977年早被Ron Rivest, Adi Shamir和Leonard Adleman一起提出,因此被稱為世人熟知的RSA。
### 產生公私鑰
1. 選出兩組差不多大的質數$p$和$q$,$n=pq$。
2. $\phi(n)=(p-1)*(q-1)$。
3. 任選一個與 $\phi(n)$ 互質的 public exponent $e$
4. 計算$d$其中$ed\equiv 1\mod \phi(n)$
第3,4步驟可調換,d也可以先產生再算e。
以上:
公鑰:$(n, e)$
私鑰:$(\phi(n), d)$
產生key的簡單實作可以參考
https://github.com/iphkwan/SimpleRSA/blob/master/src/Key.cpp
更有效率的方法請參考下面的求模反函數小節
### 加密與解密
1. 由明文m計算密文c:$m^e \equiv c \mod{n}$
2. 由密文c計算明文m:$c^d \equiv m \mod{n}$
### RSA背後的數學
數學家試著想出一個容易計算但難以回頭的數學式,除非握有Trapdoor。
$$ m^e \equiv c \mod{n} $$
上列式子意思為$m$取$e$次方取$n$的餘數為$c$。其中$m$為明文message,$c$為密文ciphertext,$0<=m<n$。
從c推回m很困難,假設存在一個數字d,使得m得以還原
$$ c^d \equiv m \mod{n}$$
這個式子也可以寫成這樣
$$ m^{ed} \equiv m \mod{n}$$
問題是,如何將$d$算出來,正整數d存在嗎?
#### Euler's Totient Function
$\phi(N)$定義為:所有小於等於N的正整數與N互質的數目。比如$\phi(8)=4$因為1,3,5,7與8互質。
這函數兩個特性我們將用到:
1. 當N為質數的時候,$\phi(N)$很容易計算即為$N-1$。
2. 並且AB互質時,$\phi(A*B)=\phi(A)\phi(B)$
因此若知道一個數的質因數分解,就能把函數值算出來。然而RSA所使用的N為兩個大質數相乘,要知道其分解並不容易,但有$p$和$q$時,計算$\phi(N)$並非難事,即為$(p-1)(q-1)$。
#### Euler's Theorem
Euler's Theorem告訴我們,當$\alpha$與$n$互質時,以下成立
$$ \alpha^{\phi(n)} \equiv 1 \mod{n} $$
這裡將$\alpha$替換成明文$m$,左側再取$k$次方($k>=0$),得到以下
$$ m^{k\phi(n)} \equiv 1^k \mod{n} \equiv 1 \mod n $$
將兩側同時乘上m
$$ m^{k\phi(n)+1} \equiv m \mod{n} $$
也就是說m的$k\phi(n)+1$次方取餘數還是m。與前面小節式聯立:
$$ k\phi(n)+1=ed $$
若有$\phi(n)$值d得以計算
$$ d = \frac{k\phi(n)+1}{e}$$
這個式子可以被看成
$$ ed \equiv 1 \mod{\phi(n)}$$
也就是e與d互為模反元素
#### 模反元素
若說$a$與$b$互為模反元素,則
$$ ab \equiv 1 \mod{n} $$
a的模反元素可寫成$a^{-1}$
模反元素有不只一個,可以用$a^{-1}+kn$列舉
Paillier Cryptosystem
--------
Paillier Cryptosystem[^pai_origin][^pai_intro][^pai_math_intro] 是個公鑰加密系統,並同態地支援某些運算。
[^pai_origin]: Paillier 原始論文, Paillier, Public-Key Cryptosystems Based on Composite
Degree Residuosity Classes http://www.cs.tau.ac.il/~fiat/crypt07/papers/Pai99pai.pdf
[^pai_intro]: Paillier 介紹文, Michael O’Keeffe, The Paillier Cryptosystem
A Look Into The Cryptosystem And Its Potential Application http://www.tcnj.edu/~hagedorn/papers/CapstonePapers/OKeeffe/CapstoneOKeeffeCryptography.pdf
[^pai_math_intro]: Paillier 數學介紹文, Paillier Cryptosystem: A Mathematical
Introduction http://www2.cs.uni-paderborn.de/cs/ag-bloemer/lehre/proseminar_WS2005/material/Volkhausen_Ausarbeitung.pdf
### 基本參數設置
Paillier Cryptosystem 的運算都是在下列三個空間中運作的:$\mathbb Z_n$、$\mathbb Z_n^*$、$\mathbb Z_{n^2}^*$。
#### 三個空間 $\mathbb Z_n$、$\mathbb Z_n^*$ 與 $\mathbb Z_{n^2}^*$
(以下用 $a\perp b$ 代表 $a,b$ 互質。)
取 $p,q:\textit{prime}$,定義 $n=pq.$
$\mathbb{Z}_n:=\{0,1,2,...,n-1\}$;作用於 $\mathbb{Z}_n$ 內的加法、乘法運算都要對 $n$ 取餘數。
$\mathbb{Z}^*_n:=\{a\in \mathbb{Z}_n | a\perp n\}$;也就是收集 $\mathbb{Z}_n$ 中有模反元素的那些數。同樣地,集合中的乘法要對 $n$ 取餘數(成為[整數模$n$乘法群](https://en.wikipedia.org/wiki/Multiplicative_group_of_integers_modulo_n))。根據定義,可計算集合大小:
$$|\mathbb{Z}_n| = \phi (n)=\phi (pq) = (p-1)(q-1).$$
$\mathbb{Z}^*_{n^2}:=\{a\in \mathbb{Z}_{n^2} | a\perp n^2\}$;也就是收集 $1,2,...,(n^2-1)$ 之中有模反元素(under modulo $n^2$)的那些數,而集合中的乘法要對 $n^2$ 取餘數。一樣來計算集合大小:
$$|\mathbb{Z}^*_{n^2}| = \phi (n^2)=p^2q^2(1-\frac1p)(1-\frac1q)=pq(p-1)(q-1)=n\phi(n).$$
上面的第二個等號是利用[歐拉函數的公式](https://en.wikipedia.org/wiki/Euler%27s_totient_function#Euler.27s_product_formula)。
#### 公鑰 $g$
公鑰是由 $n$ 以及一個小於 $n^2-1$ 的整數 $g$ 構成的序對 $(n,g)$
一個數 $g\in\mathbb{Z}_{n^2}^*$ 在 modulo $n^2$ 之下的階數(order、[multiplicative order](https://en.wikipedia.org/wiki/Multiplicative_order)),定義為
$$|g|_{n^2}:=\textrm{smallest } a\textrm{ satisfying } g^a\equiv 1\mod n^2.$$
也就是說 $g$ 在 $\mathbb{Z}_{n^2}^*$ 中要乘出 $1$ 所需的最小次方。
現在要找一個 $g\in \mathbb{Z}^*_{n^2}$ 滿足 $|g|_{n^2}$ 為 $n$ 的倍數。換句話說
$$|g|_{n^2} = kn\ \ \textrm{ (for some } k\in\mathbb{N}).$$
此外後來還提到 $g$ 需要滿足另一個條件:上式的 $k$ 不能為 $p,q$ 的倍數。
這裡把滿足$g$條件的集合稱為 $\mathcal{B}$
#### Carmichael- $\lambda$ 函數
函數 $\lambda(n)$ 定義為:能讓 $\mathbb{Z}_n^*$ 中所有元素 $a\in \mathbb{Z}_n^*$ 都乘出 $a^\square\equiv 1$ 的最小共同指數。換句話說:
$$\textrm{Minimize } \lambda(n) \textrm{ s.t. } \forall a\in \mathbb{Z}_n^*\ \ ,\ \ a^{\lambda(n)}\equiv 1 \mod n.$$
對於 $n=pq$,有 $\lambda(n)=\operatorname{lcm} (p-1,q-1)$。
根據 $\phi(n)$ 的定義,$\lambda(n)\leq\phi(n)$,這是因為 $\phi(n)$ 雖滿足
$$\forall a\in \mathbb{Z}_n\ \ ,\ \ a^{\phi(n)}\equiv 1 \mod n$$
,但它不一定是滿足上式的數中最小的。
#### 加密函數 $\varepsilon_g$
定義函數 $\varepsilon_g$
$$\begin{aligned}\varepsilon_g:(\mathbb{Z}_n\times\mathbb{Z}_n^*)&\to\mathbb{Z}_{n^2}^*\\ (x,y)&\mapsto g^x\cdot y^n\mod n^2\end{aligned}$$
若 $\operatorname{order}_{n^2}(g)$ 是 $n$ 的倍數,則 $\varepsilon_g$ 是個 bijection (一對一映成函數)(證明從略)。
這個 $\varepsilon$ 函數更早出現在 Benaloh 的論文[^benaloh]第 27 頁。
[^benaloh]: Benaloh, Verifiable Secret-Ballot Elections http://www.cs.yale.edu/publications/techreports/tr561.pdf
值得注意的是
$$(1+n)^n = \binom n0 + \binom n1n + \binom n2n^2 + \cdots \equiv 1+n^2+\cdots\equiv1\mod n^2$$
,因此 $n+1\in\mathcal{B}$,也就是 $g$ 的其中一組選擇。
若將 $\varepsilon_g$ 的反函數記為 $\varepsilon_g^{-1}: w\mapsto (x,y)$,則對任意 $w\in\mathbb{Z}^*_{n^2}$ ,定義 $[[w]]_g\in\mathbb Z_n$ 為
$$[[w]]_g:=\textrm{The } x \textrm{ component of } \varepsilon_g^{-1}(w).$$
將$n+1$代入$g$,我們可以得到
$$ c=\varepsilon_{n+1}([[c]]_{n+1}, z) = (n+1)^{[[c]]_{n+1}}z^n \mod n^2\ $$
兩側取 $\lambda(n)$ 次方
$$ c^{\lambda(n)}= (n+1)^{\lambda(n)[[c]]_{n+1}}z^{n\lambda(n)} \mod n^2 $$
由於$n\lambda(n)=\lambda(n^2)$,根據Carmichael-$\lambda$函數的定義,$z^{\lambda(n^2)} \equiv 1 \mod n^2$
$$ c^{\lambda(n)}= (n+1)^{\lambda(n)[[c]]_{n+1}} \mod n^2 $$
展開得到
$$ c^{\lambda(n)} = 1+n\lambda(n)[[c]]_{n+1} \mod n^2 $$
將此式子標記為$(*)$以利後面證明使用
### 加密與解密
#### 加密
以 $(n,g)$ 為公鑰,取 $m\in\mathbb{Z}_n$ 為明文,並選擇亂數 $r\in\mathbb{Z}_n^*$
計算密文
$$\begin{aligned}
c &= \varepsilon_g(m,r) \in \mathbb Z_{n^2}^*\\
&=g^mr^n\mod n^2
\end{aligned}$$
#### 解密
定義$L(u)=(u-1)/n\mod n$
以$\lambda(n)$為私鑰,計算明文
$$ m=L(c^{\lambda(n)}\operatorname{mod}n^2)\mu \mod n, \mu=L^{-1}(g^{\lambda(n)}\operatorname{mod}n^2) $$
將$(*)$代入
$$m=L(1+n\lambda(n)[[c]]_{n+1})*L^{-1}(1+n\lambda(n)[[g]]_{n+1}) \mod n$$
把$L$函數算出來
$$m=\frac{\lambda(n)[[c]]_{(1+n)}}{\lambda(n)[[g]]_{(1+n)}} \mod n$$
並化簡
$$m=\frac{[[c]]_{(1+n)}}{[[g]]_{(1+n)}} \mod n$$
將$[[c]]_{n+1}$換底成為$[[c]]_g[[g]]_{n+1}$(待證明)
$$ m = \frac{[[c]]_g[[g]]_{n+1}}{[[g]]_{n+1}}$$
相消後得到
$$ m = [[c]]_g$$
由於計算 $\lambda(n)=\operatorname{lcm}(p-1,q-1)$ 需要 $p,q$,因此 $p,q$ 保留為私鑰。
#### $L$ 函數
[維基百科](https://en.wikipedia.org/wiki/Paillier_cryptosystem#Background)提到,由於
$$(1+n)^x \equiv_{n^2} 1+nx$$
,因此若令 $y=(1+n)^x$,代入上式可求得 $x$:
$$\begin{aligned}
y&=1+nx\\
y-1&=nx\\
\frac{y-1}{n}&=x
\end{aligned}$$
(這裡的除不是乘以模反)
因此 $y=(1+n)^x$ 之中的指數 $x$ 可以透過基本運算得到:
$$\log_{1+n}y = \frac{y-1}n$$
將這個以 $(1+n)$ 為底的對數函數(離散對數)訂為
$$L(y) = \log_{1+n}y = \frac{y-1}n$$
### 同態性質
Paillier Cryptosystem 滿足下面的同態性質:
$$\textit{Enc}(m_1+m_2) = \textit{Enc}(m_1)\times\textit{Enc}(m_2)$$
換句話說,將明文相加再加密,與將密文相乘是同一回事。
證:
$$ \begin{aligned}
\textit{Enc}(m_1)\times\textit{Enc}(m_2) &= g^{m_1}r_1^n\times g^{m_2}r_2^n\\
&=g^{m_1+m_2}\cdot(r_1r_2)^n\\
&=\textit{Enc}(m_1+m_2)
\end{aligned} $$
上面的性質與指數律很像,因此也可以引申為
$$ \textit{Enc}(m\times k) = (\textit{Enc}(m))^k\ ,\ \ \textrm{for some integer } k.$$
不過上面對於明文的運算都要取 modulo $n$,對密文則是取 modulo $n^2$.
### 安全性基於「合數剩餘假設」
#### 模 $n^2$ 的 $n$ 次剩餘
$\mathbb{Z}^*_{n^2}$ 有一個特殊的子集:$\textit{NR}\subseteq\mathbb{Z}^*_{n^2}$,定義如下:
$$\textit{NR} := \{a\in\mathbb{Z}^*_{n^2}\ |\ a\equiv r^n \operatorname{mod} n^2\ \ ,\ \textrm{for some } r \}$$
換句話說,若某 $r$ 乘了 $n$ 次後 $\textrm{mod }n^2$ 會餘 $a$,那麼這個 $a$ 就要被收集到 $\textit{NR}$ 之中。
這個集合稱為「模 $n^2$ 的 $n$ 次剩餘(的集合)」。$\textit{NR}$ 的符號不知道怎麼來的,至少這篇[^pai_math_intro]是這樣用。以下關於難題的複雜度類別也依照這篇的記號。
#### 確定合數剩餘假設 Decisional Composite Residuosity Assumption
> 給定一個合數 $n$ 與整數 $z$,問是否存在某 $y$ 滿足
>
> $$y^n\equiv z\mod n^2$$
換句話說,$z$ 能不能是 $\textit{mod }n^2$ 下的 $n$ 次剩餘?
$$z\overset{?}{\in}\textit{NR}$$
本文把這問題的難度稱為 $\textit{CR(n)}$,DCRAssumption 猜測 $\textit{CR(n)}$ 是困難的(例如不存在多項式時間解法)。
#### 算出 $[[c]]$ 所需要的難度
考慮下面問題:
> 已知 $c, g\in\mathbb Z_{n^2}^*$,如何求出 $[[c]]_g$ ?
將這類問題的難度記為 $\textit{Class(n)}.$ 另外考慮類似的問題:
> 已知 $c, g\in\mathbb Z_{n^2}^*\ ,\ m\in\mathbb Z_n$,如何確定 $m \overset{?}{=} [[c]]_g$
將這類問題的難度記為 $\textit{D-Class(n)}.$ 可想而知,$\textit{Class(n)}$ 比 $\textit{D-Class(n)}$ 還要難,因為前者被解的話後者自然就解開了。
#### 破解得了 $\textit{CR}(n)$,才有可能破解 Paillier Cryptosystem
若 $\textit{D-Class(n)}$ 可被破解,代表取適當的 $c, g\in\mathbb Z_{n^2}^*\ ,\ m\in\mathbb Z_n$,我們能知道下式的 $r$ 存不存在(也就決定 $m$ 是不是下式的解):
$$g^m r^n\equiv c \mod n^2$$
今任取 $g$,並取 $m=0$,則利用 $r$ 的存在性便能夠確定 $c$ 是不是模 $n^2$ 的 $n$ 次剩餘。
換句話說,若 $\textit{D-Class(n)}$ 被破解,$\textit{CR}(n)$ 也會跟著被破解。因此難度的排序是
$$\textit{Paillier Crypt}\overset{def}{=}\textit{Class(n)}\geq\textit{D-Class(n)}\geq\textit{CR(n)}$$
第一個等號是因為 $[[\cdot]]$ 正是解密函數。
牽涉數論的演算法
-------------
有些內容參考這本書:*[Handbook of Applied Cryptography](http://cacr.uwaterloo.ca/hac/)*,裡面有不少密碼學常用到的、處理質數的演算法。
### 求模反元素
#### 擴展歐幾里得演算法
給定 $a$、$n$ 要尋找 $x$ 使得 $ax \equiv 1 \mod n$,相當於求解以下不定方程的整數解:
$$ ax - ny = 1$$
而 $x$、$y$ 有整數解的前提是 $a$、$n$ 互質($a\perp n$)。
利用輾轉相除法可以求解上式:輾轉相除法是將 $a$、$n$ 交替相除以得到 $\gcd(a,n)$ 的手段,因此最後 $\gcd(a,n)=1$ 能被表為 $a,n$ 的線性組合。以下舉例:
> Find $y$ such that $$32y\equiv 1\mod 77$$
這相當於解以下的方程:
$$77x + 32y = 1$$
利用輾轉相除法找到 $32$ 與 $77$ 的最大公因數,同時用下標寫出每個階段是幾個 $77$ 加上幾個 $32$。
例如 $77$ 就是「一」個 $77$ 加上「零」個 $32$,所以就寫 $77_{(1,0)}$ :

因此解得 $x=5$、$y=-12$
$\implies 32$ 在 $\operatorname{mod}77$ 下的模反元素是 $-12\equiv 65\mod 77.$
這就是[擴展歐幾里得演算法](https://zh.wikipedia.org/wiki/%E6%89%A9%E5%B1%95%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97%E7%AE%97%E6%B3%95),一邊輾轉相除同時要 maintain 餘數被 77, 32 表示為線性組合時的係數。
擴展歐幾里得演算法同時也可以用來計算[有限體](https://en.wikipedia.org/wiki/Finite_field) $\textrm{GF}(2, n)$ 的乘法反元素。
#### 利用歐拉定理
第二個求模反元素的方法是利用 $5^{\phi(23)}\equiv1\mod23$
$\implies 5^{22}\equiv1\mod23$
$\implies5\cdot5^{21}\equiv1\mod23$
因此 $5$ 在 $\operatorname{mod}23$ 下的模反元素是 $5^{21} \equiv 14 \mod 23.$
### 求 $a^k(mod\ n)$
#### 重複平方並相乘
寫出 $k$ 的二進位表示法,例如 $k=1011010_2=2^1+2^3+2^4+2^6$。
接著重複計算 $a\leftarrow a^2\textrm{ mod } n$ 以得到 $a$ 的所有 $2^i$ 次 $(i\textrm{ from }1\textrm{ to }\lfloor\lg k\rfloor)$
過程中會分別算到 $a^2, a^{2^3}, a^{2^4}, a^{2^6}$,將它們依序乘起來就好了。不考慮大數運算的話複雜度應該是 $\Theta(\lg k)$。
### 質數 / 合數檢定法
#### Fermat primality test
#### Miller-Rabin test
### 求某 $g$ 在 $\mathbb Z_n^*$ 中的 multiplicative order
#### Baby-step, Giant-step
這是任何[群](https://zh.wikipedia.org/wiki/%E7%BE%A4)都可以求 order 的演算法。$\mathbb Z_n^*$ 是群,因此也可以用,不過比較慢。此外類似的策略也被用來暴力破解離散對數問題。
首先計算第一個系列(baby-step):
$$g^1, g^2, g^3, ..., g^{999}\mod n$$
,如果其中一項為 $1$,問題就解決了。否則繼續計算第二個系列(giant-step):
$$g^{1000},g^{2000},g^{3000},...g^{1000000}\mod n$$
如果這些值與第一個系列的值有重複,那也算完了(例如 $g^{9912}\equiv1$ 會讓我們算出 $g^{88}\equiv g^{10000}$ )。
由於 $|\mathbb Z_n^*|$ 是 $g$ 的 order 的上限,因此在確定 $|\mathbb Z_n^*|<1000000$ 的情況下,上面的算法就會找到 $g$ 的 order。
如果 $|\mathbb Z_n^*|$ 未知,以上步驟又都失敗,就要考慮重新調整:讓 baby-step 走更遠一點,giant-step 跨更大步、更遠,再從頭做一次。
不過重來時有些值是不用重算的,下次 baby-step 的數列值可以由上次兩個數列互乘得到。
#### $|\mathbb Z_n^*|$ 已被分解時的算法
由於 $g^{|\mathbb Z_n^*|}\equiv 1\textrm{ (mod }n)$,因此 $|\mathbb Z_n^*|$ 是 $g$ 的 order 的上限。現在將 $|\mathbb Z_n^*|$ 質因數分解成
$$|\mathbb Z_n^*|=p_1^{e_1}p_2^{e_2}p_3^{e_3}\cdots p_k^{e_k}$$
首先測試 $g$ 的 $p_1^{\square}p_2^{e_2}p_3^{e_3}\cdots p_k^{e_k}$ 次方是否為 $1\textrm{ (mod }n)$,其中 $\square=0,1,2,\cdots$。當測出來真的變成 $1$ 時就停下,把這個 $\square$ 值記為 $r_1$。
接著測試 $g$ 的 $p_1^{r_1}p_2^{\square}p_3^{e_3}\cdots p_k^{e_k}$,一樣 $\square=0,1,2,\cdots$,當算出 $1$ 時再停下,把這個 $\square$ 值記為 $r_2$。
接著測試 $g$ 的 $p_1^{r_1}p_2^{r_2}p_3^{\square}\cdots p_k^{e_k}$,以此類推,最後得到一個數
$$p_1^{r_1}p_2^{r_2}p_3^{r_3}\cdots p_k^{r_k}$$
就是 $g$ 的 order。