This file contains various notes on the libtom routines: rants, things I think it important anyone trying to use this stuff know, etc. ---- libtommath 0.42.0 --- Doc author seems to think "moduli" is both singular and plural. More generally, there are numerous English issues which could be simple illiteracy or could be the author not being a native anglophone. tommath.h seriously invades the user's namespace. LTM_PRIME_2MSB_OFF and LTM_PRIME_2MSB_ON are documented, but only the latter is actually defined or implemented. The makefile does not work (at least not with NetBSD make); conditionals are missing their leading dots. bn_mp_read_radix.c passes a plain char to toupper. mp_rand() uses rand() (!!). tommath.src incorrectly implies that calloc is not suitable for initializing arrays of integer type to zero. mp_init uses assignments, but mp_init_size is documented as using calloc, even though it actually doesn't. mp_fread() consumes the terminating character rather than pushing it back with ungetc. (It also appears to be completely undocumented.) tommath.src fails to mention an important invariant on mp_int: that the digit vector point to malloc-managed memory. The discussion of mp_grow implies that calling it unnecessarily is an error. Is this really true? varargs funcgions such as mp_init_multi misuse NULL, not mentioning that it needs to be cast. The implementation also assumes that va_end may be called at a block nesting level different from that of its matching va_start. mp_clamp()'s documentation implies -- binds more tightly than ->, which is not true. The pseudocode for mp_abs maps all failures from mp_copy to MP_MEM, which is wrong and also is not what the actual code does. The TeX source frequently uses en-dashes where hyphens would be more appropriate. The pseudocode for mp_neg does not match the C code, both as outlined for mp_abs and in its handling of zero inputs. mp_set_int is misnamed (it takes an unsigned long, not the int the name implies and not the long tommath.src says) and gratuitously truncates the argument to 32 bits (breaks if long is mokre than 32 bits). It also breaks if DIGIT_BIT is less than 4 and is unnecessarily inefficient if DIGIT_BIT is greater than 4. mp_set_int calls mp_mul_2d with, usually, an mp_int that violates the no-high-order-0s constraint; mp_mul_2d's documentation makes no mention of this exception to the usual interface rules. Loops count up rather than down even when they don't need to (eg, mp_cmp_mag). In view of the lecture about efficiency when discussing caching pointers in variables, this is odd. mp_init_copy arguably should use mp_init_size. It also takes its arguments backwards (output arg before input arg). mp_zero zeros all the digits allocated, rather than just up to the former used value. mp_cmp implementation doesn't match the pseudocode in its handling of differing signs. The description that "the signs are assumed to be both positive" is misleading; "the signs must be both positive" would be more accurate. mp_s_add comment "clear digits above oldused" is wrong; it should be "clear digits up to olduse". It also doesn't perform the operation described in tommath.src; it replaces its destination's magnitude without affecting its sign, whereas the description would call for setting the sign to zpos. It also operates on *tmpc rather than using a temporary variable that could avoid hitting memory. It also does ripple carries even though a simple copy could be done once the carry value is zero. The code disagrees with the doc in that the variable is olduse but the doc calls it oldused. There also is no point whatever in casting shift counts to mp_digit. tommath.src uses "principle" when it means "principal". mp_s_sub has most of the flaws of mp_s_add, above. tommath.src uses "twos compliment" when it means "two's complement". mp_lshd and mp_rshd could benefit from using memmove/bcopy. mp_rshd is explicitly called out as a can't-fail, but mp_zero isn't, though it actually cannot fail. Furthermore, such can't-fail routines are a bad idea because they expose an implementaiton detail inappropriately. tommath.src contains frequent sentence fragments. mp_div_2d always uses a temporary for the remainder even if d is different from a and thus the reminder could be stored directly. mp_mod_2d uses (x/y)+(((x%y)==0)?0:1) instead of ((x+y-1)/y). It too pointlessly casts a shift count to mp_digit. s/hamming/Hamming/