📄 bn16.c
字号:
/* * bn16.c - the high-level bignum interface * * Like lbn16.c, this reserves the string "16" for textual replacement. * The string must not appear anywhere unless it is intended to be replaced * to generate other bignum interface functions. * * Copyright (c) 1995 Colin Plumb. All rights reserved. * For licensing and other legal details, see the file legal.c. */#if HAVE_CONFIG_H#include "config.h"#endif#if !NO_ASSERT_H#include <assert.h>#else#define assert(x) (void)0#endif#if !NO_STRING_H#include <string.h> /* for memmove() in bnMakeOdd */#elif HAVE_STRINGS_H#include <strings.h>#endif/* * This was useful during debugging, so it's left in here. * You can ignore it. DBMALLOC is generally undefined. */#if DBMALLOC#include "../dbmalloc/malloc.h"#define MALLOCDB malloc_chain_check(1)#else#define MALLOCDB (void)0#endif#include "lbn.h"#include "lbn16.h"#include "lbnmem.h"#include "bn16.h"#include "bn.h"#include "kludge.h" /* For memmove() *//* Functions */voidbnInit_16(void){ bnEnd = bnEnd_16; bnPrealloc = bnPrealloc_16; bnCopy = bnCopy_16; bnNorm = bnNorm_16; bnExtractBigBytes = bnExtractBigBytes_16; bnInsertBigBytes = bnInsertBigBytes_16; bnExtractLittleBytes = bnExtractLittleBytes_16; bnInsertLittleBytes = bnInsertLittleBytes_16; bnLSWord = bnLSWord_16; bnBits = bnBits_16; bnAdd = bnAdd_16; bnSub = bnSub_16; bnSetQ = bnSetQ_16; bnAddQ = bnAddQ_16; bnSubQ = bnSubQ_16; bnCmp = bnCmp_16; bnSquare = bnSquare_16; bnMul = bnMul_16; bnMulQ = bnMulQ_16; bnDivMod = bnDivMod_16; bnMod = bnMod_16; bnModQ = bnModQ_16; bnExpMod = bnExpMod_16; bnDoubleExpMod = bnDoubleExpMod_16; bnTwoExpMod = bnTwoExpMod_16; bnGcd = bnGcd_16; bnInv = bnInv_16; bnLShift = bnLShift_16; bnRShift = bnRShift_16; bnMakeOdd = bnMakeOdd_16;}voidbnEnd_16(struct BigNum *bn){ if (bn->ptr) { LBNFREE((BNWORD16 *)bn->ptr, bn->allocated); bn->ptr = 0; } bn->size = 0; bn->allocated = 0; MALLOCDB;}/* Internal function. It operates in words. */static intbnResize_16(struct BigNum *bn, unsigned len){ void *p; /* Round size up: most mallocs impose 8-byte granularity anyway */ len = (len + (8/sizeof(BNWORD16) - 1)) & ~(8/sizeof(BNWORD16) - 1); p = LBNREALLOC((BNWORD16 *)bn->ptr, bn->allocated, len); if (!p) return -1; bn->ptr = p; bn->allocated = len; MALLOCDB; return 0;}#define bnSizeCheck(bn, size) \ if (bn->allocated < size && bnResize_16(bn, size) < 0) \ return -1intbnPrealloc_16(struct BigNum *bn, unsigned bits){ bits = (bits + 16-1)/16; bnSizeCheck(bn, bits); MALLOCDB; return 0;}intbnCopy_16(struct BigNum *dest, struct BigNum const *src){ bnSizeCheck(dest, src->size); dest->size = src->size; lbnCopy_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, src->size); MALLOCDB; return 0;}voidbnNorm_16(struct BigNum *bn){ bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, bn->size);}/* * Convert a bignum to big-endian bytes. Returns, in big-endian form, a * substring of the bignum starting from lsbyte and "len" bytes long. * Unused high-order (leading) bytes are filled with 0. */voidbnExtractBigBytes_16(struct BigNum const *bn, unsigned char *dest, unsigned lsbyte, unsigned len){ unsigned s = bn->size * (16 / 8); /* Fill unused leading bytes with 0 */ while (s < lsbyte+len) { *dest++ = 0; len--; } if (len) lbnExtractBigBytes_16((BNWORD16 *)bn->ptr, dest, lsbyte, len); MALLOCDB;}intbnInsertBigBytes_16(struct BigNum *bn, unsigned char const *src, unsigned lsbyte, unsigned len){ unsigned s = bn->size; unsigned words = (len+lsbyte+sizeof(BNWORD16)-1) / sizeof(BNWORD16); /* Pad with zeros as required */ bnSizeCheck(bn, words); if (s < words) { lbnZero_16((BNWORD16 *)bn->ptr BIGLITTLE(-s,+s), words-s); s = words; } lbnInsertBigBytes_16((BNWORD16 *)bn->ptr, src, lsbyte, len); bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, s); MALLOCDB; return 0;}/* * Convert a bignum to little-endian bytes. Returns, in little-endian form, a * substring of the bignum starting from lsbyte and "len" bytes long. * Unused high-order (trailing) bytes are filled with 0. */voidbnExtractLittleBytes_16(struct BigNum const *bn, unsigned char *dest, unsigned lsbyte, unsigned len){ unsigned s = bn->size * (16 / 8); /* Fill unused leading bytes with 0 */ while (s < lsbyte+len) dest[--len] = 0; if (len) lbnExtractLittleBytes_16((BNWORD16 *)bn->ptr, dest, lsbyte, len); MALLOCDB;}intbnInsertLittleBytes_16(struct BigNum *bn, unsigned char const *src, unsigned lsbyte, unsigned len){ unsigned s = bn->size; unsigned words = (len+lsbyte+sizeof(BNWORD16)-1) / sizeof(BNWORD16); /* Pad with zeros as required */ bnSizeCheck(bn, words); if (s < words) { lbnZero_16((BNWORD16 *)bn->ptr BIGLITTLE(-s,+s), words-s); s = words; } lbnInsertLittleBytes_16((BNWORD16 *)bn->ptr, src, lsbyte, len); bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, s); MALLOCDB; return 0;}/* Return the least-significant word of the input. */unsignedbnLSWord_16(struct BigNum const *src){ return src->size ? (unsigned)((BNWORD16 *)src->ptr)[BIGLITTLE(-1,0)]: 0;}unsignedbnBits_16(struct BigNum const *src){ return lbnBits_16((BNWORD16 *)src->ptr, src->size);}intbnAdd_16(struct BigNum *dest, struct BigNum const *src){ unsigned s = src->size, d = dest->size; BNWORD16 t; if (!s) return 0; bnSizeCheck(dest, s); if (d < s) { lbnZero_16((BNWORD16 *)dest->ptr BIGLITTLE(-d,+d), s-d); dest->size = d = s; MALLOCDB; } t = lbnAddN_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s); MALLOCDB; if (t) { if (d > s) { t = lbnAdd1_16((BNWORD16 *)dest->ptr BIGLITTLE(-s,+s), d-s, t); MALLOCDB; } if (t) { bnSizeCheck(dest, d+1); ((BNWORD16 *)dest->ptr)[BIGLITTLE(-1-d,d)] = t; dest->size = d+1; } } return 0;}/* * dest -= src. * If dest goes negative, this produces the absolute value of * the difference (the negative of the true value) and returns 1. * Otherwise, it returls 0. */intbnSub_16(struct BigNum *dest, struct BigNum const *src){ unsigned s = src->size, d = dest->size; BNWORD16 t; if (d < s && d < (s = lbnNorm_16((BNWORD16 *)src->ptr, s))) { bnSizeCheck(dest, s); lbnZero_16((BNWORD16 *)dest->ptr BIGLITTLE(-d,+d), s-d); dest->size = d = s; MALLOCDB; } if (!s) return 0; t = lbnSubN_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s); MALLOCDB; if (t) { if (d > s) { t = lbnSub1_16((BNWORD16 *)dest->ptr BIGLITTLE(-s,+s), d-s, t); MALLOCDB; } if (t) { lbnNeg_16((BNWORD16 *)dest->ptr, d); dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dest->size); MALLOCDB; return 1; } } dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dest->size); return 0;}intbnSetQ_16(struct BigNum *dest, unsigned src){ if (src) { bnSizeCheck(dest, 1); ((BNWORD16 *)dest->ptr)[BIGLITTLE(-1,0)] = (BNWORD16)src; dest->size = 1; } else { dest->size = 0; } return 0;}intbnAddQ_16(struct BigNum *dest, unsigned src){ BNWORD16 t; if (!dest->size) return bnSetQ(dest, src); t = lbnAdd1_16((BNWORD16 *)dest->ptr, dest->size, (BNWORD16)src); MALLOCDB; if (t) { src = dest->size; bnSizeCheck(dest, src+1); ((BNWORD16 *)dest->ptr)[BIGLITTLE(-1-src,src)] = t; dest->size = src+1; } return 0;}/* * Return value as for bnSub: 1 if subtract underflowed, in which * case the return is the negative of the computed value. */intbnSubQ_16(struct BigNum *dest, unsigned src){ BNWORD16 t; if (!dest->size) return bnSetQ(dest, src) < 0 ? -1 : (src != 0); t = lbnSub1_16((BNWORD16 *)dest->ptr, dest->size, src); MALLOCDB; if (t) { /* Underflow. <= 1 word, so do it simply. */ lbnNeg_16((BNWORD16 *)dest->ptr, 1); dest->size = 1; return 1; }/* Try to normalize? Needing this is going to be pretty damn rare. *//* dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dest->size); */ return 0;}/* * Compare two BigNums. Returns -1. 0 or 1 if a<b, a == b or a>b. * a <=> b --> bnCmp(a,b) <=> 0 */intbnCmp_16(struct BigNum const *a, struct BigNum const *b){ unsigned s, t; s = lbnNorm_16((BNWORD16 *)a->ptr, a->size); t = lbnNorm_16((BNWORD16 *)b->ptr, b->size); if (s != t) return s > t ? 1 : -1; return lbnCmp_16((BNWORD16 *)a->ptr, (BNWORD16 *)b->ptr, s);}intbnSquare_16(struct BigNum *dest, struct BigNum const *src){ unsigned s; BNWORD16 *srcbuf; s = lbnNorm_16((BNWORD16 *)src->ptr, src->size); if (!s) { dest->size = 0; return 0; } bnSizeCheck(dest, 2*s); if (src == dest) { LBNALLOC(srcbuf, s); if (!srcbuf) return -1; lbnCopy_16(srcbuf, (BNWORD16 *)src->ptr, s); lbnSquare_16((BNWORD16 *)dest->ptr, (BNWORD16 *)srcbuf, s); LBNFREE(srcbuf, s); } else { lbnSquare_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s); } dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, 2*s); MALLOCDB; return 0;}intbnMul_16(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b){ unsigned s, t; BNWORD16 *srcbuf; s = lbnNorm_16((BNWORD16 *)a->ptr, a->size); t = lbnNorm_16((BNWORD16 *)b->ptr, b->size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -