This commit is contained in:
lda committed 2026-03-05 05:27:15 +07:00
1 parent c91740669a
commit b07c85e8cb
1 file changed
+50
+50
View File
@@ -0,0 +1,50 @@
import math
class Elgamal:
def __init__(self, p: int, alpha: int, d: int) -> None:
"contract: p is prime, and"
if not 0 <= alpha < p or math.gcd(alpha, p) != 1:
# set Z*_n is all i [0, n) st gcd(i, n) = 1, if n is prime thats jus the whole thing
raise ValueError()
if not 2 <= d <= p - 2:
raise ValueError()
self.p, self.alpha, self.d = p, alpha, d
self.beta = pow(alpha, d, p)
@property
def pubkey(self):
return (self.p, self.alpha, self.beta)
@property
def privkey(self):
return self.d
def sig_gen(self, x: int, ke: int) -> tuple[int, int]:
if not 2 <= ke <= self.p - 2 or math.gcd(ke, self.p - 1) != 1:
raise ValueError()
r = pow(self.alpha, ke, self.p)
kei = pow(ke, -1, self.p - 1) # mod p - 1
s = ((x - self.d * r) * kei) % (self.p - 1)
return r, s
@staticmethod
def sig_verify(x: int, rs: tuple[int, int], pab: tuple[int, int, int]) -> bool:
r, s = rs
p, alpha, beta = pab
t = (pow(beta, r, p) * pow(r, s, p)) % p
return (t - pow(alpha, x, p)) % p == 0
def main():
bob = Elgamal(29, 2, 12)
assert bob.beta % 29 == 7
r, s = bob.sig_gen(26, 5)
assert r % 29 == 3, f"{r = }"
assert s % 28 == 26, f"{s = }"
assert Elgamal.sig_verify(26, (r, s), bob.pubkey)
if __name__ == "__main__":
main()