|
Welcome to the GSM-Forum forums. You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. Only registered members may post questions, contact other members or search our database of over 8 million posts. Registration is fast, simple and absolutely free so please - Click to REGISTER! If you have any problems with the registration process or your account login, please contact contact us . |
|
Register | FAQ | Donate | Forum Rules | Root any Device | ★iPhone Unlock★ | ★ Direct Codes ★ | Direct Unlock Source | Search | Today's Posts | Mark Forums Read |
GSM Programming & Reverse Engineering Here you can post all Kind of GSM Programming and Reverse Engineering tools and Secrets. |
| LinkBack | Thread Tools | Display Modes |
06-11-2012, 17:42 | #1 (permalink) |
No Life Poster Join Date: Mar 2007 Location: Guangzhou-China
Posts: 1,289
Member: 468587 Status: Offline Sonork: 100.1612429 Thanks Meter: 681 | [FREE] Source code Code: Public Class .... Public Function isPrime(ByVal v As Byte) As Boolean For i = 2 To v - 1 If v Mod i = 0 Then Return False End If Next Return True End Function Private _Prime1 As Byte Public Property Prim1() As Byte Get Return _Prime1 End Get Set(ByVal value As Byte) If Not isPrime(value) Then Throw New Exception("The Number is not Prim") End If _Prime1 = value End Set End Property Private _Prime2 As Byte Public Property Prim2() As Byte Get Return _Prime2 End Get Set(ByVal value As Byte) If Not isPrime(value) Then Throw New Exception("The Number is not Prim") End If _Prime2 = value End Set End Property Private _Prime3 As Byte Public Property Prim3() As Byte Get Return _Prime3 End Get Set(ByVal value As Byte) If Not isPrime(value) Then Throw New Exception("The Number is not Prim") End If _Prime3 = value End Set End Property Private _E As Byte Public Property E() As Byte Get Return _E End Get Set(ByVal value As Byte) _E = value End Set End Property Private _d As Integer Public ReadOnly Property D() As Integer Get Dim s = 0 _d = 1 Do s = (_d * E) Mod phi _d += 1 Loop While (s <> 1) _d = _d - 1 Return _d End Get End Property Public Function Phi() As Integer Return (Prim1 - 1) * (Prim2 - 1) * (Prim3 - 1) End Function Public Function n() As Integer Return (Prim1) * (Prim2) * (Prim3) End Function Function Check() As Integer Dim i = 3 While (e Mod i == 0) And (phi Mod i == 0) i += 2 Return 1 End While Return 0 End Function Function encrypt(ByVal M As Byte) As Byte Dim i As Byte = 0 C = 1 For i = 0 To E - 1 C = C * M Mod n() C = C Mod n() Next Return C Xor E End Function Function decrypt(ByVal K As Byte) As Byte K = K Xor E Dim i As Byte Dim M = 1 For i = 0 To D - 1 M = M * K Mod n() M = M Mod n() Next Return M End Function Public Function EncryptString(ByVal S As String) As String Dim asc As Byte Dim st = "" Dim enc As New System.Text.UnicodeEncoding Dim Bytes() As Byte = enc.GetBytes(S) Dim i = 0 For Each B In Bytes asc = encrypt(B) Bytes(i) = asc i = i + 1 Next Return enc.GetChars(Bytes) End Function Public Function DecryptString(ByVal S As String) As String Dim asc As Byte Dim st = "" Dim enc As New System.Text.UnicodeEncoding Dim Bytes() As Byte = enc.GetBytes(S) Dim i = 0 For Each B In Bytes asc = decrypt(B) Bytes(i) = asc i = i + 1 Next Return enc.GetChars(Bytes) End Function Public Function EncryptBytes(ByVal B() As Byte) As Byte() For i = 0 To B.Length - 1 B(i) = encrypt(B(i)) Next Return B End Function Public Function DecryptBytes(ByVal B() As Byte) As Byte() For i = 0 To B.Length - 1 B(i) = decrypt(B(i)) Next Return B End Function Public Sub EnryptFile(ByVal inputFile As String, ByVal outFile As String) Dim inFile As New IO.FileStream(inputFile, IO.FileMode.Open) Dim oFile As New IO.FileStream(outFile, IO.FileMode.Create) Dim B(0 To 1023) As Byte Dim L As Integer While True L = inFile.Read(B, 0, B.Length - 1) If L = 0 Then Exit While End If B = EncryptBytes(B) oFile.Write(B, 0, L) End While inFile.Close() oFile.Close() End Sub Public Sub DeryptFile(ByVal inputFile As String, ByVal outFile As String) Dim inFile As New IO.FileStream(inputFile, IO.FileMode.Open) Dim oFile As New IO.FileStream(outFile, IO.FileMode.Create) Dim B(0 To 1023) As Byte Dim L As Integer While True L = inFile.Read(B, 0, B.Length - 1) If L = 0 Then Exit While End If B = DecryptBytes(B) oFile.Write(B, 0, L) End While inFile.Close() oFile.Close() End Sub End Class Code: #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> class Nb512; class Nb1024; unsigned long long NbHasard; void InitHasard(){ NbHasard=time(NULL); } class Nb2048{ public: union { unsigned D[64]; unsigned long long Q[32]; struct { unsigned long long Lo; unsigned long long Hi; } O[16]; } Nb __attribute__ ((aligned(16))); bool carry; bool ChercheQuotient; void DecaleAdd (const Nb1024 &terme, unsigned char decal); //Permet d'ajouter à un nombre de 1024 bits un nombre de 512 bits, en le décalant d'un nombre entier de qword Nb1024 operator% (const Nb1024 &Mod)const; Nb2048 operator+ (const Nb2048 &Terme)const; Nb2048 operator- (const Nb2048 &Terme)const; Nb2048& operator= (unsigned long long Nb); Nb2048& operator= (const Nb1024 &Nb); bool operator== (const Nb2048 &Nb)const; Nb2048() : ChercheQuotient(false){}; }; class Nb1024{ public: union { unsigned char B[128]; unsigned D[32]; unsigned long long Q[16]; struct { unsigned long long Lo; unsigned long long Hi; } O[8]; } Nb __attribute__ ((aligned(16))); bool carry; Nb2048* Quotient; bool ChercheQuotient; void DecaleAdd (const Nb512 &terme, unsigned char decal); //Permet d'ajouter à un nombre de 1024 bits un nombre de 512 bits, en le décalant d'un nombre entier de qword Nb1024& operator= (unsigned long long Nb); Nb1024& operator= (const Nb512 &Nb); Nb1024& operator= (const Nb1024 &Nb); Nb1024& operator= (const Nb2048 &Nb); Nb512 operator% (const Nb512 &Mod)const; Nb1024 operator+ (const Nb1024 &Terme)const; Nb1024 operator- (const Nb1024 &Terme)const; Nb2048 operator* (unsigned long long fact)const; Nb2048 operator* (const Nb1024 &fact)const; bool operator== (const Nb1024 &Nb)const; Nb1024 Nb1024::Puissance (const Nb1024 &Exp, const Nb1024 &Mod)const; Nb1024() : ChercheQuotient(false),Quotient(NULL){} Nb1024(const Nb1024& c){ for(int i=0; i<16; i++) Nb.Q[i]=c.Nb.Q[i]; carry=c.carry; ChercheQuotient=c.ChercheQuotient; if(c.Quotient!=NULL){ Quotient=new Nb2048; *Quotient=*c.Quotient; } else Quotient=NULL; } ~Nb1024(){if(Quotient!=NULL) delete Quotient;} Nb1024 Inverse(const Nb1024 &Mod)const; }; class Nb512{ public: union { unsigned char B[64]; unsigned D[16]; unsigned long long Q[8]; struct { unsigned long long Lo; unsigned long long Hi; } O[4]; } Nb __attribute__ ((aligned(16))); bool carry; Nb1024* Quotient; Nb512 operator+ (const Nb512 &Terme)const; Nb512 operator- (const Nb512 &Terme)const; Nb512& operator= (unsigned long long Nb); Nb512& operator= (const Nb512 &Nb); Nb512& operator= (const Nb1024 &Nb); Nb1024 operator* (const Nb512 &Fact)const; //Il est plus rapide de mettre les plus petits nombres en premier opérande avec cet opérateur( si possible) Nb1024 operator* (unsigned long long fact)const; bool operator== (const Nb512 &Nb)const; Nb512 Puissance (const Nb512 &Exp, const Nb512 &Mod)const; void Hasard (); //Crée un nombre aléatoire non-sécurisé ( pour les tests et le test de Miller-Rabin) bool MillerRabin(unsigned int Boucles)const; void Premier(); Nb512():Quotient(NULL){} Nb512(const Nb512& c){ for(int i=0; i<8; i++) Nb.Q[i]=c.Nb.Q[i]; carry=c.carry; if(c.Quotient!=NULL){ Quotient=new Nb1024; *Quotient=*c.Quotient; }else Quotient=NULL; } ~Nb512(){if(Quotient!=NULL) delete Quotient;} }; inline void Nb1024::DecaleAdd(const Nb512 &terme, unsigned char decal){ asm ("add %8, %0\n\t" "adc %9, %1\n\t" "adc %10,%2\n\t" "adc %11,%3\n\t" "adc %12,%4\n\t" "adc %13,%5\n\t" "adc %14,%6\n\t" "adc %15,%7\n\t" /*FIXME : mettre la derniere retenue dans la variable carry*/ "jnc 1f\n\t" "lea %7,%%R8\n\t" "0:\n\t" //gestion de la retenue : si elle persiste, on la fait remonter tout le nombre (pas de gestion de dépassement de la fin du nombre -> peut provoquer des bugs) "jnc 1f\n\t" "add $8,%%R8\n\t" "add $1,(%%R8)\n\t" "jmp 0b\n\t" "1:\n\t" : "=m" (Nb.Q[decal+0]), "=m" (Nb.Q[decal+1]), "=m" (Nb.Q[decal+2]), "=m" (Nb.Q[decal+3]), "=m" (Nb.Q[decal+4]), "=m" (Nb.Q[decal+5]), "=m" (Nb.Q[decal+6]), "=m" (Nb.Q[decal+7]) : "r" (terme.Nb.Q[0]), "r" (terme.Nb.Q[1]), "r" (terme.Nb.Q[2]), "r" (terme.Nb.Q[3]), "r" (terme.Nb.Q[4]), "r" (terme.Nb.Q[5]), "r" (terme.Nb.Q[6]), "r" (terme.Nb.Q[7]) ); } inline void Nb2048::DecaleAdd(const Nb1024 &terme, unsigned char decal){ bool c; asm ("add %9, %0\n\t" "adc %10,%1\n\t" "adc %11,%2\n\t" "adc %12,%3\n\t" "adc %13,%4\n\t" "adc %14,%5\n\t" "adc %15,%6\n\t" "adc %16,%7\n\t" "setc %8\n\t" : "=m" (Nb.Q[decal+0]), "=m" (Nb.Q[decal+1]), "=m" (Nb.Q[decal+2]), "=m" (Nb.Q[decal+3]), "=m" (Nb.Q[decal+4]), "=m" (Nb.Q[decal+5]), "=m" (Nb.Q[decal+6]), "=m" (Nb.Q[decal+7]), "=g" (c) : "r" (terme.Nb.Q[0]), "r" (terme.Nb.Q[1]), "r" (terme.Nb.Q[2]), "r" (terme.Nb.Q[3]), "r" (terme.Nb.Q[4]), "r" (terme.Nb.Q[5]), "r" (terme.Nb.Q[6]), "r" (terme.Nb.Q[7]) ); asm ("test $1,%8\n\t" "clc\n\t" "jz 1f\n\t" "stc\n\t" "1:\n\t" "adc %9, %0\n\t" "adc %10,%1\n\t" "adc %11,%2\n\t" "adc %12,%3\n\t" "adc %13,%4\n\t" "adc %14,%5\n\t" "adc %15,%6\n\t" "adc %16,%7\n\t" /*FIXME : mettre la derniere retenue dans la variable carry*/ "jnc 1f\n\t" "lea %7,%%R8\n\t" "0:\n\t" //gestion de la retenue : si elle persiste, on la fait remonter tout le nombre (pas de gestion de dépassement de la fin du nombre -> peut provoquer des bugs) "jnc 1f\n\t" "add $8,%%R8\n\t" "add $1,(%%R8)\n\t" "jmp 0b\n\t" "1:\n\t" : "=m" (Nb.Q[decal+8]), "=m" (Nb.Q[decal+9]), "=m" (Nb.Q[decal+10]),"=m" (Nb.Q[decal+11]), "=m" (Nb.Q[decal+12]),"=m" (Nb.Q[decal+13]),"=m" (Nb.Q[decal+14]),"=m" (Nb.Q[decal+15]) : "g" (c), "r" (terme.Nb.Q[8]), "r" (terme.Nb.Q[9]), "r" (terme.Nb.Q[10]),"r" (terme.Nb.Q[11]), "r" (terme.Nb.Q[12]),"r" (terme.Nb.Q[13]),"r" (terme.Nb.Q[14]),"r" (terme.Nb.Q[15]) ); } inline Nb512& Nb512::operator= (unsigned long long Nb){ memset(&this->Nb,0,sizeof(this->Nb)); this->Nb.Q[0]=Nb; return *this; } inline Nb1024& Nb1024::operator= (unsigned long long Nb){ memset(&this->Nb,0,sizeof(this->Nb)); this->Nb.Q[0]=Nb; return *this; } inline Nb2048& Nb2048::operator= (unsigned long long Nb){ memset(&this->Nb,0,sizeof(this->Nb)); this->Nb.Q[0]=Nb; return *this; } inline Nb512& Nb512::operator= (const Nb1024 &Nb){ memcpy(&this->Nb,&Nb.Nb,sizeof(this->Nb)); return *this; } inline Nb1024& Nb1024::operator= (const Nb2048 &Nb){ memcpy(&this->Nb,&Nb.Nb,sizeof(this->Nb)); return *this; } inline Nb2048& Nb2048::operator= (const Nb1024 &Nb){ memcpy(&this->Nb, &Nb.Nb, sizeof(Nb.Nb)); memset((char*)&this->Nb + sizeof(Nb.Nb), 0, sizeof(this->Nb)-sizeof(Nb.Nb)); return *this; } inline Nb1024& Nb1024::operator= (const Nb512 &Nb){ memcpy(&this->Nb, &Nb.Nb, sizeof(Nb.Nb)); memset((char*)&this->Nb + sizeof(Nb.Nb), 0, sizeof(this->Nb)-sizeof(Nb.Nb)); return *this; } inline Nb1024& Nb1024::operator= (const Nb1024 &Nb){ memcpy(this, &Nb,sizeof(Nb)); if(Nb.Quotient!=NULL){ Quotient=new Nb2048; *Quotient=*Nb.Quotient; } else Quotient=NULL; return *this; } inline Nb512& Nb512::operator= (const Nb512 &Nb){ memcpy(this, &Nb,sizeof(Nb)); if(Nb.Quotient!=NULL){ Quotient=new Nb1024; *Quotient=*Nb.Quotient; } else Quotient=NULL; return *this; } inline Nb512 Nb512::operator+ (const Nb512 &Terme)const{ Nb512 Res; asm ("add %17, %9\n\t" "adc %18, %10\n\t" "adc %19, %11\n\t" "adc %20, %12\n\t" "adc %21, %13\n\t" "adc %22, %14\n\t" "adc %23, %15\n\t" "adc %24, %16\n\t" "mov %9, %0\n\t" "mov %10,%1\n\t" "mov %11,%2\n\t" "mov %12,%3\n\t" "mov %13,%4\n\t" "mov %14,%5\n\t" "mov %15,%6\n\t" "mov %16,%7\n\t" "setc %8\n\t" : "=m" (Res.Nb.Q[0]), "=m" (Res.Nb.Q[1]), "=m" (Res.Nb.Q[2]), "=m" (Res.Nb.Q[3]), "=m" (Res.Nb.Q[4]), "=m" (Res.Nb.Q[5]), "=m" (Res.Nb.Q[6]), "=m" (Res.Nb.Q[7]), "=g" (Res.carry) : "r" (Terme.Nb.Q[0]), "r" (Terme.Nb.Q[1]), "r" (Terme.Nb.Q[2]), "r" (Terme.Nb.Q[3]), "r" (Terme.Nb.Q[4]), "r" (Terme.Nb.Q[5]), "r" (Terme.Nb.Q[6]), "r" (Terme.Nb.Q[7]), "g" (Nb.Q[0]), "g" (Nb.Q[1]), "g" (Nb.Q[2]), "g" (Nb.Q[3]), "g" (Nb.Q[4]), "g" (Nb.Q[5]), "g" (Nb.Q[6]), "g" (Nb.Q[7]) ); return Res; } inline Nb1024 Nb1024::operator+ (const Nb1024 &Terme)const{ Nb1024 Res; asm ("add %17, %9\n\t" "adc %18, %10\n\t" "adc %19, %11\n\t" "adc %20, %12\n\t" "adc %21, %13\n\t" "adc %22, %14\n\t" "adc %23, %15\n\t" "adc %24, %16\n\t" "mov %9, %0\n\t" "mov %10,%1\n\t" "mov %11,%2\n\t" "mov %12,%3\n\t" "mov %13,%4\n\t" "mov %14,%5\n\t" "mov %15,%6\n\t" "mov %16,%7\n\t" "setc %8\n\t" : "=m" (Res.Nb.Q[0]), "=m" (Res.Nb.Q[1]), "=m" (Res.Nb.Q[2]), "=m" (Res.Nb.Q[3]), "=m" (Res.Nb.Q[4]), "=m" (Res.Nb.Q[5]), "=m" (Res.Nb.Q[6]), "=m" (Res.Nb.Q[7]), "=g" (Res.carry) : "r" (Terme.Nb.Q[0]), "r" (Terme.Nb.Q[1]), "r" (Terme.Nb.Q[2]), "r" (Terme.Nb.Q[3]), "r" (Terme.Nb.Q[4]), "r" (Terme.Nb.Q[5]), "r" (Terme.Nb.Q[6]), "r" (Terme.Nb.Q[7]), "g" (Nb.Q[0]), "g" (Nb.Q[1]), "g" (Nb.Q[2]), "g" (Nb.Q[3]), "g" (Nb.Q[4]), "g" (Nb.Q[5]), "g" (Nb.Q[6]), "g" (Nb.Q[7]) ); asm ("testl $1,%8\n\t" "clc\n\t" "jz 1f\n\t" "stc\n\t" "1:\n\t" "adc %17, %9\n\t" "adc %18, %10\n\t" "adc %19, %11\n\t" "adc %20, %12\n\t" "adc %21, %13\n\t" "adc %22, %14\n\t" "adc %23, %15\n\t" "adc %24, %16\n\t" "mov %9, %0\n\t" "mov %10,%1\n\t" "mov %11,%2\n\t" "mov %12,%3\n\t" "mov %13,%4\n\t" "mov %14,%5\n\t" "mov %15,%6\n\t" "mov %16,%7\n\t" "setc %8\n\t" : "=m" (Res.Nb.Q[8]), "=m" (Res.Nb.Q[9]), "=m" (Res.Nb.Q[10]),"=m" (Res.Nb.Q[11]), "=m" (Res.Nb.Q[12]),"=m" (Res.Nb.Q[13]),"=m" (Res.Nb.Q[14]),"=m" (Res.Nb.Q[15]), "+g" (Res.carry) : "r" (Terme.Nb.Q[8]), "r" (Terme.Nb.Q[9]), "r" (Terme.Nb.Q[10]),"r" (Terme.Nb.Q[11]), "r" (Terme.Nb.Q[12]),"r" (Terme.Nb.Q[13]),"r" (Terme.Nb.Q[14]),"r" (Terme.Nb.Q[15]), "g" (Nb.Q[8]), "g" (Nb.Q[9]), "g" (Nb.Q[10]), "g" (Nb.Q[11]), "g" (Nb.Q[12]),"g" (Nb.Q[13]),"g" (Nb.Q[14]), "g" (Nb.Q[15]) ); return Res; } inline Nb512 Nb512::operator- (const Nb512 &Terme)const{ Nb512 Res; asm ("sub %17, %9\n\t" "sbb %18, %10\n\t" "sbb %19, %11\n\t" "sbb %20, %12\n\t" "sbb %21, %13\n\t" "sbb %22, %14\n\t" "sbb %23, %15\n\t" "sbb %24, %16\n\t" "mov %9, %0\n\t" "mov %10,%1\n\t" "mov %11,%2\n\t" "mov %12,%3\n\t" "mov %13,%4\n\t" "mov %14,%5\n\t" "mov %15,%6\n\t" "mov %16,%7\n\t" "setc %8\n\t" : "=m" (Res.Nb.Q[0]), "=m" (Res.Nb.Q[1]), "=m" (Res.Nb.Q[2]), "=m" (Res.Nb.Q[3]), "=m" (Res.Nb.Q[4]), "=m" (Res.Nb.Q[5]), "=m" (Res.Nb.Q[6]), "=m" (Res.Nb.Q[7]), "=g" (Res.carry) : "r" (Nb.Q[0]), "r" (Nb.Q[1]), "r" (Nb.Q[2]), "r" (Nb.Q[3]), "r" (Nb.Q[4]), "r" (Nb.Q[5]), "r" (Nb.Q[6]), "r" (Nb.Q[7]), "g" (Terme.Nb.Q[0]), "g" (Terme.Nb.Q[1]), "g" (Terme.Nb.Q[2]), "g" (Terme.Nb.Q[3]), "g" (Terme.Nb.Q[4]), "g" (Terme.Nb.Q[5]), "g" (Terme.Nb.Q[6]), "g" (Terme.Nb.Q[7]) ); return Res; } inline Nb1024 Nb1024::operator- (const Nb1024 &Terme)const{ Nb1024 Res; asm ("sub %17, %9\n\t" "sbb %18, %10\n\t" "sbb %19, %11\n\t" "sbb %20, %12\n\t" "sbb %21, %13\n\t" "sbb %22, %14\n\t" "sbb %23, %15\n\t" "sbb %24, %16\n\t" "mov %9, %0\n\t" "mov %10,%1\n\t" "mov %11,%2\n\t" "mov %12,%3\n\t" "mov %13,%4\n\t" "mov %14,%5\n\t" "mov %15,%6\n\t" "mov %16,%7\n\t" "setc %8\n\t" : "=m" (Res.Nb.Q[0]), "=m" (Res.Nb.Q[1]), "=m" (Res.Nb.Q[2]), "=m" (Res.Nb.Q[3]), "=m" (Res.Nb.Q[4]), "=m" (Res.Nb.Q[5]), "=m" (Res.Nb.Q[6]), "=m" (Res.Nb.Q[7]), "=g" (Res.carry) : "r" (Nb.Q[0]), "r" (Nb.Q[1]), "r" (Nb.Q[2]), "r" (Nb.Q[3]), "r" (Nb.Q[4]), "r" (Nb.Q[5]), "r" (Nb.Q[6]), "r" (Nb.Q[7]), "g" (Terme.Nb.Q[0]), "g" (Terme.Nb.Q[1]), "g" (Terme.Nb.Q[2]), "g" (Terme.Nb.Q[3]), "g" (Terme.Nb.Q[4]), "g" (Terme.Nb.Q[5]), "g" (Terme.Nb.Q[6]), "g" (Terme.Nb.Q[7]) ); asm ("testl $1,%8\n\t" "clc\n\t" "jz 1f\n\t" "stc\n\t" "1:\n\t" "sbb %17, %9\n\t" "sbb %18, %10\n\t" "sbb %19, %11\n\t" "sbb %20, %12\n\t" "sbb %21, %13\n\t" "sbb %22, %14\n\t" "sbb %23, %15\n\t" "sbb %24, %16\n\t" "mov %9, %0\n\t" "mov %10,%1\n\t" "mov %11,%2\n\t" "mov %12,%3\n\t" "mov %13,%4\n\t" "mov %14,%5\n\t" "mov %15,%6\n\t" "mov %16,%7\n\t" "setc %8\n\t" : "=m" (Res.Nb.Q[8]), "=m" (Res.Nb.Q[9]), "=m" (Res.Nb.Q[10]),"=m" (Res.Nb.Q[11]), "=m" (Res.Nb.Q[12]),"=m" (Res.Nb.Q[13]),"=m" (Res.Nb.Q[14]),"=m" (Res.Nb.Q[15]), "+g" (Res.carry) : "r" (Nb.Q[8]), "r" (Nb.Q[9]), "r" (Nb.Q[10]), "r" (Nb.Q[11]), "r" (Nb.Q[12]),"r" (Nb.Q[13]),"r" (Nb.Q[14]), "r" (Nb.Q[15]), "g" (Terme.Nb.Q[8]), "g" (Terme.Nb.Q[9]), "g" (Terme.Nb.Q[10]),"g" (Terme.Nb.Q[11]), "g" (Terme.Nb.Q[12]),"g" (Terme.Nb.Q[13]),"g" (Terme.Nb.Q[14]),"g" (Terme.Nb.Q[15]) ); return Res; } inline Nb2048 Nb2048::operator- (const Nb2048 &Terme)const{ Nb2048 Res; Res.carry=false; for(int i=0; i<32; i+=8) asm ("test $1,%8\n\t" "clc\n\t" "jz 1f\n\t" "stc\n\t" "1:\n\t" "sbb %17, %9\n\t" "sbb %18, %10\n\t" "sbb %19, %11\n\t" "sbb %20, %12\n\t" "sbb %21, %13\n\t" "sbb %22, %14\n\t" "sbb %23, %15\n\t" "sbb %24, %16\n\t" "mov %9, %0\n\t" "mov %10,%1\n\t" "mov %11,%2\n\t" "mov %12,%3\n\t" "mov %13,%4\n\t" "mov %14,%5\n\t" "mov %15,%6\n\t" "mov %16,%7\n\t" "setc %8\n\t" : "=m" (Res.Nb.Q[i+0]), "=m" (Res.Nb.Q[i+1]), "=m" (Res.Nb.Q[i+2]), "=m" (Res.Nb.Q[i+3]), "=m" (Res.Nb.Q[i+4]), "=m" (Res.Nb.Q[i+5]), "=m" (Res.Nb.Q[i+6]), "=m" (Res.Nb.Q[i+7]), "+g" (Res.carry) : "r" (Nb.Q[i+0]), "r" (Nb.Q[i+1]), "r" (Nb.Q[i+2]), "r" (Nb.Q[i+3]), "r" (Nb.Q[i+4]), "r" (Nb.Q[i+5]), "r" (Nb.Q[i+6]), "r" (Nb.Q[i+7]), "g" (Terme.Nb.Q[i+0]), "g" (Terme.Nb.Q[i+1]), "g" (Terme.Nb.Q[i+2]), "g" (Terme.Nb.Q[i+3]), "g" (Terme.Nb.Q[i+4]), "g" (Terme.Nb.Q[i+5]), "g" (Terme.Nb.Q[i+6]), "g" (Terme.Nb.Q[i+7]) ); return Res; } Nb1024 Nb512::operator* (const Nb512 &fact)const{ Nb512 TamponPair[8]; Nb512 TamponImpair[8]; bool Zero[8]; for(int i=0; i<8; i++){ if(Nb.Q[i]==0){ Zero[i]=true; continue; } Zero[i]=false; register unsigned long long ChiffreThis asm("%rcx")=Nb.Q[i]; for(int j=0; j<8; j+=2){ asm("mul %3" :"=a" (TamponPair[i].Nb.Q[j & 0xE]), "=d" (TamponPair[i].Nb.Q[(j & 0xE)+1]) :"a" (fact.Nb.Q[j]), "r" (ChiffreThis) ); asm("mul %3" :"=a" (TamponImpair[i].Nb.Q[j & 0xE]), "=d" (TamponImpair[i].Nb.Q[(j & 0xE)+1]) :"a" (fact.Nb.Q[j+1]), "r" (ChiffreThis) ); } } Nb1024 Retour; Retour=0; for(int i=0; i<8; i++) { if(Zero[i]==false){ Retour.DecaleAdd(TamponPair[i],i); Retour.DecaleAdd(TamponImpair[i],i+1); } } return Retour; } Nb2048 Nb1024::operator* (const Nb1024 &fact)const{ Nb1024 TamponPair[16]; Nb1024 TamponImpair[16]; bool Zero[16]; for(int i=0; i<16; i++){ if(Nb.Q[i]==0){ Zero[i]=true; continue; } Zero[i]=false; register unsigned long long ChiffreThis asm("%rcx")=Nb.Q[i]; for(int j=0; j<16; j+=2){ asm("mul %3" :"=a" (TamponPair[i].Nb.Q[j & 0xE]), "=d" (TamponPair[i].Nb.Q[(j & 0xE)+1]) :"a" (fact.Nb.Q[j]), "r" (ChiffreThis) ); asm("mul %3" :"=a" (TamponImpair[i].Nb.Q[j & 0xE]), "=d" (TamponImpair[i].Nb.Q[(j & 0xE)+1]) :"a" (fact.Nb.Q[j+1]), "r" (ChiffreThis) ); } } Nb2048 Retour; Retour=0; for(int i=0; i<16; i++) { if(Zero[i]==false){ Retour.DecaleAdd(TamponPair[i],i); Retour.DecaleAdd(TamponImpair[i],i+1); } } return Retour; } inline Nb1024 Nb512::operator* (unsigned long long fact)const{ Nb512 Tampon; Nb1024 Res; if(fact==0) return Res=0; Res=0; for(int i=0; i<8; i+=2){ asm("mul %3" :"=a" (Res.Nb.Q[i & 0xE]), "=d" (Res.Nb.Q[(i & 0xE)+1]) :"a" (Nb.Q[i]), "r" (fact) ); asm("mul %3" :"=a" (Tampon.Nb.Q[i & 0xE]), "=d" (Tampon.Nb.Q[(i & 0xE)+1]) :"a" (Nb.Q[i+1]), "r" (fact) ); } Res.DecaleAdd(Tampon,1); return Res; } inline Nb2048 Nb1024::operator* (unsigned long long fact)const{ Nb1024 Tampon; Nb2048 Res; if(fact==0) return Res=0; Res=0; for(int i=0; i<16; i+=2){ asm("mul %3" :"=a" (Res.Nb.Q[i & 0xE]), "=d" (Res.Nb.Q[(i & 0xE)+1]) :"a" (Nb.Q[i]), "r" (fact) ); asm("mul %3" :"=a" (Tampon.Nb.Q[i & 0xE]), "=d" (Tampon.Nb.Q[(i & 0xE)+1]) :"a" (Nb.Q[i+1]), "r" (fact) ); } Res.DecaleAdd(Tampon,1); return Res; } //Un chiffre = un DWORD Nb512 Nb1024::operator% (const Nb512 &Mod)const{ Nb512 Res; if(ChercheQuotient) { if(Res.Quotient!=NULL) delete Res.Quotient; Res.Quotient=new Nb1024; *Res.Quotient=0; } //ChiffreBase : contient l'index du chiffre dans Dividende que l'on va utiliser pour faire la premiere approche de Quotient signed char IndexThis, ChiffreBase; for(IndexThis=31; this->Nb.D[IndexThis]==0; IndexThis--) if (IndexThis==0) return Res=0; for(ChiffreBase=15; Mod.Nb.D[ChiffreBase]==0; ChiffreBase--) if(ChiffreBase==0) exit(-1); //division par 0 if(IndexThis<ChiffreBase) return Res=*this; Nb1024 Dividende; //Dividende partiel traité à une itération de la boucle Dividende=0; for(int i=ChiffreBase-1; i>=0; i--, IndexThis--) Dividende.Nb.D[i]=this->Nb.D[IndexThis]; for(; IndexThis>=0; IndexThis--){ // TODO : A faire en Asm (SSE ou non, selon le mieux) for(int i=15; i>=0; i--) Dividende.Nb.D[i+1]=Dividende.Nb.D[i]; Dividende.Nb.D[0]=this->Nb.D[IndexThis]; unsigned long long Quotient, RestePart; asm ("divq %4" //Premiere estimation de Quotient :"=a" (Quotient), "=d" (RestePart) :"a" ( Dividende.Nb.D[ChiffreBase] + ((unsigned long long)Dividende.Nb.D[ChiffreBase+1]<<32)), "d" (0), "g" ( (unsigned long long)Mod.Nb.D[ChiffreBase]) ); bool QuotientOK=false; if(Quotient > 0xFFFFFFFF) { Quotient=0xFFFFFFFF; //RestePart = Dividende.Nb.D[ChiffreBase+1]:Dividende.Nb.D[ChiffreBase] - 0xFFFFFFFF * Md.Nb.D[ChiffreBase] RestePart= Dividende.Nb.D[ChiffreBase] + ((unsigned long long)Dividende.Nb.D[ChiffreBase+1]<<32) - ((unsigned long long)Mod.Nb.D[ChiffreBase]<<32) + Mod.Nb.D[ChiffreBase]<<32; if(RestePart & 0xFFFFFFFF00000000) QuotientOK=true; } //Ensuite, le but est de rajouter des chiffres et de calculer l'erreur que l'on commet : on multiplie l'estimation du quotient déjà faite par les chiffres //de Mod déja pris en compte puis on soustrait les chiffres de dividende déjà pris en compte. Si le résultat est négatif ou nul, pas de problème, //Quotient n'est pas trop grand (il ne peut pas être trop petit). Dans ce cas, l'opposé du résultat correspond au reste de la division. S'il est positif, //on le divise par les chiffres de Mod déjà pris en compte : on obtient un nombre qu'il faut soustraire à Quotient. Sans optimisation, cette méthode est //impossible : on se retrouve a faire des divisions avec un dénominateur énorme et tout un tas de multiplications... //Pour simplifier, on se rend compte que ce nombre est calculable a partir du reste de la division précédente (calculé lors de la derniere estimation de //Quotient: on supprime donc beaucoup de multiplications inutiles. De plus, seules la premiere itération de cette boucle est utiles : les autres ne pourront //Faire descendre Quotient que de 1 : on remplace donc toutes ces itérations par une comparaison entre Quotient*Mod et Diviseur, qui nous dira s'il faut //décrémenter Quotient ou non. //Petite vérification.. histoire de pas faire des opérations pour rien if(Quotient == 0) continue; if(ChiffreBase == 0) QuotientOK=true; if(!QuotientOK){ unsigned long long Tmp=Quotient*Mod.Nb.D[ChiffreBase-1]; if(Tmp > ((unsigned long long)RestePart<<32) + Dividende.Nb.D[ChiffreBase-1]) //Le nombre dont on parle dans le § de commentaires plus haut est positif : on réajuste Quotient //Diviseion en arrondissant par au dessus : d'où le 1 + et le -1 Quotient-=1 + (Tmp - ((unsigned long long)RestePart<<32) - Dividende.Nb.D[ChiffreBase-1] - 1) / ( ((unsigned long long)Mod.Nb.D[ChiffreBase]<<32) + Mod.Nb.D[ChiffreBase-1] ); } Dividende=Dividende-Mod*Quotient; if(Dividende.carry) { Dividende.DecaleAdd(Mod,0); Quotient--; } if(ChercheQuotient) Res.Quotient->Nb.D[IndexThis]=Quotient; } return Res=Dividende; } Nb1024 Nb2048::operator% (const Nb1024 &Mod)const{ Nb1024 Res; if(ChercheQuotient) { if(Res.Quotient!=NULL) delete Res.Quotient; Res.Quotient=new Nb2048; *Res.Quotient=0; } //ChiffreBase : contient l'index du chiffre dans Dividende que l'on va utiliser pour faire la premiere approche de Quotient signed char IndexThis, ChiffreBase; for(IndexThis=63; this->Nb.D[IndexThis]==0; IndexThis--) if (IndexThis==0) return Res=0; for(ChiffreBase=31; Mod.Nb.D[ChiffreBase]==0; ChiffreBase--) if(ChiffreBase==0) exit(-1); //division par 0 if(IndexThis<ChiffreBase) return Res=*this; Nb2048 Dividende; //Dividende partiel traité à une itération de la boucle Dividende=0; for(int i=ChiffreBase-1; i>=0; i--, IndexThis--) Dividende.Nb.D[i]=this->Nb.D[IndexThis]; for(; IndexThis>=0; IndexThis--){ // TODO : A faire en Asm (SSE ou non, selon le mieux) for(int i=31; i>=0; i--) Dividende.Nb.D[i+1]=Dividende.Nb.D[i]; Dividende.Nb.D[0]=this->Nb.D[IndexThis]; unsigned long long Quotient, RestePart; asm ("divq %4" //Premiere estimation de Quotient :"=a" (Quotient), "=d" (RestePart) :"a" ( Dividende.Nb.D[ChiffreBase] + ((unsigned long long)Dividende.Nb.D[ChiffreBase+1]<<32)), "d" (0), "g" ( (unsigned long long)Mod.Nb.D[ChiffreBase]) ); bool QuotientOK=false; if(Quotient > 0xFFFFFFFF) { Quotient=0xFFFFFFFF; //RestePart = Dividende.Nb.D[ChiffreBase+1]:Dividende.Nb.D[ChiffreBase] - 0xFFFFFFFF * Md.Nb.D[ChiffreBase] RestePart= Dividende.Nb.D[ChiffreBase] + ((unsigned long long)Dividende.Nb.D[ChiffreBase+1]<<32) - ((unsigned long long)Mod.Nb.D[ChiffreBase]<<32) + Mod.Nb.D[ChiffreBase]<<32; if(RestePart & 0xFFFFFFFF00000000) QuotientOK=true; } //Ensuite, le but est de rajouter des chiffres et de calculer l'erreur que l'on commet : on multiplie l'estimation du quotient déjà faite par les chiffres //de Mod déja pris en compte puis on soustrait les chiffres de dividende déjà pris en compte. Si le résultat est négatif ou nul, pas de problème, //Quotient n'est pas trop grand (il ne peut pas être trop petit). Dans ce cas, l'opposé du résultat correspond au reste de la division. S'il est positif, //on le divise par les chiffres de Mod déjà pris en compte : on obtient un nombre qu'il faut soustraire à Quotient. Sans optimisation, cette méthode est //impossible : on se retrouve a faire des divisions avec un dénominateur énorme et tout un tas de multiplications... //Pour simplifier, on se rend compte que ce nombre est calculable a partir du reste de la division précédente (calculé lors de la derniere estimation de //Quotient: on supprime donc beaucoup de multiplications inutiles. De plus, seules la premiere itération de cette boucle est utiles : les autres ne pourront //Faire descendre Quotient que de 1 : on remplace donc toutes ces itérations par une comparaison entre Quotient*Mod et Diviseur, qui nous dira s'il faut //décrémenter Quotient ou non. //Petite vérification.. histoire de pas faire des opérations pour rien if(Quotient == 0) continue; if(ChiffreBase == 0) QuotientOK=true; if(!QuotientOK){ unsigned long long Tmp=Quotient*Mod.Nb.D[ChiffreBase-1]; if(Tmp > ((unsigned long long)RestePart<<32) + Dividende.Nb.D[ChiffreBase-1]) //Le nombre dont on parle dans le § de commentaires plus haut est positif : on réajuste Quotient //Diviseion en arrondissant par au dessus : d'où le 1 + et le -1 Quotient-=1 + (Tmp - ((unsigned long long)RestePart<<32) - Dividende.Nb.D[ChiffreBase-1] - 1) / ( ((unsigned long long)Mod.Nb.D[ChiffreBase]<<32) + Mod.Nb.D[ChiffreBase-1] ); } //On fait la grande multiplcation et soustraction Dividende=Dividende-Mod*Quotient; if(Dividende.carry) { Dividende.DecaleAdd(Mod,0); Quotient--; } if(ChercheQuotient) Res.Quotient->Nb.D[IndexThis]=Quotient; } return Res=Dividende; } inline bool Nb512::operator== (const Nb512 &Nb)const{ return !memcmp(&this->Nb,&Nb.Nb,sizeof(Nb.Nb)); } inline bool Nb1024::operator== (const Nb1024 &Nb)const{ return !memcmp(&this->Nb,&Nb.Nb,sizeof(Nb.Nb)); } inline bool Nb2048::operator== (const Nb2048 &Nb)const{ return !memcmp(&this->Nb,&Nb.Nb,sizeof(Nb.Nb)); } Nb512 Nb512::Puissance (const Nb512 &Exp, const Nb512 &Mod)const{ Nb512 Res; Res=1; //TODO ne pas faire les premiers octets vides for(int i=63; i>=0; i--) for(int j=128; j>0; j>>=1){ Res=Res*Res % Mod; if(Exp.Nb.B[i] & j){ Res=Res* *this % Mod; } } return Res; } Nb1024 Nb1024::Puissance (const Nb1024 &Exp, const Nb1024 &Mod)const{ Nb1024 Res; Res=1; //TODO ne pas faire les premiers octets vides for(int i=127; i>=0; i--) for(int j=128; j>0; j>>=1){ Res=Res*Res % Mod; if(Exp.Nb.B[i] & j){ Res=Res* *this % Mod; } } return Res; } void Nb512::Hasard (){ for(int i=0; i<8; i++){ NbHasard*=6364136223846793005; //Générateur de Haynes NbHasard++; this->Nb.Q[i]=NbHasard; } while ((Nb.Q[7] & ((unsigned long long)1<<63)) == 0){ //Pour avoir un VRAI nombre de 512 bits NbHasard*=6364136223846793005; //Générateur de Haynes NbHasard++; this->Nb.Q[7]=NbHasard; } } //http://cryptosec.lautre.net/article.php3?id_article=12 bool Nb512::MillerRabin(unsigned int Boucles)const{ unsigned int b; Nb512 thism1,un; un=1; thism1=*this -un; //calcul de b for(b=0;b<512; b+=64) if(thism1.Nb.Q[b>>6]!=0) break; if(b==512) return false; // *this==1 for(; b<512; b++) if( (thism1.Nb.Q[b>>6] & ( 1 << (b&63)) )!=0) break; //calcul de r Nb512 r; int i; for(i=0; i<7 - (b>>6); i++) r.Nb.Q[i]=(thism1.Nb.Q[i + (b>>6) + 1]<<(64-(b&63))) | (thism1.Nb.Q[i + (b>>6)]>>(b&63)); r.Nb.Q[i]=thism1.Nb.Q[i + (b>>6)]>>(b&63); for(i++; i<8; i++) r.Nb.Q[i]=0; for(i=0; i<Boucles; i++){ Nb512 a; a.Hasard(); //On s'assure que a<this* en mettant a 0 1 octet de plus dans a que dans this for(int j=63; j>=0; j--){ a.Nb.B[i]=0; if(this->Nb.B[i] != 0) break; } //y est représenté ici par a : a=a.Puissance(r,*this); if(a==un) continue; for( int j=0; j<b; j++){ if(a==un) return false; if(a==thism1) break; a=a*a % *this; } if(!(a==thism1)) return false; } return true; } void Nb512::Premier(){ do{ Hasard(); /*FIXME : utiliser un meilleur générateur aléatoire*/ Nb.B[0]|=1; } while (!MillerRabin(5)); } //trouve le nombre a tel que this*a = PGCD(this;Mod) modulo Mod //En fait, ici on l'appele avec this et Mod premiers entres eux.. donc PGCD=1 donc a*this = 1 modulo Mod donc a est bine l'inverse de this modulo Mod //On utilise pour ceci l'algoritme d'euclide étendu Nb1024 Nb1024::Inverse(const Nb1024 &Mod)const{ Nb1024 Tmp1024; struct sListeQuotients{ struct sListeQuotients* q; Nb1024 t; } *ListeQuotients=new struct sListeQuotients,*TmpListeQuotients; //On commence par appliquer l'algoritme d'euclide et on retient tous les quotients Nb1024 Nb2,Zero; Nb2048 Nb1; ListeQuotients->q=NULL; Zero=0; Nb1=Mod; Nb2=*this; do{ Nb1.ChercheQuotient=true; Tmp1024=Nb1 % Nb2; ListeQuotients->t=*Tmp1024.Quotient; Nb1=Nb2; Nb2=Tmp1024; TmpListeQuotients=new struct sListeQuotients; TmpListeQuotients->q=ListeQuotients; ListeQuotients=TmpListeQuotients; }while(!(Nb2==Zero)); //On enlève deux éléments de la liste : le premier car il est vide et le deuxième car on se fiche du dernier quotient obtenu TmpListeQuotients=ListeQuotients; ListeQuotients=ListeQuotients->q; delete TmpListeQuotients; TmpListeQuotients=ListeQuotients; ListeQuotients=ListeQuotients->q; delete TmpListeQuotients; //Et on le remonte pour finalement trouver les deux coefficients de Bezout, dont l'un est le nombre cherché //On calcule la suite : U(n-2)=U(n)-q(n-2)*U(n-1) où q(n) est le n-ième quotient calculé plus haut //Pour simplifier, on fait tous ces calculs modulo Mod. Si on se retrouve avec un U(n-2) négatif, on lui ajoute Mod Nb1024 Unm1,Un; Unm1=1; Un=0; while(ListeQuotients!=NULL){ Tmp1024=Un- ((ListeQuotients->t * Unm1) % Mod); if(Tmp1024.carry) Tmp1024=Tmp1024+Mod; Un=Unm1; Unm1=Tmp1024; TmpListeQuotients=ListeQuotients; ListeQuotients=ListeQuotients->q; delete TmpListeQuotients; } return Unm1; } int main(){ Nb512 p,q,un,clair512; un=1; Nb1024 n,e,d,phi,clair,chiffre,dechiffre; Nb2048 Verif; InitHasard(); p.Premier(); q.Premier(); n=p*q; printf("\n\nModulo commun aux deux clées :\n"); for(int i=31; i>=0; i--) printf("%.8X ",n.Nb.D[i]); phi=(p-un)*(q-un); e=0x10001; printf("\n\nExposant public e:(Par défaut, 0x10001)"); //for(int i=31; i>=0; i--) printf("%.8X ",e.Nb.D[i]); d=e.Inverse(phi); printf("\n\nExposant privé d :\n"); for(int i=31; i>=0; i--) printf("%.8X ",d.Nb.D[i]); printf("\n\nPour vérification, d*e mod phi(n)=(p-1)*(q-1): (doit être 1)\n"); Verif=d*e; Verif=Verif % phi; for(int i=31; i>=0; i--) printf("%.8X ",Verif.Nb.D[i]); printf("\n\n\nTest: Bloc de départ (non chiffré) :\n"); clair512.Hasard(); clair=clair512; clair512.Hasard(); clair.DecaleAdd(clair512,8); clair.Nb.B[127]&=0xf; for(int i=31; i>=0; i--) printf("%.8X ",clair.Nb.D[i]); printf("\n\nTest: Bloc chiffré :\n"); chiffre=clair.Puissance(e,n); for(int i=31; i>=0; i--) printf("%.8X ",chiffre.Nb.D[i]); printf("\n\nTest: Bloc déchiffré :\n"); dechiffre=chiffre.Puissance(d,n); for(int i=31; i>=0; i--) printf("%.8X ",dechiffre.Nb.D[i]); printf("\n"); } |
The Following User Says Thank You to MOURAD™ For This Useful Post: |
06-12-2012, 18:20 | #8 (permalink) |
No Life Poster Join Date: Oct 2010
Posts: 723
Member: 1422878 Status: Offline Thanks Meter: 164 | TurboPower LockBox LockBox 3 is a Delphi library for cryptography. It's free and provides support for AES, DES, 3DES, ****fish, Twofish, SHA, MD5, a variety of chaining modes, RSA digital signature and verific... It comes complete with a good RSA example that demonstrates how to generate your public/private keys and how to actually encrypt and decrypt data using the keys. HomePage : TurboPower LockBox 3 TurboPower LockBox | Free Security & Utilities software downloads at SourceForge.net Regards Helpy |
The Following 2 Users Say Thank You to helpinterchange For This Useful Post: |
Bookmarks |
Thread Tools | |
Display Modes | |
| |
Similar Threads | ||||
thread | Thread Starter | Forum | Replies | Last Post |
Help: Forgot my 6110 user lock code!! | GByte9 | Nokia Legacy Phones ( DCT-1 ,2 ,3 ,L ) | 4 | 02-26-2016 14:52 |
PIN1/PIN2 CODE | Jon | Nokia Legacy Phones ( DCT-1 ,2 ,3 ,L ) | 1 | 12-26-2012 04:40 |
Phone Stuff for FREE & KEy-GEn For Logo Editor ! | BoNtEk - ThA WtC MeMbA | Nokia Multimedia | 8 | 10-31-2012 20:17 |
2 FREE NOKIA SP SIM CARDS TO RELEASE FOR INFORMATION WE NEED | SP UNLOCKER 2000 | Nokia Legacy Phones ( DCT-1 ,2 ,3 ,L ) | 3 | 09-25-1999 03:34 |
|