Data Encryption Standard: Difference between revisions

m
(→‎{{header|Raku}}: major revision)
m (→‎{{header|Wren}}: Minor tidy)
 
(5 intermediate revisions by 4 users not shown)
Line 14:
=={{header|C}}==
{{trans|D}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 514:
driver(keys[2], message3, len);
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>Key : 133457799BBCDFF1
Line 532:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
using System.IO;
using System.Security.Cryptography;
Line 602:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>Encoded: 0000000000000000A913F4CB0BD30F97
Line 609:
=={{header|C++}}==
{{trans|D}}
<langsyntaxhighlight lang="cpp">#include <algorithm>
#include <array>
#include <bitset>
Line 1,030:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>Key : 133457799BBCDFF1
Line 1,049:
=={{header|D}}==
{{trans|kotlin}}
<langsyntaxhighlight lang="d">import std.stdio, std.array, std.bitmanip;
import std.bitmanip;
import std.stdio;
 
immutable PC1 = [
Line 1,172 ⟶ 1,170:
immutable SHIFTS = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];
 
BitArray bitArrayOfSize(uintulong count) {
bool[] buffer = new bool[count];
return BitArray(buffer);
Line 1,179 ⟶ 1,177:
ubyte[] encrypt(const ubyte[] key, const ubyte[] message) in {
assert(key.length == 8, "Incorrect key size");
} bodydo {
BitArray[] ks = getSubKeys(key);
ubyte[] m = message.dup;
Line 1,202 ⟶ 1,200:
ubyte[] decrypt(const ubyte[] key, const ubyte[] encoded) in {
assert(key.length == 8, "Incorrect key size");
} bodydo {
BitArray[] ks = getSubKeys(key);
// reverse the subkeys
Line 1,227 ⟶ 1,225:
private BitArray[] getSubKeys(const ubyte[] key) in {
assert(key.length == 8);
} bodydo {
auto k = key.toBitArray();
 
Line 1,407 ⟶ 1,405:
[0x0E, 0x32, 0x92, 0x32, 0xEA, 0x6D, 0x0D, 0x73],
];
 
immutable ubyte[][] messages = [
[cast(ubyte)0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF],
[0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87],
[0x59, 0x6F, 0x75, 0x72, 0x20, 0x6C, 0x69, 0x70, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x6D, 0x6F, 0x6F, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x76, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x0D, 0x0A],
0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x6D,
0x6F, 0x6F, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74,
0x68, 0x61, 0x6E, 0x20, 0x76, 0x61, 0x73, 0x65,
0x6C, 0x69, 0x6E, 0x65, 0x0D, 0x0A],
];
 
assert(keys.length == messages.length);
 
Line 1,417 ⟶ 1,421:
writefln("Key : %(%02X%)", keys[i]);
writefln("Message : %(%02X%)", messages[i]);
 
ubyte[] encoded = encrypt(keys[i], messages[i]);
writefln("Encoded : %(%02X%)", encoded);
 
ubyte[] decoded = decrypt(keys[i], encoded);
writefln("Decoded : %(%02X%)", decoded);
 
writeln;
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>Key : 133457799BBCDFF1
Line 1,443 ⟶ 1,450:
=={{header|F Sharp|F#}}==
{{trans|C#}}
<langsyntaxhighlight lang="fsharp">open System
open System.Security.Cryptography
open System.IO
Line 1,501 ⟶ 1,508:
printfn "Decoded: %s" (ByteArrayToString decBytes)
 
0 // return an integer exit code</langsyntaxhighlight>
{{out}}
<pre>Encoded: 0000000000000000A913F4CB0BD30F97
Line 1,507 ⟶ 1,514:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 20-01-2019
' compile with: fbc -s console
 
Line 1,784 ⟶ 1,791:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> key 133457799BBCDFF1
Line 1,803 ⟶ 1,810:
=={{header|Go}}==
'''Library solution:'''
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,828 ⟶ 1,835:
c.Encrypt(dst, src)
fmt.Printf("%x\n", dst)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,836 ⟶ 1,843:
=={{header|Java}}==
{{trans|Kotlin}}
<langsyntaxhighlight Javalang="java">import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
 
Line 1,877 ⟶ 1,884:
printHexBytes(decBytes, "Decoded");
}
}</langsyntaxhighlight>
{{out}}
<pre>Encoded: 0000000000000000a913f4cb0bd30f97
Line 1,884 ⟶ 1,891:
=={{header|Julia}}==
===Using the MbedTLS library===
<langsyntaxhighlight lang="julia">using MbedTLS
 
const testdata = [
Line 1,907 ⟶ 1,914:
println("Decoded : $(bytes2hex(decoded))\n")
end
</langsyntaxhighlight>{{out}}
<pre>
Key : 133457799bbcdff1
Line 1,926 ⟶ 1,933:
===Base Julia only===
{{trans|Phix}}
<langsyntaxhighlight lang="julia">const PC1 = [57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
Line 2,089 ⟶ 2,096:
println("Decoded : $(bytes2hex(decoded))\n")
end
</syntaxhighlight>
</lang>
Output: same as MbedTLS library version above.
 
Line 2,095 ⟶ 2,102:
===Version 1 (using library functions)===
Presumably, one can use library functions to demonstrate DES as it would be very tedious to implement it from scratch:
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import javax.crypto.Cipher
Line 2,132 ⟶ 2,139:
val decBytes = decCipher.doFinal(encBytes)
decBytes.printHexBytes("Decoded")
}</langsyntaxhighlight>
 
{{out}}
Line 2,142 ⟶ 2,149:
===Version 2 (from scratch)===
It wasn't as tedious as I expected due to the admirably clear article linked to above:
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import java.util.BitSet
Line 2,459 ⟶ 2,466:
println()
}
}</langsyntaxhighlight>
{{out}}
<pre>Key : 133457799BBCDFF1
Line 2,477 ⟶ 2,484:
 
=={{header|Modula-2}}==
<langsyntaxhighlight lang="modula2">MODULE DataEncryptionStandard;
FROM SYSTEM IMPORT BYTE,ADR;
FROM DES IMPORT DES,Key1,Create,Destroy,EncryptECB,DecryptECB;
Line 2,530 ⟶ 2,537:
Destroy(cipher);
ReadChar
END DataEncryptionStandard.</langsyntaxhighlight>
{{out}}
<pre>plain: 8787878787878787
Line 2,543 ⟶ 2,550:
Compared to the D (and Kotlin versions), we avoided to use an array to compute left and right part when executing the rounds. We simply switched left and right part at each round. This is the main difference with these two versions.
 
<langsyntaxhighlight Nimlang="nim">import bitops, sequtils, strutils
 
 
Line 2,871 ⟶ 2,878:
let decoded = decrypt(Keys[i], encoded)
echo "Decoded: ", decoded.toHex()
echo()</langsyntaxhighlight>
 
{{out}}
Line 2,890 ⟶ 2,897:
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
<lang Perl># 20200723 added Perl programming solution
 
use strict;
use warnings;
 
use Crypt::DES;
 
my $key = pack("H*", "0E329232EA6D0D73");
my $cipher = new Crypt::DES ->new($key);
my $ciphertext = $cipher->encrypt(pack("H*", "8787878787878787"));
print "Encoded : ", unpack("H*", $ciphertext), "\n";
print "Decoded : ", unpack("H*", $cipher->decrypt($ciphertext)), "\n";
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,915 ⟶ 2,919:
easier to debug/verify, probably sidestep a few fiddly endian issues, and certainly
simplify bit-wise permutations.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Data_Encryption_Standard.exw</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">PC1</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">57</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">49</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">41</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">33</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">25</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">17</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span>
Line 3,107 ⟶ 3,111:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Decoded : %s%s\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">dectxt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">derror</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 3,127 ⟶ 3,131:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(setq
*PC1
(57 49 41 33 25 17 9
Line 3,295 ⟶ 3,299:
16
(hex
(bin (mapcar '((I) (get R I)) *IP_INV)))) ) )</langsyntaxhighlight>
{{out}}
<pre>
Line 3,310 ⟶ 3,314:
implemented like in the article linked in description. <br>
really good article btw
<langsyntaxhighlight Pythonlang="python">#!/usr/bin/python
#!/usr/bin/python
 
Line 3,555 ⟶ 3,559:
prove(k2, m2)
 
</syntaxhighlight>
</lang>
{{Out}}
Note: This is just the algorithm for single 64-bit blocks. No padding or block chipher operation mode
Line 3,570 ⟶ 3,574:
=={{header|Raku}}==
(formerly Perl 6)
Thanks to SqrtNegInf for pointing out that \r\n is a single grapheme. ([https://docs.raku.org/type/Str#routine_chomp link 1], [https://docs.raku.org/language/newline link 2])
{{trans|Phix}}
<syntaxhighlight lang="raku" perl6line># 20220222 Updated Raku programming solution
 
my \PC1 = <
Line 3,579 ⟶ 3,583:
62 54 46 38 30 22 14 6 61 53 45 37 29 21
13 5 60 52 44 36 28 20 12 4 27 19 11 3
>; # Permuted choice 1 (PC-1) - Parity Drop Table, https://w.wiki/4yKS
my \PC2 = <
Line 3,585 ⟶ 3,589:
25 7 15 6 26 19 12 1 40 51 30 36 46 54 29 39
50 44 32 47 43 48 38 55 33 52 45 41 49 35 28 31
>; # Permuted choice 2 (PC-2) - Key Compression Table, https://w.wiki/4yKR
my \IP = <
Line 3,592 ⟶ 3,596:
56 48 40 32 24 16 8 0 58 50 42 34 26 18 10 2
60 52 44 36 28 20 12 4 62 54 46 38 30 22 14 6
>; # Initial permutation (IP), https://w.wiki/4yKN
my \IP2 = <
Line 3,599 ⟶ 3,603:
35 3 43 11 51 19 59 27 34 2 42 10 50 18 58 26
33 1 41 9 49 17 57 25 32 0 40 8 48 16 56 24
>; # Final permutation (IP⁻¹), https://w.wiki/4yKP
my \S = ( <
Line 3,625 ⟶ 3,629:
13 2 8 4 6 15 11 1 10 9 3 14 5 0 12 7 1 15 13 8 10 3 7 4 12 5 6 11 0 14 9 2
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 boxesS-Boxes, each replaces a 6-bit input with a 4-bit output, w.wiki/4yG8
my \P = <
15 6 19 20 28 11 27 16 0 14 22 25 4 17 30 9
1 7 23 13 31 26 2 8 18 12 29 5 21 10 3 24
>; # Permutation (P), shuffles the bits of a 32-bit half-block, w.wiki/4yKT
# Expansion function (E), expand 32-bit half-block to 48 bits, w.wiki/4yGC
my \E = flat 31,0..4,3..8,7..12,11..16,15..20,19..24,23..28,27..31,0;
my \SHIFTS = flat 1, 1, 2 xx 6, 1, 2 xx 6, 1 ; # schedule of left shifts, w.wiki/4yKV
## Helper subs
Line 3,646 ⟶ 3,650:
# convert hexadecimals(%02X) to UTF-8
sub h2u (\h) { Blob.new( h.comb(2)».&{ :16($_) } ).decode };
 
# convert quadbits to hex
sub q2h (\q) { [~] q.comb(4)».&{ :2($_).fmt('%X') } };
# convert every two quadbits to bytes
sub q2b (\q) { q.comb(8)».&{ :2($_) } };
 
# turn a 16 digit hexadecimal str to a 64 bits list
sub h2b (\h) { flat h.comb».&{ :16($_).base(2).fmt('%04s').comb } };
# convert hexadecimals to bytes
sub h2B (\h) { [~] h.comb(2)».&{ chr "0x$_" } };
 
# s is 16 digit hexadecimal str, M is a permuation matrix/vector
sub map64(\s,\M) { (h2b s)[M] }
 
## Core subs
sub get_subkeys(Str \key --> Seq) { # return a Seq with 16 bit vectors
my \Kₚ(@C,@D) := { .rotor(.elems div 2)».Array }(map64 key, PC1); # drop parity bitsw.wiki/4yKV
my @C = Kₚ[0..27] ; my @D = Kₚ[28..55]; # perform bits rotation next
my \CD = (^16)».&{ [ |@C.=rotate(SHIFTS[$_]), |@D.=rotate(SHIFTS[$_]) ] }
# key compression rounds, https://w.wiki/4yKb
return (^16).map: -> \row { (^48).map: -> \col { CD[row][ PC2[col] ] } }
}
Line 3,675 ⟶ 3,678:
sub ƒ (List \R, Seq \Kₙ --> List) {
my @er = map { Kₙ[$_] +^ R[E[$_]] }, ^48;
 
return ( flat (^8)».&{ # Sₙ(Bₙ) loop, process @er six bits at a time
S[$_][ ([~] @er[$_*6 , $_*6+5]).parse-base(2)*16 + # 2 bits
([~] @er[$_*6+1 .. $_*6+4]).parse-base(2) ] # 4 bits
Line 3,684 ⟶ 3,687:
sub process_block(Str \message, Seq \K --> Str) { # return 8 quadbits
my \mp(@L,@R) := { .rotor(.elems div 2)».Array }(map64 (b2h message) , IP); # turn message to hex then map to bits
my @L = mp[0..31]; my @R = mp[32..63]; # then apply 16 iterations of ƒ
{ my @Lₙ = @R; my @Rₙ = @L Z+^ ƒ @R, K[$_]; @L = @Lₙ; @R = @Rₙ } for ^16;
 
return [~] (|@R, |@L)[IP2] # inverse of the initial permutation
}
sub des(Str \key, Str $msg is copy, Bool \DECODE --> Str) { # return hexdecimal
 
my \length = $msg.encode('iso-8859-1').bytes;
 
die "Message must be in multiples of 8 bytes" if ( DECODE and length % 8 );
my \K = do given get_subkeys key { DECODE ?? reverse $_ !! $_ }(get_subkeys key);
 
# CMS style padding as per RFC 1423 & RFC 5652
{ $msg ~= (my \Pad = 8 - length % 8).chr x Pad } unless DECODE;
 
my $quad = [~] ( 0, 8 … $msg.encode('iso-8859-1').bytes-8 ).map:
{ process_block substr($msg,$_,8), K }
 
DECODE ?? do { my @decrypt = q2b $quad; # quadbits to a byte code point list
@decrypt.pop xx @decrypt.tail; # remove padding
Line 3,723 ⟶ 3,725:
say h2B des "0E329232EA6D0D73", h2B("C0999FDDE378D7ED727DA00BCA5A84EE47F269A4D6438190D9D52F78F535849980A2E7453703513E"), True;
say h2B des "0E329232EA6D0D73", h2B("C0999FDDE378D7ED727DA00BCA5A84EE47F269A4D6438190D9D52F78F53584997F922CCB5B068D99"), True;
say h2u des "0E329232EA6D0D73", h2B("C040FB6A6E72D7C36D60CA9B9A35EB38D3194468AD808103C28E33AEF0B268D0E0366C160B028DDACF340003DCA8969343EBBD289DB94774"), True; </langsyntaxhighlight>
{{out}}
<pre>Encryption examples:
Line 3,743 ⟶ 3,745:
Implementation of the algorithm described in the cited article.
<br>Decryption is now supported as well
<langsyntaxhighlight lang="rexx">/* REXX for the sake of some platforms such as good old iron */
Parse Upper Arg action
Select
Line 4,032 ⟶ 4,034:
Return r
 
debug: /* Say arg(1) */ Return</langsyntaxhighlight>
{{out}}
<pre>I:\>rexx des2
Line 4,045 ⟶ 4,047:
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec
 
Line 4,083 ⟶ 4,085:
printHexBytes(decBytes, "Decoded")
 
}</langsyntaxhighlight>
{{Out}}See it running in your browser by [https://scastie.scala-lang.org/t6nGq1ebShKEA42LSIQ6Hg Scastie (JVM)].
 
=={{header|Symsyn}}==
<langsyntaxhighlight Symsynlang="symsyn">pc1 : 56
: 48
: 40
Line 5,263 ⟶ 5,265:
endif
call Wds2Data
return</langsyntaxhighlight>
A trivial solution using the des encryption instruction:
<syntaxhighlight lang="text">key : x'0e329232ea6d0d73'
data : x'8787878787878787'
 
Line 5,273 ⟶ 5,275:
$s [] | output result - 0000000000000000
 
</syntaxhighlight>
</lang>
{{out}}
<pre>0000000000000000</pre>
Line 5,279 ⟶ 5,281:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang="vbnet">Imports System.IO
Imports System.Security.Cryptography
 
Line 5,348 ⟶ 5,350:
End Sub
 
End Module</langsyntaxhighlight>
{{out}}
<pre>Encoded: 0000000000000000A913F4CB0BD30F97
Line 5,358 ⟶ 5,360:
{{libheader|Wren-math}}
The second Kotlin version.
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt, Conv
import "./math" for Boolean
 
var PC1 = [
Line 5,675 ⟶ 5,677:
System.print("Decoded : %(decoded)")
System.print()
}</langsyntaxhighlight>
 
{{out}}
9,476

edits