need help with algorithm

N

Nemok

Hi,

I am trying to write an additive encryption algorithm in C++ that will
encrypt a text by adding a random numer to each character in a string.
The code looks similar to this:

for(int i=0;i<=tlength-1;i++)///tlength is the length of the string to
encrypt
{
ctext+=x+i;/////x is a random number and ctext is a char*
ctext+=cpass[i%plength]+tlength;///////cpass is the key
(password)
ctext[tlength-1-i]+=x-i;
}

The problem is that while adding to the values of each char that char
might be 0 which will be interpreted like the ending NULL character of
the string. So what I need is a reversable method of
elliminating\replacing all 0 values with other values and then on
decryption of the encrypted string restore them. I can't just replace
the 0 values with another value because that value might also be
encountered in another char on decryption and will be wrongfully
transformed to 0. Please help.

Thanks.
 
M

mlimber

Nemok said:
Hi,

I am trying to write an additive encryption algorithm in C++ that will
encrypt a text by adding a random numer to each character in a string.
The code looks similar to this:

for(int i=0;i<=tlength-1;i++)///tlength is the length of the string to
encrypt
{
ctext+=x+i;/////x is a random number and ctext is a char*
ctext+=cpass[i%plength]+tlength;///////cpass is the key
(password)
ctext[tlength-1-i]+=x-i;
}

The problem is that while adding to the values of each char that char
might be 0 which will be interpreted like the ending NULL character of
the string. So what I need is a reversable method of
elliminating\replacing all 0 values with other values and then on
decryption of the encrypted string restore them. I can't just replace
the 0 values with another value because that value might also be
encountered in another char on decryption and will be wrongfully
transformed to 0. Please help.

Thanks.


Try using a std::vector<char> instead of a character pointer. You'll
need to define your own input/output operations (which should be fairly
simple), but then you can use std::vector<>::size() instead of
std::strlen to get an accurate length of the string. Alternately, you
could just keep track of how long the char strings are by hand and read
and write them without using formatted IO (e.g., std::printf,
std::cout)

Cheers! --M
 
R

roberts.noah

Nemok said:
Hi,

I am trying to write an additive encryption algorithm in C++ that will
encrypt a text by adding a random numer to each character in a string.
The code looks similar to this:

for(int i=0;i<=tlength-1;i++)///tlength is the length of the string to
encrypt
{
ctext+=x+i;/////x is a random number and ctext is a char*
ctext+=cpass[i%plength]+tlength;///////cpass is the key
(password)
ctext[tlength-1-i]+=x-i;
}

The problem is that while adding to the values of each char that char
might be 0 which will be interpreted like the ending NULL character of
the string. So what I need is a reversable method of
elliminating\replacing all 0 values with other values and then on
decryption of the encrypted string restore them. I can't just replace
the 0 values with another value because that value might also be
encountered in another char on decryption and will be wrongfully
transformed to 0. Please help.


You are going to have to know the length of the string you are
encrypting. This will have to be stored somewhere so the decrypt alg
knows also. You can always treat a char[] as a simple [], you don't
have to use string processing routines on it and it isn't actually a
"string" as there is no fundamental string type. So, if decrypt finds
a 0 before the end of the string (which it knows because you told it
somehow) then it just applies the subtraction like normal.

As was suggested, you could use a std::vector<char> to do this if you
wanted and this would have the added benefit of knowing its own length.

But regardless of how you do it, you simply can't treat your encryted
text as a "string" type but as an array of bytes.
 
N

Nemok

Thanks for your fast reply but changing now to std::vector will mean a
lot of work (the algorithm is larger than hat I posted). Also I need
the output of the algorithm to be a string that I can store for later
decryption. So I would I appreciate for some math formula or something
that will replace 0 en encryption and put it back on decryption without
any safety problems.
 
R

Rennie deGraaf

Nemok said:
Hi,

I am trying to write an additive encryption algorithm in C++ that will
encrypt a text by adding a random numer to each character in a string.
The code looks similar to this:

for(int i=0;i<=tlength-1;i++)///tlength is the length of the string to
encrypt
{
ctext+=x+i;/////x is a random number and ctext is a char*
ctext+=cpass[i%plength]+tlength;///////cpass is the key
(password)
ctext[tlength-1-i]+=x-i;
}

The problem is that while adding to the values of each char that char
might be 0 which will be interpreted like the ending NULL character of
the string. So what I need is a reversable method of
elliminating\replacing all 0 values with other values and then on
decryption of the encrypted string restore them. I can't just replace
the 0 values with another value because that value might also be
encountered in another char on decryption and will be wrongfully
transformed to 0. Please help.

Thanks.


The easiest solution would be to ignore the 0 bytes in the output, and
consider the ciphertext as binary data rather than a string. Your
encryption algorithm treats the input as binary data, so there's no
simple way of converting the output to anything else.

One work-around would be to convert your algorithm to be aware of the
size of the character set used by your strings. If, for instance, you
are only concerned with the characters on a standard US keyboard, then
you could perform all operations modulo the size of your character set
and encode each plaintext and ciphertext byte to an index into your
character set. This would be a lot more complicated than the simple
loop you just described, however.

If your output must be a string and you can't change the algorithm,
consider running a second pass on the output to escape all 0 bytes. To
do that, pick another byte value, for instance 1, and use it as an
escape character. Run through the ciphertext, replacing all 1 bytes
with two 1 bytes, and replacing all 0 bytes with a 1 byte followed by a
2 byte. Then, before decrypting, run through the string replacing all
double 1 bytes with single 1 bytes, and all 1,2 byte patterns with 0
bytes. Any other 1,x byte pattern would be invalid.

Bear in mind that the cryptosystem you described can be broken with
pencil and paper within minutes, so don't use it for anything real.

