cryptotools/Cryptotools/Groups/group.py
2026-01-11 09:19:22 +01:00

125 lines
4.0 KiB
Python

#!/usr/bin/env python3
class Group:
"""
This class generate a group self._g based on the operation (here denoted +)
with the function ope: (a ** b) % n
In group theory, any group has an identity element (e), which with the binary operation, do not change the value and must satisfy the condition: $a + e = 0$
Attributes:
n (Integer): It's the G_n elements in the Group
g (List): The set of the Group
operation (Function): Function for generating the Group
identity (Integer): The identity of the group.
reverse (Dict): For each elements of the Group of n, we have the reverse value
"""
def __init__(self, n, g, ope):
self._n = n
self._g = g
self._operation = ope
self._identity = 0
self._reverse = dict()
def getG(self) -> list():
"""
This function return the Group
Returns:
List of all elements in the Group
"""
return self._g
def closure(self) -> bool:
"""
Check the closure law
In a group, each element a, b belongs to G, such as a + b belongs to G
Returns:
Return a Boolean if the closure law is respected. True if yes otherwise it's False
"""
for e1 in self._g:
for e2 in self._g:
res = self._operation(e1, e2, self._n)
if not res in self._g:
# raise Exception(f"{res} not in g. g is not a group")
return False
return True
def associative(self) -> bool:
"""
Check the associative law.
In a group, for any a, b and c belongs to G,
they must respect this condition: (a + b) + c = a + (a + b)
Returns:
Return a boolean if the Associative law is respected. True if yes otherwise it's False
"""
a = self._g[0]
b = self._g[1]
c = self._g[2]
res_ope = self._operation(a, b, self._n)
res1 = self._operation(res_ope, c, self._n)
res_ope = self._operation(b, c, self._n)
res2 = self._operation(a, res_ope, self._n)
if res1 != res2:
# raise Exception(f"{res1} is different from {res2}. g is not a group")
return False
return True
def identity(self) -> bool:
"""
Check the identity law.
In a group, an identity element exist and must be uniq
Returns:
Return a Boolean if the identity elements has been found. True if found otherwise it's False
"""
for a in self._g:
for b in self._g:
if not self._operation(a, b, self._n) == b:
break
self._identity = a
return True
return False
def getIdentity(self) -> int:
"""
Return the identity element. The function identitu() must be called before.
Returns:
Return the identity element if it has been found
"""
return self._identity
def reverse(self) -> bool:
"""
Check the inverse law
In a group, for each element belongs to G
they must have an inverse a ^ (-1) = e (identity)
Returns:
Return a Boolean if the all elements ha a reverse element. True if yes otherwise it's False
"""
reverse = False
for a in self._g:
for b in self._g:
if self._operation(a, b, self._n) == self._identity:
self._reverse[a] = b
reverse = True
break
return reverse
def getReverses(self) -> dict:
"""
This function return the dictionary of all reverses elements. The key is the element in G and the value is the reverse element
Returns:
Return the reverse dictionary
"""
return self._reverse