Jump to content

RSA Algorithm


Recommended Posts

Hi all.

I tried to convert from VB to AutoIt this code:

VB

Public key(1 To 3) As Double
Public p As Double, q As Double
Public PHI As Double

Public Sub genereazaCheie()  'metoda care-o folosesc pentru a-mi genera cheile, poate fi facuta si functie
'Genereaza cheile pentru E, d, si N
Dim E#, D#, N#
Const PQ_UP As Integer = 9999   'imi setez limita superioara a numerelor aleatorii
Const PQ_LW As Integer = 3170   'imi setez limita inferioara a numerelor aleatorii
Const limita_cheii As Long = 10000000 'setare pentru 64 biti minim
p = 0: q = 0
Randomize
Do Until D > limita_cheii      'ma asigur ca cheile sunt cel putin pe 64 biti
    Do Until esteprim(p) And esteprim(q) ' ma asigur ca p si q sunt nr prime
        p = Int((PQ_UP - PQ_LW + 1) * Rnd + PQ_LW)
        q = Int((PQ_UP - PQ_LW + 1) * Rnd + PQ_LW)
    Loop
    N = p * q
    PHI = (p - 1) * (q - 1)
    E = cmmdc(PHI)            'cel mai mare divizor comun
    D = genereazaEuler(E, PHI) '
Loop
        key(1) = E
        key(2) = D
        key(3) = N
End Sub


Private Function genereazaEuler(E3 As Double, PHI3 As Double) As Double
'genereaza pe d (exponent privat) cu ajutorul alg.Euler
On Error Resume Next
Dim u1#, u2#, u3#, v1#, v2#, v3#, q#
Dim t1#, t2#, t3#, z#, uu#, vv#, inverse#
u1 = 1
u2 = 0
u3 = PHI3
v1 = 0
v2 = 1
v3 = E3
Do Until (v3 = 0)
     q = Int(u3 / v3)
     t1 = u1 - q * v1
     t2 = u2 - q * v2
     t3 = u3 - q * v3

     u1 = v1
     u2 = v2
     u3 = v3

     v1 = t1
     v2 = t2
     v3 = t3
     z = 1
Loop
uu = u1
vv = u2
If (vv < 0) Then
          inverse = vv + PHI3
Else
     inverse = vv
End If
genereazaEuler = inverse
End Function

Private Function cmmdc(nPHI As Double) As Double 'cel mai mare divizor comun dupa algoritmul lui Euclid
'generarea unui numar prim relativ la phi
On Error Resume Next

Dim nE#, Y#
Const N_UP = 99999999      'imi setez limita superioara a lui E
Const N_LW = 10000000      'imi setez limita inferioara a lui E
Randomize
nE = Int((N_UP - N_LW + 1) * Rnd + N_LW)
top:                        'acesta e un label
    X = nPHI Mod nE      'caluleaza restul impartirii lui phi la numarul generat nE
    Y = X Mod nE            'caluleaza restul impartirii lui x la numarul generat nE
    If Y <> 0 And esteprim(nE) Then 'verific daca restul y e dif de 0 si daca numarulk generat e prim
        cmmdc = nE        'daca ambele conditii sint indeplinite atunci am generat numar nE bun
        Exit Function
    Else
        nE = nE + 1      'daca nu, la numarul generat adun 1
    End If
    GoTo top
End Function

Private Function esteprim(lngNumber As Double) As Boolean
'functie care returneaza true daca lngNumber este este prim
On Error Resume Next
Dim lngCount#
Dim lngSqr#
Dim X#
lngSqr = Int(Sqr(lngNumber))            'calculeaza radical din numar
If lngNumber < 2 Then                  'verifica daca numarul e mai mic decit 2
        esteprim = False                'nu e prim deoarece e egal cu 1
        Exit Function
    End If
    lngCount = 2                        'atribuie variabilei lngCount valoarea 2
    esteprim = True                  'seteaza valaoarea lui isprime la true
    If lngNumber Mod lngCount = 0 Then  'verifica daca restul impartirii numarului lngNumber la 2 este 0, daca e 0 atunci numarul e divizibil cu 2, deci nu e prim
        esteprim = False
        Exit Function
    End If
    lngCount = 3                        'atribuie variabilei lngCount valoarea 3

        For X = lngCount To lngSqr Step 2 'verifica pt toate numerele cuprinse in intervalul [lngCount...lngSqr] din doi in doi, daca numarul nostru (lngNumber) e divizibil cu ele
        If lngNumber Mod X = 0 Then
            esteprim = False
            Exit Function
        End If
    Next
