Data Encryption Standard: Difference between revisions
m
→{{header|Wren}}: Minor tidy
(→{{header|Raku}}: major revision) |
m (→{{header|Wren}}: Minor tidy) |
||
(5 intermediate revisions by 4 users not shown) | |||
Line 14:
=={{header|C}}==
{{trans|D}}
<
#include <stdlib.h>
#include <string.h>
Line 514:
driver(keys[2], message3, len);
return 0;
}</
{{out}}
<pre>Key : 133457799BBCDFF1
Line 532:
=={{header|C sharp|C#}}==
<
using System.IO;
using System.Security.Cryptography;
Line 602:
}
}
}</
{{out}}
<pre>Encoded: 0000000000000000A913F4CB0BD30F97
Line 609:
=={{header|C++}}==
{{trans|D}}
<
#include <array>
#include <bitset>
Line 1,030:
return 0;
}</
{{out}}
<pre>Key : 133457799BBCDFF1
Line 1,049:
=={{header|D}}==
{{trans|kotlin}}
<
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(
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");
}
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");
}
BitArray[] ks = getSubKeys(key);
// reverse the subkeys
Line 1,227 ⟶ 1,225:
private BitArray[] getSubKeys(const ubyte[] key) in {
assert(key.length == 8);
}
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],
];
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>
{{out}}
<pre>Key : 133457799BBCDFF1
Line 1,443 ⟶ 1,450:
=={{header|F Sharp|F#}}==
{{trans|C#}}
<
open System.Security.Cryptography
open System.IO
Line 1,501 ⟶ 1,508:
printfn "Decoded: %s" (ByteArrayToString decBytes)
0 // return an integer exit code</
{{out}}
<pre>Encoded: 0000000000000000A913F4CB0BD30F97
Line 1,507 ⟶ 1,514:
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
Line 1,784 ⟶ 1,791:
Print : Print "hit any key to end program"
Sleep
End</
{{out}}
<pre> key 133457799BBCDFF1
Line 1,803 ⟶ 1,810:
=={{header|Go}}==
'''Library solution:'''
<
import (
Line 1,828 ⟶ 1,835:
c.Encrypt(dst, src)
fmt.Printf("%x\n", dst)
}</
{{out}}
<pre>
Line 1,836 ⟶ 1,843:
=={{header|Java}}==
{{trans|Kotlin}}
<
import javax.crypto.spec.SecretKeySpec;
Line 1,877 ⟶ 1,884:
printHexBytes(decBytes, "Decoded");
}
}</
{{out}}
<pre>Encoded: 0000000000000000a913f4cb0bd30f97
Line 1,884 ⟶ 1,891:
=={{header|Julia}}==
===Using the MbedTLS library===
<
const testdata = [
Line 1,907 ⟶ 1,914:
println("Decoded : $(bytes2hex(decoded))\n")
end
</
<pre>
Key : 133457799bbcdff1
Line 1,926 ⟶ 1,933:
===Base Julia only===
{{trans|Phix}}
<
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>
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:
<
import javax.crypto.Cipher
Line 2,132 ⟶ 2,139:
val decBytes = decCipher.doFinal(encBytes)
decBytes.printHexBytes("Decoded")
}</
{{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:
<
import java.util.BitSet
Line 2,459 ⟶ 2,466:
println()
}
}</
{{out}}
<pre>Key : 133457799BBCDFF1
Line 2,477 ⟶ 2,484:
=={{header|Modula-2}}==
<
FROM SYSTEM IMPORT BYTE,ADR;
FROM DES IMPORT DES,Key1,Create,Destroy,EncryptECB,DecryptECB;
Line 2,530 ⟶ 2,537:
Destroy(cipher);
ReadChar
END DataEncryptionStandard.</
{{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.
<
Line 2,871 ⟶ 2,878:
let decoded = decrypt(Keys[i], encoded)
echo "Decoded: ", decoded.toHex()
echo()</
{{out}}
Line 2,890 ⟶ 2,897:
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
use warnings;
use Crypt::DES;
my $key = pack("H*", "0E329232EA6D0D73");
my $cipher =
my $ciphertext = $cipher->encrypt(pack("H*", "8787878787878787"));
print "Encoded : ", unpack("H*", $ciphertext), "\n";
print "Decoded : ", unpack("H*", $cipher->decrypt($ciphertext)), "\n";
</syntaxhighlight>
{{out}}
<pre>
Line 2,915 ⟶ 2,919:
easier to debug/verify, probably sidestep a few fiddly endian issues, and certainly
simplify bit-wise permutations.
<!--<
<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>
<!--</
{{out}}
<pre>
Line 3,127 ⟶ 3,131:
=={{header|PicoLisp}}==
<
*PC1
(57 49 41 33 25 17 9
Line 3,295 ⟶ 3,299:
16
(hex
(bin (mapcar '((I) (get R I)) *IP_INV)))) ) )</
{{out}}
<pre>
Line 3,310 ⟶ 3,314:
implemented like in the article linked in description. <br>
really good article btw
<
#!/usr/bin/python
Line 3,555 ⟶ 3,559:
prove(k2, m2)
</syntaxhighlight>
{{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"
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
> ); #
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 ; #
## 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
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
{ 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 =
# 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; </
{{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
<
Parse Upper Arg action
Select
Line 4,032 ⟶ 4,034:
Return r
debug: /* Say arg(1) */ Return</
{{out}}
<pre>I:\>rexx des2
Line 4,045 ⟶ 4,047:
=={{header|Scala}}==
<
import javax.crypto.spec.SecretKeySpec
Line 4,083 ⟶ 4,085:
printHexBytes(decBytes, "Decoded")
}</
{{Out}}See it running in your browser by [https://scastie.scala-lang.org/t6nGq1ebShKEA42LSIQ6Hg Scastie (JVM)].
=={{header|Symsyn}}==
<
: 48
: 40
Line 5,263 ⟶ 5,265:
endif
call Wds2Data
return</
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>
{{out}}
<pre>0000000000000000</pre>
Line 5,279 ⟶ 5,281:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<
Imports System.Security.Cryptography
Line 5,348 ⟶ 5,350:
End Sub
End Module</
{{out}}
<pre>Encoded: 0000000000000000A913F4CB0BD30F97
Line 5,358 ⟶ 5,360:
{{libheader|Wren-math}}
The second Kotlin version.
<
import "./math" for Boolean
var PC1 = [
Line 5,675 ⟶ 5,677:
System.print("Decoded : %(decoded)")
System.print()
}</
{{out}}
|