initial commit
This commit is contained in:
parent
20a4478f77
commit
f377305f49
184
.gitignore
vendored
Normal file
184
.gitignore
vendored
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Python template
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
env/
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*,cover
|
||||||
|
.hypothesis/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# IPython Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# dotenv
|
||||||
|
.env
|
||||||
|
|
||||||
|
# virtualenv
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
### VirtualEnv template
|
||||||
|
# Virtualenv
|
||||||
|
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
|
||||||
|
[Bb]in
|
||||||
|
[Ii]nclude
|
||||||
|
[Ll]ib
|
||||||
|
[Ll]ib64
|
||||||
|
[Ll]ocal
|
||||||
|
[Ss]cripts
|
||||||
|
pyvenv.cfg
|
||||||
|
.venv
|
||||||
|
pip-selfcheck.json
|
||||||
|
|
||||||
|
### JetBrains template
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
# idea folder, uncomment if you don't need it
|
||||||
|
.idea
|
262
lib/gcd_tables.py
Normal file
262
lib/gcd_tables.py
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
'''
|
||||||
|
Source: extendedeuclideanalgorithm.com
|
||||||
|
|
||||||
|
Modified to generate CSV tables
|
||||||
|
for iterative calculation of the modular inverse
|
||||||
|
'''
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
# Warning: can't handle b=0. See extendedeuclideanalgorithm.com/code for a version that can
|
||||||
|
def gcd_iterative(a, b):
|
||||||
|
""" Calculating the greatest common divisor
|
||||||
|
using the Euclidean Algorithm (non-recursive)
|
||||||
|
(Source: extendedeuclideanalgorithm.com/code)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Set default values for the quotient and the remainder
|
||||||
|
q = 0
|
||||||
|
r = 1
|
||||||
|
|
||||||
|
'''
|
||||||
|
In each iteration of the loop below, we
|
||||||
|
calculate the new quotient, remainder, a and b.
|
||||||
|
r decreases, so we stop when r = 0
|
||||||
|
'''
|
||||||
|
while (r > 0):
|
||||||
|
# The calculations
|
||||||
|
q = math.floor(a / b)
|
||||||
|
r = a - q * b
|
||||||
|
|
||||||
|
# The values for the next iteration
|
||||||
|
a = b
|
||||||
|
b = r if (r > 0) else b
|
||||||
|
|
||||||
|
return abs(b)
|
||||||
|
|
||||||
|
|
||||||
|
# Can handle b=0
|
||||||
|
def gcd_iterative_2(a, b):
|
||||||
|
""" Calculating the greatest common divisor
|
||||||
|
using the Euclidean Algorithm (non-recursive)
|
||||||
|
(Source: extendedeuclideanalgorithm.com/code)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Set default values for the quotient and the remainder
|
||||||
|
q = 0
|
||||||
|
r = 1
|
||||||
|
|
||||||
|
'''
|
||||||
|
In each iteration of the loop below, we
|
||||||
|
calculate the new quotient, remainder, a and b.
|
||||||
|
r decreases, so we stop when r = 0
|
||||||
|
'''
|
||||||
|
while (b > 0):
|
||||||
|
# The calculations
|
||||||
|
q = math.floor(a / b)
|
||||||
|
r = a - q * b
|
||||||
|
|
||||||
|
# The values for the next iteration
|
||||||
|
a = b
|
||||||
|
b = r
|
||||||
|
|
||||||
|
return abs(a)
|
||||||
|
|
||||||
|
|
||||||
|
def gcd(a, b):
|
||||||
|
""" Calculating the greatest common divisor
|
||||||
|
using the Euclidean Algorithm (recursive)
|
||||||
|
(Source: extendedeuclideanalgorithm.com/code)
|
||||||
|
"""
|
||||||
|
if (b == 0):
|
||||||
|
return abs(a)
|
||||||
|
|
||||||
|
q = math.floor(a / b)
|
||||||
|
r = a - q * b
|
||||||
|
return abs(b) if (r == 0) else gcd(b, r)
|
||||||
|
|
||||||
|
|
||||||
|
# Warning: this version can't handle b=0. See extendedeuclideanalgorithm.com/code for a version that can.
|
||||||
|
def xgcd_iterative(a, b):
|
||||||
|
""" Calculates the gcd and Bezout coefficients,
|
||||||
|
using the Extended Euclidean Algorithm (non-recursive).
|
||||||
|
(Source: extendedeuclideanalgorithm.com/code)
|
||||||
|
"""
|
||||||
|
# Set default values for the quotient, remainder,
|
||||||
|
# s-variables and t-variables
|
||||||
|
q = 0
|
||||||
|
r = 1
|
||||||
|
s1 = 1
|
||||||
|
s2 = 0
|
||||||
|
s3 = 1
|
||||||
|
t1 = 0
|
||||||
|
t2 = 1
|
||||||
|
t3 = 0
|
||||||
|
|
||||||
|
'''
|
||||||
|
In each iteration of the loop below, we
|
||||||
|
calculate the new quotient, remainder, a, b,
|
||||||
|
and the new s-variables and t-variables.
|
||||||
|
r decreases, so we stop when r = 0
|
||||||
|
'''
|
||||||
|
while (r > 0):
|
||||||
|
# The calculations
|
||||||
|
q = math.floor(a / b)
|
||||||
|
r = a - q * b
|
||||||
|
s3 = s1 - q * s2
|
||||||
|
t3 = t1 - q * t2
|
||||||
|
|
||||||
|
'''
|
||||||
|
The values for the next iteration,
|
||||||
|
(but only if there is a next iteration)
|
||||||
|
'''
|
||||||
|
if (r > 0):
|
||||||
|
a = b
|
||||||
|
b = r
|
||||||
|
s1 = s2
|
||||||
|
s2 = s3
|
||||||
|
t1 = t2
|
||||||
|
t2 = t3
|
||||||
|
|
||||||
|
return abs(b), s2, t2
|
||||||
|
|
||||||
|
|
||||||
|
# Can handle b=0
|
||||||
|
def xgcd_iterative_2(a, b):
|
||||||
|
""" Calculates the gcd and Bezout coefficients,
|
||||||
|
using the Extended Euclidean Algorithm (non-recursive).
|
||||||
|
(Source: extendedeuclideanalgorithm.com/code)
|
||||||
|
"""
|
||||||
|
# Set default values for the quotient, remainder,
|
||||||
|
# s-variables and t-variables
|
||||||
|
q = 0
|
||||||
|
r = 1
|
||||||
|
s1 = 1
|
||||||
|
s2 = 0
|
||||||
|
s3 = 1
|
||||||
|
t1 = 0
|
||||||
|
t2 = 1
|
||||||
|
t3 = 0
|
||||||
|
|
||||||
|
'''
|
||||||
|
In each iteration of the loop below, we
|
||||||
|
calculate the new quotient, remainder, a, b,
|
||||||
|
and the new s-variables and t-variables.
|
||||||
|
r decreases, so we stop when r = 0
|
||||||
|
'''
|
||||||
|
|
||||||
|
# CSV output
|
||||||
|
print("i, n, b, q, r, t1, t2, t3")
|
||||||
|
i = 1
|
||||||
|
|
||||||
|
while (b > 0):
|
||||||
|
# The calculations
|
||||||
|
q = math.floor(a / b)
|
||||||
|
r = a - q * b
|
||||||
|
s3 = s1 - q * s2
|
||||||
|
t3 = t1 - q * t2
|
||||||
|
|
||||||
|
# CSV output
|
||||||
|
print("{}, {}, {}, {}, {}, {}, {}, {}".format(i, a, b, q, r, t1, t2, t3))
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
'''
|
||||||
|
The values for the next iteration,
|
||||||
|
(but only if there is a next iteration)
|
||||||
|
'''
|
||||||
|
|
||||||
|
a = b
|
||||||
|
b = r
|
||||||
|
s1 = s2
|
||||||
|
s2 = s3
|
||||||
|
t1 = t2
|
||||||
|
t2 = t3
|
||||||
|
|
||||||
|
return abs(a), s1, t1
|
||||||
|
|
||||||
|
|
||||||
|
def xgcd(a, b, s1=1, s2=0, t1=0, t2=1):
|
||||||
|
""" Calculates the gcd and Bezout coefficients,
|
||||||
|
using the Extended Euclidean Algorithm (recursive).
|
||||||
|
(Source: extendedeuclideanalgorithm.com/code)
|
||||||
|
"""
|
||||||
|
if (b == 0):
|
||||||
|
return abs(a), 1, 0
|
||||||
|
|
||||||
|
q = math.floor(a / b)
|
||||||
|
r = a - q * b
|
||||||
|
s3 = s1 - q * s2
|
||||||
|
t3 = t1 - q * t2
|
||||||
|
|
||||||
|
# if r==0, then b will be the gcd and s2, t2 the Bezout coefficients
|
||||||
|
return (abs(b), s2, t2) if (r == 0) else xgcd(b, r, s2, s3, t2, t3)
|
||||||
|
|
||||||
|
|
||||||
|
def multinv(b, n):
|
||||||
|
"""
|
||||||
|
Calculates the multiplicative inverse of a number b mod n,
|
||||||
|
using the Extended Euclidean Algorithm. If b does not have a
|
||||||
|
multiplicative inverse mod n, then throw an exception.
|
||||||
|
(Source: extendedeuclideanalgorithm.com/code)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get the gcd and the second Bezout coefficient (t)
|
||||||
|
# from the Extended Euclidean Algorithm. (We don't need s)
|
||||||
|
my_gcd, _, t = xgcd(n, b)
|
||||||
|
|
||||||
|
# It only has a multiplicative inverse if the gcd is 1
|
||||||
|
if (my_gcd == 1):
|
||||||
|
return t % n
|
||||||
|
else:
|
||||||
|
raise ValueError('{} has no multiplicative inverse modulo {}'.format(b, n))
|
||||||
|
|
||||||
|
|
||||||
|
def make_eea_table(a : int, b : int):
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Euclidean algorithm:
|
||||||
|
see the output of gcd(a, b)
|
||||||
|
'''
|
||||||
|
print('Euclidean Algorithm:')
|
||||||
|
print('The gcd of', a, 'and', b, 'is', gcd(a, b))
|
||||||
|
|
||||||
|
# -------------------------------------------------------------
|
||||||
|
|
||||||
|
'''
|
||||||
|
Extended Euclidean Algorithm:
|
||||||
|
see the output of xgcd(a,b) and Bezout coefficients
|
||||||
|
And verify that they are correct
|
||||||
|
'''
|
||||||
|
my_gcd, s, t = xgcd(a, b)
|
||||||
|
verification = abs(s * a + t * b)
|
||||||
|
print('Extended Euclidean Algorithm:')
|
||||||
|
print('The gcd of', a, 'and', b, 'is', my_gcd)
|
||||||
|
print('And the Bezout coefficients: s=', s, ' and t=', t, '.', sep='')
|
||||||
|
print('And', s, '*', a, '+', t, '*', b, '=', verification)
|
||||||
|
if (my_gcd == verification):
|
||||||
|
print('So as we expect, s*a+t*b is equal to the gcd we found.')
|
||||||
|
else:
|
||||||
|
print('Something went wrong')
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
b = b
|
||||||
|
n = a
|
||||||
|
|
||||||
|
'''
|
||||||
|
Multiplicative Inverse:
|
||||||
|
Try to compute the multiplicative inverse of b mod n.
|
||||||
|
If that succeeds, verify that it's correct.
|
||||||
|
If it doesn't succeed, show the error raised by the function.
|
||||||
|
'''
|
||||||
|
|
||||||
|
print('Multiplicative inverse:')
|
||||||
|
try:
|
||||||
|
# inverse = multinv(b, n);
|
||||||
|
inverse = xgcd_iterative_2(b, n)
|
||||||
|
|
||||||
|
except ValueError as error:
|
||||||
|
print(error)
|
||||||
|
|
||||||
|
|
10
make_eea_takes.py
Normal file
10
make_eea_takes.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from lib.gcd_tables import *
|
||||||
|
|
||||||
|
|
||||||
|
def check():
|
||||||
|
make_eea_table(7, 143)
|
||||||
|
|
||||||
|
|
||||||
|
# Press the green button in the gutter to run the script.
|
||||||
|
if __name__ == '__main__':
|
||||||
|
check()
|
60
shanks_baby_giant_step.py
Normal file
60
shanks_baby_giant_step.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from math import ceil, sqrt
|
||||||
|
|
||||||
|
def bsgs(p, g, h):
|
||||||
|
##Berechne d in h = g^d mod p
|
||||||
|
|
||||||
|
N = ceil(sqrt(p - 1)) # phi(p) is p-1 if p is prime
|
||||||
|
|
||||||
|
# Baby step: compute a look-up table of g^i values for i = 0, 1, ..., N
|
||||||
|
lookup_table = {pow(g, i, p): i for i in range(N)}
|
||||||
|
|
||||||
|
# Precompute via Fermat's Little Theorem
|
||||||
|
c = pow(g, N * (p - 2), p)
|
||||||
|
|
||||||
|
# Giant step: Search for an equivalence in the lookup_table
|
||||||
|
for j in range(N):
|
||||||
|
y = (h * pow(c, j, p)) % p
|
||||||
|
if y in lookup_table:
|
||||||
|
return j * N + lookup_table[y]
|
||||||
|
|
||||||
|
# Solution not found
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
p = 27893
|
||||||
|
g = 3729
|
||||||
|
alpha = 11819
|
||||||
|
beta = 1531
|
||||||
|
|
||||||
|
# Find the discrete logarithm a such that g^a = alpha mod p
|
||||||
|
a = bsgs(p, g, alpha)
|
||||||
|
print(f"a = {a}")
|
||||||
|
|
||||||
|
# Validate the result
|
||||||
|
if a is None:
|
||||||
|
print("No solution found for a")
|
||||||
|
else:
|
||||||
|
# Recompute the shared secret key: K = beta^a mod p
|
||||||
|
K = pow(beta, a, p)
|
||||||
|
print(f"Shared secret key K = {K}")
|
||||||
|
|
||||||
|
# Find the discrete logarithm b such that g^b = beta mod p
|
||||||
|
b = bsgs(p, g, beta)
|
||||||
|
print(f"b = {b}")
|
||||||
|
|
||||||
|
# Validate the result
|
||||||
|
if b is None:
|
||||||
|
print("No solution found for b")
|
||||||
|
else:
|
||||||
|
# Recompute the shared secret key: K = alpha^b mod p
|
||||||
|
K2 = pow(alpha, b, p)
|
||||||
|
if K2 == K:
|
||||||
|
print("b is correct")
|
||||||
|
else:
|
||||||
|
print("b is not correct")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user