End Function

Public Function Mult(ByVal X As Double, ByVal p As Double, ByVal m As Double) As Double
'encripteaza/ decripteaza valori trimise catre functie
'Mult = M^E mod N (encrypt)  unde M = x , E = p, N = m
'Mult = M^D mod N (decrypt)
On Error GoTo error1
    Y = 1
    Do While p > 0
        Do While (p / 2) = Int((p / 2))
            X = nMod((X * X), m)
            p = p / 2
        Loop
        Y = nMod((X * Y), m)
        p = p - 1
    Loop
    Mult = Y
    Exit Function
error1:
Y = 0
End Function

Private Function nMod(X As Double, Y As Double) As Double
'imi inlocuiesc comanda Mod; in loc de z = x Mod y folosesc z = nMod(x,y)
'genereaza formula pt calculul modulo (restul impartirii a doua numere)
On Error Resume Next
Dim z#
z = X - (Int(X / Y) * Y) 'formula de calcul, imi scot intregul
nMod = z
End Function

Public Function encripteaza(tIp As String, EE As Double, eN As Double) As String
On Error Resume Next
Dim encSt As String
encSt = ""
e2st = ""
    If tIp = "" Then Exit Function
    For i = 1 To Len(tIp)
        encSt = encSt & Mult(CLng(Asc(Mid(tIp, i, 1))), EE, eN) & "+" 'imi construiesc sirul de caractere encriptate cu +
    Next i
encripteaza = encSt
End Function

Public Function dec(tIp As String, dD As Double, dN As Double) As String
'imi returnez caract din longuri pt a le putea reprezenta ca numere de ex A = 12345678, B = 23456789 etc..
On Error Resume Next
Dim decSt As String
decSt = ""
For z = 1 To Len(tIp)
    ptr = InStr(z, tIp, "+")
    tok = Val(Mid(tIp, z, ptr))
    decSt = decSt + Chr(Mult(tok, dD, dN))
    z = ptr
Next z
dec = decSt
End Function

and my code:

Global $KEY[3]
Global $P
Global $Q
Global $PHI

$GUI = GUICreate("RSA Algorithm",215,245,-1,-1,0x16C80000,0x00000181)
$P_INPUT = GUICtrlCreateInput("(P)",5,5,100,20,0x01)
$Q_INPUT = GUICtrlCreateInput("(Q)",110,5,100,20,0x01,0x0800)
$PHI_INP = GUICtrlCreateInput("(PHI)",5,30,100,20,0x01)
$GEN_KEY = GUICtrlCreateButton("Genereaza Chei",110,30,100,20)
$E_INP = GUICtrlCreateInput("(E)",5,55,100,20,0x01)
$N_INP = GUICtrlCreateInput("(N)",110,55,100,20,0x01)
$D_INP = GUICtrlCreateInput("(D)",5,80,100,20,0x01)
$TEXT_BOX = GUICtrlCreateEdit("Text",5,105,205,100,0x00200000)
$ENC_BUTTON = GUICtrlCreateButton("ENCRYPT",5,210,100,30)
$DEC_BUTTON = GUICtrlCreateButton("DECRYPT",110,210,100,30)
GUISetState(@SW_SHOW,$GUI)

While True
    $MSG = GUIGetMsg()
    Switch $MSG
        Case $GEN_KEY
            GenerateKey()
            GUICtrlSetData($P_INPUT,$P)
            GUICtrlSetData($Q_INPUT,$Q)
            GUICtrlSetData($PHI_INP,$PHI)
            GUICtrlSetData($E_INP,$KEY[0])
            GUICtrlSetData($N_INP,$KEY[2])
            GUICtrlSetData($D_INP,$KEY[1])
        Case $ENC_BUTTON
            $TEXT = GUICtrlRead($TEXT_BOX)
            $DATA = Encrypt($TEXT,$KEY[0],$KEY[2])
            GUICtrlSetData($TEXT_BOX,$DATA)
        Case $DEC_BUTTON
            $TEXT = GUICtrlRead($TEXT_BOX)
            $DATA = Decrypt($TEXT,$KEY[1],$KEY[2])
            GUICtrlSetData($TEXT_BOX,$DATA)
        Case -3
            Exit
    EndSwitch
    Sleep(20)
WEnd

