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