Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming > #3983

NEOCLASSIC (Version 1.2), An encryption scheme based largely on use of classical crypto techniques

From Mok-Kong Shen <mok-kong.shen@t-online.de>
Newsgroups comp.programming, sci.crypt.random-numbers, sci.math, sci.math.num-analysis
Subject NEOCLASSIC (Version 1.2), An encryption scheme based largely on use of classical crypto techniques
Date 2013-10-28 17:21 +0100
Organization albasani.net
Message-ID <l4m33o$qng$1@news.albasani.net> (permalink)

Cross-posted to 4 groups.

Show all headers | View raw


# NEOCLASSIC, A simple dynamic encryption scheme (with authentication) based
# largely on the straightforward use of well-known classical crypto 
techniques.

# [Note] Users who prefer to examine the proper code part directly may 
skip the
# prologue and epilogue section, there being sufficient comments 
explaining the
# code lines. The system parameters are explained in a section that 
follows the
# proper code part.


# 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
# and employs key materials having sufficient amount of entropy. 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 NEOCLASSIC at the very beginning: This software 
checks only
# that certain heuristically determined lower limits of system parameter 
values
# are satisfied. The user is himself responsible for the appropriate 
choice of
# the system parameters of NEOCLASSIC 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
# takes sufficient care to ensure the fulfillment of all other security 
measures
# (software, hardware, human) 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 the forum
# 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 (150) of its code
# lines and consequently presumably also less time required to 
understand its
# design and verify the coding for correctness and freedom from 
backdoors. In
# fact, NEOCLASSIC has been developed primarily in view of the evidently
# highly 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 universal secret
# surveillance done by certain mighty countries of the world as recently
# revealed by the apparently highly convincing reports of The Guardian, and
# months later of Le Monde, which aroused some noteworthy non-trivial 
reactions
# in France.

# NEOCLASSIC highly exploits the benefits of dynamics/variability, which the
# present author has repeatedly stressed in a number of Usenet groups 
and which
# seem to have been 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 (i.e. excepting some 
minor
# deviations for achieving e.g. higher variability) 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 session-key is not fixed) and ease of use to perform 
encryption and
# decryption of intuitively/presumably (since we can offer no 
crypto-"proof")
# equivalent, if not superior, strength (depending on entropy of 
session-key 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 arbitrary alphabet containing the decimal digits as a subset 
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 by us
# 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 etc., 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.
# The possibility of opponent's eventual access to one's computer and 
somehow
# recover the keys that had been employed should not be underestimated and
# preventive measures taken accordingly. Risks of electromagnetic 
emanations may
# eventually have to be considered as well (see R. Anderson, Security
# Engineering, chap. 15, Emission Security).


# Version 1.2, released on 24.10.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/7115671/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. Questions about programming
# details are also welcome (please use however email only and avoid usage of
# bandwidth of the forum).

# 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


# 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. Then this intermediate ciphertext
# character is subjected to a substitution with a dynamically varying 
alphabet.
# 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 (but which is albeit lacking in most other 
modern
# ciphers). As a second step, a global substitution is done via 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 is less than the value of the  parameter feedback, 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.
# (Some details deviate from the above for obtaining more 
dynamics/variability:
# The binary switches skip1 and skip2 determine runtime alternative 
computations
# of the ciphertext character and the sigma. The eventcount controls the 
time
# point of re-shuffling of the alphabet used in the substitution that 
involves
# sigma.)
#
# kn=0 for encryption, kn=1 for decryption.

def process(roundkey,textstring,kn):
   global alphabetstr,alphabet,lenalpha,lentext
   global feedback,eventthreshold
   lenalpham1=lenalpha-1
# Seed the built-in PRNG with roundkey.
   random.seed(roundkey)
# Generate an alphabet for a substitution processing of the individual 
characters,
# see below.
   substalphabet=alphabet[:]
   random.shuffle(substalphabet)
# Generate an alphabet for a global mono-alphabetical substitution, see 
below.
   cipheralphabet=alphabet[:]
   random.shuffle(cipheralphabet)
   cipheralphabetstr="".join(cipheralphabet)
# Generate an index sequence for performing transposition.
   ciphersequence=[i for i in range(lentext)]
   random.shuffle(ciphersequence)
