Register for your free account! | Forgot your password?

You last visited: Today at 12:46

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Reworked RC5 Cipher (Unsafe)

Discussion on Reworked RC5 Cipher (Unsafe) within the CO2 PServer Guides & Releases forum part of the CO2 Private Server category.

Reply
 
Old   #1


 
CptSky's Avatar
 
elite*gold: 0
Join Date: Jan 2008
Posts: 1,443
Received Thanks: 1,175
Reworked RC5 Cipher (Unsafe)

Similar to my other cipher topic (), here a reworked RC5 cipher for the password encryption. It uses pointers, so it can be considered as unsafe. It will work on any client, but newer client will need to generate a BufKey with the seed while older client only need the specified BufKey posted in the code. Newer clients also need another cipher, but the RC5 is still used.

PS. This should generate a valid BufKey for the specified seed. (5180+) I can't test it, but it reproduce the rand(), srand() function.
Code:
        public Byte[] Generate(Int32 Seed)
        {
            Byte[] BufKey = new Byte[0x10];
            for (SByte i = 0; i < BufKey.Length; i++)
            {
                Seed *= 0x0343FD;
                Seed += 0x269EC3;
                BufKey[i] = (Byte)((Int16)((Seed >> 0x10) & 0x7FFF));
            }
            return BufKey;
        }
Code:
// * ************************************************************
// * * START:                                          corc5.cs *
// * ************************************************************

// * ************************************************************
// *                      INFORMATIONS
// * ************************************************************
// * Conquer Online RC5 for the library.
// * corc5.cs
// * 
// * --
// *
// * Feel free to use this class in your projects, but don't
// * remove the header to keep the paternity of the class.
// * 
// * ************************************************************
// *                      CREDITS
// * ************************************************************
// * Originally created by CptSky (May 10th, 2011)
// * Copyright (C) 2011 CptSky
// * 
// * ************************************************************
// *                      CHANGE LOG
// * ************************************************************
// *
// * ************************************************************

using System;
using System.Runtime.InteropServices;

namespace CO2_CORE_DLL.Security
{
    /// <summary>
    /// Conquer Online Rivest Cipher 5
    /// </summary>
    public unsafe class CORC5
    {
        protected const Int32 RC5_32 = 32;
        protected const Int32 RC5_12 = 12;
        protected const Int32 RC5_SUB = (RC5_12 * 2 + 2);
        protected const Int32 RC5_16 = 16;
        protected const Int32 RC5_KEY = (RC5_16 / 4);

        protected UInt32* m_BufKey = null;
        protected UInt32* m_BufSub = null;
        protected UInt32 RC5_PW32 = 0xB7E15163;
        protected UInt32 RC5_QW32 = 0x9E3779B9;

        /// <summary>
        /// Create a new RC5 instance.
        /// </summary>
        public CORC5() { }

        /// <summary>
        /// Create a new RC5 instance with the specified magics numbers. (Shouldn't be used)
        /// </summary>
        public CORC5(UInt32 RC5_PW32, UInt32 RC5_QW32)
        {
            this.RC5_PW32 = RC5_PW32;
            this.RC5_QW32 = RC5_QW32;
        }

        ~CORC5()
        {
            if (m_BufKey != null)
                Marshal.FreeHGlobal((IntPtr)m_BufKey);
            if (m_BufSub != null)
                Marshal.FreeHGlobal((IntPtr)m_BufSub);
        }

