// 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 desimport ()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) {varuint32 = ^ 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)varfeistelBox [8][64]uint32varfeistelBoxOncesync.Once// general purpose function to perform DES block permutations.func ( uint64, []uint8) ( uint64) {for , := range { := ( >> ) & 1 |= << uint((len()-1)-) }return}func () {for := rangesBoxes {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.func ( uint64) uint64 {// 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 57return}// permuteFinalBlock is equivalent to the permutation defined// by finalPermutation.func ( uint64) uint64 {// 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 ^ >>48return}// creates 16 28-bit blocks rotated according// to the rotation schedule.func ( uint32) ( []uint32) { = make([]uint32, 16) := for := 0; < 16; ++ {// 28-bit circular left shift := ( << (4 + ksRotations[])) >> 4 := ( << 4) >> (32 - ksRotations[]) [] = | = [] }return}// creates 16 56-bit subkeys from the original key.func ( *desCipher) ( []byte) {feistelBoxOnce.Do(initFeistelBox)// 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 subkeysfor := 0; < 16; ++ {// combine halves to form 56-bit input to PC2 := uint64([])<<28 | uint64([])// 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 {return ((>>(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)}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.