ecc-pk-crypto.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /**
  2. \file ecc-pk-crypto.cpp
  3. \author michael.zohner@ec-spride.de
  4. \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
  5. Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU Lesser General Public License as published
  8. by the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. ABY is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "ecc-pk-crypto.h"
  18. void ecc_field::init(seclvl sp, uint8_t* seed) {
  19. relic_mutex.lock();
  20. core_set(NULL);
  21. core_init(); //initialize the relic library
  22. rand_seed(seed, sp.symbits >> 3); //set the seed of the relic's internal random generator
  23. eb_param_set_any_plain();
  24. fe_bytelen = ceil_divide(ECCLVL, 8) + 1;
  25. context = core_get();
  26. relic_mutex.unlock();
  27. generator = (ecc_fe*) get_generator();
  28. order = get_order();
  29. }
  30. ecc_field::~ecc_field() {
  31. delete generator;
  32. delete order;
  33. std::lock_guard<std::mutex> lock(relic_mutex);
  34. core_set(context);
  35. core_clean();
  36. }
  37. num* ecc_field::get_num() {
  38. return new ecc_num(this);
  39. }
  40. num* ecc_field::get_order() {
  41. relic_mutex.lock();
  42. core_set(context);
  43. bn_t bn_order;
  44. bn_null(bn_order);
  45. bn_new(bn_order);
  46. eb_curve_get_ord(bn_order);
  47. relic_mutex.unlock();
  48. return new ecc_num(this, bn_order);
  49. }
  50. num* ecc_field::get_rnd_num(uint32_t bitlen) {
  51. if (bitlen == 0) {
  52. bitlen = ECCLVL;
  53. }
  54. relic_mutex.lock();
  55. core_set(context);
  56. bn_t rnd;
  57. bn_null(rnd);
  58. bn_new(rnd);
  59. bn_rand(rnd, RLC_POS, bitlen);
  60. relic_mutex.unlock();
  61. num* res = new ecc_num(this, rnd);
  62. return res;
  63. }
  64. fe* ecc_field::get_fe() {
  65. return new ecc_fe(this);
  66. }
  67. fe* ecc_field::get_rnd_fe() {
  68. return sample_random_point();
  69. }
  70. fe* ecc_field::get_generator() {
  71. relic_mutex.lock();
  72. core_set(context);
  73. eb_t eb_generator;
  74. eb_null(eb_generator);
  75. eb_new(eb_generator);
  76. eb_curve_get_gen(eb_generator);
  77. relic_mutex.unlock();
  78. return new ecc_fe(this, eb_generator);
  79. }
  80. fe* ecc_field::get_rnd_generator() {
  81. //TODO not sure how this method is supposed to work
  82. return sample_random_point();
  83. }
  84. uint32_t ecc_field::num_byte_size() {
  85. return ceil_divide(ECCLVL, 8);
  86. }
  87. uint32_t ecc_field::get_field_size() {
  88. return ECCLVL;
  89. }
  90. brickexp* ecc_field::get_brick(fe* gen) {
  91. return new ecc_brickexp(gen, this);
  92. }
  93. uint32_t ecc_field::get_size() {
  94. return ECCLVL;
  95. }
  96. fe* ecc_field::sample_random_point() {
  97. relic_mutex.lock();
  98. core_set(context);
  99. eb_t tmp_eb;
  100. eb_null(tmp_eb);
  101. eb_new(tmp_eb);
  102. eb_rand(tmp_eb);
  103. relic_mutex.unlock();
  104. fe* tmp_fe = new ecc_fe(this, tmp_eb);
  105. return tmp_fe;
  106. }
  107. ctx_t* ecc_field::get_context() {
  108. return context;
  109. }
  110. ecc_fe::ecc_fe(ecc_field* fld) {
  111. field = fld;
  112. init();
  113. }
  114. ecc_fe::ecc_fe(ecc_field* fld, eb_t src) {
  115. field = fld;
  116. init();
  117. std::lock_guard<std::mutex> lock(relic_mutex);
  118. core_set(context);
  119. eb_copy(val, src);
  120. }
  121. ecc_fe::~ecc_fe() {
  122. std::lock_guard<std::mutex> lock(relic_mutex);
  123. core_set(context);
  124. eb_free(val);
  125. }
  126. void ecc_fe::set(fe* src) {
  127. std::lock_guard<std::mutex> lock(relic_mutex);
  128. core_set(context);
  129. eb_t tmp_val;
  130. ((ecc_fe*) src)->get_val(tmp_val);
  131. eb_copy(val, tmp_val);
  132. }
  133. void ecc_fe::get_val(eb_t res) {
  134. shallow_copy(res, val);
  135. }
  136. //Note: if the same value is processed, a has to be this value
  137. void ecc_fe::set_mul(fe* a, fe* b) {
  138. std::lock_guard<std::mutex> lock(relic_mutex);
  139. core_set(context);
  140. eb_t eb_a;
  141. eb_t eb_b;
  142. ((ecc_fe*) a)->get_val(eb_a);
  143. ((ecc_fe*) b)->get_val(eb_b);
  144. eb_add(val, eb_a, eb_b);
  145. }
  146. void ecc_fe::set_pow(fe* a, num* e) {
  147. std::lock_guard<std::mutex> lock(relic_mutex);
  148. core_set(context);
  149. eb_t eb_a;
  150. bn_t bn_e;
  151. ((ecc_fe*) a)->get_val(eb_a);
  152. ((ecc_num*) e)->get_val(bn_e);
  153. eb_mul(val, eb_a, bn_e);
  154. }
  155. //Note: if the same value is processed, a has to be this value
  156. void ecc_fe::set_div(fe* a, fe* b) {
  157. std::lock_guard<std::mutex> lock(relic_mutex);
  158. core_set(context);
  159. eb_t eb_a;
  160. eb_t eb_b;
  161. ((ecc_fe*) a)->get_val(eb_a);
  162. ((ecc_fe*) b)->get_val(eb_b);
  163. eb_sub(val, eb_a, eb_b);
  164. }
  165. //TODO not sure what double here means, please check
  166. void ecc_fe::set_double_pow_mul(fe* b1, num* e1, fe* b2, num* e2) {
  167. std::lock_guard<std::mutex> lock(relic_mutex);
  168. core_set(context);
  169. eb_t eb_b1;
  170. eb_t eb_b2;
  171. ((ecc_fe*) b1)->get_val(eb_b1);
  172. ((ecc_fe*) b2)->get_val(eb_b2);
  173. bn_t bn_e1;
  174. bn_t bn_e2;
  175. ((ecc_num*) e1)->get_val(bn_e1);
  176. ((ecc_num*) e2)->get_val(bn_e2);
  177. eb_mul_sim(val, eb_b1, bn_e1, eb_b2, bn_e2);
  178. }
  179. void ecc_fe::import_from_bytes(uint8_t* buf) {
  180. std::lock_guard<std::mutex> lock(relic_mutex);
  181. core_set(context);
  182. eb_read_bin(val, buf, field->fe_byte_size());
  183. }
  184. void ecc_fe::export_to_bytes(uint8_t* buf) {
  185. std::lock_guard<std::mutex> lock(relic_mutex);
  186. core_set(context);
  187. eb_write_bin(buf, field->fe_byte_size(), val, true);
  188. }
  189. //TODO not sure what the difference to import_from_bytes is yet
  190. void ecc_fe::sample_fe_from_bytes(uint8_t* buf, uint32_t bytelen) {
  191. std::lock_guard<std::mutex> lock(relic_mutex);
  192. core_set(context);
  193. eb_read_bin(val, buf, bytelen);
  194. //TODO normalizing or something like that
  195. }
  196. bool ecc_fe::eq(fe* a) {
  197. std::lock_guard<std::mutex> lock(relic_mutex);
  198. core_set(context);
  199. eb_t to_cmp;
  200. ((ecc_fe*) a)->get_val(to_cmp);
  201. return eb_cmp(val, to_cmp) == RLC_EQ;
  202. }
  203. void ecc_fe::init() {
  204. context = field->get_context();
  205. std::lock_guard<std::mutex> lock(relic_mutex);
  206. core_set(context);
  207. eb_null(val);
  208. eb_new(val);
  209. };
  210. void ecc_fe::print() {
  211. std::lock_guard<std::mutex> lock(relic_mutex);
  212. core_set(context);
  213. eb_print(val);
  214. };
  215. void ecc_fe::shallow_copy(eb_t to, eb_t from) {
  216. *to = *from;
  217. }
  218. ecc_num::ecc_num(ecc_field* fld) {
  219. field = fld;
  220. context = field->get_context();
  221. std::lock_guard<std::mutex> lock(relic_mutex);
  222. core_set(context);
  223. bn_null(val);
  224. bn_new(val);
  225. }
  226. ecc_num::ecc_num(ecc_field* fld, bn_t src) {
  227. field = fld;
  228. context = field->get_context();
  229. std::lock_guard<std::mutex> lock(relic_mutex);
  230. core_set(context);
  231. bn_null(val);
  232. bn_new(val);
  233. bn_copy(val, src);
  234. }
  235. ecc_num::~ecc_num() {
  236. std::lock_guard<std::mutex> lock(relic_mutex);
  237. core_set(context);
  238. bn_free(val);
  239. }
  240. void ecc_num::get_val(bn_t res) {
  241. shallow_copy(res, val);
  242. }
  243. void ecc_num::set(num* src) {
  244. std::lock_guard<std::mutex> lock(relic_mutex);
  245. core_set(context);
  246. bn_t tmp_val;
  247. ((ecc_num*) src)->get_val(tmp_val);
  248. bn_copy(val, tmp_val);
  249. }
  250. void ecc_num::set_si(int32_t src) {
  251. //TODO implement this method
  252. }
  253. void ecc_num::set_add(num* a, num* b) {
  254. std::lock_guard<std::mutex> lock(relic_mutex);
  255. core_set(context);
  256. bn_t bn_a;
  257. bn_t bn_b;
  258. ((ecc_num*) a)->get_val(bn_a);
  259. ((ecc_num*) b)->get_val(bn_b);
  260. bn_add(val, bn_a, bn_b);
  261. }
  262. void ecc_num::set_sub(num* a, num* b) {
  263. std::lock_guard<std::mutex> lock(relic_mutex);
  264. core_set(context);
  265. bn_t bn_a;
  266. bn_t bn_b;
  267. ((ecc_num*) a)->get_val(bn_a);
  268. ((ecc_num*) b)->get_val(bn_b);
  269. bn_sub(val, bn_a, bn_b);
  270. }
  271. void ecc_num::set_mul(num* a, num* b) {
  272. std::lock_guard<std::mutex> lock(relic_mutex);
  273. core_set(context);
  274. bn_t bn_a;
  275. bn_t bn_b;
  276. ((ecc_num*) a)->get_val(bn_a);
  277. ((ecc_num*) b)->get_val(bn_b);
  278. bn_mul(val, bn_a, bn_b);
  279. }
  280. void ecc_num::mod(num* modulus) {
  281. std::lock_guard<std::mutex> lock(relic_mutex);
  282. core_set(context);
  283. bn_t bn_mod;
  284. ((ecc_num*) modulus)->get_val(bn_mod);
  285. bn_mod(val, val, bn_mod);
  286. }
  287. void ecc_num::set_mul_mod(num* a, num* b, num* modulus) {
  288. //TODO is normalizing meant instead?
  289. set_mul(a, b);
  290. mod(modulus);
  291. }
  292. void ecc_num::import_from_bytes(uint8_t* buf, uint32_t field_size_bytes) {
  293. std::lock_guard<std::mutex> lock(relic_mutex);
  294. core_set(context);
  295. bn_read_bin(val, buf, field_size_bytes);
  296. }
  297. //export and pad all leading zeros
  298. void ecc_num::export_to_bytes(uint8_t* buf, uint32_t field_size_bytes) {
  299. std::lock_guard<std::mutex> lock(relic_mutex);
  300. core_set(context);
  301. bn_write_bin(buf, field_size_bytes, val);
  302. }
  303. void ecc_num::print() {
  304. std::lock_guard<std::mutex> lock(relic_mutex);
  305. core_set(context);
  306. bn_print(val);
  307. };
  308. void ecc_num::shallow_copy(bn_t to, bn_t from) {
  309. *to = *from;
  310. }
  311. ecc_brickexp::ecc_brickexp(fe* generator, ecc_field* field) {
  312. this->field = field;
  313. context = field->get_context();
  314. std::lock_guard<std::mutex> lock(relic_mutex);
  315. core_set(context);
  316. eb_t tmp_val;
  317. ((ecc_fe*) generator)->get_val(tmp_val);
  318. eb_table = new eb_t[RLC_EB_TABLE_MAX];
  319. for(uint32_t i = 0; i < RLC_EB_TABLE_MAX; i++) {
  320. eb_null(eb_table[i]);
  321. }
  322. for(uint32_t i = 0; i < RLC_EB_TABLE; i++) {
  323. eb_new(eb_table[i]);
  324. }
  325. eb_mul_pre(eb_table, tmp_val);
  326. }
  327. ecc_brickexp::~ecc_brickexp() {
  328. std::lock_guard<std::mutex> lock(relic_mutex);
  329. core_set(context);
  330. for(uint32_t i = 0; i < RLC_EB_TABLE; ++i) {
  331. eb_free(eb_table[i]);
  332. }
  333. delete eb_table;
  334. }
  335. void ecc_brickexp::pow(fe* result, num* e) {
  336. relic_mutex.lock();
  337. core_set(context);
  338. eb_t eb_res;
  339. eb_null(eb_res);
  340. eb_new(eb_res);
  341. bn_t bn_e;
  342. ((ecc_num*) e)->get_val(bn_e);
  343. eb_mul_fix(eb_res, eb_table, bn_e);
  344. relic_mutex.unlock();
  345. ecc_fe tmp_fe(field, eb_res);
  346. result->set(&tmp_fe);
  347. }