def generate_keys(): """ Supplicant Mode - Key Generation """ # Select an elliptic curve [it is defined in ecc.py] ec = ecc.ECcurve() # a = r <- {0, ..., Q − 1} [Alice calculates the private key.] print "* Generating an a random number. (Private Key)" a = Crypto.Util.number.getRandomRange(0, (q - 1)) # v = −a.G(modP) [Alice calculates the public key v (a point in the elliptic curve).] # v = (-a*ec_G) % p # atenção à coordenada y! G = (xi, xf) print "* Generating an elliptic curve point. (Public Key)" pbp = ecc.ECPoint(ec.xi, ec.yi) pbp = pbp.multiplyPointByScalar(a) pbp = pbp.simmetric() print "--- BEGIN PRIVATE KEY ---" print a print "--- BEGIN PUBLIC KEY ---" print "v(x,-) = " + str(pbp.x) print "v(-,y) = " + str(pbp.y) return [a, pbp.x, pbp.y]
def generate_keys(): """ Supplicant Mode - Key Generation """ # Select an elliptic curve [it is defined in ecc.py] ec = ecc.ECcurve() # a = r <- {0, ..., Q - 1} [Alice calculates the private key.] print("* Generating an a random number. (Private Key)") a = Crypto.Util.number.getRandomRange(0, (q - 1)) a = 1742413906660797398263574261320583321084828220183690165741 # v = -a.G(modP) [Alice calculates the public key v (a point in the elliptic curve).] # v = (-a*ec_G) % p # atencao a coordenada y! G = (xi, xf) print("* Generating an elliptic curve point. (Public Key)") pbp = ecc.ECPoint(ec.xi, ec.yi) pbp = pbp.multiplyPointByScalar(a) pbp = pbp.simmetric() print("--- BEGIN PRIVATE KEY ---") print(a) print("--- BEGIN PUBLIC KEY ---") print("v(x,-) = ", pbp.x) print("v(-,y) = ", pbp.y) return [a, pbp.x, pbp.y]
def sign(message, private_key): ec = ecc.ECcurve() r = Crypto.Util.number.getRandomRange(0, (q - 1)) x = ecc.ECPoint(ec.xi, ec.yi) x = x.multiplyPointByScalar(r) # generates e # e = Crypto.Util.number.getRandomRange(0, 2**80) e = int.from_bytes(sha224(message).digest(), 'big') % dataSize """ calculate Y """ y = _hex2int(private_key) * e + r return _ele2hex(x) + _int2hex(y, b=34)
def verify(message, x_y, public_key): px, py = _hex2ele(public_key) v = ecc.ECPoint(px, py) e = int.from_bytes(sha224(message).digest(), 'big') % dataSize print(hex(e)) v = v.multiplyPointByScalar(e) # calculate z ec = ecc.ECcurve() z = ecc.ECPoint(ec.xi, ec.yi) z = z.multiplyPointByScalar(_hex2int(x_y[byte * 4:])) z = z.sum(v) # verify z e x xx, xy = _hex2ele(x_y[:byte * 4]) if z.x == xx and z.y == xy: return True else: return False
def supplicant(a): """ Alice / Supplicant / Client Mode """ #host = 'localhost' #port = 8888 #dataSize = 1024 print "* Opening socket" print "* - host: " + str(host) print "* - port: " + str(port) aChannel = socket.socket(socket.AF_INET, socket.SOCK_STREAM) aChannel.connect((host, port)) print "\n* Connected to Bob (Authenticator)." #Generate a number R to use in [ x=r.G(modP) ] to calculate a point on the elliptic curve print "* Generating a r random number." ec = ecc.ECcurve() r = Crypto.Util.number.getRandomRange(0, (q - 1)) print "* Number r generated." print "\tr = " + str(r) print "* Getting point X on the elliptic curve." x = ecc.ECPoint(ec.xi, ec.yi) x = x.multiplyPointByScalar(r) # enviar V #print "\nVx: " + hex(x.x) #print "Vy: " + hex(x.y) #aChannel.send(str(x.x)) #aChannel.send(str(x.y)) # send x # print "\n<- sending X." print "\tXx: " + hex(x.x) print "\tXy: " + hex(x.y) aChannel.send(str(x.x)) aChannel.send(str(x.y)) print "\n<- X sent." # receive e #print "\n-> Receiving e." e = aChannel.recv(dataSize) e = int(e) print "\n-> e received." print "\te: " + hex(e) if e < 2**80: print "* e is valid." else: print "* e is not valid." return # Alice verifies that the value [e] is in the appropriate interval # calculate Y #print "\n* Calculating y." y = a * e + r print "\n* y was calculed." print "\ty: " + hex(y) # send y # print "\n<- sending y." aChannel.send(str(y)) print "\n<- y sent." aChannel.close() print "* Connection closed.\n"
def authenticator(v): """ Bob / Authenticator / Server Mode """ #host = '' #port = 8888 nClients = 5 #dataSize = 1024 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, port)) s.listen(nClients) bChannel, address = s.accept() print "* Alice is connected." # receive v #vx = bChannel.recv(dataSize) #vy = bChannel.recv(dataSize) #v = ecc.ECPoint(int(vx), int(vy)) #print "\n-> V received with the following values: " #print "\tVx: " + hex(v.x) #print "\tVy: " + hex(v.y) # receives x xx = bChannel.recv(dataSize) xy = bChannel.recv(dataSize) x = ecc.ECPoint(int(xx), int(xy)) print "\n-> x received with the following values: " print "\txx: " + hex(x.x) print "\txy: " + hex(x.y) # generates e e = Crypto.Util.number.getRandomRange(0, 2**80) print "\n* e generated.\n\t e: " + hex(e) # send e bChannel.send(str(e)) print "\n<- e sent." # receive y y = bChannel.recv(dataSize) y = int(y) print "\n-> y received with the following value: " print "\ty: " + hex(y) # calculate z ec = ecc.ECcurve() z = ecc.ECPoint(ec.xi, ec.yi) z = z.multiplyPointByScalar(y) v = v.multiplyPointByScalar(e) z = z.sum(v) # verify z e x print "\n\n* Final Result: \n" if z.x == x.x and z.y == x.y: print "\t\tSuccess!" else: print "\t\tFail!" print "\n" bChannel.close() print "* Connection closed\n"
usage = ''' Usage: ./schnorr [OPTION]... [ARGS]... Authenticates someone using Schnorr Protocol over Elliptic Curves Shows this message if none of options is used. Mandatory arguments to long options are mandatory for short options too. -gk,\t--generate-keys\tGenerates a Key Pair. -a,\t--authenticator\tUses a Public Key to authenticate a client. -s,\t--supplicant\tUses the Private Key to authenticate itself to a server.\n ''' host = 'localhost' port = 6666 dataSize = 2048 p = ecc.ECcurve().p q = ecc.ECcurve().q # --generate_keys def generate_keys(): """ Supplicant Mode - Key Generation """ # Select an elliptic curve [it is defined in ecc.py] ec = ecc.ECcurve() # a = r <- {0, ..., Q − 1} [Alice calculates the private key.] print "* Generating an a random number. (Private Key)" a = Crypto.Util.number.getRandomRange(0, (q - 1))
def get_public_key(private_key): ec = ecc.ECcurve() pbp = ecc.ECPoint(ec.xi, ec.yi) pbp = pbp.multiplyPointByScalar(_hex2int(private_key)) pbp = pbp.simmetric() return _ele2hex(pbp)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import ecc import Crypto.Util.number from binascii import hexlify, unhexlify from hashlib import sha224 p = ecc.ECcurve().p q = ecc.ECcurve().q byte = ecc.ECcurve().fieldSize // 8 dataSize = 2**80 # --INT to bytes HEX def _int2hex(i, b=byte): return hexlify(i.to_bytes(b, 'big')).decode('utf8') # --bytes HEX to INT def _hex2int(i): return int.from_bytes(unhexlify(i.encode('utf8')), 'big') # --2element to hex def _ele2hex(e): return _int2hex(e.x) + _int2hex(e.y) # --hex to 2element