Posted by devloop on Sun 8 Feb 15:24
report abuse | download | new post
- #!/usr/bin/env python
- import random
- from numpy import *
- # un byte : entier sur 8 bits
- # un char : caractere sur 8 bits
- # un block : 4 bytes
- class Crypt:
- a2b={}
- b2a={}
- def __init__(self):
- i=0
- # Chaine de 64 caracteres utilises pour les codages ASCII
- for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":
- self.a2b[c]=i
- i=i+1
- for k,v in self.a2b.items():
- self.b2a[v]=k
- def str2bytes(self,s):
- t=[]
- for c in s:
- t.append(ord(c))
- return t
- def bytes2str(self,t):
- s=""
- for x in t.values():
- s+=chr(x)
- return s
- def blocks2bytes(self,blocks):
- bytes={}
- iby=0
- ibl=0
- for a in range(len(blocks)):
- bytes[iby]=255 & blocks[ibl] >> 24
- iby+=1
- bytes[iby]=255 & blocks[ibl] >> 16
- iby+=1
- bytes[iby]=255 & blocks[ibl] >> 8
- iby+=1
- bytes[iby]=255 & blocks[ibl]
- iby+=1
- ibl+=1
- return bytes
- def bytes2blocks(self,bytes):
- # retour un tableau de long (sur 8 octets)
- blocks={}
- iby=0
- ibl=0
- while True:
- blocks[ibl]=(255 & bytes[iby]) << 24
- iby+=1
- if iby>=len(bytes):
- break
- blocks[ibl] |= (255 & bytes[iby]) << 16
- iby+=1
- if iby>=len(bytes):
- break
- blocks[ibl] |= (255 & bytes[iby]) << 8
- iby+=1
- if iby>=len(bytes):
- break
- blocks[ibl] |= (255 & bytes[iby])
- iby+=1
- if iby>=len(bytes):
- break
- ibl+=1
- return blocks
- def binary2str(self,bks):
- return self.bytes2str(self.blocks2bytes(bks))
- def str2binary(self,s):
- return self.bytes2blocks(self.str2bytes(s))
- def xor_blocks(self,blk1,blk2):
- # xor of two 8-byte blocks
- blk={}
- blk[0]=blk1[0]^blk2[0]
- blk[1]=blk1[1]^blk2[1]
- return blk
- def binarydigest(self,str1,keystr=""):
- key=[1633837924L,1650680933L,1667523942L,1684366951L]
- c0=[1633837924L,1650680933L]
- c1=c0
- v0={}
- v1={}
- blocks=self.bytes2blocks(self.digest_pad(self.str2bytes(str1)))
- ibl=0
- swap=0
- while ibl<len(blocks):
- v0[0]=blocks[ibl]
- ibl+=1
- v0[1]=blocks[ibl]
- ibl+=1
- v1[0]=blocks[ibl]
- ibl+=1
- v1[1]=blocks[ibl]
- ibl+=1
- c0=self.tea_code(self.xor_blocks(v0,c0),key)
- c1=self.tea_code(self.xor_blocks(v1,c1),key)
- swap=c0[0]
- c0[0]=c0[1]
- c0[1]=c1[0]
- c1[0]=c1[1]
- c1[1]=swap
- # mix up the two cipher blocks with a 32-bit left rotation...
- swap={}
- swap[0]=c0[0]
- swap[1]=c0[1]
- swap[2]=c1[0]
- swap[3]=c1[1]
- return swap
- def asciidigest(s):
- return self.binary2ascii(self.binarydigest(s))
- def digest_pad(self,bytearray):
- newarray={}
- npads=15-(len(bytearray)%16)
- newarray[0]=npads
- ina=1
- iba=0
- for a in range(len(bytearray)):
- newarray[ina]=bytearray[iba]
- ina+=1
- iba+=1
- for a in range(npads,0,-1):
- newarray[ina]=0
- ina+=1
- return newarray
- def rand_byte(self):
- return random.randint(0,255)
- def pad(self,bytearray):
- newarray={}
- npads=7-len(bytearray)%8
- # 248 | 7 = 255 ou encore F8 | 07 = FF
- # ainsi les premiers bits de la premiere case du tableau n'ont pas d'interet
- # d'ou l'utilisation de rand_byte()
- # les 7 derniers bits permettent de retrouver le nombre d'octets de bourrage
- newarray[0]=248 & self.rand_byte() | 7 & npads
- ina=1
- iba=0
- for a in range(len(bytearray)):
- newarray[ina]=bytearray[iba]
- ina+=1
- iba+=1
- for a in range(npads,0,-1):
- newarray[ina]=self.rand_byte()
- ina+=1
- return newarray
- def unpad(self,bytearray):
- newarray={}
- # on calcule la taille effective du tablea sans les octets de bourrage
- nba=len(bytearray) - (7 & bytearray[0])
- ina=0
- iba=1
- while iba<nba:
- newarray[ina]=bytearray[iba]
- ina+=1
- iba+=1
- return newarray
- def bytes2ascii(self,b):
- s=""
- ib=0
- b1=0
- b2=0
- b3=0
- carry=0
- # on prend 3 octets (soit 24 bits) que l'on decoupe en 4 blocks de 6 bits
- # soit 64 valeurs possibles qui servent comme index pour un caractere ASCII
- while True:
- if ib>=len(b):
- break
- b1=255 & b[ib]
- # 63 = masque 0x3F - elimine les deux premiers bits (poids fort)
- s+=self.b2a[63 & b1 >> 2]
- # carry prend les deux derniers bits (poids faible)
- carry=3 & b1
- ib+=1
- if ib>=len(b):
- s+=self.b2a[carry << 4]
- break
- b2=255 & b[ib]
- # 240 = masque 0xF0 - elimine les quatres derniers bits
- s+=self.b2a[240 & carry << 4 | b2 >> 4]
- # carry prend les quatres derniers bits (poids faible)
- carry=15 & b2
- ib+=1
- if ib>=len(b):
- s+=self.b2a[carry << 2]
- break
- b3=255 & b[ib]
- # 60 = masque 0x3C - elimine les deux premiers et deux derniers bits
- # 63 = masque 0x3F - elimine les deux premiers bits (poids fort)
- s+=self.b2a[60 & carry << 2 | b3 >> 6]+self.b2a[63 & b3]
- ib+=1
- if ib%36==0:
- s+="\n"
- return s
- def ascii2bytes(self,a):
- la=len(a)
- ia=-1 # pointeur sur chaine
- ib=0 # pointeur sur tableau
- b={} # tableau de retour
- carry=0
- while True:
- while True:
- ia+=1
- if ia>=la:
- return b
- if a[ia] in self.a2b.keys():
- break
- b[ib]=self.a2b[a[ia]] << 2
- while True:
- ia+=1
- if ia>=la:
- return b
- if a[ia] in self.a2b.keys():
- break
- carry=self.a2b[a[ia]]
- b[ib] |= carry >> 4
- ib+=1
- carry &= 15
- if carry==0 and ia==la-1:
- return b
- b[ib]=carry<<4
- while True:
- ia+=1
- if ia>=la:
- return b
- if a[ia] in self.a2b.keys():
- break
- carry=self.a2b[a[ia]]
- b[ib] |= carry >> 2
- ib+=1
- carry &= 3
- if carry==0 and ia==la-1:
- return b
- b[ib]=carry << 6
- while True:
- ia+=1
- if ia>=la:
- return b
- if a[ia] in self.a2b.keys():
- break
- b[ib] |= self.a2b[a[ia]]
- ib+=1
- return b
- def ascii2binary(self,s):
- return self.bytes2blocks(self.ascii2bytes(s))
- def binary2ascii(self,t):
- return self.bytes2ascii(self.blocks2bytes(t))
- # cf. priorite des operateurs
- # http://docs.python.org/reference/expressions.html
- def tea_code(self,v,k):
- # c'est du XTEA : http://en.wikipedia.org/wiki/XTEA
- # TEA. 2-int (64-bit) (2x 4 octets) cyphertext block in v. 4-int (128-bit) key in k.
- v0=uint32(v[0])
- v1=uint32(v[1])
- sum=0
- tmp=0
- tmp2=0
- for i in range(0,32):
- tmp=uint32( add( (self.SHL(v1,4) ^ self.USHR(v1,5)) , uint32(v1) ) )
- tmp2=uint32( sum+k[sum&3])
- v0=uint32( add(v0, tmp^tmp2))
- sum= uint32(sum - 1640531527) # TEA magic number 0x9e3779b9
- tmp=uint32( add( (self.SHL(v0,4) ^ self.USHR(v0,5)) , uint32(v0) ) )
- tmp2=uint32( sum+k[(sum >> 11) & 3])
- v1=uint32( add(v1,tmp^tmp2))
- #print "v0:",v0,"v1:",v1
- return [v0,v1]
- def tea_decode(self,v,k):
- v0=uint32(v[0])
- v1=uint32(v[1])
- sum=uint32(-957401312) # TEA magic number 0x9e3779b9<<5
- for i in range(0,32):
- tmp=uint32( add( (self.SHL(v0,4) ^ self.USHR(v0,5)) , uint32(v0) ) )
- tmp2=uint32( sum+k[(sum >> 11) & 3])
- v1 = uint32( subtract(v1, tmp^tmp2))
- sum=uint32(sum + 1640531527) # TEA magic number 0x9e3779b9
- tmp=uint32( add( (self.SHL(v1,4) ^ self.USHR(v1,5)) , uint(v1) ) )
- tmp2=uint32( sum+k[sum&3])
- v0 = uint32( subtract(v0, tmp^tmp2))
- return [v0,v1]
- def decrypt(self,M,K=""):
- if K=="":
- print "No key!!"
- return False
- if M=="":
- return ""
- bd=self.binarydigest(K)
- bin=self.ascii2binary(M)
- i=0
- j=0
- t0=[1633837924,1650680933]
- t1=[]
- t2={}
- t3={}
- while i<len(bin):
- t2[0]=bin[i]
- i+=1
- t2[1]=bin[i]
- i+=1
- t1=self.xor_blocks(t0,self.tea_decode(t2,bd))
- t3[j]=t1[0]
- j+=1
- t3[j]=t1[1]
- j+=1
- t0[0]=t2[0]
- t0[1]=t2[1]
- return self.bytes2str(self.unpad(self.blocks2bytes(t3)))
- def encrypt(self,M="",K=""):
- if K=="":
- print "No key!!"
- return False
- if M=="":
- return ""
- bd=self.binarydigest(K)
- bks=self.bytes2blocks(self.pad(self.str2bytes(M)))
- i=0
- j=0
- t0=[1633837924,1650680933]
- t1={}
- t2={}
- while i<len(bks):
- t1[0]=bks[i]
- i+=1
- t1[1]=bks[i]
- i+=1
- t0=self.tea_code(self.xor_blocks(t1,t0),bd)
- t2[j]=t0[0]
- j+=1
- t2[j]=t0[1]
- j+=1
- return self.binary2ascii(t2)
- # fonctions faits maisons pour les decalages de bits sur entier de 32 bits non signes
- def USHR(self,n,d):
- if n>=0:
- return n>>d
- else:
- return (n>>d)&(0xffffffff>>d)
- def SHL(self,n,d):
- mask=n&(0xffffffff>>d)
- return mask<<d
- # fonction trouve sur le web, affiche un chiffre sous sa forme binaire
- def Denary2Binary(self,n):
- '''convert denary (base 10) integer n to binary string bStr'''
- bStr = ''
- if n < 0: raise ValueError, "must be a positive"
- if n == 0: return '0'
- while n > 0:
- bStr = str(n % 2) + bStr
- n = n >> 1
- return bStr
- if __name__ == "__main__":
- p="plop"
- ep="ep"
- v="1"
- salt=""
- for i in range(0,8):
- salt+=str(random.randint(0,9))
- json = '{"p":"'+p+'","ep":"'
- json+=ep+'","v":"'+v+'","s":"'+salt+'"}'
- c=Crypt()
- print c.decrypt("q-mbHsiVngxbuIpQwvSCkEKSpfhfhNM7ujQB4fUcLXDbyF4cZABwsi8Vxa2n62deHjbDeZrqXTdGN4UkLDdogiiiOdpYWO9i68hX_AKZpeGtlOmyviP4JOxh13eKM7JWVXzjU3CtHefbvHiFrURTU4u6m8mmGZbuAadfnQ6UR4cqSC6bVipieCnTSpLpFQAcoXx8X86R5SmBpQ6FzQDfLXZJZhQ4MP_A4R3tBgdjSoCtbRlr7XAUV2DPe8ezkoxCq2YduYa_uOmGmB-TABOa--PMXf_XyueJi3puKyuwoJCZFfo1VFR0oA","I:NTnd7;+)WK?[:@S2ov")
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.