Commit 906b2e76 authored by Adam Langley's avatar Adam Langley

crypto/des: cleanups

R=rsc
CC=golang-dev
https://golang.org/cl/4315050
parent 2db1769d
...@@ -35,6 +35,7 @@ DIRS=\ ...@@ -35,6 +35,7 @@ DIRS=\
crypto/blowfish\ crypto/blowfish\
crypto/cast5\ crypto/cast5\
crypto/cipher\ crypto/cipher\
crypto/des\
crypto/dsa\ crypto/dsa\
crypto/ecdsa\ crypto/ecdsa\
crypto/elliptic\ crypto/elliptic\
......
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package des package des
// Encrypt one block from src into dst, using the subkeys. import (
func encryptBlock(subkeys [16]uint64, dst, src []byte) { "encoding/binary"
// perform initial permutation )
permutedSrc := permuteBlock(src, initialPermutation[0:])
// split into left and right halves func cryptBlock(subkeys []uint64, dst, src []byte, decrypt bool) {
left := uint32(permutedSrc >> 32) b := binary.BigEndian.Uint64(src)
right := uint32(permutedSrc) b = permuteBlock(b, initialPermutation[:])
left, right := uint32(b>>32), uint32(b)
// process left and right with feistel function var subkey uint64
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
previousRight := right if decrypt {
right = left ^ feistel(right, subkeys[i]) subkey = subkeys[15-i]
left = previousRight } else {
subkey = subkeys[i]
}
left, right = right, left^feistel(right, subkey)
} }
// switch left & right and perform final permutation // switch left & right and perform final permutation
preOutput := (uint64(right) << 32) | uint64(left) preOutput := (uint64(right) << 32) | uint64(left)
final := uint64ToBytes(permuteBlock(uint64ToBytes(preOutput), finalPermutation[0:])) binary.BigEndian.PutUint64(dst, permuteBlock(preOutput, finalPermutation[:]))
}
// copy bytes to destination // Encrypt one block from src into dst, using the subkeys.
copy(dst, final) func encryptBlock(subkeys []uint64, dst, src []byte) {
cryptBlock(subkeys, dst, src, false)
} }
// Decrypt one block from src into dst, using the subkeys. // Decrypt one block from src into dst, using the subkeys.
func decryptBlock(subkeys [16]uint64, dst, src []byte) { func decryptBlock(subkeys []uint64, dst, src []byte) {
// perform initial permutation cryptBlock(subkeys, dst, src, true)
permutedSrc := permuteBlock(src, initialPermutation[0:])
// split into left and right halves
left := uint32(permutedSrc >> 32)
right := uint32(permutedSrc)
// process left and right with feistel function
for i := 0; i < 16; i++ {
previousRight := right
// decryption reverses order of subkeys
right = left ^ feistel(right, subkeys[15-i])
left = previousRight
}
// switch left & right and perform final permutation
preOutput := (uint64(right) << 32) | uint64(left)
final := uint64ToBytes(permuteBlock(uint64ToBytes(preOutput), finalPermutation[0:]))
// copy bytes to destination
copy(dst, final)
} }
// DES Feistel function // DES Feistel function
func feistel(right uint32, key uint64) (result uint32) { func feistel(right uint32, key uint64) (result uint32) {
rightExpanded := permuteBlock(uint32ToBytes(right), expansionFunction[:]) sBoxLocations := key ^ permuteBlock(uint64(right), expansionFunction[:])
xorResult := key ^ rightExpanded
var sBoxResult uint32 var sBoxResult uint32
for i := uint8(0); i < 8; i++ { for i := uint8(0); i < 8; i++ {
sBoxCoordValue := uint8((xorResult << (16 + (6 * i))) >> 58) sBoxLocation := uint8(sBoxLocations>>42) & 0x3f
// determine the proper S-box row and column from the 6-bits of sBoxLocations <<= 6
// sBoxCoordValue row is determined by 1st and 6th bit // row determined by 1st and 6th bit
row := (sBoxCoordValue & 0x1) | ((sBoxCoordValue & 0x20) >> 4) row := (sBoxLocation & 0x1) | ((sBoxLocation & 0x20) >> 4)
// column is middle four bits // column is middle four bits
column := (sBoxCoordValue << 3) >> 4 column := (sBoxLocation >> 1) & 0xf
sBoxResult |= uint32(sBoxes[i][row][column]) << (4 * (7 - i)) sBoxResult |= uint32(sBoxes[i][row][column]) << (4 * (7 - i))
} }
return uint32(permuteBlock(uint32ToBytes(sBoxResult), permutationFunction[0:])) return uint32(permuteBlock(uint64(sBoxResult), permutationFunction[:]))
} }
// general purpose function to perform DES block permutations // general purpose function to perform DES block permutations
func permuteBlock(src []byte, permutation []uint8) (block uint64) { func permuteBlock(src uint64, permutation []uint8) (block uint64) {
for finalPosition, bitNumber := range permutation { for position, n := range permutation {
bitIndex := bitNumber - 1 bit := (src >> n) & 1
byteIndex := bitIndex >> 3 block |= bit << uint((len(permutation)-1)-position)
bitNumberInByte := bitIndex % 8
bitValue := (src[byteIndex] << bitNumberInByte) >> 7
block |= uint64(bitValue) << uint64((uint8(len(permutation)-1))-uint8(finalPosition))
} }
return return
} }
...@@ -87,18 +70,19 @@ func ksRotate(in uint32) (out []uint32) { ...@@ -87,18 +70,19 @@ func ksRotate(in uint32) (out []uint32) {
last := in last := in
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
// 28-bit circular left shift // 28-bit circular left shift
part1 := (last << (4 + uint32(ksRotations[i]))) >> 4 left := (last << (4 + ksRotations[i])) >> 4
part2 := (last << 4) >> (32 - ksRotations[i]) right := (last << 4) >> (32 - ksRotations[i])
out[i] = part1 | part2 out[i] = left | right
last = out[i] last = out[i]
} }
return return
} }
// creates 16 56-bit subkeys from the original key // creates 16 56-bit subkeys from the original key
func ksGenerateSubkeys(cipher *DESCipher) { func (c *Cipher) generateSubkeys(keyBytes []byte) {
// apply PC1 permutation to key // apply PC1 permutation to key
permutedKey := permuteBlock(cipher.key, permutedChoice1[0:]) key := binary.BigEndian.Uint64(keyBytes)
permutedKey := permuteBlock(key, permutedChoice1[:])
// rotate halves of permuted key according to the rotation schedule // rotate halves of permuted key according to the rotation schedule
leftRotations := ksRotate(uint32(permutedKey >> 28)) leftRotations := ksRotate(uint32(permutedKey >> 28))
...@@ -109,22 +93,6 @@ func ksGenerateSubkeys(cipher *DESCipher) { ...@@ -109,22 +93,6 @@ func ksGenerateSubkeys(cipher *DESCipher) {
// combine halves to form 56-bit input to PC2 // combine halves to form 56-bit input to PC2
pc2Input := uint64(leftRotations[i])<<28 | uint64(rightRotations[i]) pc2Input := uint64(leftRotations[i])<<28 | uint64(rightRotations[i])
// apply PC2 permutation to 7 byte input // apply PC2 permutation to 7 byte input
cipher.subkeys[i] = permuteBlock(uint64ToBytes(pc2Input)[1:], permutedChoice2[0:]) c.subkeys[i] = permuteBlock(pc2Input, permutedChoice2[:])
} }
} }
// generates a byte array from uint32 input
func uint32ToBytes(block uint32) []byte {
return []byte{
byte(block >> 24), byte(block >> 16),
byte(block >> 8), byte(block)}
}
// generates a byte array from uint64 input
func uint64ToBytes(block uint64) []byte {
return []byte{
byte(block >> 56), byte(block >> 48),
byte(block >> 40), byte(block >> 32),
byte(block >> 24), byte(block >> 16),
byte(block >> 8), byte(block)}
}
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
...@@ -18,42 +18,37 @@ func (k KeySizeError) String() string { ...@@ -18,42 +18,37 @@ func (k KeySizeError) String() string {
return "crypto/des: invalid key size " + strconv.Itoa(int(k)) return "crypto/des: invalid key size " + strconv.Itoa(int(k))
} }
// A DESCipher is an instance of DES encryption. // Cipher is an instance of DES encryption.
type DESCipher struct { type Cipher struct {
key []byte
subkeys [16]uint64 subkeys [16]uint64
} }
// NewCipher creates and returns a new Cipher. // NewCipher creates and returns a new Cipher.
func NewDESCipher(key []byte) (*DESCipher, os.Error) { func NewCipher(key []byte) (*Cipher, os.Error) {
k := len(key) if len(key) != 8 {
if k != 8 { return nil, KeySizeError(len(key))
return nil, KeySizeError(k)
} }
c := &DESCipher{key, [16]uint64{}} c := new(Cipher)
ksGenerateSubkeys(c) c.generateSubkeys(key)
return c, nil return c, nil
} }
// BlockSize returns the DES block size, 8 bytes. // BlockSize returns the DES block size, 8 bytes.
func (c *DESCipher) BlockSize() int { return BlockSize } func (c *Cipher) BlockSize() int { return BlockSize }
// Encrypts the 8-byte buffer src and stores the result in dst. // Encrypts the 8-byte buffer src and stores the result in dst.
// Note that for amounts of data larger than a block, // Note that for amounts of data larger than a block,
// it is not safe to just call Encrypt on successive blocks; // it is not safe to just call Encrypt on successive blocks;
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). // instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
func (c *DESCipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys, dst, src) } func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys[:], dst, src) }
// Decrypts the 8-byte buffer src and stores the result in dst. // Decrypts the 8-byte buffer src and stores the result in dst.
func (c *DESCipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys, dst, src) } func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) }
// Reset zeros the key data, so that it will no longer // Reset zeros the key data, so that it will no longer
// appear in the process's memory. // appear in the process's memory.
func (c *DESCipher) Reset() { func (c *Cipher) Reset() {
for i := 0; i < len(c.key); i++ {
c.key[i] = 0
}
for i := 0; i < len(c.subkeys); i++ { for i := 0; i < len(c.subkeys); i++ {
c.subkeys[i] = 0 c.subkeys[i] = 0
} }
...@@ -61,21 +56,19 @@ func (c *DESCipher) Reset() { ...@@ -61,21 +56,19 @@ func (c *DESCipher) Reset() {
// A TripleDESCipher is an instance of TripleDES encryption. // A TripleDESCipher is an instance of TripleDES encryption.
type TripleDESCipher struct { type TripleDESCipher struct {
key []byte cipher1, cipher2, cipher3 Cipher
cipher1, cipher2, cipher3 *DESCipher
} }
// NewCipher creates and returns a new Cipher. // NewCipher creates and returns a new Cipher.
func NewTripleDESCipher(key []byte) (*TripleDESCipher, os.Error) { func NewTripleDESCipher(key []byte) (*TripleDESCipher, os.Error) {
k := len(key) if len(key) != 24 {
if k != 24 { return nil, KeySizeError(len(key))
return nil, KeySizeError(k)
} }
cipher1, _ := NewDESCipher(key[0:8]) c := new(TripleDESCipher)
cipher2, _ := NewDESCipher(key[8:16]) c.cipher1.generateSubkeys(key[:8])
cipher3, _ := NewDESCipher(key[16:]) c.cipher2.generateSubkeys(key[8:16])
c := &TripleDESCipher{key, cipher1, cipher2, cipher3} c.cipher3.generateSubkeys(key[16:])
return c, nil return c, nil
} }
...@@ -104,9 +97,6 @@ func (c *TripleDESCipher) Decrypt(dst, src []byte) { ...@@ -104,9 +97,6 @@ func (c *TripleDESCipher) Decrypt(dst, src []byte) {
// Reset zeros the key data, so that it will no longer // Reset zeros the key data, so that it will no longer
// appear in the process's memory. // appear in the process's memory.
func (c *TripleDESCipher) Reset() { func (c *TripleDESCipher) Reset() {
for i := 0; i < len(c.key); i++ {
c.key[i] = 0
}
c.cipher1.Reset() c.cipher1.Reset()
c.cipher2.Reset() c.cipher2.Reset()
c.cipher3.Reset() c.cipher3.Reset()
......
...@@ -7,132 +7,133 @@ ...@@ -7,132 +7,133 @@
// in U.S. Federal Information Processing Standards Publication 46-3. // in U.S. Federal Information Processing Standards Publication 46-3.
package des package des
// Used to perform an initial permutation of a // Used to perform an initial permutation of a 64-bit input block.
// 64-bit input block var initialPermutation = [64]byte{
var initialPermutation = [64]uint8{ 6, 14, 22, 30, 38, 46, 54, 62,
58, 50, 42, 34, 26, 18, 10, 2, 4, 12, 20, 28, 36, 44, 52, 60,
60, 52, 44, 36, 28, 20, 12, 4, 2, 10, 18, 26, 34, 42, 50, 58,
62, 54, 46, 38, 30, 22, 14, 6, 0, 8, 16, 24, 32, 40, 48, 56,
64, 56, 48, 40, 32, 24, 16, 8, 7, 15, 23, 31, 39, 47, 55, 63,
57, 49, 41, 33, 25, 17, 9, 1, 5, 13, 21, 29, 37, 45, 53, 61,
59, 51, 43, 35, 27, 19, 11, 3, 3, 11, 19, 27, 35, 43, 51, 59,
61, 53, 45, 37, 29, 21, 13, 5, 1, 9, 17, 25, 33, 41, 49, 57,
63, 55, 47, 39, 31, 23, 15, 7} }
// Used to perform a final permutation of a // Used to perform a final permutation of a 4-bit preoutput block. This is the
// 64-bit preoutput block // inverse of initialPermutation
// This is the inverse of initialPermutation var finalPermutation = [64]byte{
var finalPermutation = [64]uint8{ 24, 56, 16, 48, 8, 40, 0, 32,
40, 8, 48, 16, 56, 24, 64, 32, 25, 57, 17, 49, 9, 41, 1, 33,
39, 7, 47, 15, 55, 23, 63, 31, 26, 58, 18, 50, 10, 42, 2, 34,
38, 6, 46, 14, 54, 22, 62, 30, 27, 59, 19, 51, 11, 43, 3, 35,
37, 5, 45, 13, 53, 21, 61, 29, 28, 60, 20, 52, 12, 44, 4, 36,
36, 4, 44, 12, 52, 20, 60, 28, 29, 61, 21, 53, 13, 45, 5, 37,
35, 3, 43, 11, 51, 19, 59, 27, 30, 62, 22, 54, 14, 46, 6, 38,
34, 2, 42, 10, 50, 18, 58, 26, 31, 63, 23, 55, 15, 47, 7, 39,
33, 1, 41, 9, 49, 17, 57, 25} }
// Used to expand an input block of 32 bits, // Used to expand an input block of 32 bits, producing an output block of 48
// producing an output block of 48 bits. // bits.
var expansionFunction = [48]uint8{ var expansionFunction = [48]byte{
32, 1, 2, 3, 4, 5, 0, 31, 30, 29, 28, 27, 28, 27,
4, 5, 6, 7, 8, 9, 26, 25, 24, 23, 24, 23, 22, 21,
8, 9, 10, 11, 12, 13, 20, 19, 20, 19, 18, 17, 16, 15,
12, 13, 14, 15, 16, 17, 16, 15, 14, 13, 12, 11, 12, 11,
16, 17, 18, 19, 20, 21, 10, 9, 8, 7, 8, 7, 6, 5,
20, 21, 22, 23, 24, 25, 4, 3, 4, 3, 2, 1, 0, 31,
24, 25, 26, 27, 28, 29, }
28, 29, 30, 31, 32, 1}
// Yields a 32-bit output from a 32-bit input // Yields a 32-bit output from a 32-bit input
var permutationFunction = [32]uint8{ var permutationFunction = [32]byte{
16, 7, 20, 21, 16, 25, 12, 11, 3, 20, 4, 15,
29, 12, 28, 17, 31, 17, 9, 6, 27, 14, 1, 22,
1, 15, 23, 26, 30, 24, 8, 18, 0, 5, 29, 23,
5, 18, 31, 10, 13, 19, 2, 26, 10, 21, 28, 7,
2, 8, 24, 14, }
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25}
// Used in the key schedule to select 56 bits // Used in the key schedule to select 56 bits
// from a 64-bit input. // from a 64-bit input.
var permutedChoice1 = [56]uint8{ var permutedChoice1 = [56]byte{
// left 7, 15, 23, 31, 39, 47, 55, 63,
57, 49, 41, 33, 25, 17, 9, 6, 14, 22, 30, 38, 46, 54, 62,
1, 58, 50, 42, 34, 26, 18, 5, 13, 21, 29, 37, 45, 53, 61,
10, 2, 59, 51, 43, 35, 27, 4, 12, 20, 28, 1, 9, 17, 25,
19, 11, 3, 60, 52, 44, 36, 33, 41, 49, 57, 2, 10, 18, 26,
// right 34, 42, 50, 58, 3, 11, 19, 27,
63, 55, 47, 39, 31, 23, 15, 35, 43, 51, 59, 36, 44, 52, 60,
7, 62, 54, 46, 38, 30, 22, }
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4}
// Used in the key schedule to produce // Used in the key schedule to produce each subkey by selecting 48 bits from
// each subkey by selecting 48 bits // the 56-bit input
// from the 56-bit input var permutedChoice2 = [48]byte{
var permutedChoice2 = [48]uint8{ 42, 39, 45, 32, 55, 51, 53, 28,
14, 17, 11, 24, 1, 5, 41, 50, 35, 46, 33, 37, 44, 52,
3, 28, 15, 6, 21, 10, 30, 48, 40, 49, 29, 36, 43, 54,
23, 19, 12, 4, 26, 8, 15, 4, 25, 19, 9, 1, 26, 16,
16, 7, 27, 20, 13, 2, 5, 11, 23, 8, 12, 7, 17, 0,
41, 52, 31, 37, 47, 55, 22, 3, 10, 14, 6, 20, 27, 24,
30, 40, 51, 45, 33, 48, }
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32}
// 8 S-boxes composed of 4 rows and 16 columns // 8 S-boxes composed of 4 rows and 16 columns
// Used in the DES cipher function // Used in the DES cipher function
var sBoxes = [8][4][16]uint8{ var sBoxes = [8][4][16]uint8{
// S-box 1 // S-box 1
{ {
[16]uint8{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
[16]uint8{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
[16]uint8{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
[16]uint8{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
},
// S-box 2 // S-box 2
{ {
[16]uint8{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
[16]uint8{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
[16]uint8{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
[16]uint8{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
},
// S-box 3 // S-box 3
{ {
[16]uint8{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
[16]uint8{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
[16]uint8{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
[16]uint8{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
},
// S-box 4 // S-box 4
{ {
[16]uint8{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
[16]uint8{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
[16]uint8{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
[16]uint8{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
},
// S-box 5 // S-box 5
{ {
[16]uint8{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
[16]uint8{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
[16]uint8{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
[16]uint8{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
},
// S-box 6 // S-box 6
{ {
[16]uint8{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
[16]uint8{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
[16]uint8{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
[16]uint8{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
},
// S-box 7 // S-box 7
{ {
[16]uint8{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
[16]uint8{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
[16]uint8{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
[16]uint8{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
},
// S-box 8 // S-box 8
{ {
[16]uint8{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
[16]uint8{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
[16]uint8{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
[16]uint8{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}} {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
},
}
// Size of left rotation per round in each half of the key schedule // Size of left rotation per round in each half of the key schedule
var ksRotations = [16]uint8{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1} var ksRotations = [16]uint8{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package des package des
import ( import (
"bytes"
"testing" "testing"
) )
...@@ -1263,10 +1264,9 @@ var tableA4Tests = []CryptTest{ ...@@ -1263,10 +1264,9 @@ var tableA4Tests = []CryptTest{
func TestWeakKeys(t *testing.T) { func TestWeakKeys(t *testing.T) {
for i, tt := range weakKeyTests { for i, tt := range weakKeyTests {
var encrypt = func(in []byte) (out []byte) { var encrypt = func(in []byte) (out []byte) {
c := &DESCipher{tt.key, [16]uint64{}} c, _ := NewCipher(tt.key)
ksGenerateSubkeys(c)
out = make([]byte, len(in)) out = make([]byte, len(in))
encryptBlock(c.subkeys, out, in) encryptBlock(c.subkeys[:], out, in)
return return
} }
...@@ -1275,11 +1275,8 @@ func TestWeakKeys(t *testing.T) { ...@@ -1275,11 +1275,8 @@ func TestWeakKeys(t *testing.T) {
result := encrypt(tt.in) result := encrypt(tt.in)
result = encrypt(result) result = encrypt(result)
for j, v := range result { if !bytes.Equal(result, tt.in) {
if v != tt.in[j] { t.Errorf("#%d: result: %x want: %x", i, result, tt.in)
t.Errorf("weak key test %d: result[%d] = %#x, want %#x", i, j, v, tt.in[j])
break
}
} }
} }
} }
...@@ -1288,10 +1285,9 @@ func TestWeakKeys(t *testing.T) { ...@@ -1288,10 +1285,9 @@ func TestWeakKeys(t *testing.T) {
func TestSemiWeakKeyPairs(t *testing.T) { func TestSemiWeakKeyPairs(t *testing.T) {
for i, tt := range semiWeakKeyTests { for i, tt := range semiWeakKeyTests {
var encrypt = func(key, in []byte) (out []byte) { var encrypt = func(key, in []byte) (out []byte) {
c := &DESCipher{key, [16]uint64{}} c, _ := NewCipher(key)
ksGenerateSubkeys(c)
out = make([]byte, len(in)) out = make([]byte, len(in))
encryptBlock(c.subkeys, out, in) encryptBlock(c.subkeys[:], out, in)
return return
} }
...@@ -1301,81 +1297,57 @@ func TestSemiWeakKeyPairs(t *testing.T) { ...@@ -1301,81 +1297,57 @@ func TestSemiWeakKeyPairs(t *testing.T) {
result := encrypt(tt.key, tt.in) result := encrypt(tt.key, tt.in)
result = encrypt(tt.out, result) result = encrypt(tt.out, result)
for j, v := range result { if !bytes.Equal(result, tt.in) {
if v != tt.in[j] { t.Errorf("#%d: result: %x want: %x", i, result, tt.in)
t.Errorf("semi weak key test %d: result[%d] = %#x, want %#x", i, j, v, tt.in[j])
break
}
} }
} }
} }
func TestDESEncryptBlock(t *testing.T) { func TestDESEncryptBlock(t *testing.T) {
for i, tt := range encryptDESTests { for i, tt := range encryptDESTests {
c := &DESCipher{tt.key, [16]uint64{}} c, _ := NewCipher(tt.key)
ksGenerateSubkeys(c)
out := make([]byte, len(tt.in)) out := make([]byte, len(tt.in))
encryptBlock(c.subkeys, out, tt.in) encryptBlock(c.subkeys[:], out, tt.in)
for j, v := range out { if !bytes.Equal(out, tt.out) {
if v != tt.out[j] { t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
t.Errorf("encryptBlock %d: out[%d] = %#x, want %#x", i, j, v, tt.out[j])
break
}
} }
} }
} }
func TestDESDecryptBlock(t *testing.T) { func TestDESDecryptBlock(t *testing.T) {
for i, tt := range encryptDESTests { for i, tt := range encryptDESTests {
c := &DESCipher{tt.key, [16]uint64{}} c, _ := NewCipher(tt.key)
ksGenerateSubkeys(c)
plain := make([]byte, len(tt.in)) plain := make([]byte, len(tt.in))
decryptBlock(c.subkeys, plain, tt.out) decryptBlock(c.subkeys[:], plain, tt.out)
for j, v := range plain { if !bytes.Equal(plain, tt.in) {
if v != tt.in[j] { t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
t.Errorf("decryptBlock %d: plain[%d] = %#x, want %#x", i, j, v, tt.in[j])
break
}
} }
} }
} }
func TestEncryptTripleDES(t *testing.T) { func TestEncryptTripleDES(t *testing.T) {
for i, tt := range encryptTripleDESTests { for i, tt := range encryptTripleDESTests {
cipher1, _ := NewDESCipher(tt.key[0:8]) c, _ := NewTripleDESCipher(tt.key)
cipher2, _ := NewDESCipher(tt.key[8:16])
cipher3, _ := NewDESCipher(tt.key[16:])
c := &TripleDESCipher{tt.key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.in)) out := make([]byte, len(tt.in))
c.Encrypt(out, tt.in) c.Encrypt(out, tt.in)
for j, v := range out { if !bytes.Equal(out, tt.out) {
if v != tt.out[j] { t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
t.Errorf("encrypt %d: out[%d] = %#x, want %#x", i, j, v, tt.out[j])
break
}
} }
} }
} }
func TestDecryptTripleDES(t *testing.T) { func TestDecryptTripleDES(t *testing.T) {
for i, tt := range encryptTripleDESTests { for i, tt := range encryptTripleDESTests {
cipher1, _ := NewDESCipher(tt.key[0:8]) c, _ := NewTripleDESCipher(tt.key)
cipher2, _ := NewDESCipher(tt.key[8:16])
cipher3, _ := NewDESCipher(tt.key[16:])
c := &TripleDESCipher{tt.key, cipher1, cipher2, cipher3}
plain := make([]byte, len(tt.in)) plain := make([]byte, len(tt.in))
c.Decrypt(plain, tt.out) c.Decrypt(plain, tt.out)
for j, v := range plain { if !bytes.Equal(plain, tt.in) {
if v != tt.in[j] { t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
t.Errorf("decrypt %d: plain[%d] = %#x, want %#x", i, j, v, tt.in[j])
break
}
} }
} }
} }
...@@ -1383,20 +1355,13 @@ func TestDecryptTripleDES(t *testing.T) { ...@@ -1383,20 +1355,13 @@ func TestDecryptTripleDES(t *testing.T) {
// Defined in Pub 800-20 // Defined in Pub 800-20
func TestVariablePlaintextKnownAnswer(t *testing.T) { func TestVariablePlaintextKnownAnswer(t *testing.T) {
for i, tt := range tableA1Tests { for i, tt := range tableA1Tests {
cipher1, _ := NewDESCipher(tableA1Key[0:8]) c, _ := NewTripleDESCipher(tableA1Key)
cipher2, _ := NewDESCipher(tableA1Key[8:16])
cipher3, _ := NewDESCipher(tableA1Key[16:])
c := &TripleDESCipher{tableA1Key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.in)) out := make([]byte, len(tt.in))
c.Encrypt(out, tt.in) c.Encrypt(out, tt.in)
for j, v := range out { if !bytes.Equal(out, tt.out) {
if v != tt.out[j] { t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
t.Errorf("variable plaintext known answer test %d: out[%d] = %#x, want %#x",
i, j, v, tt.out[j])
break
}
} }
} }
} }
...@@ -1404,20 +1369,13 @@ func TestVariablePlaintextKnownAnswer(t *testing.T) { ...@@ -1404,20 +1369,13 @@ func TestVariablePlaintextKnownAnswer(t *testing.T) {
// Defined in Pub 800-20 // Defined in Pub 800-20
func TestVariableCiphertextKnownAnswer(t *testing.T) { func TestVariableCiphertextKnownAnswer(t *testing.T) {
for i, tt := range tableA1Tests { for i, tt := range tableA1Tests {
cipher1, _ := NewDESCipher(tableA1Key[0:8]) c, _ := NewTripleDESCipher(tableA1Key)
cipher2, _ := NewDESCipher(tableA1Key[8:16])
cipher3, _ := NewDESCipher(tableA1Key[16:])
c := &TripleDESCipher{tableA1Key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.out)) plain := make([]byte, len(tt.out))
c.Decrypt(out, tt.out) c.Decrypt(plain, tt.out)
for j, v := range out { if !bytes.Equal(plain, tt.in) {
if v != tt.in[j] { t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
t.Errorf("variable ciphertext known answer test %d: in[%d] = %#x, want %#x",
i, j, v, tt.in[j])
break
}
} }
} }
} }
...@@ -1427,20 +1385,13 @@ func TestVariableCiphertextKnownAnswer(t *testing.T) { ...@@ -1427,20 +1385,13 @@ func TestVariableCiphertextKnownAnswer(t *testing.T) {
// 0x01... key produces the original plaintext // 0x01... key produces the original plaintext
func TestInversePermutationKnownAnswer(t *testing.T) { func TestInversePermutationKnownAnswer(t *testing.T) {
for i, tt := range tableA1Tests { for i, tt := range tableA1Tests {
cipher1, _ := NewDESCipher(tableA1Key[0:8]) c, _ := NewTripleDESCipher(tableA1Key)
cipher2, _ := NewDESCipher(tableA1Key[8:16])
cipher3, _ := NewDESCipher(tableA1Key[16:])
c := &TripleDESCipher{tableA1Key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.in)) plain := make([]byte, len(tt.in))
c.Encrypt(out, tt.out) c.Encrypt(plain, tt.out)
for j, v := range out { if !bytes.Equal(plain, tt.in) {
if v != tt.in[j] { t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
t.Errorf("inverse permutation known answer test %d: in[%d] = %#x, want %#x",
i, j, v, tt.in[j])
break
}
} }
} }
} }
...@@ -1450,20 +1401,13 @@ func TestInversePermutationKnownAnswer(t *testing.T) { ...@@ -1450,20 +1401,13 @@ func TestInversePermutationKnownAnswer(t *testing.T) {
// 0x01... key produces the corresponding ciphertext // 0x01... key produces the corresponding ciphertext
func TestInitialPermutationKnownAnswer(t *testing.T) { func TestInitialPermutationKnownAnswer(t *testing.T) {
for i, tt := range tableA1Tests { for i, tt := range tableA1Tests {
cipher1, _ := NewDESCipher(tableA1Key[0:8]) c, _ := NewTripleDESCipher(tableA1Key)
cipher2, _ := NewDESCipher(tableA1Key[8:16])
cipher3, _ := NewDESCipher(tableA1Key[16:])
c := &TripleDESCipher{tableA1Key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.in)) out := make([]byte, len(tt.in))
c.Decrypt(out, tt.in) c.Decrypt(out, tt.in)
for j, v := range out { if !bytes.Equal(out, tt.out) {
if v != tt.out[j] { t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
t.Errorf("initial permutation known answer test %d: out[%d] = %#x, want %#x",
i, j, v, tt.out[j])
break
}
} }
} }
} }
...@@ -1471,20 +1415,13 @@ func TestInitialPermutationKnownAnswer(t *testing.T) { ...@@ -1471,20 +1415,13 @@ func TestInitialPermutationKnownAnswer(t *testing.T) {
// Defined in Pub 800-20 // Defined in Pub 800-20
func TestVariableKeyKnownAnswerEncrypt(t *testing.T) { func TestVariableKeyKnownAnswerEncrypt(t *testing.T) {
for i, tt := range tableA2Tests { for i, tt := range tableA2Tests {
cipher1, _ := NewDESCipher(tt.key[0:8]) c, _ := NewTripleDESCipher(tt.key)
cipher2, _ := NewDESCipher(tt.key[8:16])
cipher3, _ := NewDESCipher(tt.key[16:])
c := &TripleDESCipher{tt.key, cipher1, cipher2, cipher3}
out := make([]byte, len(tableA2Plaintext)) out := make([]byte, len(tableA2Plaintext))
c.Encrypt(out, tableA2Plaintext) c.Encrypt(out, tableA2Plaintext)
for j, v := range out { if !bytes.Equal(out, tt.out) {
if v != tt.out[j] { t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
t.Errorf("variable key known answer encrypt test %d: out[%d] = %#x, want %#x",
i, j, v, tt.out[j])
break
}
} }
} }
} }
...@@ -1492,20 +1429,13 @@ func TestVariableKeyKnownAnswerEncrypt(t *testing.T) { ...@@ -1492,20 +1429,13 @@ func TestVariableKeyKnownAnswerEncrypt(t *testing.T) {
// Defined in Pub 800-20 // Defined in Pub 800-20
func TestVariableKeyKnownAnswerDecrypt(t *testing.T) { func TestVariableKeyKnownAnswerDecrypt(t *testing.T) {
for i, tt := range tableA2Tests { for i, tt := range tableA2Tests {
cipher1, _ := NewDESCipher(tt.key[0:8]) c, _ := NewTripleDESCipher(tt.key)
cipher2, _ := NewDESCipher(tt.key[8:16])
cipher3, _ := NewDESCipher(tt.key[16:])
c := &TripleDESCipher{tt.key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.out)) out := make([]byte, len(tt.out))
c.Decrypt(out, tt.out) c.Decrypt(out, tt.out)
for j, v := range out { if !bytes.Equal(out, tableA2Plaintext) {
if v != tableA2Plaintext[j] { t.Errorf("#%d: result: %x want: %x", i, out, tableA2Plaintext)
t.Errorf("variable key known answer decrypt test %d: out[%d] = %#x, want %#x",
i, j, v, tableA2Plaintext[j])
break
}
} }
} }
} }
...@@ -1513,20 +1443,13 @@ func TestVariableKeyKnownAnswerDecrypt(t *testing.T) { ...@@ -1513,20 +1443,13 @@ func TestVariableKeyKnownAnswerDecrypt(t *testing.T) {
// Defined in Pub 800-20 // Defined in Pub 800-20
func TestPermutationOperationKnownAnswerEncrypt(t *testing.T) { func TestPermutationOperationKnownAnswerEncrypt(t *testing.T) {
for i, tt := range tableA3Tests { for i, tt := range tableA3Tests {
cipher1, _ := NewDESCipher(tt.key[0:8]) c, _ := NewTripleDESCipher(tt.key)
cipher2, _ := NewDESCipher(tt.key[8:16])
cipher3, _ := NewDESCipher(tt.key[16:])
c := &TripleDESCipher{tt.key, cipher1, cipher2, cipher3}
out := make([]byte, len(tableA3Plaintext)) out := make([]byte, len(tableA3Plaintext))
c.Encrypt(out, tableA3Plaintext) c.Encrypt(out, tableA3Plaintext)
for j, v := range out { if !bytes.Equal(out, tt.out) {
if v != tt.out[j] { t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
t.Errorf("permutation operation known answer encrypt test %d: out[%d] = %#x, want %#x",
i, j, v, tt.out[j])
break
}
} }
} }
} }
...@@ -1534,20 +1457,13 @@ func TestPermutationOperationKnownAnswerEncrypt(t *testing.T) { ...@@ -1534,20 +1457,13 @@ func TestPermutationOperationKnownAnswerEncrypt(t *testing.T) {
// Defined in Pub 800-20 // Defined in Pub 800-20
func TestPermutationOperationKnownAnswerDecrypt(t *testing.T) { func TestPermutationOperationKnownAnswerDecrypt(t *testing.T) {
for i, tt := range tableA3Tests { for i, tt := range tableA3Tests {
cipher1, _ := NewDESCipher(tt.key[0:8]) c, _ := NewTripleDESCipher(tt.key)
cipher2, _ := NewDESCipher(tt.key[8:16])
cipher3, _ := NewDESCipher(tt.key[16:])
c := &TripleDESCipher{tt.key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.out)) out := make([]byte, len(tt.out))
c.Decrypt(out, tt.out) c.Decrypt(out, tt.out)
for j, v := range out { if !bytes.Equal(out, tableA3Plaintext) {
if v != tableA3Plaintext[j] { t.Errorf("#%d: result: %x want: %x", i, out, tableA3Plaintext)
t.Errorf("permutation operation known answer decrypt test %d: out[%d] = %#x, want %#x",
i, j, v, tableA3Plaintext[j])
break
}
} }
} }
} }
...@@ -1555,20 +1471,13 @@ func TestPermutationOperationKnownAnswerDecrypt(t *testing.T) { ...@@ -1555,20 +1471,13 @@ func TestPermutationOperationKnownAnswerDecrypt(t *testing.T) {
// Defined in Pub 800-20 // Defined in Pub 800-20
func TestSubstitutionTableKnownAnswerEncrypt(t *testing.T) { func TestSubstitutionTableKnownAnswerEncrypt(t *testing.T) {
for i, tt := range tableA4Tests { for i, tt := range tableA4Tests {
cipher1, _ := NewDESCipher(tt.key[0:8]) c, _ := NewTripleDESCipher(tt.key)
cipher2, _ := NewDESCipher(tt.key[8:16])
cipher3, _ := NewDESCipher(tt.key[16:])
c := &TripleDESCipher{tt.key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.in)) out := make([]byte, len(tt.in))
c.Encrypt(out, tt.in) c.Encrypt(out, tt.in)
for j, v := range out { if !bytes.Equal(out, tt.out) {
if v != tt.out[j] { t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
t.Errorf("substitution table known answer encrypt test %d: out[%d] = %#x, want %#x",
i, j, v, tt.out[j])
break
}
} }
} }
} }
...@@ -1576,20 +1485,13 @@ func TestSubstitutionTableKnownAnswerEncrypt(t *testing.T) { ...@@ -1576,20 +1485,13 @@ func TestSubstitutionTableKnownAnswerEncrypt(t *testing.T) {
// Defined in Pub 800-20 // Defined in Pub 800-20
func TestSubstitutionTableKnownAnswerDecrypt(t *testing.T) { func TestSubstitutionTableKnownAnswerDecrypt(t *testing.T) {
for i, tt := range tableA4Tests { for i, tt := range tableA4Tests {
cipher1, _ := NewDESCipher(tt.key[0:8]) c, _ := NewTripleDESCipher(tt.key)
cipher2, _ := NewDESCipher(tt.key[8:16])
cipher3, _ := NewDESCipher(tt.key[16:])
c := &TripleDESCipher{tt.key, cipher1, cipher2, cipher3}
out := make([]byte, len(tt.out)) out := make([]byte, len(tt.out))
c.Decrypt(out, tt.out) c.Decrypt(out, tt.out)
for j, v := range out { if !bytes.Equal(out, tt.in) {
if v != tt.in[j] { t.Errorf("#%d: result: %x want: %x", i, out, tt.in)
t.Errorf("substitution table known answer decrypt test %d: out[%d] = %#x, want %#x",
i, j, v, tt.in[j])
break
}
} }
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment