File Coverage

blib/lib/Crypt/FNA.pm
Criterion Covered Total %
statement 12 286 4.2
branch 0 60 0.0
condition 0 6 0.0
subroutine 4 29 13.7
pod 25 25 100.0
total 41 406 10.1


line stmt bran cond sub pod time code
1             # package: Anak Cryptography with Fractal Numerical Algorithm FNA
2             # author: Mario Rossano aka Anak, www.netlogicalab.com, www.netlogica.it; software@netlogicalab.com; software@netlogica.it
3             # birthday 05/08/1970; birthplace: Italy
4             # LIBRARY FILE
5            
6             # This program is free software; you can redistribute it and/or modify it
7             # under the terms of either:
8             # CC-NC-BY-SA
9             # license http://creativecommons.org/licenses/by-nc-sa/2.5/it/deed.en
10             # Creative Commons License: http://i.creativecommons.org/l/by-nc-sa/2.5/it/88x31.png
11             # FNA Fractal Numerical Algorithm for a new cryptography technology, author Mario Rossano
12             # is licensed under a: http://creativecommons.org/B/by-nc-sa/2.5/it/deed.en - Creative Commons Attribution-Noncommercial-Share Alike 2.5 Italy License
13             # Permissions beyond the scope of this license may be available at software@netlogicalab.com
14            
15             package Crypt::FNA;
16            
17             # caricamento lib
18 1     1   22142 use strict;
  1         3  
  1         43  
19 1     1   5 use warnings;
  1         2  
  1         33  
20 1     1   573 use Crypt::FNA::Validation;
  1         2  
  1         52  
21             # fine caricamento lib
22            
23             our $VERSION = '0.65';
24 1     1   8 use constant pi => 3.141592;
  1         3  
  1         3779  
