Jump to content

C to Autoit


Recommended Posts

Hello,

I'm trying "translate" XTEA decryption code to Autoit v3:

#include <stdint.h>
 
/* take 64 bits of data in v[0] and v[1] and 128 bits of key in k[0] - k[3] */
 
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const k[4]) {
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    for (i=0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
    }
    v[0]=v0; v[1]=v1;
}

Can someone who knows C help me, please?

Edited by Adrian777
Link to comment
Share on other sites

Hello,

I'm trying "translate" XTEA decryption code to Autoit v3:

#include <stdint.h>
 
/* take 64 bits of data in v[0] and v[1] and 128 bits of key in k[0] - k[3] */
 
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const k[4]) {
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    for (i=0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
    }
    v[0]=v0; v[1]=v1;
}

Can someone who knows C help me, please?

Something like this (EDIT corrected ^ to BitXOR and added ByRef to $v[2] after errors pointed out by Shaggis in next post)

; Author: Adrian777
; Topic Title: C to Autoit - AutoIt Forums
; Post URL: http://www.autoitscript.com/forum/topic/130435-c-to-autoit/page__view__findpost__p__907520

;#include <stdint.h>

;/* take 64 bits of data in v[0] and v[1] and 128 bits of key in k[0] - k[3] */

Func decipher( $num_rounds, ByRef $v[2], $k[4])
    Local $i;

    ;check types are near correct
    If Not IsInt($num_rounds) Then Return -1
    If Not IsArray($v) Then Return -2
    If UBound($v) < 2 Then Return -3
    If Not IsArray($k) Then Return -4
    If UBound($k) < 4 Then Return -5


    Local $v0 = $v[0], $v1 = $v[1], $delta = 0x9E3779B9, $sum = $delta * $num_rounds;

    For $i = 0 To num_rounds - 1
        $v1 -= BitXOR( ((BitShift($v0, -4) ^ BitShift($v0, 5)) + $v0) , ($sum + $k[BitAND(BitShift($sum, 11), 3)]));
        $sum -= $delta;
        $v0 -=  ByRef((BitShift($v1, -4) ^ BitShift($v1, 5)) + $v1) , ($sum + $k[BitAND($sum, 3)]));
    Next
    $v[0] = v0
    $v[1] = v1
EndFunc   ;==>decipher
Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Something like this

; Author: Adrian777
; Topic Title: C to Autoit - AutoIt Forums
; Post URL: http://www.autoitscript.com/forum/topic/130435-c-to-autoit/page__view__findpost__p__907520

;#include <stdint.h>

;/* take 64 bits of data in v[0] and v[1] and 128 bits of key in k[0] - k[3] */

Func decipher($num_rounds, $v[2], $k[4])
    Local $i;

    ;check types are near correct
    If Not IsInt($num_rounds) Then Return -1
    If Not IsArray($v) Then Return -2
    If UBound($v) < 2 Then Return -3
    If Not IsArray($k) Then Return -4
    If UBound($k) < 4 Then Return -5


    Local $v0 = $v[0], $v1 = $v[1], $delta = 0x9E3779B9, $sum = $delta * $num_rounds;

    For $i = 0 To num_rounds - 1
        $v1 -= ((BitShift($v0, -4) ^ BitShift($v0, 5)) + $v0) ^ ($sum + $k[BitAND(BitShift($sum, 11), 3)]);
        $sum -= $delta;
        $v0 -= ((BitShift($v1, -4) ^ BitShift($v1, 5)) + $v1) ^ ($sum + $k[BitAND($sum, 3)]);
    Next
    $v[0] = v0
    $v[1] = v1
EndFunc   ;==>decipher

^ operater in c is XOR, not an exponent like in autoit. Pretty sure this is it:

