Read Write AES - OOP

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Read Write AES - OOP

Post by StarBootics »

Hello everyone,

A small library based on AESEncode()/AESDecode().
I'm releasing it in hope it might be useful to some one.

I'm encouraging anyone to review this library before using it in your project.
Please be advise that you are using it at your own risk.

@Saki : Is this library is more what you have in mind ?

Best regards
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Object - V1.1.0
; Project name : Read Write AES
; File name : Read Write AES - OOP.pb
; File Version : 1.0.1
; Programmation : OK
; Programmed by : StarBootics
; Creation Date : October 26th, 2020
; Last update : October 29th, 2020
; Coded for PureBasic : V5.72
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule AES
  
  #Bits_128 = 128
  #Bits_192 = 192
  #Bits_256 = 256
  
  Interface AES
    
    GetKey.s()
    GetBits.w()
    GetInitVector.s()
    SetKey(P_Key.s)
    SetBits(P_Bits.w)
    SetInitVector(P_InitVector.s)
    
    AES_WriteString(FileID.i, P_String.s)
    AES_WriteByte(FileID.i, P_Value.b)
    AES_WriteAsciiCharacter(FileID.i, P_Value.a)
    AES_WriteWord(FileID.i, P_Value.w)
    AES_WriteUnicodeCharacter(FileID.i, P_Value.u)
    AES_WriteCharacter(FileID.i, P_Value.c)
    AES_WriteLong(FileID.i, P_Value.l)
    AES_WriteQuad(FileID.i, P_Value.q)
    AES_WriteInteger(FileID.i, P_Value.i)
    AES_WriteFloat(FileID.i, P_Value.f)
    AES_WriteDouble(FileID.i, P_Value.d)
    
    AES_ReadString.s(FileID.i)
    AES_ReadByte.b(FileID.i)
    AES_ReadAsciiCharacter.a(FileID.i)
    AES_ReadWord.w(FileID.i)
    AES_ReadUnicodeCharacter.u(FileID.i)
    AES_ReadCharacter.c(FileID.i)
    AES_ReadLong.l(FileID.i)
    AES_ReadQuad.q(FileID.i)
    AES_ReadInteger.i(FileID.i)
    AES_ReadFloat.f(FileID.i)
    AES_ReadDouble.d(FileID.i)
    
    Free()
    
  EndInterface
  
  Declare.i New(P_Key.s = "AESCrypting", P_Bits.w = #Bits_128, P_InitVector.s = "AESInitVector")
  
EndDeclareModule

Module AES
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Structure Declaration <<<<<

  Structure Private_Members
    
    VirtualTable.i
    Key.s
    Bits.w
    InitVector.s
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Getters <<<<<

  Procedure.s GetKey(*This.Private_Members)
    
    ProcedureReturn *This\Key
  EndProcedure
  
  Procedure.w GetBits(*This.Private_Members)
    
    ProcedureReturn *This\Bits
  EndProcedure
  
  Procedure.s GetInitVector(*This.Private_Members)
    
    ProcedureReturn *This\InitVector
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Setters <<<<<

  Procedure SetKey(*This.Private_Members, P_Key.s)
    
    If P_Key <> ""
      *This\Key = P_Key
    Else
      *This\Key = "AESCrypting"
    EndIf
    
  EndProcedure
  
  Procedure SetBits(*This.Private_Members, P_Bits.w)
    
    Select P_Bits
        
      Case #Bits_128
        *This\Bits = P_Bits
        
      Case #Bits_192
        *This\Bits = P_Bits
        
      Case #Bits_256
        *This\Bits = P_Bits
        
      Default
        *This\Bits = #Bits_128
        
    EndSelect
    
  EndProcedure
  
  Procedure SetInitVector(*This.Private_Members, P_InitVector.s)
    
    If P_InitVector <> ""
      *This\InitVector = P_InitVector
    Else
      *This\InitVector = "AESCrypting"
    EndIf
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Write on file operators <<<<<
  
  Procedure AES_WriteString(*This.Private_Members, FileID.i, String.s)
    
    Select *This\Bits
        
      Case #Bits_128
        *KeyBuffer = Ascii(Left(StringFingerprint(*This\Key, #PB_Cipher_MD5), 16))
        
      Case #Bits_192
        *KeyBuffer = Ascii(Left(StringFingerprint(*This\Key, #PB_Cipher_MD5), 24))
        
      Case #Bits_256
        *KeyBuffer = Ascii(StringFingerprint(*This\Key, #PB_Cipher_MD5))
        
    EndSelect
    
    *InitVectorBuffer = Ascii(Left(StringFingerprint(*This\InitVector, #PB_Cipher_MD5), 16))
    
    WriteLong(FileID, Len(String))
    
    While StringByteLength(String) < 16
      String + " "
    Wend
    
    StringMemorySize = StringByteLength(String) + SizeOf(Character)
    *CipheredString = AllocateMemory(StringMemorySize)
    
    If AESEncoder(@String, *CipheredString, StringByteLength(String), *KeyBuffer, *This\Bits, *InitVectorBuffer)
      
      WriteLong(FileID, StringMemorySize)
      WriteData(FileID, *CipheredString, StringMemorySize)
      
    EndIf
    
    If *KeyBuffer <> #Null
      FreeMemory(*KeyBuffer)
    EndIf
    
    If *InitVectorBuffer <> #Null
      FreeMemory(*InitVectorBuffer)
    EndIf
    
    If *CipheredString <> #Null
      FreeMemory(*CipheredString)
    EndIf
    
  EndProcedure
  
  Procedure AES_WriteByte(*This.Private_Members, FileID.i, P_Value.b)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteAsciiCharacter(*This.Private_Members, FileID.i, P_Value.a)
    
    AES_WriteString(*This, FileID, RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteWord(*This.Private_Members, FileID.i, P_Value.w)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteCharacter(*This.Private_Members, FileID.i, P_Value.c)
    
    AES_WriteString(*This, FileID, RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteUnicodeCharacter(*This.Private_Members, FileID.i, P_Value.u)
    
    AES_WriteString(*This, FileID, RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteLong(*This.Private_Members, FileID.i, P_Value.l)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 22, "0"))
    
  EndProcedure
  
  Procedure AES_WriteQuad(*This.Private_Members, FileID.i, P_Value.q)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 42, "0"))
    
  EndProcedure
  
  Procedure AES_WriteInteger(*This.Private_Members, FileID.i, P_Value.i)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 42, "0"))
    
  EndProcedure
  
  Procedure AES_WriteFloat(*This.Private_Members, FileID.i, P_Value.f)
    
    AES_WriteString(*This, FileID, StrF(P_Value, 14))
    
  EndProcedure
  
  Procedure AES_WriteDouble(*This.Private_Members, FileID.i, P_Value.d)
    
    AES_WriteString(*This, FileID, StrD(P_Value, 25))
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Read on file operators <<<<<
  
  Procedure.s AES_ReadString(*This.Private_Members, FileID.i)
    
    Select *This\Bits
        
      Case #Bits_128
        *KeyBuffer = Ascii(Left(StringFingerprint(*This\Key, #PB_Cipher_MD5), 16))
        
      Case #Bits_192
        *KeyBuffer = Ascii(Left(StringFingerprint(*This\Key, #PB_Cipher_MD5), 24))
        
      Case #Bits_256
        *KeyBuffer = Ascii(StringFingerprint(*This\Key, #PB_Cipher_MD5))
        
    EndSelect
    
    *InitVectorBuffer = Ascii(Left(StringFingerprint(*This\InitVector, #PB_Cipher_MD5), 16))
    
    OriginalStringLen.l = ReadLong(FileID)
    StringMemorySize.l = ReadLong(FileID)
    
    *CipheredString = AllocateMemory(StringMemorySize)
    *DecipheredString = AllocateMemory(StringMemorySize) 
    
    ReadData(FileID, *CipheredString, StringMemorySize)

    AESDecoder(*CipheredString, *DecipheredString, StringMemorySize - SizeOf(Character), *KeyBuffer, *This\Bits, *InitVectorBuffer)
    Output.s = Left(PeekS(*DecipheredString), OriginalStringLen)
    
    If *KeyBuffer <> #Null
      FreeMemory(*KeyBuffer)
    EndIf
    
    If *InitVectorBuffer <> #Null
      FreeMemory(*InitVectorBuffer)
    EndIf
    
    If *CipheredString <> #Null
      FreeMemory(*CipheredString)
    EndIf
    
    If *DecipheredString <> #Null
      FreeMemory(*DecipheredString)
    EndIf
    
    ProcedureReturn Output
  EndProcedure
  
  Procedure.b AES_ReadByte(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.a AES_ReadAsciiCharacter(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.w AES_ReadWord(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.c AES_ReadCharacter(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.u AES_ReadUnicodeCharacter(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.l AES_ReadLong(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.q AES_ReadQuad(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.i AES_ReadInteger(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.f AES_ReadFloat(*This.Private_Members, FileID.i)
    
    ProcedureReturn ValF(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.d AES_ReadDouble(*This.Private_Members, FileID.i)
    
    ProcedureReturn ValD(AES_ReadString(*This, FileID))
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Destructor <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Constructor <<<<<

  Procedure.i New(P_Key.s = "AESCrypting", P_Bits.w = #Bits_128, P_InitVector.s = "AESInitVector")
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    SetKey(*This, P_Key)
    SetBits(*This, P_Bits)
    SetInitVector(*This, P_InitVector)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Virtual Table Entries <<<<<

  DataSection
    START_METHODS:
    Data.i @GetKey()
    Data.i @GetBits()
    Data.i @GetInitVector()
    Data.i @SetKey()
    Data.i @SetBits()
    Data.i @SetInitVector()
    Data.i @AES_WriteString()
    Data.i @AES_WriteByte()
    Data.i @AES_WriteAsciiCharacter()
    Data.i @AES_WriteWord()
    Data.i @AES_WriteUnicodeCharacter()
    Data.i @AES_WriteCharacter()
    Data.i @AES_WriteLong()
    Data.i @AES_WriteQuad()
    Data.i @AES_WriteInteger()
    Data.i @AES_WriteFloat()
    Data.i @AES_WriteDouble()
    Data.i @AES_ReadString()
    Data.i @AES_ReadByte()
    Data.i @AES_ReadAsciiCharacter()
    Data.i @AES_ReadWord()
    Data.i @AES_ReadUnicodeCharacter()
    Data.i @AES_ReadCharacter()
    Data.i @AES_ReadLong()
    Data.i @AES_ReadQuad()
    Data.i @AES_ReadInteger()
    Data.i @AES_ReadFloat()
    Data.i @AES_ReadDouble()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.001 seconds (114000.00 lines/second) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

CompilerIf #PB_Compiler_IsMainFile
  
  UseMD5Fingerprint()
  
  AES.AES::AES = AES::New()
  
  Varb.b = 112
  Varw.w = 32700
  Varl.l = -2147483645
  Varq.q = 9223372036854775800
  Varf.f = 2 * #PI
  Vard.d = 3 * #PI
  Text.s = "J'aime les déesses nordiques super sexy !!!!!"
  Text2.s = "Hello "
  
  Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
  Debug "; Test on file"
  Debug ""
  Debug "Original : "
  
  Debug Varb
  Debug Varw
  Debug Varl
  Debug Varq
  Debug Varf
  Debug Vard
  Debug Text
  Debug Text2
  Debug ""
  
  If CreateFile(0, "Test.aes")
    
    AES\SetKey("I'm the key")
    AES\SetInitVector("I'm the InitVector")
    
    AES\AES_WriteByte(0, Varb) 
    AES\AES_WriteWord(0, Varw) 
    AES\AES_WriteLong(0, Varl)  
    AES\AES_WriteQuad(0, Varq)
    
    AES\SetKey("I'm the new key for the rest")
    AES\SetInitVector("I'm the new InitVector for the rest")
    
    AES\AES_WriteFloat(0, Varf)
    AES\AES_WriteDouble(0, Vard)
    AES\AES_WriteString(0, Text)
    AES\AES_WriteString(0, Text2)
    
    CloseFile(0)
    
  EndIf 
  
  Debug "File size : " + Str(FileSize("Test.aes")) + " bits" 
  Debug "From the file : " 
  
  If ReadFile(1, "Test.aes")
    
    AES\SetKey("I'm the key")
    AES\SetInitVector("I'm the InitVector")
    
    Debug AES\AES_ReadByte(1)
    Debug AES\AES_ReadWord(1)
    Debug AES\AES_ReadLong(1)
    Debug AES\AES_ReadQuad(1)
    
    AES\SetKey("I'm the new key for the rest")
    AES\SetInitVector("I'm the new InitVector for the rest")
    
    Debug AES\AES_ReadFloat(1)
    Debug AES\AES_ReadDouble(1)
    Debug AES\AES_ReadString(1)
    Debug AES\AES_ReadString(1)
    
    CloseFile(1)
    DeleteFile("Test.aes")
    
  EndIf 
  
  AES\Free()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Last edited by StarBootics on Fri Oct 30, 2020 12:14 am, edited 2 times in total.
The Stone Age did not end due to a shortage of stones !
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Read Write AES - OOP

Post by Saki »

AES also has its pitfalls.
But convert the key and IV hash to binary and use a SHA3 for that.
Otherwise you shorten the binary key length and the IV with a ascii string by 50%
With AES128 only 8 bytes effective key length remain.
You have to work on it for a long time to get everything as error-free as possible.
And even then it is still problematic.

But it is nice that you do these things.

Best Regards Saki
Last edited by Saki on Wed Oct 28, 2020 11:24 am, edited 1 time in total.
地球上の平和
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Read Write AES - OOP

Post by StarBootics »

Hello everyone,

A little update on the library (V1.1.0). Now you can choose the Cipher to use for the StringFingerprint() :
  • #PB_Cipher_MD5
    #PB_Cipher_SHA1
    #PB_Cipher_SHA2
    #PB_Cipher_SHA3
Call the appropriate Use****Fingerprint() somewhere in your program.

Best regards
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Object - V1.1.0
; Project name : Read Write AES
; File name : Read Write AES - OOP.pb
; File Version : 1.1.1
; Programmation : OK
; Programmed by : StarBootics
; Creation Date : October 26th, 2020
; Last update : October 29th, 2020
; Coded for PureBasic : V5.72
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule AES
  
  #Bits_128 = 128
  #Bits_192 = 192
  #Bits_256 = 256
  
  Interface AES
    
    GetKey.s()
    GetInitVector.s()
    GetBits.w()
    GetCipherPluginID.i()
    SetKey(P_Key.s)
    SetInitVector(P_InitVector.s)
    SetBits(P_Bits.w)
    SetCipherPluginID(P_CipherPluginID.i)
    
    AES_WriteString(FileID.i, P_String.s)
    AES_WriteByte(FileID.i, P_Value.b)
    AES_WriteAsciiCharacter(FileID.i, P_Value.a)
    AES_WriteWord(FileID.i, P_Value.w)
    AES_WriteUnicodeCharacter(FileID.i, P_Value.u)
    AES_WriteCharacter(FileID.i, P_Value.c)
    AES_WriteLong(FileID.i, P_Value.l)
    AES_WriteQuad(FileID.i, P_Value.q)
    AES_WriteInteger(FileID.i, P_Value.i)
    AES_WriteFloat(FileID.i, P_Value.f)
    AES_WriteDouble(FileID.i, P_Value.d)
    
    AES_ReadString.s(FileID.i)
    AES_ReadByte.b(FileID.i)
    AES_ReadAsciiCharacter.a(FileID.i)
    AES_ReadWord.w(FileID.i)
    AES_ReadUnicodeCharacter.u(FileID.i)
    AES_ReadCharacter.c(FileID.i)
    AES_ReadLong.l(FileID.i)
    AES_ReadQuad.q(FileID.i)
    AES_ReadInteger.i(FileID.i)
    AES_ReadFloat.f(FileID.i)
    AES_ReadDouble.d(FileID.i)
    
    Free()
    
  EndInterface
  
  Declare.i New(P_Key.s = "AESCrypting", P_InitVector.s = "AESInitVector", P_Bits.w = #Bits_128, P_CipherPluginID.i = #PB_Cipher_MD5)
  
EndDeclareModule

Module AES
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Structure Declaration <<<<<

  Structure Private_Members
    
    VirtualTable.i
    Key.s
    InitVector.s
    Bits.w
    CipherPluginID.i
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Getters <<<<<

  Procedure.s GetKey(*This.Private_Members)
    
    ProcedureReturn *This\Key
  EndProcedure
  
  Procedure.s GetInitVector(*This.Private_Members)
    
    ProcedureReturn *This\InitVector
  EndProcedure
  
  Procedure.w GetBits(*This.Private_Members)
    
    ProcedureReturn *This\Bits
  EndProcedure
  
  Procedure.i GetCipherPluginID(*This.Private_Members)
    
    ProcedureReturn *This\CipherPluginID
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Setters <<<<<

  Procedure SetKey(*This.Private_Members, P_Key.s)
    
    If P_Key <> ""
      *This\Key = P_Key
    Else
      *This\Key = "AESCrypting"
    EndIf
    
  EndProcedure
  
  Procedure SetInitVector(*This.Private_Members, P_InitVector.s)
    
    If P_InitVector <> ""
      *This\InitVector = P_InitVector
    Else
      *This\InitVector = "AESCrypting"
    EndIf
    
  EndProcedure
  
  Procedure SetBits(*This.Private_Members, P_Bits.w)
    
    Select P_Bits
        
      Case #Bits_128
        *This\Bits = P_Bits
        
      Case #Bits_192
        *This\Bits = P_Bits
        
      Case #Bits_256
        *This\Bits = P_Bits
        
      Default
        *This\Bits = #Bits_128
        
    EndSelect
    
  EndProcedure
  
  Procedure.i SetCipherPluginID(*This.Private_Members, P_CipherPluginID.i)
    
    CompilerIf #PB_Compiler_Debugger
      
      If P_CipherPluginID = #PB_Cipher_CRC32
        DebuggerError("Read Write AES\SetCipherPluginID() - #PB_Cipher_CRC32 not supported")
      EndIf
      
    CompilerEndIf

    *This\CipherPluginID = P_CipherPluginID
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Write on file operators <<<<<
  
  Procedure AES_WriteString(*This.Private_Members, FileID.i, String.s)
    
    Select *This\Bits
        
      Case #Bits_128
        *KeyBuffer = Ascii(Left(StringFingerprint(*This\Key, *This\CipherPluginID), 16))
        
      Case #Bits_192
        *KeyBuffer = Ascii(Left(StringFingerprint(*This\Key, *This\CipherPluginID), 24))
        
      Case #Bits_256
        *KeyBuffer = Ascii(StringFingerprint(*This\Key, *This\CipherPluginID))
        
    EndSelect
    
    *InitVectorBuffer = Ascii(Left(StringFingerprint(*This\InitVector, *This\CipherPluginID), 16))
    
    WriteLong(FileID, Len(String))
    
    String + StringFingerprint(String, *This\CipherPluginID)
    
    While StringByteLength(String) < 32
      String + " "
    Wend
    
    StringMemorySize = StringByteLength(String) + SizeOf(Character)
    *CipheredString = AllocateMemory(StringMemorySize)
    
    If AESEncoder(@String, *CipheredString, StringByteLength(String), *KeyBuffer, *This\Bits, *InitVectorBuffer)
      
      WriteLong(FileID, StringMemorySize)
      WriteData(FileID, *CipheredString, StringMemorySize)
      
    EndIf
    
    If *KeyBuffer <> #Null
      FreeMemory(*KeyBuffer)
    EndIf
    
    If *InitVectorBuffer <> #Null
      FreeMemory(*InitVectorBuffer)
    EndIf
    
    If *CipheredString <> #Null
      FreeMemory(*CipheredString)
    EndIf
    
  EndProcedure
  
  Procedure AES_WriteByte(*This.Private_Members, FileID.i, P_Value.b)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteAsciiCharacter(*This.Private_Members, FileID.i, P_Value.a)
    
    AES_WriteString(*This, FileID, RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteWord(*This.Private_Members, FileID.i, P_Value.w)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteCharacter(*This.Private_Members, FileID.i, P_Value.c)
    
    AES_WriteString(*This, FileID, RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteUnicodeCharacter(*This.Private_Members, FileID.i, P_Value.u)
    
    AES_WriteString(*This, FileID, RSet(Str(P_Value), 16, "0"))
    
  EndProcedure
  
  Procedure AES_WriteLong(*This.Private_Members, FileID.i, P_Value.l)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 22, "0"))
    
  EndProcedure
  
  Procedure AES_WriteQuad(*This.Private_Members, FileID.i, P_Value.q)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 42, "0"))
    
  EndProcedure
  
  Procedure AES_WriteInteger(*This.Private_Members, FileID.i, P_Value.i)
    
    If P_Value < 0
      Sign.s = "-"
      P_Value = P_Value * -1
    EndIf
    
    AES_WriteString(*This, FileID, Sign + RSet(Str(P_Value), 42, "0"))
    
  EndProcedure
  
  Procedure AES_WriteFloat(*This.Private_Members, FileID.i, P_Value.f)
    
    AES_WriteString(*This, FileID, StrF(P_Value, 14))
    
  EndProcedure
  
  Procedure AES_WriteDouble(*This.Private_Members, FileID.i, P_Value.d)
    
    AES_WriteString(*This, FileID, StrD(P_Value, 25))
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Read on file operators <<<<<
  
  Procedure.s AES_ReadString(*This.Private_Members, FileID.i)
    
    Select *This\Bits
        
      Case #Bits_128
        *KeyBuffer = Ascii(Left(StringFingerprint(*This\Key, *This\CipherPluginID), 16))
        
      Case #Bits_192
        *KeyBuffer = Ascii(Left(StringFingerprint(*This\Key, *This\CipherPluginID), 24))
        
      Case #Bits_256
        *KeyBuffer = Ascii(StringFingerprint(*This\Key, *This\CipherPluginID))
        
    EndSelect
    
    *InitVectorBuffer = Ascii(Left(StringFingerprint(*This\InitVector, *This\CipherPluginID), 16))
    
    OriginalStringLen.l = ReadLong(FileID)
    StringMemorySize.l = ReadLong(FileID)
    
    *CipheredString = AllocateMemory(StringMemorySize)
    *DecipheredString = AllocateMemory(StringMemorySize) 
    
    ReadData(FileID, *CipheredString, StringMemorySize)
    
    AESDecoder(*CipheredString, *DecipheredString, StringMemorySize - SizeOf(Character), *KeyBuffer, *This\Bits, *InitVectorBuffer)
    Output.s = Left(PeekS(*DecipheredString), OriginalStringLen)
    
    If *KeyBuffer <> #Null
      FreeMemory(*KeyBuffer)
    EndIf
    
    If *InitVectorBuffer <> #Null
      FreeMemory(*InitVectorBuffer)
    EndIf
    
    If *CipheredString <> #Null
      FreeMemory(*CipheredString)
    EndIf
    
    If *DecipheredString <> #Null
      FreeMemory(*DecipheredString)
    EndIf
    
    ProcedureReturn Output
  EndProcedure
  
  Procedure.b AES_ReadByte(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.a AES_ReadAsciiCharacter(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.w AES_ReadWord(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.c AES_ReadCharacter(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.u AES_ReadUnicodeCharacter(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.l AES_ReadLong(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.q AES_ReadQuad(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.i AES_ReadInteger(*This.Private_Members, FileID.i)
    
    ProcedureReturn Val(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.f AES_ReadFloat(*This.Private_Members, FileID.i)
    
    ProcedureReturn ValF(AES_ReadString(*This, FileID))
  EndProcedure
  
  Procedure.d AES_ReadDouble(*This.Private_Members, FileID.i)
    
    ProcedureReturn ValD(AES_ReadString(*This, FileID))
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Destructor <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Constructor <<<<<

  Procedure.i New(P_Key.s = "AESCrypting", P_InitVector.s = "AESInitVector", P_Bits.w = #Bits_128, P_CipherPluginID.i = #PB_Cipher_MD5)
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    SetKey(*This, P_Key)
    SetInitVector(*This, P_InitVector)
    SetBits(*This, P_Bits)
    SetCipherPluginID(*This, P_CipherPluginID)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Virtual Table Entries <<<<<

  DataSection
    START_METHODS:
    Data.i @GetKey()
    Data.i @GetInitVector()
    Data.i @GetBits()
    Data.i @GetCipherPluginID()
    Data.i @SetKey()
    Data.i @SetInitVector()
    Data.i @SetBits()
    Data.i @SetCipherPluginID()
    Data.i @AES_WriteString()
    Data.i @AES_WriteByte()
    Data.i @AES_WriteAsciiCharacter()
    Data.i @AES_WriteWord()
    Data.i @AES_WriteUnicodeCharacter()
    Data.i @AES_WriteCharacter()
    Data.i @AES_WriteLong()
    Data.i @AES_WriteQuad()
    Data.i @AES_WriteInteger()
    Data.i @AES_WriteFloat()
    Data.i @AES_WriteDouble()
    Data.i @AES_ReadString()
    Data.i @AES_ReadByte()
    Data.i @AES_ReadAsciiCharacter()
    Data.i @AES_ReadWord()
    Data.i @AES_ReadUnicodeCharacter()
    Data.i @AES_ReadCharacter()
    Data.i @AES_ReadLong()
    Data.i @AES_ReadQuad()
    Data.i @AES_ReadInteger()
    Data.i @AES_ReadFloat()
    Data.i @AES_ReadDouble()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.001 seconds (114000.00 lines/second) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

CompilerIf #PB_Compiler_IsMainFile
  
  UseSHA1Fingerprint()
  
  AES.AES::AES = AES::New("", "", AES::#Bits_256, #PB_Cipher_SHA1)
  
  Varb.b = 112
  Varw.w = 32700
  Varl.l = -2147483645
  Varq.q = 9223372036854775800
  Varf.f = 2 * #PI
  Vard.d = 3 * #PI
  Text.s = "J'aime les déesses nordiques super sexy !!!!!"
  Text2.s = "Hello "
  
  Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
  Debug "; Test on file"
  Debug ""
  Debug "Original : "
  
  Debug Varb
  Debug Varw
  Debug Varl
  Debug Varq
  Debug Varf
  Debug Vard
  Debug Text
  Debug Text2
  Debug ""
  
  If CreateFile(0, "Test.aes")
    
    AES\SetKey("I'm the key")
    AES\SetInitVector("I'm the InitVector")
    
    AES\AES_WriteByte(0, Varb) 
    AES\AES_WriteWord(0, Varw) 
    AES\AES_WriteLong(0, Varl)  
    AES\AES_WriteQuad(0, Varq)
    
    AES\SetKey("I'm the new key for the rest")
    AES\SetInitVector("I'm the new InitVector for the rest")
    
    AES\AES_WriteFloat(0, Varf)
    AES\AES_WriteDouble(0, Vard)
    AES\AES_WriteString(0, Text)
    AES\AES_WriteString(0, Text2)
    
    CloseFile(0)
    
  EndIf 
  
  Debug "File size : " + Str(FileSize("Test.aes")) + " bits" 
  Debug "From the file : " 
  
  If ReadFile(1, "Test.aes")
    
    AES\SetKey("I'm the key")
    AES\SetInitVector("I'm the InitVector")
    
    Debug AES\AES_ReadByte(1)
    Debug AES\AES_ReadWord(1)
    Debug AES\AES_ReadLong(1)
    Debug AES\AES_ReadQuad(1)
    
    AES\SetKey("I'm the new key for the rest")
    AES\SetInitVector("I'm the new InitVector for the rest")
    
    Debug AES\AES_ReadFloat(1)
    Debug AES\AES_ReadDouble(1)
    Debug AES\AES_ReadString(1)
    Debug AES\AES_ReadString(1)
    
    CloseFile(1)
    DeleteFile("Test.aes")
    
  EndIf 
  
  AES\Free()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Last edited by StarBootics on Fri Oct 30, 2020 12:15 am, edited 1 time in total.
The Stone Age did not end due to a shortage of stones !
Post Reply