        /// <summary>
        /// Generates a random key (Key) to use for the algorithm.
        /// CO2: { 0x3C, 0xDC, 0xFE, 0xE8, 0xC4, 0x54, 0xD6, 0x7E, 0x16, 0xA6, 0xF8, 0x1A, 0xE8, 0xD0, 0x38, 0xBE }
        /// </summary>
        public void GenerateKey(Byte* pBufKey, Int32 Length)
        {
            if (pBufKey == null)
                throw new NullReferenceException("Buffer can't be null!");

            if (Length != RC5_16)
                throw new Exception("Buffer length should be " + RC5_16 + "!");

            if (m_BufKey != null)
                Marshal.FreeHGlobal((IntPtr)m_BufKey);
            if (m_BufSub != null)
                Marshal.FreeHGlobal((IntPtr)m_BufSub);

            m_BufKey = (UInt32*)Marshal.AllocHGlobal(RC5_KEY * sizeof(UInt32));
            m_BufSub = (UInt32*)Marshal.AllocHGlobal(RC5_SUB * sizeof(UInt32));

            for (Int32 z = 0; z < RC5_KEY; z++)
                m_BufKey[z] = ((UInt32*)pBufKey)[z];

            m_BufSub[0] = RC5_PW32;
            Int32 i, j, k;
            for (i = 1; i < RC5_SUB; i++)
                m_BufSub[i] = m_BufSub[i - 1] - RC5_QW32;

            UInt32 x, y;
            i = j = 0;
            x = y = 0;
            for (k = 0; k < 3 * Math.Max(RC5_KEY, RC5_SUB); k++)
            {
                m_BufSub[i] = rotl((m_BufSub[i] + x + y), 3);
                x = m_BufSub[i];
                i = (i + 1) % RC5_SUB;
                m_BufKey[j] = rotl((m_BufKey[j] + x + y), (x + y));
                y = m_BufKey[j];
                j = (j + 1) % RC5_KEY;
            }
        }

        /// <summary>
        /// Generates a random key (Key) to use for the algorithm.
        /// CO2: { 0x3C, 0xDC, 0xFE, 0xE8, 0xC4, 0x54, 0xD6, 0x7E, 0x16, 0xA6, 0xF8, 0x1A, 0xE8, 0xD0, 0x38, 0xBE }
        /// </summary>
        public void GenerateKey(Byte[] BufKey)
        {
            if (BufKey == null)
                throw new NullReferenceException("Buffer can't be null!");

            if (BufKey.Length != RC5_16)
                throw new Exception("Buffer length should be " + RC5_16 + "!");

            if (m_BufKey != null)
                Marshal.FreeHGlobal((IntPtr)m_BufKey);
            if (m_BufSub != null)
                Marshal.FreeHGlobal((IntPtr)m_BufSub);

            m_BufKey = (UInt32*)Marshal.AllocHGlobal(RC5_KEY * sizeof(UInt32));
            m_BufSub = (UInt32*)Marshal.AllocHGlobal(RC5_SUB * sizeof(UInt32));

            fixed (Byte* pBufKey = BufKey)
            {
                for (Int32 z = 0; z < RC5_KEY; z++)
                    m_BufKey[z] = ((UInt32*)pBufKey)[z];
            }

            m_BufSub[0] = RC5_PW32;

            Int32 i, j, k;
            for (i = 1; i < RC5_SUB; i++)
                m_BufSub[i] = m_BufSub[i - 1] - RC5_QW32;

            UInt32 x, y;
            i = j = 0;
            x = y = 0;
            for (k = 0; k < 3 * Math.Max(RC5_KEY, RC5_SUB); k++)
            {
                m_BufSub[i] = rotl((m_BufSub[i] + x + y), 3);
                x = m_BufSub[i];
                i = (i + 1) % RC5_SUB;
                m_BufKey[j] = rotl((m_BufKey[j] + x + y), (x + y));
                y = m_BufKey[j];
                j = (j + 1) % RC5_KEY;
            }
        }

        /// <summary>
        /// Encrypts data with the CORC5 algorithm.
        /// </summary>
        public void Encrypt(Byte* pBuf, Int32 Length)
        {
            if (Length % 8 != 0)
                throw new Exception("Buffer length should be a multiple of 8.");

            Length = (Length / 8) * 8;
            if (Length <= 0)
                throw new Exception("Buffer length should be greater than 0.");

            if (pBuf == null)
                throw new NullReferenceException("Buffer can't be null!");

            UInt32* pBufData = (UInt32*)pBuf;
            for (Int32 k = 0; k < Length / 8; k++)
            {
                UInt32 a = pBufData[2 * k];
                UInt32 b = pBufData[2 * k + 1];

                UInt32 le = a + m_BufSub[0];
                UInt32 re = b + m_BufSub[1];
                for (Int32 i = 1; i <= RC5_12; i++)
                {
                    le = rotl((le ^ re), re) + m_BufSub[2 * i];
                    re = rotl((re ^ le), le) + m_BufSub[2 * i + 1];
                }

                pBufData[2 * k] = le;
                pBufData[2 * k + 1] = re;
            }
        }