# Initialize sigma, flip1, flip2 and eventcount.
   sigma=random.randint(0,lenalpham1)
   flip1=random.randint(0,1)
   flip2=random.randint(0,1)
   eventcount=0
   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)
       if flip1:
         gg=(idx+sigma+rr)%lenalpha
       else:
         gg=(idx+sigma-rr)%lenalpha
       newstring+=substalphabet[gg]
# Update sigma.
       if flip2:
         sigma=(sigma+idx)%lenalpha
       else:
         sigma=(sigma-idx)%lenalpha
       flip1^=idx&1
       flip2^=rr&1
# Very roughly with probability feedback/lengalpha an event is considered to
# have occurred, whereupon an event counter is updated and one PRN 
output from
# the PRNG is skipped. When the event counter reaches eventthreshold,
# substalphabet will be re-shuffled.
       if sigma<feedback:
         eventcount+=1
         skipped=random.randint(0,lenalpham1)
         flip1^=1
         flip2^=1
         if eventcount>=eventthreshold:
           random.shuffle(substalphabet)
           eventcount=0
# 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.
       uu=tmpstring[i]
       gg=substalphabet.index(uu)
       rr=random.randint(0,lenalpham1)
       if flip1:
         idx=(gg-sigma-rr)%lenalpha
       else:
         idx=(gg-sigma+rr)%lenalpha
       tt=alphabet[idx]
       newlist[ciphersequence[i]]=tt
# Update sigma.
       if flip2:
         sigma=(sigma+idx)%lenalpha
       else:
         sigma=(sigma-idx)%lenalpha
       flip1^=idx&1
       flip2^=rr&1
# See above for feedback.
       if sigma<feedback:
         eventcount+=1
         skipped=random.randint(0,lenalpham1)
         flip1^=1
         flip2^=1
         if eventcount>=eventthreshold:
           random.shuffle(substalphabet)
           eventcount=0
     newstring="".join(newlist)
# Return the result of processing of this round.
   return(newstring)


# Session-key used is a character string consisting in detail of two parts,
# secretkey and sessionkeyextension, of which only secretkey is assumed 
to be
# secret and to contain sufficient entropy (randomness) to be able to 
deliver
# the security protection required. It seeds Python's built-in PRNG to 
generate
# pseudo-random roundkeys that each has roundkeybits number of bits 
(plus some
# additional bits) for use (in their turn) as seeds for Python's 
built-in PRNG
# in the numround rounds of transposition and substitution done on 
inputstring
# by the function process(). authenblock is a block of pseudo-random 
characters
# generated to be processed together with inputstring to serve the 
purpose of
# authentication (integrity check).
#
# On encryption neoclassic() generates materials that are needed to call
# process() numround times to treat textstring, which is the inputstring
# extended by authenblock, 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.
#
# Encryption: kn=0.
# Decryption: kn=1.

def neoclassic(inputstring,kn):
   global alphabetstr,alphabet,lenalpha,lentext
   global secretkey,sessionkeyextension
   global numround,roundkeybits,roundkeyaddendbits,authenblocklen
   global feedback,eventthreshold
# Some plausibility checks with recommended limits. User is responsible for
# appropriate choice of system parameters as well as entropy in secretkey.
   if len(sessionkeyextension)==0 or numround<2 or roundkeybits<128 or \
     roundkeyaddendbits<10 or authenblocklen<30 or \
     feedback<1 or eventthreshold<1:
     print("Error: Inadmissible sessionkeyextension, numround, 
roundkeybits, "
           "roundkeyaddendbits, authenblocklen, feedback or eventthreshold")
     exit(1)
   for i in range(len(alphabetstr)):
     ch=alphabetstr[i]
     if alphabetstr.count(ch)!=1:
       print("Error in init: alphabetstr has duplicated character")
       exit(2)
   alphabet=list(alphabetstr)
   lenalpha=len(alphabet)
   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(3)
   if kn==0:
     lentext=len(inputstring)+authenblocklen
   else:
     lentext=len(inputstring)
# Seed the built-in PRNG with session-key (secretkey and 
sessionkeyextention).
   random.seed(str(secretkey)+str(sessionkeyextension))
# Generate roundkeys.
   roundkeys=[]
   for i in range(numround):
     roundkeys+=[random.getrandbits(roundkeybits)+\
     random.getrandbits(roundkeyaddendbits)]
