|
|
// 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 }
|