Func decipher($num_rounds,ByRef $v,ByRef const $k)
    Local $v0= $v[0], $v1= $v[1], $delta=0x9E3779B9, $sum = $delta*$num_rounds
    For $i=0 to $num_rounds Step 1
        $v1 -= BitXOR(BitXOR(BitShift($v0,-4),BitShift($v0,5)) + $v0,$sum + $k[BitAND(BitShift($sum,11),3)])
        $sum -= $delta
        $v0 -= BitXOR(BitXOR(BitShift($v1,-4),BitShift($v1,5)) + $v1,$sum + $k[BitAND($sum,3)])
    Next
    $v[0]=$v0
    $v[1]=$v1
EndFunc

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Link to comment
Share on other sites

^ operater in c is XOR, not an exponent like in autoit. Pretty sure this is it:

Yes you're right, I got that wrong.

EDIT: And I missed the ByRef for parameters$v, but I suspect that ByRef is not needed for $k.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const k[4]) {
    unsigned int i;

    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    for (i=0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
    }
    v[0]=v0; v[1]=v1;
}

This is some strange looking c code. I don't understand the parameter arguments of v[2] and k[4]. How do you refer to those parameters inside the function? As v[2] and k[4]? Or as v and k? Are v and k global variables?

Oh I get it now, that's a way of passing an array.

Edited by LaCastiglione
Link to comment
Share on other sites

@martin & Shaggi

Thank you! Code looks great and I don't have errors in console.

But what I need do with $v[0], $v[1]?

$v[0] and $v[1] are set in the function and the changes will be seen by whatever called the function because ByRef has been used as Shaggi showed. You will have to translate or understand some more of the C program.
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I found some easier to understand XTEA code:

/********************************************************************* 
*            Public Domiain Work 
*   The XTEA algorithm is public domain, as is this 
*   implementation for PICs using the CCS compilers. 
* 
********************************************************************/ 
int32 DELTA = 0x9e3779b9; 
int32 key[4]; 

/********************************************************************* 
* Function:      void Encode(int32* data, int8 dataLength) 
*            Encodes data pointed to by *data. dataLength is 
*            measured in int32s, and must be an even number. This 
*            means the minimum number of bytes to be encoded is 8. 
*            eg encoding 8 bytes: 
*               int8 some_bytes[8]; 
*               Encode(some_bytes,2); 
* 
*            uses the key[] variable - ensure it is appropriately loaded 
* 
********************************************************************/ 

void Encode(int32* data, int8 dataLength) 
{ 
   int8 i=0; 
   int32 x1; 
   int32 x2; 
   int32 sum; 
   int8 iterationCount; 

   while(i<dataLength) 
   { 
      sum = 0; 
      x1=data[i]; 
      x2=data[i+1]; 
      iterationCount = NUM_ITERATIONS; 

      while(iterationCount > 0) 
      { 
         x1 += (((x2<<4) ^ (x2>>5)) + x2) ^ (sum + key[(sum&0x03)]); 
         sum+=DELTA; 
         x2 += (((x1<<4) ^ (x1>>5)) + x1) ^ (sum + key[((sum>>11)&0x03)]); 
         iterationCount--; 
      } 
      data[i]=x1; 
      data[i+1]=x2; 
      i+=2; 
   } 
}

I try to translate to Autoit v3 by myself:

Global $Delta = 0x9e3779b9
Global $Key[4]
Func Encode($Data, $DataLenght)
$i=0
   While($i < $DataLenght)
      $Sum = 0;
      $x1=$Data[$i]
      $x2=$Data[$i+1]
      $IterationCount = NUM_ITERATIONS;

      While($IterationCount > 0)
         $x1 += ((($x2<<4) ^ (x2>>5)) + x2) ^ ($Sum + $Key[($Sum & 0x03)]);
         $Sum += $Delta
         $x2 += (((x1<<4) ^ (x1>>5)) + x1) ^ ($Sum + $Key[(($Sum>>11) & 0x03)]);
         $IterationCount -= 1
      WEnd
     $Data[$i]=$x1
     $Data[$i+1]=$x2
      $i+=2;
   WEnd