25            
26             # metodi ed attributi
27            
28             sub new {
29 0     0 1   my $class = shift;
30 0           my $init = shift;
31 0           my $self={};
32            
33 0           bless $self,$class;
34            
35 0           $self->r($init->{r});
36 0           $self->angle($init->{angle});
37 0           $self->square($init->{square});
38 0           $self->background($init->{background});
39 0           $self->foreground($init->{foreground});
40 0           $self->magic($init->{magic});
41 0           $self->message($init->{message});
42 0           $self->salted($init->{salted});
43            
44 0           my $validate=Crypt::FNA::Validation->new({intercept => $self});
45 0           $validate->method_new_fna($self);
46            
47 0           return $self
48             }
49            
50             sub r {
51 0     0 1   my $self=shift;
52 0 0         if (@_) {
53 0           $self->{r}=shift
54             }
55 0           return $self->{r}
56             }
57             sub angle {
58 0     0 1   my $self=shift;
59 0 0         if (@_) {
60 0           $self->{angle}=shift
61             }
62 0           return $self->{angle}
63             }
64             sub square {
65 0     0 1   my $self=shift;
66 0 0         if (@_) {
67 0           $self->{square}=shift
68             }
69 0           return $self->{square}
70             }
71             sub background {
72 0     0 1   my $self=shift;
73 0 0         if (@_) {
74 0           $self->{background}=shift
75             }
76 0           return $self->{background}
77             }
78             sub foreground {
79 0     0 1   my $self=shift;
80 0 0         if (@_) {
81 0           $self->{foreground}=shift
82             }
83 0           return $self->{foreground}
84             }
85             sub magic {
86 0     0 1   my $self=shift;
87 0 0         if (@_) {
88 0           $self->{magic}=shift
89             }
90 0           return $self->{magic}
91             }
92             sub message {
93 0     0 1   my $self=shift;
94 0 0         if (@_) {
95 0           $self->{message}=shift
96             }
97 0           return $self->{message}
98             }
99             sub salted {
100 0     0 1   my $self=shift;
101 0 0         if (@_) {
102 0           $self->{salted}=shift
103             }
104 0           return $self->{salted}
105             }
106            
107             sub make_fract {
108 0     0 1   my ($self,$png_filename,$zoom)=@_;
109            
110 0           (my $ro,my @initial_angle)=$self->set_starting_angle();
111 0           (my $nx,my $ny,my $di)=$self->init_geometry($ro);
112            
113 0           my $load_this_package=eval("require GD::Simple;");
114 0           $load_this_package.='';
115 0 0         if ($load_this_package eq '') {
116 0           push(@{$self->{message}},16);
  0            
117             return
118 0           }
119            
120             #controllo zoom, solo valori numerici e > 0
121 0           my $validate=Crypt::FNA::Validation->new({intercept => [$zoom,$self]});
122 0           ($zoom,@{$self->message})=$validate->param_zoom_fna($self);
  0            
123 0 0         $di=$di*$zoom if $zoom != 1;
124             #fine controllo zoom
125            
126 0           my $img = GD::Simple->new($self->square,$self->square);
127 0           $img->fgcolor(@{$self->background}); # foreground
  0            
128 0           $img->bgcolor(@{$self->background}); # background
  0            
129 0           $img->rectangle(0,0,$self->square,$self->square); # campisce il quadrato
130 0           $img->fgcolor(@{$self->foreground}); # foreground
  0            
131            
132 0           $img->move($nx,$ny);
133            
134 0           for my $k(0..$ro**($self->r)-1) {
135 0 0 0       ${$self->angle}[$k]=$self->evaluate_this_angle($k,$ro) if ($k>=$ro && $k<$ro**($self->r-1));
  0            
136 0           ($nx,$ny)=$self->evaluate_this_coords($k,$zoom,$nx,$ny,$di,$ro);
137 0           $img->lineTo($nx,$ny)
138             }
139            
140 0           my $fh_pngfile;
141 0 0         open $fh_pngfile,'>',$png_filename.'.png' or do {
142 0           push(@{$self->{message}},11);
  0            
143             return
144 0           };
145 0           binmode $fh_pngfile;
146 0           print $fh_pngfile $img->png;
147 0           close $fh_pngfile;
148 0           @{$self->angle}=@initial_angle
  0            
149             }
150            
151             sub encrypt_file {
152 0     0 1   my ($self,$name_plain_file,$name_encrypted_file)=@_;
153            
154 0           (my $ro,my @initial_angle)=$self->set_starting_angle();
155 0           (my $nx,my $ny,my $di)=$self->init_geometry($ro);
156            
157 0           $di+=$self->magic;
158 0           $nx=$nx/$self->magic; # ascissa iniziale
159 0           $ny=$ny/$self->magic; # ordinata iniziale;
160            
161 0           my ($this_byte,$byte_dec);
162 0           my $byte_pos=0;
163            
164 0           my ($fh_plain,$fh_encrypted);
165 0 0         open $fh_plain,'<',$name_plain_file or do {
166 0           push(@{$self->{message}},7);
  0            
167             return
168 0           };
169 0           binmode $fh_plain;
170            
171             # somma del valore dei bytes coinvolti: fornisce il numero dei vertici da calcolare
172             # in modo da ottimizzare l'uso della ram
173 0           my $limit=$self->calc_limit($fh_plain,$ro);
174            
175 0 0         open $fh_encrypted,'>',$name_encrypted_file or do {
176 0           push(@{$self->{message}},8);
  0            
177             return
178 0           };
179            
180             # preporre $salt criptato al contenuto di $fh_plain e procedere normalmente
181             # qui verifico se applicare il salt oppure no
182            
183             # qui calcolo il sale e lo cripto
184 0           my $salt;
185            
186 0 0         if ($self->salted eq "true") {
187 0           $salt=$self->make_salt;
188            
189 0           open my $fh_salt,"<",\$salt;
190             #occorre aumentare il limit computando quello dei bytes del salt
191 0           $limit+=$self->calc_limit($fh_salt,$ro);
192 0           while (read($fh_salt,$this_byte,1)) {
193 0           $byte_dec=unpack('C',$this_byte)+$self->magic+1;
194 0           ($nx,$ny,$byte_pos)=$self->crypt_fract($ro,1,$di,$nx,$ny,$byte_dec,$byte_pos,$limit);
195 0           print $fh_encrypted $nx."\n".$ny."\n"
196             }
197 0           close $fh_salt
198             }
199            
200             # qui processo il file in chiaro
201 0           while (read($fh_plain,$this_byte,1)) {
202 0           $byte_dec=unpack('C',$this_byte)+$self->magic+1;
203 0           ($nx,$ny,$byte_pos)=$self->crypt_fract($ro,1,$di,$nx,$ny,$byte_dec,$byte_pos,$limit);
204 0           print $fh_encrypted $nx."\n".$ny."\n"
205             }
206 0           close ($fh_encrypted);
207 0           close ($fh_plain);
208 0           @{$self->angle}=@initial_angle
  0            
209             }
210            
211             sub decrypt_file {
212 0     0 1   my ($self,$name_encrypted_file,$name_decrypted_file)=@_;
213            
214 0           (my $ro,my @initial_angle)=$self->set_starting_angle();
215 0           (my $nx,my $ny,my $di)=$self->init_geometry($ro);
216            
217 0           $di+=$self->magic;
218 0           $nx=$nx/$self->magic; # ascissa iniziale
219 0           $ny=$ny/$self->magic; # ordinata iniziale;
220            
221 0           my $from_vertex=0;
222 0           my ($this_byte,$this_byte_dec,$this_vertex,$x_coord,$y_coord);
223            
224 0           my ($fh_encrypted,$fh_decrypted);
225 0 0         open $fh_encrypted,'<',$name_encrypted_file or do {
226 0           push(@{$self->{message}},9);
  0            
227             return
228 0           };
229            
230             # qui devo valutare il $limit ma non posso essere preciso come sulla cifratura
231             # poiché non conosco a priori il valore dei bytes ma posso impostarne il limite
232             # massimo, calcolando ogni byte a 256, dovrei comunque avere un risparmio
233             # di ram nell'ordine del 50%
234             # il numero di bytes da decodificare e' pari al numero di righe del file cifrato/2
235            
236 0           my ($bytes,$limit);
237 0           $bytes++ while <$fh_encrypted>;
238 0           seek ($fh_encrypted,0,0);
239             # qui moltiplico per 128 e non per 256 perche' le righe sono il doppio dei bytes
240 0           my $exponent=log($bytes*128)/log($ro);
241 0 0         $ro**$exponent>int($ro**$exponent) ? $limit=int($ro**$exponent) : $limit=$ro**($exponent-1);
242            
243 0 0         open $fh_decrypted,'>',$name_decrypted_file or do {
244 0           push(@{$self->{message}},10);
  0            
245             return
246 0           };
247 0           binmode $fh_decrypted;
248            
249 0 0         my $ignore_this_vertex if $self->salted eq "true";
250 0           while (!eof($fh_encrypted)) {
251 0           $x_coord=<$fh_encrypted>;$y_coord=<$fh_encrypted>;
  0            
252 0           chop($x_coord,$y_coord);
253             # ho usato chop perche' l'ultimo carattere e' certamente \n e chop e' piu' veloce di chomp
254            
255 0           for my $vertex($from_vertex..256+$from_vertex+$self->magic) {
256 0           ($nx,$ny,$this_vertex)=$self->crypt_fract($ro,1,$di,$nx,$ny,1,$vertex,$limit);
257 0 0 0       if ($nx eq $x_coord && $ny eq $y_coord) {
258            
259 0           $this_byte_dec=$this_vertex-$from_vertex-$self->magic-1;
260 0           $this_byte=pack('C',$this_byte_dec);
261            
262 0 0         if ($self->salted eq "true") {
263             # se e' salato devo saltare i primi $magic**2 bytes
264 0           $ignore_this_vertex++;
265 0 0         if ($ignore_this_vertex>$self->magic**2) {
266 0           print $fh_decrypted $this_byte;
267             }
268             } else {
269 0           print $fh_decrypted $this_byte
270             }
271            
272             #imposto il from per ripartire il ciclo for dal punto giusto alla prossima iterazione del while, quando ripartira' il for
273 0           $from_vertex=$this_vertex;
274             last
275 0           }
276             } # fine for
277             } # fine ciclo while
278 0           close $fh_decrypted;
279 0           close $fh_encrypted;
280 0           @{$self->angle}=@initial_angle
  0            
281             }
282            
283             sub encrypt_scalar {
284 0     0 1   my ($self,$scalar)=@_;
285            
286             # hack cripta stringa
287 0           my ($fh_testo_chiaro,$file_chiaro);
288 0 0         open $fh_testo_chiaro, '>',\$file_chiaro or die "$_\n";
289 0           print $fh_testo_chiaro $scalar;
290 0           close $fh_testo_chiaro;
291            
292 0           my ($fh_file_criptato,$file_criptato);
293 0           $self->encrypt_file(\$file_chiaro,\$file_criptato);
294 0 0         open $fh_file_criptato,'<',\$file_criptato or die "$_\n";
295 0           my @encrypted=<$fh_file_criptato>;
296 0           close $fh_file_criptato;
297 0           for (@encrypted) {chop($_)}
  0            
298             # end
299 0           return (@encrypted)
300             }
301            
302             sub decrypt_scalar {
303 0     0 1   my ($self,@encrypted_scalar)=@_;
304            
305             # hack ricostruzione stringa
306 0           my ($fh_testo_criptato,$file_criptato);
307 0 0         open $fh_testo_criptato, '>',\$file_criptato or die "$_\n";
308 0           for (@encrypted_scalar) {print $fh_testo_criptato $_."\n"}
  0            
309 0           close $fh_testo_criptato;
310            
311 0           my ($fh_testo_decriptato,$stringa_decriptata);
312 0           $self->decrypt_file(\$file_criptato,\$stringa_decriptata);
313             # end
314 0           return ($stringa_decriptata)
315             }
316            
317             sub mac {
318 0     0 1   my ($self,$name_plain_file)=@_;
319            
320 0           my $salted_status=$self->salted;
321 0           $self->{salted}='false'; # non posso fare mac con salatura, non ha senso!
322            
323 0           my $can_use_Tie_File = eval 'use Tie::File; 1';
324            
325 0 0         if ($can_use_Tie_File) {
326            
327 0           my $name_encrypted_file=$name_plain_file.'fna';
328 0           $self->encrypt_file($name_plain_file, $name_encrypted_file);
329            
330 0           my $fh_encrypted;
331 0 0         open $fh_encrypted,'<',$name_encrypted_file or do {
332 0           push(@{$self->{message}},23);
  0            
333 0           $self->salted=$salted_status;
334             return
335 0           };
336 0           binmode $fh_encrypted;
337            
338 0           my @encrypted_file;
339 0           tie @encrypted_file, 'Tie::File', $fh_encrypted;
340 0           my $n_recs=@encrypted_file;
341 0           my $mac=$encrypted_file[$n_recs-1].$encrypted_file[$n_recs-2];
342 0           $mac =~ s/(\.|-)//g;
343 0           untie @encrypted_file;
344 0           close $fh_encrypted;
345 0           unlink $name_encrypted_file;
346            
347 0           $self->{salted}=$salted_status;
348 0           return($mac)
349             } else {
350 0           push(@{$self->{message}},22);
  0            
351 0           $self->salted=$salted_status;
352             return
353 0           }
354             }
355            
356             sub crypt_fract {
357 0     0 1   my ($self,$ro,$zoom,$di,$nx,$ny,$value_dec,$pos,$limit)=@_;
358 0           for my $k($pos..$pos+$value_dec-1) {
359 0 0         ${$self->angle}[$k]=$self->evaluate_this_angle($k,$ro) if $pos<$limit; #$k>=$ro &&
  0            
360 0           ($nx,$ny)=$self->evaluate_this_coords($k,$zoom,$nx,$ny,$di,$ro)
361             }
362 0           return($nx,$ny,$pos+$value_dec)
363             }
364            
365             # fine metodi e proprieta' oggetto
366            
367             # subroutine di servizio
368            
369             sub set_starting_angle {
370 0     0 1   my $self=shift;
371 0           my $ro=scalar(@{$self->angle});
  0            
372            
373 0           my @initial_angle;
374            
375             #conversione in radianti
376 0           for my $k(0..$ro-1) {
377 0           push(@initial_angle,${$self->angle}[$k]);
  0            
378 0           ${$self->angle}[$k]=${$self->angle}[$k]*pi/180
  0            
  0            
379             }
380 0           return ($ro,@initial_angle)
381             }
382            
383             sub init_geometry {
384 0     0 1   my ($self,$ro)=@_;
385            
386 0           my $di=int(($self->square/$ro**$self->r)*10000)/5000; # lunghezza di un segmento di curva frattale
387 0 0         $di=$di+1 if $di<1;
388 0           my $nx=$self->square/2; # ascissa iniziale
389 0           my $ny=$self->square/2; # ordinata iniziale
390 0           return ($nx,$ny,$di)
391             }
392            
393             sub make_salt {
394 0     0 1   my $self=shift;
395 0           my ($time,$rand,$salt);
396 0           do {
397 0           $time=time();
398 0           $rand=rand()+10**-8;
399 0           $salt.=int($time/$rand);
400 0           $salt=substr($salt,0,$self->magic**2)
401             } until (length($salt)==$self->magic**2);
402 0           return $salt
403             }
404            
405             sub calc_limit {
406 0     0 1   my ($self,$fh_plain,$ro)=@_;
407 0           my ($bytes,$this_byte);
408 0           while (!eof($fh_plain)) {
409 0           read($fh_plain,$this_byte,1);
410 0           $bytes+=unpack('C',$this_byte)+$self->magic+1
411             }
412 0           seek $fh_plain,0,0; # riporto il puntatore all'inizio per la successiva scansione
413 0           my $exponent=log($bytes)/log($ro);
414            
415 0           my $limit;
416 0 0         $ro**$exponent>int($ro**$exponent) ? $limit=int($ro**$exponent) : $limit=$ro**($exponent-1);
417 0           return $limit
418             }
419            
420             # functions calcolo angoli e coordinate
421            
422             sub evaluate_this_angle {
423 0     0 1   my ($self,$k,$ro)=@_;
424 0           return ${$self->angle}[g($k,$ro)]+${$self->angle}[p($k,$ro)]
  0            
  0            
425             }
426            
427             sub evaluate_this_coords {
428 0     0 1   my ($self,$k,$zoom,$nx,$ny,$di,$ro)=@_;
429            
430 0           $nx=$nx-$di*cos(${$self->angle}[g($k,$ro)]+${$self->angle}[p($k,$ro)]);
  0            
  0            
431 0           $ny=$ny-$di*sin(${$self->angle}[g($k,$ro)]+${$self->angle}[p($k,$ro)]);
  0            
  0            
432            
433 0           return (round($nx,6),round($ny,6))
434             }
435            
436             # ramo di {F}
437             sub g {
438 0     0 1   my ($k,$ro)=@_;
439 0           return int($k/$ro)
440             }
441            
442             # posizione nel ramo
443             sub p {
444 0     0 1   my ($k,$ro)=@_;
445 0           return $k-$ro*g($k,$ro)
446             }
447            
448             # tronca alla n-esima cifra decimale (piu' veloce di sprintf)
449             sub round {
450 0     0 1   my ($number,$decimal)=@_;
451 0           return int(10**$decimal*$number)/10**$decimal
452             }
453             # fine function per identificazione direzioni genitore
454            
455             # end subroutine
456            
457             1;
458            
459             # POD SECTION
460            
461             =head1 NAME
462            
463             Crypt::FNA
464            
465             =head1 VERSION
466            
467             Version 0.65
468            
469             =head1 DESCRIPTION
470            
471             FNA stands for Fractal Numerical Algorithm, the symmetrical encryption method
472             based on two algorithms that I developed for: 1. the
473             construction of a family of fractal curves (F) 2. a
474             encryption based on these curves.
475            
476             A precise description of this algorithm is covered by Article
477             on http://www.perl.it/documenti/articoli/2010/04/anakryptfna.html
478            
479            
480             =head1 CONSTRUCTOR METHOD
481            
482             my $krypto=Crypt::FNA->new(
483             {
484             r=> '8',
485             angle => [56,-187,215,64],
486             square => 4096,
487             background => [255,255,255],
488             foreground => [0,0,0],
489             magic => 2,
490             salted => 'true'
491             }
492             );
493            
494             my $krypto2=Crypt::FNA->new();
495            
496            
497             =head2 ATTRIBUTE r
498            
499             Shows the depth in the calculation of the curve. It 's a number greater than zero, not
500             necessarily integer. Indicated by the number of corners Ro basis of self-similar structure, the number of
501             segments forming the curve is given by Ro**r.
502            
503             Default value: 7
504            
505             =head2 ATTRIBUTE angle
506            
507             Are the angles covered by the recursion algorithm: these angles determines the basic structure
508             self-similar curve (F). Angles are expressed in sessadecimal system, with values ranging from
509             -360 And 360 (ie from 0 to 360).
510            
511             Default value: (56, -187, 215, -64)
512            
513             =head2 ATTRIBUTE square
514            
515             It 's the length of the side of a square container of the curve. Square has not only important for the
516             (If any) graphical representation, but also for encryption, because it is used to calculate the
517             length of the side of the curve (the square is proportional to ro r **)
518            
519             Default: 4096
520            
521             =head2 ATTRIBUTE background
522            
523             And 'the RGB color background PNG file containing the design curve. The notation is decimal, then with
524             values ranging from 0 to 255.
525            
526             Default value: (255,255,255)
527            
528             =head2 ATTRIBUTE foreground
529            
530             And 'the RGB color tract in the PNG file containing the design curve. The notation is decimal, then
531             with values ranging from 0 to 255.
532            
533             Default value: (0,0,0)
534            
535             =head2 ATTRIBUTE magic
536            
537             Indicates the number of vertices of the curve to be skipped during encryption and decryption: Since the algorithm, a
538             continuous function on the top, skipping some, this is still on top of all the isolated points
539             (Hence "fair").
540            
541             Default value: 3
542            
543             =head2 ATTRIBUTE salted
544            
545             The "salted" attribute, a boolean, instructs the class
546             to use a cryptographic salt, so that multiple encryption
547             the same data will, in general, different cryptogram.
548            
549             Default value: false (for backward compatibility with previous versions of FNA)
550            
551            
552             =head1 METHODS
553            
554            
555             =head2 new
556            
557             See CONSTRUCTOR METHOD
558            
559            
560             =head2 encrypt_file
561            
562             encrypt_file decrypt_file method and are the sum: make it useful by applying the mathematical
563             curves (F). This method carries out a very precise: it encrypt the input file to output file.
564             The syntax is:
565            
566            
567             $krypto->encrypt_file($name_plain_file, $name_encrypted_file)
568            
569            
570             The input file of any format will be encrypt by the curve (F).
571            
572             =head2 decrypt_file
573            
574             The methods and decrypt_file encrypt_file, are summa: make it useful by applying the mathematical
575             curves (F). This method carries out a very precise: it decrypt the input file (which is to
576             encrypt_file output method) in the output file (which is the input method encrypt_file).
577            
578             The syntax is:
579            
580            
581             $krypto->decrypt_file($name_encrypted_file, $name_decrypted_file)
582            
583            
584             The input file is read and decoded through the curve (F), the output file.
585            
586             =head2 encrypt_scalar
587            
588             The method encrypt_scalar digit strings: the result of encryption is a vector containing the cryptogram.
589             The syntax is:
590            
591            
592             my @encrypted_scalar=$krypto->encrypt_scalar($this_scalar)
593            
594            
595             See examples
596            
597             =head2 decrypt_scalar
598            
599             The method decrypt_scalar make a plain string from the encrypted array returned from encrypt_scalar method: the result of decryption is a scalar containing plain value.
600             The syntax is:
601            
602            
603             @decrypted_scalar=$krypto->decrypt_scalar(@encrypted_scalar)
604            
605            
606             =head2 mac
607            
608             The MAC method, computes the digital signature of a file (FNA work how a digest algoritm). The signature is represented by the coordinates of the last vertex of the curve {F} used.
609             The syntax is:
610            
611            
612             my $mac=$krypto->mac($name_plain_file)
613            
614            
615             The input file of any format will be encrypt by the curve (F).
616            
617            
618             =head2 make_fract
619            
620             This method is undoubtedly the most impressive and allows you to "touch" the curves that will be applied in cryptographic algorithms.
621             For the programmer can be useful in your application, show the curve, for example, a hypothetical control panel for managing passwords or
622             encrypted files in an attachment to forms sent by email and stored on the server.
623            
624             The graphic file output format is PNG (Portable Network Graphic), accessible from any browser by as many different graphics software.
625            
626             The syntax is:
627            
628            
629             $krypto->make_fract($pngfile, $zoom)
630            
631            
632             1. $pngfile is the name of the png files - without extension "PNG" is inserted automatically
633             2. $zoom the drawing scale - greater than zero. Default value: 1
634            
635             The image produced is contained in the square of side $square.
636            
637            
638             =head1 EXAMPLES
639            
640             =head2 making FNA object
641            
642            
643             my $krypto=Crypt::FNA->new(
644             {
645             r=> '8',
646             angle => [56,-187,215,64],
647             square => 4096,
648             background => [255,255,255],
649             foreground => [0,0,0],
650             magic => 2,
651             salted => 'true'
652             }
653             );
654            
655             my $krypto2=Crypt::FNA->new();
656            
657            
658             =head2 draw a fractal curve of {F}
659            
660            
661             $krypto->make_fract('fractal1',1);
662            
663            
664             =head2 file's encryption
665            
666            
667             $krypto->encrypt_file('test.txt','test.fna');
668            
669            
670             =head2 file's decryption
671            
672            
673             $krypto->decrypt_file('test.fna','test_rebuild.txt');
674            
675            
676             =head2 hyperencryption
677            
678            
679             $krypto->encrypt_file('test.txt','test2.fna');
680             $krypto2->encrypt_file('test2.fna','test3.fna');
681             $krypto2->decrypt_file('test3.fna','test2_rebuild.fna');
682             $krypto->decrypt_file('test2_rebuild.fna','test3_rebuild.txt');
683            
684            
685             =head2 scalar encryption
686            
687            
688             my @encrypted_scalar=$krypto->encrypt_scalar('test');
689             for(@encrypted_scalar) {print $_."\n"}
690            
691             =head2 scalar decryption
692            
693            
694             my $decrypted_scalar=$krypto->decrypt_scalar(@encrypted_scalar);
695             print $decrypted_scalar;
696            
697             =head2 reading error code
698            
699            
700             $krypto->make_fract("fractal3","3a"); # nome file png e zoom
701             my @errors=@{$krypto->message};
702             foreach my $errors(@errors) {
703             print "> 1-".$errors."\n"
704             }
705             @errors=@{$krypto2->message};
706             foreach my $errors(@errors) {
707             print "> 2-".$errors."\n"
708             }
709            
710            
711             =head2 error code -> message
712            
713             0 Order of the curve is not correct. Must necessarily be numeric. Ex. r=7
714             1 Order of the curve must be a number greater than 0
715             2 Length Square container is incorrect. Must necessarily be numeric
716             3 Side of a square container fractal must be a number greater than 0
717             5 Value of is not correct. Must necessarily be numeric.Default loaded
718             6 The angle must be expressed in the system sessadecimal (ex. 126.35) Default loaded
719             7 Error reading sub encrypt, package Crypt::FNA
720             8 error writing file, package Crypt::FNA sub encrypt
721             9 read error on sub decrypt myInput package Crypt::FNA
722             10 write error on sub decrypt MYOUTPUT package Crypt::FNA
723             11 error writing PNG sub draw_fract package Crypt::FNA
724             12 error background: only numeric character (RGB)
725             13 error background: only three number (RGB) from 0 to 255
726             14 error foreground: only numeric character (RGB)
727             15 error foreground: only three number (RGB) from 0 to 255
728             16 error loading GD::Simple, drawing aborted
729             18 error zoom: the value must be a number greater than zero
730             19 errors during object instantiation
731             20 error magic setting
732             21 error salted value (true or false only)
733             22 error loading Tie::File
734             23 Error reading sub mac, package Crypt::FNA"
735            
736            
737            
738             =head1 INTERNAL METHODS AND FUNCTIONS
739            
740            
741             =head2 set_starting_angle
742            
743             The first we meet is "set_starting_angle" which, as already briefly mentioned, the system converts radiant angles passed from parent script, initializing the object (new method). Besides this method returns the number of angles under the curve (F), $ ro, data necessary to calculate otherwise be lost during the population of $ self-> angle than the carrier that re-initializes initial_angle @ $ self-> angle at the end of processing
744            
745            
746             =head2 init_geometry
747            
748             Calculates the length of the side of the curve (F). This distance is used both in the processes of encryption (encrypt_file and encrypt_scalar) that reconstruction of the data ("decrypt_file"), as well as the drawing method (make_fract). The side of the curve, also as the distance traveled by the turtle in the design phase is a fundamental and structural, since they directly affect the coordinates of the vertices used by the various class methods FNA.
749            
750            
751             =head2 crypt_fract
752            
753             Is invoked by all methods (not "new") and calls the fundamental "evaluate_this_angle" as well as "evaluate_this_coords, calculating the angles and coordinates of the curve of its vertices. It 'a real ring junction in the recursive process.
754            
755            
756             =head2 make_salt
757            
758             Invoked from all encryption methods, if the "salted" attribute is true: return a cryptographic salt, long as the square of the magic number.
759            
760            
761             =head2 calc_limit
762            
763             This method optimizes memory usage by FNA, reducing minimum directions to be stored in memory. For properties of {F}, given 'n' vertices and a given order 'r' of the curve, the number of directions strictly necessary for the calculation is given by Ro = n ** r -> r = log (n) / log (Ro)
764            
765            
766             =head2 round
767            
768             rounding decimals
769            
770            
771             =head2 evaluate_this_angle
772            
773             calculates the angle of the segment k-th of the {F} curve
774            
775            
776             =head2 evaluate_this_coords
777            
778             calculates the X and Y of the vertex k-th of the {F} curve
779            
780            
781             =head2 g
782            
783             see Theory
784            
785            
786             =head2 p
787            
788             see Theory
789            
790            
791             =head1 THEORY
792            
793            
794             =head2 Definition of the set of curves {F}
795            
796             Briefly, indicating therefore:
797            
798             Ro -> number of parameters of the base (4 in the case of the Koch curve)
799             r -> the order of the curve
800             ann -> number of direction of the segments of the curve of order n
801            
802             We can establish that the number of directions (n) curve of order n is:
803            
804             ann = Ro**r
805            
806             Here now the directions of various orders in a building in a triangle:
807            
808             r=0 0
809             r=1 0, 60, -60, 0
810             r=2 0, 60, -60, 0, 60, 120, 0, 60, -60, 0, -120, -60, 0, 60, -60, 0
811            
812            
813             Reminds you of something? Note the similarity with the construction of the triangle Tartaglia:
814            
815             1
816             1 1
817             1 2 1
818             1 3 3 1
819             1 4 6 4 1
820            
821             This triangle shows the triangular arrangement of binomial coefficients, ie the development of the binomial coefficients (a + b) raised to any exponent n.
822            
823             The thing that interests us is that any number of the triangle is obtained as the sum of the two corresponding to the top line: note that we can express the properties of self-similarity of the Koch curve through a similar construction, combining the values of the base and then with those derived from the combination and so on iterating the procedure.
824            
825             In this case, an ex. Ro = 4, we have this situation:
826            
827             row for r = 0 -> 0 + 0 = 0
828             row for r = 1 -> 0 + 0 = 0 0 + 60 = 60, 0 to 60 = -60, 0 + 0 = 0
829             row for r = 2 ->
830            
831             I. 0+0=0 0+60=60 0-60=-60 0+0=0
832             II. 60+0=60 60+60=120 60-60=0 60+0=60
833             III. -60+0=-60 -60+60=0 -60-60=-120 -60+0=-60
834             IV. 0+0=0 0+60=60 0-60=-60 0+0=0
835            
836             Repeating the procedure, we obtain precisely the angles of the curve of order n.
837            
838             However, appear to identify the corners of the curve of order n is still necessary to identify all those angles with order
839             We continue to see, writing a succession of directions as the elements of a vector:
840            
841             a(0) = a(0) + a(0)
842             a(1) = a(0) + a(1) GROUP I
843             a(2) = a(0) + a(2)
844             a(3) = a(0) + a(3)
845             ------------------------------
846             a(4) = a(1) + a(0)
847             a(5) = a(1) + a(1) GROUP II
848             a(6) = a(1) + a(2)
849             a(7) = a(1) + a(3)
850             ------------------------------
851             a(8) = a(2) + a(0)
852             a(9) = a(2) + a(1) GROUP III
853             a(10)= a(2) + a(2)
854             a(11)= a(2) + a(3)
855             ------------------------------
856             a(12)= a(3) + a(0)
857             a(13)= a(3) + a(1) GROUP IV
858             a(14)= a(3) + a(2)
859             a(15)= a(3) + a(3)
860            
861            
862             Thus we have the summations to identify the different angles of segments approximating the curve ... written reports in this way, we can clearly see the properties of the two addends that provide the angle n-th:
863            
864             The first addendum is the group or the branch on which we iterate the construction.
865             The second term is the location of which we are calculating in that branch.
866            
867             The group that the k-th direction so we can indicate in the formalism of Perl:
868            
869             G(k) = int(k/ro)
870            
871             The location of the k-th direction its group is:
872            
873             P(k) = k-int(k/Ro) = k*G(k)
874            
875             Ultimately, the value of the k-th direction will be:
876            
877             a(k) = a(G(k)) + a(P(k)) (1)
878            
879             We note that this report is general, independent of the number of basic parameters of the curve. In one of Koch have a base of cardinality equal to 4 but is not necessarily so.
880             With this relationship becomes straightforward to derive the graph of the curve, being able to calculate the angles at a certain order and then implementing a system of turtle for use:
881            
882             while ($k<$Ro**$r) {
883             $a[$k] = $a[int($k/$Ro)] + $a[$k-int($k/$Ro)];
884             $K++
885             }
886            
887             Then we indicate with {F} the set of curves whose directions the segments are obtained by approximating the equation (1).
888             {F} has a Hausdorff dimension between 1 and 2 (with small variations can be calculated even those with size less than 1, as Cantor dust) and infinite cardinality as easily detected by observing the number of parameters possible parent.
889            
890             In short:
891            
892             =head2 encrypt to {F}
893            
894             Each byte is encrypted using the coordinates of the top of fractal curve, obtained starting from the next than previously estimated, jumping a further number of vertices equal to the magic number plus the value of bytes to encrypt.
895            
896             =head2 decrypt from {F}
897            
898             Follow the curve occurring fractal, from vertex to vertex, that the coordinates match those of the cryptogram. The value of the original byte is reconstructed having counted how many vertices have succeeded to get two values of equality, equality last met. The number of vertices, reduced the magic number added to the unit, represents the value of the n-th byte.
899            
900            
901            
902             =head1 AUTHOR
903            
904             Mario Rossano
905             software@netlogicalab.com
906             software@netlogica.it
907             http://www.netlogica.it
908            
909             =head1 BUGS
910            
911             Please, send me your alerts to software@netlogica.it
912            
913             =head1 SUPPORT
914            
915             Write me :) software@netlogica.it
916            
917            
918             =head1 COPYRIGHT & LICENSE
919            
920             FNA by Mario Rossano, http://www.netlogica.it
921            
922             This pod text by Mario Rossano
923            
924             Copyright (C) 2009 Mario Rossano aka Anak
925             birthday 05/08/1970; birthplace: Italy
926            
927             This program is free software; you can redistribute it and/or modify it
928             under the terms of either:
929             CC-NC-BY-SA
930             license http://creativecommons.org/licenses/by-nc-sa/2.5/it/deed.en
931             Creative Commons License: http://i.creativecommons.org/l/by-nc-sa/2.5/it/88x31.png
932            
933             FNA Fractal Numerical Algorithm for a new cryptography technology, author Mario Rossano
934             is licensed under a: http://creativecommons.org/B/by-nc-sa/2.5/it/deed.en - Creative Commons Attribution-Noncommercial-Share Alike 2.5 Italy License
935            
936             Permissions beyond the scope of this license may be available at software@netlogicalab.com