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.

87 lines
2.3 KiB

  1. // Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
  2. // Use of this source code is governed by a license that can be
  3. // found in the LICENSE file.
  4. // Package threefish implements the Threefish tweakable block cipher.
  5. // Threefish is designed to be the core function of the Skein hash function
  6. // family.
  7. // There are three versions of Threefish
  8. // - Threefish256 processes 256 bit blocks
  9. // - Threefish512 processes 512 bit blocks
  10. // - Threefish1024 processes 1024 bit blocks
  11. package threefish
  12. import (
  13. "crypto/cipher"
  14. "errors"
  15. )
  16. const (
  17. // The size of the tweak in bytes.
  18. TweakSize = 16
  19. // C240 is the key schedule constant
  20. C240 = 0x1bd11bdaa9fc1a22
  21. // The block size of Threefish-256 in bytes.
  22. BlockSize256 = 32
  23. // The block size of Threefish-512 in bytes.
  24. BlockSize512 = 64
  25. // The block size of Threefish-1024 in bytes.
  26. BlockSize1024 = 128
  27. )
  28. var errKeySize = errors.New("invalid key size")
  29. // NewCipher returns a cipher.Block implementing the Threefish cipher.
  30. // The length of the key must be 32, 64 or 128 byte.
  31. // The length of the tweak must be TweakSize.
  32. // The returned cipher implements:
  33. // - Threefish-256 - if len(key) = 32
  34. // - Threefish-512 - if len(key) = 64
  35. // - Threefish-1024 - if len(key) = 128
  36. func NewCipher(tweak *[TweakSize]byte, key []byte) (cipher.Block, error) {
  37. switch k := len(key); k {
  38. default:
  39. return nil, errKeySize
  40. case BlockSize256:
  41. return newCipher256(tweak, key), nil
  42. case BlockSize512:
  43. return newCipher512(tweak, key), nil
  44. case BlockSize1024:
  45. return newCipher1024(tweak, key), nil
  46. }
  47. }
  48. // Increment the tweak by the ctr argument.
  49. // Skein can consume messages up to 2^96 -1 bytes.
  50. func IncrementTweak(tweak *[3]uint64, ctr uint64) {
  51. t0 := tweak[0]
  52. tweak[0] += ctr
  53. if tweak[0] < t0 {
  54. t1 := tweak[1]
  55. tweak[1] = (t1 + 1) & 0x00000000FFFFFFFF
  56. }
  57. }
  58. // The threefish-256 tweakable blockcipher
  59. type threefish256 struct {
  60. keys [5]uint64
  61. tweak [3]uint64
  62. }
  63. func (t *threefish256) BlockSize() int { return BlockSize256 }
  64. // The threefish-512 tweakable blockcipher
  65. type threefish512 struct {
  66. keys [9]uint64
  67. tweak [3]uint64
  68. }
  69. func (t *threefish512) BlockSize() int { return BlockSize512 }
  70. // The threefish-1024 tweakable blockcipher
  71. type threefish1024 struct {
  72. keys [17]uint64
  73. tweak [3]uint64
  74. }
  75. func (t *threefish1024) BlockSize() int { return BlockSize1024 }