# 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,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,kn)
# Separate out the (recovered) authentication block from the (recovered)
# plaintext.
     lastblock=textstring[-authenblocklen:]
     textstring=textstring[:-authenblocklen]
# The recovered authentication block should be identical to the 
authentication
# block (authenblock) that is obtained from computing with session-key above
# (same as what the sender does on encryption).
     if lastblock==authenblock:
       print("Authentication (integrity check) o.k.")
     else:
       print("Authentication (integrity check) failed ***************")
       exit(4)
# Return the processing result.
   return(textstring)



################################################################################



# Installation of the software.

# Both communication partners have to download the same version 3x of Python
# from http://www.python.org. The present code can be stored in a file named
# e.g. neoclassic.py and the example given further below run in Python's GUI
# IDLE. (One could also type neoclassic.py in a DOS-window.)


# Explanation of the system parameters to be defined by the communication
# partners. The limiting lower bounds below are set heuristically, taking
# considerations of the design goals of NEOCLASSIC. Appropriate choice 
of the
# system parameters is however user's own responsibility.

# numround: Number of rounds in the encryption/decryption processing, 
min. 2.

# roundkeybits: Number of bits of roundkeys to be generated from 
session-key,
#               min. 128.

# roundkeyaddendbits: Number of bits of roundkeyaddends, min. 10.
#                     (roundkeyaddends serve to add some variablity to the
#                     roundkeys.)

# authenblocklen: Number of bytes of the authentication block generated,
#                 min. 30. (In general, the larger the value, the higher 
will be
#                 the effectiveness of authentication (integrity check)).

# feedback: Measure of feedback to trigger an event (a PRNG output is then
#           skipped etc.), min. 1. See process(). (Larger values means 
stronger
#           feedback effects.)

# eventthreshold: When number of accumulated events reaches 
eventthreshold, the
#                 prefix code is regenerated, min. 1. See process().

# alphabetstr: This string defines the user-given alphabet. The 
characters in
#              alphabetstr are arbitrary but must be unique. Size of 
alphabetstr
#              is arbitrary. 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.


# Explanation of key materials to be defined by the communication partners.

