1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 | ------------------------------------------------------------------------------
-- File: Test_RSA.adb
-- Description: Test for Multi_precision_integers : RSA cyphering
-- Author: Gautier de Montmollin
------------------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Multi_Precision_Integers; use Multi_Precision_Integers;
with Multi_Precision_Integers.IO; use Multi_Precision_Integers.IO;
with Euclidean_Ring_Tools;
procedure Test_RSA is
RSA_max : constant := 10;
subtype RSA_block is Multi_Int (RSA_max);
-- zero: constant RSA_block:=
-- (n=> RSA_max, zero=> True, neg=> False, last_used=> 0,
-- blk=>(others=> 0));
-- one: constant RSA_block:=
-- (n=> RSA_max, zero=> False, neg=> False, last_used=> 0,
-- blk=>(0=> 1, others=> 0));
-- package ERT_multi is new
-- Euclidean_Ring_Tools(RSA_block, zero, one, "-", "*", "/");
type Int_Vec is array (Integer range <>) of Integer;
function Eq_I (a, b : Integer) return Boolean renames "=";
pragma Unreferenced (Eq_I);
package ERT is new
Euclidean_Ring_Tools (Integer, 0, 1, "+", "-", "*", "/", "=", Int_Vec);
type RSA_Message is array (Integer range <>) of RSA_block;
-- Encode or decode:
procedure Code (msg : in out RSA_Message; expo, modu : Multi_Int) is
ipn : RSA_block;
begin
for i in msg'Range loop
Power (msg (i), expo, ipn, modu);
msg (i) := ipn;
end loop;
end Code;
procedure Put_in_blocks (msg : RSA_Message) is
begin
for i in msg'Range loop
Put (i); Put (" ]-> ");
Put_in_blocks (msg (i));
New_Line;
end loop;
end Put_in_blocks;
procedure Codec (msg : in out RSA_Message; e, d, n : Multi_Int) is
show_contents : constant Boolean := False;
begin
if show_contents then
Put_Line (" - Original RSA message");
Put_in_blocks (msg);
end if;
-- Encode
Code (msg, e, n);
if show_contents then
Put_Line (" - Encoded RSA message");
Put_in_blocks (msg);
end if;
-- Decode
Code (msg, d, n);
if show_contents then
Put_Line (" - Decoded RSA message");
Put_in_blocks (msg);
end if;
end Codec;
procedure Test_Allenby_Redfern (s : String; e, d, n : Multi_Int) is
msg : RSA_Message (1 .. s'Last / 2);
r : String (s'Range);
begin
New_Line;
-- Translate String into RSA blocks
Put_Line (s);
for i in msg'Range loop
Fill (msg (i), (Character'Pos (s (i * 2 - 1)) - 65) * 100 +
(Character'Pos (s (i * 2)) - 65));
end loop;
Codec (msg, e, d, n);
-- Translate RSA blocks into String
for i in msg'Range loop
r (i * 2 - 1) := Character'Val (65 + Basic (msg (i)) / 100);
r (i * 2) := Character'Val (65 + Basic (msg (i)) mod 100);
end loop;
Put_Line (r);
end Test_Allenby_Redfern;
procedure Decode_Allenby_Redfern is
msgint : constant array (1 .. 59) of Integer :=
(6132, 0615, 5995, 0615, 2368, 1225, 5201, 3198, 0499, 1342, 4718, 0499, 3221,
2851, 1520, 0001, 2432, 4326, 0472, 4945, 2555, 4718, 2271, 6219, 5941, 3266,
4713, 1990, 0036, 0096, 0744, 5882, 3998, 1790, 3198, 1541, 5349, 3998, 5941,
6098, 0048, 0893, 5349, 1835,
3221, 0615, 0044, 0021, 2915, 1318, 3696,
0744, 4885, 3608, 4719, 0615, 0832, 3147, 4718);
msg : RSA_Message (msgint'Range);
ni : constant Integer := 6499; -- 67*97
phini : constant Integer := 6636; -- 66*96
ei : constant Integer := 109;
di : Integer;
the_gcd : Integer;
d, n : Multi_Int (0);
r : String (1 .. 200) := (others => ' ');
function ASCRF (a : Integer) return Integer is
begin
if a in 0 .. 25 then
return 65 + a;
else
return Character'Pos ('*');
end if;
end ASCRF;
begin
for i in msg'Range loop Fill (msg (i), msgint (i)); end loop;
New_Line;
Fill (n, ni);
ERT.GCD (ei, phini, the_gcd);
Put (the_gcd); New_Line;
for i in 0 .. ni - 1 loop
if ei * i mod 6636 = 1 then
di := i; Put (i); New_Line;
end if;
end loop;
Fill (d, di);
Code (msg, d, n);
-- Translate RSA blocks into String
for i in msg'Range loop
r (i * 2 - 1) := Character'Val (ASCRF (Basic (msg (i)) / 100));
r (i * 2) := Character'Val (ASCRF (Basic (msg (i)) rem 100));
end loop;
Put_Line (r);
end Decode_Allenby_Redfern;
procedure Test_GM (s : String; e, d, n : Multi_Int) is
msg : RSA_Message (s'Range);
r : String (s'Range);
begin
New_Line;
-- Translate String into RSA blocks
Put_Line (s);
for i in msg'Range loop
Fill (msg (i), Character'Pos (s (i)));
end loop;
Codec (msg, e, d, n);
-- Translate RSA blocks into String
for i in msg'Range loop
r (i) := Character'Val (Basic (msg (i)));
end loop;
Put_Line (r);
end Test_GM;
begin
if Debug then
Put_Line ("NB: the constant DEBUG in Multi_precision_integers");
Put_Line (" is set on True, it means a very poor performance!");
New_Line;
Put_Line (" [x] Yes, I am aware of it !");
New_Line;
end if;
Test_Allenby_Redfern (
"THIS_IS_A_SMALL_TEST_ALLENBY_REDFERN",
e => Multi (97), d => Multi (3073), n => Multi (4453)
);
Decode_Allenby_Redfern;
Test_GM (
"Thougher test",
e => Multi (3),
d => Val ("129143530427"),
n => Val ("440171") * Val ("440093")
);
Test_GM (
"Thougher test 2",
e => Multi (5),
d => Val ("719520409731917"),
n => Val ("17144977") * Val ("104917093")
);
end Test_RSA;
|