Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.programming > #3623
| From | Mok-Kong Shen <mok-kong.shen@t-online.de> |
|---|---|
| Newsgroups | comp.programming |
| Subject | NEOCLASSIC, An encryption scheme based largely on use of well-known classical crypto techniques |
| Date | 2013-07-11 11:41 +0200 |
| Organization | albasani.net |
| Message-ID | <krlukd$js2$1@news.albasani.net> (permalink) |
# 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 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.
# 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") of equivalent, if not superior, strength (depending on
choice
# of system parameters) in practice.
# Although the author has only tested (with Python 3.2.3) 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. 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.0, released on 07.07.2013. Comment lines last updatd on
11.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-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
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
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):
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 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. neoclassic() is the function
to be
# directly invoked by the user for encryption/decryption.
# Encryption: set kn=0.
# Decryption: set 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.) 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()
Back to comp.programming | Previous | Next — Next in thread | Find similar | Unroll thread
NEOCLASSIC, An encryption scheme based largely on use of well-known classical crypto techniques Mok-Kong Shen <mok-kong.shen@t-online.de> - 2013-07-11 11:41 +0200 Re: NEOCLASSIC, An encryption scheme based largely on use of well-known classical crypto techniques Mok-Kong Shen <mok-kong.shen@t-online.de> - 2013-07-23 14:22 +0200
csiph-web