        /// <summary>
        /// Encrypts data with the CORC5 algorithm.
        /// </summary>
        public void Encrypt(ref Byte[] Buf)
        {
            if (Buf == null)
                throw new NullReferenceException("Buffer can't be null!");

            Int32 Length = Buf.Length;

            if (Length % 8 != 0)
                throw new Exception("Buffer length should be a multiple of 8.");

            Length = (Length / 8) * 8;
            if (Length <= 0)
                throw new Exception("Buffer length should be greater than 0.");

            UInt32* pBufData = null;
            fixed (Byte* pBuf = Buf)
                pBufData = (UInt32*)pBuf;
            for (Int32 k = 0; k < Length / 8; k++)
            {
                UInt32 a = pBufData[2 * k];
                UInt32 b = pBufData[2 * k + 1];

                UInt32 le = a + m_BufSub[0];
                UInt32 re = b + m_BufSub[1];
                for (Int32 i = 1; i <= RC5_12; i++)
                {
                    le = rotl((le ^ re), re) + m_BufSub[2 * i];
                    re = rotl((re ^ le), le) + m_BufSub[2 * i + 1];
                }

                pBufData[2 * k] = le;
                pBufData[2 * k + 1] = re;
            }
        }

        /// <summary>
        /// Decrypts data with the CORC5 algorithm.
        /// </summary>
        public void Decrypt(Byte* pBuf, Int32 Length)
        {
            if (Length % 8 != 0)
                throw new Exception("Buffer length should be a multiple of 8.");

            Length = (Length / 8) * 8;
            if (Length <= 0)
                throw new Exception("Buffer length should be greater than 0.");

            if (pBuf == null)
                throw new NullReferenceException("Buffer can't be null!");

            UInt32* pBufData = (UInt32*)pBuf;
            for (Int32 k = 0; k < Length / 8; k++)
            {
                UInt32 ld = pBufData[2 * k];
                UInt32 rd = pBufData[2 * k + 1];
                for (Int32 i = RC5_12; i >= 1; i--)
                {
                    rd = rotr((rd - m_BufSub[2 * i + 1]), ld) ^ ld;
                    ld = rotr((ld - m_BufSub[2 * i]), rd) ^ rd;
                }

                UInt32 b = rd - m_BufSub[1];
                UInt32 a = ld - m_BufSub[0];

                pBufData[2 * k] = a;
                pBufData[2 * k + 1] = b;
            }
        }

        /// <summary>
        /// Decrypts data with the CORC5 algorithm.
        /// </summary>
        public void Decrypt(ref Byte[] Buf)
        {
            if (Buf == null)
                throw new NullReferenceException("Buffer can't be null!");

            Int32 Length = Buf.Length;

            if (Length % 8 != 0)
                throw new Exception("Buffer length should be a multiple of 8.");

            Length = (Length / 8) * 8;
            if (Length <= 0)
                throw new Exception("Buffer length should be greater than 0.");

            UInt32* pBufData = null;
            fixed (Byte* pBuf = Buf)
                pBufData = (UInt32*)pBuf;
            for (Int32 k = 0; k < Length / 8; k++)
            {
                UInt32 ld = pBufData[2 * k];
                UInt32 rd = pBufData[2 * k + 1];
                for (Int32 i = RC5_12; i >= 1; i--)
                {
                    rd = rotr((rd - m_BufSub[2 * i + 1]), ld) ^ ld;
                    ld = rotr((ld - m_BufSub[2 * i]), rd) ^ rd;
                }

                UInt32 b = rd - m_BufSub[1];
                UInt32 a = ld - m_BufSub[0];

                pBufData[2 * k] = a;
                pBufData[2 * k + 1] = b;
            }
        }

