Browse Source

Initial Commit

master
c01rowe 5 days ago
commit
e19faa6cd9
  1. 323
      Mahdavi_OT_MP_PSI.ipynb
  2. 168
      Shamir_Secret_Sharing.ipynb

323
Mahdavi_OT_MP_PSI.ipynb

@ -0,0 +1,323 @@
{
"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
}

168
Shamir_Secret_Sharing.ipynb

@ -0,0 +1,168 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "8a105f7c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 15, 12, 18]\n",
"18*x^3 + 12*x^2 + 15*x\n",
"share 1: 7\n",
"share 2: 13\n",
"share 3: 12\n",
"share 4: 17\n",
"share 5: 3\n",
"share 6: 2\n",
"[(1, 7), (2, 13), (3, 12), (4, 17), (5, 3), (6, 2)]\n",
"0\n",
"[0, 15, 12, 18]\n",
"0\n",
"0\n"
]
}
],
"source": [
"import hashlib\n",
"import random\n",
"\n",
"# Prime order of the finite field\n",
"q = 19\n",
"\n",
"Fq = GF(q)\n",
"R = PolynomialRing(Fq,\"x\")\n",
"\n",
"t = 4\n",
"m = 7\n",
"S = 0\n",
"\n",
"coefficients = []\n",
"coefficients.append(S)\n",
"for i in range(1, t):\n",
" coefficients.append(Fq.random_element())\n",
"\n",
"print(coefficients)\n",
"\n",
"f_x = R(coefficients)\n",
"print(f_x)\n",
"shares = []\n",
"for i in range(1, m):\n",
" print(f\"share {i}: {f_x(i)}\")\n",
" shares.append((i, f_x(i)))\n",
"\n",
"def secret_recovery(shares): \n",
" return sum([i[1] * prod([(0-j[0] * pow(i[0] - j[0], -1, q)) for j in shares[:t] if i[0] != j[0]]) for i in shares[:t]])\n",
"\n",
"S_man = 0\n",
"for i in shares[:t]:\n",
" im_prod = i[1]\n",
" for j in shares[:t]:\n",
" if j[0] != i[0]:\n",
" im_prod *= ((-j[0]) * pow(i[0] - j[0], -1, q)) % q\n",
" S_man += im_prod\n",
" \n",
"\n",
"print(shares)\n",
"S_sage = R.lagrange_polynomial(shares[:t])\n",
"print(S_sage[0])\n",
"print(coefficients)\n",
"print(S_man % q)\n",
"print(secret_recovery(shares[:t]))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e5c47c9d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Information Word a: \t[0, 15, 10, 13, 13, 17, 5, 2, 8, 12, 7]\n",
"Code Word D: \t\t[7, 9, 5, 9, 0, 2, 9, 1, 7, 16, 17, 12, 18, 6, 12, 11, 8, 3]\n",
"a_0: \t\t\t0\n",
"Manipulated Codeword: \t[6, 9, 5, 9, 0, 2, 9, 1, 7, 16, 16, 12, 18, 6, 12, 11, 8, 3]\n",
"a_0: \t\t\t2\n"
]
}
],
"source": [
"non_zero_elem_of_Fq = [x for x in Fq if x != 0]\n",
"k = 11\n",
"\n",
"information_word = []\n",
"information_word.append(S)\n",
"for _ in range(0, k-1):\n",
" information_word.append(Fq.random_element())\n",
"\n",
"print(f\"Information Word a: \\t{information_word}\")\n",
"\n",
"code_word = []\n",
"for i in range(0, q-1):\n",
" code_word.append(sum([information_word[j] * pow(non_zero_elem_of_Fq[i], j) for j in range(0, k)]))\n",
"\n",
"print(f\"Code Word D: \\t\\t{code_word}\")\n",
"\n",
"secret = -sum([code_word[d] for d in range(0, q-1)])\n",
"print(f\"a_0: \\t\\t\\t{secret}\")\n",
"\n",
"assert(secret == information_word[0] == S)\n",
"\n",
"manipulated_codeword = []\n",
"for i in range(0, len(code_word)):\n",
" if i % 10 == 0:\n",
" manipulated_codeword.append(code_word[i]-1 % q)\n",
" else:\n",
" manipulated_codeword.append(code_word[i])\n",
"\n",
"print(f\"Manipulated Codeword: \\t{manipulated_codeword}\")\n",
"\n",
"secret_man = -sum([manipulated_codeword[d] for d in range(0, q-1)])\n",
"print(f\"a_0: \\t\\t\\t{secret_man}\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cff95199",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "152ae6a0",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "SageMath 10.6",
"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.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading…
Cancel
Save