# Path: crysp/utils/operators.py
# def rol(x,n):
#     return (x<<n | x>>(x.size-n))
# 
# def ror(x,n):
#     return (x>>n | x<<(x.size-n))
# 
# Path: crysp/keccak.py
# class Keccak(object):
#     def __init__(self,_b=1600,_c=576,**kargs):
#         b = kargs.get('b',_b)
#         c = kargs.get('c',_c)
#         r = kargs.get('r',b-c)
#         self.outlen = kargs.get('len',None)
#         if not (b == r+c):
#             if 'b' in kargs and 'r' in kargs:
#                 c = b-r
#             if 'r' in kargs and 'c' in kargs:
#                 b = r+c
#         assert b == r+c
#         assert b in (25,50,100,200,400,800,1600)
#         self.b = b
#         self.w = b//25 # w is supposed to fit the CPU word/register length.
#         l = {1:0,2:1,4:2,8:3,16:4,32:5,64:6}[self.w]
#         self.n = 12+2*l
#         self.setrate(r)
#         self.duplexing = False
# 
#     def setrate(self,r):
#         assert r<=1536
#         # usual rate belongs to (576,832,1024,1088,1152,1344)
#         #assert r%self.w==0
#         self.r = r
#         self.c = self.b-self.r
# 
#     def f(self,A) :
#         global RC
#         for i in range(0,self.n):
#             A = Round(A,RC[i][:self.w])
#         return A
# 
#     def __call__(self,M,bitlen=None,r=None):
#         # create state (null) :
#         S = State(self.w)
#         # set rate:
#         if r is None:
#             assert self.r
#             r = self.r
#         else:
#             self.setrate(r)
# 
#         #Absorbing phase
#         for Pi in self.iterblocks(M,bitlen):
#             Ps = State(self.w).load(Pi)
#             S = self.f(S^Ps)
# 
#         #Squeezing phase
#         Z = S.dump(r)
#         while len(Z)<self.outlen:
#             S = self.f(S)
#             Z = Z//S.dump(r)
#         return pack(Z[:self.outlen])
# 
#     def iterblocks(self,M,bitlen=None):
#         needed = len(M)*8
#         # handle NIST MSB alignment to Keccak LSB alignment for last byte
#         # (see Keccak SHA-3 submission §6.1):
#         if bitlen:
#             assert bitlen<=needed
#             needed = bitlen
#             if not self.duplexing:
#                 b = Bits(M[-1:],size=needed%8)[::-1]
#                 M = M[:needed//8]+bytes([b.ival])
#         r = self.r
#         br,rr = divmod(r,8)
#         P = BytesIO(M)
#         # init iterator loop:
#         Pi = P.read(br)
#         Pb = Bits(0,size=0)
#         while len(Pi)>0:
#             # input message bitstream buffer:
#             Pb =  Pb//Bits(Pi,bitorder=1)
#             if len(Pb)>=needed:
#                 Pb.size=needed
#                 P.read() # consume all stream to exit loop
#             if len(Pb)>=r:
#                 yield Pb[:r]
#                 needed -= r
#                 Pb = Pb[r:]
#             Pi = P.read(br)
#         # pad10*1 (with little-endian convention) :
#         Pb = Pb//Bits(1)//Bits(0,size=r-len(Pb)-2)//Bits(1)
#         yield Pb
# 
#     # Duplex construction (see "Cryptographic Sponge Functions", http://sponge.noekeon.org)
#     def duplex(self,m,bitlen=None,outlen=None):
#         self.duplexing = True
#         L = [x for x in self.iterblocks(m,bitlen)]
#         assert len(L)==1
#         if outlen is None: outlen=self.r
#         if not hasattr(self,'_S'):
#             self._S = State(self.w)
#         self._S = self.f(self._S^State(self.w).load(L[0]))
#         return pack(self._S.dump(outlen))
# 
# Path: crysp/padding.py
# class SHApadding(blockiterator):
#     def __init__(self,l,wsize):
#         self.wsize = wsize
#         super(SHApadding,self).__init__(l)
#     # add sha padding:
#     def lastblock(self,m,**kargs):
#         bitlen = kargs.get('bitlen',None)
#         if bitlen is None:
#             bitlen = self.bitcnt+len(m)*8
#         assert self.bitcnt<=bitlen
#         needed = bitlen-self.bitcnt
#         mb = Bits(m,size=needed)
#         countersize = self.wsize*2
#         N = self.blocksize-1-countersize-needed
#         if N<0: N += self.blocksize
#         pad = mb//Bits(1,1)//Bits(0,N)
#         self.padflag = True
#         self.bitcnt += needed
#         return pad.bytes()+pack(Bits(bitlen,countersize),'>L')
#     # remove sha padding:
#     def remove(self,c):
#         clen = self.wsize//4
#         counter,_ = unpack(c[-clen:],bigend=True)
#         c = list(c[:-clen])
#         while Bits(c[-1]).ival==0:
#             c.pop()
#         if len(c)==0: raise PaddingError("failed to remove padding")
#         b = Bits(c.pop())
#         b.size=str(b).rfind('1')
#         return b''.join(c)+b.bytes()


from crysp.bits import *
from crysp.utils.operators import rol,ror
from crysp.keccak import Keccak
from crysp.padding import SHApadding
# -*- coding: utf-8 -*-

# This code is part of crysp
# Copyright (C) 2008 Axel Tillequin (bdcht3@gmail.com)
# published under GPLv2 license


Ch     = lambda x,y,z: z^(x&(y^z))
Parity = lambda x,y,z: x^y^z
Maj    = lambda x,y,z: (x&y)|(x&z)|(y&z)