EndFunc

I've only problem with "<<" and ">>".

Link to comment
Share on other sites

I found some easier to understand XTEA code:

/********************************************************************* 
*            Public Domiain Work 
*   The XTEA algorithm is public domain, as is this 
*   implementation for PICs using the CCS compilers. 
* 
********************************************************************/ 
int32 DELTA = 0x9e3779b9; 
int32 key[4]; 

/********************************************************************* 
* Function:      void Encode(int32* data, int8 dataLength) 
*            Encodes data pointed to by *data. dataLength is 
*            measured in int32s, and must be an even number. This 
*            means the minimum number of bytes to be encoded is 8. 
*            eg encoding 8 bytes: 
*               int8 some_bytes[8]; 
*               Encode(some_bytes,2); 
* 
*            uses the key[] variable - ensure it is appropriately loaded 
* 
********************************************************************/ 

void Encode(int32* data, int8 dataLength) 
{ 
   int8 i=0; 
   int32 x1; 
   int32 x2; 
   int32 sum; 
   int8 iterationCount; 

   while(i<dataLength) 
   { 
      sum = 0; 
      x1=data[i]; 
      x2=data[i+1]; 
      iterationCount = NUM_ITERATIONS; 

      while(iterationCount > 0) 
      { 
        x1 += (((x2<<4) ^ (x2>>5)) + x2) ^ (sum + key[(sum&0x03)]); 
        sum+=DELTA; 
        x2 += (((x1<<4) ^ (x1>>5)) + x1) ^ (sum + key[((sum>>11)&0x03)]); 
        iterationCount--; 
      } 
      data[i]=x1; 
      data[i+1]=x2; 
      i+=2; 
   } 
}

I try to translate to Autoit v3 by myself:

Global $Delta = 0x9e3779b9
Global $Key[4]
Func Encode($Data, $DataLenght)
$i=0
   While($i < $DataLenght)
      $Sum = 0;
      $x1=$Data[$i]
    $x2=$Data[$i+1]
      $IterationCount = NUM_ITERATIONS;

      While($IterationCount > 0)
        $x1 += ((($x2<<4) ^ (x2>>5)) + x2) ^ ($Sum + $Key[($Sum & 0x03)]);
        $Sum += $Delta
        $x2 += (((x1<<4) ^ (x1>>5)) + x1) ^ ($Sum + $Key[(($Sum>>11) & 0x03)]);
        $IterationCount -= 1
      WEnd
    $Data[$i]=$x1
    $Data[$i+1]=$x2
      $i+=2;
   WEnd
EndFunc

I've only problem with "<<" and ">>".

No, you have many problems.

Shaggi has alread shown how to deal with ^, &, << and >> .

The parameter data is passed as a pointer and that is equivalent to ByRef in AutoIt.

You need to look at Shaggi's translation again.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

@martin

Global $Delta = 0x9e3779b9
Global $Key[4]
Func Encode(ByRef $Data, $DataLenght)
$i=0
   While($i < $DataLenght)
      $Sum = 0;
      $x1=$Data[$i]
      $x2=$Data[$i+1]
      $IterationCount = 64

      While($IterationCount > 0)
         $x1 += BitXOR(BitXOR(BitShift($x2,-4),BitShift($x2,5)) + $x2,$sum + $Key[BitAND(BitShift($Sum,11),3)])
         $Sum += $Delta
         $x2 += BitXOR(BitXOR(BitShift($x1,-4),BitShift($x1,5)) + $x1,$sum + $Key[BitAND($Sum,3)])
         $IterationCount -= 1
      WEnd
     $Data[$i]=$x1
     $Data[$i+1]=$x2
      $i+=2;
   WEnd
EndFunc

Local $Encypt[8] = [1, 2, 3, 4, 5, 6, 7, 8]
Encode($Encypt, 2)

Is is working good? Arrays $Encrypt[$x] are random numbers.

Edited by Adrian777
Link to comment
Share on other sites

@martin

Global $Delta = 0x9e3779b9
Global $Key[4]
Func Encode(ByRef $Data, $DataLenght)
$i=0
   While($i < $DataLenght)
      $Sum = 0;
      $x1=$Data[$i]
    $x2=$Data[$i+1]
      $IterationCount = 64

      While($IterationCount > 0)
        $x1 += BitXOR(BitXOR(BitShift($x2,-4),BitShift($x2,5)) + $x2,$sum + $Key[BitAND(BitShift($Sum,11),3)])
        $Sum += $Delta
        $x2 += BitXOR(BitXOR(BitShift($x1,-4),BitShift($x1,5)) + $x1,$sum + $Key[BitAND($Sum,3)])
        $IterationCount -= 1
      WEnd
    $Data[$i]=$x1
    $Data[$i+1]=$x2
      $i+=2;
   WEnd
EndFunc

Local $Encypt[8] = [1, 2, 3, 4, 5, 6, 7, 8]
Encode($Encypt, 2)

Is is working good? Arrays $Encrypt[$x] are random numbers.

You have mixed upthe key indexes in the calculation for $x1 and $x2 compared to the C code you are using. Otherwise I think it is ok.
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

  • 6 years later...

I realize this thread is seriously old, but for people who might think this is a valid translation of XTEA algorithm, I've found it in fact does not work (at least not compatibly with the XTEA standard, so something encrypted elsewhere wouldn't be decrypted by the above code).

First, BitShift in AutoIT is arithmatic, not logical type, meaning it will do sign extension on a right shift, so if the MSb on a 32-bit number is set, it will shift in 1's instead of 0's.  This is different from C.

Also, at least with AutoIT 3 on a Windows 10 64-bit machine, it uses 32-bit numbers for math, but it stores it in 64 bits, and some operations result in sign extension, meaning the next bit shift operation will produce a bad result.

Finally, Shaggi's corrections are good, but the # of loop iterations got off by 1.

I used C code in Visual Studio with the original open source C code to generate some known good numbers, then debugged the AutoIT code until I found the problems above.   I ended up making my own wrapper for BitShift, and some tweaks to the above code.

My (tested) solution:

#Region uBitShift
; =============================================================================
; unsigned bit shifter (logical bit shift)
; the built-in AutoIT method is an arithmatic bit shift, which doesn't work
; when porting from C code)
; arguments are the same as BitShift()
; =============================================================================
Func uBitShift ($uValue, $shift)

    Local $signBit = BitAND($uValue, 0x80000000)
    Local $shiftedVal = BitShift($uValue, $shift)

    If $signBit <> 0x00 And $shift > 0 Then
        ; remove sign extension that BitShift put in 
        Local $mask = $signBit  ; make inverted mask (easier)
        While ($shift > 0)
            $mask = BitOR ($mask, $signBit)
            $signBit /= 2
            $shift -= 1
        WEnd

        $shiftedVal = BitAND ($shiftedVal, BitNOT ($mask))
    EndIf
    Return $shiftedVal

EndFunc
#EndRegion

#Region Encipher
; =============================================================================
; Encrypt data with XTEA
; v = data (2 4-byte chunks), k = key, num_rounds suggested to be 64
; =============================================================================
Func Encipher($num_rounds, ByRef $v, const $k)
    Local $v0= $v[0], $v1= $v[1], $delta=0x9E3779b9, $sum = 0
    ; AutoIT weird bug - values are treated as 32 bits, but stores it in 64 bits
    ; use BitAND with 0xFFFFFFFF to keep it from extending sign bit into top half of 64 bits
    ; also, use my own uBitShift (logical bit shift) instead of their (arithmatic)
    ; BitShift with sign extension

    For $i=0 to $num_rounds-1 Step 1
        $v0 += BitXOR(BitXOR(uBitShift($v1,-4),uBitShift($v1,5)) + $v1,$sum + $k[BitAND($sum,3)])
        $v0  = BitAND($v0, 0xFFFFFFFF)
        $sum = BitAND($delta + $sum, 0xFFFFFFFF)
        $v1 += BitXOR(BitXOR(uBitShift($v0,-4),uBitShift($v0,5)) + $v0,$sum + $k[BitAND(uBitShift($sum,11),3)])
        $v1  = BitAND($v1, 0xFFFFFFFF)
        ConsoleWrite("...ciphering:" & hex($v0) & " " & hex($v1) & @CRLF) ;### Debug Console
    Next

    $v[0]=$v0
    $v[1]=$v1
