# Path: crysp/utils/operators.py
# def ror(x,n):
#     return (x>>n | x<<(x.size-n))
# 
# def rol(x,n):
#     return (x<<n | x>>(x.size-n))
# 
# def concat(L,bigend=False):
#     if len(L)==1: return L[0]
#     if bigend: L = reversed(L)
#     return reduce(lambda x,y: x//y, L)


from crysp.bits import *
from crysp.utils.operators import ror,rol,concat
        C = B
        return pack(C)

    def dec(self,C):
        R = Bits(C,bitorder=1)
        assert R.size==self.blocksize
        B = R
        B = _Sinv(31%8,B^self.keys[32])^self.keys[31]
        for i in range(30,-1,-1):
            B = _Sinv(i%8,_Linv(B))^self.keys[i]
        M = B
        return pack(M)

# Serpent internals:
#-------------------

def _S(i,X):
    assert 0<=i<8
    assert X.size==128
    boxes = [
       [ 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12],
       [15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4],
       [ 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2],
       [ 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14],
       [ 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13],
       [15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1],
       [ 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0],
       [ 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6],
    ]
    Sx = [Bits(boxes[i][x],4) for x in _IP(X).split(4)]

# Path: crysp/utils/operators.py
# def ror(x,n):
#     return (x>>n | x<<(x.size-n))
# 
# def rol(x,n):
#     return (x<<n | x>>(x.size-n))
# 
# def concat(L,bigend=False):
#     if len(L)==1: return L[0]
#     if bigend: L = reversed(L)
#     return reduce(lambda x,y: x//y, L)


# Path: crysp/serpent.py
from crysp.bits import *
from crysp.utils.operators import ror,rol,concat

        C = B
        return pack(C)

    def dec(self,C):
        R = Bits(C,bitorder=1)
        assert R.size==self.blocksize
        B = R
        B = _Sinv(31%8,B^self.keys[32])^self.keys[31]
        for i in range(30,-1,-1):
            B = _Sinv(i%8,_Linv(B))^self.keys[i]
        M = B
        return pack(M)

# Serpent internals:
#-------------------

def _S(i,X):
    assert 0<=i<8
    assert X.size==128
    boxes = [
       [ 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12],
       [15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4],
       [ 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2],
       [ 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14],
       [ 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13],
       [15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1],
       [ 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0],
       [ 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6],
    ]
    Sx = [Bits(boxes[i][x],4) for x in _IP(X).split(4)]

    return _FP(concat(Sx))