Python實現的Blowfish加解密

fmms 12年前發布 | 26K 次閱讀 Python Python開發

Python實現的Blowfish加解密

#

blowfish.py

Copyright (C) 2002 Michael Gilfix <mgilfix@eecs.tufts.edu>

#

This module is open source; you can redistribute it and/or

modify it under the terms of the GPL or Artistic License.

These licenses are available at http://www.opensource.org

#

This software must be used and distributed in accordance

with the law. The author claims no liability for its

misuse.

#

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#

This software was modified by Ivan Voras: CTR cipher mode of

operation was added, together with testing and example code.

These changes are (c) 2007./08. Ivan Voras <ivoras@gmail.com>

These changes can be used, modified ad distributed under the

GPL or Artistic License, the same as the original module.

All disclaimers of warranty from the original module also

apply to these changes.

CBC mode contributed by Joel Edwards <joeledwards@gmail.com>,

under the same license conditions.

""" Blowfish Encryption

This module is a pure python implementation of Bruce Schneier's encryption scheme 'Blowfish'. Blowish is a 16-round Feistel Network cipher and offers substantial speed gains over DES.

The key is a string of length anywhere between 64 and 448 bits, or equivalently 8 and 56 bytes. The encryption and decryption functions operate on 64-bit blocks, or 8 byte strings.

Send questions, comments, bugs my way: Michael Gilfix <mgilfix@eecs.tufts.edu>

The module has been expanded to include CTR stream encryption/decryption mode, built from the primitives from the orignal module. This change did not alter any of the base Blowfish code from the original author.

The author of CTR changes is: Ivan Voras <ivoras@gmail.com> """

import struct, types

author = "Michael Gilfix <mgilfix@eecs.tufts.edu>"

class Blowfish:

"""Blowfish encryption Scheme

This class implements the encryption and decryption
functionality of the Blowfish cipher.

Public functions:

    def __init__ (self, key)
        Creates an instance of blowfish using 'key'
        as the encryption key. Key is a string of
        length ranging from 8 to 56 bytes (64 to 448
        bits). Once the instance of the object is
        created, the key is no longer necessary.

    def encrypt (self, data):
        Encrypt an 8 byte (64-bit) block of text
        where 'data' is an 8 byte string. Returns an
        8-byte encrypted string.

    def decrypt (self, data):
        Decrypt an 8 byte (64-bit) encrypted block
        of text, where 'data' is the 8 byte encrypted
        string. Returns an 8-byte string of plaintext.

    def cipher (self, xl, xr, direction):
        Encrypts a 64-bit block of data where xl is
        the upper 32-bits and xr is the lower 32-bits.
        'direction' is the direction to apply the
        cipher, either ENCRYPT or DECRYPT constants.
        returns a tuple of either encrypted or decrypted
        data of the left half and right half of the
        64-bit block.

    def initCTR(self):
        Initializes CTR engine for encryption or decryption.

    def encryptCTR(self, data):
        Encrypts an arbitrary string and returns the
        encrypted string. The method can be called successively
        for multiple string blocks.

    def decryptCTR(self, data):
        Decrypts a string encrypted with encryptCTR() and
        returns the decrypted string.

Private members:

    def __round_func (self, xl)
        Performs an obscuring function on the 32-bit
        block of data 'xl', which is the left half of
        the 64-bit block of data. Returns the 32-bit
        result as a long integer.

"""

# Cipher directions
ENCRYPT = 0
DECRYPT = 1

# For the __round_func
modulus = long (2) ** 32

