RSA code: Difference between revisions
m
→{{header|Wren}}: Minor tidy
m (→{{header|Phix}}: bigint -> gmp) |
m (→{{header|Wren}}: Minor tidy) |
||
(34 intermediate revisions by 16 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].
'''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.
<
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>
{{out}}
<pre>
Line 122 ⟶ 211:
=={{header|C}}==
{{libheader|GMP}}
<syntaxhighlight lang="c">
#include <stdio.h>
#include <stdlib.h>
Line 157 ⟶ 246:
return 0;
}
</syntaxhighlight>
{{out}}
<pre>
Line 164 ⟶ 253:
As String: Rossetta Code
</pre>
=={{header|C sharp|C#}}==
Line 170 ⟶ 258:
{{libheader|System.Numerics}}
<
using System.Numerics;
using System.Text;
Line 197 ⟶ 285:
Console.WriteLine("As ASCII: " + decoded);
}
}</
{{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.
<
(defparameter *e* 65537)
(defparameter *d* 5617843187844953170308463622230283376298685)
Line 241 ⟶ 329:
(defun decode-rsa (message)
(decode-string (mod-exp message *d* *n* 1)))
</syntaxhighlight>
Interpreter output (the star * represents the interpreter prompt):
<pre>
Line 258 ⟶ 346:
This used the D module of the Modular Exponentiation Task.
{{trans|Go}}
<
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);
}</
{{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#}}==
<
//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>
{{out}}
<pre>
Line 318 ⟶ 675:
As text -> "The magic words are SQUEAMISH OSSIFRAGE"
</pre>
=={{header|FreeBASIC}}==
{{trans|C}}
<
' compile with: fbc -s console
Line 363 ⟶ 721:
Print : Print "hit any key to end program"
Sleep
End</
{{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.
<
import (
Line 419 ⟶ 777:
}
fmt.Println("Decoded number as text:", string(db[dx:]))
}</
Output:
<pre>
Line 430 ⟶ 788:
=={{header|Haskell}}==
<
where
import Data.Char ( chr )
Line 475 ⟶ 833:
decrypted = decode $ rsa_decode d n rsa_encoded
putStrLn ("Encrypted: " ++ encrypted )
putStrLn ("And now decrypted: " ++ decrypted )</
{{out}}
<pre>Enter a test text!
Line 486 ⟶ 844:
Please read talk pages.
<
n := 9516311845790656153499716760847001433441357
Line 550 ⟶ 908:
every (m := 0) := !M + b * m
return m
end</
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]
<
E=: 65537x
D=: 5617843187844953170308463622230283376298685x
Line 605 ⟶ 963:
25512506514985639724585018469
] final=: a. {~ 256x #.inv dec
Rosetta Code</
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}}==
<
public static void main(String[] args) {
/*
Line 639 ⟶ 997:
System.out.println("As text: " + decText);
}
</syntaxhighlight>
===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}}
<
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")</
{{out}}
Line 669 ⟶ 1,165:
=={{header|Kotlin}}==
<
import java.math.BigInteger
Line 696 ⟶ 1,192:
val decText = dec.toByteArray().toString(c)
println("As text : $decText")
}</
{{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 <> "'"];</
{{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}}==
<
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</
Output:<pre>
Line 764 ⟶ 1,383:
As a check: it's easy to crack this weak encrypted message without knowing secret key 'd'
<
crack = Strchr(digits(lift(Mod(encoded,n) ^ lift(Mod(1,(f[1,1]-1)*(f[2,1]-1)) / e)),256))</
Output:<pre>crack: "Rosetta Code"</pre>
=={{header|Perl}}==
{{trans|
<
$n = 9516311845790656153499716760847001433441357;
Line 834 ⟶ 1,453:
After exponentiation with SECRET exponent we get: $numeric_message2
This turns into the string $secret_message2
EOT</
{{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|Phix}}==
{{libheader|Phix/mpfr}}
{{trans|C}}
<!--<syntaxhighlight lang="phix">(notonline)-->
<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>
<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>
<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>
<span style="color: #000000;">pt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">ct</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">()</span>
<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
-- "Rosetta Code" -- matches D/FreeBasic/Go/Icon/J/Kotlin/Seed7.</span>
<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: #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>
<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>
Line 944 ⟶ 1,508:
=={{header|PicoLisp}}==
PicoLisp comes with an RSA library:
<
# Generate long random number
Line 1,059 ⟶ 1,623:
# Decrypt
: (pack (decrypt Keys CryptText))
-> "The quick brown fox jumped over the lazy dog's back"</
=={{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}}==
<
n = 9516311845790656153499716760847001433441357 # p*q = modulus
Line 1,089 ⟶ 1,678:
print('message ', binascii.unhexlify(hex(decrypted_text)[2:]).decode()) # [2:] slicing, to strip the 0x part
</syntaxhighlight>
{{output}}
<pre>
Line 1,108 ⟶ 1,697:
Cutting messages into blocks has not been done.
<
(require math/number-theory)
(define-logger rsa)
Line 1,279 ⟶ 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))</
{{out}}
Line 1,336 ⟶ 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}}==
<
#!/usr/bin/ruby
Line 1,393 ⟶ 2,047:
final = blocks_to_text(decoded)
print "Decrypted Message: "; puts final
</syntaxhighlight>
{{out}}
<pre>
Line 1,401 ⟶ 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">
object RSA_saket{
val d = BigInt("5617843187844953170308463622230283376298685")
Line 1,438 ⟶ 2,158:
}
}
</syntaxhighlight>
{{out}}
Line 1,451 ⟶ 2,171:
=={{header|Seed7}}==
<
include "bigint.s7i";
include "bytedata.s7i";
Line 1,480 ⟶ 2,200:
writeln("Decoded number as text: " <& decodedText);
end if;
end func;</
{{out}}
Line 1,492 ⟶ 2,212:
=={{header|Sidef}}==
{{trans|
<
const e = 65537
const d = 5617843187844953170308463622230283376298685
Line 1,537 ⟶ 2,257:
var secret_message2 = Message::decode(numeric_message2)
say "This turns into the string #{secret_message2}"</
{{out}}
<pre>
Line 1,551 ⟶ 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. -->
<
# This is a straight-forward square-and-multiply implementation that relies on
Line 1,598 ⟶ 2,318:
set dec [rsa_decrypt $enc $privateKey]
puts "$input -> $enc -> $dec"
}</
Output:
<pre>
Line 1,608 ⟶ 2,328:
{{trans|C#}}
{{libheader|System.Numerics}}
<
Imports System.Numerics
Imports System.Text
Line 1,628 ⟶ 2,348:
Console.WriteLine("As ASCII: " & decoded)
End Sub
End Module</
{{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,638 ⟶ 2,513:
{{libheader|GMP}}
No blocking.
<
n:=BN("9516311845790656153499716760847001433441357");
Line 1,653 ⟶ 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);</
{{out}}
<pre>
|