137 lines
4.6 KiB
Text
137 lines
4.6 KiB
Text
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[alice]: private: 895 -> public: 308\n",
|
|
"[bob]: private: 804 -> public: 801\n",
|
|
"[alice|bob] generated equal shared keys\n",
|
|
"[alice] sent message 'Hello world' to bob\n",
|
|
"[bob] received message 'Hello world' from alice\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from fractions import Fraction\n",
|
|
"import random\n",
|
|
"from dataclasses import dataclass\n",
|
|
"from sympy.ntheory.residue_ntheory import nthroot_mod\n",
|
|
"from itertools import cycle\n",
|
|
"\n",
|
|
"@dataclass \n",
|
|
"class ec:\n",
|
|
" a: int\n",
|
|
" b: int\n",
|
|
" p: int\n",
|
|
"\n",
|
|
" def ec_add(self, p1, p2):\n",
|
|
" if all(v1 == v2 for v1, v2 in zip(p1, p2)):\n",
|
|
" #print(\"H\")\n",
|
|
" if self.p:\n",
|
|
" dy = Fraction((3*p1[0]**2 + self.a), 2*p1[1])\n",
|
|
" else:\n",
|
|
" dy =(3*p1[0]**2 + self.a) / (2*p1[1])\n",
|
|
" else:\n",
|
|
" if self.p:\n",
|
|
" dy = Fraction((p2[1] - p1[1]), (p2[0] - p1[0]))\n",
|
|
" else:\n",
|
|
" dy = (p2[1] - p1[1]) / (p2[0] - p1[0])\n",
|
|
" res_x = dy ** 2 - p1[0] - p2[0]\n",
|
|
" res_y = (dy * (p1[0] - res_x) - p1[1])\n",
|
|
" if self.p != None:\n",
|
|
" res_x = int(res_x % self.p) \n",
|
|
" res_y = int(res_y % self.p) \n",
|
|
" return (res_x, res_y)\n",
|
|
" return (float(res_x), float(res_y))\n",
|
|
" def ec_mul(self, p, s):\n",
|
|
" for _ in range(s):\n",
|
|
" p = self.ec_add(p, p)\n",
|
|
" return p\n",
|
|
" def __getitem__(self, pos):\n",
|
|
" x = pos[0]\n",
|
|
" x_given = type(x) != slice\n",
|
|
" if x_given: value = x**3+self.a*x+self.b\n",
|
|
" else: raise ValueError()\n",
|
|
" solutions = [(x % self.p, s) for s in nthroot_mod(value, 2, self.p, True)]\n",
|
|
" return solutions\n",
|
|
" \n",
|
|
"@dataclass\n",
|
|
"class Person:\n",
|
|
" name: str \n",
|
|
" private: tuple[int, int] \n",
|
|
" public: tuple[int, int] \n",
|
|
" shared: tuple[int, int] \n",
|
|
"\n",
|
|
" def gen_keys(self, start, curve: ec):\n",
|
|
" self.private = random.randint(0, curve.p)\n",
|
|
" self.public = curve.ec_mul(start, self.private)\n",
|
|
" print(f\"[{self.name}]: private: {self.private} -> public: {self.public[1]}\")\n",
|
|
" return \n",
|
|
" \n",
|
|
" def gen_shared(self, public, curve: ec):\n",
|
|
" self.shared = curve.ec_mul(public, self.private)\n",
|
|
" return\n",
|
|
" \n",
|
|
" def diffie_hellman(curve: ec, alice, bob):\n",
|
|
" gen = (4, 10)\n",
|
|
" alice.gen_keys(gen, curve)\n",
|
|
" bob.gen_keys(gen, curve)\n",
|
|
" alice.gen_shared(bob.public, curve)\n",
|
|
" bob.gen_shared(alice.public, curve)\n",
|
|
" assert(alice.shared == bob.shared)\n",
|
|
" print(f\"[{alice.name}|{bob.name}] generated equal shared keys\")\n",
|
|
"\n",
|
|
" def xor(data, key): \n",
|
|
" key = str(key)\n",
|
|
" data = data.encode() if isinstance(data, str) else data\n",
|
|
" key = key.encode() if isinstance(key, str) else key\n",
|
|
" return bytearray(a ^ b for a, b in zip(data, cycle(key)))\n",
|
|
"\n",
|
|
" def send(self, msg, target):\n",
|
|
" encrypted = Person.xor(msg, self.shared[1])\n",
|
|
" print(f\"[{self.name}] sent message '{msg}' to {target.name}\")\n",
|
|
" target.recv(encrypted, self)\n",
|
|
"\n",
|
|
" def recv(self, msg, source):\n",
|
|
" decrypted = str(Person.xor(msg, self.shared[1]), encoding='utf-8')\n",
|
|
" print(f\"[{self.name}] received message '{decrypted}' from {source.name}\")\n",
|
|
"\n",
|
|
" \n",
|
|
"if __name__ == \"__main__\":\n",
|
|
" curve = ec(0, 7, 1109)\n",
|
|
" alice = Person(\"alice\", 0, 0, 0)\n",
|
|
" bob = Person(\"bob\", 0, 0, 0)\n",
|
|
"\n",
|
|
" Person.diffie_hellman(curve, alice, bob)\n",
|
|
" alice.send(\"Hello world\", bob)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "3.10.15",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"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.15"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|