home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / crypl200.zip / BNLIB / BN.DOC < prev    next >
Text File  |  1996-01-28  |  24KB  |  533 lines

  1. * The BigNum multi-precision integer math library
  2.  
  3. This is a multi-precision math library designed to be very portable,
  4. reasonably clean and easy to use, have very liberal bounds on the sizes
  5. of numbers that can be represented, but above all to perform extremely
  6. fast modular exponentiation.  It has some limitations, such as
  7. representing positive numbers only, and supporting only odd moduli,
  8. which simplify it without impairing this ability.
  9.  
  10. A second speed goal which has had considerable effort applied to it is
  11. prime number generation.
  12.  
  13. Finally, while there is probably a long way to go in this direction,
  14. some effort has gone into commenting the code a lot more than seems to
  15. be fashionable among mathematicians.
  16.  
  17. It is written in C, and should compile on any platform with an ANSI C
  18. compiler and 16 and 32-bit unsigned data types, but various primitives
  19. can be replaced with assembly versions in a great variety of ways for
  20. greater speedup.  See "bnintern.doc" for a description.
  21.  
  22. In case you're wondering, yes C++ would produce a much nicer syntax
  23. for working with these numbers, but there are a lot of compilers out
  24. there that actually implement ANSI C, and get it almost right.  I have
  25. a few kludges to deal with some that get little things wrong, but
  26. overall it's not too difficult to write code that I can be sure
  27. will work on lots of machines.  And porting it to a K&R C compiler,
  28. if it ever becomes necessary, shouldn't be all *that* difficult.
  29.  
  30. The C++ compiler world is a less friendly place.  First of all, C++
  31. compilers are still not as common as C compilers, so that hurts
  32. portability right there, and I don't need the extra power to write my
  33. code.  C++ compilers all seem to have important bugs, and different
  34. bugs for each compiler.  First I have to learn all the foibles of a
  35. whole lot of C++ compilers, and then I have write code that uses only
  36. the features that work in all of them.  This is a language not a whole
  37. heck of a lot bigger than C.
  38.  
  39. (The fact that it drives me *batty* the way that C++ drags *everything*
  40. into the same name space is also a contributing factor.  I *like*
  41. writing "struct" (or "class") before structure names.  I *like* putting
  42. "this->" in front of member references.  It makes it clear to me, when
  43. reading a single line of code, roughly what is being affected by it and
  44. where I can find the relevant source code to find out more.  I've seen
  45. people develop complicated naming conventions to make all this clear,
  46. but the conventions are still very much in flux.)
  47.  
  48. Anyway...
  49.  
  50. The main public interface is contained in the file bn.h.  This is
  51. mostly a bunch of pointers to functions which start out uninitialized.
  52. The bnInit() function sets this up.  It must be called before any other
  53. routine in the library.
  54.  
  55. All of the public routines have names of the bnFunction variety.
  56. Some internal routines are lbnFunction, but you should never have to
  57. worry about those unless you're hacking with the code.
  58.  
  59. The code uses the assert() macro a lot internally.  If you do something
  60. you're not supposed to, you'll generally notice because an assert()
  61. will fail.  The library does not have special error codes for division
  62. by zero or the like - it assert fails instead.  Just don't do that.
  63.  
  64. A BigNum is represented by a struct BigNum, which really doesn't
  65. need to be understood, but it often makes me feel better to understand
  66. what's going on, so here it is:
  67.  
  68. #> struct BigNum {
  69. #>    void *ptr;
  70. #>    unsigned size;    /* Note: in (variable-sized) words */
  71. #>    unsigned allocated;
  72. #> };
  73.  
  74. The pointer points to the least-significant end of an array of words which
  75. hold the number.  The array contains "allocated" words, but only "size"
  76. of them are actually meaningful.  The others may have any value.
  77. This is all of limited use because the size of a word is not specified.
  78. In fact, it can change at run time - if you run on an 8086 one day and an
  79. 80386 the next, you may find the word size different.
  80.  
  81. * Initialization
  82.  
  83. The first function you have to call is this:
  84. #> void bnInit(void);
  85. This sets up the library for use.  It is idempotent, so you can call it
  86. multiple times if you like.  The only thing it does right now is set
  87. up the function pointers to the rest of the library.  If you crash
  88. a program and the debugger tells you that it's trying to execute at
  89. address 0, you forgot to call bnInit.
  90.  
  91. The user of the library is responsible for allocating and freeing the struct
  92. BigNum.  All the library functions take pointers to them.  The first thing
  93. you need to do is initialize all the fields to empty, a zero-valued BigNum.
  94. This is done with the function bnBegin:
  95. #> void bnBegin(struct BigNum *bn);
  96.  
  97. When you're done with a BigNum, call bnEnd to deallocate the data storage
  98. in preparation for deallocating the structure:
  99. #> void bnEnd(struct BigNum *bn);
  100.  
  101. This resets the number to the 0 state.  You can actually start using the
  102. number right away again, or call bnEnd again, so if you're really
  103. memory-conscious you might want to use this to free a large
  104. number you're done with this way before going on to use the buffer
  105. for smaller things.
  106.  
  107. A simple assignment can be done with bnCopy.  
  108. #> int bnCopy(struct BigNum *dest, struct BigNum const *src);
  109.  
  110. This sets dest = src, and returns an error code.  Most functions in the
  111. library do this, and return 0 on success and -1 if they were unable to
  112. allocate needed memory.  If you're lazy and sure you'll never run out
  113. of memory, you can avoid checking this, but it's better to be
  114. paranoid.  If a function returns -1, the what has happened to the
  115. destination values is undefined.  They're usually unmodified, and
  116. they're always still valid BigNum numbers, but their values might be
  117. strange.
  118.  
  119. In general, anywhere that follows, unless otherwise documented, assume
  120. that an "int" return value is 0 for success or -1 for error.
  121.  
  122. A trivial little function which is sometimes handy, and quite cheap to
  123. execute (it just swaps the pointers) is:
  124. #> void bnSwap(struct BigNum *a, struct BigNum *b);
  125.  
  126. * Input and output
  127.  
  128. For now, the library only works with numbers in binary form - there's
  129. no way to get decimal numbers into or out of it.  But it's pretty
  130. flexible on how it does that.
  131.  
  132. The first function just sets a BigNum to have a small value.
  133. "small" is defined as less than 2^16, the minimum word size supported
  134. by the library.  This is still useful for a lot of work.
  135. #> int bnSetQ(struct BigNum *dest, unsigned src);
  136.  
  137. This returns the usual -1 error if it couldn't allocate memory.
  138.  
  139. There's also a function to determine the size of a BigNum, in bits.
  140. The size is the number of bits required to represent the number,
  141. 0 if the number is 0, and floor(log2(src)) + 1 otherwise.  E.g. 1 is
  142. the only 1-bit number, 2 and 3 are 2-bit numbers, etc.
  143. #> unsigned bnBits(struct BigNum const *src);
  144.  
  145. If bnBits(src) <= 16, you can get the whole number with this function.
  146. If it's larger, you get the low k bits, where k is at least 16.
  147. (This doesn't bother masking if it's easy to return more, but you
  148. shouldn't rely on it.)  Even that is useful for many things, like
  149. deciding if a number is even or odd.
  150. #> unsigned bnLSWord(struct BigNum const *src);
  151.  
  152. For larger numbers, the format used by the library is an array of
  153. unsigned 8-bit bytes.  These bytes may be in big-endian or little-endian
  154. order, and it's possible to examine or change just part of a number.
  155. The functions are:
  156. #> void bnExtractBigBytes(struct BigNum const *bn, unsigned char *dest,
  157. #>     unsigned lsbyte, unsigned len);
  158. #> int bnInsertBigBytes(struct BigNum *bn, unsigned char const *src,
  159. #>     unsigned lsbyte, unsigned len);
  160. #> void bnExtractLittleBytes(struct BigNum const *bn, unsigned char *dest,
  161. #>     unsigned lsbyte, unsigned len);
  162. #> int bnInsertLittleBytes(struct BigNum *bn, unsigned char const *src,
  163. #>     unsigned lsbyte, unsigned len);
  164.  
  165. These move bytes between the BigNum and the buffer of 8-bit bytes.  The
  166. Insert functions can allocate memory, so return an error code.  The
  167. Extract functions always succeed.
  168.  
  169. The buffer is encoded in base 256, with either the most significant
  170. byte (the Big functions) or the least significant byte (the Little
  171. functions) coming first.  "len" is the length of the buffer, so the
  172. buffer always encodes a value between 0 and 256^len.  (That's
  173. "to the power of", not "xor".)
  174.  
  175. "lsbyte" gives the offset into the BigNum which is being worked with.
  176. This is usually zero, but you can, for example, read out a large
  177. BigNum in 32-byte chunks, using a len of 32 and an lsbyte of 0, 32,
  178. 64, 96, etc.
  179.  
  180. After these complete, the number encoded in the buffer will be
  181. equal to (bn / 256^lsbyte) % 256^len.  The only difference between
  182. Insert and Extract is which is changed to match the other.
  183.  
  184. * Simple math
  185.  
  186. #> int bnAdd(struct BigNum *dest, struct BigNum const *src);
  187. #> int bnAddQ(struct BigNum *dest, unsigned src);
  188.  
  189. These add dest += src.  In the Q form, src must be < 65536.  In either
  190. case, the functions can fail and return -1, as usual.
  191.  
  192. #> int bnSub(struct BigNum *dest, struct BigNum const *src);
  193. #> int bnSubQ(struct BigNum *dest, unsigned src);
  194.  
  195. These subtract dest -= src.  If this would make the result negative,
  196. dest is set to (src-dest) and a value of 1 is returned, so you can
  197. keep track of a separate sign if you need to.  Otherwise, they return
  198. 0 on success and -1 if they were unable to allocate needed memory.
  199.  
  200. To make your life simpler if you are error checking, these are guaranteed
  201. not to allocate memory unnecessarily.  So if you know that the addition
  202. or subtraction you're doing won't produce a result larger than the
  203. input, and won't underflow either (like subtracting 1 from an odd
  204. number or adding 1 to an even number), you can skip checking the
  205. error code.
  206.  
  207. #> extern int (*bnCmp)(struct BigNum const *a, struct BigNum const *b);
  208. This returns the sign (-1, 0 or +1) of a-b.  Another way of saying
  209. this is that a <=> b is the same as bnCmp(a, b) <=> 0,
  210. where "<=>" stands for any of <, <=, =, !=, >= or >.
  211.  
  212. #> int bnSquare(struct BigNum *dest, struct BigNum const *src);
  213.  
  214. This computes dest = src^2, returning an error if it ran out of memory.
  215. If you care about performance tuning, this slows down when dest and
  216. src are the same BigNum, since it needs to allocate a temporary buffer
  217. to do the work in.  It does work, however.
  218.  
  219. #> int bnMul(struct BigNum *dest, struct BigNum const *a,
  220. #>    struct BigNum const *b);
  221. #> int bnMulQ(struct BigNum *dest, struct BigNum const *a, unsigned b);
  222.  
  223. These compute dest = a * b, and work in the same way as bnSquare.
  224. (Including the comment about preferring if dest is not the same as any of
  225. the inputs.)  bnSquare is faster if a and b are the same.
  226.  
  227. #> int bnDivMod(struct BigNum *q, struct BigNum *r,
  228. #>    struct BigNum const *n, struct BigNum const *d);
  229.  
  230. This computes division with remainder, q = n/d and r = n%d.  Don't
  231. pass in a zero d; it will blow up.  In general, all of the values
  232. must be different (it will blow up if you try), but r and n may be the
  233. same.
  234.  
  235. RE-ENTRANCY NOTE: This temporarily modifies the BigNum "d" internally,
  236. although it restores it before returning.  If you're doing something
  237. multi-threaded, you can't share the d value between threads, even though
  238. it says "const".  That's a safe assumption elsewhere, but this is an
  239. exception.
  240.  
  241. That note also means that it's not safe to let n be the same as d,
  242. although that's such a stupid way to set q to 1 and r to 0 that
  243. I don't think it's worth worrying about.  (I hope you understand that
  244. this doesn't mean that n and d can't have the same numerical value,
  245. just that they can't both point to the same struct BigNum.)
  246.  
  247. #> int bnMod(struct BigNum *dest, struct BigNum const *src,
  248. #>     struct BigNum const *d);
  249.  
  250. This works just the same as the above, but doesn't bother you with the
  251. quotient.  (No, there's no function that doesn't bother you with the
  252. remainder.)  Again, dest and src may be the same (it's actually
  253. more efficient if they are), but d may not be the same as either.
  254.  
  255. #> unsigned int bnModQ(struct BigNum const *src, unsigned d);
  256.  
  257. This also computes src % d, but does so for small (up to 65535,
  258. the usual limit on "Q" functions) values of d.  It returns the
  259. remainder.
  260.  
  261. * Advanced math
  262.  
  263. #> int bnLShift(struct BigNum *dest, unsigned amt);
  264. #> void bnRShift(struct BigNum *dest, unsigned amt);
  265.  
  266. These shift the given bignum left or right by "amt" bit positions.
  267. Left shifts multiply by 2^amt, and may have to allocate memory
  268. (and thus fail).  Right shifts divide by 2^amt, throwing away the
  269. remainder, and can never fail.
  270.  
  271. #> unsigned bnMakeOdd(struct BigNum *n);
  272.  
  273. This right shifts the input number as many places as possible without
  274. throwing anything away, and returns the number of bits shifted.
  275. If you see "let n = s * 2^t, where s is odd" in an algorithm,
  276. this is the function to call.  It modifies n in place to produce s
  277. and returns t.
  278.  
  279. This returns 0 if you pass it 0.
  280.  
  281. #> int bnExpMod(struct BigNum *result, struct BigNum const *n,
  282. #>     struct BigNum const *exp, struct BigNum const *mod);
  283.  
  284. Ah, now we get to the heart of the library - probably the most heavily
  285. optimized function in it.  This computes result = n^exp, modulo "mod".
  286. result may be the same as n, but not the same as exp or mod.  For large
  287. exponents and moduli, it can try to allocate quite a bit of working
  288. storage, although it will manage to finish its work (just slower)
  289. if some of those allocations fail.  (Not all, though - the first few
  290. are essential.)
  291.  
  292. "mod" must be odd.  It will blow up if not.  Also, n must be less than
  293. mod.  If you're not sure if it is, use bnMod first.  The return value
  294. is always between 0 and mod-1.
  295.  
  296. #> int bnTwoExpMod(struct BigNum *result, struct BigNum const *exp,
  297. #>    struct BigNum const *mod);
  298.  
  299. This computes result = 2^exp, modulo "mod".  It's faster than the general
  300. bnExpMod function, although that function checks to see if n = 2 and calls
  301. this one internally, so you don't need to check yourself if you're not
  302. sure.  The main reason to mention this is that if you're doing something
  303. like a pseudoprimality test, using a base of 2 first can save some time.
  304.  
  305. #> int bnDoubleExpMod(struct BigNum *result,
  306. #>     struct BigNum const *n1, struct BigNum const *e1,
  307. #>     struct BigNum const *n2, struct BigNum const *e2,
  308. #>     struct BigNum const *mod);
  309.  
  310. This computes dest = n1^e1 * n2^e2, modulo "mod".  It does it quite
  311. a bit faster than doing two separate bnExpMod operations; in fact,
  312. it's not that much more expensive than one.  "result" may be the
  313. same BigNum as n1 or n2, but it may not be the same as the exponents
  314. or the modulus.  All of the other caveats about bnExpMod apply.
  315.  
  316. #> int bnGcd(struct BigNum *dest, struct BigNum const *a,
  317. #>    struct BigNum const *b);
  318.  
  319. This returns dest = gcd(a,b).  dest may be the same as either input.
  320.  
  321. /* dest = src^-1, modulo "mod".  dest may be the same as src. */
  322. #> int bnInv(struct BigNum *dest, struct BigNum const *src,
  323. #>    struct BigNum const *mod);
  324.  
  325. This requires that gcd(src, mod) = 1, and returns dest = src^-1, modulo
  326. "mod".  That is, 0 < dest < mod and dest*src = 1, modulo "mod".
  327. dest and src may be the same, but mod must be different.
  328.  
  329. This will probably get extended at some point to find dest such that
  330. dest * src = gcd(src, mod), modulo "mod", but that isn't implemented
  331. yet.
  332.  
  333. * Auxiliary functions
  334.  
  335. These functions have very limited usefulness, and might even get removed,
  336. but for now they're there in the unusual case where you might want them.
  337.  
  338. #> int bnPrealloc(struct BigNum *bn, unsigned bits);
  339.  
  340. This preallocates space in bn to make sure that it can hold "bits" bits.
  341. If the overflow characteristics of various algorithms get documented
  342. better, this might allow even more error-checking to be avoided, but
  343. for now it's only to reduce memory fragmentation.
  344.  
  345. #> void bnNorm(struct BigNum *bn);
  346.  
  347. This decreases the "size" field of the given bignum until it has no leading
  348. zero words in its internal representation.  Given that almost everything
  349. in the library does the equivalent of this on input and output, the utility
  350. of this function is a bit dubious.  It's kind of a legacy.
  351.  
  352. * Extra libraries
  353.  
  354. There are a number of utilities built on top of the basic library.
  355. They are built on top of the interfaces just described, and can be used
  356. if you like.
  357.  
  358. * jacobi.h
  359.  
  360. #> int bnJacobiQ(unsigned p, struct BigNum const *bn);
  361.  
  362. This returns the Jacobi symbol J(p,bn), where p is a small number.
  363. The Jacobi symbol is always -1, 0, or +1.  You'll note that p may
  364. only be positive, even though the Jacobi symbol is defined for
  365. negative p.  If you want to worry about negative p, do it yourself.
  366. J(-p,bn) = (bnLSWord(bn) & 2 ? -1 : +1) * bnJacobiQ(p, bn).
  367.  
  368. A function to compute the Jacobi symbol for large p would be nice.
  369.  
  370. * prime.h
  371.  
  372. #> int primeGen(struct BigNum *bn, unsigned (*rand)(unsigned),
  373. #>     int (*f)(void *arg, int c), void *arg, unsigned exponent, ...);
  374.  
  375. This finds the next prime p >= bn, and sets bn to equal it.
  376. Well, sort of.
  377.  
  378. It always leaves bn at least as large as when it started (unless it
  379. runs out of memory and returns -1), and if you pass a 0 for the rand
  380. function, it will be the next prime >= bn.
  381.  
  382. Except:
  383. - It doesn't bother coping with small primes.  If it's divisible by any
  384. prime up to 65521, it's considered non-prime.  Even if the quotient is 0.
  385. If you pass in "1", expecting to get "2" back, you'll get 65537.  Maybe
  386. it would be nice to fix that.
  387. - It actually only does a few strong pseudoprimality tests to fixed
  388. bases to determine if the candidate number is prime.  For random input,
  389. this is fine; the chance of error is so infinitesimal that it is
  390. absolutely not worth worrying about.  But if you give it numbers carefully
  391. chosen to be strong pseudoprimes, it will think they're primes and not
  392. complain.  For example, 341550071728321 = 10670053 * 32010157 will
  393. pass the primality test quite handily.  So will
  394. 68528663395046912244223605902738356719751082784386681071.
  395. - If you supply a rand() function, which returns 0 <= rand(n) < n
  396. (n never gets very large - currently, at most 256), this shuffles the
  397. candidates before testing and accepting one.  If you want a "random"
  398. prime, this produces a more uniformly distributed prime, while
  399. retaining all of the speed advantages of a sequential search from a
  400. random starting point, which would otherwise produce a bias towards
  401. primes which were not closely preceded by other primes.  So, for
  402. example, the second of a pair of twin primes would be very unlikely to
  403. be chosen.  rand() doesn't totally flatten the distribution, but it
  404. comes very close.
  405.  
  406. The "f" function is called periodically during the progress of the
  407. search (which can take a while) with the supplied argument (for private
  408. context) and a character c, which sort of tells you what it's doing.
  409. c is either '.' or '*' (if it's found something and is confirming that
  410. it's really prime) or '/' (if it's having a really hard time finding
  411. something).  Also, if f returns < 0, primeGen immediately returns that
  412. value.  This can form the basis for a user interface which can show some
  413. life occasionally and abort the computation if desired.
  414.  
  415. If you just print these characters to the screen, don't forget to
  416. fflush() after printing them.
  417.  
  418. Finally, "exponent, ..." is a zero-terminated list of small numbers
  419. which must not divide p-1 when the function returns.  If the numbers
  420. are chosen to be the prime factors of n, then gcd(n, p-1) will be
  421. 1, so the map f(x) -> x^n is invertible modulo p.
  422.  
  423. #> int primeGenStrong(struct BigNum *bn, struct BigNum const *step,
  424. #>    int (*f)(void *arg, int c), void *arg);
  425.  
  426. This is similar, but searches in steps of "step", rather than 1, from the
  427. given starting value.  The starting value must be odd and the step
  428. size must be even!  If you start with bn == 1 (mod step), and step
  429. is 2*q, where q is a large prime, then this generates "strong" primes,
  430. p-1 having a large prime factor q.  There are other uses, too.
  431.  
  432. #ifdef __cplusplus
  433. }
  434. #endif
  435.  
  436. * germain.h
  437.  
  438. #> int germainPrimeGen(struct BigNum *bn, int (*f)(void *arg, int c),
  439. #>    void *arg);
  440.  
  441. This increases bn until it is a Sophie Germain prime, that is, a number p
  442. such that p and (p-1)/2 are both prime.  These numbers are rarer than
  443. ordinary primes and the search takes correspondingly longer.
  444.  
  445. It omits the randomization portion of primeGen, and the exponent list,
  446. since the factors of bn-1 are known already.  The f function for
  447. progress is the same, but it is also sometimes passed a '+' or '-'
  448. character when it's found a (p-1)/2 that's prime.  This is just to lend
  449. some interest to an otherwise very boring row of dots.  Finding large
  450. primes with this function, even though it's pretty optimized, takes a
  451. *while*, and otherwise once the screen filled with dots (one every few
  452. seconds) it would be hard to keep track of the scroll.
  453.  
  454. It varies a lot, depending on luck of the starting value and the speed
  455. of your machine, but if your starting number is over 1024 bits, plan on
  456. over an hour of run time, and if it's over 2048 bits, plan on a day.
  457. At 4096 bits, start thinking about a week.
  458.  
  459. Past that, supporting checkpoint/restart is a good idea.  Every time
  460. the progress function gets a '/' is probably a good interval, and when
  461. it happens have f return a distinct error value like -2.  When
  462. germainPrimeGen returns with that value, save the value in bn to a file
  463. somewhere and call it again with the same bn to continue searching.
  464.  
  465. * sieve.h
  466.  
  467. This is the sieving code that the other prime-finding functions call
  468. to do trial division.  You might use it if you are doing some magic
  469. prime-finding of your own.  A sieve is an array of bits, stored
  470. little-endian in an array of bytes (i.e. the lsb of byte 0 is bit 0).
  471. Sieves are indexed with the "unsigned" data type, so should not, for
  472. portability, be larger than 65536/8 = 8192 bytes long.
  473.  
  474. A 1 bit is considered "in" the sieve, it has passed all the sieving.
  475. A 0 bit has been removed by some step.
  476.  
  477. The functions are:
  478.  
  479. #> void sieveSingle(unsigned char *array, unsigned size, unsigned start,
  480. #>    unsigned step);
  481.  
  482. This (efficiently) clears the bits at positions start, start+step,
  483. start+2*step, etc. in the sieve given by array and size.  This is the
  484. elementary sieve-building step.  Start with a sieve of all 1s, and
  485. apply this as required.
  486.  
  487. #> unsigned sieveSearch(unsigned char const *array, unsigned size,
  488. #>    unsigned start);
  489.  
  490. This returns the next bit position *greater than* start which is set
  491. in the indicated sieve, or 0 on failure.  NOTE that this means that
  492. you have to look at the bit at position 0 (array[0] & 1) by yourself
  493. if you want to pay attention to it, because there's no way to tell
  494. sieveSearch to start searching at 0 - it starts at start+1.
  495.  
  496. #> int sieveBuild(unsigned char *array, unsigned size, struct BigNum const *bn,
  497. #>    unsigned step, unsigned dbl);
  498.  
  499. This initializes a sieve where, if bit i is set, then bn+step*i is not
  500. divisible by any small primes.  (Small is from 2 through 65521, the
  501. largest prime less that 65536.)  If "dbl" is > 0, then bits are also
  502. cleared if 2*(bn+step*i)+1 is divisible.  If dbl > 1, then
  503. 4*(bn+step*i)+3 is also checked, and so on.  This feature is used when
  504. generating Sohpie Germain primes.
  505.  
  506. Usually, you use a step of 2.
  507.  
  508. #> int sieveBuildBig(unsigned char *array, unsigned size,
  509. #>    struct BigNum const *bn, struct BigNum const *step, unsigned dbl);
  510.  
  511. This is just the same, but accepts a BigNum step size, and is correspondingly
  512. slower.
  513.  
  514. * bnprint.h
  515.  
  516. #> int bnPrint(FILE *f, char const *prefix, struct BigNum const *bn,
  517. #>    char const *suffix);
  518.  
  519. This prints a nicely-formatted BigNum in hexadecimal form to the given
  520. FILE *.  The "prefix" is printed before it, as a prompt, and the
  521. "suffix" is printed afterwards.  The BigNum itself is printed in
  522. 64-character lines, broken with a trailing backslash if necessary.
  523. Continuation lines are indented by the length of the prefix.
  524.  
  525. E.g. a 2^512-1, printed with the call bnPrint(stdout, "a = (", bn, ")\n")
  526. would result in:
  527.  
  528. a = (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\
  529.      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
  530.  
  531. Hex digits are printed in upper case to facilitate cutting and pasting into
  532. the Unix "dc" utility.
  533.