GMP - integer import and export

enders game endersgame99@yahoo.com
Wed, 20 Nov 2002 09:53:42 -0800 (PST)


--- Erik Johnson <erik_johnson1980@hotmail.com> wrote:
> I'm using the GMP library for an demonstration of
> various cryptographic 
> algorithms for an independent study project. I seem
> to have a problem, 
> however, with the integer import and export
> functions. Basically, I am 
> reading in binary data, using the import function to
> convert it to the GMP 
> multi-precision number format, performing the
> algorithm, and then using the 
> export function to convert the data back to binary
> and write it out to the 
> destination file.
> 
> I have no problems with text files, the algorithms
> encrypt and decrypt them 
> perfectly. The problem is this: when using
> characters with an ANSI value 
> higher than 127, the decrypted result does not match
> the original file. So, 
> binary files like wav files, PDFs, etc. don't work,
> and text files with 
> special characters (accented letters, etc.) also do
> not. Since these 
> characters do not work, but regular text does, I
> figure it is likely a 
> problem with the conversion function not properly
> converting the unsigned 
> char data to the GMP format.  Like it treats
> everything as a signed char or 
> something when converting.  My buffer is an unsigned
> char array, so I know 
> that the buffer is not the problem.
> 
> Can anyone else that has used GMP offer any insight
> into this problem?
> 
> Code sample is below.
> 
> --------------------------------------
> 
> FYI:
>   BUFFER_SIZE is a const int.
>   padding is an integer value calculated earlier in
> the program.
> 
> .
> .
> .
> .
>     unsigned char buffer[BUFFER_SIZE];
> 
>     for(int i=1; i<=num_blocks; i++)
>     {
>         if(a == 'E' && i == num_blocks)
>             // If the algorithm is encrypting, and
> this is the last block,
>             // Read the last bytes from the input
> file.
>             inp.read((char
> *)&buffer,(BUFFER_SIZE-padding));
>         else
>             // Read a full block.
>             inp.read((char *)&buffer,BUFFER_SIZE);
> 
>         // Convert to MP int.
>         mpz_import(m,1,1,BUFFER_SIZE,0,0,buffer);
> 
>         // Encrypt or decrypt the block.
>         mpz_powm(m,m,x,n);
> 
>         // Convert the block back to binary.
>        
> mpz_export(buffer,&count,1,BUFFER_SIZE,0,0,m);
> 
>         if(a == 'D' && i == num_blocks)
>             // If the algorithm is decrypting, and
> this is the last block,
>             // then disregard the padding when
> writing.
>             out.write((char
> *)&buffer,(BUFFER_SIZE-padding));
>         else
>             // Write the data out to the destination
> file.
>             out.write((char *)&buffer,BUFFER_SIZE);
>     }
> .
> .
> .
> .
> 

I might be wrong, im not sure, so im just going to
tell you my idea of what could be happening for you. 
If you read NULLs from the file before other
characters, then you will import from "000005622342"
for example.  But when you do any math (POWM) on the
number, you'll lose the leading zeroes, and wont be
able to decrypt them.  What I did was when decrypting,
exported to a zeroed array of the size each mpz-sized
block.

~Andrew


__________________________________________________
Do you Yahoo!?
Yahoo! Web Hosting - Let the expert host your site
http://webhosting.yahoo.com