1
\$\begingroup\$

I am quite new to Go but have found it to be very useful for my use case (game server).

I have a routine that encrypts/decrypts the game packets which was written in C++ which can be seen here and here as DecryptDirect.

My current Go code:

type Crypto struct {
    nkey         [256]byte
    buf          [256]byte
    i, j, iR, jR byte
    prev         byte
    iRounds      int
}

func (c *Crypto) setup() {
    c.iR, c.jR = 0, 0

    k := len(c.nkey)

    for i := 0; i < 256; i++ {
        c.buf[i] = byte(i)
    }
    var j byte = 0
    for i := 0; i < 256; i++ {
        j += byte(c.buf[i]) + c.nkey[i%k]
        c.buf[i], c.buf[j] = c.buf[j], c.buf[i]
    }
}

func (c *Crypto) reset() {
    c.setup()
    c.prev = c.getRandom()
}

func (c *Crypto) getRandom() byte {
    c.iR = (c.iR + 1) & 0xFF
    c.jR = (c.jR + c.buf[c.iR]) & 0xFF
    c.buf[c.iR], c.buf[c.jR] = c.buf[c.jR], c.buf[c.iR]

    result := c.buf[(c.buf[c.iR]+c.buf[c.jR])&0xFF]
    return result
}

func (c *Crypto) Init(a int, b int, rounds int) {
    secret := fmt.Sprintf("%05d_%05d_%05d", a+10, b+10, a+b)
    copy(c.nkey[:], secret)
    c.iRounds = rounds
    c.reset()
}

func (c *Crypto) Decrypt(dst, src []byte) {
    var i, j int

    src_size := len(src)

    var plain byte
    var seqX2, seqM2 [2]byte
    // to be improved
    seqX := make([]byte, src_size)
    seqM := make([]byte, src_size)

    for i = 0; i < src_size; i++ {
        xiRounds := 0

        for j = 0; j < c.iRounds; j++ {
            seqX2[xiRounds] = c.getRandom()
            seqM2[xiRounds] = c.getRandom()
            xiRounds++
        }

        // last m_iRounds-1 rounds
        plain = src[i]
        seqX[i] = seqX2[c.iRounds-1]
        seqM[i] = seqM2[c.iRounds-1]

        for j = c.iRounds - 1; j > 0; j-- {
            if seqM[i] <= plain {
                plain -= seqM[i]
            } else {
                seqM[i] = ^seqM[i] & 0xFF
                seqM[i]++
                plain += seqM[i]
            }
            plain ^= seqX[i]
        }
        // first round
        if seqM2[0] <= plain {
            plain -= seqM2[0]
        } else {
            seqM2[0] = ^seqM2[0] & 0xFF
            seqM2[0]++
            plain += seqM2[0]
        }
        plain ^= c.prev ^ seqX2[0]
        dst[i] = plain
        c.prev ^= plain
    }

    c.reset()
}

Any improvements made here can speed up the server much because the Decrypt function gets called quite a lot. Any ideas and examples for improvements would be much appreciated.

\$\endgroup\$
  • \$\begingroup\$ Does the code work? I am getting panics in the code... and the panics... are reasonable. The first time I called Decrypt I used rounds with the input value 100, and of course, that makes seqX2[xiRounds] = c.getRandom() panic. \$\endgroup\$ – rolfl Feb 21 '16 at 3:07
  • \$\begingroup\$ @rolfl yes the code works for me. using go1.6. my input is Init(100, 100, 2). \$\endgroup\$ – majidarif Feb 21 '16 at 14:12
  • \$\begingroup\$ OK, so run it with Init(100, 100, 3). This is your opportunity to fix it before a review comes in. Also, take the opportunity to implement a Encrypt method so people can run it in a round-trip manner - and explore the performance independently. \$\endgroup\$ – rolfl Feb 21 '16 at 15:45
  • \$\begingroup\$ The setup function si bogus. Replace ˋj += byte(c.buf[i]) + c.nkey[i%k]` with ˋ j += c.buf[i] + c.nkey[i]ˋ. The modulo and variable ˋk` is not needed because ˋi ˋ is always smaller than 256. The cast to byte of ˋc.buf[]` is not needed because its a byte and ˋj ˋ is byte. (Can’t find backticks on iPad and iOS11. Sorry) \$\endgroup\$ – chmike Oct 7 '17 at 16:13
  • \$\begingroup\$ The member variables ˋi ˋ and ˋj ˋ are unused. You can remove them. Also in getRandom you can replace ˋc.iR = (c.iR + 1) & 0xFF` by ˋc.IR++ˋ because c.iR is byte and it will wrap to 0. No need for the ˋ&0xFF`. \$\endgroup\$ – chmike Oct 7 '17 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.