source: comparacioncriptosistemas/testVarieties/polynomial.cpp

interfaz
Last change on this file was e5b15b7, checked in by usuario <usuario@…>, 8 years ago

Se agregó la ejecución múltiple del proceso de generación, cifrado y descifrado. Se almacenan los resultados en un archivo de texto separado por espacios con los valores tiempo de generación de claves, cifrado y descifrado.

  • Property mode set to 100644
File size: 19.8 KB
Line 
1// polynomial.cpp
2
3#define _CRT_SECURE_NO_WARNINGS
4
5#include "polynomial.h"
6#include <array>
7#include <map>
8#include <cstdio>
9
10using namespace pol;
11
12u61_t::u61_t(u64_t x):
13        data(x % MOD) {
14}
15inline u61_t::operator pol::u64_t() const {
16        return data;
17}
18inline u61_t u61_t::operator+(const u61_t &x) const {
19        return (data + x.data) % MOD;
20}
21inline u61_t u61_t::operator-(const u61_t &x) const {
22        return (data + MOD - x.data) % MOD;
23}
24u61_t u61_t::operator*(const u61_t &x) const {
25//#pragma warning(push)
26//#pragma warning(disable:4127)
27        if (BUFSIZE > 4) {
28//#pragma warning(pop)
29                u64_t h1 = data >> 32, h2 = x.data >> 32, l1 = data & M32, l2 = x.data & M32;
30                u64_t bot = l1 * l2;
31                u64_t mid = h1 * l2 + h2 * l1 + (bot >> 32);
32                bot = (mid << 32) + (bot & M32);
33                u64_t top = ((h1 * h2 + (mid >> 32)) << (64 - MODSIZE)) + (bot >> MODSIZE);
34                return (top + (bot & MOD)) % MOD;
35        } else {
36                return data * x.data % MOD;
37        }
38}
39u61_t u61_t::operator/(const u61_t &x) const {
40        return *this * (x.inverse());
41}
42u61_t u61_t::inverse() const {
43        if (!data) {
44                throw "Invalid inverse\n";
45        }
46        u64_t a = MOD, b = data, r;
47        std::array<u64_t, 64> q;
48        q[0] = 1;
49        u32_t i = 0;
50        do {
51                ++i;
52                r = a % b;
53                q[i] = a / b;
54                a = b; b = r;
55        } while (r);
56        for (u32_t j = 2; j < i; ++j) {
57                q[j] = q[j] * q[j - 1] + q[j - 2];
58        }
59
60        if (i & 1) {
61                return u61_t(q[i - 1]);
62        } else {
63                return u61_t(MOD - q[i - 1]);
64        }
65}
66u61_t& u61_t::operator+=(const u61_t &x) {
67        return *this = *this + x;
68}
69u61_t& u61_t::operator-=(const u61_t &x) {
70        return *this = *this - x;
71}
72u61_t& u61_t::operator*=(const u61_t &x) {
73        return *this = *this * x;
74}
75u61_t& u61_t::operator/=(const u61_t &x) {
76        return *this = *this / x;
77}
78inline u64_t* u61_t::get_addr() {
79        return &data;
80}
81inline const u64_t* u61_t::get_addr() const {
82        return &data;
83}
84inline u64_t& u61_t::get_buf() {
85        return data;
86}
87inline const u64_t& u61_t::get_buf() const {
88        return data;
89}
90void u61_t::print(FILE *fout, u32_t i) const {
91        if ((i > 0 && data != 1) || !i) {
92                fprintf(fout, "%llu", data);
93        }
94        if (i > 1) {
95                fprintf(fout, "t<sup>%u</sup>", i);
96        } else if (i == 1) {
97                fprintf(fout, "t");
98        }
99}
100u61_t u61_t::pow(u32_t p) const {
101        u61_t res, tmp = *this;
102        res = 1;
103        while (p > 0) {
104                if (p & 1) {
105                        res *= tmp;
106                }
107                p /= 2;
108                tmp *= tmp;
109        }
110        return res;
111}
112
113pol_t::pol_t():
114        data(1),
115        degree(0)
116{
117        data[0] = 0;
118}
119void pol_t::change_degree(u32_t ndegree) {
120        degree = ndegree;
121        data.resize(degree + 1);
122        for (u32_t i = 0; i <= degree; ++i) {
123                data[i] = 0;
124        }
125}
126pol_t& pol_t::operator=(const pol_t &x) {
127        if (&x != this) {
128                change_degree(x.degree);
129                for (u32_t i = 0; i <= degree; ++i) {
130                        data[i] = x[i];
131                }
132        }
133        return *this;
134}
135u61_t& pol_t::operator[](u32_t i) {
136        if (i > degree) {
137                throw "Out of array bound";
138        }
139        return data[i];
140}
141const u61_t& pol_t::operator[](u32_t i) const {
142        if (i > degree) {
143                throw "Out of array bound";
144        }
145        return data[i];
146}
147u64_t& pol_t::operator()(u32_t i) {
148        if (i > degree) {
149                throw "Out of array bound";
150        }
151        return data[i].get_buf();
152}
153const u64_t& pol_t::operator()(u32_t i) const {
154        if (i > degree) {
155                throw "Out of array bound";
156        }
157        return data[i].get_buf();
158}
159inline u32_t pol_t::get_deg() const {
160        return degree;
161}
162pol_t pol_t::operator+(const pol_t &x) const{
163        pol_t tmp;
164        u32_t tempdeg;
165        if (degree < x.degree) {
166                tempdeg = x.degree;
167        } else {
168                tempdeg = degree;
169        }
170        tmp.change_degree(tempdeg);
171        for (u32_t i = 0; i <= degree; ++i) {
172                tmp[i] = data[i];
173        }
174        for (u32_t i = 0; i <= x.degree; ++i) {
175                tmp[i] += x[i];
176        }
177        while (tmp.degree > 0 && !tmp[tmp.degree]) {
178                --(tmp.degree);
179        }
180        return tmp;
181}
182pol_t pol_t::operator-(const pol_t &x) const {
183        pol_t tmp;
184        u32_t tempdeg;
185        if (degree < x.degree) {
186                tempdeg = x.degree;
187        } else {
188                tempdeg = degree;
189        }
190        tmp.change_degree(tempdeg);
191        for (u32_t i = 0; i <= degree; ++i) {
192                tmp[i] = data[i];
193        }
194        for (u32_t i = 0; i <= x.degree; ++i) {
195                tmp[i] -= x[i];
196        }
197        while (tmp.degree > 0 && !tmp[tmp.degree]) {
198                --(tmp.degree);
199        }
200        return tmp;
201}
202pol_t pol_t::operator*(const pol_t &x) const {
203        pol_t tmp;
204        tmp.change_degree(degree + x.degree);
205        for (u32_t i = 0; i <= degree; ++i) {
206                for (u32_t j = 0; j <= x.degree; ++j) {
207                        tmp[i + j] += data[i] * x[j];
208                }
209        }
210        while (tmp.degree > 0 && !tmp[tmp.degree]) {
211                --tmp.degree;
212        }
213        return tmp;
214}
215pol_t pol_t::operator%(const pol_t &x) const {
216        if (!x) {
217                throw "Polinomial denominator = 0";
218        }
219        pol_t tmp = *this;
220        if (!x.degree) {
221                return pol_t();
222        } else {
223                u61_t inv = x[x.degree].inverse();
224                for (u32_t i = tmp.degree; i >= x.degree; --i) {
225                        u61_t q = tmp[i] * inv;
226                        for (u32_t j = 0; j <= x.degree; ++j) {
227                                tmp[i - j] -= x[x.degree - j] * q;
228                        }
229                }
230                while (tmp.degree > 0 && !tmp[tmp.degree]) {
231                        --tmp.degree;
232                }
233                return tmp;
234        }
235}
236pol_t pol_t::operator/(const pol_t &x) const {
237        if (!x) {
238                throw "Polinomial devision by 0";
239        } else if (x.degree > degree) {
240                return pol_t();
241        } else if (x.degree) {
242                pol_t tmp = *this, res;
243                res.change_degree(tmp.degree - x.degree);
244                u61_t q = x[x.degree].inverse();
245                for (u32_t i = tmp.degree; i >= x.degree; --i) {
246                        res[i - x.degree] = tmp[i] * q;
247                        for (u32_t j = 0; j <= x.degree; ++j) {
248                                tmp[i - j] -= x[x.degree - j] * res[i - x.degree];
249                        }
250                }
251                return res;
252        } else {
253                pol_t res = *this;
254                u61_t q = x[0].inverse();
255                for (u32_t i = 0; i <= res.degree; ++i) {
256                        res[i] *= q;
257                }
258                return res;
259        }
260}
261pol_t& pol_t::operator+=(const pol_t&x) {
262        return *this = *this + x;
263}
264pol_t& pol_t::operator-=(const pol_t&x) {
265        return *this = *this - x;
266}
267pol_t& pol_t::operator*=(const pol_t&x) {
268        return *this = *this * x;
269}
270pol_t& pol_t::operator%=(const pol_t&x) {
271        return *this = *this % x;
272}
273pol_t& pol_t::operator/=(const pol_t&x) {
274        return *this = *this / x;
275}
276pol_t::operator bool() const {
277        return degree || data[0];
278}
279bool pol_t::operator==(const pol_t &x) const {
280        if (x.degree != degree) {
281                return false;
282        } else {
283                for (u32_t i = 0; i <= degree; ++i) {
284                        if (data[i] != x(i)) {
285                                return false;
286                        }
287                }
288        }
289        return true;
290}
291pol_t pol_t::pow(u32_t p) const {
292        pol_t res, tmp = *this;
293        res(0) = 1;
294        while (p > 0) {
295                if (p & 1) {
296                        res *= tmp;
297                }
298                p /= 2;
299                tmp *= tmp;
300        }
301        return res;
302}
303pol_t pol_t::mpow(u64_t p, const pol_t &m) const {
304        pol_t res, tmp = *this % m;
305        res(0) = 1;
306        while (p > 0) {
307                if (p & 1) {
308                        res = res * tmp % m;
309                }
310                p /= 2;
311                tmp = tmp * tmp % m;
312        }
313        return res;
314}
315pol_t pol_t::mpow(u64_t p, u64_t d, const pol_t &m) const {
316        pol_t tmp = mpow((p - 1) / 2, m), res;
317        res[0] = 1;
318        for (u64_t i = 0; i < d; ++i) {
319                res = res * tmp % m;
320                tmp = tmp.mpow(p, m);
321        }
322        return res;
323}
324pol_t pol_t::normalize() const {
325        pol_t res = *this;
326        u61_t q = data[degree].inverse();
327        for (u32_t i = 0; i <= degree; ++i) {
328                res[i] *= q;
329        }
330        return res;
331}
332pol_t pol_t::deriv() const{
333        pol_t res;
334        if (degree) {
335                res.change_degree(degree - 1);
336                for (u32_t i = degree; i > 0; --i) {
337                        res[i - 1] = u61_t(i) * data[i];
338                }
339        }
340        while (res.degree > 0 && !res[res.degree]) {
341                --res.degree;
342        }
343        return res;
344}
345
346void pol_t::read(FILE *fin, pol_format_t format) {
347        degree = 0;
348        switch (format)
349        {
350        case BINPR:
351                std::fread(&degree, 1, 1, fin);
352                if (degree > 256) {
353                        throw "Incorrect polynomial degree";
354                }
355                data.resize(degree + 1);
356                for (u32_t i = 0; i <= degree; ++i) {
357                        u64_t buf;
358                        std::fread(&buf, BUFSIZE, 1, fin);
359                        if (buf >= MOD) {
360                                throw "Incorrect polinomial coefficient";
361                        }
362                        data[i] = buf;
363                }
364                break;
365        case TEXTPR:
366                std::fscanf(fin, "%u", &degree);
367                if (degree > 256) {
368                        throw "Incorrect polynomial degree";
369                }
370                data.resize(degree + 1);
371                for (u32_t i = 0; i <= degree; ++i) {
372                        u64_t buf;
373                        std::fscanf(fin, "%llu", &buf);
374                        if (buf >= MOD) {
375                                throw "Incorrect polinomial coefficient";
376                        }
377                        data[i] = buf;
378                }
379                break;
380        case HTMLPR:
381                break;
382        default:
383                break;
384        }
385}
386void pol_t::write(FILE *fout, pol_format_t format, bool eol) const {
387        switch (format)
388        {
389        case pol::BINPR:
390                fwrite(&degree, 1, 1, fout);
391                for (u32_t i = 0; i <= degree; ++i) {
392                        fwrite(data[i].get_addr(), BUFSIZE, 1, fout);
393                }
394                break;
395        case pol::TEXTPR:
396                fprintf(fout, "%u ", degree);
397                for (u32_t i = 0; i <= degree; ++i) {
398                        fprintf(fout, "%llu ", data[i].get_buf());
399                }
400                if (eol) fprintf(fout, "\n");
401                break;
402        case pol::HTMLPR:
403                {
404                        u32_t i = degree;
405                        u32_t min = 0;
406                        while (min < degree && !data[min]) ++min;
407                        --min;
408                        data[i].print(fout, i);
409                        --i;
410                        for (; i != min; --i) {
411                                if (data[i]) {
412                                        fprintf(fout, " + ");
413                                        data[i].print(fout, i);
414                                }
415                        }
416                        if (eol) fprintf(fout, "<br>");
417                }
418                break;
419        default:
420                break;
421        }
422}
423void pol_t::ddf(u32_t max_deg, vector_t &res) const {
424        pol_t v = *this, x = get_x(), xp = x, tmp;
425        res.resize(max_deg + 1);
426        for (u32_t i = 0; i <= max_deg; ++i) {
427                res[i](0) = 1;
428        }
429        u32_t i = 1;
430        for (; i <= max_deg; ++i)  {
431                xp = xp.mpow(MOD, v);
432                tmp = gcd(xp - x, v);
433                if (tmp.degree > 0) {
434                        res[i] = tmp;
435                        v /= tmp;
436                }
437        //fprintf(stderr, "%d of %d\n", i, max_deg);
438        }
439        res[0] = v;
440}
441void pol_t::split(u32_t deg, vector_t &res) const {
442        u32_t count = degree / deg, found = 0;
443        pol_t r_pol, r_gcd, unit;
444        unit[0] = 1;
445        std::list<pol_t> l1, l2;
446        l1.push_back(*this);
447        std::list<pol_t> *cur = &l1, *next = &l2;
448        while (found < count) {
449                r_pol = get_rand_pol(deg);
450                next->clear();
451                for (auto i = cur->begin(), end = cur->end(); i != end; ++i) {
452                        if (i->degree == deg) {
453                                res.push_back(*i);
454                                ++found;
455                        } else {
456                                r_gcd = gcd(r_pol.mpow(MOD, deg, *i) - unit, *i);
457                                if (r_gcd.degree && r_gcd.degree < i->degree) {
458                                        *i /= r_gcd;
459                                        if (i->degree == deg) {
460                                                res.push_back(*i);
461                                                ++found;
462                                        }
463                                        else {
464                                                next->push_back(*i);
465                                        }
466                                        if (r_gcd.degree == deg) {
467                                                res.push_back(r_gcd);
468                                                ++found;
469                                        }
470                                        else {
471                                                next->push_back(r_gcd);
472                                        }
473                                }
474                                else {
475                                        next->push_back(*i);
476                                }
477                        }
478                }
479                std::swap(cur, next);
480        }
481}
482void pol_t::fact(u32_t max_deg, vector_t &res) const {
483        pol_t d = gcd(deriv(), *this), tmp;
484        if (d.degree) {
485                tmp = *this / d;
486        } else {
487                tmp = *this;
488        }
489        std::vector<pol_t> ddf_pol;
490        tmp.ddf(max_deg, ddf_pol);
491        for (u32_t i = 1; i <= max_deg; ++i) {
492                if (ddf_pol[i].degree > 0) {
493                        ddf_pol[i].split(i, res);
494                }
495        }
496        if (d.degree) {
497                for (size_t i = 0, size = res.size(); i < size && d.degree; ++i) {
498                        while (!(d % res[i])) {
499                                res.push_back(res[i]);
500                                d /= res[i];
501                        }
502                }
503        }
504}
505
506deg_t::deg_t() : key(0) {}
507deg_t::deg_t(u32_t a, u32_t b) :
508        x(a),
509        y(b)
510{
511}
512bool deg_t::operator<(const deg_t &deg) const{
513        return key < deg.key;
514}
515bool deg_t::operator==(const deg_t &deg) const{
516        return key == deg.key;
517}
518deg_t deg_t::operator+(const deg_t &deg) const {
519        return deg_t(x + deg.x, y + deg.y);
520}
521
522pol3v_t::pol3v_t() {
523        data.clear();
524        data.push_back(pol3v1_t());
525        dx = 0; dy = 0; dt = 0;
526}
527pol3v_t::pol3v_t(const polmap_t &m) :
528        data(),
529        dx(0),
530        dy(0),
531        dt(0)
532{
533        data.clear();
534        bool empty = true;
535        for (auto i = m.begin(); i != m.end(); ++i) {
536                if (i->second) {
537                        if (empty) {
538                                empty = false;
539                        }
540                        data.push_back(*i);
541                        if (dx < i->first.x) dx = i->first.x;
542                        if (dy < i->first.y) dy = i->first.y;
543                        if (dt < i->second.get_deg()) dt = i->second.get_deg();
544                }
545        }
546        if (empty) {
547                data.push_back(pol3v1_t());
548        }
549}
550pol3v_t& pol3v_t::operator=(const pol3v_t &x) {
551        if (&x != this) {
552                data.clear();
553                data = x.data;
554                dx = x.dx; dy = x.dy; dt = x.dt;
555        }
556        return *this;
557}
558pol3v_t pol3v_t::operator+(const pol3v_t &x) const {
559        polmap_t tmp;
560        for (auto i = data.begin(); i != data.end(); ++i) {
561                if (tmp.find(i->first) == tmp.end()) {
562                        tmp.insert(*i);
563                } else {
564                        tmp[i->first] += i->second;
565                }
566        }
567        for (auto i = x.data.begin(); i != x.data.end(); ++i) {
568                if (tmp.find(i->first) == tmp.end()) {
569                        tmp.insert(*i);
570                } else {
571                        tmp[i->first] += i->second;
572                }
573        }
574        return tmp;
575}
576pol3v_t pol3v_t::operator-(const pol3v_t &x) const {
577        polmap_t tmp;
578        for (auto i = data.begin(); i != data.end(); ++i) {
579                if (tmp.find(i->first) == tmp.end()) {
580                        tmp.insert(*i);
581                } else {
582                        tmp[i->first] += i->second;
583                }
584        }
585        for (auto i = x.data.begin(); i != x.data.end(); ++i) {
586                if (tmp.find(i->first) == tmp.end()) {
587                        tmp.insert(pol3v1_t(i->first, pol_t() - i->second));
588                } else {
589                        tmp[i->first] -= i->second;
590                }
591        }
592        return tmp;
593}
594pol3v_t pol3v_t::operator*(const pol3v_t &x) const {
595        polmap_t tmp;
596        for (auto i = data.begin(); i != data.end(); ++i) {
597                for (auto j = x.data.begin(); j != x.data.end(); ++j) {
598                        if (tmp.find(i->first + j->first) == tmp.end()) {
599                                tmp.insert(pol3v1_t(i->first + j->first, i->second * j->second));
600                        } else {
601                                tmp[i->first + j->first] += i->second * j->second;
602                        }
603                }
604        }
605        return tmp;
606}
607pol3v_t& pol3v_t::operator+=(const pol3v_t &x) {
608        return *this = *this + x;
609}
610pol3v_t& pol3v_t::operator-=(const pol3v_t &x) {
611        return *this = *this - x;
612}
613pol3v_t& pol3v_t::operator*=(const pol3v_t &x) {
614        return *this = *this * x;
615}
616pol_t pol3v_t::subst(const pol_t &x, const pol_t &y) const {
617        pol_t res;
618        for (auto i = data.begin(), end = data.end(); i != end; ++i) {
619                res += x.pow(i->first.x) * y.pow(i->first.y) * i->second;
620        }
621        return res;
622}
623pol3v_t pol3v_t::get_same_rand_pol() const {
624        pol3v_t res = *this;
625        for (auto i = res.data.begin(), end = res.data.end(); i != end; ++i) {
626                i->second = get_rand_pol(i->second.get_deg(), false);
627        }
628        return res;
629}
630void pol3v_t::read(FILE *fin, pol_format_t format) {
631        size_t count = 0;
632        data.clear();
633        switch (format)
634        {
635        case BINPR:
636        {
637                std::fread(&count, 1, sizeof(count), fin);
638                if (!count) {
639                        data.push_back(pol3v1_t());
640                        dx = 0; dy = 0; dt = 0;
641                }
642                deg_t deg;
643                for (size_t i = 0; i < count; ++i) {
644                        std::fread(&(deg.key), sizeof(deg.key), 1, fin);
645                        pol_t tmp;
646                        tmp.read(fin, BINPR);
647                        if (tmp) {
648                                data.push_back(pol3v1_t(deg, tmp));
649                                if (deg.x > dx) dx = deg.x;
650                                if (deg.y > dy) dy = deg.y;
651                                if (tmp.get_deg() > dt) dt = tmp.get_deg();
652                        }
653                }
654                break;
655        }
656        case TEXTPR:
657                std::fscanf(fin, "%zu", &count);
658                if (!count) {
659                        data.clear();
660                        data.push_back(pol3v1_t());
661                        dx = 0; dy = 0; dt = 0;
662                } else {
663                        for (size_t i = 0; i < count; ++i) {
664                                u32_t v[2];
665                                fscanf(fin, "%u%u", v, v + 1);
666                                pol_t tmp;
667                                tmp.read(fin, TEXTPR);
668                                if (tmp) {
669                                        data.push_back(pol3v1_t(deg_t(v[0], v[1]), tmp));
670                                        if (v[0] > dx) dx = v[0];
671                                        if (v[1] > dy) dy = v[1];
672                                        if (tmp.get_deg() > dt) dt = tmp.get_deg();
673                                }
674                        }
675                }
676                break;
677        case HTMLPR:
678                break;
679        default:
680                break;
681        }
682}
683void pol3v_t::write(FILE *fout, pol_format_t format, bool eol) const {
684        size_t count = data.size();
685        switch (format)
686        {
687        case pol::BINPR:
688                std::fwrite(&count, 1, sizeof(count), fout);
689                for (auto i = data.begin(), end = data.end(); i != end; ++i) {
690                        std::fwrite(&(i->first.key), sizeof(i->first.key), 1, fout);
691                        i->second.write(fout, BINPR);
692                }
693                break;
694        case TEXTPR:
695                std::fprintf(fout, "%zu\n", count);
696                for (auto i = data.begin(), end = data.end(); i != end; ++i) {
697                        fprintf(fout, "%u %u ", i->first.x, i->first.y);
698                        i->second.write(fout, TEXTPR, true);
699                }
700                if (eol) {
701                        fprintf(fout, "\n");
702                }
703                break;
704        case pol::HTMLPR:
705                if (!count) {
706                        fprintf(fout, "0");
707                } else {
708                        auto i = data.rbegin();
709                        if (i->first.x > 1) {
710                                fprintf(fout, "x<sup>%u</sup>", i->first.x);
711                        }
712                        else if (i->first.x == 1) {
713                                fprintf(fout, "x");
714                        }
715                        if (i->first.y > 1) {
716                                fprintf(fout, "y<sup>%u</sup>", i->first.y);
717                        }
718                        else if (i->first.y == 1) {
719                                fprintf(fout, "y");
720                        }
721                        fprintf(fout, "(");
722                        i->second.write(fout, HTMLPR);
723                        fprintf(fout, ")");
724                        ++i;
725                        for (auto end = data.rend(); i != end; ++i) {
726                                fprintf(fout, " + ");
727                                if (i->first.x > 1) {
728                                        fprintf(fout, "x<sup>%u</sup>", i->first.x);
729                                }
730                                else if (i->first.x == 1) {
731                                        fprintf(fout, "x");
732                                }
733                                if (i->first.y > 1) {
734                                        fprintf(fout, "y<sup>%u</sup>", i->first.y);
735                                }
736                                else if (i->first.y == 1) {
737                                        fprintf(fout, "y");
738                                }
739                                fprintf(fout, "(");
740                                i->second.write(fout, HTMLPR);
741                                fprintf(fout, ")");
742                        }
743                }
744                if (eol) {
745                        fprintf(fout, "<br>");
746                }
747                break;
748        default:
749                break;
750        }
751}
752
753File::File() :
754        file(NULL),
755        opened(false),
756        mode(READ),
757        buf(0),
758        pos(0),
759        count(0)
760{
761}
762File::File(FILE *_file, file_mode_t m) :
763file(_file),
764opened(false),
765mode(m),
766buf(0),
767pos(0),
768count(0)
769{
770}
771File::File(const char *file_name, file_mode_t m) :
772file(NULL),
773opened(false),
774mode(m),
775buf(0),
776pos(0),
777count(0)
778{
779        if (!open(file_name, m)) {
780                throw "Can't open the file";
781        }
782}
783File::~File() {
784        close();
785}
786bool File::open(const char *file_name, file_mode_t m) {
787        if ((mode = m) == READ) {
788                file = fopen(file_name, "rb");
789        } else {
790                file = fopen(file_name, "wb");
791        }
792        return opened = !!(file);
793}
794void File::close() {
795        if (opened) {
796                flush();
797                fclose(file);
798                opened = false;
799                mode = READ;
800        }
801}
802void File::flush() {
803        if (mode == WRITE && count) {
804                buf = (buf >> pos) & ((1ull << count) - 1);
805                fwrite(&buf, 1, (count - 1) / 8 + 1, file);
806        }
807        count = 0;
808        pos = 0;
809        buf = 0;
810}
811size_t File::read(u61_t &block) {
812        if (mode != READ || !opened) {
813                throw "Incorrect read";
814        }
815        u64_t res = 0;
816        size_t cur = 0;
817        if (count) {
818                res = (buf >> pos) & ((1ull << MODSIZE) - 1) & ((1ull << count) - 1);
819                cur = count < MODSIZE ? count : MODSIZE;
820        }
821        if (cur < MODSIZE) {
822                buf = 0;
823                count = 8 * fread(&buf, 1, (MODSIZE - cur - 1) / 8 + 1, file);
824                read_size += count / 8;
825                res |= (buf << cur) & ((1ull << MODSIZE) - 1);
826        }
827        if (res >= MOD || (res < (1ull << (MODSIZE - 1)))) {
828                res &= (1ull << (MODSIZE - 1)) - 1;
829                if (count > MODSIZE - 1 - cur) {
830                        count -= MODSIZE - 1 - cur;
831                        pos = MODSIZE - 1 - cur;
832                        cur = MODSIZE - 1;
833                } else {
834                        cur += count;
835                        count = 0;
836                }
837        } else {
838                count -= MODSIZE - cur;
839                pos = MODSIZE - cur;
840                cur = MODSIZE;
841        }
842        block = res;
843        return cur;
844}
845size_t File::write(const u61_t &block, size_t block_size) {
846        if (mode != WRITE || !opened) {
847                throw "Incorrect write";
848        }
849        u64_t tmp = block;
850        size_t size;
851        if (tmp >= (1ull << (MODSIZE - 1))) {
852                size = MODSIZE;
853        } else {
854                size = block_size;
855        }
856        if (!count) {
857                buf = 0;
858        }
859        buf |= tmp << count;
860        if (size + count >= 8 * sizeof(buf)) {
861                fwrite(&buf, 1, sizeof(buf), file);
862        }
863        if (size + count > 8 *sizeof(buf)) {
864                buf = tmp >> (sizeof(buf)* 8 - count);
865        }
866        count = (size + count) % (8 * sizeof(buf));
867        return size;
868}
869
870random_t::random_t() :
871        generator(std::time(NULL))
872{
873}
874u61_t random_t::operator()() {
875        return u64_t((generator() - 1.) / generator.max() * MOD);
876}
877
878pol_t pol::gcd(const pol_t &x, const pol_t &y) {
879        pol_t a = x, b = y, q;
880        while (q = a % b, q) {
881                a = b;
882                b = q;
883        }
884        return b.normalize();
885}
886pol_t pol::get_x() {
887        pol_t res;
888        res.change_degree(1);
889        res[1] = 1;
890        return res;
891}
892
893pol_t pol::get_rand_pol(u32_t deg, bool flag) {
894        static random_t get_coef;
895        pol_t res;
896        res.change_degree(deg);
897        //res[deg] = flag ? 1 : get_coef();
898        while (!res(deg)) {
899                res[deg] = get_coef();
900        }
901        for (u32_t i = 0; i < deg; ++i) {
902                res[i] = get_coef();
903        }
904        return res;
905}
906
907
908pol3v_t pol::XXX_get_f(const u64_t max_deg, const u32_t key_deg) {
909        polmap_t tmp;
910        for (u32_t i = 0; i <= max_deg; ++i) {
911                tmp.insert(pol3v1_t(deg_t(i, i), get_rand_pol(key_deg - 1)));
912        }
913        return tmp;
914}
915
916pol3v_t pol::XXX_get_mes(const u64_t max_deg, const u32_t key_deg, const u64_t size, const std::vector<u61_t> &m) {
917        polmap_t tmp;
918        pol_t tmp2;
919        u64_t block_count = m.size();
920        tmp2.change_degree(key_deg - 1);
921        for (u32_t i = 0; i < max_deg; ++i) {
922                for (u32_t j = 0; j < key_deg; ++j) {
923                        if (i * key_deg + j < block_count) {
924                                tmp2[j] = m[block_count - 1 - (i * key_deg + j)];
925                        }
926                        else {
927                                tmp2(j) = 0;
928                        }
929                }
930                tmp.insert(pol3v1_t(deg_t(i, i), tmp2));
931        }
932        tmp2.change_degree(0);
933        tmp2[0] = size;
934        tmp.insert(pol3v1_t(deg_t(u32_t(max_deg), u32_t(max_deg)), tmp2));
935        return tmp;
936}
937void pol::XXX_get_fact(const vector_t &fact, u64_t deg, vector_t &res) {
938        size_t num = fact.size();
939        std::vector<std::list<pol_t>> tmp;
940        tmp.resize(deg + 1);
941        for (size_t i = 0; i < num; ++i) {
942                u32_t pol_deg = fact[i].get_deg();
943                for (auto j = tmp.rbegin(); j != tmp.rend(); ++j) {
944                        for (auto it = j->begin(); it != j->end(); ++it) {
945                                if (pol_deg + it->get_deg() <= deg) {
946                                        tmp[pol_deg + it->get_deg()].push_back(fact[i] * *it);
947                                }
948                        }
949                }
950                if (pol_deg <= deg) {
951                        tmp[pol_deg].push_back(fact[i]);
952                }
953        }
954        res.clear();
955        for (auto i = tmp[deg].begin(); i != tmp[deg].end(); ++i) {
956                res.push_back(*i);
957        }
958}
959
Note: See TracBrowser for help on using the repository browser.