# secretkey: This is to be specified as a string containing sufficient 
entropy,
#            preferably at least 128 bits. For example, it can be 32 hexs
#            obtained e.g. through throwing a number of 8-sided dice, each
#            delivering 3 bits. Or it can be an arbitrarily chosen natural
#            language (sensible or non-sensical) text string that is 
estimated
#            to possess the required entropy. secretkey to be used during a
#            certain time period could also be generated using e.g. a 
(longer
#            durated) master-key to encrypt a selected text (in some way
#            dependent on that time, for example explicitly containing the
#            period of use of the envisaged secretkey) and 
post-processing the
#            resulting ciphertext, e.g. xor-ing segments of its hexs, to 
result
#            in a key in the suitable format desired. (An hierachy of
#            master-keys could also be used, all stemming from a grand
#            master-key.) secretkey must be carefully kept secret by the
#            communication partners against diverse generes (software,
#            hardware and human) of sophisticated attacks by the opponent.

# sessionkeyextension: This is an arbitrary string, length min. 10. It 
is highly
#                      recommended to have this string different for 
different
#                      sessions, e.g. containing time, message serial number
#                      etc. It need not necessarily be kept secret. Its 
purpose
#                      is to render the effective key (resulting from its
#                      combined use with secretkey) variable across the
#                      different sessions, which is highly valuable for
#                      enhancing the security of encryption/decryption
#                      processing, since the material encryted by one 
and the
#                      same session-key available for analysis is greatly
#                      reduced thereby.


# Explanation of formal parameters of the function to be invoked for 
encryption
# and decryption.

# neoclassic(inputstring,kn)

# Encryption: inputstring is plaintext string, kn is 0. Ciphertext string is
#             returned.

# Decryption: inputstring is ciphertext string, kn is 1. Recovered plaintext
#             string is returned.



################################################################################



# The following is an (abitrarily chosen, toy) example illustrating how 
to use
# NEOCLASSIC to do encryption/decryption.

# Definition of the alphabet used.

alphabetstr="ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
             "abcdefghijklmnopqrstuvwxyz"\
             "0123456789()-?/=%&"

# System parameters agreed upon and used by both communication partners.

numround=3
roundkeybits=128
roundkeyaddendbits=10
authenblocklen=30
feedback=1
eventthreshold=3

# Sender encrypts the plaintext message and sends the ciphertext to the
# recipient.

print("Sender side:")
secretkey="4a98717c70e997c2715e87c3fa1ef559"
sessionkeyextension="HHH 24.10.2013 RJ053"
pt="nowisthetimeforallmentocometotheaidoftheircountry"
print("pt :")
print(pt)
ct=neoclassic(pt,0)
print("ct :")
print(ct)
print()

# Recipient with the same system parameters, secretkey and 
sessionkeyextension,
# 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.

print("Recipient side:")
secretkey="4a98717c70e997c2715e87c3fa1ef559"
sessionkeyextension="HHH 24.10.2013 RJ053"
print("ct :")
print(ct)
pt1=neoclassic(ct,1)
print("pt1:")
print(pt1)
print()

# Verification of correctness.

print("Identity of plaintext and recovered plaintext:",pt1[:len(pt)]==pt)


# 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, after decryption is performed, the recovered plaintext 
message 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 to a great extent, 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.

# 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 the
# existence of their encrypted message exchange (the protection being solely
# against the surveillance of the Big Brothers 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. Thus the recipient might 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.)
# Note that in certain situations the sender could simply publish the 
encrypted
# messages on his web page for the recipient to read from any neutral place,
# e.g. an Internet cafe.

# The present author has pointed out in posts to a few Usenet groups 
that one
# feasible way of principally reducing, if not eliminating, the impact of
# universal surveillance by the secret agencies would be to somehow 
achieve to
# have a sufficiently large number of common people in the world who, 
besides
# sending proper encrypted private messages as needed, send also encrypted
# irrelevant stuffs (e.g. texts from newspapers) or else constantly 
insert into
# their emails simply some fairly random lines of hexs or other 
characters that
# are barely distinguishable from genuine ciphertexts of good ciphers 
(random
# tapping on the keyboard, or better using e.g. Python's built-in PRNG to
# generate random characters from an arbitrary alphabet, see the code 
below).
# This way, since the secret agencies would suspect that at least some 
of these
# materials could eventually contain informations of vital interest to the
# goals of surveillance and thus would attempt to decrypt a substantial 
part of
# them (which they however can never succeed, since there is no 
corresponding
# plaintext at all), their computing resources, despite being of almost
# astronomical scale, would evidently be quickly exhausted.

#import random
#alphabetstr="ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
#            "abcdefghijklmnopqrstuvwxyz"\
#            "0123456789()-?/=%&"
#lenalpha=len(alphabetstr)
#def randomstr(textlength):
#  randstr=""
#  for i in range(textlength):
#    randstr+=alphabetstr[random.randint(0,lenalpha-1)]
#  print(randstr)
##We don't set seed, since we don't want/need reproducibility. Python 
uses then
##a dynamic seed, which is exactly what we require for the current 
purpose.
#randomstr(100)

# It cannot be overemphysized that risks of IT security are ubiquitous. 
A good
# cipher can only be one member of a chain of elements responsible for the
# desired secure communication and that that security is nonetheless 
lost, if
# any one of the other elements of the chain is insecure. A potential 
point of
# weakness that we like to specially call attention to is the use of 
proprietary
# (non-opensource) software, e.g. for digital signatures. For it is 
evidently
# fairly simple for the secret agencies to manage to implant backdoors 
in them,
# through coercion of the employees of the manufacturers of the software 
or by
# other means. One notes also that recently there are claims that even 
certain
# encryption algorithms that are standardized by NIST (and obviously 
because of
# the (till recently) good faith/trust in NIST have later also become ISO
# standards) might have weakness in them introduced by the secret 
agencies. It
# is deplorable that little details of the claimed weakness have been 
published
# to date.

# There was a challenge competition for the predecesssor version 1.1.1 of
# NEOCLASSIC, see http://s13.zetaboards.com/Crypto/topic/7078836/1/

Back to comp.programming | Previous | Next | Find similar | Unroll thread


Thread

NEOCLASSIC (Version 1.2), An encryption scheme based largely on use of classical crypto techniques Mok-Kong Shen <mok-kong.shen@t-online.de> - 2013-10-28 17:21 +0100

csiph-web