#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    2
    Rep Power
    0

    Help with implementation of s-AES


    Hi guys, having an issue with an s-AES implementation i've been working on in python.
    I get the following code,

    Traceback (most recent call last):
    File "C:/Python27/Test", line 133, in <module>
    encrypt(plaintext)
    File "C:/Python27/Test", line 90, in encrypt
    state = mixCol(shiftRow(sub4NibList(sBox, state)))
    File "C:/Python27/Test", line 54, in sub4NibList
    return [sbox[e] for e in s]
    IndexError: list index out of range

    Here is my code;

    Code:
    import sys
    
    # Round keys: K0 = w0 + w1; K1 = w2 + w3; K2 = w4 + w5
    w = [None] * 6
    
    ##################### S-Box ######################
    sBox  = [0x9, 0x4, 0xa, 0xb, 0xd, 0x1, 0x8, 0x5, #
             0x6, 0x2, 0x0, 0x3, 0xc, 0xe, 0xf, 0x7] #
    ##################################################
    
    ################ Inverse S-Box ###################
    sBoxI = [0xa, 0x5, 0x9, 0xb, 0x1, 0x7, 0x8, 0xf, #
             0x6, 0x0, 0x2, 0x3, 0xc, 0x4, 0xd, 0xe] #
    ################################################## 
    
    
    ################ Multiplcation function ################# 
    def mult(p1, p2):
        """Multiply two polynomials in GF(2^4)/x^4 + x + 1"""
        x = 0
        while p2:
            if p2 & 0b1:
                x ^= p1
            p1 <<= 1
            if p1 & 0b10000:
                p1 ^= 0b11
            p2 >>= 1
        return x & 0b1111
    
    
    
    
    def intToVec(n):
        """Convert a 2-byte integer into a 4-element vector"""
        return [n >> 12, (n >> 4) & 0xf, (n >> 8) & 0xf,  n & 0xf]           
    
    
     
    def vecToInt(m):
        """Convert a 4-element vector into 2-byte integer"""
        return (m[0] << 12) + (m[2] << 8) + (m[1] << 4) + m[3]
    
    
    
    #######################Adds Key########################## 
    def addKey(s1, s2):
        """Add two keys in GF(2^4)"""  
        return [i ^ j for i, j in zip(s1, s2)]
    
    
    ############## Byte substitution function ###############     
    def sub4NibList(sbox, s):
        """Nibble substitution function"""
        return [sbox[e] for e in s]
    
    
    ###################### Shift Rows #######################
    def shiftRow(s):
        """ShiftRow function"""
        return [s[0], s[1], s[3], s[2]]
    
    
    ##################### Key Expansion ##################### 
    def keyExpansion(key):
        #Generate the three round keys
    
        def sBoxNib(b):
            #This function swaps and substitutes using sBox
            return sBox[b >> 4] + (sBox[b & 0x0f] << 4)
     
        Rcon1 = 0b10000000
        Rcon2 = 0b00110000
        w[0] = (key & 0xff00) >> 8
        w[1] = key & 0x00ff
        w[2] = w[0] ^ Rcon1 ^ sBoxNib(w[1])
        w[3] = w[2] ^ w[1]
        w[4] = w[2] ^ Rcon2 ^ sBoxNib(w[3])
        w[5] = w[4] ^ w[3]
     
    
    ##################### ENCRYPTION #########################
    def encrypt(ptext):
        """Encrypt plaintext block"""
        def mixCol(s):
            return [s[0] ^ mult(4, s[2]), s[1] ^ mult(4, s[3]),
                    s[2] ^ mult(4, s[0]), s[3] ^ mult(4, s[1])]   
         
        state = intToVec(((w[0] << 8) + w[1]) ^ ptext) 
        print(state)
        state = mixCol(shiftRow(sub4NibList(sBox, state)))
        print(state)
        state = addKey(intToVec((w[2] << 8) + w[3]), state)
        print(state)
        state = shiftRow(sub4NibList(sBox, state))
        print(state)
        print("\n")
        return vecToInt(addKey(intToVec((w[4] << 8) + w[5]), state))
    
    
    ###################### DECRYPTION ########################     
    def decrypt(ctext):
        """Decrypt ciphertext block"""
        def iMixCol(s):
            return [mult(9, s[0]) ^ mult(2, s[2]), mult(9, s[1]) ^ mult(2, s[3]),
                    mult(9, s[2]) ^ mult(2, s[0]), mult(9, s[3]) ^ mult(2, s[1])]
    
        state = intToVec(((w[4] << 8) + w[5]) ^ ctext)
        print(state)
        state = sub4NibList(sBoxI, shiftRow(state))
        print(state)
        state = iMixCol(addKey(intToVec((w[2] << 8) + w[3]), state))
        print(state)
        state = sub4NibList(sBoxI, shiftRow(state))
        print(state)
        print("\n")
        print(ctext)
        return vecToInt(addKey(intToVec((w[0] << 8) + w[1]), state))
        
    
    ######################### MAIN ########################### 
    if __name__ == '__main__':
    
        plaintext=input('Please enter your plaintext: ')
        key = input('Please enter your key: ')
        #1101011100101000 testing plaintext
        intext = plaintext
        #0100101011110101 testing key
        key = key
        #ciphertext = 0b0010010011101100
        getBin = lambda x: x >= 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]
    
        keyExpansion(key)
        encrypt(plaintext)
        print(getBin(plaintext))
    
        decrypt(plaintext)
        #print(getBin(ciphertext))
    When I try and put in the test values for ciphertext and key, it gives me the above error. Thanks for any tips!
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,856
    Rep Power
    481

    I get different error


    Code:
    $ python3 p.py
    Please enter your plaintext: the quick fox
    Please enter your key: 12
    Traceback (most recent call last):
      File "p.py", line 122, in <module>
        keyExpansion(key)
      File "p.py", line 63, in keyExpansion
        w[0] = (key & 0xff00) >> 8
    TypeError: unsupported operand type(s) for &: 'str' and 'int'
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo