這個 libgcrypt elgamal 解密是如何工作的?
更新:在我意識到這樣做是為了防止側通道攻擊之前,提出了以下問題:https ://github.com/advisories/GHSA-5p8v-2xvp-pwmc
我仍然好奇的是,為什麼這個解決方案仍然可以解密 Elgamal 密文背後的數學原理。
原始問題:
libgcrypt elgamal 解密引入了一個隨機數來執行解密。誰能向我解釋這是如何工作的?我已經發布了只顯示相關操作的編輯原始碼。
skey->p
是素數模數,skey->x
是接收者的密鑰,加密的消息是(a,b)
。我不明白r
這裡執行解密的介紹。我原以為t1=a^x mod p
就足夠了。那麼消息可以計算為b*t1^-1 mod p
/* We need a random number of about the prime size. The random number merely needs to be unpredictable; thus we use level 0. */ _gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM); /* t1 = r^x mod p */ mpi_powm (t1, r, skey->x, skey->p); /* t2 = (a * r)^-x mod p */ mpi_mulm (t2, a, r, skey->p); mpi_powm (t2, t2, skey->x, skey->p); mpi_invm (t2, t2, skey->p); /* t1 = (t1 * t2) mod p*/ mpi_mulm (t1, t1, t2, skey->p); mpi_mulm (output, b, t1, skey->p);
它來自這個送出:https ://github.com/gpg/libgcrypt/blob/410d70bad9a650e3837055e36f157894ae49a57d/cipher/elgamal.c
原始碼從第 523 行開始
更新:
該文件的最新 1.9 版本在這裡: https ://github.com/gpg/libgcrypt/blob/LIBGCRYPT-1.9-BRANCH/cipher/elgamal.c
從第 511 行開始,我現在可以看到有額外的行來提供指數盲法。什麼是致盲,它是如何工作的,為什麼它仍然提供有效的解決方案?
/* We need a random number of about the prime size. The random number merely needs to be unpredictable; thus we use level 0. */ _gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM); /* Also, exponent blinding: x_blind = x + (p-1)*r1 */ _gcry_mpi_randomize (r1, nbits, GCRY_WEAK_RANDOM); mpi_set_highbit (r1, nbits - 1); mpi_sub_ui (h, skey->p, 1); mpi_mul (x_blind, h, r1); mpi_add (x_blind, skey->x, x_blind); /* t1 = r^x mod p */ mpi_powm (t1, r, x_blind, skey->p); /* t2 = (a * r)^-x mod p */ mpi_mulm (t2, a, r, skey->p); mpi_powm (t2, t2, x_blind, skey->p); mpi_invm (t2, t2, skey->p); /* t1 = (t1 * t2) mod p*/ mpi_mulm (t1, t1, t2, skey->p); mpi_free (x_blind); mpi_free (h); mpi_free (r1); mpi_free (r); mpi_free (t2); #else /*!USE_BLINDING*/ /* output = b/(a^x) mod p */ mpi_powm (t1, a, skey->x, skey->p); mpi_invm (t1, t1, skey->p); #endif /*!USE_BLINDING*/ mpi_mulm (output, b, t1, skey->p);
收件人有私鑰 $ x $ 與對應的公鑰 $ Y=G^x $ . 加密 $ M $ 對於收件人,選擇一個統一隨機的私鑰 $ k $ ,併計算密文 $ (A,B) = (G^k, Y^k\cdot M) $ .
正常(非盲)解密計算 $ M=\frac{B}{A^x}=\frac{(G^x)^k\cdot M}{(G^k)^x} $ . 這有效,因為 $ (G^x)^k = (G^k)^x $ .
然而,在取冪產生電磁輻射的情況下,存在側信道攻擊 $ A^x $ 可以洩露有關私鑰的資訊 $ x $ .
為了避免直接執行 $ A^x $ 取冪,解密的盲變首先選擇一個均勻隨機的值 $ R $ .
現在,我們計算 $ M=\frac{B\cdot R^x}{(A\cdot R)^x}=\frac{B\cdot R^x}{A^x\cdot R^x}=\frac{B}{A^x} $ .
請注意,我們現在只用我們的私鑰對盲值求冪 $ x $ . 自從 $ R $ 攻擊者不知道,通過監測電磁輻射更難提取有用資訊。
在您連結到的較新版本的程式碼中,我們使用了盲版本 $ x $ . 它計算為 $ x’=x+(p-1)r’ $ , 在哪裡 $ r’ $ 是一個均勻隨機值。
這意味著我們最終計算 $ M=\frac{B}{A^{x’}} $ 代替 $ M=\frac{B}{A^{x}} $ .
這有效,因為 $ (p-1) $ 是通過對組元素求冪生成的組的大小,例如 $ A $ . 由於組的循環性質,組大小的任何倍數都添加到標量(例如私鑰 $ x $ ) 將在求冪後得到相同的結果組元素值。
如果我們定義 $ \ell=(p-1) $ , 然後 $ A^x=A^{(x+\ell)}=A^{(x+\ell r’)} $ 對於任何值 $ x $ , $ A $ 和 $ r’ $ . (注意:這個答案中的所有指數都是 $ \operatorname{mod} p $ )。
因此,當使用盲值 $ x’ $ 代替 $ x $ ,即使 CPU 執行的計算(以及產生的電磁輻射)不同,結果也是相同的。