views:

65

answers:

3

I am learning about cryptographic algorithms and in the process am attempting to implement some well known schemes. I understand the mathematical explanations behind RSA and El Gamal, but am currently unable to test my implementations of either. The underlying problem is that I cannot see the way to convert plain text into a manipulatable number.

For Example:

Message = "This is a message I want to encrypt";
int x = (int)Message;
Encrypt(x,key);

In my mind, it should be possible to cast a string to an integer, but doing so in a method similar to the above example doesn't work. How can I turn a plain-text message into a numerical value (and later back into a plain-text value) for the purposes of encryption?

+3  A: 

The numbers used in Diffie-Hellman and RSA are really large, so libraries that implement them work with specialized types that can represent numbers with thousands of bits. Casting to an int would, at best, hold 32 or 64 bits.

Most of these libraries are able to convert a string of bytes to their big integer type. Converting a string to a big integer usually requires the intermediate step of applying a character encoding to convert the string of characters to a string of bytes.

erickson
I understand that the numbers in real use cases are large, but I am currently testing relatively small numbers just to make sure my implementations are correct.
XBigTK13X
@XBigTK13X - A cast still won't work in any "managed" language like Java or C#. C or C++ would let you do it with a cast, but only for 4 or 8 characters, depending on your `int` size. In Java or C#, you need to convert the string to bytes, then pack the bytes into an `int` with bit operations. I would show an example, but your implementation won't be correct if it doesn't operate on some sort of `BigInteger` type. If you used primitive `int` types in your implementation, it won't work without changes.
erickson
Also, all of the test vectors that are published in the specifications use large integers. It's also extremely helpful to test with other software, to ensure that you inter-operate successfully. Of course, that will require using large integers too.
erickson
A: 

If you really just want to cast a string of text into a numerical value, you can simply add the ASCII numerical value of each character. This is, of course, not a reliable checksum, and you may run into problems if a text has higher unicode values.

In C you can do (quick and dirty):

#include<stdio.h>
#include<string.h>

int main(){
 int k = 0;
 int value = 0;
 char text[]="this is a piece of text.";
 char c;
 for(k=0; k<strlen(text); k++){
   c = text[k];
   value = value + c;
   printf("char %c has value %d\n", c, c);
 }
 printf("total value is: %d\n", value);
 return 0;
}

The output is:

char t has value 116
char h has value 104
char i has value 105
char s has value 115
char   has value 32
char i has value 105
char s has value 115
char   has value 32
char a has value 97
char   has value 32
char p has value 112
char i has value 105
char e has value 101
char c has value 99
char e has value 101
char   has value 32
char o has value 111
char f has value 102
char   has value 32
char t has value 116
char e has value 101
char x has value 120
char t has value 116
char . has value 46
total value is: 2147

Notice that this is by no means a secure or efficient approach to ensuring that a file is what it is supposed to be (a checksum). If you want a "value" assigned to a given stream of text, try SHA-1 hash function.

Arrieta
This won't allow recovery of the message. There are many, many possible ways to create a sum of "2147".
erickson
Yep. This is only a way to "convert a string into a number" - a mediocre checksum. For the question of creating a reliable encryption algorithm... I'm afraid that's a whole different (and difficult) ball-game.
Arrieta
"How can I turn a plain-text message into a numerical value *(and later back into a plain-text value)* ... ?"
erickson
+4  A: 

There are usually two steps to converting a string to an integer. The first is to convert each character into a small integer and then convert the resulting sequence of small integers into a large integer. For example, in Java or C# you can easily convert the string into a byte array representing its UTF-8 encoding. Then, by treating the byte array as a base-256 integer, you can convert it to a large integer. Every BigInteger package that I am aware of has a constructor that will accept an array of bytes, as well as a method that will go the other way and take the BigInteger and return an array of bytes.

GregS