Drexel dragonThe Math ForumDonate to the Math Forum



Search All of the Math Forum:

Views expressed in these public forums are not endorsed by Drexel University or The Math Forum.


Math Forum » Discussions » sci.math.* » sci.math

Topic: NEOCLASSIC, An encryption scheme based largely on use of well-known
classical crypto techniques

Replies: 0  

Advanced Search

Back to Topic List Back to Topic List  
Mok-Kong Shen

Posts: 535
Registered: 12/8/04
NEOCLASSIC, An encryption scheme based largely on use of well-known
classical crypto techniques

Posted: Jul 23, 2013 8:45 AM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply


Attached below is the code of my encryption software NEOCLASSIC
Version 1.1.1. Currently there is a challenge competition for it
with a prize to be won, see:

http://s13.zetaboards.com/Crypto/topic/7078836/1/

M. K. Shen

---------------------------------------------------------------------

# 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 (preferably also easy for
# the common users to understand, verify and use) encryption algorithms
that,
# when appropriately employed (eventually in combinations, i.e. with
different
# ciphers working in tandem), 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 users of my software at the very
beginning:
# The user is himslef responsible for the appropriate choice of the system
# parameters of this software in any actual applications. On the other hand,
# it is intuitively clear that higher values of the system parameters chosen
# should, in general, imply higher security, assuming that the user also
take
# sufficient care to ensure the fulfillment of all other security measures
# that are required in practice of the applications in which NEOCLASSIC is
# selected to be utilised.

# [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 (95
# Python 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 countries of the world as
recently
# revealed by the apparently highly convincing reports of the British
newspaper
# The Guardian.

# NEOCLASSIC highly exploits the benefits of dynamics/variability, which the
# present author repeatedly stressed in a number of Usenet groups and which
# seem to be largely ignored in the design of most modern ciphers.

# Details of how the code parts work are given in the comment lines
preceding
# the respective functions further below. Here we present for the
convenience of
# those users who may prefer to postpone a detailed examination of the
code for
# a later time a brief sketch of what is in essence done in one round on
# encryption, namely in the function process(), neglecting, initially,
for ease
# of explanation, the authentication block:
#
# Perform a pseudo-random transposition of the given plaintext characters.
#
# With a variable sigma (initialized pseudo-randomly) do to each plaintext
# character the following:
#
# 1. Find the index (idx) of that plaintext character in the alphabet.
# 2. Generate a pseudo-random number (rr).
# 3. Determine the "intermediate" ciphertext character corresponding
to the
# index gg in the alphabet, with gg=(idx+sigma+rr) (modulo alphabet
# size), i.e. one does a "shift" of amount sigma+rr as is done in the
# ancient Caesar cipher (our shift is albeit not a constant value but
# pseudo-random).
# 4. Update sigma according to sigma=sigma+idx (modulo alphabet
size), i.e.
# sigma gets an addend idx, which is a value (dynamically)
dependent on
# the plaintext character that has just been processed.
#
# Perform a mono-alphabetical substitution on all the intermediate
ciphertext
# characters, yielding the ciphertext characters (to be similarly
processed in
# the next following round, if there is one).
#
# For purpose of authentication we extend the user-given plaintext with
a number
# of characters that are pseudo-randomly generated (termed the
authentication
# block). It is the thus extended plaintext that is actually subjected
to the
# kind of processing described above. Due to sigma, the processing of one
# character has influence on the processing of the next following one. Thus,
# additionally owing to the transpositions done in the number of rounds, the
# final ciphertext resulted is such that each character is highly correlated
# (the very opposite of being independent) with all the others. It is not
# difficult to see that, conversely, in case the ciphertext characters that
# correspond to the user-given plaintext are somehow manipulated/altered
by the
# opponent, the authentication block recovered on decryption by the
recipient
# will (with a very high probability) not be identical to the authentication
# block that the sender generates on encryption. In this way we achieve our
# intended goal of authentication (integrity check), the necessity of which,
# we note, is often neglected/underestimated in practical applications of
# cryptography.

# The function to be invoked by the user for encryption/decryption is
# neoclassic(). An example given further below illustrates its usage.

# Competition with established modern ciphers in processing speed is
from the
# very beginning not a design goal of NEOCLASSIC (since message volumes of
# communications of common people (who are our targeted users) are as a rule
# fairly limited anyway and hence the difference in processing times
would be
# entirely negligible) but rather in ease of code understanding and
verification
# and in flexibility (of specification of system parameters, note also
that the
# length of sessionkey is not fixed) and ease of use to perform
# encryption/decryption of intuitively/presumably (since we can offer no
# crypto-"proof") equivalent, if not superior, strength (depending on
entropy
# of sessionkey and choice of system parameters).

