【密码学】Diffie–Hellman Key Exchange

本程序演示如下过程:
在这里插入图片描述

# ============================================================================
# Copyright (c) 2021 Zhou Jin, Shandong University. All rights reserved.
# Elgamal.py - The core part of this algorithm
# Last edited time: 2021/11/3 15:48
#
# THIS PROGRAM IS FREE SOFTWARE
# If you have any question, email elford@foxmail.com
# ============================================================================

import random


# Find the greatest common divisor
def gcd(a, b):
    if a < b:
        return gcd(b, a)
    elif a % b == 0:
        return b
    else:
        return gcd(b, a % b)


# Quick power & modulo
def power(a, b, c):
    ans = 1
    while b != 0:
        if b & 1:
            ans = (ans * a) % c
        b >>= 1
        a = (a * a) % c
    return ans


# Detection of large prime numbers
def Miller_Rabin(n):
    a = random.randint(2, n - 2)  # Randomly find 'a' which is belong to [2,n-2]
    s = 0  # S is the power of factor 2 in d
    d = n - 1
    while (d & 1) == 0:  # Let's factor out all the 2's in d.
        s += 1
        d >>= 1

    x = power(a, d, n)
    for i in range(s):  # Perform s secondary probes
        newX = power(x, 2, n)
        if newX == 1 and x != 1 and x != n - 1:
            return False  # Using the inverse of the quadratic theorem, n is determined to be composite.
        x = newX

    if x != 1:  # If x=a^(n-1) (mod n), then n is determined to be composite.
        return False

    return True  # Judge by the converse of Fermat's little theorem. The number that survives this test
    # is most likely prime.


# Extended Euclidean algorithm, ab=1 (mod m), yields the multiplicative inverse b of A under module m
def Extended_Eulid(a: int, m: int) -> int:
    def extended_eulid(a: int, m: int):
        if a == 0:  # boundary condition
            return 1, 0, m
        else:
            x, y, gcd = extended_eulid(m % a, a)  # recursion
            x, y = y, (x - (m // a) * y)  # Recursively, the left end is the upper layer
            return x, y, gcd  # Returns the result of the first level calculation.
        # The final return y value is the multiplication inverse of b in mode a
        # If y is complex, y plus a is the corresponding positive inverse

    n = extended_eulid(a, m)
    if n[1] < 0:
        return n[1] + m
    else:
        return n[1]


# Generate the field parameter alpha
def Generate_alpha(p: int) -> int:
    return random.randint(2, p)


# Generate a prime number less than p, approximately 512bits long, as the private key
def Generate_private_key(p: int) -> int:
    pri = random.randint(2, p - 2)
    while gcd(pri, p) != 1:
        pri = random.randint(2, p - 2)
    return pri


# Bob or Alice uses the field parameter P and the resulting mask to encrypt the message
def encrypt(message, p, Key_mask) -> int:
    ciphertext = (message * Key_mask) % p
    return ciphertext


# Bob or Alice decrypts the ciphertext using the field parameter P and the masks obtained by them
def decrypt(ciphertext, p, Key_mask):
    # Inverse mask
    inverse_element = Extended_Eulid(Key_mask, p)
    # Decode
    plaintext = (ciphertext * inverse_element) % p
    return plaintext


def quick_power(a: int, b: int) -> int:
    ans = 1
    while b != 0:
        if b & 1:
            ans = ans * a
        b >>= 1
        a = a * a
    return ans



if __name__ == '__main__':

    print("Message: ")
    message = int(input())
    if type(message) != int:
        raise ValueError("Must be an integer!")

    p = 11483166658585481347156601461652228747628274304826764495442296421425015253161813634115028572768478982068325434874240950329795338367115426954714853905429627
    alpha = 9312361210673900259563710385567927129060681135208816314239276128613236057152973946513124497622387244317947113336161405537229616593187205949777328006346729

    # Alice selects her own private key, calculates her own public key, and passes the public key to Bob
    Private_Alice = Generate_private_key(p)
    Public_Alice = power(alpha, Private_Alice, p)

    # Bob selects his private key, calculates his public key, and places the public key on the network
    Private_Bob = Generate_private_key(p)
    Public_Bob = power(alpha, Private_Bob, p)

    # Bob and Alice calculate the mask key separately, and the results should be the same
    Key_mask_Alice = power(Public_Alice, Private_Bob, p)
    Key_mask_Bob = power(Public_Bob, Private_Alice, p)

    # Bob encrypts the message
    ciphertext_Alice = encrypt(message, p, Key_mask_Bob)
    # Alice encrypts the message
    ciphertext_Bob = encrypt(message, p, Key_mask_Alice)

    # Alice decrypts the message
    plaintext_Alice = decrypt(ciphertext_Bob, p, Key_mask_Alice)
    # Alice decrypts the message
    plaintext_Bob = decrypt(ciphertext_Alice, p, Key_mask_Bob)

    print("Alice to Bob: ")
    print(Public_Alice)
    print("Bob to Alice: ")
    print(Public_Bob)
    print("Result (Alice view):")
    print(plaintext_Alice)
    print("Result (Bob view):")
    print(plaintext_Bob)

输出结果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值