RosettaCodeData/Task/RSA-code/ALGOL-68/rsa-code.alg

74 lines
2.2 KiB
Plaintext

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