Мультипликативный обратный Python в конечном поле GF(2)
эти 2 функции выполняют расширенный евклидов алгоритм, а затем находят мультипликативный обратный. Порядок кажется правильным, но он не возвращается с тем, что я ожидаю в соответствии с этим инструментом от U Сиднея http://magma.maths.usyd.edu.au/calc/ и поскольку это делается в конечном поле GF(2), я думаю, что мне не хватает ключевого шага, который переводится из базы 10 в это поле.
Это было проверено и работало на базе 10, но с учетом многочленов с двоичным коэффициенты здесь могут быть невозможны. Поэтому мой вопрос заключается в том, какие части Python я неправильно применяю к этому алгоритму, например // floor, которые могут не переносить из того, что функция была способна в базе 10, чтобы иметь возможность сделать это в GF(2).
выше инструмента можно проверить так:
R<x>:=PolynomialRing(GF(2));
p:=x^13+x+1; q:=x^12+x;
g,r,s:=XGCD(p,q);
g eq r*p+s*q;
g,r,s;
функции:
def extendedEuclideanGF2(self,a,b): # extended euclidean. a,b are values 10110011... in integer form
inita,initb=a,b; x,prevx=0,1; y,prevy = 1,0
while b != 0:
q = int("{0:b}".format(a//b),2)
a,b = b,int("{0:b}".format(a%b),2);
x,prevx = (int("{0:b}".format(prevx-q*x)), int("{0:b}".format(x,2))); y,prevy=(prevy-q*y, y)
print("Euclidean %d * %d + %d * %d = %d" % (inita,prevx,initb,prevy,a))
return a,prevx,prevy # returns gcd of (a,b), and factors s and t
def modular_inverse(self,a,mod): # a,mod are integer values of 101010111... form
a,mod = prepBinary(a,mod)
bitsa = int("{0:b}".format(a),2); bitsb = int("{0:b}".format(mod),2)
#return bitsa,bitsb,type(bitsa),type(bitsb),a,mod,type(a),type(mod)
gcd,s,t = extendedEuclideanGF2(a,mod); s = int("{0:b}".format(s))
initmi = s%mod; mi = int("{0:b}".format(initmi))
print ("M Inverse %d * %d mod %d = 1"%(a,initmi,mod))
if gcd !=1: return mi,False
return mi # returns modular inverse of a,mod
Я тестировал с полиномами, как это, но в двоичном виде, конечно:
p = "x**13 + x**1 + x**0"
q = "x**12 + x**1"
1 ответов
функция работала при тестировании с base-10, потому что все ваши преобразования int("{0:b}".format(x))
не влияют на x:
37 == int("{0:b}".format(37), 2) # >>> True
объекты Number в python являются базовыми-10. Преобразование чисел в двоичные строки, а затем обратно в целые числа, не имеет никакого эффекта. Вот альтернативная версия вашей функции, которая должна работать на a
и b
as base-10 ints и вернуть их в двоичном формате. Вы можете удалить bin()
функция возвращает числа в 10, или использовать что-то вроде lambda x: int("%d".format(x))
преобразование a
и b
из двоичной в десятичную в первой строке функции.
def extendedEuclideanGF2(a, b): # extended euclidean. a,b are values 10110011... in integer form
inita, initb = a, b # if a and b are given as base-10 ints
x, prevx = 0, 1
y, prevy = 1, 0
while b != 0:
q = a//b
a, b = b, a%b
x, prevx = prevx - q*x, x
y, prevy = prevy - q*y, y
print("Euclidean %d * %d + %d * %d = %d" % (inita, prevx, initb, prevy, a))
i2b = lambda n: int("{0:b}".format(n)) # convert decimal number to a binary value in a decimal number
return i2b(a), i2b(prevx), i2b(prevy) # returns gcd of (a,b), and factors s and t
все, что сказано, Не используйте lambdas в такой функции - я бы предложил написать вашу программу, чтобы избежать использования двоичного файла вообще, что вы можете сделать, только конвертируя из/в двоичный файл на интерфейсе вашей программы с исходными данными.