FGIntRSA.PAS 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. {License, info, etc
  2. ------------------
  3. This implementation is made by Walied Othman, to contact me
  4. mail to Walied.Othman@Student.KULeuven.ac.be or
  5. Triade@ace.Ulyssis.Student.KULeuven.ac.be,
  6. always mention wether it 's about the FGInt for Delphi or for
  7. FreePascal, or wether it 's about the 6xs, preferably in the subject line.
  8. If you 're going to use these implementations, at least mention my
  9. name or something and notify me so I may even put a link on my page.
  10. This implementation is freeware and according to the coderpunks'
  11. manifesto it should remain so, so don 't use these implementations
  12. in commercial software. Encryption, as a tool to ensure privacy
  13. should be free and accessible for anyone. If you plan to use these
  14. implementations in a commercial application, contact me before
  15. doing so, that way you can license the software to use it in commercial
  16. Software. If any algorithm is patented in your country, you should
  17. acquire a license before using this software. Modified versions of this
  18. software must contain an acknowledgement of the original author (=me).
  19. This implementaion is available at
  20. http://ace.ulyssis.student.kuleuven.ac.be/~triade/
  21. copyright 2000, Walied Othman
  22. This header may not be removed.
  23. }
  24. Unit FGIntRSA;
  25. Interface
  26. Uses Windows, SysUtils, Controls, FGInt;
  27. Procedure RSAEncrypt(P : String; Var exp, modb : TFGInt; Var E : String);
  28. Procedure RSADecrypt(E : String; Var exp, modb, d_p, d_q, p, q : TFGInt; Var D : String);
  29. Procedure RSASign(M : String; Var d, n, dp, dq, p, q : TFGInt; Var S : String);
  30. Procedure RSAVerify(M, S : String; Var e, n : TFGInt; Var valid : boolean);
  31. Implementation
  32. {$H+}
  33. // Encrypt a string with the RSA algorithm, P^exp mod modb = E
  34. Procedure RSAEncrypt(P : String; Var exp, modb : TFGInt; Var E : String);
  35. Var
  36. i, j, modbits : longint;
  37. PGInt, temp, zero : TFGInt;
  38. tempstr1, tempstr2, tempstr3 : String;
  39. Begin
  40. Base2StringToFGInt('0', zero);
  41. FGIntToBase2String(modb, tempstr1);
  42. modbits := length(tempstr1);
  43. convertBase256to2(P, tempstr1);
  44. tempstr1 := '111' + tempstr1;
  45. j := modbits - 1;
  46. While (length(tempstr1) Mod j) <> 0 Do tempstr1 := '0' + tempstr1;
  47. j := length(tempstr1) Div (modbits - 1);
  48. tempstr2 := '';
  49. For i := 1 To j Do
  50. Begin
  51. tempstr3 := copy(tempstr1, 1, modbits - 1);
  52. While (copy(tempstr3, 1, 1) = '0') And (length(tempstr3) > 1) Do delete(tempstr3, 1, 1);
  53. Base2StringToFGInt(tempstr3, PGInt);
  54. delete(tempstr1, 1, modbits - 1);
  55. If tempstr3 = '0' Then FGIntCopy(zero, temp) Else FGIntMontgomeryModExp(PGInt, exp, modb, temp);
  56. FGIntDestroy(PGInt);
  57. tempstr3 := '';
  58. FGIntToBase2String(temp, tempstr3);
  59. While (length(tempstr3) Mod modbits) <> 0 Do tempstr3 := '0' + tempstr3;
  60. tempstr2 := tempstr2 + tempstr3;
  61. FGIntdestroy(temp);
  62. End;
  63. While (tempstr2[1] = '0') And (length(tempstr2) > 1) Do delete(tempstr2, 1, 1);
  64. ConvertBase2To256(tempstr2, E);
  65. FGIntDestroy(zero);
  66. End;
  67. // Decrypt a string with the RSA algorithm, E^exp mod modb = D
  68. // provide nil for exp.Number if you want a speedup by using the chinese
  69. // remainder theorem, modb = p*q, d_p*e mod (p-1) = 1 and
  70. // d_q*e mod (q-1) where e is the encryption exponent used
  71. Procedure RSADecrypt(E : String; Var exp, modb, d_p, d_q, p, q : TFGInt; Var D : String);
  72. Var
  73. i, j, modbits : longint;
  74. EGInt, temp, temp1, temp2, temp3, ppinvq, qqinvp, zero : TFGInt;
  75. tempstr1, tempstr2, tempstr3 : String;
  76. Begin
  77. Base2StringToFGInt('0', zero);
  78. FGIntToBase2String(modb, tempstr1);
  79. modbits := length(tempstr1);
  80. convertBase256to2(E, tempstr1);
  81. While copy(tempstr1, 1, 1) = '0' Do delete(tempstr1, 1, 1);
  82. While (length(tempstr1) Mod modbits) <> 0 Do tempstr1 := '0' + tempstr1;
  83. If exp.Number = Nil Then
  84. Begin
  85. FGIntModInv(q, p, temp1);
  86. FGIntMul(q, temp1, qqinvp);
  87. FGIntDestroy(temp1);
  88. FGIntModInv(p, q, temp1);
  89. FGIntMul(p, temp1, ppinvq);
  90. FGIntDestroy(temp1);
  91. End;
  92. j := length(tempstr1) Div modbits;
  93. tempstr2 := '';
  94. For i := 1 To j Do
  95. Begin
  96. tempstr3 := copy(tempstr1, 1, modbits);
  97. While (copy(tempstr3, 1, 1) = '0') And (length(tempstr3) > 1) Do delete(tempstr3, 1, 1);
  98. Base2StringToFGInt(tempstr3, EGInt);
  99. delete(tempstr1, 1, modbits);
  100. If tempstr3 = '0' Then FGIntCopy(zero, temp) Else
  101. Begin
  102. If exp.Number <> Nil Then FGIntMontgomeryModExp(EGInt, exp, modb, temp) Else
  103. Begin
  104. FGIntMontgomeryModExp(EGInt, d_p, p, temp1);
  105. FGIntMul(temp1, qqinvp, temp3);
  106. FGIntCopy(temp3, temp1);
  107. FGIntMontgomeryModExp(EGInt, d_q, q, temp2);
  108. FGIntMul(temp2, ppinvq, temp3);
  109. FGIntCopy(temp3, temp2);
  110. FGIntAddMod(temp1, temp2, modb, temp);
  111. FGIntDestroy(temp1);
  112. FGIntDestroy(temp2);
  113. End;
  114. End;
  115. FGIntDestroy(EGInt);
  116. tempstr3 := '';
  117. FGIntToBase2String(temp, tempstr3);
  118. While (length(tempstr3) Mod (modbits - 1)) <> 0 Do tempstr3 := '0' + tempstr3;
  119. tempstr2 := tempstr2 + tempstr3;
  120. FGIntdestroy(temp);
  121. End;
  122. If exp.Number = Nil Then
  123. Begin
  124. FGIntDestroy(ppinvq);
  125. FGIntDestroy(qqinvp);
  126. End;
  127. While (Not (copy(tempstr2, 1, 3) = '111')) And (length(tempstr2) > 3) Do delete(tempstr2, 1, 1);
  128. delete(tempstr2, 1, 3);
  129. ConvertBase2To256(tempstr2, D);
  130. FGIntDestroy(zero);
  131. End;
  132. // Sign strings with the RSA algorithm, M^d mod n = S
  133. // provide nil for exp.Number if you want a speedup by using the chinese
  134. // remainder theorem, n = p*q, dp*e mod (p-1) = 1 and
  135. // dq*e mod (q-1) where e is the encryption exponent used
  136. Procedure RSASign(M : String; Var d, n, dp, dq, p, q : TFGInt; Var S : String);
  137. Var
  138. MGInt, SGInt, temp, temp1, temp2, temp3, ppinvq, qqinvp : TFGInt;
  139. Begin
  140. Base256StringToFGInt(M, MGInt);
  141. If d.Number <> Nil Then FGIntMontgomeryModExp(MGInt, d, n, SGInt) Else
  142. Begin
  143. FGIntModInv(p, q, temp);
  144. FGIntMul(p, temp, ppinvq);
  145. FGIntDestroy(temp);
  146. FGIntModInv(q, p, temp);
  147. FGIntMul(q, temp, qqinvp);
  148. FGIntDestroy(temp);
  149. FGIntMontgomeryModExp(MGInt, dp, p, temp1);
  150. FGIntMul(temp1, qqinvp, temp2);
  151. FGIntCopy(temp2, temp1);
  152. FGIntMontgomeryModExp(MGInt, dq, q, temp2);
  153. FGIntMul(temp2, ppinvq, temp3);
  154. FGIntCopy(temp3, temp2);
  155. FGIntAddMod(temp1, temp2, n, SGInt);
  156. FGIntDestroy(temp1);
  157. FGIntDestroy(temp2);
  158. FGIntDestroy(ppinvq);
  159. FGIntDestroy(qqinvp);
  160. End;
  161. FGIntToBase256String(SGInt, S);
  162. FGIntDestroy(MGInt);
  163. FGIntDestroy(SGInt);
  164. End;
  165. // Verify digitally signed strings with the RSA algorihthm,
  166. // If M = S^e mod n then ok:=true else ok:=false
  167. Procedure RSAVerify(M, S : String; Var e, n : TFGInt; Var valid : boolean);
  168. Var
  169. MGInt, SGInt, temp : TFGInt;
  170. Begin
  171. Base256StringToFGInt(S, SGInt);
  172. Base256StringToFGInt(M, MGInt);
  173. FGIntMod(MGInt, n, temp);
  174. FGIntCopy(temp, MGInt);
  175. FGIntMontgomeryModExp(SGInt, e, n, temp);
  176. FGIntCopy(temp, SGInt);
  177. valid := (FGIntCompareAbs(SGInt, MGInt) = Eq);
  178. FGIntDestroy(SGInt);
  179. FGIntDestroy(MGInt);
  180. End;
  181. End.