// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package rc2 implements the RC2 cipher
/*
https://www.ietf.org/rfc/rfc2268.txt
http://people.csail.mit.edu/rivest/pubs/KRRR98.pdf

This code is licensed under the MIT license.
*/
package rc2

import (
	"crypto/cipher"
	"encoding/binary"
)

// The rc2 block size in bytes
const BlockSize = 8

type rc2Cipher struct {
	k [64]uint16
}

// New returns a new rc2 cipher with the given key and effective key length t1
func New(key []byte, t1 int) (cipher.Block, error) {
	// TODO(dgryski): error checking for key length
	return &rc2Cipher{
		k: expandKey(key, t1),
	}, nil
}

func (*rc2Cipher) BlockSize() int { return BlockSize }

var piTable = [256]byte{
	0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
	0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
	0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
	0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
	0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
	0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
	0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
	0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
	0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
	0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
	0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
	0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
	0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
	0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
	0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
	0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad,
}

func expandKey(key []byte, t1 int) [64]uint16 {

	l := make([]byte, 128)
	copy(l, key)

	var t = len(key)
	var t8 = (t1 + 7) / 8
	var tm = byte(255 % uint(1<<(8+uint(t1)-8*uint(t8))))

	for i := len(key); i < 128; i++ {
		l[i] = piTable[l[i-1]+l[uint8(i-t)]]
	}

	l[128-t8] = piTable[l[128-t8]&tm]

	for i := 127 - t8; i >= 0; i-- {
		l[i] = piTable[l[i+1]^l[i+t8]]
	}

	var k [64]uint16

	for i := range k {
		k[i] = uint16(l[2*i]) + uint16(l[2*i+1])*256
	}

	return k
}

func rotl16(x uint16, b uint) uint16 {
	return (x >> (16 - b)) | (x << b)
}

func (c *rc2Cipher) Encrypt(dst, src []byte) {

	r0 := binary.LittleEndian.Uint16(src[0:])
	r1 := binary.LittleEndian.Uint16(src[2:])
	r2 := binary.LittleEndian.Uint16(src[4:])
	r3 := binary.LittleEndian.Uint16(src[6:])

	var j int

	for j <= 16 {
		// mix r0
		r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
		r0 = rotl16(r0, 1)
		j++

		// mix r1
		r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
		r1 = rotl16(r1, 2)
		j++

		// mix r2
		r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
		r2 = rotl16(r2, 3)
		j++

		// mix r3
		r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
		r3 = rotl16(r3, 5)
		j++

	}

	r0 = r0 + c.k[r3&63]
	r1 = r1 + c.k[r0&63]
	r2 = r2 + c.k[r1&63]
	r3 = r3 + c.k[r2&63]

	for j <= 40 {

		// mix r0
		r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
		r0 = rotl16(r0, 1)
		j++

		// mix r1
		r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
		r1 = rotl16(r1, 2)
		j++

		// mix r2
		r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
		r2 = rotl16(r2, 3)
		j++

		// mix r3
		r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
		r3 = rotl16(r3, 5)
		j++

	}

	r0 = r0 + c.k[r3&63]
	r1 = r1 + c.k[r0&63]
	r2 = r2 + c.k[r1&63]
	r3 = r3 + c.k[r2&63]

	for j <= 60 {

		// mix r0
		r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
		r0 = rotl16(r0, 1)
		j++

		// mix r1
		r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
		r1 = rotl16(r1, 2)
		j++

		// mix r2
		r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
		r2 = rotl16(r2, 3)
		j++

		// mix r3
		r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
		r3 = rotl16(r3, 5)
		j++
	}

	binary.LittleEndian.PutUint16(dst[0:], r0)
	binary.LittleEndian.PutUint16(dst[2:], r1)
	binary.LittleEndian.PutUint16(dst[4:], r2)
	binary.LittleEndian.PutUint16(dst[6:], r3)
}

func (c *rc2Cipher) Decrypt(dst, src []byte) {

	r0 := binary.LittleEndian.Uint16(src[0:])
	r1 := binary.LittleEndian.Uint16(src[2:])
	r2 := binary.LittleEndian.Uint16(src[4:])
	r3 := binary.LittleEndian.Uint16(src[6:])

	j := 63

	for j >= 44 {
		// unmix r3
		r3 = rotl16(r3, 16-5)
		r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
		j--

		// unmix r2
		r2 = rotl16(r2, 16-3)
		r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
		j--

		// unmix r1
		r1 = rotl16(r1, 16-2)
		r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
		j--

		// unmix r0
		r0 = rotl16(r0, 16-1)
		r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
		j--
	}

	r3 = r3 - c.k[r2&63]
	r2 = r2 - c.k[r1&63]
	r1 = r1 - c.k[r0&63]
	r0 = r0 - c.k[r3&63]

	for j >= 20 {
		// unmix r3
		r3 = rotl16(r3, 16-5)
		r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
		j--

		// unmix r2
		r2 = rotl16(r2, 16-3)
		r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
		j--

		// unmix r1
		r1 = rotl16(r1, 16-2)
		r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
		j--

		// unmix r0
		r0 = rotl16(r0, 16-1)
		r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
		j--

	}

	r3 = r3 - c.k[r2&63]
	r2 = r2 - c.k[r1&63]
	r1 = r1 - c.k[r0&63]
	r0 = r0 - c.k[r3&63]

	for j >= 0 {

		// unmix r3
		r3 = rotl16(r3, 16-5)
		r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
		j--

		// unmix r2
		r2 = rotl16(r2, 16-3)
		r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
		j--

		// unmix r1
		r1 = rotl16(r1, 16-2)
		r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
		j--

		// unmix r0
		r0 = rotl16(r0, 16-1)
		r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
		j--

	}

	binary.LittleEndian.PutUint16(dst[0:], r0)
	binary.LittleEndian.PutUint16(dst[2:], r1)
	binary.LittleEndian.PutUint16(dst[4:], r2)
	binary.LittleEndian.PutUint16(dst[6:], r3)
}
