Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/RSA-code/00-META.yaml
Normal file
3
Task/RSA-code/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/RSA_code
|
||||
note: Encryption
|
||||
38
Task/RSA-code/00-TASK.txt
Normal file
38
Task/RSA-code/00-TASK.txt
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
Given an [[wp:RSA|RSA]] key (n,e,d), construct a program to encrypt and decrypt plaintext messages strings.
|
||||
|
||||
'''Background'''
|
||||
|
||||
RSA code is used to encode secret messages. It is named after Ron Rivest, Adi Shamir, and Leonard Adleman who published it at MIT in 1977. The advantage of this type of encryption is that you can distribute the number “<math>n</math>” and “<math>e</math>” (which makes up the Public Key used for encryption) to everyone. The Private Key used for decryption “<math>d</math>” is kept secret, so that only the recipient can read the encrypted plaintext.
|
||||
|
||||
The process by which this is done is that a message, for example “Hello World” is encoded as numbers (This could be encoding as ASCII or as a subset of characters <math>a=01,b=02,...,z=26</math>). This yields a string of numbers, generally referred to as "numerical plaintext", “<math>P</math>”. For example, “Hello World” encoded with a=1,...,z=26 by hundreds would yield <math>0805 1212 1523 1518 1204</math>.
|
||||
|
||||
The plaintext must also be split into blocks so that the numerical plaintext is smaller than <math>n</math> otherwise the decryption will fail.
|
||||
|
||||
The ciphertext, <math>C</math>, is then computed by taking each block of <math>P</math>, and computing
|
||||
: <math>C \equiv P^e \mod n</math>
|
||||
Similarly, to decode, one computes
|
||||
: <math>P \equiv C^d \mod n</math>
|
||||
|
||||
To generate a key, one finds 2 (ideally large) primes <math>p</math> and <math>q</math>. the value “<math>n</math>” is simply: <math>n = p \times q</math>.
|
||||
One must then choose an “<math>e</math>” such that <math>\gcd(e, (p-1)\times(q-1) ) = 1</math>. That is to say, <math>e</math> and <math>(p-1)\times(q-1)</math> are relatively prime to each other.
|
||||
|
||||
The decryption value <math>d</math> is then found by solving
|
||||
: <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 829 bits have been successfully factored, and NIST now recommends 2048 bit keys going forward (see [[wp:Key_size#Asymmetric_algorithm_key_lengths|Asymmetric algorithm key lengths]]).
|
||||
|
||||
'''Summary of the task requirements:'''
|
||||
|
||||
* Encrypt and Decrypt a short message or two using RSA with a demonstration key.
|
||||
* Implement RSA do not call a library.
|
||||
* Encode and decode the message using any reversible method of your choice (ASCII or a=1,..,z=26 are equally fine).
|
||||
* Either support blocking or give an error if the message would require blocking)
|
||||
* Demonstrate that your solution could support real keys by using a non-trivial key that requires large integer support (built-in or libraries). There is no need to include library code but it must be referenced unless it is built into the language. The following keys will be meet this requirement;however, they are NOT long enough to be considered secure:
|
||||
:: n = 9516311845790656153499716760847001433441357
|
||||
:: e = 65537
|
||||
:: d = 5617843187844953170308463622230283376298685
|
||||
* Messages can be hard-coded into the program, there is no need for elaborate input coding.
|
||||
* Demonstrate that your implementation works by showing plaintext, intermediate results, encrypted text, and decrypted text.
|
||||
|
||||
{{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]].}}
|
||||
|
||||
23
Task/RSA-code/11l/rsa-code.11l
Normal file
23
Task/RSA-code/11l/rsa-code.11l
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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))
|
||||
73
Task/RSA-code/ALGOL-68/rsa-code.alg
Normal file
73
Task/RSA-code/ALGOL-68/rsa-code.alg
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
COMMENT
|
||||
First cut. Doesn't yet do blocking and deblocking. Also, as
|
||||
encryption and decryption are identical operations but for the
|
||||
reciprocal exponents used, only one has been implemented below.
|
||||
|
||||
A later release will address these issues.
|
||||
COMMENT
|
||||
|
||||
BEGIN
|
||||
PR precision=1000 PR
|
||||
MODE LLI = LONG LONG INT; CO For brevity CO
|
||||
PROC mod power = (LLI base, exponent, modulus) LLI :
|
||||
BEGIN
|
||||
LLI result := 1, b := base, e := exponent;
|
||||
IF exponent < 0
|
||||
THEN
|
||||
put (stand error, (("Negative exponent", exponent, newline)))
|
||||
ELSE
|
||||
WHILE e > 0
|
||||
DO
|
||||
(ODD e | result := (result * b) MOD modulus);
|
||||
e OVERAB 2; b := (b * b) MOD modulus
|
||||
OD
|
||||
FI;
|
||||
result
|
||||
END;
|
||||
PROC modular inverse = (LLI a, m) LLI :
|
||||
BEGIN
|
||||
PROC extended gcd = (LLI x, y) []LLI :
|
||||
BEGIN
|
||||
LLI v := 1, a := 1, u := 0, b := 0, g := x, w := y;
|
||||
WHILE w>0
|
||||
DO
|
||||
LLI q := g % w, t := a - q * u;
|
||||
a := u; u := t;
|
||||
t := b - q * v;
|
||||
b := v; v := t;
|
||||
t := g - q * w;
|
||||
g := w; w := t
|
||||
OD;
|
||||
a PLUSAB (a < 0 | u | 0);
|
||||
(a, b, g)
|
||||
END;
|
||||
[] LLI egcd = extended gcd (a, m);
|
||||
(egcd[3] > 1 | 0 | egcd[1] MOD m)
|
||||
END;
|
||||
PROC number to string = (LLI number) STRING :
|
||||
BEGIN
|
||||
[] CHAR map = (blank + "ABCDEFGHIJKLMNOPQRSTUVWXYZ")[@0];
|
||||
LLI local number := number;
|
||||
INT length := SHORTEN SHORTEN ENTIER long long log(number) + 1;
|
||||
(ODD length | length PLUSAB 1);
|
||||
[length % 2] CHAR text;
|
||||
FOR i FROM length % 2 BY -1 TO 1
|
||||
DO
|
||||
INT index = SHORTEN SHORTEN (local number MOD 100);
|
||||
text[i] := (index > 26 | "?" | map[index]);
|
||||
local number := local number % 100
|
||||
OD;
|
||||
text
|
||||
END;
|
||||
CO The parameters of a particular RSA cryptosystem CO
|
||||
LLI p = 3490529510847650949147849619903898133417764638493387843990820577;
|
||||
LLI q = 32769132993266709549961988190834461413177642967992942539798288533;
|
||||
LLI n = p * q;
|
||||
LLI phi n = (p-1) * (q-1);
|
||||
LLI e = 9007;
|
||||
LLI d = modular inverse (e, phi n);
|
||||
CO A ciphertext CO
|
||||
LLI cipher text = 96869613754622061477140922254355882905759991124574319874695120930816298225145708356931476622883989628013391990551829945157815154;
|
||||
CO Print out the corresponding plain text CO
|
||||
print (number to string (mod power (ciphertext, d, n)))
|
||||
END
|
||||
38
Task/RSA-code/Ada/rsa-code.ada
Normal file
38
Task/RSA-code/Ada/rsa-code.ada
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
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;
|
||||
28
Task/RSA-code/C-sharp/rsa-code.cs
Normal file
28
Task/RSA-code/C-sharp/rsa-code.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
BigInteger n = BigInteger.Parse("9516311845790656153499716760847001433441357");
|
||||
BigInteger e = 65537;
|
||||
BigInteger d = BigInteger.Parse("5617843187844953170308463622230283376298685");
|
||||
|
||||
const string plaintextstring = "Hello, Rosetta!";
|
||||
byte[] plaintext = ASCIIEncoding.ASCII.GetBytes(plaintextstring);
|
||||
BigInteger pt = new BigInteger(plaintext);
|
||||
if (pt > n)
|
||||
throw new Exception();
|
||||
|
||||
BigInteger ct = BigInteger.ModPow(pt, e, n);
|
||||
Console.WriteLine("Encoded: " + ct);
|
||||
|
||||
BigInteger dc = BigInteger.ModPow(ct, d, n);
|
||||
Console.WriteLine("Decoded: " + dc);
|
||||
|
||||
string decoded = ASCIIEncoding.ASCII.GetString(dc.ToByteArray());
|
||||
Console.WriteLine("As ASCII: " + decoded);
|
||||
}
|
||||
}
|
||||
34
Task/RSA-code/C/rsa-code.c
Normal file
34
Task/RSA-code/C/rsa-code.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmp.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mpz_t n, d, e, pt, ct;
|
||||
|
||||
mpz_init(pt);
|
||||
mpz_init(ct);
|
||||
mpz_init_set_str(n, "9516311845790656153499716760847001433441357", 10);
|
||||
mpz_init_set_str(e, "65537", 10);
|
||||
mpz_init_set_str(d, "5617843187844953170308463622230283376298685", 10);
|
||||
|
||||
const char *plaintext = "Rossetta Code";
|
||||
mpz_import(pt, strlen(plaintext), 1, 1, 0, 0, plaintext);
|
||||
|
||||
if (mpz_cmp(pt, n) > 0)
|
||||
abort();
|
||||
|
||||
mpz_powm(ct, pt, e, n);
|
||||
gmp_printf("Encoded: %Zd\n", ct);
|
||||
|
||||
mpz_powm(pt, ct, d, n);
|
||||
gmp_printf("Decoded: %Zd\n", pt);
|
||||
|
||||
char buffer[64];
|
||||
mpz_export(buffer, NULL, 1, 1, 0, 0, pt);
|
||||
printf("As String: %s\n", buffer);
|
||||
|
||||
mpz_clears(pt, ct, n, e, d, NULL);
|
||||
return 0;
|
||||
}
|
||||
32
Task/RSA-code/Common-Lisp/rsa-code.lisp
Normal file
32
Task/RSA-code/Common-Lisp/rsa-code.lisp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
(defparameter *n* 9516311845790656153499716760847001433441357)
|
||||
(defparameter *e* 65537)
|
||||
(defparameter *d* 5617843187844953170308463622230283376298685)
|
||||
|
||||
;; magic
|
||||
(defun encode-string (message)
|
||||
(parse-integer (reduce #'(lambda (x y) (concatenate 'string x y))
|
||||
(loop for c across message collect (format nil "~2,'0d" (- (char-code c) 32))))))
|
||||
|
||||
;; sorcery
|
||||
(defun decode-string (message) (coerce (loop for (a b) on
|
||||
(loop for char across (write-to-string message) collect char)
|
||||
by #'cddr collect (code-char (+ (parse-integer (coerce (list a b) 'string)) 32))) 'string))
|
||||
|
||||
;; ACTUAL RSA ALGORITHM STARTS HERE ;;
|
||||
|
||||
;; fast modular exponentiation: runs in O(log exponent)
|
||||
;; acc is initially 1 and contains the result by the end
|
||||
(defun mod-exp (base exponent modulus acc)
|
||||
(if (= exponent 0) acc
|
||||
(mod-exp (mod (* base base) modulus) (ash exponent -1) modulus
|
||||
(if (= (mod exponent 2) 1) (mod (* acc base) modulus) acc))))
|
||||
|
||||
;; to encode a message, we first convert it to its integer form.
|
||||
;; then, we raise it to the *e* power, modulo *n*
|
||||
(defun encode-rsa (message)
|
||||
(mod-exp (encode-string message) *e* *n* 1))
|
||||
|
||||
;; to decode a message, we raise it to *d* power, modulo *n*
|
||||
;; and then convert it back into a string
|
||||
(defun decode-rsa (message)
|
||||
(decode-string (mod-exp message *d* *n* 1)))
|
||||
35
Task/RSA-code/D/rsa-code.d
Normal file
35
Task/RSA-code/D/rsa-code.d
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
void main() {
|
||||
import std.stdio, std.bigint, std.algorithm, std.string, std.range,
|
||||
modular_exponentiation;
|
||||
|
||||
immutable txt = "Rosetta Code";
|
||||
writeln("Plain text: ", txt);
|
||||
|
||||
// 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.
|
||||
immutable BigInt n = "2463574872878749457479".BigInt *
|
||||
"3862806018422572001483".BigInt;
|
||||
immutable BigInt e = 2 ^^ 16 + 1;
|
||||
immutable BigInt d = "5617843187844953170308463622230283376298685";
|
||||
|
||||
// Convert plain text to a number.
|
||||
immutable txtN = reduce!q{ (a << 8) | uint(b) }(0.BigInt, txt);
|
||||
if (txtN >= n)
|
||||
return writeln("Plain text message too long.");
|
||||
writeln("Plain text as a number: ", txtN);
|
||||
|
||||
// Encode a single number.
|
||||
immutable enc = txtN.powMod(e, n);
|
||||
writeln("Encoded: ", enc);
|
||||
|
||||
// Decode a single number.
|
||||
auto dec = enc.powMod(d, n);
|
||||
writeln("Decoded: ", dec);
|
||||
|
||||
// Convert number to text.
|
||||
char[] decTxt;
|
||||
for (; dec; dec >>= 8)
|
||||
decTxt ~= (dec & 0xff).toInt;
|
||||
writeln("Decoded number as text: ", decTxt.retro);
|
||||
}
|
||||
145
Task/RSA-code/Delphi/rsa-code.delphi
Normal file
145
Task/RSA-code/Delphi/rsa-code.delphi
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
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.
|
||||
103
Task/RSA-code/Erlang/rsa-code.erl
Normal file
103
Task/RSA-code/Erlang/rsa-code.erl
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
%%% @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)).
|
||||
9
Task/RSA-code/F-Sharp/rsa-code.fs
Normal file
9
Task/RSA-code/F-Sharp/rsa-code.fs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
//Nigel Galloway February 12th., 2018
|
||||
let RSA n g l = bigint.ModPow(l,n,g)
|
||||
let encrypt = RSA 65537I 9516311845790656153499716760847001433441357I
|
||||
let m_in = System.Text.Encoding.ASCII.GetBytes "The magic words are SQUEAMISH OSSIFRAGE"|>Array.chunkBySize 16|>Array.map(Array.fold(fun n g ->(n*256I)+(bigint(int g))) 0I)
|
||||
let n = Array.map encrypt m_in
|
||||
let decrypt = RSA 5617843187844953170308463622230283376298685I 9516311845790656153499716760847001433441357I
|
||||
let g = Array.map decrypt n
|
||||
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
|
||||
44
Task/RSA-code/FreeBASIC/rsa-code.basic
Normal file
44
Task/RSA-code/FreeBASIC/rsa-code.basic
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
' version 17-01-2017
|
||||
' compile with: fbc -s console
|
||||
|
||||
#Include Once "gmp.bi"
|
||||
|
||||
Dim As Mpz_ptr e, d, n, pt, ct
|
||||
|
||||
e = Allocate(Len(__mpz_struct))
|
||||
d = Allocate(Len(__mpz_struct))
|
||||
n = Allocate(Len(__mpz_struct))
|
||||
pt = Allocate(Len(__mpz_struct)) : mpz_init(pt)
|
||||
ct = Allocate(Len(__mpz_struct)) : mpz_init(ct)
|
||||
|
||||
mpz_init_set_str(e, "65537", 10)
|
||||
mpz_init_set_str(d, "5617843187844953170308463622230283376298685", 10)
|
||||
mpz_init_set_str(n, "9516311845790656153499716760847001433441357", 10)
|
||||
|
||||
Dim As ZString Ptr plaintext : plaintext = Allocate(1000)
|
||||
Dim As ZString Ptr text : text = Allocate(1000)
|
||||
*plaintext = "Rosetta Code"
|
||||
|
||||
mpz_import(pt, Len(*plaintext), 1, 1, 0, 0, plaintext)
|
||||
|
||||
If mpz_cmp(pt, n) > 0 Then GoTo clean_up
|
||||
|
||||
mpz_powm(ct, pt, e, n)
|
||||
gmp_printf(!" Encoded: %Zd\n", ct)
|
||||
|
||||
mpz_powm(pt, ct, d, n)
|
||||
gmp_printf(!" Decoded: %Zd\n", pt)
|
||||
|
||||
mpz_export(text, NULL, 1, 1, 0, 0, pt)
|
||||
Print "As string: "; *text
|
||||
|
||||
clean_up:
|
||||
DeAllocate(plaintext) : DeAllocate(text)
|
||||
mpz_clear(e) : mpz_clear(d) : mpz_clear(n)
|
||||
mpz_clear(pt) : mpz_clear(ct)
|
||||
|
||||
' empty keyboard buffer
|
||||
While Inkey <> "" : Wend
|
||||
Print : Print "hit any key to end program"
|
||||
Sleep
|
||||
End
|
||||
48
Task/RSA-code/Go/rsa-code.go
Normal file
48
Task/RSA-code/Go/rsa-code.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var n, e, d, bb, ptn, etn, dtn big.Int
|
||||
pt := "Rosetta Code"
|
||||
fmt.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.SetString("9516311845790656153499716760847001433441357", 10)
|
||||
e.SetString("65537", 10)
|
||||
d.SetString("5617843187844953170308463622230283376298685", 10)
|
||||
|
||||
// convert plain text to a number
|
||||
for _, b := range []byte(pt) {
|
||||
ptn.Or(ptn.Lsh(&ptn, 8), bb.SetInt64(int64(b)))
|
||||
}
|
||||
if ptn.Cmp(&n) >= 0 {
|
||||
fmt.Println("Plain text message too long")
|
||||
return
|
||||
}
|
||||
fmt.Println("Plain text as a number:", &ptn)
|
||||
|
||||
// encode a single number
|
||||
etn.Exp(&ptn, &e, &n)
|
||||
fmt.Println("Encoded: ", &etn)
|
||||
|
||||
// decode a single number
|
||||
dtn.Exp(&etn, &d, &n)
|
||||
fmt.Println("Decoded: ", &dtn)
|
||||
|
||||
// convert number to text
|
||||
var db [16]byte
|
||||
dx := 16
|
||||
bff := big.NewInt(0xff)
|
||||
for dtn.BitLen() > 0 {
|
||||
dx--
|
||||
db[dx] = byte(bb.And(&dtn, bff).Int64())
|
||||
dtn.Rsh(&dtn, 8)
|
||||
}
|
||||
fmt.Println("Decoded number as text:", string(db[dx:]))
|
||||
}
|
||||
46
Task/RSA-code/Haskell/rsa-code.hs
Normal file
46
Task/RSA-code/Haskell/rsa-code.hs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
module RSAMaker
|
||||
where
|
||||
import Data.Char ( chr )
|
||||
|
||||
encode :: String -> [Integer]
|
||||
encode s = map (toInteger . fromEnum ) s
|
||||
|
||||
rsa_encode :: Integer -> Integer -> [Integer] -> [Integer]
|
||||
rsa_encode n e numbers = map (\num -> mod ( num ^ e ) n ) numbers
|
||||
|
||||
rsa_decode :: Integer -> Integer -> [Integer] -> [Integer]
|
||||
rsa_decode d n ciphers = map (\c -> mod ( c ^ d ) n ) ciphers
|
||||
|
||||
decode :: [Integer] -> String
|
||||
decode encoded = map ( chr . fromInteger ) encoded
|
||||
|
||||
divisors :: Integer -> [Integer]
|
||||
divisors n = [m | m <- [1..n] , mod n m == 0 ]
|
||||
|
||||
isPrime :: Integer -> Bool
|
||||
isPrime n = divisors n == [1,n]
|
||||
|
||||
totient :: Integer -> Integer -> Integer
|
||||
totient prime1 prime2 = (prime1 - 1 ) * ( prime2 - 1 )
|
||||
|
||||
myE :: Integer -> Integer
|
||||
myE tot = head [n | n <- [2..tot - 1] , gcd n tot == 1]
|
||||
|
||||
myD :: Integer -> Integer -> Integer -> Integer
|
||||
myD e n phi = head [d | d <- [1..n] , mod ( d * e ) phi == 1]
|
||||
|
||||
main = do
|
||||
putStrLn "Enter a test text!"
|
||||
text <- getLine
|
||||
let primes = take 90 $ filter isPrime [1..]
|
||||
p1 = last primes
|
||||
p2 = last $ init primes
|
||||
tot = totient p1 p2
|
||||
e = myE tot
|
||||
n = p1 * p2
|
||||
rsa_encoded = rsa_encode n e $ encode text
|
||||
d = myD e n tot
|
||||
encrypted = concatMap show rsa_encoded
|
||||
decrypted = decode $ rsa_decode d n rsa_encoded
|
||||
putStrLn ("Encrypted: " ++ encrypted )
|
||||
putStrLn ("And now decrypted: " ++ decrypted )
|
||||
65
Task/RSA-code/Icon/rsa-code.icon
Normal file
65
Task/RSA-code/Icon/rsa-code.icon
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
procedure main() # rsa demonstration
|
||||
|
||||
n := 9516311845790656153499716760847001433441357
|
||||
e := 65537
|
||||
d := 5617843187844953170308463622230283376298685
|
||||
b := 2^integer(log(n,2)) # for blocking
|
||||
write("RSA Demo using\n n = ",n,"\n e = ",e,"\n d = ",d,"\n b = ",b)
|
||||
|
||||
every m := !["Rosetta Code", "Hello Word!",
|
||||
"This message is too long.", repl("x",*decode(n+1))] do {
|
||||
write("\nMessage = ",image(m))
|
||||
write( "Encoded = ",m := encode(m))
|
||||
if m := rsa(m,e,n) then { # unblocked
|
||||
write( "Encrypt = ",m)
|
||||
write( "Decrypt = ",m := rsa(m,d,n))
|
||||
}
|
||||
else { # blocked
|
||||
every put(C := [], rsa(!block(m,b),e,n))
|
||||
writes("Encrypt = ") ; every writes(!C," ") ; write()
|
||||
every put(P := [], rsa(!C,d,n))
|
||||
writes("Decrypt = ") ; every writes(!P," ") ; write()
|
||||
write("Unblocked = ",m := unblock(P,b))
|
||||
}
|
||||
write( "Decoded = ",image(decode(m)))
|
||||
}
|
||||
end
|
||||
|
||||
procedure mod_power(base, exponent, modulus) # fast modular exponentation
|
||||
result := 1
|
||||
while exponent > 0 do {
|
||||
if exponent % 2 = 1 then
|
||||
result := (result * base) % modulus
|
||||
exponent /:= 2
|
||||
base := base ^ 2 % modulus
|
||||
}
|
||||
return result
|
||||
end
|
||||
|
||||
procedure rsa(text,e,n) # return rsa encryption of numerically encoded message; fail if text < n
|
||||
return mod_power(text,e,text < n)
|
||||
end
|
||||
|
||||
procedure encode(text) # numerically encode ascii text as int
|
||||
every (message := 0) := ord(!text) + 256 * message
|
||||
return message
|
||||
end
|
||||
|
||||
procedure decode(message) # numerically decode int to ascii text
|
||||
text := ""
|
||||
while text ||:= char((0 < message) % 256) do
|
||||
message /:= 256
|
||||
return reverse(text)
|
||||
end
|
||||
|
||||
procedure block(m,b) # break lg int into blocks of size b
|
||||
M := []
|
||||
while push(M, x := (0 < m) % b) do
|
||||
m /:= b
|
||||
return M
|
||||
end
|
||||
|
||||
procedure unblock(M,b) # reassemble blocks of size b into lg int
|
||||
every (m := 0) := !M + b * m
|
||||
return m
|
||||
end
|
||||
16
Task/RSA-code/J/rsa-code.j
Normal file
16
Task/RSA-code/J/rsa-code.j
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
N=: 9516311845790656153499716760847001433441357x
|
||||
E=: 65537x
|
||||
D=: 5617843187844953170308463622230283376298685x
|
||||
|
||||
] text=: 'Rosetta Code'
|
||||
Rosetta Code
|
||||
] num=: 256x #. a.i.text
|
||||
25512506514985639724585018469
|
||||
num >: N NB. check if blocking is necessary (0 means no)
|
||||
0
|
||||
] enc=: N&|@^&E num
|
||||
916709442744356653386978770799029131264344
|
||||
] dec=: N&|@^&D enc
|
||||
25512506514985639724585018469
|
||||
] final=: a. {~ 256x #.inv dec
|
||||
Rosetta Code
|
||||
27
Task/RSA-code/Java/rsa-code-1.java
Normal file
27
Task/RSA-code/Java/rsa-code-1.java
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
public static void main(String[] args) {
|
||||
/*
|
||||
This is probably not the best method...or even the most optimized way...however it works since n and d are too big to be ints or longs
|
||||
This was also only tested with 'Rosetta Code' and 'Hello World'
|
||||
It's also pretty limited on plainText size (anything bigger than the above will fail)
|
||||
*/
|
||||
BigInteger n = new BigInteger("9516311845790656153499716760847001433441357");
|
||||
BigInteger e = new BigInteger("65537");
|
||||
BigInteger d = new BigInteger("5617843187844953170308463622230283376298685");
|
||||
Charset c = Charsets.UTF_8;
|
||||
String plainText = "Rosetta Code";
|
||||
System.out.println("PlainText : " + plainText);
|
||||
byte[] bytes = plainText.getBytes();
|
||||
BigInteger plainNum = new BigInteger(bytes);
|
||||
System.out.println("As number : " + plainNum);
|
||||
BigInteger Bytes = new BigInteger(bytes);
|
||||
if (Bytes.compareTo(n) == 1) {
|
||||
System.out.println("Plaintext is too long");
|
||||
return;
|
||||
}
|
||||
BigInteger enc = plainNum.modPow(e, n);
|
||||
System.out.println("Encoded: " + enc);
|
||||
BigInteger dec = enc.modPow(d, n);
|
||||
System.out.println("Decoded: " + dec);
|
||||
String decText = new String(dec.toByteArray(), c);
|
||||
System.out.println("As text: " + decText);
|
||||
}
|
||||
36
Task/RSA-code/Java/rsa-code-2.java
Normal file
36
Task/RSA-code/Java/rsa-code-2.java
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
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()));
|
||||
}
|
||||
}
|
||||
64
Task/RSA-code/Jq/rsa-code.jq
Normal file
64
Task/RSA-code/Jq/rsa-code.jq
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# 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!!!!")
|
||||
18
Task/RSA-code/Julia/rsa-code.julia
Normal file
18
Task/RSA-code/Julia/rsa-code.julia
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
function rsaencode(clearmsg::AbstractString, nmod::Integer, expub::Integer)
|
||||
bytes = parse(BigInt, "0x" * bytes2hex(collect(UInt8, clearmsg)))
|
||||
return powermod(bytes, expub, nmod)
|
||||
end
|
||||
|
||||
function rsadecode(cryptmsg::Integer, nmod::Integer, dsecr::Integer)
|
||||
decoded = powermod(encoded, dsecr, nmod)
|
||||
return join(Char.(hex2bytes(hex(decoded))))
|
||||
end
|
||||
|
||||
msg = "Rosetta Code."
|
||||
nmod = big"9516311845790656153499716760847001433441357"
|
||||
expub = 65537
|
||||
dsecr = big"5617843187844953170308463622230283376298685"
|
||||
|
||||
encoded = rsaencode(msg, nmod, expub)
|
||||
decoded = rsadecode(encoded, nmod, dsecr)
|
||||
println("\n# $msg\n -> ENCODED: $encoded\n -> DECODED: $decoded")
|
||||
28
Task/RSA-code/Kotlin/rsa-code.kotlin
Normal file
28
Task/RSA-code/Kotlin/rsa-code.kotlin
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// version 1.1.4-3
|
||||
|
||||
import java.math.BigInteger
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val n = BigInteger("9516311845790656153499716760847001433441357")
|
||||
val e = BigInteger("65537")
|
||||
val d = BigInteger("5617843187844953170308463622230283376298685")
|
||||
val c = Charsets.UTF_8
|
||||
val plainText = "Rosetta Code"
|
||||
println("PlainText : $plainText")
|
||||
val bytes = plainText.toByteArray(c)
|
||||
val plainNum = BigInteger(bytes)
|
||||
println("As number : $plainNum")
|
||||
if (plainNum > n) {
|
||||
println("Plaintext is too long")
|
||||
return
|
||||
}
|
||||
|
||||
val enc = plainNum.modPow(e, n)
|
||||
println("Encoded : $enc")
|
||||
|
||||
val dec = enc.modPow(d, n)
|
||||
println("Decoded : $dec")
|
||||
|
||||
val decText = dec.toByteArray().toString(c)
|
||||
println("As text : $decText")
|
||||
}
|
||||
20
Task/RSA-code/Mathematica/rsa-code.math
Normal file
20
Task/RSA-code/Mathematica/rsa-code.math
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
toNumPlTxt[s_] := FromDigits[ToCharacterCode[s], 256];
|
||||
fromNumPlTxt[plTxt_] := FromCharacterCode[IntegerDigits[plTxt, 256]];
|
||||
enc::longmess = "Message '``' is too long for n = ``.";
|
||||
enc[n_, _, mess_] /;
|
||||
toNumPlTxt[mess] >= n := (Message[enc::longmess, mess, n]; $Failed);
|
||||
enc[n_, e_, mess_] := PowerMod[toNumPlTxt[mess], e, n];
|
||||
dec[n_, d_, en_] := fromNumPlTxt[PowerMod[en, d, n]];
|
||||
text = "The cake is a lie!";
|
||||
n = 9516311845790656153499716760847001433441357;
|
||||
e = 65537;
|
||||
d = 5617843187844953170308463622230283376298685;
|
||||
en = enc[n, e, text];
|
||||
de = dec[n, d, en];
|
||||
Print["Text: '" <> text <> "'"];
|
||||
Print["n = " <> IntegerString[n]];
|
||||
Print["e = " <> IntegerString[e]];
|
||||
Print["d = " <> IntegerString[d]];
|
||||
Print["Numeric plaintext: " <> IntegerString[toNumPlTxt[text]]];
|
||||
Print["Encoded: " <> IntegerString[en]];
|
||||
Print["Decoded: '" <> de <> "'"];
|
||||
50
Task/RSA-code/Nim/rsa-code.nim
Normal file
50
Task/RSA-code/Nim/rsa-code.nim
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
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")
|
||||
12
Task/RSA-code/PARI-GP/rsa-code-1.parigp
Normal file
12
Task/RSA-code/PARI-GP/rsa-code-1.parigp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
stigid(V,b)=subst(Pol(V),'x,b); \\ inverse function digits(...)
|
||||
|
||||
n = 9516311845790656153499716760847001433441357;
|
||||
e = 65537;
|
||||
d = 5617843187844953170308463622230283376298685;
|
||||
|
||||
text = "Rosetta Code"
|
||||
|
||||
inttext = stigid(Vecsmall(text),256) \\ message as an integer
|
||||
encoded = lift(Mod(inttext, n) ^ e) \\ encrypted message
|
||||
decoded = lift(Mod(encoded, n) ^ d) \\ decrypted message
|
||||
message = Strchr(digits(decoded, 256)) \\ readable message
|
||||
3
Task/RSA-code/PARI-GP/rsa-code-2.parigp
Normal file
3
Task/RSA-code/PARI-GP/rsa-code-2.parigp
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
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))
|
||||
63
Task/RSA-code/Perl/rsa-code.pl
Normal file
63
Task/RSA-code/Perl/rsa-code.pl
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
use bigint;
|
||||
|
||||
$n = 9516311845790656153499716760847001433441357;
|
||||
$e = 65537;
|
||||
$d = 5617843187844953170308463622230283376298685;
|
||||
|
||||
package Message {
|
||||
my @alphabet;
|
||||
push @alphabet, $_ for 'A' .. 'Z', ' ';
|
||||
my $rad = +@alphabet;
|
||||
$code{$alphabet[$_]} = $_ for 0..$rad-1;
|
||||
|
||||
sub encode {
|
||||
my($t) = @_;
|
||||
my $cnt = my $sum = 0;
|
||||
for (split '', reverse $t) {
|
||||
$sum += $code{$_} * $rad**$cnt;
|
||||
$cnt++;
|
||||
}
|
||||
$sum;
|
||||
}
|
||||
|
||||
sub decode {
|
||||
my($n) = @_;
|
||||
my(@i);
|
||||
while () {
|
||||
push @i, $n % $rad;
|
||||
last if $n < $rad;
|
||||
$n = int $n / $rad;
|
||||
}
|
||||
reverse join '', @alphabet[@i];
|
||||
}
|
||||
|
||||
sub expmod {
|
||||
my($a, $b, $n) = @_;
|
||||
my $c = 1;
|
||||
do {
|
||||
($c *= $a) %= $n if $b % 2;
|
||||
($a *= $a) %= $n;
|
||||
} while ($b = int $b/2);
|
||||
$c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
my $secret_message = "ROSETTA CODE";
|
||||
|
||||
$numeric_message = Message::encode $secret_message;
|
||||
$numeric_cipher = Message::expmod $numeric_message, $e, $n;
|
||||
$text_cipher = Message::decode $numeric_cipher;
|
||||
$numeric_cipher2 = Message::encode $text_cipher;
|
||||
$numeric_message2 = Message::expmod $numeric_cipher2, $d, $n;
|
||||
$secret_message2 = Message::decode $numeric_message2;
|
||||
|
||||
print <<"EOT";
|
||||
Secret message is $secret_message
|
||||
Secret message in integer form is $numeric_message
|
||||
After exponentiation with public exponent we get: $numeric_cipher
|
||||
This turns into the string $text_cipher
|
||||
If we re-encode it in integer form we get $numeric_cipher2
|
||||
After exponentiation with SECRET exponent we get: $numeric_message2
|
||||
This turns into the string $secret_message2
|
||||
EOT
|
||||
32
Task/RSA-code/Phix/rsa-code.phix
Normal file
32
Task/RSA-code/Phix/rsa-code.phix
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
(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>
|
||||
<!--
|
||||
116
Task/RSA-code/PicoLisp/rsa-code.l
Normal file
116
Task/RSA-code/PicoLisp/rsa-code.l
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
### This is a copy of "lib/rsa.l" ###
|
||||
|
||||
# Generate long random number
|
||||
(de longRand (N)
|
||||
(use (R D)
|
||||
(while (=0 (setq R (abs (rand)))))
|
||||
(until (> R N)
|
||||
(unless (=0 (setq D (abs (rand))))
|
||||
(setq R (* R D)) ) )
|
||||
(% R N) ) )
|
||||
|
||||
# X power Y modulus N
|
||||
(de **Mod (X Y N)
|
||||
(let M 1
|
||||
(loop
|
||||
(when (bit? 1 Y)
|
||||
(setq M (% (* M X) N)) )
|
||||
(T (=0 (setq Y (>> 1 Y)))
|
||||
M )
|
||||
(setq X (% (* X X) N)) ) ) )
|
||||
|
||||
# Probabilistic prime check
|
||||
(de prime? (N)
|
||||
(and
|
||||
(> N 1)
|
||||
(bit? 1 N)
|
||||
(let (Q (dec N) K 0)
|
||||
(until (bit? 1 Q)
|
||||
(setq
|
||||
Q (>> 1 Q)
|
||||
K (inc K) ) )
|
||||
(do 50
|
||||
(NIL (_prim? N Q K))
|
||||
T ) ) ) )
|
||||
|
||||
# (Knuth Vol.2, p.379)
|
||||
(de _prim? (N Q K)
|
||||
(use (X J Y)
|
||||
(while (> 2 (setq X (longRand N))))
|
||||
(setq
|
||||
J 0
|
||||
Y (**Mod X Q N) )
|
||||
(loop
|
||||
(T
|
||||
(or
|
||||
(and (=0 J) (= 1 Y))
|
||||
(= Y (dec N)) )
|
||||
T )
|
||||
(T
|
||||
(or
|
||||
(and (> J 0) (= 1 Y))
|
||||
(<= K (inc 'J)) )
|
||||
NIL )
|
||||
(setq Y (% (* Y Y) N)) ) ) )
|
||||
|
||||
# Find a prime number with `Len' digits
|
||||
(de prime (Len)
|
||||
(let P (longRand (** 10 (*/ Len 2 3)))
|
||||
(unless (bit? 1 P)
|
||||
(inc 'P) )
|
||||
(until (prime? P) # P: Prime number of size 2/3 Len
|
||||
(inc 'P 2) )
|
||||
# R: Random number of size 1/3 Len
|
||||
(let (R (longRand (** 10 (/ Len 3))) K (+ R (% (- P R) 3)))
|
||||
(when (bit? 1 K)
|
||||
(inc 'K 3) )
|
||||
(until (prime? (setq R (inc (* K P))))
|
||||
(inc 'K 6) )
|
||||
R ) ) )
|
||||
|
||||
# Generate RSA key
|
||||
(de rsaKey (N) #> (Encrypt . Decrypt)
|
||||
(let (P (prime (*/ N 5 10)) Q (prime (*/ N 6 10)))
|
||||
(cons
|
||||
(* P Q)
|
||||
(/
|
||||
(inc (* 2 (dec P) (dec Q)))
|
||||
3 ) ) ) )
|
||||
|
||||
# Encrypt a list of characters
|
||||
(de encrypt (Key Lst)
|
||||
(let Siz (>> 1 (size Key))
|
||||
(make
|
||||
(while Lst
|
||||
(let N (char (pop 'Lst))
|
||||
(while (> Siz (size N))
|
||||
(setq N (>> -16 N))
|
||||
(inc 'N (char (pop 'Lst))) )
|
||||
(link (**Mod N 3 Key)) ) ) ) ) )
|
||||
|
||||
# Decrypt a list of numbers
|
||||
(de decrypt (Keys Lst)
|
||||
(mapcan
|
||||
'((N)
|
||||
(let Res NIL
|
||||
(setq N (**Mod N (cdr Keys) (car Keys)))
|
||||
(until (=0 N)
|
||||
(push 'Res (char (& `(dec (** 2 16)) N)))
|
||||
(setq N (>> 16 N)) )
|
||||
Res ) )
|
||||
Lst ) )
|
||||
### End of "lib/rsa.l" ###
|
||||
|
||||
# Generate 100-digit keys (private . public)
|
||||
: (setq Keys (rsaKey 100))
|
||||
-> (14394597526321726957429995133376978449624406217727317004742182671030....
|
||||
|
||||
# Encrypt
|
||||
: (setq CryptText
|
||||
(encrypt (car Keys)
|
||||
(chop "The quick brown fox jumped over the lazy dog's back") ) )
|
||||
-> (72521958974980041245760752728037044798830723189142175108602418861716...
|
||||
|
||||
# Decrypt
|
||||
: (pack (decrypt Keys CryptText))
|
||||
-> "The quick brown fox jumped over the lazy dog's back"
|
||||
13
Task/RSA-code/PowerShell/rsa-code.psh
Normal file
13
Task/RSA-code/PowerShell/rsa-code.psh
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
$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"
|
||||
25
Task/RSA-code/Python/rsa-code.py
Normal file
25
Task/RSA-code/Python/rsa-code.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import binascii
|
||||
|
||||
n = 9516311845790656153499716760847001433441357 # p*q = modulus
|
||||
e = 65537
|
||||
d = 5617843187844953170308463622230283376298685
|
||||
|
||||
message='Rosetta Code!'
|
||||
print('message ', message)
|
||||
|
||||
hex_data = binascii.hexlify(message.encode())
|
||||
print('hex data ', hex_data)
|
||||
|
||||
plain_text = int(hex_data, 16)
|
||||
print('plain text integer ', plain_text)
|
||||
|
||||
if plain_text > n:
|
||||
raise Exception('plain text too large for key')
|
||||
|
||||
encrypted_text = pow(plain_text, e, n)
|
||||
print('encrypted text integer ', encrypted_text)
|
||||
|
||||
decrypted_text = pow(encrypted_text, d, n)
|
||||
print('decrypted text integer ', decrypted_text)
|
||||
|
||||
print('message ', binascii.unhexlify(hex(decrypted_text)[2:]).decode()) # [2:] slicing, to strip the 0x part
|
||||
172
Task/RSA-code/Racket/rsa-code.rkt
Normal file
172
Task/RSA-code/Racket/rsa-code.rkt
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
#lang racket
|
||||
(require math/number-theory)
|
||||
(define-logger rsa)
|
||||
(current-logger rsa-logger)
|
||||
|
||||
;; -| STRING TO NUMBER MAPPING |----------------------------------------------------------------------
|
||||
(define (bytes->number B) ; We'll need our data in numerical form ..
|
||||
(for/fold ((rv 0)) ((b B)) (+ b (* rv 256))))
|
||||
|
||||
(define (number->bytes N) ; .. and back again
|
||||
(define (inr n b) (if (zero? n) b (inr (quotient n 256) (bytes-append (bytes (modulo n 256)) b))))
|
||||
(inr N (bytes)))
|
||||
|
||||
;; -| RSA PUBLIC / PRIVATE FUNCTIONS |----------------------------------------------------------------
|
||||
;; The basic definitions... pretty well lifted from the text book!
|
||||
(define ((C e n) p)
|
||||
;; Just do the arithmetic to demonstrate RSA...
|
||||
;; breaking large messages into blocks is something for another day.
|
||||
(unless (< p n) (raise-argument-error 'C (format "(and/c integer? (</c ~a))" n) p))
|
||||
(modular-expt p e n))
|
||||
|
||||
(define ((P d n) c)
|
||||
(modular-expt c d n))
|
||||
|
||||
;; -| RSA KEY GENERATION |----------------------------------------------------------------------------
|
||||
;; Key generation
|
||||
;; Full description of the steps can be found on Wikipedia
|
||||
(define (RSA-keyset function-base-name)
|
||||
(log-info "RSA-keyset: ~s" function-base-name)
|
||||
(define max-k 4294967087)
|
||||
;; I'm guessing this RNG is about as cryptographically strong as replacing spaces with tabs.
|
||||
(define (big-random n-rolls)
|
||||
(for/fold ((rv 1)) ((roll (in-range n-rolls 0 -1))) (+ (* rv (add1 max-k)) 1 (random max-k))))
|
||||
(define (big-random-prime)
|
||||
(define start-number (big-random (/ 1024 32)))
|
||||
(log-debug "got large (possibly non-prime) number, finding next prime")
|
||||
(next-prime (match start-number ((? odd? o) o) ((app add1 e) e))))
|
||||
|
||||
;; [1] Choose two distinct prime numbers p and q.
|
||||
(log-debug "generating p")
|
||||
(define p (big-random-prime))
|
||||
(log-debug "p generated")
|
||||
(log-debug "generating q")
|
||||
(define q (big-random-prime))
|
||||
(log-debug "q generated")
|
||||
(log-info "primes generated")
|
||||
|
||||
;; [2] Compute n = pq.
|
||||
(define n (* p q))
|
||||
|
||||
;; [3] Compute φ(n) = φ(p)φ(q) = (p − 1)(q − 1) = n - (p + q -1),
|
||||
;; where φ is Euler's totient function.
|
||||
(define φ (- n (+ p q -1)))
|
||||
|
||||
;; [4] Choose an integer e such that 1 < e < φ(n) and gcd(e, φ(n)) = 1; i.e., e and φ(n) are
|
||||
;; coprime. ... most commonly 2^16 + 1 = 65,537 ...
|
||||
(define e (+ (expt 2 16) 1))
|
||||
|
||||
;; [5] Determine d as d ≡ e−1 (mod φ(n)); i.e., d is the multiplicative inverse of e (modulo φ(n)).
|
||||
(log-debug "generating d")
|
||||
(define d (modular-inverse e φ))
|
||||
(log-info "d generated")
|
||||
(values n e d))
|
||||
|
||||
;; -| GIVE A USABLE SET OF PRIVATE STUFF TO A USER |--------------------------------------------------
|
||||
;; six values: the public (encrypt) function (numeric)
|
||||
;; the private (decrypt) function (numeric)
|
||||
;; the public (encrypt) function (bytes)
|
||||
;; the private (decrypt) function (bytes)
|
||||
;; private (list n e d)
|
||||
;; public (list n e)
|
||||
(define (RSA-key-pack #:function-base-name function-base-name)
|
||||
(define (rnm-fn f s) (procedure-rename f (string->symbol (format "~a-~a" function-base-name s))))
|
||||
(define-values (n e d) (RSA-keyset function-base-name))
|
||||
(define my-C (rnm-fn (C e n) "C"))
|
||||
(define my-P (rnm-fn (P d n) "P"))
|
||||
(define my-encrypt (rnm-fn (compose number->bytes my-C bytes->number) "encrypt"))
|
||||
(define my-decrypt (rnm-fn (compose number->bytes my-P bytes->number) "decrypt"))
|
||||
(values my-C my-P my-encrypt my-decrypt (list n e d) (list n e)))
|
||||
|
||||
;; -| HEREON IS JUST A LOAD OF CHATTY DEMOS |---------------------------------------------------------
|
||||
(define (narrated-encrypt-bytes C who plain-text)
|
||||
(define plain-n (bytes->number plain-text))
|
||||
(define cypher-n (C plain-n))
|
||||
(define cypher-text (number->bytes cypher-n))
|
||||
(printf #<<EOS
|
||||
~a wants to send plain text: ~s
|
||||
as number: ~s
|
||||
cyphered number: ~s
|
||||
sent by ~a over the public interwebs:
|
||||
~s
|
||||
...
|
||||
|
||||
|
||||
EOS
|
||||
who plain-text plain-n cypher-n who cypher-text)
|
||||
cypher-text)
|
||||
|
||||
(define (narrated-decrypt-bytes P who cypher-text)
|
||||
(define cypher-n (bytes->number cypher-text))
|
||||
(define plain-n (P cypher-n))
|
||||
(define plain-text (number->bytes plain-n))
|
||||
(printf #<<EOS
|
||||
...
|
||||
~s
|
||||
received by ~a
|
||||
as number: ~s
|
||||
decyphered (with P) number: ~s
|
||||
decyphered text:
|
||||
~s
|
||||
|
||||
|
||||
EOS
|
||||
cypher-text who cypher-n plain-n plain-text)
|
||||
plain-text)
|
||||
|
||||
;; ENCRYPT AND DECRYPT A MESSAGE WITH THE e.g. KEYS
|
||||
(define-values (given-n given-e given-d)
|
||||
(values 9516311845790656153499716760847001433441357
|
||||
65537
|
||||
5617843187844953170308463622230283376298685))
|
||||
|
||||
;; Get the keys specific RSA functions
|
||||
(for ((message-text (list #"hello world" #"TOP SECRET!")))
|
||||
(define Bobs-public-function (C given-e given-n))
|
||||
(define Bobs-private-function (P given-d given-n))
|
||||
(define cypher-text (narrated-encrypt-bytes Bobs-public-function "Alice" message-text))
|
||||
(define plain-text (narrated-decrypt-bytes Bobs-private-function "Bob" cypher-text))
|
||||
plain-text)
|
||||
|
||||
;; Demonstrate with larger keys.
|
||||
;; (And include a free recap on digital signatures, too)
|
||||
(define-values (A-pub-C A-pvt-P A-pub-encrypt A-pvt-decrypt A-pvt-keys A-pub-keys)
|
||||
(RSA-key-pack #:function-base-name 'Alice))
|
||||
(define-values (B-pub-C B-pvt-P B-pub-encrypt B-pvt-decrypt B-pvt-keys B-pub-keys)
|
||||
(RSA-key-pack #:function-base-name 'Bob))
|
||||
|
||||
;; Since p and q are random, it is possible that message' = "message modulo {A,B}-key-n" will be too
|
||||
;; big for "message' modulo {B,A}-key-n", if that happens then I run the program again until it
|
||||
;; works. Strictly, we need blocking of the signed message -- which is not yet implemented.
|
||||
(let* ((plain-A-to-B #"Dear Bob, meet you in Lymm at 1200, Alice")
|
||||
(signed-A-to-B (A-pvt-decrypt plain-A-to-B))
|
||||
(unsigned-A-to-B (A-pub-encrypt signed-A-to-B))
|
||||
(crypt-signed-A-to-B (B-pub-encrypt signed-A-to-B))
|
||||
(decrypt-signed-A-to-B (B-pvt-decrypt crypt-signed-A-to-B))
|
||||
(decrypt-verified-B (A-pub-encrypt decrypt-signed-A-to-B)))
|
||||
(printf
|
||||
#<<EOS
|
||||
Alice wants to send ~s to Bob.
|
||||
She "encrypts" with her private "decryption" key.
|
||||
(A-prv msg) -> ~s
|
||||
Only she could have done this (only she has the her private key data) -- so this is a signature on the
|
||||
message. Anyone can verify the signature by "decrypting" the message with the public "encryption" key.
|
||||
(A-pub (A-prv msg)) -> ~s
|
||||
But anyone is able to do this, so there is no privacy here.
|
||||
Everyone knows that it can only be Alice at Lymm at noon, but this message is for Bob's eyes only.
|
||||
We need to encrypt this with his public key:
|
||||
(B-pub (A-prv msg)) -> ~s
|
||||
Which is what gets posted to alt.chat.secret-rendezvous
|
||||
Bob decrypts this to get the signed message from Alice:
|
||||
(B-prv (B-pub (A-prv msg))) -> ~s
|
||||
And verifies Alice's signature:
|
||||
(A-pub (B-prv (B-pub (A-prv msg)))) -> ~s
|
||||
Alice genuinely sent the message.
|
||||
And nobody else (on a.c.s-r, at least) has read it.
|
||||
|
||||
KEYS:
|
||||
Alice's full set: ~s
|
||||
Bob's full set: ~s
|
||||
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))
|
||||
50
Task/RSA-code/Raku/rsa-code.raku
Normal file
50
Task/RSA-code/Raku/rsa-code.raku
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
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;
|
||||
55
Task/RSA-code/Ruby/rsa-code.rb
Normal file
55
Task/RSA-code/Ruby/rsa-code.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/ruby
|
||||
|
||||
require 'openssl' # for mod_exp only
|
||||
require 'prime'
|
||||
|
||||
def rsa_encode blocks, e, n
|
||||
blocks.map{|b| b.to_bn.mod_exp(e, n).to_i}
|
||||
end
|
||||
|
||||
def rsa_decode ciphers, d, n
|
||||
rsa_encode ciphers, d, n
|
||||
end
|
||||
|
||||
# all numbers in blocks have to be < modulus, or information is lost
|
||||
# for secure encryption only use big modulus and blocksizes
|
||||
def text_to_blocks text, blocksize=64 # 1 hex = 4 bit => default is 256bit
|
||||
text.each_byte.reduce(""){|acc,b| acc << b.to_s(16).rjust(2, "0")} # convert text to hex (preserving leading 0 chars)
|
||||
.each_char.each_slice(blocksize).to_a # slice hexnumbers in pieces of blocksize
|
||||
.map{|a| a.join("").to_i(16)} # convert each slice into internal number
|
||||
end
|
||||
|
||||
def blocks_to_text blocks
|
||||
blocks.map{|d| d.to_s(16)}.join("") # join all blocks into one hex-string
|
||||
.each_char.each_slice(2).to_a # group into pairs
|
||||
.map{|s| s.join("").to_i(16)} # number from 2 hexdigits is byte
|
||||
.flatten.pack("C*") # pack bytes into ruby-string
|
||||
.force_encoding(Encoding::default_external) # reset encoding
|
||||
end
|
||||
|
||||
def generate_keys p1, p2
|
||||
n = p1 * p2
|
||||
t = (p1 - 1) * (p2 - 1)
|
||||
e = 2.step.each do |i|
|
||||
break i if i.gcd(t) == 1
|
||||
end
|
||||
d = 1.step.each do |i|
|
||||
break i if (i * e) % t == 1
|
||||
end
|
||||
return e, d, n
|
||||
end
|
||||
|
||||
p1, p2 = Prime.take(100).last(2)
|
||||
public_key, private_key, modulus =
|
||||
generate_keys p1, p2
|
||||
|
||||
print "Message: "
|
||||
message = gets
|
||||
blocks = text_to_blocks message, 4 # very small primes
|
||||
print "Numbers: "; p blocks
|
||||
encoded = rsa_encode(blocks, public_key, modulus)
|
||||
print "Encrypted as: "; p encoded
|
||||
decoded = rsa_decode(encoded, private_key, modulus)
|
||||
print "Decrypted to: "; p decoded
|
||||
final = blocks_to_text(decoded)
|
||||
print "Decrypted Message: "; puts final
|
||||
53
Task/RSA-code/Rust/rsa-code.rust
Normal file
53
Task/RSA-code/Rust/rsa-code.rust
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
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);
|
||||
}
|
||||
32
Task/RSA-code/Scala/rsa-code.scala
Normal file
32
Task/RSA-code/Scala/rsa-code.scala
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
object RSA_saket{
|
||||
val d = BigInt("5617843187844953170308463622230283376298685")
|
||||
val n = BigInt("9516311845790656153499716760847001433441357")
|
||||
val e = 65537
|
||||
val text = "Rosetta Code"
|
||||
val encode = (msg:BigInt) => pow_mod(msg,e,n)
|
||||
val decode = (msg:BigInt) => pow_mod(msg,d,n)
|
||||
val getmsg = (txt:String) => BigInt(txt.map(x => "%03d".format(x.toInt)).reduceLeft(_+_))
|
||||
def pow_mod(p:BigInt, q:BigInt, n:BigInt):BigInt = {
|
||||
if(q==0) BigInt(1)
|
||||
else if(q==1) p
|
||||
else if(q%2 == 1) pow_mod(p,q-1,n)*p % n
|
||||
else pow_mod(p*p % n,q/2,n)
|
||||
}
|
||||
def gettxt(num:String) = {
|
||||
if(num.size%3==2)
|
||||
("0" + num).grouped(3).toList.foldLeft("")(_ + _.toInt.toChar)
|
||||
else
|
||||
num.grouped(3).toList.foldLeft("")(_ + _.toInt.toChar)
|
||||
}
|
||||
def main(args: Array[String]): Unit = {
|
||||
println(f"Original String \t: "+text)
|
||||
val msg = getmsg(text)
|
||||
println(f"Converted Signal \t: "+msg)
|
||||
val enc_sig = encode(msg)
|
||||
println("Encoded Signal \t\t: "+ enc_sig)
|
||||
val dec_sig = decode(enc_sig)
|
||||
println("Decoded String \t\t: "+ dec_sig)
|
||||
val rec_msg = gettxt(dec_sig.toString)
|
||||
println("Retrieved Signal \t: "+rec_msg)
|
||||
}
|
||||
}
|
||||
30
Task/RSA-code/Seed7/rsa-code.seed7
Normal file
30
Task/RSA-code/Seed7/rsa-code.seed7
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
$ include "seed7_05.s7i";
|
||||
include "bigint.s7i";
|
||||
include "bytedata.s7i";
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
const string: plainText is "Rosetta Code";
|
||||
# Use a key big enough to hold 16 bytes of plain text in a single block.
|
||||
const bigInteger: modulus is 9516311845790656153499716760847001433441357_;
|
||||
const bigInteger: encode is 65537_;
|
||||
const bigInteger: decode is 5617843187844953170308463622230283376298685_;
|
||||
var bigInteger: plainTextNumber is 0_;
|
||||
var bigInteger: encodedNumber is 0_;
|
||||
var bigInteger: decodedNumber is 0_;
|
||||
var string: decodedText is "";
|
||||
begin
|
||||
writeln("Plain text: " <& plainText);
|
||||
plainTextNumber := bytes2BigInt(plainText, UNSIGNED, BE);
|
||||
if plainTextNumber >= modulus then
|
||||
writeln("Plain text message too long");
|
||||
else
|
||||
writeln("Plain text as a number: " <& plainTextNumber);
|
||||
encodedNumber := modPow(plainTextNumber, encode, modulus);
|
||||
writeln("Encoded: " <& encodedNumber);
|
||||
decodedNumber := modPow(encodedNumber, decode, modulus);
|
||||
writeln("Decoded: " <& decodedNumber);
|
||||
decodedText := bytes(decodedNumber, UNSIGNED, BE);
|
||||
writeln("Decoded number as text: " <& decodedText);
|
||||
end if;
|
||||
end func;
|
||||
45
Task/RSA-code/Sidef/rsa-code.sidef
Normal file
45
Task/RSA-code/Sidef/rsa-code.sidef
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
const n = 9516311845790656153499716760847001433441357
|
||||
const e = 65537
|
||||
const d = 5617843187844953170308463622230283376298685
|
||||
|
||||
module Message {
|
||||
var alphabet = [('A' .. 'Z')..., ' ']
|
||||
var rad = alphabet.len
|
||||
var code = Hash(^rad -> map {|i| (alphabet[i], i) }...)
|
||||
func encode(String t) {
|
||||
[code{t.reverse.chars...}] ~Z* t.len.range.map { |i| rad**i } -> sum(0)
|
||||
}
|
||||
func decode(Number n) {
|
||||
''.join(alphabet[
|
||||
gather {
|
||||
loop {
|
||||
var (d, m) = n.divmod(rad)
|
||||
take(m)
|
||||
break if (n < rad)
|
||||
n = d
|
||||
}
|
||||
}...]
|
||||
).reverse
|
||||
}
|
||||
}
|
||||
|
||||
var secret_message = "ROSETTA CODE"
|
||||
say "Secret message is #{secret_message}"
|
||||
|
||||
var numeric_message = Message::encode(secret_message)
|
||||
say "Secret message in integer form is #{numeric_message}"
|
||||
|
||||
var numeric_cipher = expmod(numeric_message, e, n)
|
||||
say "After exponentiation with public exponent we get: #{numeric_cipher}"
|
||||
|
||||
var text_cipher = Message::decode(numeric_cipher)
|
||||
say "This turns into the string #{text_cipher}"
|
||||
|
||||
var numeric_cipher2 = Message::encode(text_cipher)
|
||||
say "If we re-encode it in integer form we get #{numeric_cipher2}"
|
||||
|
||||
var numeric_message2 = expmod(numeric_cipher2, d, n)
|
||||
say "After exponentiation with SECRET exponent we get: #{numeric_message2}"
|
||||
|
||||
var secret_message2 = Message::decode(numeric_message2)
|
||||
say "This turns into the string #{secret_message2}"
|
||||
48
Task/RSA-code/Tcl/rsa-code.tcl
Normal file
48
Task/RSA-code/Tcl/rsa-code.tcl
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package require Tcl 8.5
|
||||
|
||||
# This is a straight-forward square-and-multiply implementation that relies on
|
||||
# Tcl 8.5's bignum support (based on LibTomMath) for speed.
|
||||
proc modexp {b expAndMod} {
|
||||
lassign $expAndMod -> e n
|
||||
if {$b >= $n} {puts stderr "WARNING: modulus too small"}
|
||||
for {set r 1} {$e != 0} {set e [expr {$e >> 1}]} {
|
||||
if {$e & 1} {
|
||||
set r [expr {($r * $b) % $n}]
|
||||
}
|
||||
set b [expr {($b ** 2) % $n}]
|
||||
}
|
||||
return $r
|
||||
}
|
||||
|
||||
# Assumes that messages are shorter than the modulus
|
||||
proc rsa_encrypt {message publicKey} {
|
||||
if {[lindex $publicKey 0] ne "publicKey"} {error "key handling"}
|
||||
set toEnc 0
|
||||
foreach char [split [encoding convertto utf-8 $message] ""] {
|
||||
set toEnc [expr {$toEnc * 256 + [scan $char "%c"]}]
|
||||
}
|
||||
return [modexp $toEnc $publicKey]
|
||||
}
|
||||
|
||||
proc rsa_decrypt {encrypted privateKey} {
|
||||
if {[lindex $privateKey 0] ne "privateKey"} {error "key handling"}
|
||||
set toDec [modexp $encrypted $privateKey]
|
||||
for {set message ""} {$toDec > 0} {set toDec [expr {$toDec >> 8}]} {
|
||||
append message [format "%c" [expr {$toDec & 255}]]
|
||||
}
|
||||
return [encoding convertfrom utf-8 [string reverse $message]]
|
||||
}
|
||||
|
||||
# Assemble packaged public and private keys
|
||||
set e 65537
|
||||
set n 9516311845790656153499716760847001433441357
|
||||
set d 5617843187844953170308463622230283376298685
|
||||
set publicKey [list "publicKey" $e $n]
|
||||
set privateKey [list "privateKey" $d $n]
|
||||
|
||||
# Test on some input strings
|
||||
foreach input {"Rosetta Code" "UTF-8 \u263a test"} {
|
||||
set enc [rsa_encrypt $input $publicKey]
|
||||
set dec [rsa_decrypt $enc $privateKey]
|
||||
puts "$input -> $enc -> $dec"
|
||||
}
|
||||
92
Task/RSA-code/V-(Vlang)/rsa-code.v
Normal file
92
Task/RSA-code/V-(Vlang)/rsa-code.v
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*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()}")
|
||||
}
|
||||
21
Task/RSA-code/Visual-Basic-.NET/rsa-code.vb
Normal file
21
Task/RSA-code/Visual-Basic-.NET/rsa-code.vb
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
Imports System
|
||||
Imports System.Numerics
|
||||
Imports System.Text
|
||||
|
||||
Module Module1
|
||||
Sub Main()
|
||||
Dim n As BigInteger = BigInteger.Parse("9516311845790656153499716760847001433441357")
|
||||
Dim e As BigInteger = 65537
|
||||
Dim d As BigInteger = BigInteger.Parse("5617843187844953170308463622230283376298685")
|
||||
Dim plainTextStr As String = "Hello, Rosetta!"
|
||||
Dim plainTextBA As Byte() = ASCIIEncoding.ASCII.GetBytes(plainTextStr)
|
||||
Dim pt As BigInteger = New BigInteger(plainTextBA)
|
||||
If pt > n Then Throw New Exception() ' Blocking not implemented
|
||||
Dim ct As BigInteger = BigInteger.ModPow(pt, e, n)
|
||||
Console.WriteLine(" Encoded: " & ct.ToString("X"))
|
||||
Dim dc As BigInteger = BigInteger.ModPow(ct, d, n)
|
||||
Console.WriteLine(" Decoded: " & dc.ToString("X"))
|
||||
Dim decoded As String = ASCIIEncoding.ASCII.GetString(dc.ToByteArray())
|
||||
Console.WriteLine("As ASCII: " & decoded)
|
||||
End Sub
|
||||
End Module
|
||||
38
Task/RSA-code/Wren/rsa-code.wren
Normal file
38
Task/RSA-code/Wren/rsa-code.wren
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
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)")
|
||||
16
Task/RSA-code/Zkl/rsa-code.zkl
Normal file
16
Task/RSA-code/Zkl/rsa-code.zkl
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
var BN=Import.lib("zklBigNum");
|
||||
|
||||
n:=BN("9516311845790656153499716760847001433441357");
|
||||
e:=BN("65537");
|
||||
d:=BN("5617843187844953170308463622230283376298685");
|
||||
|
||||
const plaintext="Rossetta Code";
|
||||
pt:=BN(Data(Int,0,plaintext)); // convert string (as stream of bytes) to big int
|
||||
if(pt>n) throw(Exception.ValueError("Message is too large"));
|
||||
|
||||
println("Plain text: ",plaintext);
|
||||
println("As Int: ",pt);
|
||||
ct:=pt.powm(e,n); println("Encoded: ",ct);
|
||||
pt =ct.powm(d,n); println("Decoded: ",pt);
|
||||
txt:=pt.toData().text; // convert big int to bytes, treat as string
|
||||
println("As String: ",txt);
|
||||
Loading…
Add table
Add a link
Reference in a new issue