Bigint.C
上传用户:zbbssh
上传日期:2007-01-08
资源大小:196k
文件大小:8k
源码类别:

CA认证

开发平台:

C/C++

  1. /*
  2. ------------------------------------------------------------------
  3.   Copyright
  4.   Sun Microsystems, Inc.
  5.   Copyright (C) 1994, 1995, 1996 Sun Microsystems, Inc.  All Rights
  6.   Reserved.
  7.   Permission is hereby granted, free of charge, to any person
  8.   obtaining a copy of this software and associated documentation
  9.   files (the "Software"), to deal in the Software without
  10.   restriction, including without limitation the rights to use,
  11.   copy, modify, merge, publish, distribute, sublicense, and/or sell
  12.   copies of the Software or derivatives of the Software, and to 
  13.   permit persons to whom the Software or its derivatives is furnished 
  14.   to do so, subject to the following conditions:
  15.   The above copyright notice and this permission notice shall be
  16.   included in all copies or substantial portions of the Software.
  17.   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18.   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  19.   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20.   NONINFRINGEMENT.  IN NO EVENT SHALL SUN MICROSYSTEMS, INC., BE LIABLE
  21.   FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22.   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.   CONNECTION WITH THE SOFTWARE OR DERIVATES OF THIS SOFTWARE OR 
  24.   THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.   Except as contained in this notice, the name of Sun Microsystems, Inc.
  26.   shall not be used in advertising or otherwise to promote
  27.   the sale, use or other dealings in this Software or its derivatives 
  28.   without prior written authorization from Sun Microsystems, Inc.
  29. */
  30. #pragma ident "@(#)Bigint.C 1.7 96/01/29 Sun Microsystems"
  31. #include <sys/types.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #define GUIDE_INCLUDES
  35. #include "my_types.h"
  36. #include "Bstream.h"
  37. #include "Bigint.h"
  38. #include "Time.h"
  39. #include "asn1_der.h"
  40. #ifndef SOLARIS2
  41. extern "C" {
  42. void bzero(void *, int);
  43. };
  44. #endif 
  45. Bigint::Bigint() 
  46. {
  47. flag = USE_DOUBLE;
  48. longint = 0;
  49. }
  50. Bigint::Bigint(short n) 
  51. {
  52. flag = USE_DOUBLE;
  53. longint = n;
  54. }
  55. byte
  56. atob(char c)
  57. {
  58.         if (c >= '0' && c <= '9') {
  59.                 return(c - '0');
  60.         } else if (c >= 'a' && c <= 'f') {
  61.                 return(c - 'a' + 10);
  62.         } else if (c >= 'A' && c <= 'F') {
  63.                 return(c - 'A' + 10);
  64.         } else {
  65.                 return(0xff);
  66.         }
  67. }
  68. byte
  69. bigintatob(char c)
  70. {
  71. if (c >= '0' && c <= '9') {
  72. return(c - '0');
  73. } else if (c >= 'a' && c <= 'f') {
  74. return(c - 'a' + 10);
  75. } else if (c >= 'A' && c <= 'F') {
  76. return(c - 'A' + 10);
  77. } else {
  78. return(0xff);
  79. }
  80. }
  81. Bigint::Bigint(const char *s) 
  82. {
  83. if (strlen(s) < sizeof(longint)*2) {
  84. flag = USE_DOUBLE;
  85. longint = strtol(s, NULL, 16);
  86. } else {
  87. while (*s == '0' ) 
  88. s++;
  89. flag = USE_BSTREAM;
  90. const char *inthexstr = s;
  91. int len = strlen(s);
  92. Boolean isodd = BOOL_FALSE;
  93. if (len & 0x01) { // odd number of digits
  94. len++;
  95. isodd = BOOL_TRUE;
  96. }
  97. int intlen = len/2;
  98. byte *intstr = new byte[intlen]; // a hex digit takes half an octet
  99. bzero(intstr, intlen);
  100. for (int i=0, j=0; i < intlen; i++) {
  101. byte hinib, lonib;
  102. if (isodd == BOOL_TRUE && i == 0) {
  103. hinib = 0x0;
  104. lonib = bigintatob((char )inthexstr[j]);
  105. j += 1;
  106. } else {
  107. hinib = bigintatob((char )inthexstr[j]);
  108. lonib = bigintatob((char )inthexstr[j+1]);
  109. j += 2;
  110. }
  111. intstr[i] = (hinib << 4) | lonib;
  112. }
  113. bstrint = Bstream(intlen, intstr);
  114. }
  115. }
  116. #ifdef BIGINT_DEBUG
  117. int inline convert_bytes_to_int(byte *four_bytes)
  118. {
  119. #if defined(sparc)
  120. int val;
  121. byte *bytep = (byte *)&val;
  122. bytep[0] = four_bytes[3];
  123. bytep[1] = four_bytes[2];
  124. bytep[2] = four_bytes[1];
  125. bytep[3] = four_bytes[0];
  126. return (val);
  127. #else
  128. printf("convert_bytes_to_int: machine architecture not supportedn");
  129. return (-1);
  130. #endif
  131. }
  132. #else BIGINT_DEBUG
  133. extern int convert_bytes_to_int(byte *);
  134. #endif BIGINT_DEBUG
  135. Bigint::Bigint(const unsigned char *d, int len)
  136. {
  137. while (*d == 0 && len > 0) {
  138. d++;len--;
  139. }
  140. if (len > 4) {
  141. flag = USE_BSTREAM;
  142. bstrint = Bstream(len, (byte *)d);
  143. } else {
  144. int i,j;
  145. flag = USE_DOUBLE;
  146. byte fourbytes[4];
  147. bzero(fourbytes, sizeof(fourbytes));
  148. for (i = len - 1, j=0; i >= 0; i--, j++) {
  149. fourbytes[i] = d[j];
  150. }
  151. longint = convert_bytes_to_int(fourbytes);
  152. }
  153. }
  154. Bigint::~Bigint() 
  155. {
  156. }
  157. Bigint::Bigint(const Bigint &a)
  158. {
  159. flag = a.flag;
  160. longint = a.longint;
  161. bstrint = a.bstrint;
  162. }
  163. Bigint&
  164. Bigint:: operator =(const Bigint &a)
  165. {
  166. // Release memory from old information, if any
  167. // XXX- TM
  168. // Bigint::~Bigint();
  169. flag = a.flag;
  170. longint = a.longint;
  171. bstrint = a.bstrint;
  172. return (*this);
  173. }
  174. Bigint operator + (const Bigint& a, const Bigint& b)
  175. {
  176. Bigint c;
  177. if ((a.flag == b.flag) && (a.flag == USE_DOUBLE)) {
  178. c.longint = a.longint + b.longint;
  179. return (c);
  180. }
  181. fprintf(stderr, "Bigint: Cannot add larger than double valuesn");
  182. abort();
  183. return (c);
  184. }
  185. Bigint operator * (const Bigint& a, const Bigint& b)
  186. {
  187. Bigint c;
  188. if ((a.flag == b.flag) && (a.flag == USE_DOUBLE)) {
  189. c.longint = a.longint * b.longint;
  190. return (c);
  191. }
  192. fprintf(stderr, "Bigint: Cannot multiply larger than double valuesn");
  193. abort();
  194. return (c);
  195. }
  196. Bigint operator - (const Bigint& a, const Bigint& b)
  197. {
  198. Bigint c;
  199. if ((a.flag == b.flag) && (a.flag == USE_DOUBLE)) {
  200. c.longint = a.longint - b.longint;
  201. return (c);
  202. }
  203. fprintf(stderr, "Bigint: Cannot subtract larger than double valuesn");
  204. abort();
  205. return (c);
  206. }
  207. Boolean operator ==(const Bigint& a, const Bigint& b)
  208. {
  209. if ((a.flag == b.flag) && (a.flag == USE_DOUBLE)) {
  210. if (a.longint == b.longint)
  211. return TRUE;
  212. else
  213. return FALSE;
  214. } else {
  215. if (a.bstrint == b.bstrint)
  216. return TRUE;
  217. else
  218. return FALSE;
  219. }
  220. }
  221. Boolean operator !=(const Bigint& a, const Bigint& b)
  222. {
  223. if (a == b)
  224. return FALSE;
  225. else
  226. return TRUE;
  227. }
  228. Boolean operator <(const Bigint& a, const Bigint& b)
  229. {
  230. if ((a.flag == b.flag) && a.flag == USE_DOUBLE) {
  231. return (a.longint < b.longint);
  232. }
  233. fprintf(stderr, "Cannot check for < for this Bigintn");
  234. abort();
  235. return TRUE;
  236. }
  237. // Hex output
  238. void Bigint::print() const
  239. {
  240. if (flag == USE_DOUBLE) {
  241. printf("%x", longint);
  242. } else {
  243. bstrint.printhexint();
  244. }
  245. return;
  246. }
  247. // Decimal output
  248. void Bigint::printd() const
  249. {
  250. if (flag == USE_DOUBLE) {
  251. printf("%d", longint);
  252. } else {
  253. bstrint.printdecint();
  254. }
  255. return;
  256. }
  257. // Hex output to a String
  258. String Bigint::getnumstr() const
  259. {
  260. char buf[100];
  261. bzero(buf, sizeof(buf));
  262. if (flag == USE_DOUBLE) {
  263. sprintf(buf,"%x", longint);
  264. String numstr = buf;
  265. return numstr;
  266. } else {
  267. return bstrint.gethexstr();
  268. }
  269. }
  270. // Decimal output to a String
  271. String Bigint::getnumstrd() const
  272. {
  273. char buf[100];
  274. bzero(buf, sizeof(buf));
  275. if (flag == USE_DOUBLE) {
  276. sprintf(buf,"%d", longint);
  277. String numstr = buf;
  278. return numstr;
  279. } else {
  280. return bstrint.getdecstr();
  281. }
  282. }
  283. Bstream Bigint::getbstr() const
  284. {
  285. Bstream result;
  286. return bstrint;
  287. }
  288. int Bigint::bits() const
  289. {
  290.         Bstream temp;
  291. temp = Bigint_to_Bstr(*this);
  292.         int n;
  293.         byte s;
  294.         do {
  295.                 temp.peekbyte(s);
  296.                 if (s == 0)
  297.                         temp.consume(1);
  298.         } while (s == 0);
  299.         return (temp.getlength()*8);
  300. }
  301. // Converts Bigint to a unsigned char *, returning number of bytes in bigint
  302. int convert_Bigint_to_bytes(const Bigint b, int n, unsigned char *buf)
  303. {
  304. Bstream bstr;
  305. byte s;
  306. int diff;
  307. bstr = Bigint_to_Bstr(b);
  308. // strip off leading zeros
  309. do {
  310. bstr.peekbyte(s);
  311. if (s == 0)
  312. bstr.consume(1);
  313. } while (s == 0);
  314. bzero(buf, n);
  315. diff = n - bstr.getlength();
  316. bcopy(bstr.getdatap(), buf+diff, bstr.getlength());
  317. return (bstr.getlength());
  318. }
  319. Bstream
  320. Bigint_to_Bstr(const Bigint& val)
  321. {
  322. // G++ will produce nasty memory bugs with this line
  323. // const char *inthexstr = (const char *)val.getnumstr();
  324. String hexstr=val.getnumstr();
  325. const char *inthexstr = (const char *)hexstr;
  326.         while (*inthexstr == '0' )
  327.                 inthexstr++;
  328. int len = strlen(inthexstr);
  329. Boolean isodd = BOOL_FALSE;
  330. if (len & 0x01) { // odd number of digits
  331. len++;
  332. isodd = BOOL_TRUE;
  333. }
  334. int intlen = len/2;
  335. byte *intstr = new byte[intlen]; // a hex digit takes half an octet
  336. bzero(intstr, intlen);
  337. for (int i=0, j=0; i < intlen; i++) {
  338. byte hinib, lonib;
  339. if (isodd == BOOL_TRUE && i == 0) {
  340. hinib = 0x0;
  341. lonib = atob((char )inthexstr[j]);
  342. j += 1;
  343. } else {
  344. hinib = atob((char )inthexstr[j]);
  345. lonib = atob((char )inthexstr[j+1]);
  346. j += 2;
  347. }
  348. intstr[i] = (hinib << 4) | lonib;
  349. }
  350. Bstream res = Bstream(intlen, intstr);
  351. delete intstr;
  352. return res;
  353. }