RSA code: Difference between revisions

42,769 bytes added ,  3 months ago
m
m (→‎{{header|Wren}}: Minor tidy)
 
(39 intermediate revisions by 17 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.
 
<syntaxhighlight 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;
 
PROCEDURE Main IS
FUNCTION "+" (U : Unbounded_Integer) RETURN Mpz_T IS (Aliased_Internal_Value (U));
FUNCTION "+" (S : String) RETURN Unbounded_Integer IS (To_Unbounded_Integer (S));
FUNCTION Image_Cleared (M : Mpz_T) RETURN String IS (Image (To_Unbounded_Integer (M)));
N : Unbounded_Integer := +"9516311845790656153499716760847001433441357";
E : Unbounded_Integer := +"65537";
D : Unbounded_Integer := +"5617843187844953170308463622230283376298685";
Plain_Text : CONSTANT String := "Rosetta Code";
M, M_C, M_D : Mpz_T;
-- We import two C functions from the GMP library which are not in the specs of the gmp package
PROCEDURE Mpz_Import
(Rop : Mpz_T; Count : Size_T; Order : Int; Size : Size_T; Endian : Int;
Nails : Size_T; Op : Char_Array);
PRAGMA Import (C, Mpz_Import, "__gmpz_import");
 
PROCEDURE Mpz_Export
(Rop : OUT Char_Array; Count : ACCESS Size_T; Order : Int; Size : Size_T;
Endian : Int; Nails : Size_T; Op : Mpz_T);
PRAGMA Import (C, Mpz_Export, "__gmpz_export");
BEGIN
Mpz_Init (M);
Mpz_Init (M_C);
Mpz_Init (M_D);
Mpz_Import (M, Plain_Text'Length + 1, 1, 1, 0, 0, To_C (Plain_Text));
Mpz_Powm (M_C, M, +E, +N);
Mpz_Powm (M_D, M_C, +D, +N);
Put_Line ("Encoded plain text: " & Image_Cleared (M));
DECLARE Decrypted : Char_Array (1 .. Mpz_Sizeinbase (M_C, 256));
BEGIN
Put_Line ("Encryption of this encoding: " & Image_Cleared (M_C));
Mpz_Export (Decrypted, NULL, 1, 1, 0, 0, M_D);
Put_Line ("Decryption of the encoding: " & Image_Cleared (M_D));
Put_Line ("Final decryption: " & To_Ada (Decrypted));
END;
END Main;
</syntaxhighlight>
 
{{out}}
<pre>
Encoded plain text: 6531201667836323769493764728064
Encryption of this encoding: 8527003485686414372697775926080309566820293
Decryption of the encoding: 6531201667836323769493764728064
Final decryption: Rosetta Code
</pre>
 
=={{header|ALGOL 68}}==
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 114 ⟶ 203:
print (number to string (mod power (ciphertext, d, n)))
END
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 122 ⟶ 211:
=={{header|C}}==
{{libheader|GMP}}
<syntaxhighlight lang="c">
<lang C>
#include <stdio.h>
#include <stdlib.h>
Line 157 ⟶ 246:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 164 ⟶ 253:
As String: Rossetta Code
</pre>
 
 
=={{header|C sharp|C#}}==
Line 170 ⟶ 258:
{{libheader|System.Numerics}}
 
<langsyntaxhighlight lang="csharp">using System;
using System.Numerics;
using System.Text;
Line 197 ⟶ 285:
Console.WriteLine("As ASCII: " + decoded);
}
}</langsyntaxhighlight>
 
{{out}}
Line 209 ⟶ 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 241 ⟶ 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 258 ⟶ 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 292 ⟶ 380:
decTxt ~= (dec & 0xff).toInt;
writeln("Decoded number as text: ", decTxt.retro);
}</langsyntaxhighlight>
{{out}}
<pre>Plain text: Rosetta Code
Line 299 ⟶ 387:
Decoded: 25512506514985639724585018469
Decoded number as text: Rosetta Code</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| Velthuis.BigIntegers}}
{{Trans|Go}}
Thanks for Rudy Velthuis, BigIntegers library
<syntaxhighlight lang="delphi">
program RSA_code;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
Velthuis.BigIntegers;
 
type
TRSA = record
private
n, e, d: BigInteger;
class function PlainTextAsNumber(data: AnsiString): BigInteger; static;
class function NumberAsPlainText(Num: BigInteger): AnsiString; static;
public
constructor Create(n, e, d: string);
function Encode(data: AnsiString): string;
function Decode(code: string): AnsiString;
end;
 
