#!/usr/bin/env python
# -*- coding: utf-8 -*-

import hashlib
from struct import *
from sha import sha as common_sha
secret = 'sharedsecret'

class SHA1Extend(common_sha):
    def __init__(self, length, hexdigest):
        self.input = []
        self.setStateHex(length, hexdigest)

    def setState(self, length, H0, H1, H2, H3, H4):
        self.prefixLength = length
        self.length = length+len(self.getPadding(length))
        self.count = [0, self.length*8]
        self.H0=H0
        self.H1=H1
        self.H2=H2
        self.H3=H3
        self.H4=H4

    def setStateHex(self,length, hexdigest):
        H0 = long(hexdigest[0:8], 16)
        H1 = long(hexdigest[8:16], 16)
        H2 = long(hexdigest[16:24], 16)
        H3 = long(hexdigest[24:32], 16)
        H4 = long(hexdigest[32:40], 16)
        self.setState(length, H0, H1, H2, H3, H4)

    def getPadding(self,length=None):
        if not length : length = self.prefixLength
        m = (length%64)
        if( m > 55): 
            m = 119-m
        else: 
            m = 55-m
        return '\x80'+('\0'*m)+pack('>2L', 0L, length*8)


def is_valid(m, m_hash):
    if hashlib.sha1(secret+m).hexdigest() == m_hash:
        return True
    return False

def main():
    known_message = 'known_message'
    known_hash = hashlib.sha1(secret+known_message).hexdigest()
    message = 'additional_message'
    shd = SHA1Extend(len(secret)+len(known_message), known_hash)
    shd.update(message)
    padded_message = known_message+shd.getPadding()+message
    padded_hash = shd.hexdigest()
    if is_valid(padded_message, padded_hash):
        print 'it works!'
        return
    print 'incorrect :('

if __name__ == "__main__":
    main()