# Path: crysp/utils/operators.py
# def rol(x,n):
#     return (x<<n | x>>(x.size-n))
# 
# def ror(x,n):
#     return (x>>n | x<<(x.size-n))
# 
# Path: crysp/keccak.py
# class Keccak(object):
#     def __init__(self,_b=1600,_c=576,**kargs):
#         b = kargs.get('b',_b)
#         c = kargs.get('c',_c)
#         r = kargs.get('r',b-c)
#         self.outlen = kargs.get('len',None)
#         if not (b == r+c):
#             if 'b' in kargs and 'r' in kargs:
#                 c = b-r
#             if 'r' in kargs and 'c' in kargs:
#                 b = r+c
#         assert b == r+c
#         assert b in (25,50,100,200,400,800,1600)
#         self.b = b
#         self.w = b//25 # w is supposed to fit the CPU word/register length.
#         l = {1:0,2:1,4:2,8:3,16:4,32:5,64:6}[self.w]
#         self.n = 12+2*l
#         self.setrate(r)
#         self.duplexing = False
# 
#     def setrate(self,r):
#         assert r<=1536
#         # usual rate belongs to (576,832,1024,1088,1152,1344)
#         #assert r%self.w==0
#         self.r = r
#         self.c = self.b-self.r
# 
#     def f(self,A) :
#         global RC
#         for i in range(0,self.n):
#             A = Round(A,RC[i][:self.w])
#         return A
# 
#     def __call__(self,M,bitlen=None,r=None):
#         # create state (null) :
#         S = State(self.w)
#         # set rate:
#         if r is None:
#             assert self.r
#             r = self.r
#         else:
#             self.setrate(r)
# 
#         #Absorbing phase
#         for Pi in self.iterblocks(M,bitlen):
#             Ps = State(self.w).load(Pi)
#             S = self.f(S^Ps)
# 
#         #Squeezing phase
#         Z = S.dump(r)
#         while len(Z)<self.outlen:
#             S = self.f(S)
#             Z = Z//S.dump(r)
#         return pack(Z[:self.outlen])
# 
#     def iterblocks(self,M,bitlen=None):
#         needed = len(M)*8
#         # handle NIST MSB alignment to Keccak LSB alignment for last byte
#         # (see Keccak SHA-3 submission §6.1):
#         if bitlen:
#             assert bitlen<=needed
#             needed = bitlen
#             if not self.duplexing:
#                 b = Bits(M[-1:],size=needed%8)[::-1]
#                 M = M[:needed//8]+bytes([b.ival])
#         r = self.r
#         br,rr = divmod(r,8)
#         P = BytesIO(M)
#         # init iterator loop:
#         Pi = P.read(br)
#         Pb = Bits(0,size=0)
#         while len(Pi)>0:
#             # input message bitstream buffer:
#             Pb =  Pb//Bits(Pi,bitorder=1)
#             if len(Pb)>=needed:
#                 Pb.size=needed
#                 P.read() # consume all stream to exit loop
#             if len(Pb)>=r:
#                 yield Pb[:r]
#                 needed -= r
#                 Pb = Pb[r:]
#             Pi = P.read(br)
#         # pad10*1 (with little-endian convention) :
#         Pb = Pb//Bits(1)//Bits(0,size=r-len(Pb)-2)//Bits(1)
#         yield Pb
# 
#     # Duplex construction (see "Cryptographic Sponge Functions", http://sponge.noekeon.org)
#     def duplex(self,m,bitlen=None,outlen=None):
#         self.duplexing = True
#         L = [x for x in self.iterblocks(m,bitlen)]
#         assert len(L)==1
#         if outlen is None: outlen=self.r
#         if not hasattr(self,'_S'):
#             self._S = State(self.w)
#         self._S = self.f(self._S^State(self.w).load(L[0]))
#         return pack(self._S.dump(outlen))
# 
# Path: crysp/padding.py
# class SHApadding(blockiterator):
#     def __init__(self,l,wsize):
#         self.wsize = wsize
#         super(SHApadding,self).__init__(l)
#     # add sha padding:
#     def lastblock(self,m,**kargs):
#         bitlen = kargs.get('bitlen',None)
#         if bitlen is None:
#             bitlen = self.bitcnt+len(m)*8
#         assert self.bitcnt<=bitlen
#         needed = bitlen-self.bitcnt
#         mb = Bits(m,size=needed)
#         countersize = self.wsize*2
#         N = self.blocksize-1-countersize-needed
#         if N<0: N += self.blocksize
#         pad = mb//Bits(1,1)//Bits(0,N)
#         self.padflag = True
#         self.bitcnt += needed
#         return pad.bytes()+pack(Bits(bitlen,countersize),'>L')
#     # remove sha padding:
#     def remove(self,c):
#         clen = self.wsize//4
#         counter,_ = unpack(c[-clen:],bigend=True)
#         c = list(c[:-clen])
#         while Bits(c[-1]).ival==0:
#             c.pop()
#         if len(c)==0: raise PaddingError("failed to remove padding")
#         b = Bits(c.pop())
#         b.size=str(b).rfind('1')
#         return b''.join(c)+b.bytes()


# Path: crysp/sha.py
from crysp.bits import *
from crysp.utils.operators import rol,ror
from crysp.keccak import Keccak
from crysp.padding import SHApadding

# -*- coding: utf-8 -*-

# This code is part of crysp
# Copyright (C) 2008 Axel Tillequin (bdcht3@gmail.com)
# published under GPLv2 license


Ch     = lambda x,y,z: z^(x&(y^z))
Parity = lambda x,y,z: x^y^z
Maj    = lambda x,y,z: (x&y)|(x&z)|(y&z)


class SHA1(object):