Func GenerateKey()
    Local Const $UP_LIMIT = 9999
    Local Const $LW_LIMIT = 3170
    Local Const $KEY_LIMIT = 10000000
    Do
        Do
            $P = Int(($UP_LIMIT - $LW_LIMIT + 1) * Random() + $LW_LIMIT)
            $Q = Int(($UP_LIMIT - $LW_LIMIT + 1) * Random() + $LW_LIMIT)
        Until IsPrime($P) And IsPrime($Q)
        $N = $P * $Q
        $PHI = ($P - 1) * ($Q - 1)
        $E = CMMDC($PHI)
        $D = GenerateEuler($E,$PHI)
    Until $D > $KEY_LIMIT
    $KEY[0] = $E
    $KEY[1] = $D
    $KEY[2] = $N
    Return $KEY
EndFunc

Func IsPrime($NUM)
    $SQRT = Sqrt($NUM)
    If $NUM < 2 Then
        $IS_PRIME = False
        Return $IS_PRIME
    EndIf
    $COUNT = 2
    $IS_PRIME = True
    If Mod($NUM,$COUNT) = 0 Then
        $IS_PRIME = False
        Return $IS_PRIME
    EndIf
    $COUNT = 3
    For $X = $COUNT To $SQRT Step 2
        If Mod($NUM,$X) = 0 Then
            $IS_PRIME = False
            Return $IS_PRIME
        EndIf
    Next
    Return $IS_PRIME
EndFunc

Func CMMDC($PHI_NUM)
    Local Const $UP_LIMIT = 99999999
    Local Const $LW_LIMIT = 10000000
    Local $E = Int(($UP_LIMIT - $LW_LIMIT + 1) * Random() + $LW_LIMIT)
    While True
        $X = Mod($PHI_NUM,$E)
        $Y = Mod($X,$E)
        If $Y <> 0 And IsPrime($E) Then
            $CMMDC = $E
            Return $CMMDC
        Else
            $E += 1
        EndIf
    WEnd
EndFunc

Func GenerateEuler($E_NUM,$PHI_NUM)
    Local $U1 = 1
    Local $U2 = 0
    Local $U3 = $PHI_NUM
    Local $V1 = 0
    Local $V2 = 1
    Local $V3 = $E_NUM
    Do
        $QU = Int($U3/$V3)
        $T1 = $U1 - $QU * $V1
        $T2 = $U2 - $QU * $V2
        $T3 = $U3 - $QU * $V3
        $U1 = $V1
        $U2 = $V2
        $U3 = $V3
        $V1 = $T1
        $V2 = $T2
        $V3 = $T3
        $Z = 1
    Until $V3 = 0
    $UU = $U1
    $VV = $U2
    If ($VV < 0) Then
        $INVERSE = $VV + $PHI_NUM
    Else
        $INVERSE = $VV
    EndIf
    Return $INVERSE
EndFunc

Func Mult($X,$P_NUM,$M)
    $Y = 1
    Do
        Do
            $X = NMod(($X * $X),$M)
            $P_NUM = $P_NUM / 2
        Until ($P_NUM/2) <> Int(($P_NUM/2))
        $Y = NMod(($X * $Y),$M)
        $P_NUM = $P_NUM - 1
    Until $P_NUM < 0
    Return $Y
EndFunc

Func Encrypt($TEXT,$EE,$EN)
    Local $ENC = ""
    If $TEXT = "" Then Return ""
    For $INDEX = 1 To StringLen($TEXT)
        $ENC &= Mult(Int(Asc(StringMid($TEXT,$INDEX,1))),$EE,$EN) & "+"
    Next
    Return StringTrimRight($ENC,1)
EndFunc

Func Decrypt($TEXT,$DD,$DN)
    Local $DEC = ""
    $SPLIT = StringSplit($TEXT,"+")
    For $INDEX = 1 To $SPLIT[0]
        $TOK = Number($SPLIT[$INDEX])
        $DEC &= Chr(Mult($TOK,$DD,$DN))
    Next
    Return $DEC
EndFunc

But my code doesn't work. I think that Mult function I convert in wrong mode. Please correct me if I write somethign wrong. I didn't find something similar in AutoIt for CLng(). There is the wrong part? Who know VB please help me.

EDIT: I attach VB project source, if someone want to try the program written in VB:

RSA.rar

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

Can someone help me to convert this function in AutoIt?

Public Function Mult(ByVal X As Double, ByVal p As Double, ByVal m As Double) As Double
'encripteaza/ decripteaza valori trimise catre functie
'Mult = M^E mod N (encrypt)  unde M = x , E = p, N = m
'Mult = M^D mod N (decrypt)
MsgBox (X & " " & p & " " & m)
On Error GoTo error1
    Y = 1
    Do While p > 0
        Do While (p / 2) = Int((p / 2))
            X = nMod((X * X), m)
            p = p / 2
        Loop
        Y = nMod((X * Y), m)
        p = p - 1
    Loop
    Mult = Y
    MsgBox (Mult)
    Exit Function
error1:
Y = 0
End Function

When the words fail... music speaks.

Link to comment
Share on other sites

Mult(64, 8192, 0xCC)


Func Mult($dX, $dp, $dm)
    Local $dY = 1
; encripteaza/ decripteaza valori trimise catre functie
; Mult = M^E mod N (encrypt)  unde M = x , E = p, N = m
; Mult = M^D mod N (decrypt)
    
    While $dp > 0
        While ($dp / 2) = Int($dp / 2)
            $dX = Int(Mod($dX*$dX, $dm))
            $dp /= 2
        WEnd
        $dY = Int(Mod($dX * $dY, $dm))
        $dp -= 1
    WEnd
    
    MsgBox (0x40, 'Title', $dY)
    Return $dY
EndFunc

Link to comment
Share on other sites

Mult(64, 8192, 0xCC)


Func Mult($dX, $dp, $dm)
    Local $dY = 1
; encripteaza/ decripteaza valori trimise catre functie
; Mult = M^E mod N (encrypt)  unde M = x , E = p, N = m
; Mult = M^D mod N (decrypt)
    
    While $dp > 0
        While ($dp / 2) = Int($dp / 2)
            $dX = Int(Mod($dX*$dX, $dm))
            $dp /= 2
        WEnd
        $dY = Int(Mod($dX * $dY, $dm))
        $dp -= 1
    WEnd
    
    MsgBox (0x40, 'Title', $dY)
    Return $dY
EndFunc
Thanks, I solve this problem. The result is here:

Global $KEY[3]
Global $P
Global $Q
Global $PHI

#Region GUI
$GUI = GUICreate("RSA Algorithm",320,320,-1,-1,0x16C80000,0x00000181)
$P_LABEL = GUICtrlCreateLabel("(P)",5,5,100,20,BitOR(0x01,0x1000))
$P_INPUT = GUICtrlCreateInput("",5,30,100,20,0x01)
$Q_LABEL = GUICtrlCreateLabel("(Q)",110,5,100,20,BitOR(0x01,0x1000))
$Q_INPUT = GUICtrlCreateInput("",110,30,100,20,0x01)
$PHI_LABEL = GUICtrlCreateLabel("(PHI)",215,5,100,20,BitOR(0x01,0x1000))
$PHI_INP = GUICtrlCreateInput("",215,30,100,20,0x01)
$E_LABEL = GUICtrlCreateLabel("(E)",5,55,100,20,BitOR(0x01,0x1000))
$E_INP = GUICtrlCreateInput("",5,80,100,20,0x01)
$N_LABEL = GUICtrlCreateLabel("(N)",110,55,100,20,BitOR(0x01,0x1000))
$N_INP = GUICtrlCreateInput("",110,80,100,20,0x01)
$D_LABEL = GUICtrlCreateLabel("(D)",215,55,100,20,BitOR(0x01,0x1000))
$D_INP = GUICtrlCreateInput("",215,80,100,20,0x01)
$TEXT_BOX = GUICtrlCreateEdit("",5,105,310,180,0x00200000)
$GEN_KEY = GUICtrlCreateButton("Genereaza Chei",5,290,100,25)
$ENC_BUTTON = GUICtrlCreateButton("ENCRYPT",110,290,100,25)
$DEC_BUTTON = GUICtrlCreateButton("DECRYPT",215,290,100,25)
GUISetState(@SW_SHOW,$GUI)
#EndRegion

#Region Main Loop
While True
    $MSG = GUIGetMsg()
    Switch $MSG
        Case $GEN_KEY
            GenerateKey()
            GUICtrlSetData($P_INPUT,$P)
            GUICtrlSetData($Q_INPUT,$Q)
            GUICtrlSetData($PHI_INP,$PHI)
            GUICtrlSetData($E_INP,$KEY[0])
            GUICtrlSetData($N_INP,$KEY[2])
            GUICtrlSetData($D_INP,$KEY[1])
        Case $ENC_BUTTON
            $TEXT = GUICtrlRead($TEXT_BOX)
            $DATA = Encrypt($TEXT,$KEY[0],$KEY[2])
            GUICtrlSetData($TEXT_BOX,$DATA)
        Case $DEC_BUTTON
            $TEXT = GUICtrlRead($TEXT_BOX)
            $DATA = Decrypt($TEXT,$KEY[1],$KEY[2])
            GUICtrlSetData($TEXT_BOX,$DATA)
        Case -3
            Exit
    EndSwitch
    Sleep(20)
WEnd
#EndRegion

Func GenerateKey()
    Local Const $UP_LIMIT = 9999
    Local Const $LW_LIMIT = 3170
    Local Const $KEY_LIMIT = 10000000
    Do
        Do
            $P = Int(($UP_LIMIT - $LW_LIMIT + 1) * Random() + $LW_LIMIT)
            $Q = Int(($UP_LIMIT - $LW_LIMIT + 1) * Random() + $LW_LIMIT)
        Until IsPrime($P) And IsPrime($Q)
        $N = $P * $Q
        $PHI = ($P - 1) * ($Q - 1)
        $E = CMMDC($PHI)
        $D = GenerateEuler($E,$PHI)
    Until $D > $KEY_LIMIT
    $KEY[0] = $E
    $KEY[1] = $D
    $KEY[2] = $N
    Return $KEY
EndFunc

Func IsPrime($NUM)
    $SQRT = Sqrt($NUM)
    If $NUM < 2 Then
        $IS_PRIME = False
        Return $IS_PRIME
    EndIf
    $COUNT = 2
    $IS_PRIME = True
    If Mod($NUM,$COUNT) = 0 Then
        $IS_PRIME = False
        Return $IS_PRIME
    EndIf
    $COUNT = 3
    For $X = $COUNT To $SQRT Step 2
        If Mod($NUM,$X) = 0 Then
            $IS_PRIME = False
            Return $IS_PRIME
        EndIf
    Next
    Return $IS_PRIME
EndFunc

Func CMMDC($PHI_NUM)
    Local Const $UP_LIMIT = 99999999
    Local Const $LW_LIMIT = 10000000
    Local $E = Int(($UP_LIMIT - $LW_LIMIT + 1) * Random() + $LW_LIMIT)
    While True
        $X = Mod($PHI_NUM,$E)
        $Y = Mod($X,$E)
        If $Y <> 0 And IsPrime($E) Then
            $CMMDC = $E
            Return $CMMDC
        Else
            $E += 1
        EndIf
    WEnd
EndFunc

Func GenerateEuler($E_NUM,$PHI_NUM)
    Local $U1 = 1
    Local $U2 = 0
    Local $U3 = $PHI_NUM
    Local $V1 = 0
    Local $V2 = 1
    Local $V3 = $E_NUM
    Do
        $QU = Int($U3/$V3)
        $T1 = $U1 - $QU * $V1
        $T2 = $U2 - $QU * $V2
        $T3 = $U3 - $QU * $V3
        $U1 = $V1
        $U2 = $V2
        $U3 = $V3
        $V1 = $T1
        $V2 = $T2
        $V3 = $T3
        $Z = 1
    Until $V3 = 0
    $UU = $U1
    $VV = $U2
    If ($VV < 0) Then
        $INVERSE = $VV + $PHI_NUM
    Else
        $INVERSE = $VV
    EndIf
    Return $INVERSE
EndFunc

Func Mult($X,$P_NUM,$M)
    Local $Y = 1
    While $P_NUM > 0
        While ($P_NUM/2) = Int(($P_NUM/2))
            $X = NMod(($X*$X),$M)
            $P_NUM = $P_NUM/2
        WEnd
        $Y = NMod(($X*$Y),$M)
        $P_NUM = $P_NUM-1
    WEnd
    Return $Y
EndFunc

Func Encrypt($TEXT,$EE,$EN)
    Local $ENC = ""
    If $TEXT = "" Then Return ""
    For $INDEX = 1 To StringLen($TEXT)
        $ENC &= Mult(Asc(StringMid($TEXT,$INDEX,1)),$EE,$EN) & "+"
    Next
    Return StringTrimRight($ENC,1)
EndFunc

Func Decrypt($TEXT,$DD,$DN)
    Local $DEC = ""
    $SPLIT = StringSplit($TEXT,"+")
    For $INDEX = 1 To $SPLIT[0]
        $TOK = Number($SPLIT[$INDEX])
        $DEC &= Chr(Mult($TOK,$DD,$DN))
    Next
    Return $DEC
EndFunc

Func NMod($X,$Y)
    $Z = $X - (Int($X/$Y)* $Y)
    Return $Z
EndFunc

When the words fail... music speaks.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...