• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Our weekly protagonist poll is now up! Vote for your favorite Trading Card Game 2 protagonist in the poll by clicking here.
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Linear Cong Encryption

  • 1,748
    Posts
    15
    Years
    Well, today I was thinking, hey why shouldn't I encrypt my save, but I had a few problems, I didn't want something easy to crack, so I came up with the Linear Cong encryption, it's basically the same as random encryption, but it uses the LinearCong class that I think almost no one knew existed in essentials.

    Anyways enough talk, here's the script:

    By default, this script automatically encrypts your saves, making it a lot more difficult to crack (but this comes at the cost of nice and fast saves, well, it only slows it down by about 4 or 5 seconds which isn't too bad)
    Code:
    ################################################################################
    # Linear Cong Hasher
    # By Rei
    # Credits Required
    ################################################################################
    # Uses Linear Cong Random methods to encrypt your data.
    #
    # NOTICE: This will automatically encrypt your save data. UNLESS you set the
    #         variable "USE_HASHER" to false
    #
    # WARNING: DO NOT AT ANY CONDITION MODIFY THE CODE DOWN THERE AFTER MAKING YOUR
    #          FIRST ENCRYPTED SAVE, OTHERWISE YOUR DATA COULD GET CORRUPTED!
    #
    # How to Use (Save Encryptions):
    #     * Insert this script
    #     * Set the variable "USE_HASHER" to true (this is the default setting)
    #     * Test saving
    #
    # How to Use (Object Encryptions):
    #     * To Encrypt call: object.lch_encrypt
    #     * To Decrypt call: encrypted_object.lch_decrypt
    #
    # How to Use (Encryptions):
    #     * To Encrypt call: LinearCongHasher.encrypt(data string)
    #     * To Decrypt call: LinearCongHasher.decrypt(encrypted data string)
    #
    ################################################################################
    
    USE_HASHER = true # Use the Hasher for SAVE DATA only (the other data cannot be
                      # encrypted due to RMXP needing to read data)
    
    ENCRYPTION_SALT = "VVvvCCccMMmmNNnnCvCCCvvBBBcCCbb+"
                      
    module LinearCongHasher
      
      def self.saltToKey(salt=ENCRYPTION_SALT)
        return salt.hash ^ salt[0] * salt[0] - salt[salt.length-1]
      end
      
      def self.getCryption(index, r1, r2)
        r1=r1.round
        r2=r2.floor
        return (index + r1 * r2) ^ (index + r1 + r2)
      end
      
      def self.encrypt(data)
        n = LinearCongRandom.new(6, 7, saltToKey)
        key = [n.getNext, n.getNext, n.getNext, n.getNext, n.getNext, n.getNext,
        n.getNext, n.getNext, n.getNext, n.getNext, n.getNext, n.getNext, n.getNext]
        
        for i in 0...data.length
          k = key[i % key.length]
          total = getCryption(getCryption(i, k, n.getNext), n.getNext, k)
          data[i] = (data[i] - total) % 255
        end
        return data
      end
      
      def self.decrypt(data)
        n = LinearCongRandom.new(6, 7, saltToKey)
        key = [n.getNext, n.getNext, n.getNext, n.getNext, n.getNext, n.getNext,
        n.getNext, n.getNext, n.getNext, n.getNext, n.getNext, n.getNext, n.getNext]
        
        for i in 0...data.length
          k = key[i % key.length]
          total = getCryption(getCryption(i, k, n.getNext), n.getNext , k)
          data[i] = (data[i] + total) % 255
        end
        return data
      end
    end
    
    class Object
      def lch_encrypt
        return LinearCongHasher.encrypt(Marshal.dump(self))
      end
    end
    
    class String
      def lch_decrypt
        return Marshal.restore(LinearCongHasher.decrypt(self))
      end
    end
    
    module Marshal
      
      class << self
        alias lch_load load
        alias lch_dump dump
      end
      
      def self.load(file)
        data = lch_load(file)
        if !file.is_a?(String) && file.path == RTP.getSaveFileName("Game.rxdata") &&
          USE_HASHER && data.is_a?(String)
          return data.lch_decrypt
        end
        return data
      end
      
      def self.dump(data, file=nil)
        if file && file.path == RTP.getSaveFileName("Game.rxdata") && USE_HASHER &&
          !data.is_a?(Game_Screen) && !data.is_a?(Game_Map) &&
          !data.is_a?(Game_Player) && !data.is_a?(Game_System) &&
          !data.is_a?(PokemonMapFactory)
          data = data.lch_encrypt
        end
        if !file
          file = File.open("Temp", "wb")
          tf=true
        end
        data = lch_dump(data, file)
        if tf
          file.close
          file = File.open("Temp", "rb")
          data = file.read
          file.close
          File.delete("Temp")
        end
        return data
      end
    end
     
    Last edited:
    So if we just insert this script do we have to do we have to call something after saving, or is just adding the script enough?

    Just add the script, it will automatically encrypt the save and load encrypted saves, also it doesn't crash if the script isn't encrypted so you won't need to do new game to get the updates
     
    Code:
    ---------------------------
    Pokemon Melanite
    ---------------------------
    Exception: ArgumentError
    
    Message: dump format error(0x73)
    
    ** Save File Encryption:81:in `restore'
    
    ** Save File Encryption:81:in `lch_decrypt'
    
    ** Save File Encryption:96:in `load'
    
    * PokemonLoad:346:in `pbStartLoadScreen'
    
    * PokemonLoad:332:in `open'
    
    * PokemonLoad:332:in `pbStartLoadScreen'
    
    * PokemonLoad:323:in `loop'
    
    * PokemonLoad:463:in `pbStartLoadScreen'
    
    DebugIntro:6:in `main'
    
    Main:37:in `mainFunctionDebug'
    
    
    
    This exception was logged in 
    
    C:\Users\Administrator\Saved Games/Pokemon Melanite/errorlog.txt.
    
    Press Ctrl+C to copy this message to the clipboard.
    ---------------------------
    OK   
    ---------------------------

    I've been using this for a few days with no issues. I just hit continue from the main menu today in the middle of testing things and got this. I had literally continued the game, saved and exited multiple times within 20 min of this happening. Any idea what it is and what caused it?
     
    Code:
    ---------------------------
    Pokemon Melanite
    ---------------------------
    Exception: ArgumentError
    
    Message: dump format error(0x73)
    
    ** Save File Encryption:81:in `restore'
    
    ** Save File Encryption:81:in `lch_decrypt'
    
    ** Save File Encryption:96:in `load'
    
    * PokemonLoad:346:in `pbStartLoadScreen'
    
    * PokemonLoad:332:in `open'
    
    * PokemonLoad:332:in `pbStartLoadScreen'
    
    * PokemonLoad:323:in `loop'
    
    * PokemonLoad:463:in `pbStartLoadScreen'
    
    DebugIntro:6:in `main'
    
    Main:37:in `mainFunctionDebug'
    
    
    
    This exception was logged in 
    
    C:\Users\Administrator\Saved Games/Pokemon Melanite/errorlog.txt.
    
    Press Ctrl+C to copy this message to the clipboard.
    ---------------------------
    OK   
    ---------------------------

    I've been using this for a few days with no issues. I just hit continue from the main menu today in the middle of testing things and got this. I had literally continued the game, saved and exited multiple times within 20 min of this happening. Any idea what it is and what caused it?

    I'll look a bit more into this, I honestly don't know why it would fail unless the game was interrupted during the save.

    So does this mean that when compressing the game's data it builds a better encrypted archive? Moreover; does it withstand current decryption software?

    No it does not, as for this method is defined in the RGSS10XE.dll (X being the version you are using) and it cannot be modified (although there are tricks to make a better encrypted archive)
     
    Hansiec... You're contributing a few really nice scripts.

    I guess Game Dev hasn't got what it needs for you anymore lol.
    This is definitely a good script to use, if you can perfect it anyway.
    I look forward to more scripts from you.
    I haven't used any of them, but it's good for me to learn from them.
     
    Hansiec... You're contributing a few really nice scripts.

    I guess Game Dev hasn't got what it needs for you anymore lol.
    This is definitely a good script to use, if you can perfect it anyway.
    I look forward to more scripts from you.
    I haven't used any of them, but it's good for me to learn from them.

    Thank-you, but I don't plan on making more scripts for a bit, as I am working on my Scorpion Engine
     
    Back
    Top