# Python Code Skeleton
# Prepared for: 6.857 PS2
# Last Modified: 9/18/06
#
# Desc:
# Highlights how to use a stack and calculate/compare
# k^th truncated SHA=256 hash values.

# import hash module (requires Python 2.5)
import hashlib


# define our stack variable
stack = []


# SIMPLE STACK USAGE
print "Simple Stack Usage:\n"

# push some values
stack.append("first push")
stack.append("second push")

# print the stack size
print "stack size:", len(stack)

# pop the values
first_pop = stack.pop()
second_pop = stack.pop()

# print what just happened
print "first pop:",first_pop
print "second pop:",second_pop
print "new size:",len(stack)

print "\n"



# SIMPLE SHA-256 HASH FUNCTION USAGE 
#
# Here we calculate the first x values in a hash chain sequence.
# 
print "Fun With Hashes:\n"

iVal = "Sample initial value"

nextVal = iVal
prettyNextVal = iVal


# We can loop x times printing out links in our chain
# of hash values.
# Notice that we declare a new sha object each time.
# Keeping the same SHA object and continually calling update()
# would have the effect of calculating the digest of the concatenation
# of all values updated so far...not what we want!
#
# set printMode = 0 if you want out the output in hex numbers,
# set printMode = 1 if you want the program to dump raw bytes with \n
#                   between each unique hash digest
# set printMode = 2 if you want the program to dump the raw bytes,
#                   as in 1 but also include the ascii bytes for "[VAL: x ] "
#                    at the beginning of each new hash digest

x = 4
printMode = 0


print "Starting with initial value [",nextVal,"] and hashing",x,"times.\n"

for i in range(x):
    currVal = nextVal
    prettyCurrVal = prettyNextVal
    hasher = hashlib.sha256(currVal)
    nextVal = hasher.digest()
    prettyNextVal = hasher.hexdigest()

    # print
    if printMode == 0:
        print prettyCurrVal,"--->", prettyNextVal
    elif printMode == 1:
        print nextVal
    else:
        print "[VAL:",i+1,"]", nextVal

print "\n"

# Comparing only the first k bits of two hash values
# Here we require that k mod 4 = 0 so that our division
# is clean.

k = 20
hexDigits = k/4

hash1 = hashlib.sha256("random input 1");
hash2 = hashlib.sha256("random input 2");
hash3 = hashlib.sha256("random input 1");

# compare k^th truncated hash of hash1 and hash2
print "Comparing first",k,"bits of", hash1.hexdigest(), "to",hash2.hexdigest()
if hash1.hexdigest()[0:hexDigits] == hash2.hexdigest()[0:hexDigits]:
    print "Equal.\n"
else:
    print "Not Equal.\n"

# compare k^th truncated hash of hash1 and hash3
print "Comparing first",k,"bits of", hash1.hexdigest(), "to",hash3.hexdigest()
if hash1.hexdigest()[0:hexDigits] == hash3.hexdigest()[0:hexDigits]:
    print "Equal.\n"
else:
    print "Not Equal.\n"