# Although the author has only tested (with Python 3.3.2) the software
on texts
# in English, there seems to be no reason why NEOCLASSIC shouldn't well
function
# on texts in other languages that have an alphabet. For Chinese, use of the
# Unicode or telegraphic codes to transcribe the logograms into decimal
digits
# and an alphabet for English appears to be a viable possibility for
employing
# NEOCLASSIC in practical applications.

# 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 stream
encryption
# processing. (In stream encryption, outputs of a PRNG are xor-ed with the
# plaintext characters to result in the ciphertext characters, such
that, if a
# segment of the plaintext happens to be known to the analyst via some
means, he
# would know the corresponding outputs of the PRNG with which he could then
# eventually manage to determine the parameters of the PRNG and thus to
decrypt
# the rest of the ciphertext.) 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
preferably
# 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.1.1, released on 15.07.2013. Comment lines updated on
18.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/ or from the author.


# 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-kong.shen@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 (altered, shortened or lengthened) by the user, if
# needed. Plaintext may only use a subset of alphabet, but ciphertext
will as
# a rule nonetheless involve the entire set of characters in 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 defined.
alphabet=list(alphabetstr)

# Alphabet size.
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.
# process() is called by neocalssic() (which is directly invoked by the
user)
# numround times.

def process(roundkey,textstring,feedbackval,kn):
global alphabet,lenalpha,lentext
lenalpham1=lenalpha-1
# Seed the built-in PRNG with roundkey.
random.seed(roundkey)
# Generate cipheralphabet.
cipheralphabet=alphabet[:]
random.shuffle(cipheralphabet)
cipheralphabetstr="".join(cipheralphabet)
# Generate index sequence for performing transposition.
ciphersequence=[i for i in range(lentext)]
random.shuffle(ciphersequence)
# Initialize sigma.
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
ciphertext
# alphabet, a mono-alphabetical substitution).
transtab=newstring.maketrans(alphabetstr,cipheralphabetstr)
newstring=newstring.translate(transtab)
else:
# Begin of decryption processing for this round (reversal of encryption
# processing):
# This reverses the global substitution.
tmpstring=textstring[:]
transtab=tmpstring.maketrans(cipheralphabetstr,alphabetstr)
tmpstring=tmpstring.translate(transtab)
newlist=["" for i in range(lentext)]
for i in range(lentext):
# This reverses the substitution of the individual character.
tt=tmpstring[i]
gg=alphabet.index(tt)
rr=random.randint(0,lenalpham1)
idx=(gg-sigma-rr)%lenalpha
newlist[ciphersequence[i]]=alphabet[idx]
# Update sigma.
sigma=(sigma+idx)%lenalpha
# Skip one PRN pseudo-randomly if sigma=feedbackval.
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 preferably 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. In general, the larger the
value of
# authenblocklen chosen, the higher will be the effectiveness of
authentication.
#
# neoclassic() is the function to be directly invoked by the user for
encryption
# and decryption. On encryption neoclassic() generates materials that
are needed
# to call process() numround times to treat textstring, which is the
inputstring
# extended by authentication block, and performs a final transposition
of the
# characters (which renders the scheme more symmetrical with respect to
# transpositions and should also enhance its strength). On decryption these
# steps are reversed in the opposite order, with check of correctness of the
# decrypted authentication block for ensuring the integrity of the
ciphertext
# during transmission from the sender to the recipient. Note that, as
stated in
# the prologue, the appropriate choice of the parameter values is user's
# responsibility and so there is no check excepting the trivial one for
# authenblocklen.
#
# Encryption: set kn=0.
# Decryption: set kn=1.

