KKRT-PSI

KKRT庫:https://github.com/osu-crypto/BaRK-OPRF

文章:Efficient Batched Oblivious PRF with Applications to Private Set Intersection-2016

方案

解讀論文,參考:Efficient Batched Oblivious PRF -Private Set Intersection

關鍵詞:兩方PSI、ORFT、OTE

引言

KKRT-PSI方案使用了OTE(OT擴展)、OPRF、Cuckoo哈希等技術,在大集合場景、局域網(帶寬20GB/s)下運行效果最好。

方案構造思路:先設計一個OTE,進而設計一個OPRF,最後設計一個PSI

image-20230516223618857

基礎

1-2 OT

協議功能:Sender不知道Receiver的選擇\(r\);Receiver只知道\(X_r\)

image-20230516223752763

協議實現:有基於RSA的、基於DH的、基於ECC的等。

下面介紹的是Naor-Pinkas-OT,Naor和Pinkas通過三次公鑰密碼學操作實現了半誠實模型下的1-2 OT:

論文:Efficient oblivious transfer protocols-2001

參考:Naor-Pinkas茫然傳輸協議

image-20230516225600242

其中\(E_{r,2}\)表示\(E_r\)的第二部分,若\(r=0\),則:

image-20230516225725013

安全性:Sender根據\(PK_0\)不能反推出\(k\);Receiver根據\(g^a\)不能反推出\(a\)

1-2 OTE

1-2 OT在實際應用中,每次都需使用一次,效率較低,所以下一步採用“固定數量的OT來實現任意數量的OT”,例如下圖只需要使用\(k\)次1-2OT即可實現,其中\(k\)是根據安全參數決定的。

image-20230517101653981

Ishai、Kilian、Nissim和Petrank於2003年提出基於矩陣變化實現少量1-2OT和對稱密鑰構造大量OT實例的不經意傳輸擴展協議。

論文:Extending Oblivious Transfers Efficiently-2003

參考:[IKNP03] Extending Oblivious Transfers Efficiently

本文提出了一種OT擴展協議,即\(k\)次1-2OT實現了\(m\)次1-OT,其中\(k<m\),,即每次有兩種選擇。文中給出了兩種情況的協議:Receiver半誠實和Receiver惡意,下面介紹Receiver半誠實的協議

image-20230518160911170

分析:

注意:\(m_i\)表示列,\(m^i\)表示行

  • 輸入
    • S:\(m\)\((x_{j,0},x_{j,1})\),其中\(x_{j,b}\)是一個\(l\)bit的字符串
    • R:選擇比特\(r=(r_1,...,r_m)\in[0,1]\)
  • 輸出:
    • R:得到\(m\)\(x_{j,b}\)
