Encryption with Python

K

Kamilche

I've looked at a few alternatives for encryption with Python, and
didn't come up anything very speedy.

I've written an encryption algorithm in pure Python that can process
22 megs of data a second. I know it's not secure, but it should be
enough to ward off casual hacking. Does someone know of something
speedier?

--Kamilche
 
E

Erik Max Francis

Kamilche said:
I've looked at a few alternatives for encryption with Python, and
didn't come up anything very speedy.

I've written an encryption algorithm in pure Python that can process
22 megs of data a second. I know it's not secure, but it should be
enough to ward off casual hacking. Does someone know of something
speedier?

If you're only concerned with warding off casual hacking, and speed is
your maximal concern, why not just XOR each byte with 0xFF or something
equally brainless?
 
P

Paul Rubin

I've written an encryption algorithm in pure Python that can process
22 megs of data a second. I know it's not secure, but it should be
enough to ward off casual hacking. Does someone know of something
speedier?

Yes, you can just copy the input to the output. That's quite fast,
and it's at least as insecure as your method.
 
P

Peter Hansen

Kamilche said:
I've looked at a few alternatives for encryption with Python, and
didn't come up anything very speedy.

I've written an encryption algorithm in pure Python that can process
22 megs of data a second. I know it's not secure, but it should be
enough to ward off casual hacking. Does someone know of something
speedier?

In addition to Erik and Paul's comments: if you don't specify
what machine you ran your benchmark on, the number "22MB/s" is
completely meaningless...

Besides, what you say is not possible. On my machine,
which is about a P4 2500MHz, scanning an array.array('c') with
22MB of data in it, doing nothing but reading each byte and
ignoring it, takes about 8 seconds. So does converting the
array to a list, which is pretty much all C code. Strings
are immutable, so you can't be working with one of them...

Doing anything meaningful with real data, no matter how trivial
the algorithm, would definitely take longer.

-Peter
 
P

Paul Rubin

Peter Hansen said:
Besides, what you say is not possible. On my machine,
which is about a P4 2500MHz, scanning an array.array('c') with
22MB of data in it, doing nothing but reading each byte and
ignoring it, takes about 8 seconds. So does converting the
array to a list, which is pretty much all C code. Strings
are immutable, so you can't be working with one of them...

Well, you could do 32-bit operations which are maybe 4x faster.
You could maybe get even more speedup using built-in C functions.
For example, you could do rot13 encryption with the string.translate
method which should be quite fast. FWIW,

http://www.nightsong.com/phr/crypto/p3.py

should be quite secure, and should run at least 1 mbyte/sec on your
p4/2500, maybe quite a bit more.
 
P

Peter Hansen

Paul said:
Well, you could do 32-bit operations which are maybe 4x faster.
You could maybe get even more speedup using built-in C functions.
For example, you could do rot13 encryption with the string.translate
method which should be quite fast.

Both are good ideas, but I made an assumption that I was starting
with a simple 22MB string, and the cost of converting that to 32-bit
(presumably using array.array still?) would have to be taken into
account, for fairness. I also assume Kamilche wasn't talking
about using the builtin rot13, since he claimed to have written
this himself...

-Peter
 
P

Paul Rubin

Peter Hansen said:
Both are good ideas, but I made an assumption that I was starting
with a simple 22MB string, and the cost of converting that to 32-bit
(presumably using array.array still?) would have to be taken into
account, for fairness. I also assume Kamilche wasn't talking
about using the builtin rot13, since he claimed to have written
this himself...

There's no special conversion needed, just use array.array('L', whatever)
instead of array.array('B', whatever), if I remember right.
 
P

Peter Hansen

There's no special conversion needed, just use array.array('L', whatever)
instead of array.array('B', whatever), if I remember right.

Cool! I didn't realize you could initialize effectively any
array object from a string as well as a list. Never too late
to read the docs... :)

-Peter
 
K

Kamilche

Peter Hansen said:
Besides, what you say is not possible. On my machine,
which is about a P4 2500MHz, scanning an array.array('c') with
22MB of data in it, doing nothing but reading each byte and
ignoring it, takes about 8 seconds. So does converting the
array to a list, which is pretty much all C code. Strings
are immutable, so you can't be working with one of them...

Doing anything meaningful with real data, no matter how trivial
the algorithm, would definitely take longer.

But I DON'T manipulate the data byte by byte, only the encryption
tables.
Ah, the power of algorithms! ;-)
Take a look at this:

def encrypt(s, offset = 0, _tables = []):
' Encrypt or decrypt a string'
cnt = len(_tables)
if cnt == 0:
# Initialize static variable _tables
# Increase 'cnt' to prevent recurring patterns.
import random
cnt = 10
random.seed(257)
for i in range(cnt):
marked, table, max = [], [], 256
for j in range(max):
table.append(chr(j))
marked.append(False)
marked[0] = True
marked[255] = True
for j in range(max):
if not marked[j]:
while 1:
c = random.randint(0, 255)
if marked[c] == False:
table[j], table[c] = table[c], table[j]
marked[c] = True
marked[j] = True
break
_tables.append(''.join(table))

# Tables initialized - encrypt the data.
return s.translate(_tables[offset % cnt])

s = "This is a standard length string to encrypt."
print "\nYou need to specify an offset to avoid patterns."
print "The string is:", s
print "\nEncrypted with offsets, you get:"
for i in range(5):
print "\t", encrypt(s, i)
print "\nEncrypted without offsets, you get:"
for i in range(5):
print "\t", encrypt(s)


Most XOR algorithms could benefit from using this technique. There's
never a need to XOR a byte more than once, while building the table.
From then on, it's a simple substitution problem, which the
'translate' function accomplishes quite nicely.
 
L

