|
|
// 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
func (t *threefish256) Encrypt(dst, src []byte) { var block [4]uint64
bytesToBlock256(&block, src)
Encrypt256(&block, &(t.keys), &(t.tweak))
block256ToBytes(dst, &block) }
func (t *threefish256) Decrypt(dst, src []byte) { var block [4]uint64
bytesToBlock256(&block, src)
Decrypt256(&block, &(t.keys), &(t.tweak))
block256ToBytes(dst, &block) }
func newCipher256(tweak *[TweakSize]byte, key []byte) *threefish256 { c := new(threefish256)
c.tweak[0] = uint64(tweak[0]) | uint64(tweak[1])<<8 | uint64(tweak[2])<<16 | uint64(tweak[3])<<24 | uint64(tweak[4])<<32 | uint64(tweak[5])<<40 | uint64(tweak[6])<<48 | uint64(tweak[7])<<56
c.tweak[1] = uint64(tweak[8]) | uint64(tweak[9])<<8 | uint64(tweak[10])<<16 | uint64(tweak[11])<<24 | uint64(tweak[12])<<32 | uint64(tweak[13])<<40 | uint64(tweak[14])<<48 | uint64(tweak[15])<<56
c.tweak[2] = c.tweak[0] ^ c.tweak[1]
for i := range c.keys[:4] { j := i * 8 c.keys[i] = uint64(key[j]) | uint64(key[j+1])<<8 | uint64(key[j+2])<<16 | uint64(key[j+3])<<24 | uint64(key[j+4])<<32 | uint64(key[j+5])<<40 | uint64(key[j+6])<<48 | uint64(key[j+7])<<56 } c.keys[4] = C240 ^ c.keys[0] ^ c.keys[1] ^ c.keys[2] ^ c.keys[3]
return c }
// Encrypt256 encrypts the 4 words of block using the expanded 256 bit key and
// the 128 bit tweak. The keys[4] must be keys[0] xor keys[1] xor ... keys[3] xor C240.
// The tweak[2] must be tweak[0] xor tweak[1].
func Encrypt256(block *[4]uint64, keys *[5]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3]
for r := 0; r < 17; r++ { b0 += keys[r%5] b1 += keys[(r+1)%5] + tweak[r%3] b2 += keys[(r+2)%5] + tweak[(r+1)%3] b3 += keys[(r+3)%5] + uint64(r)
b0 += b1 b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0 b2 += b3 b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2
b0 += b3 b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0 b2 += b1 b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2
b0 += b1 b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0 b2 += b3 b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2
b0 += b3 b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0 b2 += b1 b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2
r++
b0 += keys[r%5] b1 += keys[(r+1)%5] + tweak[r%3] b2 += keys[(r+2)%5] + tweak[(r+1)%3] b3 += keys[(r+3)%5] + uint64(r)
b0 += b1 b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0 b2 += b3 b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2
b0 += b3 b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0 b2 += b1 b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2
b0 += b1 b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0 b2 += b3 b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2
b0 += b3 b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0 b2 += b1 b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2 }
b0 += keys[3] b1 += keys[4] + tweak[0] b2 += keys[0] + tweak[1] b3 += keys[1] + uint64(18)
block[0], block[1], block[2], block[3] = b0, b1, b2, b3 }
// Decrypt256 decrypts the 4 words of block using the expanded 256 bit key and
// the 128 bit tweak. The keys[4] must be keys[0] xor keys[1] xor ... keys[3] xor C240.
// The tweak[2] must be tweak[0] xor tweak[1].
func Decrypt256(block *[4]uint64, keys *[5]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3]
var tmp uint64 for r := 18; r > 1; r-- { b0 -= keys[r%5] b1 -= keys[(r+1)%5] + tweak[r%3] b2 -= keys[(r+2)%5] + tweak[(r+1)%3] b3 -= keys[(r+3)%5] + uint64(r)
tmp = b1 ^ b2 b1 = (tmp >> 32) | (tmp << (64 - 32)) b2 -= b1 tmp = b3 ^ b0 b3 = (tmp >> 32) | (tmp << (64 - 32)) b0 -= b3
tmp = b3 ^ b2 b3 = (tmp >> 22) | (tmp << (64 - 22)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 58) | (tmp << (64 - 58)) b0 -= b1
tmp = b1 ^ b2 b1 = (tmp >> 12) | (tmp << (64 - 12)) b2 -= b1 tmp = b3 ^ b0 b3 = (tmp >> 46) | (tmp << (64 - 46)) b0 -= b3
tmp = b3 ^ b2 b3 = (tmp >> 33) | (tmp << (64 - 33)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 25) | (tmp << (64 - 25)) b0 -= b1
r--
b0 -= keys[r%5] b1 -= keys[(r+1)%5] + tweak[r%3] b2 -= keys[(r+2)%5] + tweak[(r+1)%3] b3 -= keys[(r+3)%5] + uint64(r)
tmp = b1 ^ b2 b1 = (tmp >> 37) | (tmp << (64 - 37)) b2 -= b1 tmp = b3 ^ b0 b3 = (tmp >> 5) | (tmp << (64 - 5)) b0 -= b3
tmp = b3 ^ b2 b3 = (tmp >> 40) | (tmp << (64 - 40)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 23) | (tmp << (64 - 23)) b0 -= b1
tmp = b1 ^ b2 b1 = (tmp >> 57) | (tmp << (64 - 57)) b2 -= b1 tmp = b3 ^ b0 b3 = (tmp >> 52) | (tmp << (64 - 52)) b0 -= b3
tmp = b3 ^ b2 b3 = (tmp >> 16) | (tmp << (64 - 16)) b2 -= b3 tmp = b1 ^ b0 b1 = (tmp >> 14) | (tmp << (64 - 14)) b0 -= b1 }
b0 -= keys[0] b1 -= keys[1] + tweak[0] b2 -= keys[2] + tweak[1] b3 -= keys[3]
block[0], block[1], block[2], block[3] = b0, b1, b2, b3 }
// UBI256 does a Threefish256 encryption of the given block using
// the chain values hVal and the tweak.
// The chain values are updated through hVal[i] = block[i] ^ Enc(block)[i]
func UBI256(block *[4]uint64, hVal *[5]uint64, tweak *[3]uint64) { b0, b1, b2, b3 := block[0], block[1], block[2], block[3]
hVal[4] = C240 ^ hVal[0] ^ hVal[1] ^ hVal[2] ^ hVal[3] tweak[2] = tweak[0] ^ tweak[1]
Encrypt256(block, hVal, tweak)
hVal[0] = block[0] ^ b0 hVal[1] = block[1] ^ b1 hVal[2] = block[2] ^ b2 hVal[3] = block[3] ^ b3 }
|