image-20230518163524140
  • 協議:
    • 兩方執行\(OT_m^k\)協議,S得到一個矩陣\(Q_{m*k}\),其中\(q^i=(s_i*r)\oplus t^i,i\in[1,k]\)(從列看)
      • 從行看,\(q_j=(s*r_j)\oplus t_j=\left\{\begin{matrix}q_j=t_j,if(r_j=0)\\q_i=s\oplus t_j,if(r_j=1)\end{matrix}\right.,j\in[1,m]\)
      • 從而有:\(t_j=q_j\oplus s\)
    • S:對於每對\((x_{j,0},x_{j,1}),j\in[1,m]\),計算\(y_{j,0}=x_{j,0}\oplus H(j,q_j),y_{j,1}=x_{j,1}\oplus H(j,q_j\oplus s)\),併發送給R
    • R:計算\(z_j=y_{j,r_j}\oplus H(j,t_j)\)
  • 正確性:
image-20230518164452912

1-n OTE

IKN03方案是用\(k\)次OT實現了\(m\)次1-2OT,其中\(k<<m\)。KK13方案將IKN03中的\(r\)看作一個矩陣\(R_{m*k}\)(每列都一樣),計算\(T=U \oplus R\),無需使用1-2OT實現1-nOT,僅改變了\(R\),利用編碼技術,實現了\(1-n\)OTE。

image-20230520221053784

論文:Improved OT Extension for Transferring Short Secrets-2013

參考:KK13 OTE——Improved OT Extension for Transferring Short Secrets

image-20230520221552629

image-20230520221612380

\(k\)次1-n OT傳遞了\(m\)個信息,每個消息是\(lbit\),且是n箇中選1個,其中\(k>=n\)

  • ⚠️
    • \(t_{j,0}\)表示矩陣\(T_0\)的第\(j\)行,有\(k\)個數據,每個數據爲\(1bit\)
    • \(C_{WH}^k(a)\)表示輸入一個\(log^k\)bit的字符串\(a\),輸出一個\(k\)個字符串\((c_0,...,c_{k-1})\),每個字符串爲\(kbit\),即可以看作是一個\(k*k\)的比特矩陣。
    • 從行看,\(t_{j,0}\oplus t_{j,1}=c_{r_j}\),即\(T_1\)的行等於\(T_0\)的行和\(R\)中的行。
  • S和R之間進行\(k\)次1-nOT,S獲得了矩陣\(Q_{m*k}\)
    • 從列看,若\(s_i=0\),則\(q^i=t_0^i\);若\(s_i=1\),則\(q^i=t_1^i\),所以\(q^i=t_{s_i}^i\)
    • 從行看,\(q_j=((t_{j,0}\oplus t_{j,1})*s)\oplus t_{j,0} \to q_j=(c_{r_j}*s)\oplus t_{j,0}\)

image-20230517171956123

  • 證明
    • 最後S計算\(y_{j,r}\),共要計算\(m*n\)個,例如\(j=1\),則需發送\(y_{1,0},y_{1,1},...,y_{1,n-1}\),對於R來說,只取\(y_{1,1}\),其他無用。

image-20230520230352035

關於WH編碼:

image-20230521160011224

1-$\infty $ OTE

從KK13方案中,知道\(C_{WH}^k(a)\)是一種編碼形式,即輸入一個\(log^k\)bit的字符串\(a\),輸出一個\(k\)個字符串\((c_0,...,c_{k-1})\),每個字符串爲\(k\)bit,在進行隱私相等性測試時,即已知\(C_{WH}^k(a),C_{WH}^k(b)\),如何安全判斷\(a\)\(b\)是否相等,無需解碼,只需比較\(C_{WH}^k(a),C_{WH}^k(b)\)是否相等即可,這裏需要保證\(C_{WH}^k(a)\oplus C_{WH}^k(b)\)的漢明距離不小於計算安全參數。所以在KKRT16方案中的OTE,無需使用\(WH\)編碼技術,只需要一個漢明距離不小於計算安全參數的僞隨機函數即可

image-20230521161618009

BaRK-OPRF

image-20230525144607074

  • 首先介紹一下OPRF:

發送方和接收者執行兩方OPRF協議,發送方無輸入,接收方輸入元素\(x_i\),發送方輸出密鑰\(k\),接收方輸出OPRF值\(F(k,x_i)\)

image-20230521162004250

  • 下面介紹如何將KKRT16-OTE解釋爲一個OPRF協議:

上面提到需使用僞隨機函數,這裏僞隨機函數的功能相當於KK13中的哈希,即\(F=H(j,\mathbf{q}_{j}\oplus(\mathbf{c}_{r}\odot\mathbf{s}))\)。一共有\(m\)\(r_i\),可以執行\(m\)次OPRF。另外在2019年PRTY19和2020年CM20都基於第3個屬性對OPRF協議進行了進一步的改進,得到多點OPRF,實現了正常帶寬下最快的PSI協議

image-20230521163122730

KKRT167中使用的OPRF由於是Batch、relaxed的,所以叫做BaRK-OPRF。

得到一個OPRF協議後,就可以很容易的構造一個PSI協議。例如下圖:

  • S與R執行OPRF,R輸入隱私集合,輸出OPRF值;
  • S輸出密鑰\(k\),可計算任意的OPRF值,\(S\)本地計算OPRF值並將其發送給接收方,R通過字符串比較得到交集;

image-20230521165747410

但接收方需要進行\(O(n^2)\)次比較。

Cuckoo 哈希

更多參考:https://www.cnblogs.com/pam-sh/p/16155650.html#cuckoo-hash

Cuckoo hashing分爲兩個存儲表,一個爲Cuchoo哈希表,一個稱爲堆存儲容器。(本文協議採用的這樣的容器,之後的文章有采用無堆存儲容器的Cuckoo hashing)。

Cuckoo插入元素\(x\)的算法如下:

  1. 計算元素\(x\)的三個哈希值,尋找對應索引的位置,若至少有一個位置爲空則隨機插入空位置。若一個位置也沒空,則隨機選擇一個位置替換該元素,然後對該元素執行上述步驟。
  2. 若執行\(k\)次後,仍然需要替換,則將該元素存儲到堆存儲器中!

image-20230521165758902

PSI協議

上述基於一個理想的OPRF構造了一個簡單的PSI協議,但效率(計算和通信)較低。

KKRT16-PSI協議遵循了PSZZ15基於KK13-OTE構造PSI的思路,採用Cuckoo hashing算法減少了比較次數。對於128bit的字符串和足夠大的集合,求交速度比PSZZ15快3.1~3.6倍,具體說只需3.8s就能求出集合大小爲\(2^{20}\)的交集。

「PSZZ15」Phasing: Private set intersection using permutation-based hashing-2015

「PSZ14」Faster private set intersection based on OT extension-2014

總結了PSI協議構造的方法:基於哈希的、基於公鑰加密的、基於GC的、基於OT的等。改進了「PSZ14」方案:使用置換哈希減少

bin的位長、使用哈希和安全電路計算,降低電路深度和通信消耗、使用改進的OT協議改進計算和內存消耗。

  • 以PSSZ15的構造方式構造PSI協議,僅將OPRF協議替換爲KKRT16-OTE
  1. 接收方隨機選擇3個hash函數,將集合元素通過布穀鳥hash算法映射到布穀鳥表或堆容器中,最後空餘的地方採用虛擬元素填充;
  2. 發送方和接收方執行\((b+s)\)次OPRF實例,其中\(b\)\(s\)分別代表布穀鳥表和堆容器的長度,並將OPRF值和元素\(x\)的對應存儲位置聯繫起來;
  3. 發送方擁有密鑰\(K\),本地計算H和S並將每一行打亂再發送給接收方;
  4. 接收方哈希表每一行的比較次數爲3次,堆容器中的每個元素需要比較n次但只有s個元素且s爲常量,因此只需要比較(3+s)n次;

image-20230521170207039

  • 優化後,性能提升10%。

對於在bin中的數據,\(z\)表示所用的哈希函數,OPRF的輸入爲\(x||z\),輸出爲\(F(k_{h_z(x)},x||z)\);對於在stash中的數據,OPRF的輸入不變,即\(x\),輸出爲\(F(k_{1.2n+x},x)\),所以H和S的生成爲:\(\begin{gathered} H_{i} =\{F(k_{h_t(x)},x\|i)\mid x\in X\},\text{for}i\in\{1,2,3\} \\ S_{j} =\{F(k_{1.2n+j},x)|x\in X\},\text{for}j\in\{1,\ldots,s\} \end{gathered}\)

這樣PRF的值變爲了\(n+ns\),且降低了OPRF的碰撞概率。

  • 最後方案:

image-20230525150559558

關於\(K=(k_1,....,k_{1.2n+s})\)的生成沒有具體說,待補充。

論文

image-20230525150900463

image-20230525150937225

image-20230525151215735

image-20230525151230334

image-20230525151251470

image-20230525151326896

image-20230525151338921

程序

編譯安裝

環境:Centos7.6

## 下載
git clone https://github.com/osu-crypto/BaRK-OPRF.git

## 下載依賴庫
cd BaRK-OPRF/thirdparty
bash all_linux.get

## 會發現有些問題,需要將makelist中的'yum -Y'改爲'yum -y'

## 編譯
cd ..
make

## 會發現mpir安裝的有問題,原來是給的下載鏈接失效了,重新找了一個替換上
## mpir.get文件
wget http://sources.buildroot.net/mpir/mpir-3.0.0.tar.bz2
tar -xjf mpir-3.0.0.tar.bz2 
mv mpir-3.0.0 mpir
rm mpir-3.0.0.tar.bz2 

cp ./mpir_patch/mpirxx.h ./mpir/
cp ./mpir_patch/mpir.h ./mpir/

cd mpir
./configure
make

## 重新編輯,即可
make

## 測試
./Release/bOPRFmain.exe -t

測試

單元測試

# 輸入數據集規模爲2^{12},進行測試
./Release/bOPRFmain.exe -t

image-20230516212311198

模擬測試

計算6種情況下的PSI,輸入數據規模爲(\(2^8\)\(2^{12}\)\(2^{16}\)\(2^{20}\)\(2^{24}\))。對於每種情況,運行代碼10次來計算PSI。輸出包括平均在線/離線/總運行時間(顯示在屏幕上)和output.txt文件。

  • 同機器
# Sener
./Release/bOPRFmain.exe -r 0

# Receiver
./Release/bOPRFmain.exe -r 1
  • 不同機器
# Sener
./Release/bOPRFmain.exe -r 0 -ip <ipAdrress:portNumber>

# Receiver
./Release/bOPRFmain.exe -r 1 -ip <ipAdrress:portNumber> 	

解讀

基礎

  • int main(int argc, char **argv)
//提示函數,其中argv0指向exe
void usage(const char *argv0)
{
	std::cout << "Error! Please use:" << std::endl;
	std::cout << "\t 1. For unit test: " << argv0 << " -t" << std::endl;
	std::cout << "\t 2. For simulation (2 terminal): " << std::endl;
	;
	std::cout << "\t\t Sender terminal (localhost): " << argv0 << " -r 0" << std::endl;
	std::cout << "\t\t Receiver terminal (localhost): " << argv0 << " -r 1" << std::endl;

	std::cout << "\t\t Sender terminal (with ip input): " << argv0 << " -r 0 -ip <ip:port>" << std::endl;
	std::cout << "\t\t Receiver terminal (with ip input): " << argv0 << " -r 1 -ip <ip:port>" << std::endl;
}

int main(int argc, char **argv)
{

	//有兩個參數,第一個爲exe,第二個爲“-t”,其中第二個參數argv[1][0] == '-',argv[1][1] == 't'
	if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 't')
	{
		BopTest();
	}
	//有三個參數,第一個爲exe,第二個爲“-r”,第三個爲“0”,另外atoi()能把字符串轉換成整型數
	else if (argc == 3 && argv[1][0] == '-' && argv[1][1] == 'r' && atoi(argv[2]) == 0)
	{
		BopSender("localhost:1213");
	}
	//有三個參數,第一個爲exe,第二個爲“-r”,第三個爲“1”
	else if (argc == 3 && argv[1][0] == '-' && argv[1][1] == 'r' && atoi(argv[2]) == 1)
	{
		BopRecv("localhost:1213");
	}
	else if (argc == 5 && argv[1][0] == '-' && argv[1][1] == 'r' && atoi(argv[2]) == 0 && argv[3][0] == '-' && argv[3][1] == 'i' && argv[3][2] == 'p')
	{
		//獲取ip
		string ipAddr = argv[4];
		BopSender(ipAddr);
	}
	else if (argc == 5 && argv[1][0] == '-' && argv[1][1] == 'r' && atoi(argv[2]) == 1 && argv[3][0] == '-' && argv[3][1] == 'i' && argv[3][2] == 'p')
	{
		string ipAddr = argv[4];
		BopRecv(ipAddr);
	}
	else
	{
		//跳轉提示
		usage(argv[0]);
	}

	return 0;
}

int main(int argc, char** argv)主函數中的argc代表的是參數的數量,至少爲1(argv[0]即.exe文件的路徑)。argv指針表示的參數,argv[0]表示第一個參數,argv[1]表示第二個參數,以此類推。

預處理

待補充

應用

隱語

參考:隱私集合求交

[KKRT16] 是半誠實 OT-based PSI協議,基於 OT Extension, BaRK-OPRF 和 CuckooHash。 [KKRT16] 是第一個在千萬( 224224)規模,長度(128 bits)數據集上,求交時間在1分鐘之內的PSI協議.

隱語 SPU PSI 中使用了 [PSZ18] 提到的 3-way stash-less CuckooHash:

img

image-20230525151529282

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章