Advertisement
Chris_M_Thomasson

Funny Fractal Encryption Command Line

Nov 16th, 2015
581
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 23.62 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stddef.h>
  4. #include <stdint.h>
  5. #include <limits.h>
  6. #include <math.h>
  7. #include <time.h>
  8.  
  9.  
  10.  
  11. /* Defines/Macros
  12. _____________________________________________________________*/
  13. #define FFE_AXES_ARGS 4
  14. #define FFE_SECRET_KEY_ARGS 13
  15. #define FFE_CMDLINE_ARGS 4
  16. #define FFE_JULIA_N 3
  17. #define FFE_BUFSZ (1024 * 1024 * 4)
  18. #define FFE_ERROR 0x1
  19. #define FFE_BYTESZ (UCHAR_MAX + 1)
  20. #define FFE_PREC "%.13lf"
  21.  
  22. #define FFE_MIN(mp_n0, mp_n1) \
  23.     ((mp_n0) < (mp_n1) ? (mp_n0) : (mp_n1))
  24.  
  25. #define RN ffe_util_random
  26.  
  27.  
  28.  
  29. /* Conversions
  30. _____________________________________________________________*/
  31. int
  32. ffe_cnv_uint_from_buffer(
  33.     const char* buf,
  34.     unsigned int* pret
  35. ){
  36.     unsigned int ret = 0;
  37.  
  38.     if (sscanf(buf, "%u", &ret) == 1)
  39.     {
  40.         *pret = ret;
  41.  
  42.         return 0;
  43.     }
  44.  
  45.     return FFE_ERROR;
  46. }
  47.  
  48.  
  49. int
  50. ffe_cnv_double_to_string_to_double(
  51.     double n,
  52.     double* pret
  53. ){
  54.     char nbuf[UCHAR_MAX + 1] = { '\0' };
  55.  
  56.     if (sprintf(nbuf, FFE_PREC, n))
  57.     {
  58.         if (sscanf(nbuf, "%lf", pret) == 1)
  59.         {
  60.             return 0;
  61.         }
  62.     }
  63.  
  64.     return FFE_ERROR;
  65. }
  66.  
  67.  
  68.  
  69. /* Utility
  70. _____________________________________________________________*/
  71. size_t
  72. ffe_util_cantor_packing(
  73.     size_t n0,
  74.     size_t n1
  75. ){
  76.     size_t ret = (size_t)(0.5 * (n0 + n1) * (n0 + n1 + 1) + n1);
  77.  
  78.     return ret;
  79. }
  80.  
  81.  
  82. double
  83. ffe_util_random(void)
  84. {
  85.     return (rand() / (RAND_MAX - 1.0));
  86. }
  87.  
  88.  
  89. double
  90. ffe_util_random_sign(double n)
  91. {
  92.     return (ffe_util_random() < 0.5) ? (n) : (-n);
  93. }
  94.  
  95.  
  96.  
  97. /* A 2d point
  98. _____________________________________________________________*/
  99. struct ffe_point
  100. {
  101.     double x;
  102.     double y;
  103. };
  104.  
  105. struct ffe_point
  106. ffe_complex_add(
  107.     struct ffe_point n0,
  108.     struct ffe_point n1
  109. ){
  110.     struct ffe_point ret = { n0.x + n1.x, n0.y + n1.y };
  111.     return ret;
  112. }
  113.  
  114. struct ffe_point
  115. ffe_complex_mul(
  116.     struct ffe_point n0,
  117.     struct ffe_point n1
  118. ){
  119.     struct ffe_point ret = {
  120.         n0.x * n1.x - n0.y * n1.y,
  121.         n0.x * n1.y + n0.y * n1.x
  122.     };
  123.  
  124.     return ret;
  125. }
  126.  
  127.  
  128. /* Axes describing a 2d plane
  129. _____________________________________________________________*/
  130. struct ffe_axes
  131. {
  132.     double xmin;
  133.     double xmax;
  134.     double ymin;
  135.     double ymax;
  136. };
  137.  
  138.  
  139. /* The Secret Key
  140. _____________________________________________________________*/
  141. struct ffe_secret_key
  142. {
  143.     unsigned int iters;
  144.     struct ffe_point scale;
  145.     struct ffe_point julia[FFE_JULIA_N];
  146.     struct ffe_axes axes;
  147. };
  148.  
  149. int
  150. ffe_secret_key_output_status(
  151.     struct ffe_secret_key const* const self,
  152.     FILE* out_file
  153. ){
  154.     if (fprintf(out_file,
  155.         "Secret Key:\r\n"
  156.         "____________________________________________\r\n"
  157.         "iters: %u\r\n"
  158.         "scale: (" FFE_PREC ", " FFE_PREC ")\r\n"
  159.         "julia0: (" FFE_PREC ", " FFE_PREC ")\r\n"
  160.         "julia1: (" FFE_PREC ", " FFE_PREC ")\r\n"
  161.         "julia2: (" FFE_PREC ", " FFE_PREC ")\r\n"
  162.         "axes: (" FFE_PREC ", " FFE_PREC "\r\n       "
  163.                   FFE_PREC ", " FFE_PREC ")\r\n"
  164.         "____________________________________________\r\n\r\n",
  165.         self->iters,
  166.         self->scale.x, self->scale.y,
  167.         self->julia[0].x, self->julia[0].y,
  168.         self->julia[1].x, self->julia[1].y,
  169.         self->julia[2].x, self->julia[2].y,
  170.         self->axes.xmin, self->axes.xmax,
  171.         self->axes.ymin, self->axes.ymax
  172.         ) > 0)
  173.     {
  174.         return 0;
  175.     }
  176.  
  177.     return FFE_ERROR;
  178. }
  179.  
  180. int
  181. ffe_secret_key_parse_from_file(
  182.     struct ffe_secret_key* const self,
  183.     FILE* in_file
  184. ){
  185.     int ret = fscanf(
  186.         in_file,
  187.         "iters:%u\r\n"
  188.         "scale:(%lf, %lf)\r\n"
  189.         "julia0:(%lf, %lf)\r\n"
  190.         "julia1:(%lf, %lf)\r\n"
  191.         "julia2:(%lf, %lf)\r\n"
  192.         "axes:(%lf, %lf, %lf, %lf)",
  193.         &self->iters,
  194.         &self->scale.x, &self->scale.y,
  195.         &self->julia[0].x, &self->julia[0].y,
  196.         &self->julia[1].x, &self->julia[1].y,
  197.         &self->julia[2].x, &self->julia[2].y,
  198.         &self->axes.xmin, &self->axes.xmax,
  199.         &self->axes.ymin, &self->axes.ymax
  200.     );
  201.  
  202.     if (ret == FFE_SECRET_KEY_ARGS)
  203.     {
  204.         return 0;
  205.     }
  206.  
  207.     return FFE_ERROR;
  208. }
  209.  
  210.  
  211. int
  212. ffe_secret_key_store_to_file(
  213.     struct ffe_secret_key const* const self,
  214.     FILE* out_file
  215. ){
  216.     int ret = fprintf(
  217.         out_file,
  218.         "iters:%u\r\n"
  219.         "scale:(" FFE_PREC ", " FFE_PREC ")\r\n"
  220.         "julia0:(" FFE_PREC ", " FFE_PREC ")\r\n"
  221.         "julia1:(" FFE_PREC ", " FFE_PREC ")\r\n"
  222.         "julia2:(" FFE_PREC ", " FFE_PREC ")\r\n"
  223.         "axes:(" FFE_PREC ", " FFE_PREC ", "
  224.                  FFE_PREC ", " FFE_PREC ")",
  225.         self->iters,
  226.         self->scale.x, self->scale.y,
  227.         self->julia[0].x, self->julia[0].y,
  228.         self->julia[1].x, self->julia[1].y,
  229.         self->julia[2].x, self->julia[2].y,
  230.         self->axes.xmin, self->axes.xmax,
  231.         self->axes.ymin, self->axes.ymax
  232.     );
  233.  
  234.     if (ret > 0)
  235.     {
  236.         return 0;
  237.     }
  238.  
  239.     return FFE_ERROR;
  240. }
  241.  
  242.  
  243.  
  244. /* The Salt
  245. _____________________________________________________________*/
  246. struct ffe_salt
  247. {
  248.     struct ffe_axes axes;
  249. };
  250.  
  251. int
  252. ffe_salt_output_status(
  253.     struct ffe_salt* const self,
  254.     FILE* out_file
  255. ){
  256.     if (fprintf(out_file,
  257.             "Salt:\r\n"
  258.             "____________________________________________\r\n"
  259.             "xmin = " FFE_PREC "\r\n"
  260.             "xmax = " FFE_PREC "\r\n"
  261.             "ymin = " FFE_PREC "\r\n"
  262.             "ymax = " FFE_PREC "\r\n"
  263.             "____________________________________________\r\n\r\n",
  264.             self->axes.xmin, self->axes.xmax,
  265.             self->axes.ymin, self->axes.ymax) > 0)
  266.     {
  267.         return 0;
  268.     }
  269.  
  270.     return FFE_ERROR;
  271. }
  272.  
  273. int
  274. ffe_salt_parse_from_file(
  275.     struct ffe_salt* const self,
  276.     FILE* in_file,
  277.     unsigned char* buf,
  278.     size_t bufsz,
  279.     size_t* pin_file_size
  280. ){
  281.     int ret = fscanf(
  282.         in_file,
  283.         "axes:(%lf, %lf, %lf, %lf)\r\n",
  284.         &self->axes.xmin, &self->axes.xmax,
  285.         &self->axes.ymin, &self->axes.ymax
  286.     );
  287.  
  288.     if (ret == FFE_AXES_ARGS)
  289.     {
  290.         size_t size = 0;
  291.         size_t rbytes = 0;
  292.  
  293.         long offset = ftell(in_file);
  294.  
  295.         if (offset > 0)
  296.         {
  297.             while ((rbytes = fread(buf, 1, bufsz, in_file)))
  298.             {
  299.                 size += rbytes;
  300.                 printf("Parsing salt %lu bytes...\r", (unsigned long)size);
  301.             }
  302.  
  303.             printf("\r\n\r\n");
  304.  
  305.             *pin_file_size = size;
  306.  
  307.             if (! fseek(in_file, offset, SEEK_SET))
  308.             {
  309.                 if (pin_file_size)
  310.                 {
  311.                     return 0;
  312.                 }
  313.             }
  314.         }
  315.     }
  316.  
  317.     return FFE_ERROR;
  318. }
  319.  
  320. int
  321. ffe_salt_generate_from_file(
  322.     struct ffe_salt* const self,
  323.     FILE* in_file,
  324.     unsigned char* buf,
  325.     size_t bufsz,
  326.     size_t* pin_file_size
  327. ){
  328.     size_t size = 0;
  329.     size_t rbytes = 0;
  330.     size_t pack = 0;
  331.  
  332.     while ((rbytes = fread(buf, 1, bufsz, in_file)))
  333.     {
  334.         size += rbytes;
  335.  
  336.         for (size_t i = 0; i < rbytes; ++i)
  337.         {
  338.             pack = (pack + ffe_util_cantor_packing(pack, buf[i])) % SIZE_MAX;
  339.         }
  340.  
  341.         printf("Generating salt %lu bytes...\r", (unsigned long)size);
  342.     }
  343.  
  344.     printf("\r\n\r\n");
  345.  
  346.     *pin_file_size = size;
  347.  
  348.     rewind(in_file);
  349.  
  350.     if (! ferror(in_file))
  351.     {
  352.         if (pin_file_size)
  353.         {
  354.             double pack_m[4] = {
  355.                 fmod(pow(pack, RN() * 0.3 + 0.3), 0.3 + RN() * 0.6),
  356.                 fmod(pow(pack, RN() * 0.3 + 0.3), 0.3 + RN() * 0.6),
  357.                 fmod(pow(pack, RN() * 0.3 + 0.3), 0.3 + RN() * 0.6),
  358.                 fmod(pow(pack, RN() * 0.3 + 0.3), 0.3 + RN() * 0.6)
  359.             };
  360.  
  361.             ffe_cnv_double_to_string_to_double(pack_m[0], &pack_m[0]);
  362.             ffe_cnv_double_to_string_to_double(pack_m[1], &pack_m[1]);
  363.             ffe_cnv_double_to_string_to_double(pack_m[2], &pack_m[2]);
  364.             ffe_cnv_double_to_string_to_double(pack_m[3], &pack_m[3]);
  365.  
  366.             self->axes.xmin = pack_m[0];
  367.             self->axes.xmax = pack_m[1];
  368.             self->axes.ymin = pack_m[2];
  369.             self->axes.ymax = pack_m[3];
  370.  
  371.             return 0;
  372.         }
  373.     }
  374.  
  375.     return FFE_ERROR;
  376. }
  377.  
  378. int
  379. ffe_salt_store_to_file(
  380.     struct ffe_salt const* const self,
  381.     FILE* out_file
  382. ){
  383.     int ret = fprintf(
  384.         out_file,
  385.         "axes:(" FFE_PREC ", " FFE_PREC ", "
  386.                  FFE_PREC ", " FFE_PREC ")\r\n",
  387.         self->axes.xmin, self->axes.xmax,
  388.         self->axes.ymin, self->axes.ymax
  389.     );
  390.  
  391.     if (ret > 1)
  392.     {
  393.         if (! ferror(out_file))
  394.         {
  395.             return 0;
  396.         }
  397.     }
  398.  
  399.     return FFE_ERROR;
  400. }
  401.  
  402.  
  403.  
  404.  
  405. /* Funny Fractal Encryption
  406. _____________________________________________________________*/
  407. struct ffe
  408. {
  409.     unsigned char* buf;
  410.     size_t bufsz;
  411. };
  412.  
  413. struct ffe_cipher
  414. {
  415.     size_t in_file_size;
  416.     unsigned int dims;
  417.     struct ffe_secret_key const* skey;
  418.     struct ffe_salt salt;
  419. };
  420.  
  421. struct ffe_mutator
  422. {
  423.     unsigned int iters;
  424.     struct ffe_point z;
  425.     double min_orbit_trap;
  426. };
  427.  
  428. int
  429. ffe_create(
  430.     struct ffe* const self,
  431.     size_t bufsz
  432. ){
  433.     self->buf = malloc(bufsz);
  434.  
  435.     if (self->buf)
  436.     {
  437.         self->bufsz = bufsz;
  438.         return 0;
  439.     }
  440.  
  441.     return FFE_ERROR;
  442. }
  443.  
  444. void
  445. ffe_destroy(
  446.     struct ffe* const self
  447. ){
  448.     free(self->buf);
  449. }
  450.  
  451. int
  452. ffe_cipher_iterate_point(
  453.     struct ffe_cipher const* const cipher,
  454.     struct ffe_point const* c,
  455.     struct ffe_mutator* mutator
  456. ){
  457.     struct ffe_point z = *c;
  458.  
  459.     double min_orbit_trap = 99999999999999.0;
  460.  
  461.     double orbit_escape = 2.0 + (
  462.         fabs(cipher->skey->julia[0].x) + fabs(cipher->skey->julia[0].y) +
  463.         fabs(cipher->skey->julia[1].x) + fabs(cipher->skey->julia[1].y) +
  464.         fabs(cipher->skey->julia[2].x) + fabs(cipher->skey->julia[2].y)
  465.     );
  466.  
  467.     for (size_t i = 0; i < cipher->skey->iters; ++i)
  468.     {
  469.         z = ffe_complex_mul(z, z);
  470.         z = ffe_complex_add(z, cipher->skey->julia[i % FFE_JULIA_N]);
  471.         z = ffe_complex_mul(z, cipher->skey->scale);
  472.  
  473.         double orbit_dis = sqrt(z.x * z.x + z.y * z.y);
  474.  
  475.         min_orbit_trap = FFE_MIN(min_orbit_trap, orbit_dis);
  476.  
  477.         if (orbit_dis > orbit_escape)
  478.         {
  479.             mutator->iters = i + 1;
  480.             mutator->min_orbit_trap = min_orbit_trap;
  481.             mutator->z = z;
  482.  
  483.             return 0;
  484.         }
  485.     }
  486.  
  487.     mutator->iters = cipher->skey->iters + 1;
  488.     mutator->min_orbit_trap = min_orbit_trap;
  489.     mutator->z = z;
  490.  
  491.     return 1;
  492. }
  493.  
  494. int
  495. ffe_cipher_buffer_inplace(
  496.     struct ffe* const self,
  497.     struct ffe_cipher const* const cipher,
  498.     unsigned char* buf,
  499.     size_t bufsz,
  500.     size_t n,
  501.     unsigned int flags
  502. ){
  503.     double xstep = (cipher->salt.axes.xmax -
  504.         cipher->salt.axes.xmin) / (cipher->dims - 1);
  505.  
  506.     double ystep = (cipher->salt.axes.ymax -
  507.         cipher->salt.axes.ymin) / (cipher->dims - 1);
  508.  
  509.     struct ffe_mutator mutator = { 0, { 0.0, 0.0 }, 0.0 };
  510.  
  511.     for (size_t i = 0; i < bufsz; ++i, ++n)
  512.     {
  513.         unsigned int vpx = n % cipher->dims;
  514.         unsigned int vpy = n / cipher->dims;
  515.  
  516.         struct ffe_point c = {
  517.             cipher->salt.axes.xmin + vpx * xstep,
  518.             cipher->salt.axes.ymax - vpy * ystep
  519.         };
  520.  
  521.         int iret = ffe_cipher_iterate_point(cipher, &c, &mutator);
  522.  
  523.         double cmutator_real = mutator.iters * mutator.min_orbit_trap *
  524.             (mutator.min_orbit_trap + mutator.z.x + mutator.z.y);
  525.  
  526.         cmutator_real += cos((mutator.min_orbit_trap +
  527.             mutator.z.x + mutator.z.y) * 1304) * 256;
  528.  
  529.         if (! iret)
  530.         {
  531.             cmutator_real *= 17273;
  532.         }
  533.  
  534.         else
  535.         {
  536.             cmutator_real *= 115237;
  537.         }
  538.  
  539.         unsigned int cmutator_uint = ((size_t)fabs(cmutator_real)) % FFE_BYTESZ;
  540.         int cmutated_byte = 0;
  541.  
  542.         if (flags == 0x1)
  543.         {
  544.             // Encrypt
  545.             cmutated_byte = (buf[i] + cmutator_uint) % FFE_BYTESZ;
  546.         }
  547.  
  548.         else
  549.         {
  550.             // Decrypt
  551.             cmutated_byte = buf[i] - cmutator_uint;
  552.  
  553.             if (cmutated_byte < 0)
  554.             {
  555.                 cmutated_byte = abs((buf[i] + FFE_BYTESZ) - cmutator_uint);
  556.             }
  557.         }
  558.  
  559.         buf[i] = cmutated_byte;
  560.  
  561.         if (! (n % 8192))
  562.         {
  563.             unsigned int per = (unsigned int)ceil((n / (double)cipher->in_file_size) * 100.0);
  564.             if (flags == 0x1) printf("Encrypted %lu bytes: %u%% complete...\r", (unsigned long)n, per);
  565.                 else printf("Decrypted %lu bytes: %u%% complete...\r", (unsigned long)n, per);
  566.         }
  567.     }
  568.  
  569.     unsigned int per = (unsigned int)ceil((n / (double)cipher->in_file_size) * 100.0);
  570.     if (flags == 0x1) printf("Encrypted %lu bytes: %u%% complete...\r", (unsigned long)n, per);
  571.         else printf("Decrypted %lu bytes: %u%% complete...\r", (unsigned long)n, per);
  572.  
  573.     return 0;
  574. }
  575.  
  576. int
  577. ffe_sys_calc_salt(
  578.     struct ffe_cipher* cipher,
  579.     size_t in_file_size
  580. ){
  581.     cipher->dims = (size_t)(sqrt(in_file_size) + 1);
  582.  
  583.  
  584.     cipher->in_file_size = in_file_size;
  585.     cipher->salt.axes.xmin = cipher->skey->axes.xmin - cipher->salt.axes.xmin;
  586.     cipher->salt.axes.xmax = cipher->skey->axes.xmax + cipher->salt.axes.xmax;
  587.     cipher->salt.axes.ymin = cipher->skey->axes.ymin - cipher->salt.axes.ymin;
  588.     cipher->salt.axes.ymax = cipher->skey->axes.ymax + cipher->salt.axes.ymax;
  589.  
  590.     printf(
  591.         "Processing %lu bytes...\r\n"
  592.         "____________________________________________\r\n"
  593.         "axes:(" FFE_PREC ", " FFE_PREC "\r\n      "
  594.                  FFE_PREC ", " FFE_PREC ")\r\n\r\n",
  595.         (unsigned long)in_file_size,
  596.         cipher->salt.axes.xmin, cipher->salt.axes.xmax,
  597.         cipher->salt.axes.ymin, cipher->salt.axes.ymax);
  598.  
  599.     return 0;
  600. }
  601.  
  602. int
  603. ffe_encrypt(
  604.     struct ffe* const self,
  605.     struct ffe_secret_key const* skey,
  606.     FILE* in_file,
  607.     FILE* out_file
  608. ){
  609.     size_t in_file_size = 0;
  610.  
  611.     struct ffe_cipher cipher = {
  612.         0, 0, skey, { { 0.0, 0.0, 0.0, 0.0 } }
  613.     };
  614.  
  615.     if (! ffe_salt_generate_from_file(
  616.             &cipher.salt,
  617.             in_file,
  618.             self->buf,
  619.             self->bufsz,
  620.             &in_file_size))
  621.     {
  622.         ffe_salt_output_status(&cipher.salt, stdout);
  623.  
  624.         if (! ffe_salt_store_to_file(&cipher.salt, out_file))
  625.         {
  626.             size_t size = 0;
  627.             size_t rbytes = 0;
  628.  
  629.             ffe_sys_calc_salt(&cipher, in_file_size);
  630.  
  631.             while ((rbytes = fread(self->buf, 1, self->bufsz, in_file)))
  632.             {
  633.                 if (ffe_cipher_buffer_inplace(
  634.                         self,
  635.                         &cipher,
  636.                         self->buf,
  637.                         rbytes,
  638.                         size,
  639.                         0x1))
  640.                 {
  641.                     return FFE_ERROR;
  642.                 }
  643.  
  644.                 if (fwrite(self->buf, 1, rbytes, out_file) != rbytes)
  645.                 {
  646.                     return FFE_ERROR;
  647.                 }
  648.  
  649.                 size += rbytes;
  650.             }
  651.  
  652.             if (in_file_size == size)
  653.             {
  654.                 return 0;
  655.             }
  656.         }
  657.     }
  658.  
  659.     return FFE_ERROR;
  660. }
  661.  
  662.  
  663. int
  664. ffe_decrypt(
  665.     struct ffe* const self,
  666.     struct ffe_secret_key const* skey,
  667.     FILE* in_file,
  668.     FILE* out_file
  669. ){
  670.     size_t in_file_size = 0;
  671.  
  672.     struct ffe_cipher cipher = {
  673.         0, 0, skey, { { 0.0, 0.0, 0.0, 0.0 } }
  674.     };
  675.  
  676.     if (! ffe_salt_parse_from_file(
  677.             &cipher.salt,
  678.             in_file,
  679.             self->buf,
  680.             self->bufsz,
  681.             &in_file_size))
  682.     {
  683.         size_t size = 0;
  684.         size_t rbytes = 0;
  685.  
  686.         ffe_salt_output_status(&cipher.salt, stdout);
  687.  
  688.         ffe_sys_calc_salt(&cipher, in_file_size);
  689.  
  690.         while ((rbytes = fread(self->buf, 1, self->bufsz, in_file)))
  691.         {
  692.             if (ffe_cipher_buffer_inplace(
  693.                     self,
  694.                     &cipher,
  695.                     self->buf,
  696.                     rbytes,
  697.                     size,
  698.                     0x2))
  699.             {
  700.                 return FFE_ERROR;
  701.             }
  702.  
  703.             if (fwrite(self->buf, 1, rbytes, out_file) != rbytes)
  704.             {
  705.                 return FFE_ERROR;
  706.             }
  707.  
  708.             size += rbytes;
  709.         }
  710.  
  711.         if (in_file_size == size)
  712.         {
  713.             return 0;
  714.         }
  715.     }
  716.  
  717.     return FFE_ERROR;
  718. }
  719.  
  720.  
  721.  
  722.  
  723. /* Funny Fractal Encryption Test Command Line App
  724. _____________________________________________________________*/
  725. struct ffe_cmdline_args
  726. {
  727.     int argc;
  728.     char **argv;
  729. };
  730.  
  731. struct ffe_cmdline_app
  732. {
  733.     struct ffe_cmdline_args cmdargs;
  734.     struct ffe cipher;
  735.     struct ffe_secret_key skey;
  736.     unsigned int flags;
  737.     FILE* in_file;
  738.     FILE* out_file;
  739. };
  740.  
  741. int
  742. ffe_cmdline_app_create(
  743.     struct ffe_cmdline_app* const self,
  744.     struct ffe_cmdline_args const* cmdargs
  745. ){
  746.     printf(
  747.         "Funny Fractal Encryption ver:(0.0.0) pre-alpha\r\n"
  748.         "by: Chris M. Thomasson\r\n"
  749.         "==================================================\r\n\r\n");
  750.  
  751.     self->cmdargs = *cmdargs;
  752.     self->in_file = self->out_file = NULL;
  753.  
  754.     srand((unsigned int)time(NULL));
  755.  
  756.     if (self->cmdargs.argc < 2)
  757.     {
  758.         return FFE_ERROR;
  759.     }
  760.  
  761.     self->flags = 0;
  762.     if (ffe_cnv_uint_from_buffer(self->cmdargs.argv[1], &self->flags))
  763.     {
  764.         return FFE_ERROR;
  765.     }
  766.  
  767.     if (self->flags == 0)
  768.     {
  769.         return 0;
  770.     }
  771.  
  772.     else if (self->cmdargs.argc == FFE_CMDLINE_ARGS + 1)
  773.     {
  774.         // Read the secret key
  775.         const char* skey_fname = self->cmdargs.argv[2];
  776.         FILE* skey_file = fopen(skey_fname, "rb");
  777.  
  778.         if (skey_file)
  779.         {
  780.             if (! ffe_secret_key_parse_from_file(&self->skey, skey_file))
  781.             {
  782.                 if (! fclose(skey_file))
  783.                 {
  784.                     if (! ffe_create(&self->cipher, FFE_BUFSZ))
  785.                     {
  786.                         if (self->flags == 1)
  787.                         {
  788.                             printf(
  789.                                 "secret key: %s\r\n"
  790.                                 "in file:    %s\r\n"
  791.                                 "out file:   %s\r\n\r\n",
  792.                                 self->cmdargs.argv[2],
  793.                                 self->cmdargs.argv[3],
  794.                                 self->cmdargs.argv[4]
  795.                             );
  796.                         }
  797.  
  798.                         else if (self->flags == 2)
  799.                         {
  800.                             printf(
  801.                                 "secret key: %s\r\n"
  802.                                 "in file:    %s\r\n"
  803.                                 "out file:   %s\r\n\r\n",
  804.                                 self->cmdargs.argv[2],
  805.                                 self->cmdargs.argv[4],
  806.                                 self->cmdargs.argv[3]
  807.                             );
  808.                         }
  809.  
  810.                         ffe_secret_key_output_status(&self->skey, stdout);
  811.  
  812.                         return 0;
  813.                     }
  814.                 }
  815.             }
  816.  
  817.             else
  818.             {
  819.                 fclose(skey_file);
  820.             }
  821.         }
  822.     }
  823.  
  824.     return FFE_ERROR;
  825. }
  826.  
  827. int
  828. ffe_cmdline_sys_create_default_skey(
  829.     struct ffe_cmdline_app* const self
  830. ){
  831.     struct ffe_secret_key const skey = {
  832.         314,
  833.         { 1.0, 0.0 },
  834.         { { 0.36, 0.0 }, { -0.75, 0.1 }, { 0.35, 0.1 } },
  835.         { -0.7, 0.3, -0.2, 0.8 }
  836.     };
  837.  
  838.     if (! self->out_file)
  839.     {
  840.         self->out_file = fopen(self->cmdargs.argv[2], "wb");
  841.         if (! self->out_file) return FFE_ERROR;
  842.     }
  843.  
  844.     if (! ffe_secret_key_store_to_file(&skey, self->out_file))
  845.     {
  846.         printf("out file: %s\r\n"
  847.                "default secret key created!\r\n\r\n",
  848.                self->cmdargs.argv[2]);
  849.  
  850.         ffe_secret_key_output_status(&skey, stdout);
  851.  
  852.         return 0;
  853.     }
  854.  
  855.     return FFE_ERROR;
  856. }
  857.  
  858. int
  859. ffe_cmdline_sys_encrypt(
  860.     struct ffe_cmdline_app* const self
  861. ){
  862.     if (! self->out_file)
  863.     {
  864.         self->in_file = fopen(self->cmdargs.argv[3], "rb");
  865.         self->out_file = fopen(self->cmdargs.argv[4], "wb");
  866.         if (! self->in_file || ! self->out_file) return FFE_ERROR;
  867.     }
  868.  
  869.     if (! ffe_encrypt(
  870.             &self->cipher,
  871.             &self->skey,
  872.             self->in_file,
  873.             self->out_file))
  874.     {
  875.         printf("\r\n____________________________________________\r\n\r\n");
  876.  
  877.         return 0;
  878.     }
  879.  
  880.     return FFE_ERROR;
  881. }
  882.  
  883. int
  884. ffe_cmdline_sys_decrypt(
  885.     struct ffe_cmdline_app* const self
  886. ){
  887.     if (! self->out_file)
  888.     {
  889.         self->in_file = fopen(self->cmdargs.argv[4], "rb");
  890.         self->out_file = fopen(self->cmdargs.argv[3], "wb");
  891.         if (! self->in_file || ! self->out_file) return FFE_ERROR;
  892.     }
  893.  
  894.     if (! ffe_decrypt(
  895.             &self->cipher,
  896.             &self->skey,
  897.             self->in_file,
  898.             self->out_file))
  899.     {
  900.         printf("\r\n____________________________________________\r\n\r\n");
  901.  
  902.         return 0;
  903.     }
  904.  
  905.     return FFE_ERROR;
  906. }
  907.  
  908. void
  909. ffe_cmdline_display_help(
  910.     FILE* out_file
  911. ){
  912.     fprintf(out_file,
  913.         "\r\n\r\nProgram Usage:\r\n"
  914.         "___________________________________________\r\n"
  915.         "The command line for creating a default secret key file that can\r\n"
  916.         "be changed with a text editor has two arguments:\r\n\r\n"
  917.         "ffe 0 <secret_key_filename>\r\n\r\n\r\n"
  918.         "The encryption command line will encrypt a plaintext into a ciphertext\r\n"
  919.         "using a secret key, and has 4 arguments:\r\n\r\n"
  920.         "ffe 1 <secret_key_filename> <plaintext_filename> <ciphertext_filename>\r\n\r\n\r\n"
  921.         "The decryption command line will decrypt a ciphertext into a plaintext\r\n"
  922.         "using a secret key, and has 4 arguments:\r\n\r\n"
  923.         "ffe 2 <secret_key_filename> <plaintext_filename> <ciphertext_filename>\r\n\r\n\r\n"
  924.         "The command line for displaying this usage information has no arguments:\r\n"
  925.         "ffe\r\n\r\n\r\n"
  926.         "Enjoy!\r\n"
  927.         "___________________________________________\r\n\r\n"
  928.     );
  929. }
  930.  
  931. int
  932. ffe_cmdline_app_run(
  933.     struct ffe_cmdline_app* const self
  934. ){
  935.     int ret = FFE_ERROR;
  936.  
  937.     if (self->flags == 0x0)
  938.     {
  939.         ret = ffe_cmdline_sys_create_default_skey(self);
  940.     }
  941.  
  942.     else if (self->flags == 0x1)
  943.     {
  944.         ret = ffe_cmdline_sys_encrypt(self);
  945.     }
  946.  
  947.     else if (self->flags == 0x2)
  948.     {
  949.         ret = ffe_cmdline_sys_decrypt(self);
  950.     }
  951.  
  952.     return ret;
  953. }
  954.  
  955. int
  956. ffe_cmdline_app_destroy(
  957.     struct ffe_cmdline_app* const self
  958. ){
  959.     int ret = 0;
  960.  
  961.     if ((self->in_file && fclose(self->in_file)) ||
  962.         (self->out_file && fclose(self->out_file)))
  963.     {
  964.         ret = FFE_ERROR;
  965.     }
  966.  
  967.     if (self->flags != 0)
  968.     {
  969.         ffe_destroy(&self->cipher);
  970.     }
  971.  
  972.     return ret;
  973. }
  974.  
  975.  
  976.  
  977. int
  978. main(int argc, char **argv)
  979. {
  980.     struct ffe_cmdline_app self;
  981.     struct ffe_cmdline_args cmdargs = { argc, argv };
  982.  
  983.     if (! ffe_cmdline_app_create(&self, &cmdargs))
  984.     {
  985.         if (! ffe_cmdline_app_run(&self))
  986.         {
  987.             if (! ffe_cmdline_app_destroy(&self))
  988.             {
  989.                 puts("\r\n\r\nProgram Completed!");
  990.                 getchar();
  991.  
  992.                 return EXIT_SUCCESS;
  993.             }
  994.         }
  995.  
  996.         else
  997.         {
  998.             ffe_cmdline_app_destroy(&self);
  999.         }
  1000.     }
  1001.  
  1002.     ffe_cmdline_display_help(stdout);
  1003.  
  1004.     puts("\r\n\r\nProgram Failed!");
  1005.     getchar();
  1006.  
  1007.     return EXIT_FAILURE;
  1008. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement