MQV Protocol


from ECurve import *


class MQV_Skeleton(object):
    "Algoritmi stile MQV"

    def __init__(self, ECurve, P):
        self.ECurve = ECurve
        self.P = P
        self.n = P.order()
        self.h = len(ECurve) // self.n

    def GetIdParams(self, a):
        # a=Chiave segreta
        # P**a=Chiave pubblica
        return [a, P ** a]

    def GenMsg(self):
        x = randrange(1, self.n)
        return [x, self.P ** x]

    def GetSecret(
        self, SK_A, PK_B, x, X, Y, Name_A="", Name_B=""
    ):
        S = x + self.xTract(X, Name_A) * SK_A
        e = self.h * S
        K = (Y + PK_B ** self.xTract(Y, Name_B)) ** e
        return K

    def xTract(self, x, y):
        raise NotImplementedError(
            "xTract should be defined in a derived class"
        )


class MQV_Protocol(MQV_Skeleton):
    def xTract(self, X, extra=""):
        L = int(floor(ceil(log(self.n) / log(2) + 1) / 2))
        return (int(X[0]) % (2 ** L)) + 2 ** L


class HMQV_Protocol(MQV_Skeleton):
    def xTract(self, X, Name):
        print("X=", repr(X), "\n")
        print("Name=", Name, "\n")
        import hashlib

        H = hashlib.sha256()
        H.update(repr(X).encode("utf-8"))
        H.update(Name.encode("utf-8"))
        i = int(H.hexdigest(), 16) % len(X.EC)
        return i


# Example

# SETUP
Ec = ECurve(2, [1, 0, 1, 0, 0, 1])
Ec.EquSSing([1, 1], [0, 1], [1, 1])
P = Ec.random()
Protocol = MQV_Protocol(Ec, P)

# Parametri pubblici e privati
SK_Alice = 7
PK_Alice = Protocol.GetIdParams(SK_Alice)[1]
SK_Bob = 11
PK_Bob = Protocol.GetIdParams(SK_Bob)[1]

# GenMsg
[x_Alice, M_Alice] = Protocol.GenMsg()
[x_Bob, M_Bob] = Protocol.GenMsg()

# Segreto
Secret_Alice = Protocol.GetSecret(
    SK_Alice, PK_Bob, x_Alice, M_Alice, M_Bob
)
Secret_Bob = Protocol.GetSecret(
    SK_Bob, PK_Alice, x_Bob, M_Bob, M_Alice
)

# Protocollo HMQV
HProtocol = HMQV_Protocol(Ec, P)
HSecret_Alice = HProtocol.GetSecret(
    SK_Alice,
    PK_Bob,
    x_Alice,
    M_Alice,
    M_Bob,
    "Alice",
    "Bob",
)
HSecret_Bob = HProtocol.GetSecret(
    SK_Bob, PK_Alice, x_Bob, M_Bob, M_Alice, "Bob", "Alice"
)