def
neoclassic(sessionkey,numround,roundkeybits,authenblocklen,inputstring,kn):
global alphabet,lenalpha,lentext
if authenblocklen<=0:
print("Error: No authentication block")
exit(1)
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)
if kn==0:
lentext=len(inputstring)+authenblocklen
else:
lentext=len(inputstring)
# Seed the built-in PRNG with sessionkey.
random.seed(sessionkey)
# Generate the arrays roundkeys and feedbackvals.
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)]
# Generate index sequence for performing the final transposition (on
# encryption).
finaltranspsequence=[i for i in range(lentext)]
random.shuffle(finaltranspsequence)
if kn==0:
# Encryption processing.
# Append authentication block.
textstring=inputstring+authenblock
# Perform numround rounds of encryption processing.
for i in range(numround):
textstring=process(roundkeys[i],textstring,feedbackvals[i],kn)
# Perform final transposition.
tmpstring=textstring[:]
textstring=""
for i in range(lentext):
textstring+=tmpstring[finaltranspsequence[i]]
else:
# Decryption processing:
# This reverses the final transposition done on encryption.
tmpstring=inputstring[:]
newlist=["" for i in range(lentext)]
for i in range(lentext):
newlist[finaltranspsequence[i]]=tmpstring[i]
textstring="".join(newlist)
# Perform numround rounds of decryption processing.
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 authentication block (lastblock) should be identical to the
# authentication block (authenblock) that is obtained from computing with
# sessionkey above (similar to what sender does on encryption).
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.) Concerning 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)

# If the plaintext message to be encrypted is in an external file (last line
# preferably without 'return'), it can be read into pt with:
# f=open("messagetobesent.txt","r"))
# pt=f.read()
# f.close()
# Similarly the received plaintext message (after decryption is
performed) can
# be stored into an external file from pt1 with:
# f=open("messagereceived.txt","w")
# f.write(pt1)
# f.close()



# Epilogue:

# In order to maximize the ease of examination as well as undestanding
of the
# code by the majority of our targeted users, we have opted to reduce the
# complexity of the design as far as feasible, relying on the fact that
there
# is in any case always the possiblity available to the user to arbitrarily
# tune to his desire the strength of protection by NEOCLASSIC throgh a
# corresponding appropriate choice of the system parameters, e.g. the
value of
# numrounds, without thereby seriously effecting its acceptance in issues of
# processing efficiency in practice. Thus, for example, in the
substitution of
# the individual character (see process()) we employ the normal alphabet
instead
# of a shuffled alphabet and we apply also a mono-alphabetical substitution
# instead of a poly-alphabetical substitution at the end of each round.
(User
# having good experiences in programming may like to perform such
modifications
# to NEOCLASSIC, albeit on his own responsibility.)

# If both sender and recipient are in genuinely democratic countries and
hence
# there is no problem at all arising from any third person's knowing of
their
# encrypted message transfer (the protection being solely against the
# surveillance of the Big Brother of the Internet), then the ciphertext
could be
# simply sent via email as usual. Otherwise, as I recently argued in
some Usenet
# groups, use of facilities of the genre of remailer or Tor is risky
anyway for
# the sender. For his email carries his own IP address (which cannot be
faked)
# and hence the agencies could efficiently obtain his identity by
tapping at the
# entrance of the remailer or Tor network, to which his email is being
sent. In
# such situations the best solution is to post the ciphertext (encrypted at
# home) to a Usenet group like alt.anonymous.messages from a call shop or
# internet cafe (utilising the facility available there to access the Usenet
# group, thus not involving one's own IP address, nor email address). The
# recipient can collect the ciphertext similarly and decrypt it (at home) to
# obtain the plaintext. In order that the recipient could uniquely
identify the
# post of the sender, a chosen pseudonym and/or some special plaintext
string in
# the subject line of the post may not always be sufficient, because other
# posters may by chance or for other reasons employ the same distinguishing
# feature. So the recipient may under circumstances have to pick up also a
# number of posts that are not from his partner and later discard these
(after
# failing to decrypt them properly with the agreed-upon session key).
One method
# of avoiding this is to encrypt something agreed upon (which may be
dynamically
# varying) and use the corresponding ciphertext as the subject line for
posting
# to the Usenet group. (The cipher for obtaining the subject line need not
# necessarily be one of very high quality, since the purpose is solely to
# perform an arbitrary transformation for purpose of distinguishing, though
# users of NEOCLASSIC could certainly conveniently do the subject line
# encryption processing with NEOCLASSIC as well. Its key should however
# preferably be one different from the session key that is used to
encrypt the
# message proper.) It goes without saying that in non-democratic
countries there
# may be agents doing observations in call shops or internet cafes and the
# communication partners have to take the potential risks duly into account.
# (A Usenet post claimed that in one West-European country customers of call
# shops or internet cafes must show their identities on entrance. The
present
# author unfortunately could currently neither verify that claim nor
have good
# ideas of eliminating risks arising from such control.)



Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© Drexel University 1994-2014. All Rights Reserved.
The Math Forum is a research and educational enterprise of the Drexel University School of Education.