Jump to content

Data Encryption Standard: Difference between revisions

→‎{{header|Perl 6}}: bug fixed ; revamp the des routine
(→‎{{header|Perl 6}}: bug fixed ; revamp the des routine)
Line 2,330:
=={{header|Perl 6}}==
This is mainly a translation from the Phix entry, with an additional example on UTF-8. Regarding the many conversions among different number/string formats, small (and hopefully reusable ) helper routines are created to serve the purpose.
Update 20190323: After a bug fixed an example does behave correctly and is now in line with the results from the C, D, Kotlin and Phix entries. By the way it seems ''.comb'' handle "\r\n" inconsistently, why? [https://pastebin.com/d7dBpYkL]
{{trans|Phix}}
<lang perl6>#!/usr/bin/env perl6
 
use v6.d;
use experimental :pack;
 
my \PC1 = <
57 49 41 33 25 17 9 1 58 50 42 34 26 18
Line 2,342 ⟶ 2,343:
14 6 61 53 45 37 29 21 13 5 28 20 12 4
>; # Permuted choice 1 (PC-1) - Parity Drop Table
 
my \PC2 = <
14 17 11 24 1 5 3 28 15 6 21 10 23 19 12 4
Line 2,348 ⟶ 2,349:
51 45 33 48 44 49 39 56 34 53 46 42 50 36 29 32
>; # Permuted choice 2 (PC-2) - Key Compression Table
 
my \IP = <
58 50 42 34 26 18 10 2 60 52 44 36 28 20 12 4
Line 2,355 ⟶ 2,356:
61 53 45 37 29 21 13 5 63 55 47 39 31 23 15 7
>; # Initial permutation (IP)
 
my \IP2 = <
40 8 48 16 56 24 64 32 39 7 47 15 55 23 63 31
Line 2,362 ⟶ 2,363:
34 2 42 10 50 18 58 26 33 1 41 9 49 17 57 25
>; # Final permutation (IP⁻¹)
 
my \S = ( <
14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7 0 15 7 4 14 2 13 1 10 6 12 11 9 5 3 8
Line 2,388 ⟶ 2,389:
7 11 4 1 9 12 14 2 0 6 10 13 15 3 5 8 2 1 14 7 4 10 8 13 15 12 9 0 3 5 6 11
> ); # 8 Substitution boxes, each replaces a 6-bit input with a 4-bit output
 
my \P = <
16 7 20 21 29 12 28 17 1 15 23 26 5 18 31 10
2 8 24 14 32 27 3 9 19 13 30 6 22 11 4 25
>; # Permutation (P), shuffles the bits of a 32-bit half-block
 
# Expansion function (E), expand 32-bit half-block to 48 bits
my \E = flat 32,1..5,4..9,8..13,12..17,16..21,20..25,24..29,28..32,1;
 
my \SHIFTS = < 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1 >; # schedule of left shifts
 
## Helper subs
 
# convert iso-8859-1 to hexadecimals
sub b2h (\b) { [~] map { .encode('iso-8859-1').unpack('H*') }, b.comb };
 
# convert UTF8s to bytes
sub u2b (\u) { [~] map { .chr }, @( [~] map { .encode('utf8') }, u.comb) };
 
# convert hexadecimals to UTF-8
sub h2u (\h) { pack("H" x h.chars/2, h ~~ m:g/../).decode('utf8') };
 
# convert quadbits to hex
sub q2h (\q) { [~] map { :2($_.Str).fmt('%X') }, q ~~ m:g/..../ };
 
# convert every two quadbits to bytes
sub q2b (\q) { map { :2($_.Str) }, q ~~ m:g/. ** 8/ };
 
# trun a 16 digit hexadecimal str to a 64 bits list
sub h2bits (\h) { ([~] map { :16($_).base(2).fmt('%04s') }, h.comb).split("")[1..64] };
 
sub infix:<⥀>(\a is copy, \b) { a.append: a.shift for ^b ; a } # XOR addition
 
# convert hexadecimals to bytes
sub h2bytes (\h) { [~] map { :16($_.Str).chr }, h ~~ m:g/../ };
 
# s is 16 digit hexadecimal str, M is a permuation matrix/vector
sub map64(\s, \M) { my \b = h2bits s; map { b[$_-1] }, M; }
 
## Core subs
 
sub get_subkeys(Str \key --> Seq) { # return a Seq with 16 bit vectors
my \Kₚ = map64 key, PC1; # drop parity bits
Line 2,435 ⟶ 2,436:
return map { map { CD[$_][PC2[$^a]-1] }, ^48 }, ^16; # key compression rounds
}
 
sub ƒ (List \R is copy, Seq \Kₙ is copy --> Seq) {
my @er = map { Kₙ[$_] +^ R[E[$_]-1] }, ^48;
Line 2,444 ⟶ 2,445:
return map { @sr[$_-1] }, P;
}
 
sub process_block(Str \message, \K is copy --> Str) { # return 8 quadbits
my \mp = map64 (b2h message) , IP; # turn message to hex then map to bits
Line 2,453 ⟶ 2,454:
return [~] map { res[$_-1] }, IP2 ; # inverse of the initial permutation
}
 
sub des(Str \key, Str $msg is copy, Bool \DECODE --> Str) { # return hexdecimal
my @K; my $P\length = 8 - $msg.encode('iso-8859-1').bytes % 8; # number of pad bytes
my @K = get_subkeys key ; # 16 bit vectors, each with 48 elements
if ( DECODE and length % 8 ) { # early exit, avoid the subkeys computation
if DECODE {
die "Message must be in multiples of 8 bytes"
@K = @K.reverse; # reverse the subkeys
} else {
@K = DECODE ?? reverse get_subkeys key !! get_subkeys key
my $P = 8 - $msg.encode('iso-8859-1').bytes % 8; # number of pad bytes
$msg ~= $P.chr x $P ; # CMS style padding as per RFC 1423 & RFC 5652
}
{ my \P = 8 - length % 8; # number of pad bytes
my $quad ~= process_block substr($msg, $_..$_+7), @K for 0, 8 … +$msg.comb-8;
$msg ~= $P.chr x $P ; # CMS style padding as per RFC 1423 & RFC 5652
if} DECODEunless {DECODE;
 
my $quad ~= process_block substr($msg, $_..$_+7,8), @K for 0, 8 … +$msg.comb-8;
{ my @decrypt = q2b $quad; # quadbits to a byte list
0, 8 … $msg.encode('iso-8859-1').bytes-8;
 
{ my @decrypt = q2b $quad; # quadbits to a byte code point list
@decrypt.pop xx @decrypt.tail; # remove padding
return b2h ( [~] map { .chr } , @decrypt )
} if DECODE ;
 
return q2h $quad
}
 
say "Encryption examples: ";
say des "133457799BBCDFF1", h2bytes("0123456789ABCDEF"), False;
say des "0E329232EA6D0D73", h2bytes("8787878787878787"), False;
say des "0E329232EA6D0D73", "Your lips are smoother than vaseline", False;
say des "0E329232EA6D0D73", "Your lips are smoother than vaseline\r\n", False;
say des "0E329232EA6D0D73", u2b("BMP: こんにちは ; Astral plane: 𝒳𝒴𝒵"), False;
 
say "Decryption examples: ";
say des "133457799BBCDFF1", h2bytes("85E813540F0AB405FDF2E174492922F8"), True;
say des "0E329232EA6D0D73", h2bytes("0000000000000000A913F4CB0BD30F97"), True;
say h2bytes des "0E329232EA6D0D73", h2bytes("C0999FDDE378D7ED727DA00BCA5A84EE47F269A4D6438190D9D52F78F535849980A2E7453703513E"), True;
say h2uh2bytes des "0E329232EA6D0D73", h2bytes("C040FB6A6E72D7C36D60CA9B9A35EB38D3194468AD808103C28E33AEF0B268D0E0366C160B028DDACF340003DCA8969343EBBD289DB94774C0999FDDE378D7ED727DA00BCA5A84EE47F269A4D6438190D9D52F78F53584997F922CCB5B068D99"), True;
say h2u des "0E329232EA6D0D73", h2bytes("C040FB6A6E72D7C36D60CA9B9A35EB38D3194468AD808103C28E33AEF0B268D0E0366C160B028DDACF340003DCA8969343EBBD289DB94774"), True;</lang>
</lang>
{{out}}
<pre>Encryption examples:
Line 2,489 ⟶ 2,495:
0000000000000000A913F4CB0BD30F97
C0999FDDE378D7ED727DA00BCA5A84EE47F269A4D6438190D9D52F78F535849980A2E7453703513E
C0999FDDE378D7ED727DA00BCA5A84EE47F269A4D6438190D9D52F78F53584997F922CCB5B068D99
C040FB6A6E72D7C36D60CA9B9A35EB38D3194468AD808103C28E33AEF0B268D0E0366C160B028DDACF340003DCA8969343EBBD289DB94774
Decryption examples:
Line 2,494 ⟶ 2,501:
8787878787878787
Your lips are smoother than vaseline
Your lips are smoother than vaseline
 
BMP: こんにちは ; Astral plane: 𝒳𝒴𝒵</pre>
 
350

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.