function EncodeRSA(data: AnsiString): string;
var
n, e, d, bb, ptn, etn, dtn: BigInteger;
begin
// 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 := '9516311845790656153499716760847001433441357';
e := '65537';
d := '5617843187844953170308463622230283376298685';
 
for var c in data do
begin
bb := ord(c);
ptn := (ptn shl 8) or bb;
end;
 
if BigInteger.Compare(ptn, n) >= 0 then
begin
Writeln('Plain text message too long');
exit;
end;
writeln('Plain text as a number:', ptn.ToString);
writeln(ptn.ToString);
 
// encode a single number
etn := BigInteger.ModPow(ptn, e, n);
Writeln('Encoded: ', etn.ToString);
 
// decode a single number
dtn := BigInteger.ModPow(etn, d, n);
Writeln('Decoded: ', dtn.ToString);
 
// convert number to text
var db: AnsiString;
var bff: BigInteger := $FF;
while dtn.BitLength > 0 do
begin
db := ansichar((dtn and bff).AsInteger) + db;
dtn := dtn shr 8;
end;
Write('Decoded number as text:"', db, '"');
end;
 
const
pt = 'Rosetta Code';
 
{ TRSA }
 
constructor TRSA.Create(n, e, d: string);
begin
self.n := n;
self.e := e;
self.d := d;
end;
 
function TRSA.Decode(code: string): AnsiString;
var
etn, dtn: BigInteger;
begin
// decode a single number
etn := code;
dtn := BigInteger.ModPow(etn, d, n);
Result := NumberAsPlainText(dtn);
end;
 
function TRSA.Encode(data: AnsiString): string;
var
ptn: BigInteger;
begin
ptn := PlainTextAsNumber(data);
 
// encode a single number
Result := BigInteger.ModPow(ptn, e, n).ToString;
end;
 
class function TRSA.NumberAsPlainText(Num: BigInteger): AnsiString;
var
bff: BigInteger;
begin
// convert number to text
bff := $FF;
Result := '';
while Num.BitLength > 0 do
begin
Result := ansichar((Num and bff).AsInteger) + Result;
Num := Num shr 8;
end;
end;
 
class function TRSA.PlainTextAsNumber(data: AnsiString): BigInteger;
var
c: AnsiChar;
bb, n: BigInteger;
begin
Result := 0;
n := '9516311845790656153499716760847001433441357';
for c in data do
begin
bb := ord(c);
Result := (Result shl 8) or bb;
end;
 
if BigInteger.Compare(Result, n) >= 0 then
raise Exception.Create('Plain text message too long');
end;
 
var
RSA: TRSA;
Encoded: string;
 
const
n = '9516311845790656153499716760847001433441357';
e = '65537';
d = '5617843187844953170308463622230283376298685';
TEST_WORD = 'Rosetta Code';
 
begin
RSA := TRSA.Create(n, e, d);
Encoded := RSA.Encode(TEST_WORD);
writeln('Plain text: ', TEST_WORD);
writeln('Encoded: ', Encoded);
writeln('Decoded: ', RSA.Decode(Encoded));
Readln;
end.</syntaxhighlight>
{{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 310 ⟶ 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 318 ⟶ 675:
As text -> "The magic words are SQUEAMISH OSSIFRAGE"
</pre>
 
=={{header|FreeBASIC}}==
{{trans|C}}
<langsyntaxhighlight lang="freebasic">' version 17-01-2017
' compile with: fbc -s console
 
Line 363 ⟶ 721:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> Encoded: 916709442744356653386978770799029131264344
Line 372 ⟶ 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 419 ⟶ 777:
}
fmt.Println("Decoded number as text:", string(db[dx:]))
}</langsyntaxhighlight>
Output:
<pre>
Line 430 ⟶ 788:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">module RSAMaker
where
import Data.Char ( chr )
Line 475 ⟶ 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 486 ⟶ 844:
Please read talk pages.
 
<langsyntaxhighlight Iconlang="icon">procedure main() # rsa demonstration
n := 9516311845790656153499716760847001433441357
Line 550 ⟶ 908:
every (m := 0) := !M + b * m
return m
end</langsyntaxhighlight>
 
Output:
Line 590 ⟶ 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 605 ⟶ 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 611 ⟶ 969:
=={{header|Java}}==
 
