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