        protected UInt32 rotl(UInt32 Value, UInt32 Count)
        {
            Count %= 32;

            UInt32 High = Value >> (32 - (Int32)Count);
            return (Value << (Int32)Count) | High;
        }

        protected UInt32 rotr(UInt32 Value, UInt32 Count)
        {
            Count %= 32;

            UInt32 Low = Value << (32 - (Int32)Count);
            return (Value >> (Int32)Count) | Low;
        }
    }
}

// * ************************************************************
// * * END:                                            corc5.cs *
// * ************************************************************
CptSky is offline  
Thanks
3 Users
Old 06/23/2011, 00:46   #2


 
CptSky's Avatar
 
elite*gold: 0
Join Date: Jan 2008
Posts: 1,443
Received Thanks: 1,175
Quote:
Originally Posted by Y u k i View Post
why do you use a destructor method? Is it acctually faster than letting the GC handle that on its own?
The GC will call the destructor, so it's not faster. The destructor method is required when you have unmanaged resources. The GC will never touch the unmanaged memory, so you need to alloc/free the unmanaged memory like in C/C++. This destructor is required to free the memory.

Also, I always create a destructor method. It's from when I code in C/C++...
CptSky is offline  
Old 06/23/2011, 01:03   #3


 
KraHen's Avatar
 
elite*gold: 0
Join Date: Jul 2006
Posts: 2,216
Received Thanks: 794
Though this kinda ruins the whole point in managed code, doesn`t it? Stay native
KraHen is offline  
Old 12/29/2011, 10:52   #4
 
Spirited's Avatar
 
elite*gold: 12
Join Date: Jul 2011
Posts: 8,282
Received Thanks: 4,190
RC5_QW32 needs to be changed to 0x61C88647.
Then it'll work on the 5180 - 5527 clients. =p
Spirited is offline  
Old 12/30/2011, 03:47   #5
 
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
Quote:
Originally Posted by KraHen View Post
Though this kinda ruins the whole point in managed code, doesn`t it? Stay native
All the code is managed code, why would you want to go unmanaged/native?
IAmHawtness is offline  
Reply


Similar Threads Similar Threads
Reworked CO2 Cipher (Unsafe)
11/16/2011 - CO2 PServer Guides & Releases - 8 Replies
Similar to my older cipher (http://www.elitepvpers.com/forum/co2-pserver-guid es-releases/986229-reworked-co2-cipher.html), this one use pointers, so it can be considered as unsafe. In general, the speed is better with this crypto, but it doesn't change a lot... (Few ms...) Anyway, I think that the code is better than my older cipher. Maybe it will interest some people. Special thanks to Sparkie for the IV generation algorithm. Auth: Any client... Game: 5017 & before... // *...
Atlantica Online Bot Package / Reworked
08/07/2011 - Atlantica Online - 61 Replies
This thread is ment for the Reworked Atlantica Online Bot done by me TheOnlyOne. If everything wents right, its getting Released somewhere in the next week.
Reworked CO2 Cipher
01/30/2011 - CO2 PServer Guides & Releases - 0 Replies
I made a new version of the CO2 cipher used by the auth server and the game server (5017 and before). I don't use any pointers in this version. The class is based on the dotNet AsymmetricAlgorithm class. If you use this class in your projects, please mention who is the autor... Thanks. // * *************************************** // * _ _ _ // * | | (_) | // * | | ___ __ _ _| | __ // * | | / _ \ / _` | | |/ / // * |...
Venom Unsafe?
12/10/2007 - Conquer Online 2 - 1 Replies
Since Queen took venom down should I stop using it? Would or could Queen mess with our accounts if we continue using the older versions that were posted like what happend with the original proxy this one was based off of?



All times are GMT +1. The time now is 12:48.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.