Rennie deGraaf
 
R

Randy

In general, a [finite] mapping from N items to N items is
invertible if and only if it is one-to-one (or onto).

Why not used a canned library like Crypto++?

http://www.eskimo.com/~weidai/cryptlib.html

I haven't used it, but it seems like it and others
of that ilk would be fairly easy to incorporate into
your code, and it would be more secure, too.

--RY
 
N

Nemok

First of all thanks for your reply. I can't add 2 bytes instead of one
because I want the encrypted string to be same size as the original
string. Someone suggested adding something like
ctext=(ctext-1)%99+1 to encrypt and ctext=(ctext-1+99)%99+1
for decryption but it doesn't seem to work.
And I don't think it can be broken with a pencil and paper because it
uses random numbers, a key and XOR sys too.
 
R

Rennie deGraaf

Nemok said:
First of all thanks for your reply. I can't add 2 bytes instead of one
because I want the encrypted string to be same size as the original
string. Someone suggested adding something like
ctext=(ctext-1)%99+1 to encrypt and ctext=(ctext-1+99)%99+1
for decryption but it doesn't seem to work.


If I'm reading your original algorithm correctly, it's equivalent to

for(int i=0;ctext;i++)
{
ctext += x + i + strlen(ctext) + cpass[i%plength] + x -
(strlen(ctext) - 1 - i);
}

which simplifies to

for(int i=0;ctext;i++)
{
ctext += 2*x + 2*i + cpass[i%plength] + 1;
}

This maps each input byte to a value over a huge range, limited only by
the range of your random 'x' and the maximum length of a plaintext.
Even assuming that 'x' is a single byte and that plaintexts are limited
to a maximum length of 256 characters, there are still 1537 possible
output values. There's simply no way to truncate output values to a
single byte each and be able to decrypt your message. However your
cryptosystem works, it must be a bijection - that is, it must map values
from a set of k elements to a set of k elements where for each possible
ciphertext value, some plaintext value maps to it, and for each possible
plaintext value, some ciphertext value maps to it.

This whole problem looks suspiciously like a 1st year computer science
assignment. Just use something simple, like XORing your plaintext with
your key. If you're developing this to actually use in the real world,
please give up now, and use something like AES.
And I don't think it can be broken with a pencil and paper because it
uses random numbers, a key and XOR sys too.

I wouldn't make any bets on that.

Has anyone ever told you the first law of designing crypto?
It's "Don't do it.".

Rennie deGraaf
 
N

Nemok

I ma trying to develop this for real life. I need this encryption for 2
applications. In one I am going to encrypt passwords the users set to
limit applications's usage. The password will be stored in the
Registry. A second application I am gone use it in is a PECompressor
and file binder (nBinder). I need encryption to store data like number
of files, files names, unpacking options, run passwords and other
things like that. so this is why I need a small encryption\decryption
algorithm (to keep a small footprint for the unpacker) and it needs to
have a small output for the same reasons and also for memory
limitations due to the possible high number of files that might be
binded at a time. Also unlike AES I need something with customizable
block sizes for the same reasons. The strings lengths may vary from 4
chars to 200 chars.
This is why I was trying to write my own because it is hard to find one
that matches my critereas. Pelase feel free to ask if you need any more
details about what I need.
Thanks.
 
R

Rennie deGraaf

Nemok said:
I ma trying to develop this for real life. I need this encryption for 2
applications. In one I am going to encrypt passwords the users set to
limit applications's usage. The password will be stored in the
Registry. A second application I am gone use it in is a PECompressor
and file binder (nBinder). I need encryption to store data like number
of files, files names, unpacking options, run passwords and other
things like that. so this is why I need a small encryption\decryption
algorithm (to keep a small footprint for the unpacker) and it needs to
have a small output for the same reasons and also for memory
limitations due to the possible high number of files that might be
binded at a time. Also unlike AES I need something with customizable
block sizes for the same reasons. The strings lengths may vary from 4
chars to 200 chars.
This is why I was trying to write my own because it is hard to find one
that matches my critereas. Pelase feel free to ask if you need any more
details about what I need.
Thanks.

For that purpose, I'd reccomend starting with a good book on
cryptography. _Applied Cryptography_ by Bruce Schneier or _Cryptography
and Network Security_ by William Stallings would be a good start.
_Handbook of Applied Cryptography_ by Menezes, van Oorschot, and
Vanstone might also be a good reference, and it's available for free
online. If you don't think that block ciphers like AES are appropriate
for your system, try looking at stream ciphers like RC4. And don't try
implementing them yourself - get a cryptographic library from a
reputable source. OpenSSL (http://www.openssl.org/) would be a good
choice, and is available for most platforms. There are also commercial
cryptography libraries out there that you can buy/license.

Rennie deGraaf
 
R

rossum

First of all thanks for your reply. I can't add 2 bytes instead of one
because I want the encrypted string to be same size as the original
string.
For the password encoding output size can hardly be critical. One way
to get round the zero byte problem would be to treat the encrypted
text string as bytes, and to store it in Base-64 encoding. That will
guarantee no zero bytes (or other nasties like EoF markers) though it
will increase the length.

As others have said your best bet is probably to use an existing
library, many (?most?) of which will include Base-64 as well because
of the problem you have encountered.

rossum
Someone suggested adding something like
ctext=(ctext-1)%99+1 to encrypt and ctext=(ctext-1+99)%99+1
for decryption but it doesn't seem to work.
And I don't think it can be broken with a pencil and paper because it
uses random numbers, a key and XOR sys too.
 

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

Similar Threads

Algorithm 1
I need help with homework 1
Need help with this code 2
Need help with this script 4
Help in hangman game 1
Need help with a script... (my first!) 6
Help with Loop 0
I need help with some python code 1

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top