def __init__ (self, key):

    if not key or len (key) < 8 or len (key) > 56:
        raise RuntimeError, "Attempted to initialize Blowfish cipher with key of invalid length: %s" % len (key)

    self.p_boxes = [
        0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
        0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
        0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
        0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
        0x9216D5D9, 0x8979FB1B
    ]

    self.s_boxes = [
        [
            0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
            0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
            0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
            0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
            0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
            0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
            0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
            0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
            0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
            0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
            0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
            0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
            0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
            0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
            0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
            0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
            0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
            0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
            0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
            0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
            0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
            0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
            0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
            0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
            0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
            0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
            0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
            0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
            0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
            0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
            0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
            0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
            0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
            0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
            0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
            0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
            0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
            0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
            0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
            0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
            0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
            0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
            0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
            0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
            0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
            0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
            0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
            0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
            0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
            0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
            0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
            0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
            0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
            0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
            0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
            0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
            0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
            0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
            0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
            0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
            0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
            0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
            0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
            0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
        ],
        [
            0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
            0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
            0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
            0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
            0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
            0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
            0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
            0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
            0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
            0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
            0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
            0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
            0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
            0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
            0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
            0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
            0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
            0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
            0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
            0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
            0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
            0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
            0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
            0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
            0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
            0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
            0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
            0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
            0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
            0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
            0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
            0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
            0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
            0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
            0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
            0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
            0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
            0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
            0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
            0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
            0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
            0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
            0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
            0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
            0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
            0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
            0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
            0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
            0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
            0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
            0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
            0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
            0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
            0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
            0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
            0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
            0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
            0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
            0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
            0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
            0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
            0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
            0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
            0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
        ],
        [
            0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
            0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
            0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
            0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
            0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
            0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
            0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
            0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
            0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
            0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
            0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
            0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
            0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
            0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
            0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
            0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
            0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
            0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
            0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
            0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
            0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
            0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
            0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
            0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
            0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
            0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
            0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
            0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
            0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
            0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
            0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
            0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
            0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
            0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
            0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
            0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
            0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
            0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
            0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
            0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
            0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
            0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
            0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
            0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
            0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
            0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
            0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
            0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
            0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
            0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
            0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
            0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
            0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
            0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
            0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
            0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
            0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
            0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
            0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
            0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
            0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
            0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
            0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
            0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
        ],
        [
            0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
            0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
            0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
            0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
            0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
            0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
            0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
            0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
            0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
            0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
            0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
            0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
            0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
            0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
            0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
            0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
            0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
            0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
            0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
            0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
            0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
            0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
            0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
            0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
            0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
            0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
            0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
            0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
            0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
            0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
            0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
            0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
            0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
            0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
            0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
            0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
            0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
            0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
            0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
            0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
            0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
            0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
            0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
            0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
            0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
            0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
            0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
            0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
            0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
            0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
            0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
            0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
            0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
            0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
            0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
            0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
            0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
            0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
            0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
            0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
            0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
            0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
            0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
            0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
        ]
    ]

    # Cycle through the p-boxes and round-robin XOR the
    # key with the p-boxes
    key_len = len (key)
    index = 0
    for i in range (len (self.p_boxes)):
        val = (ord (key[index % key_len]) << 24) + \
              (ord (key[(index + 1) % key_len]) << 16) + \
              (ord (key[(index + 2) % key_len]) << 8) + \
               ord (key[(index + 3) % key_len])
        self.p_boxes[i] = self.p_boxes[i] ^ val
        index = index + 4

    # For the chaining process
    l, r = 0, 0

    # Begin chain replacing the p-boxes
    for i in range (0, len (self.p_boxes), 2):
        l, r = self.cipher (l, r, self.ENCRYPT)
        self.p_boxes[i] = l
        self.p_boxes[i + 1] = r

    # Chain replace the s-boxes
    for i in range (len (self.s_boxes)):
        for j in range (0, len (self.s_boxes[i]), 2):
            l, r = self.cipher (l, r, self.ENCRYPT)
            self.s_boxes[i][j] = l
            self.s_boxes[i][j + 1] = r

    self.initCTR()


def cipher (self, xl, xr, direction):
    """Encryption primitive"""
    if direction == self.ENCRYPT:
        for i in range (16):
            xl = xl ^ self.p_boxes[i]
            xr = self.__round_func (xl) ^ xr
            xl, xr = xr, xl
        xl, xr = xr, xl
        xr = xr ^ self.p_boxes[16]
        xl = xl ^ self.p_boxes[17]
    else:
        for i in range (17, 1, -1):
            xl = xl ^ self.p_boxes[i]
            xr = self.__round_func (xl) ^ xr
            xl, xr = xr, xl
        xl, xr = xr, xl
        xr = xr ^ self.p_boxes[1]
        xl = xl ^ self.p_boxes[0]
    return xl, xr


def __round_func (self, xl):
    a = (xl & 0xFF000000) >> 24
    b = (xl & 0x00FF0000) >> 16
    c = (xl & 0x0000FF00) >> 8
    d = xl & 0x000000FF

    # Perform all ops as longs then and out the last 32-bits to
    # obtain the integer
    f = (long (self.s_boxes[0][a]) + long (self.s_boxes[1][b])) % self.modulus
    f = f ^ long (self.s_boxes[2][c])
    f = f + long (self.s_boxes[3][d])
    f = (f % self.modulus) & 0xFFFFFFFF

    return f


