// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
|
|
// Use of this source code is governed by a license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Package threefish implements the Threefish tweakable block cipher.
|
|
// Threefish is designed to be the core function of the Skein hash function
|
|
// family.
|
|
// There are three versions of Threefish
|
|
// - Threefish256 processes 256 bit blocks
|
|
// - Threefish512 processes 512 bit blocks
|
|
// - Threefish1024 processes 1024 bit blocks
|
|
package threefish
|
|
|
|
import (
|
|
"crypto/cipher"
|
|
"errors"
|
|
)
|
|
|
|
const (
|
|
// The size of the tweak in bytes.
|
|
TweakSize = 16
|
|
// C240 is the key schedule constant
|
|
C240 = 0x1bd11bdaa9fc1a22
|
|
// The block size of Threefish-256 in bytes.
|
|
BlockSize256 = 32
|
|
// The block size of Threefish-512 in bytes.
|
|
BlockSize512 = 64
|
|
// The block size of Threefish-1024 in bytes.
|
|
BlockSize1024 = 128
|
|
)
|
|
|
|
var errKeySize = errors.New("invalid key size")
|
|
|
|
// NewCipher returns a cipher.Block implementing the Threefish cipher.
|
|
// The length of the key must be 32, 64 or 128 byte.
|
|
// The length of the tweak must be TweakSize.
|
|
// The returned cipher implements:
|
|
// - Threefish-256 - if len(key) = 32
|
|
// - Threefish-512 - if len(key) = 64
|
|
// - Threefish-1024 - if len(key) = 128
|
|
func NewCipher(tweak *[TweakSize]byte, key []byte) (cipher.Block, error) {
|
|
switch k := len(key); k {
|
|
default:
|
|
return nil, errKeySize
|
|
case BlockSize256:
|
|
return newCipher256(tweak, key), nil
|
|
case BlockSize512:
|
|
return newCipher512(tweak, key), nil
|
|
case BlockSize1024:
|
|
return newCipher1024(tweak, key), nil
|
|
}
|
|
}
|
|
|
|
// Increment the tweak by the ctr argument.
|
|
// Skein can consume messages up to 2^96 -1 bytes.
|
|
func IncrementTweak(tweak *[3]uint64, ctr uint64) {
|
|
t0 := tweak[0]
|
|
tweak[0] += ctr
|
|
if tweak[0] < t0 {
|
|
t1 := tweak[1]
|
|
tweak[1] = (t1 + 1) & 0x00000000FFFFFFFF
|
|
}
|
|
}
|
|
|
|
// The threefish-256 tweakable blockcipher
|
|
type threefish256 struct {
|
|
keys [5]uint64
|
|
tweak [3]uint64
|
|
}
|
|
|
|
func (t *threefish256) BlockSize() int { return BlockSize256 }
|
|
|
|
// The threefish-512 tweakable blockcipher
|
|
type threefish512 struct {
|
|
keys [9]uint64
|
|
tweak [3]uint64
|
|
}
|
|
|
|
func (t *threefish512) BlockSize() int { return BlockSize512 }
|
|
|
|
// The threefish-1024 tweakable blockcipher
|
|
type threefish1024 struct {
|
|
keys [17]uint64
|
|
tweak [3]uint64
|
|
}
|
|
|
|
func (t *threefish1024) BlockSize() int { return BlockSize1024 }
|