<langsyntaxhighlight lang="java">
public static void main(String[] args) {
/*
Line 639 ⟶ 997:
System.out.println("As text: " + decText);
}
</syntaxhighlight>
</lang>
===Alternative solution - convert to byte array then to BigInteger: ===
<syntaxhighlight lang="java">
import java.math.BigInteger;
import java.util.Random;
 
public class rsaCode {
public static void main(String[]args){
//Size of primes
int BIT_LENGTH = 4096;
Random rand = new Random();
//Generate primes and other necessary values
BigInteger p = BigInteger.probablePrime(BIT_LENGTH / 2, rand);
BigInteger q = BigInteger.probablePrime(BIT_LENGTH / 2, rand);
BigInteger n = p.multiply(q);
BigInteger phi = p.subtract(BigInteger.valueOf(1)).multiply(q.subtract(BigInteger.valueOf(1)));
BigInteger e;
BigInteger d;
do {
e = new BigInteger(phi.bitLength(), rand);
} while (e.compareTo(BigInteger.valueOf(1)) <= 0 || e.compareTo(phi) >= 0 || !e.gcd(phi).equals(BigInteger.valueOf(1)));
d = e.modInverse(phi);
//Convert message to byte array and then to a BigInteger
BigInteger message = new BigInteger("Hello World! - From Rosetta Code".getBytes());
BigInteger cipherText = message.modPow(e, n);
BigInteger decryptedText = cipherText.modPow(d, n);
System.out.println("Message: " + message);
System.out.println("Prime 1: " + p);
System.out.println("Prime 2: " + q);
System.out.println("Phi p1 * p2: " + phi);
System.out.println("p1 * p2: " + n);
System.out.println("Public key: " + e);
System.out.println("Private key: " + d);
System.out.println("Ciphertext: " + cipherText);
System.out.println("Decrypted message(number form): " + decryptedText);
//Convert BigInteger to byte array then to String
System.out.println("Decrypted message(string): " + new String(decryptedText.toByteArray()));
}
}
</syntaxhighlight>
{{out}}
<pre>Message: 32745724963520459128167607565116331713761641910444445962992228853365120918629
Prime 1: 19236082984974163990952162748173714068049389803543876908591023542434008581726901827775282361343539027357627272183474081300821830594665417249999421476471444612045376319151307819458083226682409477411524022807762467877933511178646356355356721278159329226472299570078614830307335816363768128995044913560110586093645150502887099142708810425659608200567299323058631080348801201371891024721397456687923823598994147721120698707559677560198153919129668778208924015134166710369131053236474139106999881687335966483688956493993503452781613364724067448118712996621139377805320411264206346354690147839668674568385780953439324061827
Prime 2: 17979329033868078796981009025342087899891110883452413861085335446537232859657584956199529432436753743100057017453176958641563538906032576785591580481524960405796753482749211728790206586594224271803757384485305551705171358489679998051039658612346599741622638134691446099105450988669667758655426868708523266671158484337114750111466361420411180131539156350206088712722069263680478398363920580976741655559629459204726096055804150577131670026585406567505359058210528861172448235138919989250928848721850118962177309953951127503325970279819172102106621073790956566530104217789478786634899278802600883073967446382373644250257
Phi p1 * p2: 345851865309641725173652598401242058900566653910908938475312921380066114219124630361012048649340940349701681628058518630535276222954695692233147670047674008455691941733381178283159719985229687501019788350058464636500196522521346408404768715926660411771389935137989577763538670548607053837834611583177259789432946335846775973340201166384784256821490809726897985505537384164828673170953111807028144501567927080933277305734847328999516054393161305269105612852357562678721346577533872335946654435942111678921979428611842390495534195723208415846942969477148117377158823876687230703157218761840307200229212313941422321195051355226377851222163854147510935258095666300221082823130614374400292194084084333352100386386600651725502133645428505729406848959785973133150969119775159790464605612595258587741654065352840099419921194642121733262659814580729725479879031162109276830902575494117198577188807279359692336933181285455336126206772237317229756148090589146421446485136412385682723586947367965091078676401379642267664924847358476052429919297388821038943132363371365451994109675932621652038431036384121653367832798502022879709943736316295610602665722391298109723459179009548775436875778616030750642493163185541967992915955989097200396360327456
p1 * p2: 345851865309641725173652598401242058900566653910908938475312921380066114219124630361012048649340940349701681628058518630535276222954695692233147670047674008455691941733381178283159719985229687501019788350058464636500196522521346408404768715926660411771389935137989577763538670548607053837834611583177259789432946335846775973340201166384784256821490809726897985505537384164828673170953111807028144501567927080933277305734847328999516054393161305269105612852357562678721346577533872335946654435942111678921979428611842390495534195723208415846942969477148117377158823876687230703157218761840307200229212313941422321195088570638396693464951787319284451060063606800908079113900290733389263435525468820136075198180380944495959817935065156769349234329286671127186560121733156195482447742397159107289902355166116733169136476049414801282242919450398051834285427541999782759870670431821968638118220066164725772820831757237604760059537040952069757997344764318267517273468518841355988306740438835556131045824464960305329590326517099659355766092152184867080462187317080527339823959005966347609972615672497047496190727232432065795389602582743555233621829974942652963009404343619187532820114040659804327626152774968610262473598342324536209328639539
Public key: 193579940416764762032781091221143757801413904551984303885407040026321908965197971867687112770438003048686335467825121571041736775396425178706013366881005246973351188647629560663037810331045292388828497048500842585316962463760854316963245076613682542629780184301654965436793943481122744003077197338402843407520722504896640189710671321124115630104805979401188537742997889316213029383963089439143905748656345056757946693819634971714186428073990059096062771479710217863926284515341443931092854041306087536208153864059633604334787035313177701948799425284530371404018395643074910533253129726213643193854656336232925658951811658248314007700619000559672273590950586652099230800733098520827807590026231300954320448333065980082309254977488081625340716095420728271744505284703847569933308644755417715559811180764086973488668246118187715534944871349843316776293048731714297576612062481854912918664986385922123428018736434561518771685854566894264705876397229699222060976725454055036743075458563364307745597456824543609383372429743649103452964024219143956601668222718087847554469024737873441872945480724976527827721060219946775750776694792509727838512629661637130805269017888622785492890741411798087685393616016451666522802755139926311245306229041
Private key: 219036175169203544315490853999486820834618560996816043411987210664248102884377915567272406198057873662330646577076795355640818453754512006948660586443609679011052139043660581484406998357727395227184641632029033848943507736672039637904589489626534363470520344933214278535075666039716685014892551021861132000517572948046870070641407067319704943583671179776670601874690644590228314092730047599467716558027443683253737751585758991176998516378325292822247842855150355043416320003512453741917219948896684868393696007264717697967091707113384847407621846752255898098912112528872599250195047315005253431619786863325536528182598792588704861531564144935586585480994816595663012912390628905402008731003235520424397350241617043412307761990786711273480686856614955176903059108533627807572077696388568308581773433971401736018773723311485647784158083000913638874130114372027510789163873963163280849749880619112666293979830817843596818936327354256104400652111217685523782967475741729222155996255475772715455781288940265345618022791173798222315117453828105848080873781770073614996444414329484314974671715475986173113744470587849073918357399130907446602201256421236363869748993676713228862789197394591401079130691347928057018496258825068434610372879057
Ciphertext: 751802077965963630324549365263121640277689482825128224616526073196054301029392106215761462171255492597878612184351606323296123153021421277191908278007450520130118453205040455128556435393691729542297181525367763857641211099694558032110059874156910175402903627759175935900055257215548262301358748652386044838566618270488287858766869634274195146217020325014127218881028662056032737660265341221411932659292844178938078127559747544470249139600492686861162904399444542749100026596955221740375230453344396141534329779530430928001439479395156999496805099234924399049952788417632216512939528956109220706809364166228124854558311835437452608371779980805227059349785343399382366770619320980575920634550115026075376299109862825119723058827075167366432962208711425854647134395509013075755502864140908914499073909257771585668395445413050111450415828406012614877021632277223689796818643848597729370856433117827304201297547912764020996146635163811573223631120712910083451904964228318515972103019499763177402019351409722785807448842923761649884358555226283418059099812653679780193380193208207168410802721122329377467373427784070234188000453256581358361888268040964222190110448131244743936030485464773996914221120717918807573232494076059754978713933
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 661 ⟶ 1,157:
encoded = rsaencode(msg, nmod, expub)
decoded = rsadecode(encoded, nmod, dsecr)
println("\n# $msg\n -> ENCODED: $encoded\n -> DECODED: $decoded")</langsyntaxhighlight>
 
{{out}}
Line 669 ⟶ 1,165:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.4-3
 
import java.math.BigInteger
Line 696 ⟶ 1,192:
val decText = dec.toByteArray().toString(c)
println("As text : $decText")
}</langsyntaxhighlight>
 
{{out}}
Line 707 ⟶ 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 728 ⟶ 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 737 ⟶ 1,233:
Encoded: 199505409518408949879682159958576932863989
Decoded: 'The cake is a lie!'</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import strutils, streams, strformat
# nimble install stint
import stint
 
const messages = ["PPAP", "I have a pen, I have a apple\nUh! Apple-pen!",
"I have a pen, I have pineapple\nUh! Pineapple-pen!",
"Apple-pen, pineapple-pen\nUh! Pen-pineapple-apple-pen\nPen-pineapple-apple-pen\nDance time!", "\a\0"]
const
n = u256("9516311845790656153499716760847001433441357")
e = u256("65537")
d = u256("5617843187844953170308463622230283376298685")
proc pcount(s: string, c: char): int{.inline.} =
for ch in s:
if ch != c:
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 = newStringStream(hexString)
chunk, residue, tempChunk: string
let chunkSize = len(toHex(divisor))
while true:
tempChunk = strm.peekStr(chunkSize-int(encrypt)*3)
if len(chunk) > 0:
if len(tempChunk) == 0:
if encrypt:
result&=powmodHexStr(pcount(chunk, '0').toHex(2)&align(chunk,
chunkSize-3, '0'), key, divisor)
else:
tempChunk = align(powmodHexStr(chunk, key, divisor), chunkSize-1, '0')
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
strm.close()
for message in messages:
echo(&"plaintext:\n{message}")
var numPlaintext = message.toHex()
echo(&"numerical plaintext in hex:\n{numPlaintext}")
var ciphertext = translate(numPlaintext, e, n)
echo(&"ciphertext is: \n{ciphertext}")
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")</syntaxhighlight>
{{out}}
<pre>plaintext:
PPAP
numerical plaintext in hex:
50504150
ciphertext is:
6c55b71c718b8921555eaa9754b7bfd7018b
deciphered numerical plaintext in hex is:
50504150
deciphered plaintext is:
PPAP
 
 
plaintext:
I have a pen, I have a apple
Uh! Apple-pen!
numerical plaintext in hex:
49206861766520612070656E2C204920686176652061206170706C650A556821204170706C652D70656E21
ciphertext is:
4614caba02ac33654130c10485dcceeec4a2443f4bffb46e389c2705d4ebd7ac7185a206ae0294575f283841baad236fa90d5c5536b
deciphered numerical plaintext in hex is:
49206861766520612070656e2c204920686176652061206170706c650a556821204170706c652d70656e21
deciphered plaintext is:
I have a pen, I have a apple
Uh! Apple-pen!
 
 
plaintext:
I have a pen, I have pineapple
Uh! Pineapple-pen!
numerical plaintext in hex:
49206861766520612070656E2C204920686176652070696E656170706C650A5568212050696E656170706C652D70656E21
ciphertext is:
4614caba02ac33654130c10485dcceeec4a21c96dd7a5048e412a16c65e274609964ffb14231b9d6a70a59380d4bbaef3c40e88afa3d
deciphered numerical plaintext in hex is:
49206861766520612070656e2c204920686176652070696e656170706c650a5568212050696e656170706c652d70656e21
deciphered plaintext is:
I have a pen, I have pineapple
Uh! Pineapple-pen!
 
 
plaintext:
Apple-pen, pineapple-pen
Uh! Pen-pineapple-apple-pen
Pen-pineapple-apple-pen
Dance time!
numerical plaintext in hex:
4170706C652D70656E2C2070696E656170706C652D70656E0A5568212050656E2D70696E656170706C652D6170706C652D70656E0A50656E2D70696E656170706C652D6170706C652D70656E0A44616E63652074696D6521
ciphertext is:
5d733e3979b0b43207dace453c3ec65baaff54571a3127be4ccd120dff94fb2e1b9258d6067cee2669e868ee4390c5e16f61016a171f6585ad4cd58ca3335bc9faa96da943bfedad0dd0ac7cbc83a256bf9f6f65d755865aed232e1e0a467512a6744f3f470ee283c8b4e2e5
deciphered numerical plaintext in hex is:
4170706c652d70656e2c2070696e656170706c652d70656e0a5568212050656e2d70696e656170706c652d6170706c652d70656e0a50656e2d70696e656170706c652d6170706c652d70656e0a44616e63652074696d6521
deciphered plaintext is:
Apple-pen, pineapple-pen
Uh! Pen-pineapple-apple-pen
Pen-pineapple-apple-pen
Dance time!
 
 
plaintext:
(shell terminal cannot display "\a\0")
numerical plaintext in hex:
0700
ciphertext is:
2177c0b1865ac16e47807e4f4d82e421bbdf
deciphered numerical plaintext in hex is:
0700
deciphered plaintext is:
(shell terminal cannot display "\a\0")
 
</pre>
 
=={{header|PARI/GP}}==
 
<langsyntaxhighlight lang="parigp">stigid(V,b)=subst(Pol(V),'x,b); \\ inverse function digits(...)
 
n = 9516311845790656153499716760847001433441357;
Line 751 ⟶ 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 764 ⟶ 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>
 
=={{header|Perl}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="perl">use bigint;
 
$n = 9516311845790656153499716760847001433441357;
Line 834 ⟶ 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 843 ⟶ 1,462:
After exponentiation with SECRET exponent we get: 97525102075211938
This turns into the string ROSETTA CODE</pre>
 
=={{header|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'.
<lang perl6>constant $n = 9516311845790656153499716760847001433441357;
constant $e = 65537;
constant $d = 5617843187844953170308463622230283376298685;
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) {
[+] %code{$t.flip.comb} Z* (1, $rad, $rad*$rad ... *);
}
our sub decode(Int $n is copy) {
@alphabet[
gather loop {
take $n % $rad;
last if $n < $rad;
$n div= $rad;
}
].join.flip;
}
}
use Test;
plan 1;
say "Secret message is $secret-message";
say "Secret message in integer form is $_" given
my $numeric-message = Message::encode $secret-message;
say "After exponentiation with public exponent we get: $_" given
my $numeric-cipher = expmod $numeric-message, $e, $n;
say "This turns into the string $_" given
my $text-cipher = Message::decode $numeric-cipher;
say "If we re-encode it in integer form we get $_" given
my $numeric-cipher2 = Message::encode $text-cipher;
say "After exponentiation with SECRET exponent we get: $_" given
my $numeric-message2 = expmod $numeric-cipher2, $d, $n;
say "This turns into the string $_" given
my $secret-message2 = Message::decode $numeric-message2;
is $secret-message, $secret-message2, "the message has been correctly decrypted";</lang>
{{out}}
<pre>1..1
Secret message is ROSETTA CODE
Secret message in integer form is 97525102075211938
After exponentiation with public exponent we get: 8326171774113983822045243488956318758396426
This turns into the string ZULYDCEZOWTFXFRRNLIMGNUPHVCJSX
If we re-encode it in integer form we get 8326171774113983822045243488956318758396426
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|Phix}}==
{{libheader|Phix/mpfr}}
<lang Phix>include builtins/bigint.e -- (0.8.0+, not yet properly documented)
{{trans|C}}
 
<!--<syntaxhighlight lang="phix">(notonline)-->
string plaintext = "Rosetta Code"
<span style="color: #008080;">without</span> <span style="color: #008080;">javascript_semantics</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>
bigint n = bi_new("9516311845790656153499716760847001433441357"),
e = bi_new(65537),
<span style="color: #004080;">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>
d = bi_new("5617843187844953170308463622230283376298685"),
<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>
pt = bi_new_bin(plaintext,true,0)
<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>
 
<span style="color: #000000;">pt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(),</span>
if bi_compare(pt,n)>0 then ?9/0 end if
<span style="color: #000000;">ct</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">()</span>
bigint ct = bi_mod_exp(pt, e, n),
<span style="color: #004080;">string</span> <span style="color: #000000;">plaintext</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Rossetta Code"</span> <span style="color: #000080;font-style:italic;">-- matches C/zkl
dc = bi_mod_exp(ct, d, n)
-- "Rosetta Code" -- matches D/FreeBasic/Go/Icon/J/Kotlin/Seed7.</span>
printf(1,"Original: %s\n",{plaintext})
<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>
printf(1,"As Number: %s\n",{bi_sprint(pt)})
printf(1,"Encoded: %s\n",{bi_sprint(ct)})
<span style="color: #008080;">if</span> <span style="color: #7060A8;">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>
printf(1,"Decoded: %s\n",{bi_sprint(dc)})
printf(1,"As ASCII: %s\n",{bi_bin(dc)})</lang>
<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>
<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;">"Encoded: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ct</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">mpz_powm</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;">d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">);</span>
<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\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">)})</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">size</span> <span style="color: #0000FF;">=</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #7060A8;">mpz_sizeinbase</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">7</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">pMem</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">size</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mpz_export</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pMem</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;">pt</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">></span><span style="color: #000000;">size</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;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"As String: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">peek</span><span style="color: #0000FF;">({</span><span style="color: #000000;">pMem</span><span style="color: #0000FF;">,</span><span style="color: #000000;">count</span><span style="color: #0000FF;">})})</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> <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>
<!--</syntaxhighlight>-->
<small>(mpz_import() and mpz_export() are not supported under pwa/p2js)</small>
{{out}}
<pre>
Encoded: 5278143020249600501803788468419399384934220
Original: Rosetta Code
Decoded: 6531201733672758787904906421349
As Number: 25512506514985639724585018469
As String: Rossetta Code
Encoded: 916709442744356653386978770799029131264344
Decoded: 25512506514985639724585018469
As ASCII: Rosetta Code
</pre>
 
=={{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,048 ⟶ 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">
$n = [BigInt]::Parse("9516311845790656153499716760847001433441357")
$e = [BigInt]::new(65537)
$d = [BigInt]::Parse("5617843187844953170308463622230283376298685")
$plaintextstring = "Hello, Rosetta!"
$plaintext = [Text.ASCIIEncoding]::ASCII.GetBytes($plaintextstring)
[BigInt]$pt = [BigInt]::new($plaintext)
if ($n -lt $pt) {throw "`$n = $n < $pt = `$pt"}
$ct = [BigInt]::ModPow($pt, $e, $n)
"Encoded: $ct"
$dc = [BigInt]::ModPow($ct, $d, $n)
"Decoded: $dc"
$decoded = [Text.ASCIIEncoding]::ASCII.GetString($dc.ToByteArray())
"As ASCII: $decoded"
</syntaxhighlight>
 
{{out}}
<pre>
Encoded: 8545729659809274764853392532557102329563535
Decoded: 173322416552962951144796590453843272
As ASCII: Hello, Rosetta!
</pre>
 
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">import binascii
 
n = 9516311845790656153499716760847001433441357 # p*q = modulus
e = 65537
d = 5617843187844953170308463622230283376298685
 
print('public key ', n, e)
print('private key ', n, d, '\n')
 
message='Rosetta Code!'
Line 1,071 ⟶ 1,668:
 
if plain_text > n:
raise Exception('plain text too large for key')
 
encrypted_text = pow(plain_text, e, n)
Line 1,081 ⟶ 1,678:
print('message ', binascii.unhexlify(hex(decrypted_text)[2:]).decode()) # [2:] slicing, to strip the 0x part
 
</syntaxhighlight>
</lang>
{{output}}
<pre>
message Rosetta Code!
hex data b'526f736574746120436f646521'
plain text integer 6531201667836323769493764728097
encrypted text integer 5307878626309103053766094186556322974789734
decrypted text integer 6531201667836323769493764728097
message Rosetta Code!
</pre>
 
=={{header|Racket}}==
Line 1,091 ⟶ 1,697:
Cutting messages into blocks has not been done.
 
<langsyntaxhighlight lang="racket">#lang racket
(require math/number-theory)
(define-logger rsa)
Line 1,262 ⟶ 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,319 ⟶ 1,925:
The burden seems to be in finding (proving) the next large prime after the big random number.
However, once keys are generated, things are pretty snappy.
 
=={{header|Raku}}==
(formerly Perl 6)
 
No blocking here. Algorithm doesn't really work if either red or black text begins with 'A'.
<syntaxhighlight lang="raku" line>class RSA-message {
has ($.n, $.e, $.d); # the 3 elements that define an RSA key
 
my @alphabet = |('A' .. 'Z'), ' ';
my $rad = +@alphabet;
my %code = @alphabet Z=> 0 .. *;
subset Text of Str where /^^ @alphabet+ $$/;
 
method encode(Text $t) {
[+] %code{$t.flip.comb} Z× (1, $rad, $rad×$rad … *);
}
 
method decode(Int $n is copy) {
@alphabet[
gather loop {
take $n % $rad;
last if $n < $rad;
$n div= $rad;
}
].join.flip;
}
}
 
constant $n = 9516311845790656153499716760847001433441357;
constant $e = 65537;
constant $d = 5617843187844953170308463622230283376298685;
 
my $fmt = "%48s %s\n";
 
my $message = 'ROSETTA CODE';
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;
 
printf $fmt, 'This turns into the string',
my $text-cipher = $rsa.decode: $numeric-cipher;
 
printf $fmt, 'If we re-encode it in integer form we get',
my $numeric-cipher2 = $rsa.encode: $text-cipher;
 
printf $fmt, 'After exponentiation with SECRET exponent we get',
my $numeric-message2 = expmod $numeric-cipher2, $d, $n;
 
printf $fmt, 'This turns into the string',
my $message2 = $rsa.decode: $numeric-message2;
</syntaxhighlight>
{{out}}
<pre> Secret message is ROSETTA CODE
Secret message in integer form is 97525102075211938
After exponentiation with public exponent we get 8326171774113983822045243488956318758396426
This turns into the string ZULYDCEZOWTFXFRRNLIMGNUPHVCJSX
If we re-encode it in integer form we get 8326171774113983822045243488956318758396426
After exponentiation with SECRET exponent we get 97525102075211938
This turns into the string ROSETTA CODE</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">
#!/usr/bin/ruby
 
Line 1,376 ⟶ 2,047:
final = blocks_to_text(decoded)
print "Decrypted Message: "; puts final
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,384 ⟶ 2,055:
Decrypted to: [58008, 34336, 29295, 29541, 29812, 24931, 28516, 25902, 28530, 26400, 58012, 37642]
Decrypted Message: ☆ rosettacode.org ✓
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
extern crate num;
 
use num::bigint::BigUint;
use num::integer::Integer;
use num::traits::{One, Zero};
 
fn mod_exp(b: &BigUint, e: &BigUint, n: &BigUint) -> Result<BigUint, &'static str> {
if n.is_zero() {
return Err("modulus is zero");
}
if b >= n {
// base is too large and should be split into blocks
return Err("base is >= modulus");
}
if b.gcd(n) != BigUint::one() {
return Err("base and modulus are not relatively prime");
}
 
let mut bb = b.clone();
let mut ee = e.clone();
let mut result = BigUint::one();
while !ee.is_zero() {
if ee.is_odd() {
result = (result * &bb) % n;
}
ee >>= 1;
bb = (&bb * &bb) % n;
}
Ok(result)
}
 
fn main() {
let msg = "Rosetta Code";
 
let n = "9516311845790656153499716760847001433441357"
.parse()
.unwrap();
let e = "65537".parse().unwrap();
let d = "5617843187844953170308463622230283376298685"
.parse()
.unwrap();
 
let msg_int = BigUint::from_bytes_be(msg.as_bytes());
let enc = mod_exp(&msg_int, &e, &n).unwrap();
let dec = mod_exp(&enc, &d, &n).unwrap();
let msg_dec = String::from_utf8(dec.to_bytes_be()).unwrap();
 
println!("msg as txt: {}", msg);
println!("msg as num: {}", msg_int);
println!("enc as num: {}", enc);
println!("dec as num: {}", dec);
println!("dec as txt: {}", msg_dec);
}
 
</syntaxhighlight>
{{out}}
<pre>
msg as txt: Rosetta Code
msg as num: 25512506514985639724585018469
enc as num: 916709442744356653386978770799029131264344
dec as num: 25512506514985639724585018469
dec as txt: Rosetta Code
</pre>
 
=={{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,421 ⟶ 2,158:
}
}
</syntaxhighlight>
</lang>
{{out}}
 
Line 1,434 ⟶ 2,171:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "bigint.s7i";
include "bytedata.s7i";
Line 1,463 ⟶ 2,200:
writeln("Decoded number as text: " <& decodedText);
end if;
end func;</langsyntaxhighlight>
 
{{out}}
Line 1,475 ⟶ 2,212:
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">const n = 9516311845790656153499716760847001433441357
const e = 65537
const d = 5617843187844953170308463622230283376298685
Line 1,520 ⟶ 2,257:
 
var secret_message2 = Message::decode(numeric_message2)
say "This turns into the string #{secret_message2}"</langsyntaxhighlight>
{{out}}
<pre>
Line 1,534 ⟶ 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 1,581 ⟶ 2,318:
set dec [rsa_decrypt $enc $privateKey]
puts "$input -> $enc -> $dec"
}</langsyntaxhighlight>
Output:
<pre>
Line 1,591 ⟶ 2,328:
{{trans|C#}}
{{libheader|System.Numerics}}
<langsyntaxhighlight lang="vbnet">Imports System
Imports System.Numerics
Imports System.Text
Line 1,611 ⟶ 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}}
<syntaxhighlight lang="wren">import "./big" for BigInt
 
var pt = "Rosetta Code"
System.print("Plain text: : %(pt)")
var n = BigInt.new("9516311845790656153499716760847001433441357")
var e = BigInt.new("65537")
var d = BigInt.new("5617843187844953170308463622230283376298685")
var ptn = BigInt.zero
// convert plain text to a number
for (b in pt.bytes) {
ptn = (ptn << 8) | BigInt.new(b)
}
if (ptn >= n) {
System.print("Plain text message too long")
return
}
System.print("Plain text as a number : %(ptn)")
 
// encode a single number
var etn = ptn.modPow(e, n)
System.print("Encoded : %(etn)")
 
// decode a single number
var dtn = etn.modPow(d, n)
System.print("Decoded : %(dtn)")
 
// convert number to text
var db = List.filled(16, 0)
var dx = 16
var bff = BigInt.new(255)
while (dtn.bitLength > 0) {
dx = dx - 1
db[dx] = (dtn & bff).toSmall
dtn = dtn >> 8
}
var s = ""
for (i in dx..15) s = s + String.fromByte(db[i])
System.print("Decoded number as text : %(s)")</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|zkl}}==
Line 1,621 ⟶ 2,513:
{{libheader|GMP}}
No blocking.
<langsyntaxhighlight lang="zkl">var BN=Import.lib("zklBigNum");
 
n:=BN("9516311845790656153499716760847001433441357");
Line 1,636 ⟶ 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,476

edits