Commit 05d0e7dc authored by Niels Möller's avatar Niels Möller
Browse files

*** empty log message ***

Rev: src/Makefile.in:1.2
Rev: src/bignum.c:1.1
Rev: src/bignum.h:1.1
Rev: src/format.c:1.2
Rev: src/parse.c:1.2
Rev: src/parse.h:1.2
parent 5bb13c27
atoms.h: atoms.in process_atoms
bash process_atoms header <atoms.in >atoms.h
atoms_defines.h: atoms.in process_atoms
bash process_atoms header <atoms.in >atoms_defines.h
atoms_gperf.c: atoms.in process_atoms
bash process_atoms gperf <atoms.in |gperf -t -k1,7,$$ >atoms_gperf.c
......
/* bignum.c
*
*/
#include "bignum.h"
void parse_bignum(bignum n, UINT32 length, UINT8 *data)
{
int negative = length && (*data & 0x80);
int i;
mpz_t digit;
mpz_init(digit);
mpz_set_ui(n, 0);
for (i = 0; i < length; i++)
{
mpz_set_ui(digit, data[i]);
mpz_mul_2exp(digit, digit, (length - i - 1) * 8);
mpz_ior(n, n, digit);
}
if (negative)
{
mpz_set_ui(digit, 1);
mpz_mul2exp(digit, digit, length*8);
mpz_sub(n, n, digit);
}
mpz_clear(digit);
}
int mpz_size_of_complement(mpz_t n)
{
int bits;
/* One's complement(x) = - x - 1 */
mpz_t complement;
mpz_init(complement);
mpz_com(complement, n);
/* Note that bits == 1 if complement == 0, i.e n = -1 */
bits = mpz_sizeinbase(complement, 2);
mpz_clear(complement);
return bits;
}
/* This function should handle both positive and negative numbers */
UINT32 bignum_format_length(bignum n)
{
switch(mpz_sgn(n))
{
case 0:
return 0;
case 1:
return mpz_sizeinbase(n, 2)/8 + 1;
case -1:
return mpz_size_of_complement(mpz_t n)/8 + 1;
}
}
void limbs_to_octets(n, length, UINT8 pad, UINT8 *data)
{
UINT32 *dst = data + length - 1;
mp_limb_t *l = n->_md_d; /* Starts at the least significant limb */
int left = n->_mp_size;
while( (len > 0) && (left > 0) )
{
int i;
mp_limb_t word = *l++;
for(i = 0; i<sizeof(mp_limb_t); i++)
{
*dst-- = word & 0xff;
word >>= 8;
len--;
if (!len)
break;
}
}
while (len > 0)
{
*dst-- = pad;
len--;
}
}
UINT32 bignum_format(bignum n, UINT8 *data)
{
switch(mpz_sgn(n))
{
case 0:
return 0;
case 1:
{
int length = mpz_sizeinbase(n, 2)/8 + 1;
limbs_to_octets(n, length, 0, *data);
return length;
}
case -1:
{
mpz_t complement;
int length;
int i;
mpz_init(complement);
mpz_com(complement, n);
/* Note that mpz_sizeinbase(0) == 0.*/
length = sizeinbase(complement, 2)/8 + 1;
for (i = 0; i<complement->_mp_size; i++)
complement->_mp_d[i] = ~complement->_mp_d[i];
limbs_to_octets(complement, length, 0xff, *data);
mpz_clear(complement);
return length;
}
}
}
/* bignum.h
*
* Interface and conversion functions for GMP.
*/
#ifndef LSH_BIGNUM_H_INCLUDED
#define LSH_BIGNUM_H_INCLUDED
#include <gmp.h>
#define bignum mpz_t
void parse_bignum(bignum n, UINT32 length, UINT8 *data);
UINT32 bignum_format_length(bignum n);
void bignum_format(bignum n, UINT8 *data);
#endif /* LSH_BIGNUM_H_INCLUDED */
......@@ -100,10 +100,10 @@ UINT32 *ssh_vformat_length(char *f, va_list args)
break;
case 'n':
{
mpz_t n = va_arg(args, mpz_t);
bignum n = va_arg(args, bignum);
/* Calculate length of written number */
#error foo
length += bignum_format_length(n);
if (!literal)
length += 4;
......@@ -227,10 +227,10 @@ void ssh_vformat(char *f, UINT *buffer, va_list args)
break;
case 'n':
{
mpz_t n = va_arg(args, mpz_t);
UINT32 length;
/* Calculate length of written number */
#error foo
bignum n = va_arg(args, bignum);
UINT32 length = bignum_format(n, buffer);
buffer += length;
if (!literal)
{
......@@ -238,7 +238,6 @@ void ssh_vformat(char *f, UINT *buffer, va_list args)
buffer += 4;
}
/* Write digits */
f++;
}
break;
......@@ -246,3 +245,4 @@ void ssh_vformat(char *f, UINT *buffer, va_list args)
}
*buffer++ = *f++;
}
}
......@@ -66,16 +66,17 @@ int parse_uint8(struct simple_buffer *buffer, uint8 *result)
return 1;
}
int parse_bignum(struct simple_buffer *buffer, mpz_t result)
int parse_bignum(struct simple_buffer *buffer, bignum result)
{
UINT32 length;
UINT8 *digits;
if (!parse_string(buffer, &length, &data))
if (!parse_string(buffer, &length, &digits))
return 0;
/* init mpz */
#error
parse_bignum(result, length, digits);
return 1;
}
/* Returns 1 on success, 0 on failure, and -1 at end of buffer.
......
......@@ -27,7 +27,7 @@ int parse_sub_buffer(struct simple_buffer *buffer,
int parse_uint8(struct simple_buffer *buffer, uint8 *result);
#define parse_boolean parse_uint8
int parse_bignum(struct simple_buffer *buffer, mpz_t result);
int parse_bignum(struct simple_buffer *buffer, bignum result);
/* Returns 1 on success, 0 on failure, and -1 at end of buffer.
* Unknown atoms sets result to zero. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment