You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
6.9 KiB
323 lines
6.9 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d172899c",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Mahdavi et al.'s OT-MP-PSI Protocol\n",
|
|
"## An implementation in SageMath for research purposes\n",
|
|
"\n",
|
|
"We implement the OT-MP-PSI protocol of Mahdavi et al. It is based on Shamir's Secret Sharing and the homomorphic Paillier encryption scheme.\n",
|
|
"\n",
|
|
"### Mathematical Preamble\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"id": "42670e84",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import hashlib\n",
|
|
"import random\n",
|
|
"\n",
|
|
"# Prime order of the finite field\n",
|
|
"q = 11\n",
|
|
"p = 2*q + 1 # 23 is prime!\n",
|
|
"# Threshold value\n",
|
|
"t = 4\n",
|
|
"# Number of participants (holders of a dataset)\n",
|
|
"m = 7\n",
|
|
"# Secret to reconstruct\n",
|
|
"S = 0\n",
|
|
"\n",
|
|
"Fp = GF(p)\n",
|
|
"R = PolynomialRing(Fp,\"x\")\n",
|
|
"\n",
|
|
"G = Integers(q)\n",
|
|
"\n",
|
|
"# Paillier Cryptosystem\n",
|
|
"p2 = 13\n",
|
|
"q2 = 17\n",
|
|
"assert(p2.is_prime())\n",
|
|
"assert(q2.is_prime())\n",
|
|
"N = p2 * q2\n",
|
|
"\n",
|
|
"alpha = 0\n",
|
|
"\n",
|
|
"#FN2 = FiniteField(N^2, 'g')\n",
|
|
"ZN2 = Zmod(N^2)\n",
|
|
"FN2 = [a for a in ZN2 if gcd(a,N^2) == 1]\n",
|
|
"\n",
|
|
"g = random.choice(FN2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "8c2c98e4",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Paillier Encryption"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"id": "a264ea15",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def paillier_encrypt(element):\n",
|
|
" r = random.randint(0, N-1)\n",
|
|
" return pow(g, element) * pow(r, N)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d76a9195",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Initialize Shamir's Secret Sharing"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"id": "695e93bf",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def sample_coefficients(t):\n",
|
|
" coefficients = []\n",
|
|
" coefficients.append(S)\n",
|
|
" for i in range(0, t-1):\n",
|
|
" coefficients.append(Fp.random_element())\n",
|
|
" print(coefficients)\n",
|
|
" return coefficients"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"id": "7c2565c5",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Construct Polynomial\n",
|
|
"def poly(coefficients):\n",
|
|
" return R(coefficients)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"id": "b61c1603",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[0, 6, 6, 0]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"5"
|
|
]
|
|
},
|
|
"execution_count": 27,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"f_x = poly(sample_coefficients(t))\n",
|
|
"f_x(4)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"id": "4c8c5660",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def H(element):\n",
|
|
" h = hashlib.new('sha256')\n",
|
|
" h.update(bytes(element))\n",
|
|
" return int(h.hexdigest(), 16) % q"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"id": "54e8a4bf",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"7"
|
|
]
|
|
},
|
|
"execution_count": 29,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"H(0b10011101)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 39,
|
|
"id": "b9bada7f",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def keyholder_init():\n",
|
|
" coefficients = sample_coefficients(t)\n",
|
|
" \n",
|
|
"def participant_init(element):\n",
|
|
" global alpha \n",
|
|
" alpha = random.randint(1,p)\n",
|
|
" print(alpha)\n",
|
|
" return (pow(H(element), alpha), pow(g, alpha))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "5d43f845",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 40,
|
|
"id": "fd75b745",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def keyholder_processing(part_init_res):\n",
|
|
" hash_element, g_power_alpha = part_init_res\n",
|
|
" print(hash_element)\n",
|
|
" random_numbers = []\n",
|
|
" for i in range(0, t-1):\n",
|
|
" random_numbers.append(Fp.random_element())\n",
|
|
" \n",
|
|
" return_values = []\n",
|
|
" print(random_numbers)\n",
|
|
" for j in range(0, t-1):\n",
|
|
" return_values.append(pow(g_power_alpha, random_numbers[j]) * pow(hash_element, coefficients[j+1]))\n",
|
|
" \n",
|
|
" return return_values"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 41,
|
|
"id": "8395e9bd",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[0, 8, 14, 12]\n",
|
|
"[0, 8, 14, 12]\n",
|
|
"3\n",
|
|
"3\n",
|
|
"(64, 16102)\n",
|
|
"64\n",
|
|
"[21, 21, 3]\n",
|
|
"3\n",
|
|
"64\n",
|
|
"[6, 9, 6]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[5806, 32072, 38726]"
|
|
]
|
|
},
|
|
"execution_count": 41,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"coefficients = sample_coefficients(t)\n",
|
|
"print(coefficients)\n",
|
|
"res = participant_init(10)\n",
|
|
"print(alpha)\n",
|
|
"print(res)\n",
|
|
"keyholder_processing(res)\n",
|
|
"\n",
|
|
"def participant_2(keyholder_values):\n",
|
|
" intermediate_results = []\n",
|
|
" for i in keyholder_values:\n",
|
|
" intermediate_results.append(pow(i, alpha))\n",
|
|
" \n",
|
|
" # Paillier Encryption\n",
|
|
" encrypted_values = []\n",
|
|
" for i in intermediate_results:\n",
|
|
" encrypted_values.append(paillier_encrypt(i))\n",
|
|
" \n",
|
|
" return encrypted_values\n",
|
|
" \n",
|
|
" \n",
|
|
"participant_2(keyholder_processing(participant_init(10)))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "6cc33c78",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def keyholder_2(encrypted_values):\n",
|
|
" intermediate_values = []\n",
|
|
" for i in encrypted_values:\n",
|
|
" intermediate_values.append(i * )"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "dcb3185e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "SageMath 9.5",
|
|
"language": "sage",
|
|
"name": "sagemath"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.12"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|