RSA code: Difference between revisions

11,329 bytes added ,  4 months ago
m
m (Undo revision 332577 by IterableTrucks (talk))
m (→‎{{header|Wren}}: Minor tidy)
 
(12 intermediate revisions by 10 users not shown)
Line 21:
: <math>d\times e \equiv 1 \mod (p-1)\times(q-1)</math>
 
The security of the code is based on the secrecy of the Private Key (decryption exponent) “<math>d</math>” and the difficulty in factoring “<math>n</math>”. Research into RSA facilitated advances in factoring and a number of [http://www.rsa.com/rsalabs/node.asp?id=2092 factoring challenges]. Keys of 768829 bits have been successfully factored., While factoring of keys of 1024 bits has not been demonstrated,and NIST expected them to be factorable by 2010 and now recommends 2048 bit keys going forward (see [[wp:Key_size#Asymmetric_algorithm_key_lengths|Asymmetric algorithm key lengths]] or [http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57-Part1-revised2_Mar08-2007.pdf NIST 800-57 Pt 1 Revised Table 4: Recommended algorithms and minimum key sizes]).
 
'''Summary of the task requirements:'''
Line 37:
 
{{alertbox|#ffff70|'''<big>Warning</big>'''<br/>Rosetta Code is '''not''' a place you should rely on for examples of code in critical roles, including security.<br/>Cryptographic routines should be validated before being used.<br/>For a discussion of limitations and please refer to [[Talk:RSA_code#Difference_from_practical_cryptographical_version]].}}
 
=={{header|11l}}==
{{trans|D}}
 
<syntaxhighlight lang="11l">V n = BigInt(‘9516311845790656153499716760847001433441357’)
V e = BigInt(65537)
V d = BigInt(‘5617843187844953170308463622230283376298685’)
 
V txt = ‘Rosetta Code’
 
print(‘Plain text: ’txt)
 
V txtN = txt.reduce(BigInt(0), (a, b) -> a * 256 + b.code)
print(‘Plain text as a number: ’txtN)
 
V enc = pow(txtN, e, n)
print(‘Encoded: ’enc)
 
V dec = pow(enc, d, n)
print(‘Decoded: ’dec)
 
V decTxt = ‘’
L dec != 0
decTxt ‘’= Char(code' dec % 256)
dec I/= 256
 
print(‘Decoded number as text: ’reversed(decTxt))</syntaxhighlight>
 
{{out}}
<pre>
Plain text: Rosetta Code
Plain text as a number: 25512506514985639724585018469
Encoded: 916709442744356653386978770799029131264344
Decoded: 25512506514985639724585018469
Decoded number as text: Rosetta Code
</pre>
 
=={{header|Ada}}==
The code below uses a thik and a thin binding of gmp.
 
<langsyntaxhighlight lang="ada">
WITH GMP, GMP.Integers, Ada.Text_IO, GMP.Integers.Aliased_Internal_Value, Interfaces.C;
USE GMP, Gmp.Integers, Ada.Text_IO, Interfaces.C;
Line 80 ⟶ 116:
END;
END Main;
</syntaxhighlight>
</lang>
 
{{out}}
Line 93 ⟶ 129:
The code below uses Algol 68 Genie which provides arbitrary precision arithmetic for LONG LONG modes.
 
<langsyntaxhighlight lang="algol68">
COMMENT
First cut. Doesn't yet do blocking and deblocking. Also, as
Line 167 ⟶ 203:
print (number to string (mod power (ciphertext, d, n)))
END
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 175 ⟶ 211:
=={{header|C}}==
{{libheader|GMP}}
<syntaxhighlight lang="c">
<lang C>
#include <stdio.h>
#include <stdlib.h>
Line 210 ⟶ 246:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 222 ⟶ 258:
{{libheader|System.Numerics}}
 
<langsyntaxhighlight lang="csharp">using System;
using System.Numerics;
using System.Text;
Line 249 ⟶ 285:
Console.WriteLine("As ASCII: " + decoded);
}
}</langsyntaxhighlight>
 
{{out}}
Line 261 ⟶ 297:
The string is encoded as follows: each character is converted into 2 digits based on ASCII value (subtracting 32, so that SPACE=00, and so on.) To decode we simply read every 2 digits from the given integer in order, adding 32 and converting back into characters.
 
<langsyntaxhighlight lang="lisp">(defparameter *n* 9516311845790656153499716760847001433441357)
(defparameter *e* 65537)
(defparameter *d* 5617843187844953170308463622230283376298685)
Line 293 ⟶ 329:
(defun decode-rsa (message)
(decode-string (mod-exp message *d* *n* 1)))
</syntaxhighlight>
</lang>
Interpreter output (the star * represents the interpreter prompt):
<pre>
Line 310 ⟶ 346:
This used the D module of the Modular Exponentiation Task.
{{trans|Go}}
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.bigint, std.algorithm, std.string, std.range,
modular_exponentiation;
Line 344 ⟶ 380:
decTxt ~= (dec & 0xff).toInt;
writeln("Decoded number as text: ", decTxt.retro);
}</langsyntaxhighlight>
{{out}}
<pre>Plain text: Rosetta Code
Line 356 ⟶ 392:
{{Trans|Go}}
Thanks for Rudy Velthuis, BigIntegers library
<syntaxhighlight lang="delphi">
<lang Delphi>
program RSA_code;
 
Line 501 ⟶ 537:
writeln('Decoded: ', RSA.Decode(Encoded));
Readln;
end.</langsyntaxhighlight>
{{out}}
<pre>Plain text: Rosetta Code
Encoded: 916709442744356653386978770799029131264344
Decoded: Rosetta Code</pre>
=={{header|Erlang}}==
Solution split into 2 modules, the mod module does the modulo aritmetic as per separate Rosetta Code entry.
<syntaxhighlight lang="erlang">
%%% @author Tony Wallace <tony@tony.gen.nz>
%%% @doc
%%% For details of the algorithms used see
%%% https://en.wikipedia.org/wiki/Modular_exponentiation
%%% @end
%%% Created : 21 Jul 2021 by Tony Wallace <tony@resurrection>
 
-module mod.
-export [mod_mult/3,mod_exp/3,binary_exp/2,test/0].
 
mod_mult(I1,I2,Mod) when
I1 > Mod,
is_integer(I1), is_integer(I2), is_integer(Mod) ->
mod_mult(I1 rem Mod,I2,Mod);
mod_mult(I1,I2,Mod) when
I2 > Mod,
is_integer(I1), is_integer(I2), is_integer(Mod) ->
mod_mult(I1,I2 rem Mod,Mod);
mod_mult(I1,I2,Mod) when
is_integer(I1), is_integer(I2), is_integer(Mod) ->
(I1 * I2) rem Mod.
 
mod_exp(Base,Exp,Mod) when
is_integer(Base),
is_integer(Exp),
is_integer(Mod),
Base > 0,
Exp > 0,
Mod > 0 ->
binary_exp_mod(Base,Exp,Mod);
mod_exp(_,0,_) -> 1.
 
 
binary_exp(Base,Exponent) when
is_integer(Base),
is_integer(Exponent),
Base > 0,
Exponent > 0 ->
binary_exp(Base,Exponent,1);
binary_exp(_,0) ->
1.
 
binary_exp(_,0,Result) ->
Result;
binary_exp(Base,Exponent,Acc) ->
binary_exp(Base*Base,Exponent bsr 1,Acc * exp_factor(Base,Exponent)).
 
 
binary_exp_mod(Base,Exponent,Mod) ->
binary_exp_mod(Base rem Mod,Exponent,Mod,1).
binary_exp_mod(_,0,_,Result) ->
Result;
binary_exp_mod(Base,Exponent,Mod,Acc) ->
binary_exp_mod((Base*Base) rem Mod,
Exponent bsr 1,Mod,(Acc * exp_factor(Base,Exponent))rem Mod).
 
exp_factor(_,0) ->
1;
exp_factor(Base,1) ->
Base;
exp_factor(Base,Exponent) ->
exp_factor(Base,Exponent band 1).
 
test() ->
445 = mod_exp(4,13,497),
%% Rosetta code example:
R = 1527229998585248450016808958343740453059 =
mod_exp(2988348162058574136915891421498819466320163312926952423791023078876139,
2351399303373464486466122544523690094744975233415544072992656881240319,
binary_exp(10,40)),
R.
 
%%%-------------------------------------------------------------------
%%% @author Tony Wallace <tony@tony.gen.nz>
%%% @doc
%%% Blocking not implemented. Runtime exception if message too long
%%% Not a practical issue as RSA usually limited to symmetric key exchange
%%% However as a key exchange tool no advantage in compressing plaintext
%%% so that is not done either.
%%% @end
%%% Created : 24 Jul 2021 by Tony Wallace <tony@resurrection>
%%%-------------------------------------------------------------------
 
-module rsa.
-export([key_gen/2,encrypt/2,decrypt/2,test/0]).
-type key() :: {integer(),integer()}.
key_gen({N,D},E) ->
{{E,N},{D,N}}.
-spec encrypt(key(),integer()) -> integer().
encrypt({E,N},MessageInt)
when MessageInt < N ->
mod:mod_exp(MessageInt,E,N).
-spec decrypt(key(),integer()) -> integer().
decrypt({D,N},Message) ->
mod:mod_exp(Message,D,N).
test() ->
PlainText=10722935,
N = 9516311845790656153499716760847001433441357,
E = 65537,
D = 5617843187844953170308463622230283376298685,
{PublicKey,PrivateKey} = key_gen({N,D},E),
PlainText =:= decrypt(PrivateKey,
encrypt(PublicKey,PlainText)).
 
</syntaxhighlight>
Running test:
8> rsa:test().
rsa:test().
true
9>
 
=={{header|F Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
//Nigel Galloway February 12th., 2018
let RSA n g l = bigint.ModPow(l,n,g)
Line 517 ⟶ 667:
let m_out = Array.collect(fun n->Array.unfold(fun n->if n>0I then Some(byte(int (n%256I)),n/256I) else None) n|>Array.rev) g|>System.Text.Encoding.ASCII.GetString
printfn "'The magic words are SQUEAMISH OSSIFRAGE' as numbers -> %A\nEncrypted -> %A\nDecrypted -> %A\nAs text -> %A" m_in n g m_out
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 528 ⟶ 678:
=={{header|FreeBASIC}}==
{{trans|C}}
<langsyntaxhighlight lang="freebasic">' version 17-01-2017
' compile with: fbc -s console
 
Line 571 ⟶ 721:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> Encoded: 916709442744356653386978770799029131264344
Line 580 ⟶ 730:
Note: see the [https://golang.org/pkg/crypto/rsa/ crypto/rsa] package
included with Go for a full implementation.
<langsyntaxhighlight lang="go">package main
 
import (
Line 627 ⟶ 777:
}
fmt.Println("Decoded number as text:", string(db[dx:]))
}</langsyntaxhighlight>
Output:
<pre>
Line 638 ⟶ 788:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">module RSAMaker
where
import Data.Char ( chr )
Line 683 ⟶ 833:
decrypted = decode $ rsa_decode d n rsa_encoded
putStrLn ("Encrypted: " ++ encrypted )
putStrLn ("And now decrypted: " ++ decrypted )</langsyntaxhighlight>
{{out}}
<pre>Enter a test text!
Line 694 ⟶ 844:
Please read talk pages.
 
<langsyntaxhighlight Iconlang="icon">procedure main() # rsa demonstration
n := 9516311845790656153499716760847001433441357
Line 758 ⟶ 908:
every (m := 0) := !M + b * m
return m
end</langsyntaxhighlight>
 
Output:
Line 798 ⟶ 948:
Note, for an implementation with blocking (and a much smaller key) see [http://rosettacode.org/mw/index.php?title=RSA_code&oldid=103802]
 
<langsyntaxhighlight lang="j"> N=: 9516311845790656153499716760847001433441357x
E=: 65537x
D=: 5617843187844953170308463622230283376298685x
Line 813 ⟶ 963:
25512506514985639724585018469
] final=: a. {~ 256x #.inv dec
Rosetta Code</langsyntaxhighlight>
 
Note: as indicated at http://www.jsoftware.com/help/dictionary/special.htm, <code>N&|@^</code> does not bother with creating the exponential intermediate result.
Line 819 ⟶ 969:
=={{header|Java}}==
 
<langsyntaxhighlight lang="java">
public static void main(String[] args) {
/*
Line 847 ⟶ 997:
System.out.println("As text: " + decText);
}
</syntaxhighlight>
</lang>
===Alternative solution - convert to byte array then to BigInteger: ===
<langsyntaxhighlight lang="java">
import java.math.BigInteger;
import java.util.Random;
Line 886 ⟶ 1,036:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>Message: 32745724963520459128167607565116331713761641910444445962992228853365120918629
Line 898 ⟶ 1,048:
Decrypted message(number form): 32745724963520459128167607565116331713761641910444445962992228853365120918629
Decrypted message(string): Hello World! - From Rosetta Code</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]] after correcting for a bug in the decode-to-text algorithm''' as of 2023-02-07
 
'''Works with gojq, the Go implementation of jq, and with fq'''
 
The following assumes unbounded-precision integer arithmetic.
<syntaxhighlight lang=jq>
# If $j is 0, then an error condition is raised;
# otherwise, assuming infinite-precision integer arithmetic,
# if the input and $j are integers, then the result will be an integer.
def idivide($j): (. - (. % $j)) / $j ;
 
# shift left
def left8: 256 * .;
 
# shift right
def right8: idivide(256);
 
def modPow($b; $e; $m):
if ($m == 1) then 0
else {b: ($b % $m), $e, r: 1}
| until( .e <= 0 or .return;
if .b == 0 then .return = 0
else if .e % 2 == 1 then .r = (.r * .b) % $m else . end
| .e |= idivide(2)
| .b = (.b * .b) % $m
end)
| if .return then .return else .r end
end;
 
# Convert the input integer to a stream of 8-bit integers, most significant first
def bytes:
def stream:
recurse(if . >= 256 then ./256|floor else empty end) | . % 256 ;
[stream] | reverse ;
 
# convert ASCII plain text to a number
def ptn:
reduce explode[] as $b (0; left8 + $b);
 
def n: 9516311845790656153499716760847001433441357;
def e: 65537;
def d: 5617843187844953170308463622230283376298685;
 
# encode a single number
def etn: . as $ptn | modPow($ptn; e; n);
 
# decode a single number
def dtn: . as $etn | modPow($etn; d; n);
 
def decode:
[recurse(right8 | select(.>0)) % 256]
| reverse
| implode;
 
def task($pt):
($pt|ptn) as $ptn
| if ($ptn >= n) then "Plain text message too long" | error else . end
| ($ptn|etn) as $etn
| ($etn|dtn) as $dtn
| ($ptn|decode) as $text
| "Plain text: : \($pt)",
"Plain text as a number : \($ptn)",
"Encoded : \($etn)",
"Decoded : \($dtn)",
"Decoded number as text : \($text)"
;
 
task("Rosetta Code"),
"",
task("Hello, Rosetta!!!!")
</syntaxhighlight>
'''Invocation''': gojq -nr -f rsa-code.jq
{{output}}
<pre>
Plain text: : Rosetta Code
Plain text as a number : 25512506514985639724585018469
Encoded : 916709442744356653386978770799029131264344
Decoded : 25512506514985639724585018469
Decoded number as text : Rosetta Code
 
Plain text: : Hello, Rosetta!!!!
Plain text as a number : 6306597225792201544376884997106189304144161
Encoded : 3763881655974029977658577646869029457590896
Decoded : 6306597225792201544376884997106189304144161
Decoded number as text : Hello, Rosetta!!!!
</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">function rsaencode(clearmsg::AbstractString, nmod::Integer, expub::Integer)
bytes = parse(BigInt, "0x" * bytes2hex(collect(UInt8, clearmsg)))
return powermod(bytes, expub, nmod)
Line 919 ⟶ 1,157:
encoded = rsaencode(msg, nmod, expub)
decoded = rsadecode(encoded, nmod, dsecr)
println("\n# $msg\n -> ENCODED: $encoded\n -> DECODED: $decoded")</langsyntaxhighlight>
 
{{out}}
Line 927 ⟶ 1,165:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.4-3
 
import java.math.BigInteger
Line 954 ⟶ 1,192:
val decText = dec.toByteArray().toString(c)
println("As text : $decText")
}</langsyntaxhighlight>
 
{{out}}
Line 965 ⟶ 1,203:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Does not support blocking.
<syntaxhighlight lang="text">toNumPlTxt[s_] := FromDigits[ToCharacterCode[s], 256];
fromNumPlTxt[plTxt_] := FromCharacterCode[IntegerDigits[plTxt, 256]];
enc::longmess = "Message '``' is too long for n = ``.";
Line 986 ⟶ 1,224:
Print["Numeric plaintext: " <> IntegerString[toNumPlTxt[text]]];
Print["Encoded: " <> IntegerString[en]];
Print["Decoded: '" <> de <> "'"];</langsyntaxhighlight>
{{out}}
<pre>Text: 'The cake is a lie!'
Line 997 ⟶ 1,235:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import strutils, streams, strformat
# nimble install stint
import stint
Line 1,013 ⟶ 1,251:
break
result+=1
func powmodHexStr(s: string, key, divisor: UInt256): string{.inline.} =
toHex(powmod(UInt256.fromHex(s), key, divisor))
proc translate(hexString: string, key, divisor: UInt256,
encrypt = true): string =
var
strm: StringStream= newStringStream(hexString)
chunk, residue, tempChunk: string
zeros: int
let chunkSize = len(toHex(divisor))
if encrypt:
strm = newStringStream(hexString)
else:
strm = newStringStream(hexString[2..^1])
zeros = fromHex[int](hexString[0..1])
while true:
tempChunk = strm.peekStr(chunkSize-int(encrypt)*3)
if len(tempChunkchunk) ==> 0:
if encryptlen(tempChunk) == 0:
zerosif = pcount(chunk, '0')encrypt:
result result&=powmodHexStr(pcount(chunk, zeros'0').toHex(2)&result&residuealign(chunk,
chunkSize-3, '0'), key, divisor)
else:
else:
result&=align(residue, len(residue)+zeros, '0')
tempChunk = align(powmodHexStr(chunk, key, divisor), chunkSize-1, '0')
break
residue = tempChunk[2..^1].strip(trailing = false, chars = {'0'})
result&=align(residue, fromHex[int](tempChunk[0..1])+len(residue), '0')
break
result&=align(powmodHexStr(chunk, key, divisor), chunkSize-3+int(
encrypt)*3, '0')
discard strm.readStr(chunkSize-int(encrypt)*3)
chunk = tempChunk
if len(residue) > 0:
result&=align(residue, chunkSize-1+int(encrypt), '0')
discard strm.readStr(chunkSize-int(encrypt))
residue = toHex(powmod(UInt256.fromHex(chunk), key, divisor))
strm.close()
for message in messages:
Line 1,048 ⟶ 1,284:
var deciphertext = translate(ciphertext, d, n, false)
echo(&"deciphered numerical plaintext in hex is:\n{deciphertext}")
echo(&"deciphered plaintext is:\n{parseHexStr(deciphertext)}\n\n")</langsyntaxhighlight>
{{out}}
<pre>plaintext:
Line 1,055 ⟶ 1,291:
50504150
ciphertext is:
6c55b71c718b8921555eaa9754b7bfd7018b
006c55b71c718b8921555eaa9754b7bfd7018b
deciphered numerical plaintext in hex is:
50504150
Line 1,068 ⟶ 1,304:
49206861766520612070656E2C204920686176652061206170706C650A556821204170706C652D70656E21
ciphertext is:
4614caba02ac33654130c10485dcceeec4a2443f4bffb46e389c2705d4ebd7ac7185a206ae0294575f283841baad236fa90d5c5536b
000095018316e01ab0c681c61ed03c12e49fd34363bf2498b4d6d5a396cf3ad7a86018609448e92cb927a9444b1225f085f68cbaf103d5
deciphered numerical plaintext in hex is:
49206861766520612070656e2c204920686176652061206170706c650a556821204170706c652d70656e21
Line 1,082 ⟶ 1,318:
49206861766520612070656E2C204920686176652070696E656170706C650A5568212050696E656170706C652D70656E21
ciphertext is:
4614caba02ac33654130c10485dcceeec4a21c96dd7a5048e412a16c65e274609964ffb14231b9d6a70a59380d4bbaef3c40e88afa3d
000095018316e01ab0c681c61ed03c12e49fd35da93d762b6d4d80a227fa6394136bb95ed725f8c4b378297efb4c417da533f488b3ce8e
deciphered numerical plaintext in hex is:
49206861766520612070656e2c204920686176652070696e656170706c650a5568212050696e656170706c652d70656e21
Line 1,098 ⟶ 1,334:
4170706C652D70656E2C2070696E656170706C652D70656E0A5568212050656E2D70696E656170706C652D6170706C652D70656E0A50656E2D70696E656170706C652D6170706C652D70656E0A44616E63652074696D6521
ciphertext is:
5d733e3979b0b43207dace453c3ec65baaff54571a3127be4ccd120dff94fb2e1b9258d6067cee2669e868ee4390c5e16f61016a171f6585ad4cd58ca3335bc9faa96da943bfedad0dd0ac7cbc83a256bf9f6f65d755865aed232e1e0a467512a6744f3f470ee283c8b4e2e5
0049c1a7c0844fbc0d3d6915539cdde8794b6f58ae75cf4e4f452a5004147788b71a96fc5e6cb5c08bd9b78b3630615a877740735ec9bb3d7a45a45b43b8ae2bffca38dd4e4bd8361f60961dc9acd9a362d5c0cf2f158d4948f90a1
deciphered numerical plaintext in hex is:
4170706c652d70656e2c2070696e656170706c652d70656e0a5568212050656e2d70696e656170706c652d6170706c652d70656e0a50656e2d70696e656170706c652d6170706c652d70656e0a44616e63652074696d6521
Line 1,113 ⟶ 1,349:
0700
ciphertext is:
2177c0b1865ac16e47807e4f4d82e421bbdf
0156badfbcc0e1903e0e1869d16b6ef901f885
deciphered numerical plaintext in hex is:
0700
deciphered plaintext is:
(shell terminal cannot display "\a\0")
 
 
</pre>
Line 1,124 ⟶ 1,359:
=={{header|PARI/GP}}==
 
<langsyntaxhighlight lang="parigp">stigid(V,b)=subst(Pol(V),'x,b); \\ inverse function digits(...)
 
n = 9516311845790656153499716760847001433441357;
Line 1,135 ⟶ 1,370:
encoded = lift(Mod(inttext, n) ^ e) \\ encrypted message
decoded = lift(Mod(encoded, n) ^ d) \\ decrypted message
message = Strchr(digits(decoded, 256)) \\ readable message</langsyntaxhighlight>
 
Output:<pre>
Line 1,148 ⟶ 1,383:
 
As a check: it's easy to crack this weak encrypted message without knowing secret key 'd'
<langsyntaxhighlight lang="parigp">f = factor(n); \\ factorize public key 'n'
 
crack = Strchr(digits(lift(Mod(encoded,n) ^ lift(Mod(1,(f[1,1]-1)*(f[2,1]-1)) / e)),256))</langsyntaxhighlight>
 
Output:<pre>crack: "Rosetta Code"</pre>
Line 1,156 ⟶ 1,391:
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use bigint;
 
$n = 9516311845790656153499716760847001433441357;
Line 1,218 ⟶ 1,453:
After exponentiation with SECRET exponent we get: $numeric_message2
This turns into the string $secret_message2
EOT</langsyntaxhighlight>
{{out}}
<pre>Secret message is ROSETTA CODE
Line 1,231 ⟶ 1,466:
{{libheader|Phix/mpfr}}
{{trans|C}}
<!--<langsyntaxhighlight Phixlang="phix">(notonline)-->
<span style="color: #008080;">includewithout</span> <span style="color: #000000008080;">builtinsjavascript_semantics</span><span style="color: #0000FF;">/</span><span style="color: #7060A8;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #7060A8004080;">mpz</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"9516311845790656153499716760847001433441357"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"65537"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"5617843187844953170308463622230283376298685"</span><span style="color: #0000FF;">),</span>
Line 1,245 ⟶ 1,481:
<span style="color: #000000;">mpz_import</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plaintext</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">plaintext</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #0000007060A8;">mpz_cmp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">mpz_powm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ct</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pt</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">);</span>
Line 1,261 ⟶ 1,497:
<span style="color: #0000FF;">{</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ct</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_free</span><span style="color: #0000FF;">({</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ct</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">})</span>
<!--</langsyntaxhighlight>-->
<small>(mpz_import() and mpz_export() are not supported under pwa/p2js)</small>
{{out}}
<pre>
Line 1,271 ⟶ 1,508:
=={{header|PicoLisp}}==
PicoLisp comes with an RSA library:
<langsyntaxhighlight PicoLisplang="picolisp">### This is a copy of "lib/rsa.l" ###
 
# Generate long random number
Line 1,386 ⟶ 1,623:
# Decrypt
: (pack (decrypt Keys CryptText))
-> "The quick brown fox jumped over the lazy dog's back"</langsyntaxhighlight>
 
=={{header|PowerShell}}==
{{trans|C#}}
<syntaxhighlight lang="powershell">
<lang PowerShell>
$n = [BigInt]::Parse("9516311845790656153499716760847001433441357")
$e = [BigInt]::new(65537)
Line 1,404 ⟶ 1,641:
$decoded = [Text.ASCIIEncoding]::ASCII.GetString($dc.ToByteArray())
"As ASCII: $decoded"
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,415 ⟶ 1,652:
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">import binascii
 
n = 9516311845790656153499716760847001433441357 # p*q = modulus
Line 1,441 ⟶ 1,678:
print('message ', binascii.unhexlify(hex(decrypted_text)[2:]).decode()) # [2:] slicing, to strip the 0x part
 
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 1,460 ⟶ 1,697:
Cutting messages into blocks has not been done.
 
<langsyntaxhighlight lang="racket">#lang racket
(require math/number-theory)
(define-logger rsa)
Line 1,631 ⟶ 1,868:
EOS
plain-A-to-B signed-A-to-B unsigned-A-to-B crypt-signed-A-to-B decrypt-signed-A-to-B
decrypt-verified-B A-pvt-keys B-pvt-keys))</langsyntaxhighlight>
 
{{out}}
Line 1,691 ⟶ 1,928:
=={{header|Raku}}==
(formerly Perl 6)
 
{{Works with|rakudo|2015-11-04}}
No blocking here. Algorithm doesn't really work if either red or black text begins with 'A'.
<syntaxhighlight lang="raku" line>class RSA-message {
<lang perl6>constant $n = 9516311845790656153499716760847001433441357;
has ($.n, $.e, $.d); # the 3 elements that define an RSA key
constant $e = 65537;
 
constant $d = 5617843187844953170308463622230283376298685;
my @alphabet = |('A' .. 'Z'), ' ';
my $secret-message = "ROSETTA CODE";
package Message {
my @alphabet = slip('A' .. 'Z'), ' ';
my $rad = +@alphabet;
my %code = @alphabet Z=> 0 .. *;
subset Text of Str where /^^ @alphabet+ $$/;
 
our sub encode(Text $t) {
method encode(Text $t) {
[+] %code{$t.flip.comb} Z* (1, $rad, $rad*$rad ... *);
[+] %code{$t.flip.comb} Z× (1, $rad, $rad×$rad … *);
}
 
our sub decode(Int $n is copy) {
method decode(Int $n is copy) {
@alphabet[
gather loop { @alphabet[
gather loop {
take $n % $rad;
last if take $n <% $rad;
last if $n div=< $rad;
$n div= $rad;
}
}
].join.flip;
].join.flip;
}
}
 
constant $n = 9516311845790656153499716760847001433441357;
use Test;
constant $e = 65537;
plan 1;
constant $d = 5617843187844953170308463622230283376298685;
 
say "Secret message is $secret-message";
my $fmt = "%48s %s\n";
say "Secret message in integer form is $_" given
 
my $numeric-message = Message::encode $secret-message;
my $message = 'ROSETTA CODE';
say "After exponentiation with public exponent we get: $_" given
printf $fmt, 'Secret message is', $message;
 
my $rsa = RSA-message.new: n => $n, e => $e, d => $d;
printf $fmt, 'Secret message in integer form is',
my $numeric-message = $rsa.encode: $message;
 
printf $fmt, 'After exponentiation with public exponent we get',
my $numeric-cipher = expmod $numeric-message, $e, $n;
 
say "This turns into the string $_" given
printf $fmt, 'This turns into the string',
my $text-cipher = Message::decode $numeric-cipher;
my $text-cipher = $rsa.decode: $numeric-cipher;
 
say "If we re-encode it in integer form we get $_" given
printf $fmt, 'If we re-encode it in integer form we get',
my $numeric-cipher2 = Message::encode $text-cipher;
my $numeric-cipher2 = $rsa.encode: $text-cipher;
say "After exponentiation with SECRET exponent we get: $_" given
 
printf $fmt, 'After exponentiation with SECRET exponent we get',
my $numeric-message2 = expmod $numeric-cipher2, $d, $n;
 
say "This turns into the string $_" given
printf $fmt, 'This turns into the string',
my $secret-message2 = Message::decode $numeric-message2;
my $message2 = $rsa.decode: $numeric-message2;
</syntaxhighlight>
is $secret-message, $secret-message2, "the message has been correctly decrypted";</lang>
{{out}}
<pre> Secret message is ROSETTA CODE
<pre>1..1
Secret message isin ROSETTAinteger form is CODE97525102075211938
After exponentiation with public exponent we get 8326171774113983822045243488956318758396426
Secret message in integer form is 97525102075211938
This turns into the string ZULYDCEZOWTFXFRRNLIMGNUPHVCJSX
After exponentiation with public exponent we get: 8326171774113983822045243488956318758396426
If we re-encode it in integer form we get 8326171774113983822045243488956318758396426
This turns into the string ZULYDCEZOWTFXFRRNLIMGNUPHVCJSX
After exponentiation with SECRET exponent we get 97525102075211938
If we re-encode it in integer form we get 8326171774113983822045243488956318758396426
This turns into the string ROSETTA CODE</pre>
After exponentiation with SECRET exponent we get: 97525102075211938
This turns into the string ROSETTA CODE
ok 1 - the message has been correctly decrypted</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">
#!/usr/bin/ruby
 
Line 1,805 ⟶ 2,047:
final = blocks_to_text(decoded)
print "Decrypted Message: "; puts final
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,816 ⟶ 2,058:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">
extern crate num;
 
Line 1,871 ⟶ 2,113:
}
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,883 ⟶ 2,125:
=={{header|Scala}}==
The code below demonstrates RSA encryption and decryption in Scala. Text to integer encryption using ASCII code.
<syntaxhighlight lang="scala">
<lang Scala>
object RSA_saket{
val d = BigInt("5617843187844953170308463622230283376298685")
Line 1,916 ⟶ 2,158:
}
}
</syntaxhighlight>
</lang>
{{out}}
 
Line 1,929 ⟶ 2,171:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "bigint.s7i";
include "bytedata.s7i";
Line 1,958 ⟶ 2,200:
writeln("Decoded number as text: " <& decodedText);
end if;
end func;</langsyntaxhighlight>
 
{{out}}
Line 1,971 ⟶ 2,213:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">const n = 9516311845790656153499716760847001433441357
const e = 65537
const d = 5617843187844953170308463622230283376298685
Line 2,015 ⟶ 2,257:
 
var secret_message2 = Message::decode(numeric_message2)
say "This turns into the string #{secret_message2}"</langsyntaxhighlight>
{{out}}
<pre>
Line 2,029 ⟶ 2,271:
=={{header|Tcl}}==
This code is careful to avoid the assumption that the input string is in a single-byte encoding, instead forcing the encryption to be performed on the UTF-8 form of the text. <!-- NB: Doesn't print the intermediate encoded value; see talk page for discussion why. -->
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# This is a straight-forward square-and-multiply implementation that relies on
Line 2,076 ⟶ 2,318:
set dec [rsa_decrypt $enc $privateKey]
puts "$input -> $enc -> $dec"
}</langsyntaxhighlight>
Output:
<pre>
Line 2,086 ⟶ 2,328:
{{trans|C#}}
{{libheader|System.Numerics}}
<langsyntaxhighlight lang="vbnet">Imports System
Imports System.Numerics
Imports System.Text
Line 2,106 ⟶ 2,348:
Console.WriteLine("As ASCII: " & decoded)
End Sub
End Module</langsyntaxhighlight>
{{out}}
<pre> Encoded: 6219A470D8B319A31C8E13F612B31337098F
Decoded: 2161747465736F52202C6F6C6C6548
As ASCII: Hello, Rosetta!</pre>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="ecmascript">/*import math.big
fn main() {
//var bb, ptn, etn, dtn big.Int
pt := "Rosetta Code"
println("Plain text: $pt")
// a key set big enough to hold 16 bytes of plain text in
// a single block (to simplify the example) and also big enough
// to demonstrate efficiency of modular exponentiation.
n := big.integer_from_string("9516311845790656153499716760847001433441357")?
e := big.integer_from_string("65537")?
d := big.integer_from_string("5617843187844953170308463622230283376298685")?
mut ptn := big.zero_int
// convert plain text to a number
for b in pt.bytes() {
bb := big.integer_from_i64(i64(b))
ptn = ptn.lshift(8).bitwise_or(bb)
}
if ptn >= n {
println("Plain text message too long")
return
}
println("Plain text as a number:$ptn")
// encode a single number
etn := ptn.big_mod_pow(e,n)
println("Encoded: $etn")
// decode a single number
mut dtn := etn.big_mod_pow(d,n)
println("Decoded: $dtn")
// convert number to text
mut db := [16]u8{}
mut dx := 16
bff := big.integer_from_int(0xff)
for dtn.bit_len() > 0 {
dx--
bb := dtn.bitwise_and(bff)
db[dx] = u8(i64(bb.int()))
dtn = dtn.rshift(8)
println('${db[0..].bytestr()} ${dtn.bit_len()}')
}
println("Decoded number as text: ${db[dx..].bytestr()}")
}*/
 
import math.big
fn main() {
//var bb, ptn, etn, dtn big.Int
pt := "Hello World"
println("Plain text: $pt")
// a key set big enough to hold 16 bytes of plain text in
// a single block (to simplify the example) and also big enough
// to demonstrate efficiency of modular exponentiation.
n := big.integer_from_string("9516311845790656153499716760847001433441357")?
e := big.integer_from_string("65537")?
d := big.integer_from_string("5617843187844953170308463622230283376298685")?
mut ptn := big.zero_int
// convert plain text to a number
for b in pt.bytes() {
bb := big.integer_from_i64(i64(b))
ptn = ptn.lshift(8).bitwise_or(bb)
}
if ptn >= n {
println("Plain text message too long")
return
}
println("Plain text as a number:$ptn")
// encode a single number
etn := ptn.big_mod_pow(e,n)
println("Encoded: $etn")
// decode a single number
mut dtn := etn.big_mod_pow(d,n)
println("Decoded: $dtn")
// convert number to text
mut db := [16]u8{}
mut dx := 16
bff := big.integer_from_int(0xff)
for dtn.bit_len() > 0 {
dx--
bb := dtn.bitwise_and(bff)
db[dx] = u8(i64(bb.int()))
dtn = dtn.rshift(8)
}
println("Decoded number as text: ${db[dx..].bytestr()}")
}</syntaxhighlight>
 
{{out}}
<pre>
Plain text: Hello World
Plain text as a number:87521618088882533792115812
Encoded: 8455179966388263657372423602482472996174613
Decoded: 87521618088882533792115812
Decoded number as text: Hello World
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-big}}
<langsyntaxhighlight ecmascriptlang="wren">import "./big" for BigInt
 
var pt = "Rosetta Code"
Line 2,152 ⟶ 2,498:
var s = ""
for (i in dx..15) s = s + String.fromByte(db[i])
System.print("Decoded number as text : %(s)")</langsyntaxhighlight>
 
{{out}}
Line 2,167 ⟶ 2,513:
{{libheader|GMP}}
No blocking.
<langsyntaxhighlight lang="zkl">var BN=Import.lib("zklBigNum");
 
n:=BN("9516311845790656153499716760847001433441357");
Line 2,182 ⟶ 2,528:
pt =ct.powm(d,n); println("Decoded: ",pt);
txt:=pt.toData().text; // convert big int to bytes, treat as string
println("As String: ",txt);</langsyntaxhighlight>
{{out}}
<pre>
9,485

edits