...

Source file src/pkg/crypto/des/cipher.go

     1	// Copyright 2011 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package des
     6	
     7	import (
     8		"crypto/cipher"
     9		"crypto/internal/subtle"
    10		"encoding/binary"
    11		"strconv"
    12	)
    13	
    14	// The DES block size in bytes.
    15	const BlockSize = 8
    16	
    17	type KeySizeError int
    18	
    19	func (k KeySizeError) Error() string {
    20		return "crypto/des: invalid key size " + strconv.Itoa(int(k))
    21	}
    22	
    23	// desCipher is an instance of DES encryption.
    24	type desCipher struct {
    25		subkeys [16]uint64
    26	}
    27	
    28	// NewCipher creates and returns a new cipher.Block.
    29	func NewCipher(key []byte) (cipher.Block, error) {
    30		if len(key) != 8 {
    31			return nil, KeySizeError(len(key))
    32		}
    33	
    34		c := new(desCipher)
    35		c.generateSubkeys(key)
    36		return c, nil
    37	}
    38	
    39	func (c *desCipher) BlockSize() int { return BlockSize }
    40	
    41	func (c *desCipher) Encrypt(dst, src []byte) {
    42		if len(src) < BlockSize {
    43			panic("crypto/des: input not full block")
    44		}
    45		if len(dst) < BlockSize {
    46			panic("crypto/des: output not full block")
    47		}
    48		if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
    49			panic("crypto/des: invalid buffer overlap")
    50		}
    51		encryptBlock(c.subkeys[:], dst, src)
    52	}
    53	
    54	func (c *desCipher) Decrypt(dst, src []byte) {
    55		if len(src) < BlockSize {
    56			panic("crypto/des: input not full block")
    57		}
    58		if len(dst) < BlockSize {
    59			panic("crypto/des: output not full block")
    60		}
    61		if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
    62			panic("crypto/des: invalid buffer overlap")
    63		}
    64		decryptBlock(c.subkeys[:], dst, src)
    65	}
    66	
    67	// A tripleDESCipher is an instance of TripleDES encryption.
    68	type tripleDESCipher struct {
    69		cipher1, cipher2, cipher3 desCipher
    70	}
    71	
    72	// NewTripleDESCipher creates and returns a new cipher.Block.
    73	func NewTripleDESCipher(key []byte) (cipher.Block, error) {
    74		if len(key) != 24 {
    75			return nil, KeySizeError(len(key))
    76		}
    77	
    78		c := new(tripleDESCipher)
    79		c.cipher1.generateSubkeys(key[:8])
    80		c.cipher2.generateSubkeys(key[8:16])
    81		c.cipher3.generateSubkeys(key[16:])
    82		return c, nil
    83	}
    84	
    85	func (c *tripleDESCipher) BlockSize() int { return BlockSize }
    86	
    87	func (c *tripleDESCipher) Encrypt(dst, src []byte) {
    88		if len(src) < BlockSize {
    89			panic("crypto/des: input not full block")
    90		}
    91		if len(dst) < BlockSize {
    92			panic("crypto/des: output not full block")
    93		}
    94		if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
    95			panic("crypto/des: invalid buffer overlap")
    96		}
    97	
    98		b := binary.BigEndian.Uint64(src)
    99		b = permuteInitialBlock(b)
   100		left, right := uint32(b>>32), uint32(b)
   101	
   102		left = (left << 1) | (left >> 31)
   103		right = (right << 1) | (right >> 31)
   104	
   105		for i := 0; i < 8; i++ {
   106			left, right = feistel(left, right, c.cipher1.subkeys[2*i], c.cipher1.subkeys[2*i+1])
   107		}
   108		for i := 0; i < 8; i++ {
   109			right, left = feistel(right, left, c.cipher2.subkeys[15-2*i], c.cipher2.subkeys[15-(2*i+1)])
   110		}
   111		for i := 0; i < 8; i++ {
   112			left, right = feistel(left, right, c.cipher3.subkeys[2*i], c.cipher3.subkeys[2*i+1])
   113		}
   114	
   115		left = (left << 31) | (left >> 1)
   116		right = (right << 31) | (right >> 1)
   117	
   118		preOutput := (uint64(right) << 32) | uint64(left)
   119		binary.BigEndian.PutUint64(dst, permuteFinalBlock(preOutput))
   120	}
   121	
   122	func (c *tripleDESCipher) Decrypt(dst, src []byte) {
   123		if len(src) < BlockSize {
   124			panic("crypto/des: input not full block")
   125		}
   126		if len(dst) < BlockSize {
   127			panic("crypto/des: output not full block")
   128		}
   129		if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
   130			panic("crypto/des: invalid buffer overlap")
   131		}
   132	
   133		b := binary.BigEndian.Uint64(src)
   134		b = permuteInitialBlock(b)
   135		left, right := uint32(b>>32), uint32(b)
   136	
   137		left = (left << 1) | (left >> 31)
   138		right = (right << 1) | (right >> 31)
   139	
   140		for i := 0; i < 8; i++ {
   141			left, right = feistel(left, right, c.cipher3.subkeys[15-2*i], c.cipher3.subkeys[15-(2*i+1)])
   142		}
   143		for i := 0; i < 8; i++ {
   144			right, left = feistel(right, left, c.cipher2.subkeys[2*i], c.cipher2.subkeys[2*i+1])
   145		}
   146		for i := 0; i < 8; i++ {
   147			left, right = feistel(left, right, c.cipher1.subkeys[15-2*i], c.cipher1.subkeys[15-(2*i+1)])
   148		}
   149	
   150		left = (left << 31) | (left >> 1)
   151		right = (right << 31) | (right >> 1)
   152	
   153		preOutput := (uint64(right) << 32) | uint64(left)
   154		binary.BigEndian.PutUint64(dst, permuteFinalBlock(preOutput))
   155	}
   156	

View as plain text