1 | #include "polynomial.h" |
---|
2 | //using namespace pol; |
---|
3 | |
---|
4 | |
---|
5 | |
---|
6 | template <unsigned KEY_DEG> |
---|
7 | void encrypt(File &in, FILE *out, const pol3v_t &D) { |
---|
8 | std::vector<u61_t> m; |
---|
9 | u61_t buf; |
---|
10 | u64_t size = 0, block_size; |
---|
11 | while (block_size = in.read(buf), block_size) { |
---|
12 | m.push_back(buf); |
---|
13 | size += block_size; |
---|
14 | } |
---|
15 | block512_t h = hash_nm::hash((char *)(m.data()), m.size() * sizeof(u61_t)); |
---|
16 | fwrite(&h, sizeof(h), 1, out); |
---|
17 | u64_t max_deg = (m.size() - 1) / KEY_DEG + 2; |
---|
18 | pol3v_t f = XXX_get_f(max_deg, KEY_DEG); |
---|
19 | pol3v_t mes = XXX_get_mes(max_deg, KEY_DEG, size, m); |
---|
20 | (mes += f * D.get_same_rand_pol() + D * f.get_same_rand_pol()).write(out, TEXTPR); |
---|
21 | (mes += f * D.get_same_rand_pol() + D * f.get_same_rand_pol()).write(out, TEXTPR); |
---|
22 | } |
---|
23 | |
---|
24 | template <unsigned CLOSE_KEY_DEG, unsigned OPEN_KEY_DEG> |
---|
25 | void decrypt(FILE *in, File &out, const pol_t &x, const pol_t &y) { |
---|
26 | block512_t h1, h2; |
---|
27 | fread(&h1, sizeof(h1), 1, in); |
---|
28 | pol3v_t tmp; |
---|
29 | tmp.read(in, TEXTPR); |
---|
30 | pol_t m, m1, fc, pol_x = get_x(), kxy = x * y; |
---|
31 | m1 = tmp.subst(x, y); |
---|
32 | tmp.read(in, TEXTPR); |
---|
33 | fc = tmp.subst(x, y) - m1; |
---|
34 | vector_t factor; |
---|
35 | fc.fact(CLOSE_KEY_DEG * OPEN_KEY_DEG * 2 + 1, factor); |
---|
36 | XXX_get_fact(factor, CLOSE_KEY_DEG * OPEN_KEY_DEG * 2 + 1, factor); |
---|
37 | std::vector<u61_t> res; |
---|
38 | u61_t a = x[CLOSE_KEY_DEG].inverse() * y[CLOSE_KEY_DEG].inverse(); |
---|
39 | for (u32_t j = 0; j < factor.size(); ++j) { |
---|
40 | res.clear(); |
---|
41 | m = m1 % (fc / factor[j]); |
---|
42 | u32_t deg = m.get_deg(); |
---|
43 | u64_t size = m[deg] * a.pow(deg / (2 * CLOSE_KEY_DEG)); |
---|
44 | m %= kxy.pow(deg / (2 * CLOSE_KEY_DEG)) * pol_x.pow(deg % (2 * CLOSE_KEY_DEG)); |
---|
45 | deg = m.get_deg(); |
---|
46 | for (u32_t i = 0; i <= deg; ++i) { |
---|
47 | res.push_back(m[deg - i] * a.pow((deg - i) / (2 * CLOSE_KEY_DEG))); |
---|
48 | m %= kxy.pow((deg - i) / (2 * CLOSE_KEY_DEG)) * pol_x.pow((deg - i) % (2 * CLOSE_KEY_DEG)); |
---|
49 | } |
---|
50 | |
---|
51 | block512_t h2 = hash_nm::hash((char *)(res.data()), res.size() * sizeof(u61_t)); |
---|
52 | |
---|
53 | // escritura del mensaje cifrado en el archivo de salida |
---|
54 | for (u32_t i = 0; i < res.size(); ++i) { |
---|
55 | if (size > MODSIZE - 1) { |
---|
56 | size -= out.write(res[i]); |
---|
57 | } |
---|
58 | else { |
---|
59 | size -= out.write(res[i], size); |
---|
60 | } |
---|
61 | } |
---|
62 | out.flush(); |
---|
63 | break; |
---|
64 | } |
---|
65 | } |
---|
66 | |
---|
67 | template <unsigned CLOSE_KEY_DEG, unsigned OPEN_KEY_DEG> |
---|
68 | pol3v_t get_open_key(const pol_t &x, const pol_t &y) { |
---|
69 | polmap_t tmp; |
---|
70 | pol3v_t tmp2; |
---|
71 | for (u32_t i = 1; i <= OPEN_KEY_DEG; ++i) { |
---|
72 | tmp.insert(pol3v1_t(deg_t(i, i), get_rand_pol(2 * (OPEN_KEY_DEG - i) * CLOSE_KEY_DEG + 1, false))); |
---|
73 | } |
---|
74 | tmp.insert(pol3v1_t(deg_t(OPEN_KEY_DEG - 1, OPEN_KEY_DEG), get_rand_pol(1 + CLOSE_KEY_DEG, false))); |
---|
75 | tmp.insert(pol3v1_t(deg_t(OPEN_KEY_DEG, OPEN_KEY_DEG - 1), get_rand_pol(1 + CLOSE_KEY_DEG, false))); |
---|
76 | tmp.insert(pol3v1_t(deg_t(0, 1), get_rand_pol(CLOSE_KEY_DEG * (2 * OPEN_KEY_DEG - 1) + 1, false))); |
---|
77 | tmp.insert(pol3v1_t(deg_t(1, 0), get_rand_pol(CLOSE_KEY_DEG * (2 * OPEN_KEY_DEG - 1) + 1, false))); |
---|
78 | tmp2 = tmp; |
---|
79 | tmp.insert(pol3v1_t(deg_t(0, 0), pol_t() - tmp2.subst(x, y))); |
---|
80 | return tmp; |
---|
81 | } |
---|
82 | |
---|