You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
1.8 KiB

  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. /*
  5. Implementation adapted from Needham and Wheeler's paper:
  6. http://www.cix.co.uk/~klockstone/xtea.pdf
  7. A precalculated look up table is used during encryption/decryption for values that are based purely on the key.
  8. */
  9. package xtea
  10. // XTEA is based on 64 rounds.
  11. const numRounds = 64
  12. // blockToUint32 reads an 8 byte slice into two uint32s.
  13. // The block is treated as big endian.
  14. func blockToUint32(src []byte) (uint32, uint32) {
  15. r0 := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
  16. r1 := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
  17. return r0, r1
  18. }
  19. // uint32ToBlock writes two uint32s into an 8 byte data block.
  20. // Values are written as big endian.
  21. func uint32ToBlock(v0, v1 uint32, dst []byte) {
  22. dst[0] = byte(v0 >> 24)
  23. dst[1] = byte(v0 >> 16)
  24. dst[2] = byte(v0 >> 8)
  25. dst[3] = byte(v0)
  26. dst[4] = byte(v1 >> 24)
  27. dst[5] = byte(v1 >> 16)
  28. dst[6] = byte(v1 >> 8)
  29. dst[7] = byte(v1 >> 0)
  30. }
  31. // encryptBlock encrypts a single 8 byte block using XTEA.
  32. func encryptBlock(c *Cipher, dst, src []byte) {
  33. v0, v1 := blockToUint32(src)
  34. // Two rounds of XTEA applied per loop
  35. for i := 0; i < numRounds; {
  36. v0 += ((v1<<4 ^ v1>>5) + v1) ^ c.table[i]
  37. i++
  38. v1 += ((v0<<4 ^ v0>>5) + v0) ^ c.table[i]
  39. i++
  40. }
  41. uint32ToBlock(v0, v1, dst)
  42. }
  43. // decryptBlock decrypt a single 8 byte block using XTEA.
  44. func decryptBlock(c *Cipher, dst, src []byte) {
  45. v0, v1 := blockToUint32(src)
  46. // Two rounds of XTEA applied per loop
  47. for i := numRounds; i > 0; {
  48. i--
  49. v1 -= ((v0<<4 ^ v0>>5) + v0) ^ c.table[i]
  50. i--
  51. v0 -= ((v1<<4 ^ v1>>5) + v1) ^ c.table[i]
  52. }
  53. uint32ToBlock(v0, v1, dst)
  54. }