Lev Elblert

Kamilche!

I'm also puzzeld with your results. Here is a little test script,
which generates 16mb array and scans it.

import time
s = 'C'
print time.clock()
for i in range(24): s += s
print len(s)
print time.clock()
for c in s: pass
print time.clock()

When I run it on 500mg P3 the output is:

8.38095110386e-006
16777216
0.275403081843
10.9032218052

on 1.6 P4 it runs 4 seconds.

I'm new to Python and learnig it. Can't you publish the code? If the
crypto method you are using is a secret, please give the basic idea,
how did you achived such a speed.
 
P

Peter Hansen

Kamilche said:
But I DON'T manipulate the data byte by byte, only the encryption
tables.
[snip code]

Very interesting use of translate. I doubt anyone, certainly
not I, guessed that's what you were using. Kudos! (though it
certainly fits your description of "not secure", but it's
admittedly a step up from XOR).

-Peter
 
K

Kamilche

Peter Hansen said:
Very interesting use of translate. I doubt anyone, certainly
not I, guessed that's what you were using. Kudos!

I'm glad you enjoyed it!
{unwraps and eats her first Python kudos bar.}
 
T

Till Plewe

Kamilche wrote:
....

In addition to Erik and Paul's comments: if you don't specify
what machine you ran your benchmark on, the number "22MB/s" is
completely meaningless...

Besides, what you say is not possible. On my machine,
which is about a P4 2500MHz, scanning an array.array('c') with
22MB of data in it, doing nothing but reading each byte and
ignoring it, takes about 8 seconds.
So does converting the
array to a list, which is pretty much all C code.

are you sure it takes 8s?
0.681946992874

That is over ten times faster than your machine. I cannot
believe that. I use
Python 2.3.4 (#2, Jun 24 2004, 13:32:58)
[GCC 3.3.3 [FreeBSD] 20031106] on freebsd5
CPU: AMD Opteron(tm) Processor 248 (2205.01-MHz K8-class CPU)
.... s=time()
.... for i in r:
.... A^=7877854
.... t=time()
.... print t-s
....
1.80496907234
So with a 4Ghz Opteron (or better) he should be able to xor
a 22MB array in one second with some constant.

- Till
 
P

Peter Hansen

Till said:
are you sure it takes 8s?

What I meant (but didn't state explicitly) was that even if you
convert the string to a list of 23068672 individual characters,
scanning the list takes about as long as scanning the array
did.

And not only did I not say all that, but what I did say I
even said wrong, since I notice I said "array to list"
instead of "string to list".

Basically, I've been totally wrong in everything I said
in this thread. ;-)

-except-this-post-ly y'rs,
Peter
 
?

=?iso-8859-15?Q?Pierre-Fr=E9d=E9ric_Caillaud?=

Blowfish encryption is very secure (128 bits) and very fast (10
megabytes/s on a Celeron 400).
I used that, you could try it.
 
I

Ivan Voras

Pierre-Frédéric Caillaud said:
Blowfish encryption is very secure (128 bits) and very fast (10
megabytes/s on a Celeron 400).
I used that, you could try it.

Is that for the python implementation or a C one? :))
 
T

Till Plewe

Peter Hansen said:
Besides, what you say is not possible. On my machine,
which is about a P4 2500MHz, scanning an array.array('c') with
22MB of data in it, doing nothing but reading each byte and
ignoring it, takes about 8 seconds. So does converting the
array to a list, which is pretty much all C code. Strings
are immutable, so you can't be working with one of them...

Doing anything meaningful with real data, no matter how trivial
the algorithm, would definitely take longer.

But I DON'T manipulate the data byte by byte, only the encryption
tables.
Ah, the power of algorithms! ;-)
Take a look at this:

def encrypt(s, offset = 0, _tables = []):
....
# Tables initialized - encrypt the data.
return s.translate(_tables[offset % cnt])

I apologize for my previous post (of course I don't know when it will
actually show up). The only rather weak excuse I have is that I have
spent my entire last month using nothing but C. (Of course, the real
culprit is www.python.org for not sending your message above earlier).

In any case I still have one or two comments.

I think it is not quite "the power of algorithms" but rather making
good use of the speed of string.translate which makes your encryption
function fast. string.translate allows you to use a loop programmed in
C rather than a loop you have to program yourself in python.

If you are happy xoring then there is an even faster method: use
numarray. For me xoring a numarray.array is twice as fast as
string.translate is on the corresponding string for UInt8 arrays and
four times as fast for UInt64 arrays. (But adding the two conversions
between strings and numarrays makes the two methods comparable).


- Till
 
D

Dennis Lee Bieber

On Wed, Jun 23, 2004 at 12:56:49PM -0700, Kamilche wrote:
said:
But I DON'T manipulate the data byte by byte, only the encryption
tables.
Ah, the power of algorithms! ;-)
Take a look at this:

def encrypt(s, offset = 0, _tables = []):
...
# Tables initialized - encrypt the data.
return s.translate(_tables[offset % cnt])
Pardon the hijacking off one response to back up to the quoted
persons comments.

I wouldn't call the above an "encryption" function -- it looks
to be nothing more than a substitution cipher. (I don't know how "cnt"
is determined, but translate will, for any given invocation, return the
same output character for any repeat occurrences of the input. A good
encryption algorithm should not do that -- ideally, "bookkeeper" will
encrypt with no repeated characters in the oo, kk, ee*e positions)

--
 
?

=?iso-8859-15?Q?Pierre-Fr=E9d=E9ric_Caillaud?=

It was in C but I suppose if you pass a Pyhon string to the Blowfish
function which is in written in C, you'll get the same speed.

It's implemented in OpenSSL. This is probably accessible from Python.
Dunno which module.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top