bignum.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*****************************************************************************
  2. Filename : bignum.c
  3. Author : Terrantsh (tanshanhe@foxmail.com)
  4. Date : 2018-8-31 10:31:23
  5. Description : 整理数据
  6. *****************************************************************************/
  7. #include <string.h>
  8. #include "bignum.h"
  9. static bn_t bn_sub_digit_mul(bn_t *a, bn_t *b, bn_t c, bn_t *d, uint32_t digits);
  10. static bn_t bn_add_digit_mul(bn_t *a, bn_t *b, bn_t c, bn_t *d, uint32_t digits);
  11. static uint32_t bn_digit_bits(bn_t a);
  12. void bn_decode(bn_t *bn, uint32_t digits, uint8_t *hexarr, uint32_t size)
  13. {
  14. bn_t t;
  15. int j;
  16. uint32_t i, u;
  17. for(i=0,j=size-1; i<digits && j>=0; i++) {
  18. t = 0;
  19. for(u=0; j>=0 && u<BN_DIGIT_BITS; j--, u+=8) {
  20. t |= ((bn_t)hexarr[j]) << u;
  21. }
  22. bn[i] = t;
  23. }
  24. for(; i<digits; i++) {
  25. bn[i] = 0;
  26. }
  27. }
  28. void bn_encode(uint8_t *hexarr, uint32_t size, bn_t *bn, uint32_t digits)
  29. {
  30. bn_t t;
  31. int j;
  32. uint32_t i, u;
  33. for(i=0,j=size-1; i<digits && j>=0; i++) {
  34. t = bn[i];
  35. for(u=0; j>=0 && u<BN_DIGIT_BITS; j--, u+=8) {
  36. hexarr[j] = (uint8_t)(t >> u);
  37. }
  38. }
  39. for(; j>=0; j--) {
  40. hexarr[j] = 0;
  41. }
  42. }
  43. void bn_assign(bn_t *a, bn_t *b, uint32_t digits)
  44. {
  45. uint32_t i;
  46. for(i=0; i<digits; i++) {
  47. a[i] = b[i];
  48. }
  49. }
  50. void bn_assign_zero(bn_t *a, uint32_t digits)
  51. {
  52. uint32_t i;
  53. for(i=0; i<digits; i++) {
  54. a[i] = 0;
  55. }
  56. }
  57. bn_t bn_add(bn_t *a, bn_t *b, bn_t *c, uint32_t digits)
  58. {
  59. bn_t ai, carry;
  60. uint32_t i;
  61. carry = 0;
  62. for(i=0; i<digits; i++) {
  63. if((ai = b[i] + carry) < carry) {
  64. ai = c[i];
  65. } else if((ai += c[i]) < c[i]) {
  66. carry = 1;
  67. } else {
  68. carry = 0;
  69. }
  70. a[i] = ai;
  71. }
  72. return carry;
  73. }
  74. bn_t bn_sub(bn_t *a, bn_t *b, bn_t *c, uint32_t digits)
  75. {
  76. bn_t ai, borrow;
  77. uint32_t i;
  78. borrow = 0;
  79. for(i=0; i<digits; i++) {
  80. if((ai = b[i] - borrow) > (BN_MAX_DIGIT - borrow)) {
  81. ai = BN_MAX_DIGIT - c[i];
  82. } else if((ai -= c[i]) > (BN_MAX_DIGIT - c[i])) {
  83. borrow = 1;
  84. } else {
  85. borrow = 0;
  86. }
  87. a[i] = ai;
  88. }
  89. return borrow;
  90. }
  91. void bn_mul(bn_t *a, bn_t *b, bn_t *c, uint32_t digits)
  92. {
  93. bn_t t[2*BN_MAX_DIGITS];
  94. uint32_t bdigits, cdigits, i;
  95. bn_assign_zero(t, 2*digits);
  96. bdigits = bn_digits(b, digits);
  97. cdigits = bn_digits(c, digits);
  98. for(i=0; i<bdigits; i++) {
  99. t[i+cdigits] += bn_add_digit_mul(&t[i], &t[i], b[i], c, cdigits);
  100. }
  101. bn_assign(a, t, 2*digits);
  102. // Clear potentially sensitive information
  103. memset((uint8_t *)t, 0, sizeof(t));
  104. }
  105. void bn_div(bn_t *a, bn_t *b, bn_t *c, uint32_t cdigits, bn_t *d, uint32_t ddigits)
  106. {
  107. dbn_t tmp;
  108. bn_t ai, t, cc[2*BN_MAX_DIGITS+1], dd[BN_MAX_DIGITS];
  109. int i;
  110. uint32_t dddigits, shift;
  111. dddigits = bn_digits(d, ddigits);
  112. if(dddigits == 0)
  113. return;
  114. shift = BN_DIGIT_BITS - bn_digit_bits(d[dddigits-1]);
  115. bn_assign_zero(cc, dddigits);
  116. cc[cdigits] = bn_shift_l(cc, c, shift, cdigits);
  117. bn_shift_l(dd, d, shift, dddigits);
  118. t = dd[dddigits-1];
  119. bn_assign_zero(a, cdigits);
  120. i = cdigits - dddigits;
  121. for(; i>=0; i--) {
  122. if(t == BN_MAX_DIGIT) {
  123. ai = cc[i+dddigits];
  124. } else {
  125. tmp = cc[i+dddigits-1];
  126. tmp += (dbn_t)cc[i+dddigits] << BN_DIGIT_BITS;
  127. ai = tmp / (t + 1);
  128. }
  129. cc[i+dddigits] -= bn_sub_digit_mul(&cc[i], &cc[i], ai, dd, dddigits);
  130. // printf("cc[%d]: %08X\n", i, cc[i+dddigits]);
  131. while(cc[i+dddigits] || (bn_cmp(&cc[i], dd, dddigits) >= 0)) {
  132. ai++;
  133. cc[i+dddigits] -= bn_sub(&cc[i], &cc[i], dd, dddigits);
  134. }
  135. a[i] = ai;
  136. // printf("ai[%d]: %08X\n", i, ai);
  137. }
  138. bn_assign_zero(b, ddigits);
  139. bn_shift_r(b, cc, shift, dddigits);
  140. // Clear potentially sensitive information
  141. memset((uint8_t *)cc, 0, sizeof(cc));
  142. memset((uint8_t *)dd, 0, sizeof(dd));
  143. }
  144. bn_t bn_shift_l(bn_t *a, bn_t *b, uint32_t c, uint32_t digits)
  145. {
  146. bn_t bi, carry;
  147. uint32_t i, t;
  148. if(c >= BN_DIGIT_BITS)
  149. return 0;
  150. t = BN_DIGIT_BITS - c;
  151. carry = 0;
  152. for(i=0; i<digits; i++) {
  153. bi = b[i];
  154. a[i] = (bi << c) | carry;
  155. carry = c ? (bi >> t) : 0;
  156. }
  157. return carry;
  158. }
  159. bn_t bn_shift_r(bn_t *a, bn_t *b, uint32_t c, uint32_t digits)
  160. {
  161. bn_t bi, carry;
  162. int i;
  163. uint32_t t;
  164. if(c >= BN_DIGIT_BITS)
  165. return 0;
  166. t = BN_DIGIT_BITS - c;
  167. carry = 0;
  168. i = digits - 1;
  169. for(; i>=0; i--) {
  170. bi = b[i];
  171. a[i] = (bi >> c) | carry;
  172. carry = c ? (bi << t) : 0;
  173. }
  174. return carry;
  175. }
  176. void bn_mod(bn_t *a, bn_t *b, uint32_t bdigits, bn_t *c, uint32_t cdigits)
  177. {
  178. bn_t t[2*BN_MAX_DIGITS] = {0};
  179. bn_div(t, a, b, bdigits, c, cdigits);
  180. // Clear potentially sensitive information
  181. memset((uint8_t *)t, 0, sizeof(t));
  182. }
  183. void bn_mod_mul(bn_t *a, bn_t *b, bn_t *c, bn_t *d, uint32_t digits)
  184. {
  185. bn_t t[2*BN_MAX_DIGITS];
  186. bn_mul(t, b, c, digits);
  187. bn_mod(a, t, 2*digits, d, digits);
  188. // Clear potentially sensitive information
  189. memset((uint8_t *)t, 0, sizeof(t));
  190. }
  191. void bn_mod_exp(bn_t *a, bn_t *b, bn_t *c, uint32_t cdigits, bn_t *d, uint32_t ddigits)
  192. {
  193. bn_t bpower[3][BN_MAX_DIGITS], ci, t[BN_MAX_DIGITS];
  194. int i;
  195. uint32_t ci_bits, j, s;
  196. bn_assign(bpower[0], b, ddigits);
  197. bn_mod_mul(bpower[1], bpower[0], b, d, ddigits);
  198. bn_mod_mul(bpower[2], bpower[1], b, d, ddigits);
  199. BN_ASSIGN_DIGIT(t, 1, ddigits);
  200. cdigits = bn_digits(c, cdigits);
  201. i = cdigits - 1;
  202. for(; i>=0; i--) {
  203. ci = c[i];
  204. ci_bits = BN_DIGIT_BITS;
  205. if(i == (int)(cdigits - 1)) {
  206. while(!DIGIT_2MSB(ci)) {
  207. ci <<= 2;
  208. ci_bits -= 2;
  209. }
  210. }
  211. for(j=0; j<ci_bits; j+=2) {
  212. bn_mod_mul(t, t, t, d, ddigits);
  213. bn_mod_mul(t, t, t, d, ddigits);
  214. if((s = DIGIT_2MSB(ci)) != 0) {
  215. bn_mod_mul(t, t, bpower[s-1], d, ddigits);
  216. }
  217. ci <<= 2;
  218. }
  219. }
  220. bn_assign(a, t, ddigits);
  221. // Clear potentially sensitive information
  222. memset((uint8_t *)bpower, 0, sizeof(bpower));
  223. memset((uint8_t *)t, 0, sizeof(t));
  224. }
  225. int bn_cmp(bn_t *a, bn_t *b, uint32_t digits)
  226. {
  227. int i;
  228. for(i=digits-1; i>=0; i--) {
  229. if(a[i] > b[i]) return 1;
  230. if(a[i] < b[i]) return -1;
  231. }
  232. return 0;
  233. }
  234. uint32_t bn_digits(bn_t *a, uint32_t digits)
  235. {
  236. int i;
  237. for(i=digits-1; i>=0; i--) {
  238. if(a[i]) break;
  239. }
  240. return (i + 1);
  241. }
  242. static bn_t bn_add_digit_mul(bn_t *a, bn_t *b, bn_t c, bn_t *d, uint32_t digits)
  243. {
  244. dbn_t result;
  245. bn_t carry, rh, rl;
  246. uint32_t i;
  247. if(c == 0)
  248. return 0;
  249. carry = 0;
  250. for(i=0; i<digits; i++) {
  251. result = (dbn_t)c * d[i];
  252. rl = result & BN_MAX_DIGIT;
  253. rh = (result >> BN_DIGIT_BITS) & BN_MAX_DIGIT;
  254. if((a[i] = b[i] + carry) < carry) {
  255. carry = 1;
  256. } else {
  257. carry = 0;
  258. }
  259. if((a[i] += rl) < rl) {
  260. carry++;
  261. }
  262. carry += rh;
  263. }
  264. return carry;
  265. }
  266. static bn_t bn_sub_digit_mul(bn_t *a, bn_t *b, bn_t c, bn_t *d, uint32_t digits)
  267. {
  268. dbn_t result;
  269. bn_t borrow, rh, rl;
  270. uint32_t i;
  271. if(c == 0)
  272. return 0;
  273. borrow = 0;
  274. for(i=0; i<digits; i++) {
  275. result = (dbn_t)c * d[i];
  276. rl = result & BN_MAX_DIGIT;
  277. rh = (result >> BN_DIGIT_BITS) & BN_MAX_DIGIT;
  278. if((a[i] = b[i] - borrow) > (BN_MAX_DIGIT - borrow)) {
  279. borrow = 1;
  280. } else {
  281. borrow = 0;
  282. }
  283. if((a[i] -= rl) > (BN_MAX_DIGIT - rl)) {
  284. borrow++;
  285. }
  286. borrow += rh;
  287. }
  288. return borrow;
  289. }
  290. static uint32_t bn_digit_bits(bn_t a)
  291. {
  292. uint32_t i;
  293. for(i=0; i<BN_DIGIT_BITS; i++) {
  294. if(a == 0) break;
  295. a >>= 1;
  296. }
  297. return i;
  298. }