[OTR-dev] working with the libgcrypt mpi type and getting the actual integer value

Ileana ileana at fairieunderground.info
Wed Feb 27 13:18:01 EST 2013


On Tue, 26 Feb 2013 18:04:23 -0500
Bjorn Kuiper <bjorn at kuiper.nu> wrote:

> Hi,
> 
> I'm trying to develop a C# implementation of the Off-the-record
> library, but I'm having some problems with the libgcrypt library.
> 
> Can somebody explain to me how you can print out the actual integer 
> value of an hex'd MPI ?
> 
> Basically i want to know the integer value of this 'private' key
> 
> 48BFDA215C31A9F0B226B3DB11F862450A0F30DA
> 
> I think it is
> 
> 415325779662433871844955547383752003988573073626
> 
> but I'm unable to find a way to confirm this using libgcrypt
> 
> I tried the following code:
> 
> -- code snippit
> gcry_mpi_t cript_prime;
> char buffer[50] = {0};
> char number[50] = {0};
> 
> cript_prime = gcry_mpi_new(50);
> 
> strcpy(number,"415325779662433871844955547383752003988573073626");

So you are storing the 'number' as a string.  At this point its not
even a number.  You can't convert it directly to hex because that
requires divisions of a strings by 16. You can't divide strings by
16, but you can divide numbers.  You can't just use shift because you
will lose the remainders.

But since you must store it as binary anyway, what you are doing is
converting to binary, then binary to hex string.  Remember in computers
everything is in binary.

Most processor integer division puts dividends in one register, and
remainders in another.  So you are not going to beat the built in
implementation unless you plan on assembly code.  And once you do
that you see how difficult it is dividing a number larger then
your register size.  (Maybe your compiler will help you?)

Alternately, you can create a table array which indexes ascii
representations into integer equivalents.  The unfortunate space
complexity of this constant time operation is O(n*log(n)).  Normally we
think O(n*log(n)) is a nice number, but in this case, we want
O(log16(n)), which is an even nicer number.  :)

So you might as well just use BigInteger (or c# equiv) to store the
value as binary in ram, and print out as hex.

But maybe your private key is already sitting in ram as a binary
number!  But with what endianness and what representation?  If you can
directly access that ram, you can simply do the binary to decimal
conversion directly!

And what do you know?
http://msdn.microsoft.com/en-us/library/dd268207.aspx

What a weird question.  I don't think I will use the C# otr...


> gcry_mpi_scan(&cript_prime,GCRYMPI_FMT_USG,number,sizeof(number),NULL);
> 
> gcry_mpi_print(GCRYMPI_FMT_USG,buffer,sizeof(buffer),NULL,cript_prime);
> 
> printf("The number tested is: %s\n",buffer);
> 
> printf("trying to convert to HEX\n");
> 
> /* get actual value */
> gcry_mpi_print (GCRYMPI_FMT_HEX, buffer, sizeof(buffer), NULL,
> cript_prime); /* print actual value */
> printf("result: %s\n", buffer);
> -- end of code snippit
> 
> which results in:
> 
> -- output
> The number tested is: 415325779662433871844955547383752003988573073626
> trying to convert to HEX
> result: 415325779662433871844955547383752003988573073626
> -- end of output
> 
> I expected the second gcry_mpi_print to convert it to HEX by using 
> GCRYPT_FMT_HEX enum, but that doesn't seem to work.
> 
> I also devoted an stackoverflow question to it:
> http://stackoverflow.com/questions/15080516/print-unsigned-int-value-of-mpi
> 
> Thank you for your help, this will help me advance my implementation 
> efforts in creating a C# lib.
> 
> Greetings Bjorn
> _______________________________________________
> OTR-dev mailing list
> OTR-dev at lists.cypherpunks.ca
> http://lists.cypherpunks.ca/mailman/listinfo/otr-dev




More information about the OTR-dev mailing list