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

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