- D1F331872729DE629191F57371544DA4AC672DCE61B7CD9829912EAA07DAD4628A297AFD91AB2A923B39BF640AB3787F4BA6662119B2A4FD9C7C79B82B11E097+ 5D7FFD960A5F49E0FCB3CD30EDBD2BE5E6D111A820293DAB68638966B6B2DC264A97EF05039FBECF0AB7C72E57EFB53D8BB665BC2B80D302CB31C1177E10CDB8ffa/libffa/fz_modex.adb(23 . 7)(23 . 6)
221 with FZ_Mul;   use FZ_Mul;
222 with FZ_Sqr;   use FZ_Sqr;
223 with FZ_Divis; use FZ_Divis;
224 with FZ_Barr;  use FZ_Barr;
225 
226 
227 package body FZ_ModEx is
(81 . 11)(80 . 37)
229    end FZ_Mod_Sqr;
230    
231    
232    -- (Barrettronic) Modular Exponent: Result := Base^Exponent mod Modulus
233    procedure FZ_Mod_Exp(Base     : in  FZ;
234                         Exponent : in  FZ;
235                         Modulus  : in  FZ;
236                         Result   : out FZ) is
237    -- (Barrettronic) Modular Squaring, using given Barrettoid
238    procedure FZ_Mod_Sqr_Barrett(X        : in  FZ;
239                                 Bar      : in  Barretoid;
240                                 Product  : out FZ) is
241       
242       -- The wordness of both operands is equal:
243       L     : constant Indices := X'Length;
244       
245       -- Double-width register for squaring and modulus operations
246       XX    : FZ(1 .. L * 2);
247       
248       -- To refer to the lower and upper halves of the working register:
249       XX_Lo : FZ renames XX(1     .. L);
250       XX_Hi : FZ renames XX(L + 1 .. XX'Last);
251    
252    begin
253       
254       -- XX_Lo:XX_Hi := X^2
255       FZ_Square_Buffered(X, XX_Lo, XX_Hi);
256       
257       -- Product := XX mod M
258       FZ_Barrett_Reduce(X => XX, Bar => Bar, XReduced => Product);
259       
260    end FZ_Mod_Sqr_Barrett;
261    
262    
263    -- Barrettronic Modular Exponent, using given Barrettoid
264    procedure FZ_Mod_Exp_Barrett(Base     : in  FZ;
265                                 Exponent : in  FZ;
266                                 Bar      : in  Barretoid;
267                                 Result   : out FZ) is
268       
269       -- Double-width scratch buffer for the modular operations
270       D   : FZ(1 .. Base'Length * 2);
(99 . 15)(124 . 8)
272       -- Buffer register for the Result
273       R   : FZ(Result'Range);
274       
275       -- Space for Barrettoid
276       Bar : Barretoid(ZXMLength       => Modulus'Length + 1,
277                       BarretoidLength => 2 * B'Length);
278       
279    begin
280       
281       -- First, pre-compute the Barretoid for the given Modulus:
282       FZ_Make_Barrettoid(Modulus => Modulus, Result => Bar);
283       
284       -- Result := 1
285       WBool_To_FZ(1, R);
286       
(149 . 6)(167 . 30)
288       -- Output the Result:
289       Result := R;
290       
291    end FZ_Mod_Exp_Barrett;
292    
293    
294    -- (Barrettronic) Modular Exponent: Result := Base^Exponent mod Modulus
295    procedure FZ_Mod_Exp(Base     : in  FZ;
296                         Exponent : in  FZ;
297                         Modulus  : in  FZ;
298                         Result   : out FZ) is
299       
300       -- Space for Barrettoid
301       Bar : Barretoid(ZXMLength       => Modulus'Length + 1,
302                       BarretoidLength => 2 * Base'Length);
303       
304    begin
305       
306       -- First, pre-compute the Barretoid for the given Modulus:
307       FZ_Make_Barrettoid(Modulus => Modulus, Result => Bar);
308       
309       -- Compute the modular exponentiation using the above Barrettoid:
310       FZ_Mod_Exp_Barrett(Base     => Base,
311                          Exponent => Exponent,
312                          Bar      => Bar,
313                          Result   => Result);
314       
315    end FZ_Mod_Exp;
316    
317 end FZ_ModEx;