Проблема вычисления дискретного логарифма с использованием кода Python
У меня есть набор логарифмов L1, L2 и L3, который я получил из статьи "Ультра-безопасная система спонтанного обмена ключами между маршрутизаторами" (2015), здесь. Цель этой статьи - надежно разделить ключ между Алисой и Бобом. Например, Алиса отправила K = 46
Бобу. Боб получил ключ от Алисы. Ключ может быть представлен как:
![enter image description here]()
Ключ должен быть разделен с использованием трехэтапного процесса. L1: Алиса Бобу. L2: Боб Алисе. L3: Алиса Бобу. Уравнения:
![enter image description here]()
![enter image description here]()
![enter image description here]()
Боб может оценить ключ, используя: ![enter image description here]()
Это результат для уравнений: ![enter image description here]()
Учитывая значение alpha = 5
, x = 15
и p = 97
. После того, как я реализовал это в Python, я получил неправильный результат, который не совпадает с результатом в таблице:
a=5
x=15
p=97
i1=0.958478
i2=4.238835
L1=a**(x+i1)%p
L2=a**(x+i1+i2)%p
L3=a**(x+i2)%p
K=L3*(a**(-i2))
print ("L1",L1)
print ("L2",L2)
print ("L3",L3)
print ("K",K)
Которые дают этот результат:
L1 55.596893310546875
L2 2.15625
L3 68.87890625
K 0.07503566293789979
Другая проблема заключается в том, что я пытался вычислить его вручную, но результат все еще не совпадает с результатом в таблице. Я надеюсь, что кто-нибудь может мне помочь. Спасибо.
Ответы
Ответ 1
Конечно, при вычислении L2
Боб не будет иметь доступа к Алисе i1
, и Алиса не сможет использовать i2
для вычисления L3
. Однако для воспроизведения этих результатов это не имеет большого значения.
Насколько я могу судить, трудности, с которыми вы сталкиваетесь, не являются вашими собственными силами. Похоже, проблема в том, что конкретный алгоритм невероятно чувствителен к входным данным i1
и i2
, и авторы решили предоставлять их только с ограниченной точностью. Я проиллюстрирую, используя ваш пример кода, изменяя только i1
и i2
вокруг значений, которые вы предоставили, так что они все еще округляются до заданных значений (первая строка в таблице 1 статьи),
i1 i2 L1 L2 L3 K
0.9584775 4.2388345 50.82189941 44.171875 14.53515625 0.01583440
0.9584776 4.2388346 32.36941528 66.515625 62.78515625 0.06839727
0.9584777 4.2388347 13.92065430 6.187500 14.59765625 0.01590248
0.9584778 4.2388348 92.47598267 55.687500 64.30078125 0.07004834
0.9584779 4.2388349 74.03457642 21.765625 17.72656250 0.01931106
0.9584780 4.2388350 55.59689331 2.156250 68.87890625 0.07503566 # your result
0.9584781 4.2388351 37.16333008 92.375000 23.59765625 0.02570693
0.9584782 4.2388352 18.73303223 2.171875 76.20312500 0.08301453
0.9584783 4.2388353 0.30642700 23.296875 32.37109375 0.03526457
0.9584784 4.2388354 78.88394165 57.234375 86.42578125 0.09415091
Вывод кажется ясным: данные, приведенные в статье, кажутся недостаточными для воспроизведения результатов. Я предлагаю вам связаться с авторами и попытаться получить их код, данные и любые другие материалы, которые они могут иметь в отношении этой публикации.
Ответ 2
Указанный вами документ немного размыт. Пример, приведенный ниже, охватывает нефиксированные точки.
Вы не разделяете gm,pm
если хотите (как статическое определение или таблица).
Работа, которую вы делаете, важнее алгоритма. Не перепутайте basic
и improved
условия.
am=5 #Secret key of A node
bm=9 #Secret key of B node
gm=15 #Shared Base Number
pm=97 #Shared Modulos
A = (gm^am)%p #Shared key from A
B = (gm^bm)%p #Shared key from B
Ka = (A^bm) %p #Calculate Key wit A node Answer
Kb = (B^am)%p #Calculate Key wit B node Answer
print "Shared Key A:",A,"Shared Key B:",B
print "Node A key :",Ka,"Node B key :",Kb
NUMSA = [[i,(am**i)%p] for i in range(p) if i > 0]
NUMSB = [[i,(bm**i)%p] for i in range(p) if i > 0]
print NUMSA #ALL Numbers and means for A node
print NUMSB #ALL Numbers and means for B node
Что поэт хотел сказать здесь? Мне не нравится такая интерпретация.
Что ты понимаешь?
Я надеюсь, что это помогает.
Ответ 3
Не зная слишком много о криптовалютах, я бы предположил, что таблица в статье показывает округленные значения, т.е. не воспроизводится простым копированием значений, которые там записаны.
В качестве теста вы можете легко оставить первые 6 цифр i1
и i2
такими, как они есть в вашем примере скрипта, но добавьте несколько случайных цифр - и вы увидите, что с каждым новым Variation ваши значения Lx
будут переключаться между от того, что таблица показывает, до очень близко.
Пример:
import numpy as np
a=5
x=15
p=97
i1=0.958478
i2=4.238835
np.random.seed(1234)
for _ in range(3):
i1 += np.random.random()/1e7
i2 += np.random.random()/1e7
print(i1)
print(i2)
L1=a**(x+i1)%p
L2=a**(x+i1+i2)%p
L3=a**(x+i2)%p
K=L3*(a**(-i2))
print ("L1",L1)
print ("L2",L2)
print ("L3",L3)
print()
# 0.9584780191519451
# 4.238835062210877
# L1 89.90701293945312
# L2 6.828125
# L3 63.7265625
# 0.9584780629247189
# 4.238835140746736
# L1 56.760833740234375
# L2 91.6875
# L3 53.03515625
# 0.9584781409222998
# 4.238835168005997
# L1 28.248016357421875
# L2 73.265625
# L3 77.52734375
Ответ 4
хорошо, я нашел ошибку:
-
(a^(x+i2) % p) * a^(-i2) != a^(x+i2 -i2) % p
по модулю - Кроме того, вам не нужно 4 способа обмена, если a, x и p известны и если они неизвестны, они не могут отправлять сообщения.
Ответ 5
Я получил тот же ответ, что и вы, после того, как попробовал в Python, Java и сделал это с помощью калькулятора и бумаги (дольше, чем мне хотелось бы признать). Я написал одному из авторов статьи по электронной почте в надежде получить от них ответ. Если они ответят, я отредактирую этот ответ, чтобы включить их ответ! Пожалуйста, обновите свой оригинальный пост, если вы сами разберетесь, мне интересно, что я делаю неправильно.
Ответ 6
Мой знакомый друг по математике помог мне понять, что пошло не так. Ответы, которые вы получили, верны. Проблема со значениями, которые авторы дали для i1 и i2.
Одно дополнительное десятичное число полностью меняет результат операции mod p в этой части:
L1 = a ** (x + i1)% p В случае, если i1 равно 0,958478, на выходе получается: 55,596893310546875
Теперь, если вы добавите хотя бы один дополнительный 1 к концу значения для i1, что приведет к i1 0,9584781, выходное значение этого же уравнения станет совершенно другим числом: 37.163330078125
Если вы сравните алгоритм, чтобы определить, что K = L3 * a ** (-i2), используя заданный i2 из 4.238835, вы также быстро обнаружите, что результат не равен 46. Начальное значение K, рассчитанное с алгоритмом (a ** x)% p, равным 46, так что то, что вышеупомянутый алгоритм должен был оценить. Вместо этого результат этого уравнения с заданными значениями равен 0,05102662974.
Мой друг выдвинул теорию, основанную на том факте, что авторы сказали, что они используют Matlab. Matlab имеет функцию, которая позволяет пользователю ограничивать отображаемые десятичные разряды. Десятичные числа по-прежнему ведут себя в соответствии с их фактическим значением, но их представление на экране усекается до указанного десятичного знака. Для большинства операций это вполне нормально и окажет незначительное влияние на результаты расчетов. Тем не менее, при выполнении операции модуля, один 1, даже в младшем значащем десятичном знаке числа, может изменить все число.
Таким образом, мы предполагаем, что фактические значения i1 и i2 были усечены их настройками отображения в Matlab. Это не изменит правильности алгоритма, а также не помешает ему оценить правильное значение переменной K в конце операции. Все результаты использования полных десятичных значений i1 и i2 будут отображаться. Однако это также сделало бы невозможным воспроизведение всего процесса для кого-либо, используя те же цифры, которые Matlab показал нашим авторам во время расчета.