.h文件
#ifndef _MP_H
#define _MP_H
#define _REENTRANT
#include <stdlib.h>
#include <string.h>
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#define MP_WBITS 32U
typedef uint8_t byte;
typedef uint32_t mpw;
typedef uint16_t mphw;
#define MP_HWBITS (MP_WBITS >> 1)
#define MP_WBYTES (MP_WBITS >> 3)
#define MP_WNIBBLES (MP_WBITS >> 2)
# define MP_WORDS_TO_BITS(x) ((x) << 5)
# define MP_WORDS_TO_NIBBLES(x) ((x) << 3)
# define MP_WORDS_TO_BYTES(x) ((x) << 2)
# define MP_BITS_TO_WORDS(x) ((x) >> 5)
# define MP_NIBBLES_TO_WORDS(x) ((x) >> 3)
# define MP_BYTES_TO_WORDS(x) ((x) >> 2)
#define MP_MSBMASK (((mpw) 0x1) << (MP_WBITS-1))
#define MP_LSBMASK ((mpw) 0x1)
#define MP_ALLMASK ~((mpw) 0x0)
#ifdef __cplusplus
extern "C" {
#endif
/*!/fn void mpzero(size_t size, mpw* data)
* /brief This function zeroes a multi-precision integer of a given size.
* /param size The size of the multi-precision integer.
* /param data The multi-precision integer data.
*/
void mpzero(size_t size, mpw* data);
/*!/fn void mpsetw(size_t size, mpw* xdata, mpw y)
* /brief This function sets the value of a multi-precision integer to the
* given word. The given value is copied into the least significant word,
* while the most significant words are zeroed.
* /param size The size of the multi-precision integer.
* /param xdata The first multi-precision integer.
* /param y The multi-precision word.
*/
void mpsetw(size_t size, mpw* xdata, mpw y);
int mpmultwo(size_t size, mpw* data);
/*
* Conversion Routines
*/
int os2ip(mpw* idata, size_t isize, const byte* osdata, size_t ossize);
int i2osp(byte* osdata, size_t ossize, const mpw* idata, size_t isize);
#ifdef __cplusplus
}
#endif
#endif
.c 文件
#include "O_I.h"
//#ifndef ASM_MPZERO
void mpzero(size_t size, mpw* data)
{
while (size--)
*(data++) = 0;
}
//#endif
//#ifndef ASM_MPMSZCNT
size_t mpmszcnt(size_t size, const mpw* data)
{
register size_t zbits = 0;
register size_t i = 0;
while (i < size)
{
register mpw temp = data[i++];
if (temp)
{
while (!(temp & MP_MSBMASK))
{
zbits++;
temp <<= 1;
}
break;
}
else
zbits += MP_WBITS;
}
return zbits;
}
//#endif
//#ifndef ASM_MPBITS
size_t mpbits(size_t size, const mpw* data)
{
return MP_WORDS_TO_BITS(size) - mpmszcnt(size, data);
}
//#endif
int i2osp(byte *osdata, size_t ossize, const mpw* idata, size_t isize)
{
#if WORDS_BIGENDIAN
size_t max_bytes = MP_WORDS_TO_BYTES(isize);
#endif
size_t significant_bytes = (mpbits(isize, idata) + 7) >> 3;
/* verify that ossize is large enough to contain the significant bytes */
if (ossize >= significant_bytes)
{
/* looking good; check if we have more space than significant bytes */
if (ossize > significant_bytes)
{ /* fill most significant bytes with zero */
memset(osdata, 0, ossize - significant_bytes);
osdata += ossize - significant_bytes;
}
if (significant_bytes)
{ /* fill remaining bytes with endian-adjusted data */
#if !WORDS_BIGENDIAN
mpw w = idata[--isize];
byte shift = 0;
/* fill right-to-left; much easier than left-to-right */
do
{
osdata[--significant_bytes] = (byte)(w >> shift);
shift += 8;
if (shift == MP_WBITS)
{
shift = 0;
w = idata[--isize];
}
} while (significant_bytes);
#else
/* just copy data past zero bytes */
memcpy(osdata, ((byte*) idata) + (max_bytes - significant_bytes), significant_bytes);
#endif
}
return 0;
}
return -1;
}
int os2ip(mpw* idata, size_t isize, const byte* osdata, size_t ossize)
{
size_t required;
/* skip non-significant leading zero bytes */
while (!(*osdata) && ossize)
{
osdata++;
ossize--;
}
required = MP_BYTES_TO_WORDS(ossize + MP_WBYTES - 1);
if (isize >= required)
{
/* yes, we have enough space and can proceed */
mpw w = 0;
/* adjust counter so that the loop will start by skipping the proper
* amount of leading bytes in the first significant word
*/
byte b = (ossize % MP_WBYTES);
if (isize > required)
{ /* fill initials words with zero */
mpzero(isize-required, idata);
idata += isize-required;
}
if (b == 0)
b = MP_WBYTES;
while (ossize--)
{
w <<= 8;
w |= *(osdata++);
b--;
if (b == 0)
{
*(idata++) = w;
w = 0;
b = MP_WBYTES;
}
}
return 0;
}
return -1;
}
int hs2ip(mpw* idata, size_t isize, const char* hsdata, size_t hssize)
{
size_t required = MP_NIBBLES_TO_WORDS(hssize + MP_WNIBBLES - 1);
if (isize >= required)
{
register size_t i;
if (isize > required)
{ /* fill initial words with zero */
for (i = required; i < isize; i++)
*(idata++) = 0;
}
while (hssize)
{
register mpw w = 0;
register size_t chunk = hssize & (MP_WNIBBLES - 1);
register char ch;
if (chunk == 0) chunk = MP_WNIBBLES;
for (i = 0; i < chunk; i++)
{
ch = *(hsdata++);
w <<= 4;
if (ch >= '0' && ch <= '9')
w += (ch - '0');
else if (ch >= 'A' && ch <= 'F')
w += (ch - 'A') + 10;
else if (ch >= 'a' && ch <= 'f')
w += (ch - 'a') + 10;
}
*(idata++) = w;
hssize -= chunk;
}
return 0;
}
return -1;
}
//#ifndef ASM_MPMULTWO
int mpmultwo(size_t size, mpw* data)
{
register mpw temp, carry = 0;
data += size;
while (size--)
{
temp = *(--data);
*data = (temp << 1) | carry;
carry = (temp >> (MP_WBITS-1));
}
return (int) carry;
}
//#endif
//#ifndef ASM_MPSETW
void mpsetw(size_t size, mpw* xdata, mpw y)
{
while (--size)
*(xdata++) = 0;
*(xdata++) = y;
}
//#endif
测试文件:
#include <stdio.h>
#include "O_I.h"
void hexdump(byte* b, int count)
{
int i;
for (i = 0; i < count; i++)
{
printf("%02x", b[i]);
if ((i & 0xf) == 0xf)
printf("/n");
}
if (i & 0xf)
printf("/n");
}
int main()
{
int rc;
mpw x[4];
byte o[9];
mpsetw(4, x, 255);
mpmultwo(4, x);
rc = i2osp(o, 9, x, 4);
printf("rc = %d/n", rc);
hexdump(o, 9);
rc = os2ip(x, 4, o, 9);
printf("rc = %d/n", rc);
//mpprintln(4, x);
while(1);
exit(0);
return 0;
}