EndFunc
#EndRegion

#Region Decipher
; =============================================================================
; Decrypt data with XTEA
; v = data, k = key, num_rounds suggested to be 64
; =============================================================================
Func Decipher($num_rounds, ByRef $v, const $k)
    Local $v0= $v[0], $v1= $v[1], $delta=0x9E3779b9, $sum = $delta * $num_rounds
    ; AutoIT weird bug - values are treated as 32 bits, but stores it in 64 bits
    ; use BitAND with 0xFFFFFFFF to keep it from extending sign bit into top half of 64 bits
    ; also, use my own uBitShift (logical bit shift) instead of their (arithmatic)
    ; BitShift with sign extension

    For $i=0 to $num_rounds-1 Step 1
        $v1 -= BitXOR(BitXOR(uBitShift($v0,-4),uBitShift($v0,5)) + $v0,$sum + $k[BitAND(uBitShift($sum,11),3)])
        $v1  = BitAND($v1, 0xFFFFFFFF)
        $sum = BitAND($sum - $delta, 0xFFFFFFFF)
        $v0 -= BitXOR(BitXOR(uBitShift($v1,-4),uBitShift($v1,5)) + $v1,$sum + $k[BitAND($sum,3)])
        $v0  = BitAND($v0, 0xFFFFFFFF)
    Next
    $v[0]=$v0
    $v[1]=$v1
EndFunc
#EndRegion

  ; main code ...
  
        Local $startval[2]
        $startval[0] = 0x00112233
        $startval[1] = 0xCCDDEEFF
        Local $cipherkey[4]
        $cipherkey[0] = 0x09
        $cipherkey[1] = 0x0A
        $cipherkey[2] = 0x0B
        $cipherkey[3] = 0x0C
        
        ConsoleWrite("Original data:" & Hex($startval[0]) & " " & Hex($startval[1]) & @CRLF) ;### Debug Console
        ConsoleWrite("Key:" & Hex($cipherkey[0]) & " " & Hex($cipherkey[1]) & " " & Hex($cipherkey[2]) & " " & Hex($cipherkey[3]) & @CRLF) ;### Debug Console
        Encipher (4, $startval, $cipherkey)
        ConsoleWrite("Encoded data:" & Hex($startval[0]) & " " & Hex($startval[1]) & @CRLF) ;### Debug Console
        Decipher (4, $startval, $cipherkey)
        ConsoleWrite("Decoded data:" & Hex($startval[0]) & " " & Hex($startval[1]) & @CRLF) ;### Debug Console

(Also, In my personal implementation I'm keeping the delta in two parts which I OR together, so if somebody searches my .exe they won't find the XTEA signature as an easy give-away to what kind of encryption it uses.  But I simplified it here to better match the public domain examples.)

Output:

Original data:00112233 CCDDEEFF
Key:00000009 0000000A 0000000B 0000000C
...ciphering:98A711C2 864A3EB4
...ciphering:1193926C 9D71FE76
...ciphering:5E9C26E0 30E6D998
...ciphering:F9140CB3 2828787D
Encoded data:F9140CB3 2828787D
Decoded data:00112233 CCDDEEFF

 

Edited by quickbeam
Minor clarifications
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...