def encrypt (self, data):
    if not len (data) == 8:
        raise RuntimeError, "Attempted to encrypt data of invalid block length: %s" % len(data)

    # Use big endianess since that's what everyone else uses
    xl = ord (data[3]) | (ord (data[2]) << 8) | (ord (data[1]) << 16) | (ord (data[0]) << 24)
    xr = ord (data[7]) | (ord (data[6]) << 8) | (ord (data[5]) << 16) | (ord (data[4]) << 24)

    cl, cr = self.cipher (xl, xr, self.ENCRYPT)
    chars = ''.join ([
        chr ((cl >> 24) & 0xFF), chr ((cl >> 16) & 0xFF), chr ((cl >> 8) & 0xFF), chr (cl & 0xFF),
        chr ((cr >> 24) & 0xFF), chr ((cr >> 16) & 0xFF), chr ((cr >> 8) & 0xFF), chr (cr & 0xFF)
    ])
    return chars


def decrypt (self, data):
    if not len (data) == 8:
        raise RuntimeError, "Attempted to encrypt data of invalid block length: %s" % len(data)

    # Use big endianess since that's what everyone else uses
    cl = ord (data[3]) | (ord (data[2]) << 8) | (ord (data[1]) << 16) | (ord (data[0]) << 24)
    cr = ord (data[7]) | (ord (data[6]) << 8) | (ord (data[5]) << 16) | (ord (data[4]) << 24)

    xl, xr = self.cipher (cl, cr, self.DECRYPT)
    chars = ''.join ([
        chr ((xl >> 24) & 0xFF), chr ((xl >> 16) & 0xFF), chr ((xl >> 8) & 0xFF), chr (xl & 0xFF),
        chr ((xr >> 24) & 0xFF), chr ((xr >> 16) & 0xFF), chr ((xr >> 8) & 0xFF), chr (xr & 0xFF)
    ])
    return chars


# ==== CBC Mode ====
def initCBC(self, iv=0):
    """Initializes CBC mode of the cypher"""
    assert struct.calcsize("Q") == self.block_size()
    self.cbc_iv = struct.pack("Q", iv)


def encryptCBC(self, data):
    """
    Encrypts a buffer of data using CBC mode. Multiple successive buffers
    (belonging to the same logical stream of buffers) can be encrypted
    with this method one after the other without any intermediate work.
    Each buffer must be a multiple of 8-octets (64-bits) in length.
    """
    if type(data) != types.StringType:
        raise RuntimeError, "Can only work on 8-bit strings"
    if (len(data) % 8) != 0:
        raise RuntimeError, "Can only work with data in 64-bit multiples in CBC mode"

    xor = lambda t: ord(t[0]) ^ ord(t[1])
    result = ''
    block_size = self.block_size()
    for i in range(0, len(data), block_size):
        p_block = data[i:i+block_size]
        pair = zip(p_block, self.cbc_iv)
        j_block = ''.join(map(chr, map(xor, pair)))
        c_block = self.encrypt(j_block)
        result += c_block
        self.cbc_iv = c_block
    return result


def decryptCBC(self, data):
    if type(data) != types.StringType:
        raise RuntimeError, "Can only work on 8-bit strings"
    if (len(data) % 8) != 0:
        raise RuntimeError, "Can only work with data in 64-bit multiples in CBC mode"

    xor = lambda t: ord(t[0]) ^ ord(t[1])
    result = ''
    block_size = self.block_size()
    for i in range(0, len(data), block_size):
        c_block = data[i:i+block_size]
        j_block = self.decrypt(c_block)
        pair = zip(j_block, self.cbc_iv)
        p_block = ''.join(map(chr, map(xor, pair)))
        result += p_block
        self.cbc_iv = c_block
    return result


# ==== CTR Mode ====
def initCTR(self, iv=0):
    """Initializes CTR mode of the cypher"""
    assert struct.calcsize("Q") == self.block_size()
    self.ctr_iv = iv
    self._calcCTRBUF()


def _calcCTRBUF(self):
    """Calculates one block of CTR keystream"""
    self.ctr_cks = self.encrypt(struct.pack("Q", self.ctr_iv)) # keystream block
    self.ctr_iv += 1
    self.ctr_pos = 0


