Mok-Kong Shen
2013-07-07 17:42:05 UTC
# NEOCLASSIC, A simple versatile encryption scheme (with authentication)
based
# largely on the straightforward use of well-known classical crypto
techniques.
# Prologue:
# Having during the years designed a small number of encryption
algorithms, I
# am increasingly convinced that no practical encryption algorithm could be
# absolutely secure in the strict sense of the word and hence the quest for
# such is futile from the very beginning. In fact, there exist rather strong
# critiques [1] on the so-called proofs of crypto security. Thus what
seems to
# be desirable in practice will be the availability of a sufficiently large
# number of diverse kinds of sufficiently strong encryption algorithms that,
# when appropriately used (eventually in combinations, i.e. the so-called
# superencipherment), are intuitively safe with a satisfactory "factor of
# safety" in relationship to the power of attacks that one's opponent
# "presumably" has in hand. One is IMHO therefore defacto always doing some
# gambling in the crypto practice. But this is actually also the case
everywhere
# in real life, e.g. in the practice of medicine. In releasing the present
# software to the public, I am certainly conscious that it is definitely not
# absolutely secure but can only be hopefully practically secure, namely
when
# the user chooses sufficiently conservative values for its system
parameters.
# A deplorable dilemma I am facing as designer is however that, in
distinction
# to e.g. pharmacy, there are in crypto barely any practical tests of the
# nature of those pertaining to drugs to determine the right dosage for
# administration to the patients. Since I could hardly provide any sensible,
# ubiquitously valid, guidances to the selection of the system parameters, I
# am obliged to warn the potential user of my software at the very
beginning:
# The user is himslef responsible for the appropriate choice of the system
# parameters of the software in any actual applications.
# [1] N. Koblitz, The uneasy relationship between mathematics and
cryptology.
# Notices AMS, vol.54, 2007, pp.972-979, 1454-1456, vol.55, 2008, pp.6-7.
# NEOCLASSIC is a Python code for encryption processing that performs an
# arbitrary user-chosen number of rounds of pseudo-random transposition and
# substitution determined by a user-given session-key utilizing Python's
# built-in pseudo-random number generator (PRNG). Excepting the use of
PRNG (and
# the use of computer), everything in NEOCLASSIC is straightforward
application
# of well-known techniques in classical cryptography, hence the name of the
# scheme. It is the latest member of a set of (to date) 4 members of
encryption
# algorithms first published by the present author in
# http://s13.zetaboards.com/Crypto/index/ (the other 3 are JADE-S, JADE,
# SHUFFLE2). With appropriate setting of parameters, its strength is
considered
# to be comparable to the other members of the set. It may however be
preferred
# by the user because of the comparatively smaller number of its code
lines and
# consequently presumably also less time required to understand its
design and
# verify the coding for correctness and freedom from malicious backdoors. In
# fact, NEOCLASSIC has been developed primarily in view of the evidently
# enhanced needs of the common people to choose and employ sufficiently
strong
# encryption software to protect the privacy of their innocent
communications
# against the appallingly huge-scale international secret surveillance
done by
# certain mighty nation-states of the world as recently revealed by the
# apparently highly convincing reports of the British newspaper The
Guardian.
# It may be noted that outputs of Python't built-in PRNG are only used
# indirectly and not directly as would have been the case for streám
encryption
# processing. Further, there is processing-dependent dynamics/variability
# provided by the feedback operations (skipping of PRNs output from the
PRNG,
# see the function process()). Thus the question concerning extremely high
# quality of the PRNG being used isn't a critical one to be examined for
# applications of NEOCLASSIC in practice.
# Communication partners should ensure having installed the same version of
# Python, since NEOCLASSIC depends on Python's built-in PRNG. We like to
mention
# that, besides the evident requirement of keeping session-keys (and
preferrably
# also the chosen system parameters) secret, it may be under circumstances
# prudent (because of possible malware infections) to do
encryption/decryption
# processing exclusively on physically secure computers isolated from the
# Internet and transfer the processed materials manually, i.e. on papers, to
# computers connected to the Internet, noting possible insecurity of USB
sticks.
# Risks of electromagnetic emanations may eventually have to be
considered as
# well (see R. Anderson, Security Engineering, chap. 15, Emission Security).
# Version 1.0, released on 07.07.2013.
# Code lines of documents with the same version number are always identical.
# There may be interim modifications of comment lines. The most recent
document
# of NEOCLASSIC can be obtained from
# http://s13.zetaboards.com/Crypto/topic/7077275/1/
# This software may be freely used:
# 1. for all personal purposes unconditionally and
# 2. for all other purposes under the condition that its name, version
number
# and authorship are explicitly mentioned and that the author is
informed of
# all eventual code modifications done.
# The author is indebted to TPS for review and suggestions throughout
# NEOCLASSIC's development phase. Any remaining deficiencies of the
software are
# however the sole responsibilty of the author.
# Concrete comments and constructive critiques are sincerely solicited
either
# via the above thread or directly via email.
# Email address of the author: mok-***@t-online.de
# Loading a system module of Python that provides functionalities of its
# built-in PRNG.
import random
# The following string defines the alphabet to be used by NEOCLASSIC and
may be
# arbitrarily modified by the user, if needed. Plaintext may use a subset of
# alphabet, but ciphertext will generally involve characters of the whole
# alphabet. If space is included in alphabet, user should note that the last
# character of the ciphertext obtained may happen to be a space and
consequently
# could be easily overlooked on subsequent handling of the ciphertext.
alphabetstr="ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
"abcdefghijklmnopqrstuvwxyz"\
"0123456789()-?/=%&"
alphabet=list(alphabetstr)
lenalpha=len(alphabet)
# Perform one round of pseudo-random transposition and substitution on
# textstring with Python's built-in PRNG seeded by roundkey.
Transposition is
# done in the straightforward classical sense by Python's function
shuffle() on
# textstring. Substitution is done in two stages. First, each
character's index
# in alphabet is added by sigma and a pseudo-random value from Python's
built-in
# PRNG (modulo alphabet size). This kind of addition goes back to the
ancient
# Caesar cipher in classical cryptography. The variable sigma is initialized
# with a pseudo-random value from Python's built-in PRNG and updated
with the
# index of the character being processed as the addend, thus resulting in
# processing-dependent dynamics/variability which is beneficial for security
# (albeit lacking in most other modern ciphers). Then there is a global
# substitution with Python's function translate(), with a substitution
alphabet
# determined by Python's function shuffle(). This is mono-alphabetical
# substitution in the straightforward classical sense. Note that the varying
# value of sigma has the effect of block-chaining known in modern block
# encryption and is thus of particular significance to the performance of
# authentication achieved via the authentication block (i.e. the MAC in
modern
# crypto terminology). If the updated sigma equals feedbackval, then the
next
# PRN from the PRNG is skipped. This feedback to the PRNG provides further
# dynamics/variability that renders the cryptanalysis by the opponent hard.
def process(roundkey,textstring,feedbackval,kn):
global alphabet,lenalpha
lenalpham1=lenalpha-1
lentext=len(textstring)
random.seed(roundkey)
cipheralphabet=alphabet[:]
random.shuffle(cipheralphabet)
cipheralphabetstr="".join(cipheralphabet)
ciphersequence=[i for i in range(lentext)]
random.shuffle(ciphersequence)
sigma=random.randint(0,lenalpham1)
if kn==0:
# Begin of encryption processing for this round:
newstring=""
for i in range(lentext):
# This does transposition of the characters of textstring.
tt=textstring[ciphersequence[i]]
# This does a substitution of the individual character.
idx=alphabet.index(tt)
rr=random.randint(0,lenalpham1)
gg=(idx+sigma+rr)%lenalpha
newstring+=alphabet[gg]
# Update sigma.
sigma=(sigma+idx)%lenalpha
# Skip one PRN pseudo-randomly if sigma=feedbackval (this has a
probability of
# 1/lenalpha in case the characters in textstring are uniformly
distributed).
if sigma==feedbackval:
skipped=random.randint(0,lenalpham1)
# This does a global substitution (here from plaintext alphabet to
cipherhext
# alphabet).
transtab=newstring.maketrans(alphabetstr,cipheralphabetstr)
newstring=newstring.translate(transtab)
else:
# Begin of decryption processing for this round (reversal of encryption
# processing):
tmpstring=textstring[:]
transtab=tmpstring.maketrans(cipheralphabetstr,alphabetstr)
tmpstring=tmpstring.translate(transtab)
newlist=["" for i in range(lentext)]
for i in range(lentext):
tt=tmpstring[i]
gg=alphabet.index(tt)
rr=random.randint(0,lenalpham1)
idx=(gg-sigma-rr)%lenalpha
newlist[ciphersequence[i]]=alphabet[idx]
sigma=(sigma+idx)%lenalpha
if sigma==feedbackval:
skipped=random.randint(0,lenalpham1)
newstring="".join(newlist)
# Return the result of processing of this round.
return(newstring)
# sessionkey may be a decimal or hexadecimal integer or a character
string of
# sufficient entropy. sessionkey is used as a seed for Python's built-in
PRNG to
# generate pseudo-random roundkeys that each has roundkeybits number of
bits for
# use as seeds for Python's built-in PRNG in the numround rounds of
# transposition and substitution done on inputstring by the function
process().
# It also used to generate feedbackvals, an array of PRNs used for feedback
# operations done in the function process(). sessionkey is preferrably to be
# chosen different for different sessions (it may consist e.g. of a
fixed secret
# part of sufficient entropy and a variable session-dependent part (not
# necessarily to be guarded secret) that is determined from e.g. date, time,
# message number etc.). roundkeybits is to be appropriately chosen in
relation
# to entropy of sessionkey, i.e. too large a value for roundkeybits
relative to
# entropy of sessionkey doesn't make much sense in practice.
authenblocklen is
# the length of authenblock, which is a block of pseudo-random characters
# automatically generated by NEOCLASSIC to be processed together with
# inputstring to serve the purpose of authentication (integrity check),
see also
# comment to the function process() above.
# Encryption: kn=0.
# Decryption: kn=1.
def
neoclassic(sessionkey,numround,roundkeybits,authenblocklen,inputstring,kn):
global alphabet,lenalpha
lenalpham1=lenalpha-1
for i in range(len(inputstring)):
if inputstring[i] not in alphabet:
print("Error: inputstring contains character",\
inputstring[i],"which is not in the defined alphabet")
exit(1)
random.seed(sessionkey)
roundkeys=[]
feedbackvals=[]
for i in range(numround):
roundkeys+=[random.getrandbits(roundkeybits)]
feedbackvals+=[random.randint(0,lenalpham1)]
# Generate authentication block.
authenblock=""
for i in range(authenblocklen):
authenblock+=alphabet[random.randint(0,lenalpham1)]
if kn==0:
# Append authentication block.
textstring=inputstring+authenblock
# Encryption processing.
for i in range(numround):
textstring=process(roundkeys[i],textstring,feedbackvals[i],kn)
else:
# Decryption processing:
textstring=inputstring
for i in range(numround-1,-1,-1):
textstring=process(roundkeys[i],textstring,feedbackvals[i],kn)
# Separate out the (recovered) authentication block from the (recovered)
# plaintext.
lastblock=textstring[-authenblocklen:]
textstring=textstring[:-authenblocklen]
# The recovered authenblock (lastblock) should be identical to the
authenblock
# that is obtained from computing with sessionkey above.
if lastblock==authenblock:
print("Authentication (integrity check) o.k.")
else:
print("Authentication (integrity check) failed ***************")
exit(2)
# Return the processing result.
return(textstring)
# The following is an (abitrarily chosen, toy) example illustrating how
to use
# NEOCLASSIC to do encryption/decryption.
# The alphabet (same for sender and recipient) has been defined further
above.
# Sender defines the session-key and the other parameters and encrypts the
# plaintext pt to ciphertext ct for transmission to the recipient. (pt
chosen
# here uses only a subset of the alphabet defined further above. This
limitation
# is arbitrarily done by the sender in this particular example case and
is not
# a necessary one.) For choice of system parameters, see prologue at the
# beginning of the document.
sessionkey="sodifreruvsfuvherudf0607052"
numround=3
roundkeybits=128
authenblocklen=15
print("Sender side:")
pt="nowisthetimeforallmentocometotheaidoftheircountry"
print("pt:",pt)
ct=neoclassic(sessionkey,numround,roundkeybits,authenblocklen,pt,0)
print("ct:",ct)
print()
# Recipient defines the same (agreed-upon with sender) session-key and the
# other parameters and decrypts the received ciphertext ct to plaintext pt1.
# NEOCLASSIC automatically verifies the correctness of the
authentication block
# recovered from ct and tells whether the authentication is o.k., see
# the function neoclassic().
sessionkey="sodifreruvsfuvherudf0607052"
numround=3
roundkeybits=128
authenblocklen=15
print("Recipient side:")
print("ct:",ct)
pt1=neoclassic(sessionkey,numround,roundkeybits,authenblocklen,ct,1)
print("pt1:",pt1)
based
# largely on the straightforward use of well-known classical crypto
techniques.
# Prologue:
# Having during the years designed a small number of encryption
algorithms, I
# am increasingly convinced that no practical encryption algorithm could be
# absolutely secure in the strict sense of the word and hence the quest for
# such is futile from the very beginning. In fact, there exist rather strong
# critiques [1] on the so-called proofs of crypto security. Thus what
seems to
# be desirable in practice will be the availability of a sufficiently large
# number of diverse kinds of sufficiently strong encryption algorithms that,
# when appropriately used (eventually in combinations, i.e. the so-called
# superencipherment), are intuitively safe with a satisfactory "factor of
# safety" in relationship to the power of attacks that one's opponent
# "presumably" has in hand. One is IMHO therefore defacto always doing some
# gambling in the crypto practice. But this is actually also the case
everywhere
# in real life, e.g. in the practice of medicine. In releasing the present
# software to the public, I am certainly conscious that it is definitely not
# absolutely secure but can only be hopefully practically secure, namely
when
# the user chooses sufficiently conservative values for its system
parameters.
# A deplorable dilemma I am facing as designer is however that, in
distinction
# to e.g. pharmacy, there are in crypto barely any practical tests of the
# nature of those pertaining to drugs to determine the right dosage for
# administration to the patients. Since I could hardly provide any sensible,
# ubiquitously valid, guidances to the selection of the system parameters, I
# am obliged to warn the potential user of my software at the very
beginning:
# The user is himslef responsible for the appropriate choice of the system
# parameters of the software in any actual applications.
# [1] N. Koblitz, The uneasy relationship between mathematics and
cryptology.
# Notices AMS, vol.54, 2007, pp.972-979, 1454-1456, vol.55, 2008, pp.6-7.
# NEOCLASSIC is a Python code for encryption processing that performs an
# arbitrary user-chosen number of rounds of pseudo-random transposition and
# substitution determined by a user-given session-key utilizing Python's
# built-in pseudo-random number generator (PRNG). Excepting the use of
PRNG (and
# the use of computer), everything in NEOCLASSIC is straightforward
application
# of well-known techniques in classical cryptography, hence the name of the
# scheme. It is the latest member of a set of (to date) 4 members of
encryption
# algorithms first published by the present author in
# http://s13.zetaboards.com/Crypto/index/ (the other 3 are JADE-S, JADE,
# SHUFFLE2). With appropriate setting of parameters, its strength is
considered
# to be comparable to the other members of the set. It may however be
preferred
# by the user because of the comparatively smaller number of its code
lines and
# consequently presumably also less time required to understand its
design and
# verify the coding for correctness and freedom from malicious backdoors. In
# fact, NEOCLASSIC has been developed primarily in view of the evidently
# enhanced needs of the common people to choose and employ sufficiently
strong
# encryption software to protect the privacy of their innocent
communications
# against the appallingly huge-scale international secret surveillance
done by
# certain mighty nation-states of the world as recently revealed by the
# apparently highly convincing reports of the British newspaper The
Guardian.
# It may be noted that outputs of Python't built-in PRNG are only used
# indirectly and not directly as would have been the case for streám
encryption
# processing. Further, there is processing-dependent dynamics/variability
# provided by the feedback operations (skipping of PRNs output from the
PRNG,
# see the function process()). Thus the question concerning extremely high
# quality of the PRNG being used isn't a critical one to be examined for
# applications of NEOCLASSIC in practice.
# Communication partners should ensure having installed the same version of
# Python, since NEOCLASSIC depends on Python's built-in PRNG. We like to
mention
# that, besides the evident requirement of keeping session-keys (and
preferrably
# also the chosen system parameters) secret, it may be under circumstances
# prudent (because of possible malware infections) to do
encryption/decryption
# processing exclusively on physically secure computers isolated from the
# Internet and transfer the processed materials manually, i.e. on papers, to
# computers connected to the Internet, noting possible insecurity of USB
sticks.
# Risks of electromagnetic emanations may eventually have to be
considered as
# well (see R. Anderson, Security Engineering, chap. 15, Emission Security).
# Version 1.0, released on 07.07.2013.
# Code lines of documents with the same version number are always identical.
# There may be interim modifications of comment lines. The most recent
document
# of NEOCLASSIC can be obtained from
# http://s13.zetaboards.com/Crypto/topic/7077275/1/
# This software may be freely used:
# 1. for all personal purposes unconditionally and
# 2. for all other purposes under the condition that its name, version
number
# and authorship are explicitly mentioned and that the author is
informed of
# all eventual code modifications done.
# The author is indebted to TPS for review and suggestions throughout
# NEOCLASSIC's development phase. Any remaining deficiencies of the
software are
# however the sole responsibilty of the author.
# Concrete comments and constructive critiques are sincerely solicited
either
# via the above thread or directly via email.
# Email address of the author: mok-***@t-online.de
# Loading a system module of Python that provides functionalities of its
# built-in PRNG.
import random
# The following string defines the alphabet to be used by NEOCLASSIC and
may be
# arbitrarily modified by the user, if needed. Plaintext may use a subset of
# alphabet, but ciphertext will generally involve characters of the whole
# alphabet. If space is included in alphabet, user should note that the last
# character of the ciphertext obtained may happen to be a space and
consequently
# could be easily overlooked on subsequent handling of the ciphertext.
alphabetstr="ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
"abcdefghijklmnopqrstuvwxyz"\
"0123456789()-?/=%&"
alphabet=list(alphabetstr)
lenalpha=len(alphabet)
# Perform one round of pseudo-random transposition and substitution on
# textstring with Python's built-in PRNG seeded by roundkey.
Transposition is
# done in the straightforward classical sense by Python's function
shuffle() on
# textstring. Substitution is done in two stages. First, each
character's index
# in alphabet is added by sigma and a pseudo-random value from Python's
built-in
# PRNG (modulo alphabet size). This kind of addition goes back to the
ancient
# Caesar cipher in classical cryptography. The variable sigma is initialized
# with a pseudo-random value from Python's built-in PRNG and updated
with the
# index of the character being processed as the addend, thus resulting in
# processing-dependent dynamics/variability which is beneficial for security
# (albeit lacking in most other modern ciphers). Then there is a global
# substitution with Python's function translate(), with a substitution
alphabet
# determined by Python's function shuffle(). This is mono-alphabetical
# substitution in the straightforward classical sense. Note that the varying
# value of sigma has the effect of block-chaining known in modern block
# encryption and is thus of particular significance to the performance of
# authentication achieved via the authentication block (i.e. the MAC in
modern
# crypto terminology). If the updated sigma equals feedbackval, then the
next
# PRN from the PRNG is skipped. This feedback to the PRNG provides further
# dynamics/variability that renders the cryptanalysis by the opponent hard.
def process(roundkey,textstring,feedbackval,kn):
global alphabet,lenalpha
lenalpham1=lenalpha-1
lentext=len(textstring)
random.seed(roundkey)
cipheralphabet=alphabet[:]
random.shuffle(cipheralphabet)
cipheralphabetstr="".join(cipheralphabet)
ciphersequence=[i for i in range(lentext)]
random.shuffle(ciphersequence)
sigma=random.randint(0,lenalpham1)
if kn==0:
# Begin of encryption processing for this round:
newstring=""
for i in range(lentext):
# This does transposition of the characters of textstring.
tt=textstring[ciphersequence[i]]
# This does a substitution of the individual character.
idx=alphabet.index(tt)
rr=random.randint(0,lenalpham1)
gg=(idx+sigma+rr)%lenalpha
newstring+=alphabet[gg]
# Update sigma.
sigma=(sigma+idx)%lenalpha
# Skip one PRN pseudo-randomly if sigma=feedbackval (this has a
probability of
# 1/lenalpha in case the characters in textstring are uniformly
distributed).
if sigma==feedbackval:
skipped=random.randint(0,lenalpham1)
# This does a global substitution (here from plaintext alphabet to
cipherhext
# alphabet).
transtab=newstring.maketrans(alphabetstr,cipheralphabetstr)
newstring=newstring.translate(transtab)
else:
# Begin of decryption processing for this round (reversal of encryption
# processing):
tmpstring=textstring[:]
transtab=tmpstring.maketrans(cipheralphabetstr,alphabetstr)
tmpstring=tmpstring.translate(transtab)
newlist=["" for i in range(lentext)]
for i in range(lentext):
tt=tmpstring[i]
gg=alphabet.index(tt)
rr=random.randint(0,lenalpham1)
idx=(gg-sigma-rr)%lenalpha
newlist[ciphersequence[i]]=alphabet[idx]
sigma=(sigma+idx)%lenalpha
if sigma==feedbackval:
skipped=random.randint(0,lenalpham1)
newstring="".join(newlist)
# Return the result of processing of this round.
return(newstring)
# sessionkey may be a decimal or hexadecimal integer or a character
string of
# sufficient entropy. sessionkey is used as a seed for Python's built-in
PRNG to
# generate pseudo-random roundkeys that each has roundkeybits number of
bits for
# use as seeds for Python's built-in PRNG in the numround rounds of
# transposition and substitution done on inputstring by the function
process().
# It also used to generate feedbackvals, an array of PRNs used for feedback
# operations done in the function process(). sessionkey is preferrably to be
# chosen different for different sessions (it may consist e.g. of a
fixed secret
# part of sufficient entropy and a variable session-dependent part (not
# necessarily to be guarded secret) that is determined from e.g. date, time,
# message number etc.). roundkeybits is to be appropriately chosen in
relation
# to entropy of sessionkey, i.e. too large a value for roundkeybits
relative to
# entropy of sessionkey doesn't make much sense in practice.
authenblocklen is
# the length of authenblock, which is a block of pseudo-random characters
# automatically generated by NEOCLASSIC to be processed together with
# inputstring to serve the purpose of authentication (integrity check),
see also
# comment to the function process() above.
# Encryption: kn=0.
# Decryption: kn=1.
def
neoclassic(sessionkey,numround,roundkeybits,authenblocklen,inputstring,kn):
global alphabet,lenalpha
lenalpham1=lenalpha-1
for i in range(len(inputstring)):
if inputstring[i] not in alphabet:
print("Error: inputstring contains character",\
inputstring[i],"which is not in the defined alphabet")
exit(1)
random.seed(sessionkey)
roundkeys=[]
feedbackvals=[]
for i in range(numround):
roundkeys+=[random.getrandbits(roundkeybits)]
feedbackvals+=[random.randint(0,lenalpham1)]
# Generate authentication block.
authenblock=""
for i in range(authenblocklen):
authenblock+=alphabet[random.randint(0,lenalpham1)]
if kn==0:
# Append authentication block.
textstring=inputstring+authenblock
# Encryption processing.
for i in range(numround):
textstring=process(roundkeys[i],textstring,feedbackvals[i],kn)
else:
# Decryption processing:
textstring=inputstring
for i in range(numround-1,-1,-1):
textstring=process(roundkeys[i],textstring,feedbackvals[i],kn)
# Separate out the (recovered) authentication block from the (recovered)
# plaintext.
lastblock=textstring[-authenblocklen:]
textstring=textstring[:-authenblocklen]
# The recovered authenblock (lastblock) should be identical to the
authenblock
# that is obtained from computing with sessionkey above.
if lastblock==authenblock:
print("Authentication (integrity check) o.k.")
else:
print("Authentication (integrity check) failed ***************")
exit(2)
# Return the processing result.
return(textstring)
# The following is an (abitrarily chosen, toy) example illustrating how
to use
# NEOCLASSIC to do encryption/decryption.
# The alphabet (same for sender and recipient) has been defined further
above.
# Sender defines the session-key and the other parameters and encrypts the
# plaintext pt to ciphertext ct for transmission to the recipient. (pt
chosen
# here uses only a subset of the alphabet defined further above. This
limitation
# is arbitrarily done by the sender in this particular example case and
is not
# a necessary one.) For choice of system parameters, see prologue at the
# beginning of the document.
sessionkey="sodifreruvsfuvherudf0607052"
numround=3
roundkeybits=128
authenblocklen=15
print("Sender side:")
pt="nowisthetimeforallmentocometotheaidoftheircountry"
print("pt:",pt)
ct=neoclassic(sessionkey,numround,roundkeybits,authenblocklen,pt,0)
print("ct:",ct)
print()
# Recipient defines the same (agreed-upon with sender) session-key and the
# other parameters and decrypts the received ciphertext ct to plaintext pt1.
# NEOCLASSIC automatically verifies the correctness of the
authentication block
# recovered from ct and tells whether the authentication is o.k., see
# the function neoclassic().
sessionkey="sodifreruvsfuvherudf0607052"
numround=3
roundkeybits=128
authenblocklen=15
print("Recipient side:")
print("ct:",ct)
pt1=neoclassic(sessionkey,numround,roundkeybits,authenblocklen,ct,1)
print("pt1:",pt1)