Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package des

import (
	
	
)

func ( []uint64, ,  []byte,  bool) {
	 := binary.BigEndian.Uint64()
	 = permuteInitialBlock()
	,  := uint32(>>32), uint32()

	 = ( << 1) | ( >> 31)
	 = ( << 1) | ( >> 31)

	if  {
		for  := 0;  < 8; ++ {
			,  = feistel(, , [15-2*], [15-(2*+1)])
		}
	} else {
		for  := 0;  < 8; ++ {
			,  = feistel(, , [2*], [2*+1])
		}
	}

	 = ( << 31) | ( >> 1)
	 = ( << 31) | ( >> 1)
switch left & right and perform final permutation
	 := (uint64() << 32) | uint64()
	binary.BigEndian.PutUint64(, permuteFinalBlock())
}
Encrypt one block from src into dst, using the subkeys.
func ( []uint64, ,  []byte) {
	cryptBlock(, , , false)
}
Decrypt one block from src into dst, using the subkeys.
func ( []uint64, ,  []byte) {
	cryptBlock(, , , true)
}
DES Feistel function. feistelBox must be initialized via feistelBoxOnce.Do(initFeistelBox) first.
func (,  uint32, ,  uint64) (,  uint32) {
	var  uint32

	 =  ^ uint32(>>32)
	 ^= feistelBox[7][&0x3f] ^
		feistelBox[5][(>>8)&0x3f] ^
		feistelBox[3][(>>16)&0x3f] ^
		feistelBox[1][(>>24)&0x3f]

	 = (( << 28) | ( >> 4)) ^ uint32()
	 ^= feistelBox[6][()&0x3f] ^
		feistelBox[4][(>>8)&0x3f] ^
		feistelBox[2][(>>16)&0x3f] ^
		feistelBox[0][(>>24)&0x3f]

	 =  ^ uint32(>>32)
	 ^= feistelBox[7][&0x3f] ^
		feistelBox[5][(>>8)&0x3f] ^
		feistelBox[3][(>>16)&0x3f] ^
		feistelBox[1][(>>24)&0x3f]

	 = (( << 28) | ( >> 4)) ^ uint32()
	 ^= feistelBox[6][()&0x3f] ^
		feistelBox[4][(>>8)&0x3f] ^
		feistelBox[2][(>>16)&0x3f] ^
		feistelBox[0][(>>24)&0x3f]

	return , 
}
feistelBox[s][16*i+j] contains the output of permutationFunction for sBoxes[s][i][j] << 4*(7-s)
general purpose function to perform DES block permutations
func ( uint64,  []uint8) ( uint64) {
	for ,  := range  {
		 := ( >> ) & 1
		 |=  << uint((len()-1)-)
	}
	return
}

func () {
	for  := range sBoxes {
		for  := 0;  < 4; ++ {
			for  := 0;  < 16; ++ {
				 := uint64(sBoxes[][][]) << (4 * (7 - uint()))
				 = permuteBlock(, permutationFunction[:])
Row is determined by the 1st and 6th bit. Column is the middle four bits.
				 := uint8((( & 2) << 4) | &1)
				 := uint8( << 1)
				 :=  | 
The rotation was performed in the feistel rounds, being factored out and now mixed into the feistelBox.
				 = ( << 1) | ( >> 31)

				feistelBox[][] = uint32()
			}
		}
	}
}
permuteInitialBlock is equivalent to the permutation defined by initialPermutation.
block = b7 b6 b5 b4 b3 b2 b1 b0 (8 bytes)
	 :=  >> 48
	 :=  << 48
	 ^=  ^  ^ <<48 ^ >>48
block = b1 b0 b5 b4 b3 b2 b7 b6
	 =  >> 32 & 0xff00ff
	 = ( & 0xff00ff00)
	 ^= <<32 ^  ^ <<8 ^ <<24 // exchange b0 b4 with b3 b7
block is now b1 b3 b5 b7 b0 b2 b4 b6, the permutation: ... 8 ... 24 ... 40 ... 56 7 6 5 4 3 2 1 0 23 22 21 20 19 18 17 16 ... 32 ... 48
exchange 4,5,6,7 with 32,33,34,35 etc.
	 =  & 0x0f0f00000f0f0000
	 =  & 0x0000f0f00000f0f0
	 ^=  ^  ^ >>12 ^ <<12
block is the permutation: [+8] [+40] 7 6 5 4 23 22 21 20 3 2 1 0 19 18 17 16 [+32]
exchange 0,1,4,5 with 18,19,22,23
	 =  & 0x3300330033003300
	 =  & 0x00cc00cc00cc00cc
	 ^=  ^  ^ >>6 ^ <<6
block is the permutation: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 [+16] [+32] [+64]
exchange 0,2,4,6 with 9,11,13,15:
	 =  & 0xaaaaaaaa55555555
	 ^=  ^ >>33 ^ <<33
block is the permutation: 6 14 22 30 38 46 54 62 4 12 20 28 36 44 52 60 2 10 18 26 34 42 50 58 0 8 16 24 32 40 48 56 7 15 23 31 39 47 55 63 5 13 21 29 37 45 53 61 3 11 19 27 35 43 51 59 1 9 17 25 33 41 49 57
	return 
}
permuteInitialBlock is equivalent to the permutation defined by finalPermutation.
Perform the same bit exchanges as permuteInitialBlock but in reverse order.
	 :=  & 0xaaaaaaaa55555555
	 ^=  ^ >>33 ^ <<33

	 =  & 0x3300330033003300
	 :=  & 0x00cc00cc00cc00cc
	 ^=  ^  ^ >>6 ^ <<6

	 =  & 0x0f0f00000f0f0000
	 =  & 0x0000f0f00000f0f0
	 ^=  ^  ^ >>12 ^ <<12

	 =  >> 32 & 0xff00ff
	 = ( & 0xff00ff00)
	 ^= <<32 ^  ^ <<8 ^ <<24

	 =  >> 48
	 =  << 48
	 ^=  ^  ^ <<48 ^ >>48
	return 
}
creates 16 28-bit blocks rotated according to the rotation schedule
func ( uint32) ( []uint32) {
	 = make([]uint32, 16)
	 := 
28-bit circular left shift
		 := ( << (4 + ksRotations[])) >> 4
		 := ( << 4) >> (32 - ksRotations[])
		[] =  | 
		 = []
	}
	return
}
creates 16 56-bit subkeys from the original key
apply PC1 permutation to key
	 := binary.BigEndian.Uint64()
	 := permuteBlock(, permutedChoice1[:])
rotate halves of permuted key according to the rotation schedule
	 := ksRotate(uint32( >> 28))
	 := ksRotate(uint32(<<4) >> 4)
generate subkeys
combine halves to form 56-bit input to PC2
apply PC2 permutation to 7 byte input
		.subkeys[] = unpack(permuteBlock(, permutedChoice2[:]))
	}
}
Expand 48-bit input to 64-bit, with each 6-bit block padded by extra two bits at the top. By doing so, we can have the input blocks (four bits each), and the key blocks (six bits each) well-aligned without extra shifts/rotations for alignments.
func ( uint64) uint64 {
	var  uint64

	 = ((>>(6*1))&0xff)<<(8*0) |
		((>>(6*3))&0xff)<<(8*1) |
		((>>(6*5))&0xff)<<(8*2) |
		((>>(6*7))&0xff)<<(8*3) |
		((>>(6*0))&0xff)<<(8*4) |
		((>>(6*2))&0xff)<<(8*5) |
		((>>(6*4))&0xff)<<(8*6) |
		((>>(6*6))&0xff)<<(8*7)

	return