Commits

Ivan Vučica committed 8cc68c4

Functional RSA decryption

  • Participants
  • Parent commits a6e009d

Comments (0)

Files changed (4)

 		owner="Ivan Vucica" 
 		owneremail="ivan@vucica.net" 
 		url="http://ivan.vucica.net/pythia/"/>
+	<key
+		p="14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113"
+		q="7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101"
+		d="46730330223584118622160180015036832148732986808519344675210555262940258739805766860224610646919605860206328024326703361630109888417839241959507572247284807035235569619173792292786907845791904955103601652822519121908367187885509270025388641700821735345222087940578381210879116823013776808975766851829020659073"/>
+
 </pythia>
 
 import server
 from xml.dom import minidom
-
+from rsa import rsa
 
 srv = None # just do define it globally
 
 			srv.mMetaOwner = param.attributes['owner'].nodeValue
 			srv.mMetaOwnerMail = param.attributes['owneremail'].nodeValue
 			srv.mMetaURL = param.attributes['url'].nodeValue
+		if param.nodeName == 'key':
+			rsa.setKey(str(param.attributes['p'].nodeValue), str(param.attributes['q'].nodeValue), str(param.attributes['d'].nodeValue))
 	print "."
 
 	print "Starting server."
 # Consequently it is licensed under GNU General Public License v2, license
 # common to both sources.
 
+
+# TODO investigate replacing getInt(), getString() etc with
+# stuff from struct module
+
 import math
 import types
 
+def getIntFromASCII(string):
+	if not (type(string) is types.StringType):
+		raise TypeError("You must pass a string ")
+	
+	num = 0
+	for char in string:
+		char = ord(char) - ord('0')
+		num *= 10
+		num += char
+	
+	return num
 
 def getInt(string):
 	if not (type(string) is types.StringType):
 	num  = 0
 	for char in string:
 		char = ord(char)
-		num >>= 8
+		num <<= 8
 		num += char
 
-	return integer
+	return num
 
 def getString(num):
 	if not (type(num) is types.LongType or type(num) is types.IntType):
 
 	string = ""
 
-	while number > 0:
-		string = "%s%s" % (chr(number & 0xFF), string)
-		number <<= 8
+	while num > 0:
+		string = "%s%s" % (chr(num & 0xFF), string)
+		num >>= 8
 
 	return string
 
 	n"""
 
 	if type(message) is types.IntType:
-		return encrypt_int(long(message), ekey, n)
+		return encryptInt(long(message), ekey, n)
 
 	if not type(message) is types.LongType:
 		raise TypeError("You must pass a long or an int")
 	if q == 0: return p
 	return calcGCD(q, abs(p%q))
 
-# invmodp from: http://code.activestate.com/recipes/576737-inverse-modulo-p/
-def invmodp(a, p):
-	'''
-	The multiplicitive inverse of a in the integers modulo p.
-	Return b s.t.
-	a * b == 1 mod p
-	'''
-	
-	r = a
-	d = 1
-	for count in xrange(p):
-		d = ((p // r + 1) * d) % p
-		r = (d * a) % p
-		if r == 1:
-			break
-	else:
-		raise ValueError('%d has no inverse mod %d' % (a, p))
-	return d
-	
-#def __invmodp__test__():
-#	p = 101
-#	for i in range(1, p):
-#		iinv = invmodp(i, p)
-#		assert (iinv * i) % p == 1
-#__invmodp__test__()
-
+def invmod(a, b):
+	"""
+	Modular multiplicative inverse
+	http://stackoverflow.com/questions/4798654/modular-multiplicative-inverse-function-in-python
+	"""
+	return pow(a, b-2, b)
 
 class RSA:
 	def __init__(self):
 		self.mDq = 0 # 1024bit number
 		self.mMod = 0 # 1024bit number
 
-	def setKey(p, q, d):
-		self.mP = getInt(p)
-		self.mQ = getInt(q)
-		self.mD = getInt(d)
+	def setKey(self, p, q, d):
+		self.mP = getIntFromASCII(p)
+		self.mQ = getIntFromASCII(q)
+		self.mD = getIntFromASCII(d)
 
-		self.mU = invmodp(self.mP, self.mQ)
+		self.mU = invmod(self.mP, self.mQ)
 		self.mDP = self.mD % (self.mP - 1)
 		self.mDQ = self.mD % (self.mQ - 1)
 		
 		self.mMod = self.mP * self.mQ
 		
-		self.keySet = true
+		self.keySet = True
 
-	def decrypt(characters):
+	def decrypt(self, characters):
 		c = getInt(characters)
-		tmp = c % self.mP
-		v1 = (tmp ** self.mDP) % self.mP
-		tmp = c % self.mQ
-		v2 = (tmp ** self.mDQ) % self.mQ
-
-		u2 = v2 - v1
-		tmp = u2 * self.mU
-		u2 = tmp * self.mQ
+		v1 = pow(c % self.mP, self.mDP, self.mP) #((c % self.mP) ** self.mDP) % self.mP
+		v2 = pow(c % self.mQ, self.mDQ, self.mQ)  #((c % self.mQ)** self.mDQ) % self.mQ
+		u2 = ((v2 - v1) * self.mU % self.mQ)
 		if u2 < 0:
 			tmp = u2 + self.mQ
 			u2 = tmp
 		tmp = u2 * self.mP
 		c = 0
 		c = v1 + tmp
-
 		return getString(c)
 
+rsa = RSA()
 ######################
 
 import socket,threading
+from rsa import rsa
 
 class Server:
 	""" 
 		r2 = self.readU16()
 		return r1 + r2*256*256
 
+	def decryptRSA(self):
+		decrypted = rsa.decrypt(self.msg[:128])
+		self.msg = decrypted
+
 #################################################
 
 class Connection(threading.Thread):
 		print "Dat: " + str(dat),
 		print "Spr: " + str(spr),
 		print "Pic: " + str(pic)
+
+		init_netmsg.decryptRSA()
+		
+		key = [	init_netmsg.readU32(), 
+			init_netmsg.readU32(), 
+			init_netmsg.readU32(), 
+			init_netmsg.readU32()]
+		print "Key: " + str(key)
 		self.mSocket.close()
 
 class GameworldConnection(Connection):