One Time Pad (OTP)
Fri. July 2, 2010Categories: machinehack
Tags: One Time, One Time Pad, OTP
One Time Pad
OTP in 1 line of perl:
vec($_,0,1);open(P,shift);read(P,$p,length),print $_^$p while<>
John Allen
shortened my previous perl implemenation by 11 chars. He also has
this even shorter perl5 specific version:
open P,shift;read(P,$p,length),print $_^$p while<>
Paul Leyland wrote one in 1 line of C :
main(i,c)int*c;{for(c=fopen(c[1],"r");i=~getchar();putchar(getc(c)^~i));}
What is a One Time Pad?
A one time pad is the only currently known unconditionally secure
encryption system. Other encryption systems are cryptographically
secure which means that they have a cost associated with breaking,
this cost will be very high, but it would theoretically be possible to
break if enough compute time could be gathered.
OTPs are provably unconditionally secure, this means that you can not
break them with any amount of compute time. It is
mathematically impossible to break a OTP.
Okay, so a OTP is a marvelously secure crypto system, so why isn’t it
more widely used? This is due to convenience, in order to use a OTP
you have to trade pads with each person you wish to communicate with.
The pad should be a truly random number, so you would ideally want a
radioactive decay card or something to generate the pad. The system
will critically depend on the true randomness of the pad, and of
course on keeping the pad known only to you and the recipient.
This is where the inconvenience comes in, you must somehow trade pads
with your intendend recipient securely, this means meeting in person
or using a trusted courier.
How does it work
Basically you have your random OTP, which both you and your intended
recipient have. You have a message M, and you compute the ciphertext
C by XORing the message with the OTP:
C = M xor OTP
You send the ciphertext to your recipient, the recipient knowing the
OTP also can recover the message by computing the reverse, XORing the
ciphertext C with the OTP:
M = C xor OTP
You must never re-use the OTP, other wise it wouldn’t be a
“One-Time” pad anymore, and it would loose it’s unbreakable properties
as information would start to be leaked.
One Time Pad in 1 line of perl
#!/usr/local/bin/perl
open(P,$ARGV[0]);print pack(C,unpack(C,$_)^unpack(C,getc(P)))while$_=getc;
Save as otp and mark as executable:
% chmod 700 otp
One Time Pad in 1 line of C
main(i,c)int*c;{for(c=fopen(c[1],"r");~(i=getchar());putchar(getc(c)^i));}
by Paul Leyland. Just compile with a
K&R or ANSI C compiler:
% cc -o otp otp.c
Using the OTP
You must create and exchange a OTP with your recipient. We call the
OTP file “pad” here, the message to exchange “msg”, and the encrypted
ciphertext “cipher”.
To encrypt, do (same usage for C or perl versions):
% otp pad < msg > cipher
Now you can send “cipher” to your recipient in the clear, just email
will do fine as you will be the only two people who will ever be able
to decipher the message.
To decrypt your recipient does:
% otp pad < cipher > msg
to recover the message.
Generating OTPs
It can’t be stressed enough how important it is to have a truly random
OTP. Just using the random() function provided with C
libraries is nowhere near good enough, these typically have a seed of
one 32 bit word, so that even if you used the millisecond of your
clock as a seed the whole system could be broken with a brute force
keysearch of all possible seeds. In cryptographic terms a 32 bit
keyspace is tiny, and would take a negligble amount of compute time to
break.
Basically if you use pseudo-random number generators they are going to
be the weak point in the system, unless you have external input like a
radio-active decay card, or timings of the milliseconds between
keystrokes with proper entropy estimation as used by PGP.
Comments