-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathFGIntRSA.pas
More file actions
210 lines (180 loc) · 6.91 KB
/
FGIntRSA.pas
File metadata and controls
210 lines (180 loc) · 6.91 KB
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
205
206
207
208
209
{License, info, etc
------------------
This implementation is made by me, Walied Othman, to contact me
mail to Walied.Othman@belgacom.net or Triade@ulyssis.org,
always mention wether it 's about the FGInt for Delphi or for
FreePascal, or wether it 's about the 6xs, preferably in the subject line.
If you 're going to use these implementations, at least mention my
name or something and notify me so I may even put a link on my page.
This implementation is freeware and according to the coderpunks'
manifesto it should remain so, so don 't use these implementations
in commercial software. Encryption, as a tool to ensure privacy
should be free and accessible for anyone. If you plan to use these
implementations in a commercial application, contact me before
doing so, that way you can license the software to use it in commercial
Software. If any algorithm is patented in your country, you should
acquire a license before using this software. Modified versions of this
software must contain an acknowledgement of the original author (=me).
This implementation is available at
http://triade.studentenweb.org
copyright 2000, Walied Othman
This header may not be removed.
}
Unit FGIntRSA;
Interface
{$H+}
Uses SysUtils, FGInt;
Procedure RSAEncrypt(P : String; Var exp, modb : TFGInt; Var E : String);
Procedure RSADecrypt(E : String; Var exp, modb, d_p, d_q, p, q : TFGInt; Var D : String);
Procedure RSASign(M : String; Var d, n, dp, dq, p, q : TFGInt; Var S : String);
Procedure RSAVerify(M, S : String; Var e, n : TFGInt; Var valid : boolean);
Implementation
// Encrypt a string with the RSA algorithm, P^exp mod modb = E
Procedure RSAEncrypt(P : String; Var exp, modb : TFGInt; Var E : String);
Var
i, j, modbits : longint;
PGInt, temp, zero : TFGInt;
tempstr1, tempstr2, tempstr3 : String;
Begin
Base2StringToFGInt('0', zero);
FGIntToBase2String(modb, tempstr1);
modbits := length(tempstr1);
convertBase256to2(P, tempstr1);
tempstr1 := '111' + tempstr1;
j := modbits - 1;
While (length(tempstr1) Mod j) <> 0 Do tempstr1 := '0' + tempstr1;
j := length(tempstr1) Div (modbits - 1);
tempstr2 := '';
For i := 1 To j Do
Begin
tempstr3 := copy(tempstr1, 1, modbits - 1);
While (copy(tempstr3, 1, 1) = '0') And (length(tempstr3) > 1) Do delete(tempstr3, 1, 1);
Base2StringToFGInt(tempstr3, PGInt);
delete(tempstr1, 1, modbits - 1);
If tempstr3 = '0' Then FGIntCopy(zero, temp) Else FGIntMontgomeryModExp(PGInt, exp, modb, temp);
FGIntDestroy(PGInt);
tempstr3 := '';
FGIntToBase2String(temp, tempstr3);
While (length(tempstr3) Mod modbits) <> 0 Do tempstr3 := '0' + tempstr3;
tempstr2 := tempstr2 + tempstr3;
FGIntdestroy(temp);
End;
While (tempstr2[1] = '0') And (length(tempstr2) > 1) Do delete(tempstr2, 1, 1);
ConvertBase2To256(tempstr2, E);
FGIntDestroy(zero);
End;
// Decrypt a string with the RSA algorithm, E^exp mod modb = D
// provide nil for exp.Number if you want a speedup by using the chinese
// remainder theorem, modb = p*q, d_p*e mod (p-1) = 1 and
// d_q*e mod (q-1) where e is the encryption exponent used
Procedure RSADecrypt(E : String; Var exp, modb, d_p, d_q, p, q : TFGInt; Var D : String);
Var
i, j, modbits : longint;
EGInt, temp, temp1, temp2, temp3, ppinvq, qqinvp, zero : TFGInt;
tempstr1, tempstr2, tempstr3 : String;
Begin
Base2StringToFGInt('0', zero);
FGIntToBase2String(modb, tempstr1);
modbits := length(tempstr1);
convertBase256to2(E, tempstr1);
While copy(tempstr1, 1, 1) = '0' Do delete(tempstr1, 1, 1);
While (length(tempstr1) Mod modbits) <> 0 Do tempstr1 := '0' + tempstr1;
If exp.Number = Nil Then
Begin
FGIntModInv(q, p, temp1);
FGIntMul(q, temp1, qqinvp);
FGIntDestroy(temp1);
FGIntModInv(p, q, temp1);
FGIntMul(p, temp1, ppinvq);
FGIntDestroy(temp1);
End;
j := length(tempstr1) Div modbits;
tempstr2 := '';
For i := 1 To j Do
Begin
tempstr3 := copy(tempstr1, 1, modbits);
While (copy(tempstr3, 1, 1) = '0') And (length(tempstr3) > 1) Do delete(tempstr3, 1, 1);
Base2StringToFGInt(tempstr3, EGInt);
delete(tempstr1, 1, modbits);
If tempstr3 = '0' Then FGIntCopy(zero, temp) Else
Begin
If exp.Number <> Nil Then FGIntMontgomeryModExp(EGInt, exp, modb, temp) Else
Begin
FGIntMontgomeryModExp(EGInt, d_p, p, temp1);
FGIntMul(temp1, qqinvp, temp3);
FGIntCopy(temp3, temp1);
FGIntMontgomeryModExp(EGInt, d_q, q, temp2);
FGIntMul(temp2, ppinvq, temp3);
FGIntCopy(temp3, temp2);
FGIntAddMod(temp1, temp2, modb, temp);
FGIntDestroy(temp1);
FGIntDestroy(temp2);
End;
End;
FGIntDestroy(EGInt);
tempstr3 := '';
FGIntToBase2String(temp, tempstr3);
While (length(tempstr3) Mod (modbits - 1)) <> 0 Do tempstr3 := '0' + tempstr3;
tempstr2 := tempstr2 + tempstr3;
FGIntdestroy(temp);
End;
If exp.Number = Nil Then
Begin
FGIntDestroy(ppinvq);
FGIntDestroy(qqinvp);
End;
While (Not (copy(tempstr2, 1, 3) = '111')) And (length(tempstr2) > 3) Do delete(tempstr2, 1, 1);
delete(tempstr2, 1, 3);
ConvertBase2To256(tempstr2, D);
FGIntDestroy(zero);
End;
// Sign strings with the RSA algorithm, M^d mod n = S
// provide nil for exp.Number if you want a speedup by using the chinese
// remainder theorem, n = p*q, dp*e mod (p-1) = 1 and
// dq*e mod (q-1) where e is the encryption exponent used
Procedure RSASign(M : String; Var d, n, dp, dq, p, q : TFGInt; Var S : String);
Var
MGInt, SGInt, temp, temp1, temp2, temp3, ppinvq, qqinvp : TFGInt;
Begin
Base256StringToFGInt(M, MGInt);
If d.Number <> Nil Then FGIntMontgomeryModExp(MGInt, d, n, SGInt) Else
Begin
FGIntModInv(p, q, temp);
FGIntMul(p, temp, ppinvq);
FGIntDestroy(temp);
FGIntModInv(q, p, temp);
FGIntMul(q, temp, qqinvp);
FGIntDestroy(temp);
FGIntMontgomeryModExp(MGInt, dp, p, temp1);
FGIntMul(temp1, qqinvp, temp2);
FGIntCopy(temp2, temp1);
FGIntMontgomeryModExp(MGInt, dq, q, temp2);
FGIntMul(temp2, ppinvq, temp3);
FGIntCopy(temp3, temp2);
FGIntAddMod(temp1, temp2, n, SGInt);
FGIntDestroy(temp1);
FGIntDestroy(temp2);
FGIntDestroy(ppinvq);
FGIntDestroy(qqinvp);
End;
FGIntToBase256String(SGInt, S);
FGIntDestroy(MGInt);
FGIntDestroy(SGInt);
End;
// Verify digitally signed strings with the RSA algorihthm,
// If M = S^e mod n then ok:=true else ok:=false
Procedure RSAVerify(M, S : String; Var e, n : TFGInt; Var valid : boolean);
Var
MGInt, SGInt, temp : TFGInt;
Begin
Base256StringToFGInt(S, SGInt);
Base256StringToFGInt(M, MGInt);
FGIntMod(MGInt, n, temp);
FGIntCopy(temp, MGInt);
FGIntMontgomeryModExp(SGInt, e, n, temp);
FGIntCopy(temp, SGInt);
valid := (FGIntCompareAbs(SGInt, MGInt) = Eq);
FGIntDestroy(SGInt);
FGIntDestroy(MGInt);
End;
End.