From 692951d34c8969e959b92eedb5310c8858b790f6 Mon Sep 17 00:00:00 2001 From: Gerald Teschl Date: Tue, 12 Nov 2024 15:28:12 +0100 Subject: [PATCH] Small bugs in ec --- doc/kryptools.ipynb | 107 +++++++++++++++++++++++++------------------- kryptools/ec.py | 10 ++++- tests/test_ec.py | 2 +- 3 files changed, 72 insertions(+), 47 deletions(-) diff --git a/doc/kryptools.ipynb b/doc/kryptools.ipynb index ae3c28f..12d9a40 100644 --- a/doc/kryptools.ipynb +++ b/doc/kryptools.ipynb @@ -462,15 +462,44 @@ }, { "cell_type": "markdown", - "id": "a027ad19-3b29-4f24-9744-713e65e78dfa", + "id": "ce4e2e80-38b0-48dd-99ad-32fbb2312203", "metadata": {}, "source": [ - "For convenience, the AES Galois field is also available as `GF2_aes`. It has an additional mehtod for applying the AES sbox (to get the inverse sbox, use the option `inv=True`):" + "Elements from $\\mathrm{GF}(2^n)$ can be convertet to `int`, `bytes`, or to a polynomial (see the `Poly` class below):" ] }, { "cell_type": "code", "execution_count": 16, + "id": "184a5c32-0ce6-47a5-87b7-6f5478e18886", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "x^4 + x^2 + 1" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "_.poly()" + ] + }, + { + "cell_type": "markdown", + "id": "a027ad19-3b29-4f24-9744-713e65e78dfa", + "metadata": {}, + "source": [ + "For convenience, the AES Galois field is also available as `GF2_aes`. It has an additional method for applying the AES sbox (to get the inverse sbox, use the option `inv=True`):" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "id": "6dfd72e4-3fe5-43c3-a9aa-61df75f7e6f4", "metadata": {}, "outputs": [ @@ -480,7 +509,7 @@ "63" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -491,17 +520,25 @@ "GF2_aes(0).sbox()" ] }, + { + "cell_type": "markdown", + "id": "ee4f4390-7846-4fa0-b77a-bc1b33af8ac2", + "metadata": {}, + "source": [ + "### Showcase: Ghash" + ] + }, { "cell_type": "markdown", "id": "8dcc1f27-e264-4846-8eb4-d7c96a53dd51", "metadata": {}, "source": [ - "For [Ghash](https://en.wikipedia.org/wiki/Galois/Counter_Mode) the polynomial is $1 + x + x^2 + x^7 + x^{128}$. Can explicitely define the corresponding Galois filed using" + "For [Ghash](https://en.wikipedia.org/wiki/Galois/Counter_Mode) the polynomial is $1 + x + x^2 + x^7 + x^{128}$. You can explicitely define the corresponding Galois filed using" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "id": "cdff9c2d-b22e-479c-acd0-f36c5a943b5a", "metadata": {}, "outputs": [], @@ -519,7 +556,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "id": "78ed0971-22bf-40b0-aad2-27bde4825ca1", "metadata": {}, "outputs": [ @@ -529,7 +566,7 @@ "b'\\xcc\\x16\\x99\\x1d\\x8d`\\xadu\\xc9+\\xe1,\\x98\\x13j\\x17'" ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -556,35 +593,6 @@ "ghash(text, h)" ] }, - { - "cell_type": "markdown", - "id": "4aca5ed1-4fc0-4c4c-9467-9ef6b44a7e03", - "metadata": {}, - "source": [ - "Elements from $\\mathrm{GF}(2^n)$ can be convertet to `int`, `bytes`, or to a polynomial (see the `Poly` class below):" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "5adf3be1-b00a-4339-a335-4e6bd86cbf8b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "x" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "gf(1 << 126).poly()" - ] - }, { "cell_type": "markdown", "id": "a6d87a55-5338-49d5-92cf-d273f248de58", @@ -816,11 +824,12 @@ "metadata": {}, "outputs": [], "source": [ - "from kryptools import is_safeprime, random_safeprime\n", + "from kryptools import is_safeprime, random_safeprime, order\n", "\n", "p = random_safeprime(128)\n", "assert is_safeprime(p)\n", - "assert p.bit_length() == 128" + "assert p.bit_length() == 128\n", + "assert order(2, p) == (p - 1) // 2" ] }, { @@ -1218,7 +1227,7 @@ "id": "f65b39b9-8ca2-4d18-b895-d101efcd7092", "metadata": {}, "source": [ - "### Asmuth-Bloom scheme" + "### Showcase: Asmuth-Bloom scheme" ] }, { @@ -2505,7 +2514,7 @@ "id": "0d523353-9d2f-4ffe-b6f0-5dedde19f8f7", "metadata": {}, "source": [ - "### GGH cryptosystem" + "### Showcase: GGH cryptosystem" ] }, { @@ -3130,7 +3139,7 @@ "id": "09aad163-7b1a-4804-b556-d4bb65630355", "metadata": {}, "source": [ - "### AES" + "### Showcase: AES" ] }, { @@ -3597,7 +3606,7 @@ "id": "15b5e705-0d1a-40b0-b6d4-84c7c037f135", "metadata": {}, "source": [ - "### NTRU" + "### Showcase: NTRU" ] }, { @@ -3688,7 +3697,7 @@ "id": "1c412818-aee2-42b8-a4b5-a6e9f3fb44b5", "metadata": {}, "source": [ - "### Kyber" + "### Showcase: Kyber" ] }, { @@ -3952,7 +3961,7 @@ "source": [ "P = ec.random()\n", "Q = ec.random()\n", - "O = ec(None, None) # point at infinity\n", + "O = ec.inf() # point at infinity\n", "P + Q" ] }, @@ -4061,7 +4070,15 @@ "source": [ "k = 12\n", "R = k * Q\n", - "assert R.dlog(Q) == k" + "assert R.dlog(Q) == k % Q.order()" + ] + }, + { + "cell_type": "markdown", + "id": "c1808758-ca5f-468d-b69f-1cbb8e86e30c", + "metadata": {}, + "source": [ + "### Showcase: Bitcoin curve" ] }, { diff --git a/kryptools/ec.py b/kryptools/ec.py index d3eee09..11a951c 100644 --- a/kryptools/ec.py +++ b/kryptools/ec.py @@ -67,7 +67,7 @@ def __call__(self, x: int | str | None = None, y: int | None = None, short: bool return ECPoint(x, y, self, short) def __iter__(self): - yield ECPoint(None, None, self) + yield self.inf() for x in range(self.p): y2 = int(x**3 + self.a * x + self.b) y = sqrt_mod(y2, self.p) @@ -89,6 +89,10 @@ def __contains__(self, P: "ECPoint") -> bool: return True return P.y**2 == P.x**3 + self.a * P.x + self.b + def inf(self): + "Point at infinity" + return ECPoint(None, None, self) + def info(self): "Display some basic info on the curve" out = "Weierstrass curve y^2 = x^3" @@ -125,6 +129,8 @@ def dbl(self, x, y): def mult(self, j: int, x, y): # Addition-subtraction ladder "Point multiplication" + if x is None: + return None, None if j == 0: return None, None if j < 0: @@ -343,6 +349,8 @@ def __neg__(self) -> "ECPoint": def order(self) -> int: """Compute the order of an element.""" + if self.x is None: + return 1 self.curve.factor_order() # Make sure the factorization is available order = self.curve.group_order for p, k in self.curve.group_order_factors.items(): diff --git a/tests/test_ec.py b/tests/test_ec.py index 2043d51..dd1c0db 100644 --- a/tests/test_ec.py +++ b/tests/test_ec.py @@ -6,7 +6,7 @@ def test_EC(): ec = EC_Weierstrass(239, 3, 1) - O = ec(None, None) # point at infinity + O = ec.inf() # point at infinity assert O in ec P = ec.random() assert P in ec