diff --git a/src/CryptoPlus/Cipher/pyserpent.py b/src/CryptoPlus/Cipher/pyserpent.py
deleted file mode 100644
index 8f9cf97..0000000
--- a/src/CryptoPlus/Cipher/pyserpent.py
+++ /dev/null
@@ -1,1354 +0,0 @@
-#!/usr/local/bin/python
-
-# $Id: serpref.py,v 1.19 1998/09/02 21:28:02 fms Exp $
-#
-# Python reference implementation of Serpent.
-#
-# Written by Frank Stajano,
-# Olivetti Oracle Research Laboratory and
-# Cambridge University Computer Laboratory .
-#
-# (c) 1998 Olivetti Oracle Research Laboratory (ORL)
-#
-# Original (Python) Serpent reference development started on 1998 02 12.
-# C implementation development started on 1998 03 04.
-#
-# Serpent cipher invented by Ross Anderson, Eli Biham, Lars Knudsen.
-# Serpent is a candidate for the Advanced Encryption Standard.
-
-# --------------------------------------------------------------
-
-"""This is an illustrative reference implementation of the Serpent cipher
-invented by Eli Biham, Ross Anderson, Lars Knudsen. It is written for the
-human reader more than for the machine and, as such, it is optimised for
-clarity rather than speed. ("Premature optimisation is the root of all
-evil.")
-
-It can print out all the intermediate results (such as the subkeys) for a
-given input and key so that implementers debugging erroneous code can
-quickly verify which one of the building blocks is giving the wrong
-answers.
-
-This version implements Serpent-1, i.e. the variant defined in the final
-submission to NIST.
-"""
-
-# --------------------------------------------------------------
-# My own additions
-# --------------------------------------------------------------
-import binascii
-class Serpent:
- #class to
- def __init__(self,key):
- key = binascii.hexlify(key)
- bitsInKey = keyLengthInBitsOf(key)
- rawKey = convertToBitstring(reverse(key.lower()), bitsInKey)
- self.userKey = makeLongKey(rawKey)
-
- def encrypt(self,block):
- plainText = convertToBitstring(reverse(binascii.hexlify(block).lower()), 128)
- cipherText = encrypt(plainText, self.userKey)
- return binascii.unhexlify(reverse(bitstring2hexstring(cipherText)))
-
- def decrypt(self,block):
- cipherText = convertToBitstring(reverse(binascii.hexlify(block).lower()), 128)
- plainText = decrypt(cipherText, self.userKey)
- return binascii.unhexlify(reverse(bitstring2hexstring(plainText)))
-
- def get_block_size(self):
- return 16
-
-def reverse(toreverse):
- out = b""
- for i in range(len(toreverse)//2):
- out += toreverse[len(toreverse)-i*2-2:len(toreverse)-i*2]
- return out
-# --------------------------------------------------------------
-#
-# --------------------------------------------------------------
-
-# --------------------------------------------------------------
-# Requires python 1.5, freely available from http://www.python.org/
-# --------------------------------------------------------------
-import string
-import sys
-import getopt
-import re
-
-# --------------------------------------------------------------
-# Functions used in the formal description of the cipher
-
-def S(box, input):
- """Apply S-box number 'box' to 4-bit bitstring 'input' and return a
- 4-bit bitstring as the result."""
-
- return SBoxBitstring[box%8][input]
- # There used to be 32 different S-boxes in serpent-0. Now there are
- # only 8, each of which is used 4 times (Sboxes 8, 16, 24 are all
- # identical to Sbox 0, etc). Hence the %8.
-
-def SInverse(box, output):
- """Apply S-box number 'box' in reverse to 4-bit bitstring 'output' and
- return a 4-bit bitstring (the input) as the result."""
-
- return SBoxBitstringInverse[box%8][output]
-
-
-def SHat(box, input):
- """Apply a parallel array of 32 copies of S-box number 'box' to the
- 128-bit bitstring 'input' and return a 128-bit bitstring as the
- result."""
-
- result = ""
- for i in range(32):
- result = result + S(box, input[4*i:4*(i+1)])
- return result
-
-def SHatInverse(box, output):
- """Apply, in reverse, a parallel array of 32 copies of S-box number
- 'box' to the 128-bit bitstring 'output' and return a 128-bit bitstring
- (the input) as the result."""
-
- result = ""
- for i in range(32):
- result = result + SInverse(box, output[4*i:4*(i+1)])
- return result
-
-
-def SBitslice(box, words):
- """Take 'words', a list of 4 32-bit bitstrings, least significant word
- first. Return a similar list of 4 32-bit bitstrings obtained as
- follows. For each bit position from 0 to 31, apply S-box number 'box'
- to the 4 input bits coming from the current position in each of the
- items in 'words'; and put the 4 output bits in the corresponding
- positions in the output words."""
-
- result = ["", "", "", ""]
- for i in range(32): # ideally in parallel
- quad = S(box, words[0][i] + words[1][i] + words[2][i] + words[3][i])
- for j in range(4):
- result[j] = result[j] + quad[j]
- return result
-
-def SBitsliceInverse(box, words):
- """Take 'words', a list of 4 32-bit bitstrings, least significant word
- first. Return a similar list of 4 32-bit bitstrings obtained as
- follows. For each bit position from 0 to 31, apply S-box number 'box'
- in reverse to the 4 output bits coming from the current position in
- each of the items in the supplied 'words'; and put the 4 input bits in
- the corresponding positions in the returned words."""
-
- result = ["", "", "", ""]
- for i in range(32): # ideally in parallel
- quad = SInverse(
- box, words[0][i] + words[1][i] + words[2][i] + words[3][i])
- for j in range(4):
- result[j] = result[j] + quad[j]
- return result
-
-
-def LT(input):
- """Apply the table-based version of the linear transformation to the
- 128-bit string 'input' and return a 128-bit string as the result."""
-
- if len(input) != 128:
- raise ValueError("input to LT is not 128 bit long")
-
- result = ""
- for i in range(len(LTTable)):
- outputBit = "0"
- for j in LTTable[i]:
- outputBit = xor(outputBit, input[j])
- result = result + outputBit
- return result
-
-def LTInverse(output):
- """Apply the table-based version of the inverse of the linear
- transformation to the 128-bit string 'output' and return a 128-bit
- string (the input) as the result."""
-
- if len(output) != 128:
- raise ValueError("input to inverse LT is not 128 bit long")
-
- result = ""
- for i in range(len(LTTableInverse)):
- inputBit = "0"
- for j in LTTableInverse[i]:
- inputBit = xor(inputBit, output[j])
- result = result + inputBit
- return result
-
-
-
-def LTBitslice(X):
- """Apply the equations-based version of the linear transformation to
- 'X', a list of 4 32-bit bitstrings, least significant bitstring first,
- and return another list of 4 32-bit bitstrings as the result."""
-
- X[0] = rotateLeft(X[0], 13)
- X[2] = rotateLeft(X[2], 3)
- X[1] = xor(X[1], X[0], X[2])
- X[3] = xor(X[3], X[2], shiftLeft(X[0], 3))
- X[1] = rotateLeft(X[1], 1)
- X[3] = rotateLeft(X[3], 7)
- X[0] = xor(X[0], X[1], X[3])
- X[2] = xor(X[2], X[3], shiftLeft(X[1], 7))
- X[0] = rotateLeft(X[0], 5)
- X[2] = rotateLeft(X[2], 22)
-
- return X
-
-def LTBitsliceInverse(X):
- """Apply, in reverse, the equations-based version of the linear
- transformation to 'X', a list of 4 32-bit bitstrings, least significant
- bitstring first, and return another list of 4 32-bit bitstrings as the
- result."""
-
- X[2] = rotateRight(X[2], 22)
- X[0] = rotateRight(X[0], 5)
- X[2] = xor(X[2], X[3], shiftLeft(X[1], 7))
- X[0] = xor(X[0], X[1], X[3])
- X[3] = rotateRight(X[3], 7)
- X[1] = rotateRight(X[1], 1)
- X[3] = xor(X[3], X[2], shiftLeft(X[0], 3))
- X[1] = xor(X[1], X[0], X[2])
- X[2] = rotateRight(X[2], 3)
- X[0] = rotateRight(X[0], 13)
-
- return X
-
-
-def IP(input):
- """Apply the Initial Permutation to the 128-bit bitstring 'input'
- and return a 128-bit bitstring as the result."""
-
- return applyPermutation(IPTable, input)
-
-def FP(input):
- """Apply the Final Permutation to the 128-bit bitstring 'input'
- and return a 128-bit bitstring as the result."""
-
- return applyPermutation(FPTable, input)
-
-
-def IPInverse(output):
- """Apply the Initial Permutation in reverse."""
-
- return FP(output)
-
-def FPInverse(output):
- """Apply the Final Permutation in reverse."""
-
- return IP(output)
-
-
-def applyPermutation(permutationTable, input):
- """Apply the permutation specified by the 128-element list
- 'permutationTable' to the 128-bit bitstring 'input' and return a
- 128-bit bitstring as the result."""
-
- if len(input) != len(permutationTable):
- raise ValueError("input size (%d) doesn't match perm table size (%d)"\
- % (len(input), len(permutationTable)))
-
- result = ""
- for i in range(len(permutationTable)):
- result = result + input[permutationTable[i]]
- return result
-
-
-def R(i, BHati, KHat):
- """Apply round 'i' to the 128-bit bitstring 'BHati', returning another
- 128-bit bitstring (conceptually BHatiPlus1). Do this using the
- appropriately numbered subkey(s) from the 'KHat' list of 33 128-bit
- bitstrings."""
-
- #O.show("BHati", BHati, "(i=%2d) BHati" % i)
-
- xored = xor(BHati, KHat[i])
- #O.show("xored", xored, "(i=%2d) xored" % i)
-
- SHati = SHat(i, xored)
- #O.show("SHati", SHati, "(i=%2d) SHati" % i)
-
- if 0 <= i <= r-2:
- BHatiPlus1 = LT(SHati)
- elif i == r-1:
- BHatiPlus1 = xor(SHati, KHat[r])
- else:
- raise ValueError("round %d is out of 0..%d range" % (i, r-1))
- #O.show("BHatiPlus1", BHatiPlus1, "(i=%2d) BHatiPlus1" % i)
-
- return BHatiPlus1
-
-
-def RInverse(i, BHatiPlus1, KHat):
- """Apply round 'i' in reverse to the 128-bit bitstring 'BHatiPlus1',
- returning another 128-bit bitstring (conceptually BHati). Do this using
- the appropriately numbered subkey(s) from the 'KHat' list of 33 128-bit
- bitstrings."""
-
- #O.show("BHatiPlus1", BHatiPlus1, "(i=%2d) BHatiPlus1" % i)
-
- if 0 <= i <= r-2:
- SHati = LTInverse(BHatiPlus1)
- elif i == r-1:
- SHati = xor(BHatiPlus1, KHat[r])
- else:
- raise ValueError("round %d is out of 0..%d range" % (i, r-1))
- #O.show("SHati", SHati, "(i=%2d) SHati" % i)
-
- xored = SHatInverse(i, SHati)
- #O.show("xored", xored, "(i=%2d) xored" % i)
-
- BHati = xor(xored, KHat[i])
- #O.show("BHati", BHati, "(i=%2d) BHati" % i)
-
- return BHati
-
-
-def RBitslice(i, Bi, K):
- """Apply round 'i' (bitslice version) to the 128-bit bitstring 'Bi' and
- return another 128-bit bitstring (conceptually B i+1). Use the
- appropriately numbered subkey(s) from the 'K' list of 33 128-bit
- bitstrings."""
-
- #O.show("Bi", Bi, "(i=%2d) Bi" % i)
-
- # 1. Key mixing
- xored = xor (Bi, K[i])
- #O.show("xored", xored, "(i=%2d) xored" % i)
-
- # 2. S Boxes
- Si = SBitslice(i, quadSplit(xored))
- # Input and output to SBitslice are both lists of 4 32-bit bitstrings
- #O.show("Si", Si, "(i=%2d) Si" % i, "tlb")
-
-
- # 3. Linear Transformation
- if i == r-1:
- # In the last round, replaced by an additional key mixing
- BiPlus1 = xor(quadJoin(Si), K[r])
- else:
- BiPlus1 = quadJoin(LTBitslice(Si))
- # BIPlus1 is a 128-bit bitstring
- #O.show("BiPlus1", BiPlus1, "(i=%2d) BiPlus1" % i)
-
- return BiPlus1
-
-
-def RBitsliceInverse(i, BiPlus1, K):
- """Apply the inverse of round 'i' (bitslice version) to the 128-bit
- bitstring 'BiPlus1' and return another 128-bit bitstring (conceptually
- B i). Use the appropriately numbered subkey(s) from the 'K' list of 33
- 128-bit bitstrings."""
-
- #O.show("BiPlus1", BiPlus1, "(i=%2d) BiPlus1" % i)
-
- # 3. Linear Transformation
- if i == r-1:
- # In the last round, replaced by an additional key mixing
- Si = quadSplit(xor(BiPlus1, K[r]))
- else:
- Si = LTBitsliceInverse(quadSplit(BiPlus1))
- # SOutput (same as LTInput) is a list of 4 32-bit bitstrings
-
- #O.show("Si", Si, "(i=%2d) Si" % i, "tlb")
-
- # 2. S Boxes
- xored = SBitsliceInverse(i, Si)
- # SInput and SOutput are both lists of 4 32-bit bitstrings
-
- #O.show("xored", xored, "(i=%2d) xored" % i)
-
- # 1. Key mixing
- Bi = xor (quadJoin(xored), K[i])
-
- #O.show("Bi", Bi, "(i=%2d) Bi" % i)
-
- return Bi
-
-
-
-def encrypt(plainText, userKey):
- """Encrypt the 128-bit bitstring 'plainText' with the 256-bit bitstring
- 'userKey', using the normal algorithm, and return a 128-bit ciphertext
- bitstring."""
-
- #O.show("fnTitle", "encrypt", None, "tu")
- #O.show("plainText", plainText, "plainText")
- #O.show("userKey", userKey, "userKey")
-
- K, KHat = makeSubkeys(userKey)
-
- BHat = IP(plainText) # BHat_0 at this stage
- for i in range(r):
- BHat = R(i, BHat, KHat) # Produce BHat_i+1 from BHat_i
- # BHat is now _32 i.e. _r
- C = FP(BHat)
-
- #O.show("cipherText", C, "cipherText")
-
- return C
-
-
-def encryptBitslice(plainText, userKey):
- """Encrypt the 128-bit bitstring 'plainText' with the 256-bit bitstring
- 'userKey', using the bitslice algorithm, and return a 128-bit ciphertext
- bitstring."""
-
- #O.show("fnTitle", "encryptBitslice", None, "tu")
- #O.show("plainText", plainText, "plainText")
- #O.show("userKey", userKey, "userKey")
-
- K, KHat = makeSubkeys(userKey)
-
- B = plainText # B_0 at this stage
- for i in range(r):
- B = RBitslice(i, B, K) # Produce B_i+1 from B_i
- # B is now _r
-
- #O.show("cipherText", B, "cipherText")
-
- return B
-
-def decrypt(cipherText, userKey):
- """Decrypt the 128-bit bitstring 'cipherText' with the 256-bit
- bitstring 'userKey', using the normal algorithm, and return a 128-bit
- plaintext bitstring."""
-
- #O.show("fnTitle", "decrypt", None, "tu")
- #O.show("cipherText", cipherText, "cipherText")
- #O.show("userKey", userKey, "userKey")
-
- K, KHat = makeSubkeys(userKey)
-
- BHat = FPInverse(cipherText) # BHat_r at this stage
- for i in range(r-1, -1, -1): # from r-1 down to 0 included
- BHat = RInverse(i, BHat, KHat) # Produce BHat_i from BHat_i+1
- # BHat is now _0
- plainText = IPInverse(BHat)
-
- #O.show("plainText", plainText, "plainText")
- return plainText
-
-
-def decryptBitslice(cipherText, userKey):
- """Decrypt the 128-bit bitstring 'cipherText' with the 256-bit
- bitstring 'userKey', using the bitslice algorithm, and return a 128-bit
- plaintext bitstring."""
-
- #O.show("fnTitle", "decryptBitslice", None, "tu")
- #O.show("cipherText", cipherText, "cipherText")
- #O.show("userKey", userKey, "userKey")
-
- K, KHat = makeSubkeys(userKey)
-
- B = cipherText # B_r at this stage
- for i in range(r-1, -1, -1): # from r-1 down to 0 included
- B = RBitsliceInverse(i, B, K) # Produce B_i from B_i+1
- # B is now _0
-
- #O.show("plainText", B, "plainText")
- return B
-
-
-def makeSubkeys(userKey):
- """Given the 256-bit bitstring 'userKey' (shown as K in the paper, but
- we can't use that name because of a collision with K[i] used later for
- something else), return two lists (conceptually K and KHat) of 33
- 128-bit bitstrings each."""
-
- # Because in Python I can't index a list from anything other than 0,
- # I use a dictionary instead to legibly represent the w_i that are
- # indexed from -8.
-
- # We write the key as 8 32-bit words w-8 ... w-1
- # ENOTE: w-8 is the least significant word
- w = {}
- for i in range(-8, 0):
- w[i] = userKey[(i+8)*32:(i+9)*32]
- #O.show("wi", w[i], "(i=%2d) wi" % i)
-
- # We expand these to a prekey w0 ... w131 with the affine recurrence
- for i in range(132):
- w[i] = rotateLeft(
- xor(w[i-8], w[i-5], w[i-3], w[i-1],
- bitstring(phi, 32), bitstring(i,32)),
- 11)
- #O.show("wi", w[i], "(i=%2d) wi" % i)
-
- # The round keys are now calculated from the prekeys using the S-boxes
- # in bitslice mode. Each k[i] is a 32-bit bitstring.
- k = {}
- for i in range(r+1):
- whichS = (r + 3 - i) % r
- k[0+4*i] = ""
- k[1+4*i] = ""
- k[2+4*i] = ""
- k[3+4*i] = ""
- for j in range(32): # for every bit in the k and w words
- # ENOTE: w0 and k0 are the least significant words, w99 and k99
- # the most.
- input = w[0+4*i][j] + w[1+4*i][j] + w[2+4*i][j] + w[3+4*i][j]
- output = S(whichS, input)
- for l in range(4):
- k[l+4*i] = k[l+4*i] + output[l]
-
- # We then renumber the 32 bit values k_j as 128 bit subkeys K_i.
- K = []
- for i in range(33):
- # ENOTE: k4i is the least significant word, k4i+3 the most.
- K.append(k[4*i] + k[4*i+1] + k[4*i+2] + k[4*i+3])
-
- # We now apply IP to the round key in order to place the key bits in
- # the correct column
- KHat = []
- for i in range(33):
- KHat.append(IP(K[i]))
-
- #O.show("Ki", K[i], "(i=%2d) Ki" % i)
- #O.show("KHati", KHat[i], "(i=%2d) KHati" % i)
-
- return K, KHat
-
-
-def makeLongKey(k):
- """Take a key k in bitstring format. Return the long version of that
- key."""
-
- l = len(k)
- if l % 32 != 0 or l < 64 or l > 256:
- raise ValueError("Invalid key length (%d bits)" % l)
-
- if l == 256:
- return k
- else:
- return k + "1" + "0"*(256 -l -1)
-
-# --------------------------------------------------------------
-# Generic bit-level primitives
-
-# Internally, we represent the numbers manipulated by the cipher in a
-# format that we call 'bitstring'. This is a string of "0" and "1"
-# characters containing the binary representation of the number in
-# little-endian format (so that subscripting with an index of i gives bit
-# number i, corresponding to a weight of 2^i). This representation is only
-# defined for nonnegative numbers (you can see why: think of the great
-# unnecessary mess that would result from sign extension, two's complement
-# and so on). Example: 10 decimal is "0101" in bitstring format.
-
-def bitstring(n, minlen=1):
- """Translate n from integer to bitstring, padding it with 0s as
- necessary to reach the minimum length 'minlen'. 'n' must be >= 0 since
- the bitstring format is undefined for negative integers. Note that,
- while the bitstring format can represent arbitrarily large numbers,
- this is not so for Python's normal integer type: on a 32-bit machine,
- values of n >= 2^31 need to be expressed as python long integers or
- they will "look" negative and won't work. E.g. 0x80000000 needs to be
- passed in as 0x80000000, or it will be taken as -2147483648 instead of
- +2147483648.
-
- EXAMPLE: bitstring(10, 8) -> "01010000"
- """
-
- if minlen < 1:
- raise ValueError("a bitstring must have at least 1 char")
- if n < 0:
- raise ValueError("bitstring representation undefined for neg numbers")
-
- result = ""
- while n > 0:
- if n & 1:
- result = result + "1"
- else:
- result = result + "0"
- n = n >> 1
- if len(result) < minlen:
- result = result + "0" * (minlen - len(result))
- return result
-
-
-def binaryXor(n1, n2):
- """Return the xor of two bitstrings of equal length as another
- bitstring of the same length.
-
- EXAMPLE: binaryXor("10010", "00011") -> "10001"
- """
-
- if len(n1) != len(n2):
- raise ValueError("can't xor bitstrings of different " + \
- "lengths (%d and %d)" % (len(n1), len(n2)))
- # We assume that they are genuine bitstrings instead of just random
- # character strings.
-
- result = ""
- for i in range(len(n1)):
- if n1[i] == n2[i]:
- result = result + "0"
- else:
- result = result + "1"
- return result
-
-
-def xor(*args):
- """Return the xor of an arbitrary number of bitstrings of the same
- length as another bitstring of the same length.
-
- EXAMPLE: xor("01", "11", "10") -> "00"
- """
-
- if args == []:
- raise ValueError("at least one argument needed")
-
- result = args[0]
- for arg in args[1:]:
- result = binaryXor(result, arg)
- return result
-
-
-def rotateLeft(input, places):
- """Take a bitstring 'input' of arbitrary length. Rotate it left by
- 'places' places. Left means that the 'places' most significant bits are
- taken out and reinserted as the least significant bits. Note that,
- because the bitstring representation is little-endian, the visual
- effect is actually that of rotating the string to the right.
-
- EXAMPLE: rotateLeft("000111", 2) -> "110001"
- """
-
- p = places % len(input)
- return input[-p:] + input[:-p]
-
-def rotateRight(input, places):
- return rotateLeft(input, -places)
-
-def shiftLeft(input, p):
- """Take a bitstring 'input' of arbitrary length. Shift it left by 'p'
- places. Left means that the 'p' most significant bits are shifted out
- and dropped, while 'p' 0s are inserted in the the least significant
- bits. Note that, because the bitstring representation is little-endian,
- the visual effect is actually that of shifting the string to the
- right. Negative values for 'p' are allowed, with the effect of shifting
- right instead (i.e. the 0s are inserted in the most significant bits).
-
- EXAMPLE: shiftLeft("000111", 2) -> "000001"
- shiftLeft("000111", -2) -> "011100"
- """
-
- if abs(p) >= len(input):
- # Everything gets shifted out anyway
- return "0" * len(input)
- if p < 0:
- # Shift right instead
- return input[-p:] + "0" * len(input[:-p])
- elif p == 0:
- return input
- else: # p > 0, normal case
- return "0" * len(input[-p:]) + input[:-p]
-
-def shiftRight(input, p):
- """Take a bitstring 'input' and shift it right by 'p' places. See the
- doc for shiftLeft for more details."""
-
- return shiftLeft(input, -p)
-
-
-def keyLengthInBitsOf(k):
- """Take a string k in I/O format and return the number of bits in it."""
-
- return len(k) * 4
-
-# --------------------------------------------------------------
-# Hex conversion functions
-
-# For I/O we use BIG-ENDIAN hexstrings. Do not get confused: internal stuff
-# is LITTLE-ENDIAN bitstrings (so that digit i has weight 2^i) while
-# external stuff is in BIG-ENDIAN hexstrings (so that it's shorter and it
-# looks like the numbers you normally write down). The external (I/O)
-# representation is the same as used by the C reference implementation.
-
-bin2hex = {
- # Given a 4-char bitstring, return the corresponding 1-char hexstring
- "0000": b"0", "1000": b"1", "0100": b"2", "1100": b"3",
- "0010": b"4", "1010": b"5", "0110": b"6", "1110": b"7",
- "0001": b"8", "1001": b"9", "0101": b"a", "1101": b"b",
- "0011": b"c", "1011": b"d", "0111": b"e", "1111": b"f",
- }
-
-# Make the reverse lookup table too
-hex2bin = {}
-for (bin, hex) in bin2hex.items():
- hex2bin[hex] = bin
-
-
-def bitstring2hexstring(b):
- """Take bitstring 'b' and return the corresponding hexstring."""
-
- result = b""
- l = len(b)
- if l % 4:
- b = b + "0" * (4-(l%4))
- for i in range(0, len(b), 4):
- result = result+bin2hex[b[i:i+4]]
- return reverseString(result)
-
-def hexstring2bitstring(h):
- """Take hexstring 'h' and return the corresponding bitstring."""
-
- result = ""
- for c in bytearray(reverseString(h)):
- result = result + hex2bin[bytes(bytearray([c]))]
- return result
-
-def reverseString(s):
- l = bytearray(s)
- l.reverse()
- return bytes(l)
-
-
-
-
-# --------------------------------------------------------------
-# Format conversions
-
-def quadSplit(b128):
- """Take a 128-bit bitstring and return it as a list of 4 32-bit
- bitstrings, least significant bitstring first."""
-
- if len(b128) != 128:
- raise ValueError("must be 128 bits long, not " + len(b128))
-
- result = []
- for i in range(4):
- result.append(b128[(i*32):(i+1)*32])
- return result
-
-
-def quadJoin(l4x32):
- """Take a list of 4 32-bit bitstrings and return it as a single 128-bit
- bitstring obtained by concatenating the internal ones."""
-
- if len(l4x32) != 4:
- raise ValueError("need a list of 4 bitstrings, not " + len(l4x32))
-
- return l4x32[0] + l4x32[1] + l4x32[2] + l4x32[3]
-
-# --------------------------------------------------
-# Seeing what happens inside
-
-class Observer:
- """An object of this class can selectively display the values of the
- variables you want to observe while the program is running. There are
- tags that you can switch on or off. You sprinkle show() statements
- throughout the program to show the value of a variable at a particular
- point: show() will display the relevant variable only if the
- corresponding tag is currently on. The special tag "ALL" forces all
- show() statements to display their variable."""
-
- typesOfVariable = {
- "tu": "unknown", "tb": "bitstring", "tlb": "list of bitstrings",}
-
- def __init__(self, tags=[]):
- self.tags = {}
- for tag in tags:
- self.tags[tag] = 1
-
-
- def addTag(self, *tags):
- """Add the supplied tag(s) to those that are currently active,
- i.e. those that, if a corresponding "show()" is executed, will
- print something."""
-
- for t in tags:
- self.tags[t] = 1
-
- def removeTag(self, *tags):
- """Remove the supplied tag(s) from those currently active."""
- for t in tags:
- if t in self.tags.keys():
- del self.tags[t]
-
- def show(self, tag, variable, label=None, type="tb"):
- """Conditionally print a message with the current value of
- 'variable'. The message will only be printed if the supplied 'tag'
- is among the active ones (or if the 'ALL' tag is active). The
- 'label', if not null, is printed before the value of the
- 'variable'; if it is null, it is substituted with the 'tag'. The
- 'type' of the 'variable' (giving us a clue on how to print it) must
- be one of Observer.typesOfVariable."""
-
- if label == None:
- label = tag
- if "ALL" in self.tags.keys() or tag in self.tags.keys():
- if type == "tu":
- output = repr(variable)
- elif type == "tb":
- output = bitstring2hexstring(variable)
- elif type == "tlb":
- output = ""
- for item in variable:
- output = output + " %s" % bitstring2hexstring(item)
- output = "[" + output[1:] + "]"
- else:
- raise ValueError("unknown type: %s. Valid ones are %s" % (
- type, self.typesOfVariable.keys()))
-
- if output:
- print(label, "=", output)
- else:
- print(label)
-
-
-# We make one global observer object that is always available
-O = Observer(["plainText", "userKey", "cipherText"])
-
-# --------------------------------------------------------------
-# Constants
-phi = 0x9e3779b9
-r = 32
-# --------------------------------------------------------------
-# Data tables
-
-
-# Each element of this list corresponds to one S-box. Each S-box in turn is
-# a list of 16 integers in the range 0..15, without repetitions. Having the
-# value v (say, 14) in position p (say, 0) means that if the input to that
-# S-box is the pattern p (0, or 0x0) then the output will be the pattern v
-# (14, or 0xe).
-SBoxDecimalTable = [
- [ 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12 ], # S0
- [15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4 ], # S1
- [ 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2 ], # S2
- [ 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14 ], # S3
- [ 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13 ], # S4
- [15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1 ], # S5
- [ 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0 ], # S6
- [ 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6 ], # S7
- ]
-# NB: in serpent-0, this was a list of 32 sublists (for the 32 different
-# S-boxes derived from DES). In the final version of Serpent only 8 S-boxes
-# are used, with each one being reused 4 times.
-
-
-# Make another version of this table as a list of dictionaries: one
-# dictionary per S-box, where the value of the entry indexed by i tells you
-# the output configuration when the input is i, with both the index and the
-# value being bitstrings. Make also the inverse: another list of
-# dictionaries, one per S-box, where each dictionary gets the output of the
-# S-box as the key and gives you the input, with both values being 4-bit
-# bitstrings.
-SBoxBitstring = []
-SBoxBitstringInverse = []
-for line in SBoxDecimalTable:
- dict = {}
- inverseDict = {}
- for i in range(len(line)):
- index = bitstring(i, 4)
- value = bitstring(line[i], 4)
- dict[index] = value
- inverseDict[value] = index
- SBoxBitstring.append(dict)
- SBoxBitstringInverse.append(inverseDict)
-
-
-# The Initial and Final permutations are each represented by one list
-# containing the integers in 0..127 without repetitions. Having value v
-# (say, 32) at position p (say, 1) means that the output bit at position p
-# (1) comes from the input bit at position v (32).
-IPTable = [
- 0, 32, 64, 96, 1, 33, 65, 97, 2, 34, 66, 98, 3, 35, 67, 99,
- 4, 36, 68, 100, 5, 37, 69, 101, 6, 38, 70, 102, 7, 39, 71, 103,
- 8, 40, 72, 104, 9, 41, 73, 105, 10, 42, 74, 106, 11, 43, 75, 107,
- 12, 44, 76, 108, 13, 45, 77, 109, 14, 46, 78, 110, 15, 47, 79, 111,
- 16, 48, 80, 112, 17, 49, 81, 113, 18, 50, 82, 114, 19, 51, 83, 115,
- 20, 52, 84, 116, 21, 53, 85, 117, 22, 54, 86, 118, 23, 55, 87, 119,
- 24, 56, 88, 120, 25, 57, 89, 121, 26, 58, 90, 122, 27, 59, 91, 123,
- 28, 60, 92, 124, 29, 61, 93, 125, 30, 62, 94, 126, 31, 63, 95, 127,
- ]
-FPTable = [
- 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
- 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
- 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61,
- 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125,
- 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62,
- 66, 70, 74, 78, 82, 86, 90, 94, 98, 102, 106, 110, 114, 118, 122, 126,
- 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63,
- 67, 71, 75, 79, 83, 87, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127,
- ]
-
-
-# The Linear Transformation is represented as a list of 128 lists, one for
-# each output bit. Each one of the 128 lists is composed of a variable
-# number of integers in 0..127 specifying the positions of the input bits
-# that must be XORed together (say, 72, 144 and 125) to yield the output
-# bit corresponding to the position of that list (say, 1).
-LTTable = [
- [16, 52, 56, 70, 83, 94, 105],
- [72, 114, 125],
- [2, 9, 15, 30, 76, 84, 126],
- [36, 90, 103],
- [20, 56, 60, 74, 87, 98, 109],
- [1, 76, 118],
- [2, 6, 13, 19, 34, 80, 88],
- [40, 94, 107],
- [24, 60, 64, 78, 91, 102, 113],
- [5, 80, 122],
- [6, 10, 17, 23, 38, 84, 92],
- [44, 98, 111],
- [28, 64, 68, 82, 95, 106, 117],
- [9, 84, 126],
- [10, 14, 21, 27, 42, 88, 96],
- [48, 102, 115],
- [32, 68, 72, 86, 99, 110, 121],
- [2, 13, 88],
- [14, 18, 25, 31, 46, 92, 100],
- [52, 106, 119],
- [36, 72, 76, 90, 103, 114, 125],
- [6, 17, 92],
- [18, 22, 29, 35, 50, 96, 104],
- [56, 110, 123],
- [1, 40, 76, 80, 94, 107, 118],
- [10, 21, 96],
- [22, 26, 33, 39, 54, 100, 108],
- [60, 114, 127],
- [5, 44, 80, 84, 98, 111, 122],
- [14, 25, 100],
- [26, 30, 37, 43, 58, 104, 112],
- [3, 118],
- [9, 48, 84, 88, 102, 115, 126],
- [18, 29, 104],
- [30, 34, 41, 47, 62, 108, 116],
- [7, 122],
- [2, 13, 52, 88, 92, 106, 119],
- [22, 33, 108],
- [34, 38, 45, 51, 66, 112, 120],
- [11, 126],
- [6, 17, 56, 92, 96, 110, 123],
- [26, 37, 112],
- [38, 42, 49, 55, 70, 116, 124],
- [2, 15, 76],
- [10, 21, 60, 96, 100, 114, 127],
- [30, 41, 116],
- [0, 42, 46, 53, 59, 74, 120],
- [6, 19, 80],
- [3, 14, 25, 100, 104, 118],
- [34, 45, 120],
- [4, 46, 50, 57, 63, 78, 124],
- [10, 23, 84],
- [7, 18, 29, 104, 108, 122],
- [38, 49, 124],
- [0, 8, 50, 54, 61, 67, 82],
- [14, 27, 88],
- [11, 22, 33, 108, 112, 126],
- [0, 42, 53],
- [4, 12, 54, 58, 65, 71, 86],
- [18, 31, 92],
- [2, 15, 26, 37, 76, 112, 116],
- [4, 46, 57],
- [8, 16, 58, 62, 69, 75, 90],
- [22, 35, 96],
- [6, 19, 30, 41, 80, 116, 120],
- [8, 50, 61],
- [12, 20, 62, 66, 73, 79, 94],
- [26, 39, 100],
- [10, 23, 34, 45, 84, 120, 124],
- [12, 54, 65],
- [16, 24, 66, 70, 77, 83, 98],
- [30, 43, 104],
- [0, 14, 27, 38, 49, 88, 124],
- [16, 58, 69],
- [20, 28, 70, 74, 81, 87, 102],
- [34, 47, 108],
- [0, 4, 18, 31, 42, 53, 92],
- [20, 62, 73],
- [24, 32, 74, 78, 85, 91, 106],
- [38, 51, 112],
- [4, 8, 22, 35, 46, 57, 96],
- [24, 66, 77],
- [28, 36, 78, 82, 89, 95, 110],
- [42, 55, 116],
- [8, 12, 26, 39, 50, 61, 100],
- [28, 70, 81],
- [32, 40, 82, 86, 93, 99, 114],
- [46, 59, 120],
- [12, 16, 30, 43, 54, 65, 104],
- [32, 74, 85],
- [36, 90, 103, 118],
- [50, 63, 124],
- [16, 20, 34, 47, 58, 69, 108],
- [36, 78, 89],
- [40, 94, 107, 122],
- [0, 54, 67],
- [20, 24, 38, 51, 62, 73, 112],
- [40, 82, 93],
- [44, 98, 111, 126],
- [4, 58, 71],
- [24, 28, 42, 55, 66, 77, 116],
- [44, 86, 97],
- [2, 48, 102, 115],
- [8, 62, 75],
- [28, 32, 46, 59, 70, 81, 120],
- [48, 90, 101],
- [6, 52, 106, 119],
- [12, 66, 79],
- [32, 36, 50, 63, 74, 85, 124],
- [52, 94, 105],
- [10, 56, 110, 123],
- [16, 70, 83],
- [0, 36, 40, 54, 67, 78, 89],
- [56, 98, 109],
- [14, 60, 114, 127],
- [20, 74, 87],
- [4, 40, 44, 58, 71, 82, 93],
- [60, 102, 113],
- [3, 18, 72, 114, 118, 125],
- [24, 78, 91],
- [8, 44, 48, 62, 75, 86, 97],
- [64, 106, 117],
- [1, 7, 22, 76, 118, 122],
- [28, 82, 95],
- [12, 48, 52, 66, 79, 90, 101],
- [68, 110, 121],
- [5, 11, 26, 80, 122, 126],
- [32, 86, 99],
- ]
-
-# The following table is necessary for the non-bitslice decryption.
-LTTableInverse = [
- [53, 55, 72],
- [1, 5, 20, 90],
- [15, 102],
- [3, 31, 90],
- [57, 59, 76],
- [5, 9, 24, 94],
- [19, 106],
- [7, 35, 94],
- [61, 63, 80],
- [9, 13, 28, 98],
- [23, 110],
- [11, 39, 98],
- [65, 67, 84],
- [13, 17, 32, 102],
- [27, 114],
- [1, 3, 15, 20, 43, 102],
- [69, 71, 88],
- [17, 21, 36, 106],
- [1, 31, 118],
- [5, 7, 19, 24, 47, 106],
- [73, 75, 92],
- [21, 25, 40, 110],
- [5, 35, 122],
- [9, 11, 23, 28, 51, 110],
- [77, 79, 96],
- [25, 29, 44, 114],
- [9, 39, 126],
- [13, 15, 27, 32, 55, 114],
- [81, 83, 100],
- [1, 29, 33, 48, 118],
- [2, 13, 43],
- [1, 17, 19, 31, 36, 59, 118],
- [85, 87, 104],
- [5, 33, 37, 52, 122],
- [6, 17, 47],
- [5, 21, 23, 35, 40, 63, 122],
- [89, 91, 108],
- [9, 37, 41, 56, 126],
- [10, 21, 51],
- [9, 25, 27, 39, 44, 67, 126],
- [93, 95, 112],
- [2, 13, 41, 45, 60],
- [14, 25, 55],
- [2, 13, 29, 31, 43, 48, 71],
- [97, 99, 116],
- [6, 17, 45, 49, 64],
- [18, 29, 59],
- [6, 17, 33, 35, 47, 52, 75],
- [101, 103, 120],
- [10, 21, 49, 53, 68],
- [22, 33, 63],
- [10, 21, 37, 39, 51, 56, 79],
- [105, 107, 124],
- [14, 25, 53, 57, 72],
- [26, 37, 67],
- [14, 25, 41, 43, 55, 60, 83],
- [0, 109, 111],
- [18, 29, 57, 61, 76],
- [30, 41, 71],
- [18, 29, 45, 47, 59, 64, 87],
- [4, 113, 115],
- [22, 33, 61, 65, 80],
- [34, 45, 75],
- [22, 33, 49, 51, 63, 68, 91],
- [8, 117, 119],
- [26, 37, 65, 69, 84],
- [38, 49, 79],
- [26, 37, 53, 55, 67, 72, 95],
- [12, 121, 123],
- [30, 41, 69, 73, 88],
- [42, 53, 83],
- [30, 41, 57, 59, 71, 76, 99],
- [16, 125, 127],
- [34, 45, 73, 77, 92],
- [46, 57, 87],
- [34, 45, 61, 63, 75, 80, 103],
- [1, 3, 20],
- [38, 49, 77, 81, 96],
- [50, 61, 91],
- [38, 49, 65, 67, 79, 84, 107],
- [5, 7, 24],
- [42, 53, 81, 85, 100],
- [54, 65, 95],
- [42, 53, 69, 71, 83, 88, 111],
- [9, 11, 28],
- [46, 57, 85, 89, 104],
- [58, 69, 99],
- [46, 57, 73, 75, 87, 92, 115],
- [13, 15, 32],
- [50, 61, 89, 93, 108],
- [62, 73, 103],
- [50, 61, 77, 79, 91, 96, 119],
- [17, 19, 36],
- [54, 65, 93, 97, 112],
- [66, 77, 107],
- [54, 65, 81, 83, 95, 100, 123],
- [21, 23, 40],
- [58, 69, 97, 101, 116],
- [70, 81, 111],
- [58, 69, 85, 87, 99, 104, 127],
- [25, 27, 44],
- [62, 73, 101, 105, 120],
- [74, 85, 115],
- [3, 62, 73, 89, 91, 103, 108],
- [29, 31, 48],
- [66, 77, 105, 109, 124],
- [78, 89, 119],
- [7, 66, 77, 93, 95, 107, 112],
- [33, 35, 52],
- [0, 70, 81, 109, 113],
- [82, 93, 123],
- [11, 70, 81, 97, 99, 111, 116],
- [37, 39, 56],
- [4, 74, 85, 113, 117],
- [86, 97, 127],
- [15, 74, 85, 101, 103, 115, 120],
- [41, 43, 60],
- [8, 78, 89, 117, 121],
- [3, 90],
- [19, 78, 89, 105, 107, 119, 124],
- [45, 47, 64],
- [12, 82, 93, 121, 125],
- [7, 94],
- [0, 23, 82, 93, 109, 111, 123],
- [49, 51, 68],
- [1, 16, 86, 97, 125],
- [11, 98],
- [4, 27, 86, 97, 113, 115, 127],
-]
-
-
-# --------------------------------------------------
-# Handling command line arguments and stuff
-
-help = """
- # $Id: serpref.py,v 1.19 1998/09/02 21:28:02 fms Exp $
- #
- # Python reference implementation of Serpent.
- #
- # Written by Frank Stajano,
- # Olivetti Oracle Research Laboratory and
- # Cambridge University Computer Laboratory .
- #
- # (c) 1998 Olivetti Oracle Research Laboratory (ORL)
- #
- # Original (Python) Serpent reference development started on 1998 02 12.
- # C implementation development started on 1998 03 04.
- #
- # Serpent cipher invented by Ross Anderson, Eli Biham, Lars Knudsen.
- # Serpent is a candidate for the Advanced Encryption Standard.
-
- Encrypts or decrypts one block of data using the Serpent cipher and
- optionally showing you what's going on inside at the various stages of
- the computation.
-
- SYNTAX: serpref mode [options]
-
- MODE is one of the following:
- -e -> encrypt
- -d -> decrypt
- -h -> help (the text you're reading right now)
-
- OPTIONS are:
- -p plainText -> The 128-bit value to be encrypted. Required in mode -e,
- ignored otherwise. Short texts are zeropadded.
- -c cipherText -> The 128-bit value to be decrypted. Required in mode -d,
- ignored otherwise. Short texts are zeropadded.
- -k key -> The value of the key (allowed lengths are from 64 to
- 256 bits, but must be a multiple of 32 bits). Keys
- shorter than 256 bits are internally transformed into
- the equivalent long keys (NOT the same as zeropadding!).
- Required for -e and -d.
- -t tagName -> Turn on the observer tag with that name. This means that
- any observer messages associated with this tag will
- now be displayed. This option may be specified several
- times to add multiple tags.
- The special tag ALL turns on all the messages.
-
- -b -> Use the bitslice version instead of the traditional
- version, which is otherwise used by default. Optional.
-
- TAGS:
- These are the tags of the quantities you can currently observe with
- -t. Names are modelled on the paper's notation.
-
- For the non-bitslice: BHati xored SHati BHatiPlus1 wi KHati
- For the bitslice: Bi xored Si BiPlus1 wi Ki
- Generic: plainText userKey cipherText testTitle fnTitle
-
-
- I/O FORMAT:
- All I/O is performed using hex numbers of the appropriate size, written
- as sequences of hex digits, most significant digit first (big-endian),
- without any leading or trailing markers such as 0x, &, h or whatever.
- Example: the number ten is "a" in four bits or "000a" in sixteen bits.
-
-
- USAGE EXAMPLES:
-
- serpref -e -k 123456789abcdef -p 0
- Encrypt the plaintext "all zeros" with the given key.
-
- serpref -e -b -k 123456789abcdef -p 0
- Same as above, but the extra -b requests bitslice operation. As
- things are, we won't notice the difference, but see below...
-
- serpref -e -b -k 123456789abcdef -p 0 -t Bi
- Same as above, but the "-t Bi" prints out all the intermediate
- results with a tag of Bi, allowing you to see what happens inside
- the rounds. Compare this with the following...
-
- serpref -e -k 123456789abcdef -p 0 -t BHati
- Same as above except that we are back to the non-bitslice version
- (there is no -b) and we are printing the items with the BHati tag
- (which is the equivalent of Bi for the non-bitslice version).
-
- serpref -e -k 123456789abcdef -p 0 -t xored -t SHati -t BHati
- Same as above but we are requesting even more details, basically
- looking at all the intermediate results of each round as well. (You
- could use the single magic tag -t ALL if you didn't want to have to
- find out the names of the individual tags.)
-"""
-
-
-def helpExit(message = None):
- print(help)
- if message:
- print("ERROR:", message)
- sys.exit()
-
-def convertToBitstring(input, numBits):
- """Take a string 'input', theoretically in std I/O format, but in
- practice liable to contain any sort of crap since it's user supplied,
- and return its bitstring representation, normalised to numBits
- bits. Raise the appropriate variant of ValueError (with explanatory
- message) if anything can't be done (this includes the case where the
- 'input', while otherwise syntactically correct, can't be represented in
- 'numBits' bits)."""
-
- if re.match(b"^[0-9a-f]+$", input):
- bitstring = hexstring2bitstring(input)
- else:
- raise ValueError("%s is not a valid hexstring" % input)
-
- # assert: bitstring now contains the bitstring version of the input
-
- if len(bitstring) > numBits:
- # Last chance: maybe it's got some useless 0s...
- if re.match("^0+$", bitstring[numBits:]):
- bitstring = bitstring[:numBits]
- else:
- raise ValueError("input too large to fit in %d bits" % numBits)
- else:
- bitstring = bitstring + "0" * (numBits-len(bitstring))
-
- return bitstring
-
-
-def main():
-
- optList, rest = getopt.getopt(sys.argv[1:], "edhbt:k:p:c:")
-
- if rest:
- helpExit("Sorry, can't make sense of this: '%s'" % rest)
-
- # Transform the list of options into a more comfortable
- # dictionary. This only works with non-repeated options, though, so
- # tags (which are repeated) must be dealt with separately.
- options = {}
- for key, value in optList:
- if key == "-t":
- O.addTag(value)
- else:
- if key in options.keys():
- helpExit("Multiple occurrences of " + key)
- else:
- options[string.strip(key)] = string.strip(value)
-
- # Not more than one mode
- mode = None
- for k in options.keys():
- if k in ["-e", "-d", "-h"]:
- if mode:
- helpExit("you can only specify one mode")
- else:
- mode = k
- if not mode:
- helpExit("No mode specified")
-
- # Put plainText, userKey, cipherText in bitstring format.
- plainText = userKey = cipherText = None
- if options.has_key("-k"):
- bitsInKey = keyLengthInBitsOf(options["-k"])
- rawKey = convertToBitstring(options["-k"], bitsInKey)
- userKey = makeLongKey(rawKey)
- if options.has_key("-p"):
- plainText = convertToBitstring(options["-p"], 128)
- if options.has_key("-c"):
- cipherText = convertToBitstring(options["-c"], 128)
- if mode == "-e" or mode == "-d":
- if not userKey:
- helpExit("-k (key) required with -e (encrypt) or -d (decrypt)")
- if mode == "-e":
- if not plainText:
- helpExit("-p (plaintext) is required when doing -e (encrypt)")
- if mode == "-d":
- if not cipherText:
- helpExit("-c (ciphertext) is required when doing -d (decrypt)")
-
- # Perform the action specified by the mode
- # NOTE that the observer will automatically print the basic stuff such
- # as plainText, userKey and cipherText (in the right format too), so we
- # only need to perform the action, without adding any extra print
- # statements here.
- if mode == "-e":
- if options.has_key("-b"):
- cipherText = encryptBitslice(plainText, userKey)
- else:
- cipherText = encrypt(plainText, userKey)
- elif mode == "-d":
- if options.has_key("-b"):
- plainText = decryptBitslice(cipherText, userKey)
- else:
- plainText = decrypt(cipherText, userKey)
- elif mode == "-s":
- O.addTag("testTitle", "fnTitle")
-
- printTest(test1(plainText, userKey))
- printTest(test2(plainText, userKey))
- printTest(test3(plainText, userKey))
- else:
- helpExit()
-
-
-if __name__ == "__main__":
- main()
diff --git a/src/CryptoPlus/Cipher/python_Serpent.py b/src/CryptoPlus/Cipher/python_Serpent.py
index 3a8272d..38a4675 100644
--- a/src/CryptoPlus/Cipher/python_Serpent.py
+++ b/src/CryptoPlus/Cipher/python_Serpent.py
@@ -1,5 +1,5 @@
from .blockcipher import *
-from .pyserpent import Serpent
+from .serpent import Serpent
def new(key,mode=MODE_ECB,IV=None,counter=None,segment_size=None):
"""Create a new cipher object
diff --git a/src/CryptoPlus/Cipher/serpent.py b/src/CryptoPlus/Cipher/serpent.py
new file mode 100644
index 0000000..30633ef
--- /dev/null
+++ b/src/CryptoPlus/Cipher/serpent.py
@@ -0,0 +1,680 @@
+## serpent.py - pure Python implementation of the Serpent algorithm.
+## Bjorn Edstrom 13 december 2007.
+##
+## Copyrights
+## ==========
+##
+## This code is a derived from an implementation by Dr Brian Gladman
+## (gladman@seven77.demon.co.uk) which is subject to the following license.
+## This Python implementation is not subject to any other license.
+##
+##/* This is an independent implementation of the encryption algorithm:
+## *
+## * Serpent by Ross Anderson, Eli Biham and Lars Knudsen
+## *
+## * which is a candidate algorithm in the Advanced Encryption Standard
+## * programme of the US National Institute of Standards and Technology
+## *
+## * Copyright in this implementation is held by Dr B R Gladman but I
+## * hereby give permission for its free direct or derivative use subject
+## * to acknowledgment of its origin and compliance with any conditions
+## * that the originators of the algorithm place on its exploitation.
+## *
+## * Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999
+## */
+##
+## The above copyright notice must not be removed.
+##
+## Information
+## ===========
+##
+## Anyone thinking of using this code should reconsider. It's slow.
+## Try python-mcrypt instead. In case a faster library is not installed
+## on the target system, this code can be used as a portable fallback.
+
+try:
+ import psyco
+ psyco.full()
+except ImportError:
+ pass
+
+block_size = 16
+key_size = 32
+
+class Serpent:
+
+ def __init__(self, key=None):
+ """Serpent."""
+
+ if key:
+ self.set_key(key)
+
+
+ def set_key(self, key):
+ """Init."""
+
+ key_len = len(key)
+ if key_len % 4:
+ # XXX: add padding?
+ raise KeyError("key not a multiple of 4")
+ if key_len > 32:
+ # XXX: prune?
+ raise KeyError("key_len > 32")
+
+ self.key_context = [0] * 140
+
+ key_word32 = [0] * 32
+ i = 0
+ while key:
+ key_word32[i] = struct.unpack("> n) | ((x << (32 - n)) & 0xFFFFFFFF)
+
+def rotl32(x, n):
+ return ((x << n) & 0xFFFFFFFF) | (x >> (32 - n))
+
+def byteswap32(x):
+ return ((x & 0xff) << 24) | (((x >> 8) & 0xff) << 16) | \
+ (((x >> 16) & 0xff) << 8) | ((x >> 24) & 0xff)
+
+def sb0(a, b, c, d, e, f, g, h):
+ t1 = a ^ d
+ t2 = a & d
+ t3 = c ^ t1
+ t6 = b & t1
+ t4 = b ^ t3
+ t10 = (~t3) % 0x100000000
+ h = t2 ^ t4
+ t7 = a ^ t6
+ t14 = (~t7) % 0x100000000
+ t8 = c | t7
+ t11 = t3 ^ t7
+ g = t4 ^ t8
+ t12 = h & t11
+ f = t10 ^ t12
+ e = t12 ^ t14
+ return e, f, g, h
+
+def ib0(a, b, c, d, e, f, g, h):
+ t1 = (~a) % 0x100000000
+ t2 = a ^ b
+ t3 = t1 | t2
+ t4 = d ^ t3
+ t7 = d & t2
+ t5 = c ^ t4
+ t8 = t1 ^ t7
+ g = t2 ^ t5
+ t11 = a & t4
+ t9 = g & t8
+ t14 = t5 ^ t8
+ f = t4 ^ t9
+ t12 = t5 | f
+ h = t11 ^ t12
+ e = h ^ t14
+ return e, f, g, h
+
+def sb1(a, b, c, d, e, f, g, h):
+ t1 = (~a) % 0x100000000
+ t2 = b ^ t1
+ t3 = a | t2
+ t4 = d | t2
+ t5 = c ^ t3
+ g = d ^ t5
+ t7 = b ^ t4
+ t8 = t2 ^ g
+ t9 = t5 & t7
+ h = t8 ^ t9
+ t11 = t5 ^ t7
+ f = h ^ t11
+ t13 = t8 & t11
+ e = t5 ^ t13
+ return e, f, g, h
+
+def ib1(a, b, c, d, e, f, g, h):
+ t1 = a ^ d
+ t2 = a & b
+ t3 = b ^ c
+ t4 = a ^ t3
+ t5 = b | d
+ t7 = c | t1
+ h = t4 ^ t5
+ t8 = b ^ t7
+ t11 = (~t2) % 0x100000000
+ t9 = t4 & t8
+ f = t1 ^ t9
+ t13 = t9 ^ t11
+ t12 = h & f
+ g = t12 ^ t13
+ t15 = a & d
+ t16 = c ^ t13
+ e = t15 ^ t16
+ return e, f, g, h
+
+def sb2(a, b, c, d, e, f, g, h):
+ t1 = (~a) % 0x100000000
+ t2 = b ^ d
+ t3 = c & t1
+ t13 = d | t1
+ e = t2 ^ t3
+ t5 = c ^ t1
+ t6 = c ^ e
+ t7 = b & t6
+ t10 = e | t5
+ h = t5 ^ t7
+ t9 = d | t7
+ t11 = t9 & t10
+ t14 = t2 ^ h
+ g = a ^ t11
+ t15 = g ^ t13
+ f = t14 ^ t15
+ return e, f, g, h
+
+def ib2(a, b, c, d, e, f, g, h):
+ t1 = b ^ d
+ t2 = (~t1) % 0x100000000
+ t3 = a ^ c
+ t4 = c ^ t1
+ t7 = a | t2
+ t5 = b & t4
+ t8 = d ^ t7
+ t11 = (~t4) % 0x100000000
+ e = t3 ^ t5
+ t9 = t3 | t8
+ t14 = d & t11
+ h = t1 ^ t9
+ t12 = e | h
+ f = t11 ^ t12
+ t15 = t3 ^ t12
+ g = t14 ^ t15
+ return e, f, g, h
+
+def sb3(a, b, c, d, e, f, g, h):
+ t1 = a ^ c
+ t2 = d ^ t1
+ t3 = a & t2
+ t4 = d ^ t3
+ t5 = b & t4
+ g = t2 ^ t5
+ t7 = a | g
+ t8 = b | d
+ t11 = a | d
+ t9 = t4 & t7
+ f = t8 ^ t9
+ t12 = b ^ t11
+ t13 = g ^ t9
+ t15 = t3 ^ t8
+ h = t12 ^ t13
+ t16 = c & t15
+ e = t12 ^ t16
+ return e, f, g, h
+
+def ib3(a, b, c, d, e, f, g, h):
+ t1 = b ^ c
+ t2 = b | c
+ t3 = a ^ c
+ t7 = a ^ d
+ t4 = t2 ^ t3
+ t5 = d | t4
+ t9 = t2 ^ t7
+ e = t1 ^ t5
+ t8 = t1 | t5
+ t11 = a & t4
+ g = t8 ^ t9
+ t12 = e | t9
+ f = t11 ^ t12
+ t14 = a & g
+ t15 = t2 ^ t14
+ t16 = e & t15
+ h = t4 ^ t16
+ return e, f, g, h
+
+def sb4(a, b, c, d, e, f, g, h):
+ t1 = a ^ d
+ t2 = d & t1
+ t3 = c ^ t2
+ t4 = b | t3
+ h = t1 ^ t4
+ t6 = (~b) % 0x100000000
+ t7 = t1 | t6
+ e = t3 ^ t7
+ t9 = a & e
+ t10 = t1 ^ t6
+ t11 = t4 & t10
+ g = t9 ^ t11
+ t13 = a ^ t3
+ t14 = t10 & g
+ f = t13 ^ t14
+ return e, f, g, h
+
+def ib4(a, b, c, d, e, f, g, h):
+ t1 = c ^ d
+ t2 = c | d
+ t3 = b ^ t2
+ t4 = a & t3
+ f = t1 ^ t4
+ t6 = a ^ d
+ t7 = b | d
+ t8 = t6 & t7
+ h = t3 ^ t8
+ t10 = (~a) % 0x100000000
+ t11 = c ^ h
+ t12 = t10 | t11
+ e = t3 ^ t12
+ t14 = c | t4
+ t15 = t7 ^ t14
+ t16 = h | t10
+ g = t15 ^ t16
+ return e, f, g, h
+
+def sb5(a, b, c, d, e, f, g, h):
+ t1 = (~a) % 0x100000000
+ t2 = a ^ b
+ t3 = a ^ d
+ t4 = c ^ t1
+ t5 = t2 | t3
+ e = t4 ^ t5
+ t7 = d & e
+ t8 = t2 ^ e
+ t10 = t1 | e
+ f = t7 ^ t8
+ t11 = t2 | t7
+ t12 = t3 ^ t10
+ t14 = b ^ t7
+ g = t11 ^ t12
+ t15 = f & t12
+ h = t14 ^ t15
+ return e, f, g, h
+
+def ib5(a, b, c, d, e, f, g, h):
+ t1 = (~c) % 0x100000000
+ t2 = b & t1
+ t3 = d ^ t2
+ t4 = a & t3
+ t5 = b ^ t1
+ h = t4 ^ t5
+ t7 = b | h
+ t8 = a & t7
+ f = t3 ^ t8
+ t10 = a | d
+ t11 = t1 ^ t7
+ e = t10 ^ t11
+ t13 = a ^ c
+ t14 = b & t10
+ t15 = t4 | t13
+ g = t14 ^ t15
+ return e, f, g, h
+
+def sb6(a, b, c, d, e, f, g, h):
+ t1 = (~a) % 0x100000000
+ t2 = a ^ d
+ t3 = b ^ t2
+ t4 = t1 | t2
+ t5 = c ^ t4
+ f = b ^ t5
+ t13 = (~t5) % 0x100000000
+ t7 = t2 | f
+ t8 = d ^ t7
+ t9 = t5 & t8
+ g = t3 ^ t9
+ t11 = t5 ^ t8
+ e = g ^ t11
+ t14 = t3 & t11
+ h = t13 ^ t14
+ return e, f, g, h
+
+def ib6(a, b, c, d, e, f, g, h):
+ t1 = (~a) % 0x100000000
+ t2 = a ^ b
+ t3 = c ^ t2
+ t4 = c | t1
+ t5 = d ^ t4
+ t13 = d & t1
+ f = t3 ^ t5
+ t7 = t3 & t5
+ t8 = t2 ^ t7
+ t9 = b | t8
+ h = t5 ^ t9
+ t11 = b | h
+ e = t8 ^ t11
+ t14 = t3 ^ t11
+ g = t13 ^ t14
+ return e, f, g, h
+
+def sb7(a, b, c, d, e, f, g, h):
+ t1 = (~c) % 0x100000000
+ t2 = b ^ c
+ t3 = b | t1
+ t4 = d ^ t3
+ t5 = a & t4
+ t7 = a ^ d
+ h = t2 ^ t5
+ t8 = b ^ t5
+ t9 = t2 | t8
+ t11 = d & t3
+ f = t7 ^ t9
+ t12 = t5 ^ f
+ t15 = t1 | t4
+ t13 = h & t12
+ g = t11 ^ t13
+ t16 = t12 ^ g
+ e = t15 ^ t16
+ return e, f, g, h
+
+def ib7(a, b, c, d, e, f, g, h):
+ t1 = a & b
+ t2 = a | b
+ t3 = c | t1
+ t4 = d & t2
+ h = t3 ^ t4
+ t6 = (~d) % 0x100000000
+ t7 = b ^ t4
+ t8 = h ^ t6
+ t11 = c ^ t7
+ t9 = t7 | t8
+ f = a ^ t9
+ t12 = d | f
+ e = t11 ^ t12
+ t14 = a & h
+ t15 = t3 ^ f
+ t16 = e ^ t14
+ g = t15 ^ t16
+ return e, f, g, h
+
+def k_xor(key, r, a, b, c, d):
+ a ^= key[4 * r + 8]
+ b ^= key[4 * r + 9]
+ c ^= key[4 * r + 10]
+ d ^= key[4 * r + 11]
+ return a, b, c, d
+
+def k_set(key, r):
+ a = key[4 * r + 8]
+ b = key[4 * r + 9]
+ c = key[4 * r + 10]
+ d = key[4 * r + 11]
+ return a, b, c, d
+
+def k_get(key, r, a, b, c, d):
+ key[4 * r + 8] = a
+ key[4 * r + 9] = b
+ key[4 * r + 10] = c
+ key[4 * r + 11] = d
+
+def rot(a, b, c, d):
+ a = rotl32(a, 13)
+ c = rotl32(c, 3)
+ d ^= c ^ ((a << 3) & 0xFFFFFFFF)
+ b ^= a ^ c
+ d = rotl32(d, 7)
+ b = rotl32(b, 1)
+ a ^= b ^ d
+ c ^= d ^ ((b << 7) & 0xFFFFFFFF)
+ a = rotl32(a, 5)
+ c = rotl32(c, 22)
+ return a, b, c, d
+
+def irot(a, b, c, d):
+ c = rotr32(c, 22)
+ a = rotr32(a, 5)
+ c ^= d ^ ((b << 7) & 0xFFFFFFFF)
+ a ^= b ^ d
+ d = rotr32(d, 7)
+ b = rotr32(b, 1)
+ d ^= c ^ ((a << 3) & 0xFFFFFFFF)
+ b ^= a ^ c
+ c = rotr32(c, 3)
+ a = rotr32(a, 13)
+ return a, b, c, d
+
+def set_key(l_key, key, key_len):
+ key_len *= 8
+ if key_len > 256:
+ return False
+
+ i = 0
+ lk = (key_len + 31) // 32
+ while i < lk:
+ l_key[i] = key[i]
+ if WORD_BIGENDIAN:
+ l_key[i] = byteswap32(key[i])
+ i += 1
+
+ if key_len < 256:
+ while i < 8:
+ l_key[i] = 0
+ i += 1
+ i = key_len // 32
+ lk = 1 << (key_len % 32)
+ l_key[i] = (l_key[i] & (lk - 1)) | lk
+ for i in range(132):
+ lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5] ^ l_key[i + 7] ^ 0x9e3779b9 ^ i
+ l_key[i + 8] = ((lk << 11) & 0xFFFFFFFF) | (lk >> 21)
+
+ key = l_key
+ e = 0
+ f = 0
+ g = 0
+ h = 0
+ a, b, c, d = k_set(key, 0); e, f, g, h = sb3(a, b, c, d, e, f, g, h); k_get(key, 0, e, f, g, h)
+ a, b, c, d = k_set(key, 1); e, f, g, h = sb2(a, b, c, d, e, f, g, h); k_get(key, 1, e, f, g, h)
+ a, b, c, d = k_set(key, 2); e, f, g, h = sb1(a, b, c, d, e, f, g, h); k_get(key, 2, e, f, g, h)
+ a, b, c, d = k_set(key, 3); e, f, g, h = sb0(a, b, c, d, e, f, g, h); k_get(key, 3, e, f, g, h)
+ a, b, c, d = k_set(key, 4); e, f, g, h = sb7(a, b, c, d, e, f, g, h); k_get(key, 4, e, f, g, h)
+ a, b, c, d = k_set(key, 5); e, f, g, h = sb6(a, b, c, d, e, f, g, h); k_get(key, 5, e, f, g, h)
+ a, b, c, d = k_set(key, 6); e, f, g, h = sb5(a, b, c, d, e, f, g, h); k_get(key, 6, e, f, g, h)
+ a, b, c, d = k_set(key, 7); e, f, g, h = sb4(a, b, c, d, e, f, g, h); k_get(key, 7, e, f, g, h)
+ a, b, c, d = k_set(key, 8); e, f, g, h = sb3(a, b, c, d, e, f, g, h); k_get(key, 8, e, f, g, h)
+ a, b, c, d = k_set(key, 9); e, f, g, h = sb2(a, b, c, d, e, f, g, h); k_get(key, 9, e, f, g, h)
+ a, b, c, d = k_set(key, 10); e, f, g, h = sb1(a, b, c, d, e, f, g, h); k_get(key, 10, e, f, g, h)
+ a, b, c, d = k_set(key, 11); e, f, g, h = sb0(a, b, c, d, e, f, g, h); k_get(key, 11, e, f, g, h)
+ a, b, c, d = k_set(key, 12); e, f, g, h = sb7(a, b, c, d, e, f, g, h); k_get(key, 12, e, f, g, h)
+ a, b, c, d = k_set(key, 13); e, f, g, h = sb6(a, b, c, d, e, f, g, h); k_get(key, 13, e, f, g, h)
+ a, b, c, d = k_set(key, 14); e, f, g, h = sb5(a, b, c, d, e, f, g, h); k_get(key, 14, e, f, g, h)
+ a, b, c, d = k_set(key, 15); e, f, g, h = sb4(a, b, c, d, e, f, g, h); k_get(key, 15, e, f, g, h)
+ a, b, c, d = k_set(key, 16); e, f, g, h = sb3(a, b, c, d, e, f, g, h); k_get(key, 16, e, f, g, h)
+ a, b, c, d = k_set(key, 17); e, f, g, h = sb2(a, b, c, d, e, f, g, h); k_get(key, 17, e, f, g, h)
+ a, b, c, d = k_set(key, 18); e, f, g, h = sb1(a, b, c, d, e, f, g, h); k_get(key, 18, e, f, g, h)
+ a, b, c, d = k_set(key, 19); e, f, g, h = sb0(a, b, c, d, e, f, g, h); k_get(key, 19, e, f, g, h)
+ a, b, c, d = k_set(key, 20); e, f, g, h = sb7(a, b, c, d, e, f, g, h); k_get(key, 20, e, f, g, h)
+ a, b, c, d = k_set(key, 21); e, f, g, h = sb6(a, b, c, d, e, f, g, h); k_get(key, 21, e, f, g, h)
+ a, b, c, d = k_set(key, 22); e, f, g, h = sb5(a, b, c, d, e, f, g, h); k_get(key, 22, e, f, g, h)
+ a, b, c, d = k_set(key, 23); e, f, g, h = sb4(a, b, c, d, e, f, g, h); k_get(key, 23, e, f, g, h)
+ a, b, c, d = k_set(key, 24); e, f, g, h = sb3(a, b, c, d, e, f, g, h); k_get(key, 24, e, f, g, h)
+ a, b, c, d = k_set(key, 25); e, f, g, h = sb2(a, b, c, d, e, f, g, h); k_get(key, 25, e, f, g, h)
+ a, b, c, d = k_set(key, 26); e, f, g, h = sb1(a, b, c, d, e, f, g, h); k_get(key, 26, e, f, g, h)
+ a, b, c, d = k_set(key, 27); e, f, g, h = sb0(a, b, c, d, e, f, g, h); k_get(key, 27, e, f, g, h)
+ a, b, c, d = k_set(key, 28); e, f, g, h = sb7(a, b, c, d, e, f, g, h); k_get(key, 28, e, f, g, h)
+ a, b, c, d = k_set(key, 29); e, f, g, h = sb6(a, b, c, d, e, f, g, h); k_get(key, 29, e, f, g, h)
+ a, b, c, d = k_set(key, 30); e, f, g, h = sb5(a, b, c, d, e, f, g, h); k_get(key, 30, e, f, g, h)
+ a, b, c, d = k_set(key, 31); e, f, g, h = sb4(a, b, c, d, e, f, g, h); k_get(key, 31, e, f, g, h)
+ a, b, c, d = k_set(key, 32); e, f, g, h = sb3(a, b, c, d, e, f, g, h); k_get(key, 32, e, f, g, h)
+
+def encrypt(key, in_blk):
+ a = in_blk[0]
+ b = in_blk[1]
+ c = in_blk[2]
+ d = in_blk[3]
+ if WORD_BIGENDIAN:
+ a = byteswap32(a)
+ b = byteswap32(b)
+ c = byteswap32(c)
+ d = byteswap32(d)
+ e = 0
+ f = 0
+ g = 0
+ h = 0
+ a, b, c, d = k_xor(key, 0, a, b, c, d); e, f, g, h = sb0(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 1, e, f, g, h); a, b, c, d = sb1(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 2, a, b, c, d); e, f, g, h = sb2(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 3, e, f, g, h); a, b, c, d = sb3(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 4, a, b, c, d); e, f, g, h = sb4(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 5, e, f, g, h); a, b, c, d = sb5(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 6, a, b, c, d); e, f, g, h = sb6(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 7, e, f, g, h); a, b, c, d = sb7(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 8, a, b, c, d); e, f, g, h = sb0(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 9, e, f, g, h); a, b, c, d = sb1(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 10, a, b, c, d); e, f, g, h = sb2(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 11, e, f, g, h); a, b, c, d = sb3(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 12, a, b, c, d); e, f, g, h = sb4(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 13, e, f, g, h); a, b, c, d = sb5(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 14, a, b, c, d); e, f, g, h = sb6(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 15, e, f, g, h); a, b, c, d = sb7(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 16, a, b, c, d); e, f, g, h = sb0(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 17, e, f, g, h); a, b, c, d = sb1(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 18, a, b, c, d); e, f, g, h = sb2(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 19, e, f, g, h); a, b, c, d = sb3(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 20, a, b, c, d); e, f, g, h = sb4(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 21, e, f, g, h); a, b, c, d = sb5(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 22, a, b, c, d); e, f, g, h = sb6(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 23, e, f, g, h); a, b, c, d = sb7(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 24, a, b, c, d); e, f, g, h = sb0(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 25, e, f, g, h); a, b, c, d = sb1(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 26, a, b, c, d); e, f, g, h = sb2(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 27, e, f, g, h); a, b, c, d = sb3(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 28, a, b, c, d); e, f, g, h = sb4(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 29, e, f, g, h); a, b, c, d = sb5(e, f, g, h, a, b, c, d); a, b, c, d = rot(a, b, c, d)
+ a, b, c, d = k_xor(key, 30, a, b, c, d); e, f, g, h = sb6(a, b, c, d, e, f, g, h); e, f, g, h = rot(e, f, g, h)
+ e, f, g, h = k_xor(key, 31, e, f, g, h); a, b, c, d = sb7(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 32, a, b, c, d)
+ if WORD_BIGENDIAN:
+ a = byteswap32(a)
+ b = byteswap32(b)
+ c = byteswap32(c)
+ d = byteswap32(d)
+ in_blk[0] = a
+ in_blk[1] = b
+ in_blk[2] = c
+ in_blk[3] = d
+
+def decrypt(key, in_blk):
+ a = in_blk[0]
+ b = in_blk[1]
+ c = in_blk[2]
+ d = in_blk[3]
+ if WORD_BIGENDIAN:
+ a = byteswap32(a)
+ b = byteswap32(b)
+ c = byteswap32(c)
+ d = byteswap32(d)
+ e = 0
+ f = 0
+ g = 0
+ h = 0
+ a, b, c, d = k_xor(key, 32, a, b, c, d); e, f, g, h = ib7(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 31, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib6(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 30, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib5(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 29, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib4(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 28, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib3(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 27, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib2(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 26, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib1(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 25, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib0(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 24, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib7(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 23, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib6(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 22, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib5(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 21, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib4(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 20, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib3(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 19, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib2(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 18, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib1(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 17, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib0(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 16, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib7(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 15, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib6(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 14, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib5(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 13, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib4(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 12, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib3(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 11, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib2(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 10, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib1(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 9, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib0(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 8, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib7(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 7, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib6(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 6, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib5(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 5, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib4(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 4, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib3(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 3, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib2(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 2, a, b, c, d); a, b, c, d = irot(a, b, c, d); e, f, g, h = ib1(a, b, c, d, e, f, g, h)
+ e, f, g, h = k_xor(key, 1, e, f, g, h); e, f, g, h = irot(e, f, g, h); a, b, c, d = ib0(e, f, g, h, a, b, c, d)
+ a, b, c, d = k_xor(key, 0, a, b, c, d)
+ if WORD_BIGENDIAN:
+ a = byteswap32(a)
+ b = byteswap32(b)
+ c = byteswap32(c)
+ d = byteswap32(d)
+ in_blk[0] = a
+ in_blk[1] = b
+ in_blk[2] = c
+ in_blk[3] = d
+
+__testkey = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'
+__testdat = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
+assert b'\xde&\x9f\xf83\xe42\xb8[.\x88\xd2p\x1c\xe7\\' == Serpent(__testkey).encrypt(__testdat)
+assert __testdat == Serpent(__testkey).decrypt(b'\xde&\x9f\xf83\xe42\xb8[.\x88\xd2p\x1c\xe7\\')