SharedLD-OTS.sagewsOpen in CoCalc
######################
# PoC implementation of
# Lamport-Diffie one-time signature scheme (LD-OTS)
######################

import sys

# "hash" function
def H(input):
    return R(input + 1)

# security parameter n
n = 16
print ("security parameter n =  {}".format(n))

#  0 ... 2^n - 1
R = IntegerModRing(2**n)

# random message
m = R.random_element()
print ("random message m = {}".format(m))

# message in base 2
d = Integer(m).digits(2)

# padding d
d_ = [ d.insert(0,0) for i in range(len(d),n) ]
print ("padded message d = {}".format(d))

# create secret key
# .... create 2*n random in ModRing(2**n)
X = [ R.random_element() for i in range(2*n) ]
print ("secret key X = {}, sizeof(X) = {} bytes".format(X, sys.getsizeof(X)))

# create public key
# Y[i] = X[i] + 1 modulo (2^n)
Y = [ H(X[i])  for i in range(len(X))]
print ("public key Y = {}".format(Y))

# create signature
S = [ X[i*2 + d[i]] for i in range(len(d)) ]
print ("signature S = {}, sizeof(S) = {} bytes".format(S, sys.getsizeof(S)))

# check signature
H_S = [ H(S[i])  for i in range(len(S))]

# verify signature using the public key
Y_S = [ Y[i*2 + d[i]] for i in range(len(d)) ]
print ("verfication = {}".format(H_S == Y_S))

# flip the first bit in the message
d[0] = (d[0] + 1) % 2
print ("manipulated d = {}".format(d))

# verify signature using the public key
Y_S = [ Y[i*2 + d[i]] for i in range(len(d)) ]
print ("verfication = {}".format(H_S == Y_S))

security parameter n = 16 random message m = 51262 padded message d = [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1] secret key X = [2149, 41928, 48597, 47263, 59472, 61730, 35662, 50687, 21254, 13355, 47749, 56138, 19503, 8130, 1166, 28614, 55126, 39082, 18250, 31980, 27293, 39121, 56801, 42524, 44389, 12895, 51214, 44604, 53462, 28257, 27959, 4579], sizeof(X) = 352 bytes public key Y = [2150, 41929, 48598, 47264, 59473, 61731, 35663, 50688, 21255, 13356, 47750, 56139, 19504, 8131, 1167, 28615, 55127, 39083, 18251, 31981, 27294, 39122, 56802, 42525, 44390, 12896, 51215, 44605, 53463, 28258, 27960, 4580] signature S = [2149, 47263, 61730, 50687, 13355, 56138, 19503, 1166, 55126, 18250, 27293, 42524, 44389, 51214, 28257, 4579], sizeof(S) = 200 bytes verfication = True manipulated d = [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1] verfication = False