def _nextCTRByte(self):
    """Returns one byte of CTR keystream"""
    b = ord(self.ctr_cks[self.ctr_pos])
    self.ctr_pos += 1
    if self.ctr_pos >= len(self.ctr_cks):
        self._calcCTRBUF()
    return b


def encryptCTR(self, data):
    """
    Encrypts a buffer of data with CTR mode. Multiple successive buffers
    (belonging to the same logical stream of buffers) can be encrypted
    with this method one after the other without any intermediate work.
    """
    if type(data) != types.StringType:
        raise RuntimeException, "Can only work on 8-bit strings"
    result = []
    for ch in data:
        result.append(chr(ord(ch) ^ self._nextCTRByte()))
    return "".join(result)


def decryptCTR(self, data):
    return self.encryptCTR(data)


def block_size(self):
    return 8


def key_length(self):
    return 56


def key_bits(self):
    return 56 * 8

@staticmethod
def testVectors():
    import binascii
    # for more vectors see http://www.schneier.com/code/vectors.txt
    vectors = (
        ('0000000000000000',        '0000000000000000',        '4EF997456198DD78'),
        ('FFFFFFFFFFFFFFFF',        'FFFFFFFFFFFFFFFF',        '51866FD5B85ECB8A'),
        ('3000000000000000',        '1000000000000001',        '7D856F9A613063F2'),
        ('1111111111111111',        '1111111111111111',        '2466DD878B963C9D'),
        ('49E95D6D4CA229BF',        '02FE55778117F12A',        'CF9C5D7A4986ADB5'),
        ('E0FEE0FEF1FEF1FE',        '0123456789ABCDEF',        'C39E072D9FAC631D'),
        ('07A7137045DA2A16',        '3BDD119049372802',        '2EEDDA93FFD39C79'),
    )
    ok = True
    for v in vectors:
        c = Blowfish(binascii.a2b_hex(v[0]))
        e = binascii.b2a_hex(c.encrypt(binascii.a2b_hex(v[1]))).upper()
        if e != v[2]:
            print "VECTOR TEST FAIL: expecting %s, got %s" % (repr(v), e)
            ok = False
    return ok



#

Module testing

if name == 'main': if not Blowfish.testVectors(): print "WARNING: The implementation doesn't pass algorithm test vectors!" else: print "The implementation passes algorithm test vectors (ECB)."

key = 'This is a test key'
cipher = Blowfish (key)

print "Testing encryption:"
xl = 123456
xr = 654321
print "\tPlain text: (%s, %s)" %(xl, xr)
cl, cr = cipher.cipher (xl, xr, cipher.ENCRYPT)
print "\tCrypted is: (%s, %s)" %(cl, cr)
dl, dr = cipher.cipher (cl, cr, cipher.DECRYPT)
print "\tUnencrypted is: (%s, %s)" %(dl, dr)

print "Testing block encrypt:"
text = 'testtest'
print "\tText:\t\t%s" %text
crypted = cipher.encrypt(text)
print "\tEncrypted:\t%s" % repr(crypted)
decrypted = cipher.decrypt(crypted)
print "\tDecrypted:\t%s" %decrypted

print "Testing CTR encrypt:"
cipher.initCTR()
text = "The quick brown fox jumps over the lazy dog"
print "\tText:\t\t", text
crypted = cipher.encryptCTR(text)
print "\tEncrypted:\t", repr(crypted)
cipher.initCTR()
decrypted = cipher.decryptCTR(crypted)
print "\tDecrypted:\t", decrypted

print "Testing CBC encrypt:"
cipher.initCBC()
text = "Owen's Ornery Old Oryx Obstructed Olga's Optics."
print "\tText:\t\t", text
crypted = cipher.encryptCBC(text)
print "\tEncrypted:\t", repr(crypted)
cipher.initCBC()
decrypted = cipher.decryptCBC(crypted)
print "\tDecrypted:\t", decrypted

print "Testing speed"
from time import time
t1 = time()
n = 0
tlen = 0
while True:
    for i in xrange(1000):
        tstr = "The quick brown fox jumps over the lazy dog %d" % i
        enc = cipher.encryptCTR(tstr)
        tlen += len(tstr)
    n += 1000
    t2 = time()
    if t2 - t1 > 5:
        break
t = t2 - t1
print "%d encryptions in %0.1f seconds: %0.1f enc/s, %0.1f bytes/s" % (n, t, n / t, tlen / t)</pre>  
 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!