tree checksum vpatch file split hunks
all signers: bvt asciilifeform diana_coman
antecedents: ffa_ch1_genesis.kv ffa_ch11_tuning_and_api.kv ffa_ch12_karatsuba_redux.kv ffa_w_borrow_expr.kv
press order: 
patch: 
(11 . 3)(11 . 4)
  5 xxxxxxx ffa_ch11_tuning_and_api        "Tuning and Unified API."
  6  551091 ffa_ch12_karatsuba_redux       "Karatsuba Redux."
  7  551348 ffa_w_borrow_expr diana_coman Replaces expression for calculating borrow bit with more readable version that is also symmetrical to that for carry bit.
  8  551516 ffa_ch13_measure_and_qshifts   "Measure and Quiet Shifts."
- 4A851245719704AF35888E2D1BC00B4CEC16E66093E7D79408E98E8A2EABA0E0F5A7ED1EEE26D0F75FA651DBE4BDDD48C31722A2B9B98464362B681F5D7B4C8A(108 . 6)(108 . 11)- AA1B855DFFA6FB750CF1778F0DFB532328FC555DFA0C1FAB99B3D9DD85B6C5BC16508A1422273F9706ACC917E1B873A38AE9B358FB9A070F25F5403195CAC01C
13 QuoteLevel : Natural := 0;
14 CommLevel : Natural := 0;
15 CondLevel : Natural := 0;
16
17 -- Prefixed Operators
18 PrevC : Character := ' ';
19 HavePrefix : Boolean := False;
20
21 --------------------------------------------------------
22
23
(122 . 6)(127 . 9)
25 SP := Stack_Positions'First;
26 -- Clear Overflow flag
27 Flag := 0;
28 -- Clear prefix
29 HavePrefix := False;
30 PrevC := ' ';
31 end Zap;
32
33
(197 . 6)(205 . 13)
35 end Print_FZ;
36
37
38 -- Denote that the given op is a prefix
39 procedure IsPrefix is
40 begin
41 HavePrefix := True;
42 end IsPrefix;
43
44
45 -- Execute a Normal Op
46 procedure Op_Normal(C : in Character) is
47
(377 . 28)(392 . 6)
49 XY_Lo => Stack(SP - 1),
50 XY_Hi => Stack(SP));
51
52 -- Modular Multiplication
53 when 'M' =>
54 Want(3);
55 MustNotZero(Stack(SP));
56 FFA_FZ_Modular_Multiply(X => Stack(SP - 2),
57 Y => Stack(SP - 1),
58 Modulus => Stack(SP),
59 Product => Stack(SP - 2));
60 Drop;
61 Drop;
62
63 -- Modular Exponentiation
64 when 'X' =>
65 Want(3);
66 MustNotZero(Stack(SP));
67 FFA_FZ_Modular_Exponentiate(Base => Stack(SP - 2),
68 Exponent => Stack(SP - 1),
69 Modulus => Stack(SP),
70 Result => Stack(SP - 2));
71 Drop;
72 Drop;
73
74 -----------------
75 -- Bitwise Ops --
76 -----------------
(452 . 6)(445 . 19)
78 Drop;
79 Drop;
80
81 -- Find the position of eldest nonzero bit, if any exist
82 when 'W' =>
83 Want(1);
84 declare
85 Measure : Word;
86 begin
87 -- Find the measure ( 0 if no 1s, or 1 .. FZBitness )
88 Measure := FFA_FZ_Measure(Stack(SP));
89 -- Put on top of stack
90 FFA_FZ_Clear(Stack(SP));
91 FFA_FZ_Set_Head(Stack(SP), Measure);
92 end;
93
94 -- Put the Overflow flag on the stack
95 when 'O' =>
96 Push;
(474 . 8)(480 . 6)
98 end loop;
99 Quit(0);
100
101 ---------------------------------------------------------
102 -- Ch. 12B:
103 -- Square, give bottom and top halves
104 when 'S' =>
105 Want(1);
(483 . 13)(487 . 38)
107 FFA_FZ_Square(X => Stack(SP - 1),
108 XX_Lo => Stack(SP - 1),
109 XX_Hi => Stack(SP));
110
111 --------------
112 -- Prefixes --
113 --------------
114
115 -- 'Left...' :
116 when 'L' =>
117 IsPrefix;
118
119 -- 'Right...' :
120 when 'R' =>
121 IsPrefix;
122
123 -- 'Modular...' :
124 when 'M' =>
125 IsPrefix;
126
127 ---------------------------------------------------------
128 -- Reserved Ops, i.e. ones we have not defined yet: --
129 ---------------------------------------------------------
130 when '!' | '@' | '$' | ':' | ';' | ',' |
131 'G' | 'H' | 'I' | 'J' | 'K' | 'N' |
132 'P' | 'T' | 'V' | 'X' | 'Y' =>
133
134 E("This Operator is not defined yet: " & C);
135 ---------------------------------------------------------
136
137 ----------
138 -- NOPs --
139 ----------
140
141 -- Ops we have not yet spoken of -- do nothing
142 -- Unprintables and spaces DO NOTHING:
143 when others =>
144 null;
145
(498 . 6)(527 . 118)
147 end Op_Normal;
148
149
150 -- Execute a Prefixed Op
151 procedure Op_Prefixed(Prefix : in Character;
152 O : in Character) is
153 begin
154
155 -- The Prefixed Op:
156 case Prefix is
157
158 ---------------------------------------------------------
159 -- Left...
160 when 'L' =>
161
162 -- Which L-op?
163 case O is
164
165 -- ... Shift :
166 when 'S' =>
167 Want(2);
168 declare
169 -- Number of bit positions to shift by:
170 ShiftCount : FZBit_Index
171 := FZBit_Index(FFA_FZ_Get_Head(Stack(SP)));
172 begin
173 FFA_FZ_Quiet_ShiftLeft(N => Stack(SP - 1),
174 ShiftedN => Stack(SP - 1),
175 Count => ShiftCount);
176 end;
177 Drop;
178
179 -- ... Rotate :
180 when 'R' =>
181 E("Left-Rotate not yet defined!");
182
183 -- ... Unknown:
184 when others =>
185 E("Undefined Op: L" & O);
186
187 end case;
188 ---------------------------------------------------------
189 -- Right...
190 when 'R' =>
191
192 -- Which R-op?
193 case O is
194
195 -- ... Shift:
196 when 'S' =>
197 Want(2);
198 declare
199 -- Number of bit positions to shift by:
200 ShiftCount : FZBit_Index
201 := FZBit_Index(FFA_FZ_Get_Head(Stack(SP)));
202 begin
203 FFA_FZ_Quiet_ShiftRight(N => Stack(SP - 1),
204 ShiftedN => Stack(SP - 1),
205 Count => ShiftCount);
206 end;
207 Drop;
208
209 -- ... Rotate:
210 when 'R' =>
211 E("Right-Rotate not yet defined!");
212
213 -- ... Unknown:
214 when others =>
215 E("Undefined Op: R" & O);
216
217 end case;
218 ---------------------------------------------------------
219 -- Modular...
220 when 'M' =>
221
222 -- Which M-op?
223 case O is
224
225 -- ... Multiplication :
226 when '*' =>
227 Want(3);
228 MustNotZero(Stack(SP));
229 FFA_FZ_Modular_Multiply(X => Stack(SP - 2),
230 Y => Stack(SP - 1),
231 Modulus => Stack(SP),
232 Product => Stack(SP - 2));
233 Drop;
234 Drop;
235
236 -- ... Exponentiation :
237 when 'X' =>
238 Want(3);
239 MustNotZero(Stack(SP));
240 FFA_FZ_Modular_Exponentiate(Base => Stack(SP - 2),
241 Exponent => Stack(SP - 1),
242 Modulus => Stack(SP),
243 Result => Stack(SP - 2));
244 Drop;
245 Drop;
246
247 -- ... Unknown:
248 when others =>
249 E("Undefined Op: M" & O);
250
251 end case;
252 ---------------------------------------------------------
253 -- ... Unknown: (impossible per mechanics, but must handle case)
254 when others =>
255 E("Undefined Prefix: " & Prefix);
256
257 end case;
258
259 end Op_Prefixed;
260
261
262 -- Process a Symbol
263 procedure Op(C : in Character) is
264 begin
(548 . 6)(689 . 16)
266 when others =>
267 null; -- Other symbols have no effect on the level
268 end case;
269
270 --- ... if in a prefixed op:
271 elsif HavePrefix then
272
273 -- Drop the prefix-op hammer, until another prefix-op cocks it
274 HavePrefix := False;
275
276 -- Dispatch this op, where prefix is the preceding character
277 Op_Prefixed(Prefix => PrevC, O => C);
278
279 else
280 -- This is a Normal Op, so proceed with the normal rules.
281 Op_Normal(C);
(569 . 6)(720 . 8)
283 Op(C);
284 -- Advance Odometer
285 Pos := Pos + 1;
286 -- Save the op for use in prefixed ops
287 PrevC := C;
288 else
289 Zap;
290 Quit(0); -- if EOF, we're done
(30 . 6)(30 . 8)- 4E704ADD5330464A8DF437A836B5232F754D31E1C27141A79C7ADD51EDCA2A2BF4F3C63F098110BE6A751D29DB1FE99776A961CD089B920651D3A4324A43E33F
295 with FZ_BitOp;
296 with FZ_Divis;
297 with FZ_ModEx;
298 with FZ_Measr;
299 with FZ_QShft;
300
301
302 -- FFA Exports
(41 . 15)(43 . 16)
304 --- Fundamental Types and Sizes
305 ----------------------------------------------------------------------------
306
307 subtype Word is Words.Word;
308 subtype WBool is Words.WBool;
309 subtype Word is Words.Word;
310 subtype WBool is Words.WBool;
311
312 subtype Nibble is Words.Nibble;
313 subtype Nibble is Words.Nibble;
314
315 subtype FZ is FZ_Type.FZ;
316 subtype Indices is FZ_Type.Indices;
317 subtype FZ is FZ_Type.FZ;
318 subtype Indices is FZ_Type.Indices;
319 subtype FZBit_Index is FZ_Type.FZBit_Index;
320
321 subtype Char_Count is FZ_IO.Char_Count;
322 subtype Char_Count is FZ_IO.Char_Count;
323
324 Bitness : Positive renames Words.Bitness;
325
(282 . 4)(285 . 24)
327 Result : out FZ)
328 renames FZ_ModEx.FZ_Mod_Exp;
329
330 ----------------------------------------------------------------------------
331 --- Other Operations on FZ
332 ----------------------------------------------------------------------------
333
334 -- Find the index of eldest nonzero bit ( 0 if none, or 1 .. FZBitness )
335 function FFA_FZ_Measure(N : in FZ) return Word
336 renames FZ_Measr.FZ_Measure;
337
338 -- Constant-time arbitrary right-shift.
339 procedure FFA_FZ_Quiet_ShiftRight(N : in FZ;
340 ShiftedN : in out FZ;
341 Count : in FZBit_Index)
342 renames FZ_QShft.FZ_Quiet_ShiftRight;
343
344 -- Constant-time arbitrary left-shift.
345 procedure FFA_FZ_Quiet_ShiftLeft(N : in FZ;
346 ShiftedN : in out FZ;
347 Count : in FZBit_Index)
348 renames FZ_QShft.FZ_Quiet_ShiftLeft;
349
350 end FFA;
(33 . 6)(33 . 19)
355    end FZ_Bitness;
356    
357    
358    -- Determine the Bitness of the given FZ's Length
359    function FZ_Bitness_Log2(N : in FZ) return Positive is
360       W : Bit_Count := N'Length;
361       R : Positive  := 1;
362    begin
363       while W > 1 loop
364          W := W / 2;
365          R := R + 1;
366       end loop;
367       return R - 1;
368    end FZ_Bitness_Log2;
369    
370    
371    -- N := 0
372    procedure FZ_Clear(N : out FZ) is
373    begin
- 780724C25222C12597A25E39885E33D30AE89BDAD814C271CFB5E353A3B1D48760342186F7A0AA44C47D3433FE02891935E27CD2B1D8AB94C3AA61C128DF3C33(29 . 6)(29 . 10)
378    function FZ_Bitness(N : in FZ) return Bit_Count;
379    pragma Inline_Always(FZ_Bitness);
380    
381    -- Determine the Bitness of the given FZ's Length
382    function FZ_Bitness_Log2(N : in FZ) return Positive;
383    pragma Inline_Always(FZ_Bitness_Log2);
384    
385    -- N := 0
386    procedure FZ_Clear(N : out FZ);
387    pragma Inline_Always(FZ_Clear);
-(0 . 0)(1 . 68)
392 ------------------------------------------------------------------------------
393 ------------------------------------------------------------------------------
394 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'.               --
395 --                                                                          --
396 -- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
397 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
398 --                                                                          --
399 -- You do not have, nor can you ever acquire the right to use, copy or      --
400 -- distribute this software ; Should you use this software for any purpose, --
401 -- or copy and distribute it to anyone or in any manner, you are breaking   --
402 -- the laws of whatever soi-disant jurisdiction, and you promise to         --
403 -- continue doing so for the indefinite future. In any case, please         --
404 -- always : read and understand any software ; verify any PGP signatures    --
405 -- that you use - for any purpose.                                          --
406 --                                                                          --
407 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
408 ------------------------------------------------------------------------------
409 ------------------------------------------------------------------------------
410 
411 with Word_Ops; use Word_Ops;
412 with W_Pred;   use W_Pred;
413 with W_Shifts; use W_Shifts;
414 
415 
416 package body FZ_Measr is
417    
418    -- Find the index of eldest nonzero bit ( 0 if none, or 1 .. FZBitness )
419    function FZ_Measure(N : in FZ) return Word is
420       
421       -- The result (default : 0, will remain 0 if N is in fact zero)
422       Index     : Word := 0;
423       
424       -- The currently-examined Word, starting from the junior-most
425       Ni        : Word;
426       
427       -- The most recently-seen nonzero Word, if indeed any exist
428       W         : Word := 0;
429       
430       -- 1 if currently-examined Word is zero, otherwise 0
431       NiZ       : WBool;
432       
433    begin
434       
435       -- Find, in constant time, eldest non-zero Word:
436       for i in 0 .. Indices(N'Length - 1) loop
437          Ni    := N(N'First + i);              -- Ni := current Word;
438          NiZ   := W_ZeroP(Ni);                 -- ... is this Word = 0?
439          Index := W_Mux(Word(i), Index, NiZ);  -- If NO, save the Index,
440          W     := W_Mux(Ni,      W,     NiZ);  -- ... and save that Word.
441       end loop;
442       
443       -- Set Index to be the bit-position of the eldest non-zero Word:
444       Index := Shift_Left(Index, BitnessLog2); -- Index := Index * Bitness
445       
446       -- Find, in constant time, eldest non-zero bit in that Word:
447       for b in 1 .. Bitness loop
448          -- If W is non-zero, advance the Index...
449          Index := W_Mux(Index + 1, Index, W_ZeroP(W));
450          -- ... in either case, advance W:
451          W     := Shift_Right(W, 1);
452       end loop;
453       
454       -- If N = 0, result will be 0; otherwise: index of the eldest 1 bit.
455       return Index;
456       
457    end FZ_Measure;
458    
459 end FZ_Measr;
-(0 . 0)(1 . 32)
464 ------------------------------------------------------------------------------
465 ------------------------------------------------------------------------------
466 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'.               --
467 --                                                                          --
468 -- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
469 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
470 --                                                                          --
471 -- You do not have, nor can you ever acquire the right to use, copy or      --
472 -- distribute this software ; Should you use this software for any purpose, --
473 -- or copy and distribute it to anyone or in any manner, you are breaking   --
474 -- the laws of whatever soi-disant jurisdiction, and you promise to         --
475 -- continue doing so for the indefinite future. In any case, please         --
476 -- always : read and understand any software ; verify any PGP signatures    --
477 -- that you use - for any purpose.                                          --
478 --                                                                          --
479 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
480 ------------------------------------------------------------------------------
481 ------------------------------------------------------------------------------
482 
483 with Words;   use Words;
484 with FZ_Type; use FZ_Type;
485 
486 
487 package FZ_Measr is
488    
489    pragma Pure;
490    
491    -- Find the index of eldest nonzero bit ( 0 if none, or 1 .. FZBitness )
492    function FZ_Measure(N : in FZ) return Word;
493    pragma Inline_Always(FZ_Measure);
494    
495 end FZ_Measr;
-(0 . 0)(1 . 233)
500 ------------------------------------------------------------------------------
501 ------------------------------------------------------------------------------
502 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'.               --
503 --                                                                          --
504 -- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
505 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
506 --                                                                          --
507 -- You do not have, nor can you ever acquire the right to use, copy or      --
508 -- distribute this software ; Should you use this software for any purpose, --
509 -- or copy and distribute it to anyone or in any manner, you are breaking   --
510 -- the laws of whatever soi-disant jurisdiction, and you promise to         --
511 -- continue doing so for the indefinite future. In any case, please         --
512 -- always : read and understand any software ; verify any PGP signatures    --
513 -- that you use - for any purpose.                                          --
514 --                                                                          --
515 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
516 ------------------------------------------------------------------------------
517 ------------------------------------------------------------------------------
518 
519 with Iron;     use Iron;
520 with Word_Ops; use Word_Ops;
521 with W_Pred;   use W_Pred;
522 with W_Shifts; use W_Shifts;
523 with FZ_Basic; use FZ_Basic;
524 with FZ_Shift; use FZ_Shift;
525 
526 
527 package body FZ_QShft is
528    
529    -- Constant-time subword shift, for where there is no barrel shifter
530    procedure FZ_Quiet_ShiftRight_SubW_Soft(N        : in FZ;
531                                            ShiftedN : in out FZ;
532                                            Count    : in WBit_Index) is
533       Nw  : constant Word  := Word(Count);
534       nC  : constant WBool := W_ZeroP(Nw); -- 'no carry' for Count == 0 case
535       Ni  : Word := 0; -- Current word
536       C   : Word := 0; -- Current carry
537       S   : Positive;  -- Current shiftness level
538       B   : Word;      -- Quantity of shift (bitwalked over)
539       CB  : Word;      -- Quantity of carry counter-shift (bitwalked over)
540       St  : Word;      -- Temporary word shift candidate
541       Ct  : Word;      -- Temporary carry counter-shift candidate
542    begin
543       for i in reverse N'Range loop
544          Ni          := N(i);
545          ShiftedN(i) := C;
546          C           := W_Mux(Ni, 0, nC);
547          S           := 1;
548          B           := Nw;
549          CB          := Word(Bitness) - B;
550          -- For each shift level (of the subword shiftvalue width) :
551          for j in 1 .. BitnessLog2 loop
552             -- Shift and mux the current word
553             St := Shift_Right(Ni, S);
554             Ni := W_Mux(Ni, St, B and 1);
555             -- Shift and mux the current carry
556             Ct := Shift_Left(C, S);
557             C  := W_Mux(C,  Ct, CB and 1);
558             -- Go to the next shiftness level
559             S  := S * 2;
560             B  := Shift_Right(B,  1);
561             CB := Shift_Right(CB, 1);
562          end loop;
563          -- Slide in the carry from the previous shift
564          ShiftedN(i) := ShiftedN(i) or Ni;
565       end loop;
566    end FZ_Quiet_ShiftRight_SubW_Soft;
567    
568    
569    -- Constant-time subword shift, for where there is no barrel shifter
570    procedure FZ_Quiet_ShiftLeft_SubW_Soft(N        : in FZ;
571                                           ShiftedN : in out FZ;
572                                           Count    : in WBit_Index) is
573       Nw  : constant Word  := Word(Count);
574       nC  : constant WBool := W_ZeroP(Nw); -- 'no carry' for Count == 0 case
575       Ni  : Word := 0; -- Current word
576       C   : Word := 0; -- Current carry
577       S   : Positive;  -- Current shiftness level
578       B   : Word;      -- Quantity of shift (bitwalked over)
579       CB  : Word;      -- Quantity of carry counter-shift (bitwalked over)
580       St  : Word;      -- Temporary word shift candidate
581       Ct  : Word;      -- Temporary carry counter-shift candidate
582    begin
583       for i in N'Range loop
584          Ni          := N(i);
585          ShiftedN(i) := C;
586          C           := W_Mux(Ni, 0, nC);
587          S           := 1;
588          B           := Nw;
589          CB          := Word(Bitness) - B;
590          -- For each shift level (of the subword shiftvalue width) :
591          for j in 1 .. BitnessLog2 loop
592             -- Shift and mux the current word
593             St := Shift_Left(Ni, S);
594             Ni := W_Mux(Ni, St, B and 1);
595             -- Shift and mux the current carry
596             Ct := Shift_Right(C, S);
597             C  := W_Mux(C,  Ct, CB and 1);
598             -- Go to the next shiftness level
599             S  := S * 2;
600             B  := Shift_Right(B,  1);
601             CB := Shift_Right(CB, 1);
602          end loop;
603          -- Slide in the carry from the previous shift
604          ShiftedN(i) := ShiftedN(i) or Ni;
605       end loop;
606    end FZ_Quiet_ShiftLeft_SubW_Soft;
607    
608    
609    -- Constant-time arbitrary Right-Shift.
610    procedure FZ_Quiet_ShiftRight(N        : in     FZ;
611                                  ShiftedN : in out FZ;
612                                  Count    : in     FZBit_Index) is
613       
614       -- Total number of bit positions to shift by
615       C     : constant Word     := Word(Count);
616       
617       -- Number of sub-Word bit positions to shift by
618       Bits  : constant Natural  := Natural(C and (2**BitnessLog2 - 1));
619       
620       -- The Bitness of N's Length
621       Wb    : constant Positive := FZ_Bitness_Log2(N);
622       
623       -- Number of whole-Word bitnesses to shift by
624       Words : Word              := Shift_Right(C, BitnessLog2);
625       
626       -- Current 'shiftness level'
627       S     : Indices           := 1;
628       
629    begin
630       
631       -- Subword shift first:
632       if HaveBarrelShifter then
633          -- If permitted, use iron shifter:
634          FZ_ShiftRight(N, ShiftedN, Bits);
635       else
636          -- Otherwise, use the soft subword shifter:
637          FZ_Quiet_ShiftRight_SubW_Soft(N, ShiftedN, Bits);
638       end if;
639       
640       -- Then whole-Word shift:
641       for i in 1 .. Wb loop
642          
643          declare
644             
645             -- Current bit of Words
646             WordsBit : constant WBool := Words and 1;
647             
648          begin
649             
650             -- Shift at the current shiftness
651             for i in ShiftedN'First        .. ShiftedN'Last - S loop
652                ShiftedN(i) := W_Mux(ShiftedN(i), ShiftedN(i + S), WordsBit);
653             end loop;
654             
655             -- Fill the emptiness
656             for i in ShiftedN'Last - S + 1 .. ShiftedN'Last loop
657                ShiftedN(i) := W_Mux(ShiftedN(i), 0,               WordsBit);
658             end loop;
659             
660             -- Go to the next shiftness level
661             S     := S * 2;
662             Words := Shift_Right(Words, 1);
663             
664          end;
665          
666       end loop;
667       
668    end FZ_Quiet_ShiftRight;
669    
670    
671    -- Constant-time arbitrary Left-Shift.
672    procedure FZ_Quiet_ShiftLeft(N        : in     FZ;
673                                 ShiftedN : in out FZ;
674                                 Count    : in     FZBit_Index) is
675       
676       -- Total number of bit positions to shift by
677       C     : constant Word     := Word(Count);
678       
679       -- Number of sub-Word bit positions to shift by
680       Bits  : constant Natural  := Natural(C and (2**BitnessLog2 - 1));
681       
682       -- The Bitness of N's Length
683       Wb    : constant Positive := FZ_Bitness_Log2(N);
684       
685       -- Number of whole-Word bitnesses to shift by
686       Words : Word              := Shift_Right(C, BitnessLog2);
687       
688       -- Current 'shiftness level'
689       S     : Indices           := 1;
690       
691    begin
692       
693       -- Subword shift first:
694       if HaveBarrelShifter then
695          -- If permitted, use iron shifter:
696          FZ_ShiftLeft(N, ShiftedN, Bits);
697       else
698          -- Otherwise, use the soft subword shifter:
699          FZ_Quiet_ShiftLeft_SubW_Soft(N, ShiftedN, Bits);
700       end if;
701       
702       -- Then whole-Word shift:
703       for i in 1 .. Wb loop
704          
705          declare
706             
707             -- Current bit of Words
708             WordsBit : constant WBool := Words and 1;
709             
710          begin
711             
712             -- Shift at the current shiftness
713             for i in reverse ShiftedN'First + S .. ShiftedN'Last loop
714                ShiftedN(i) := W_Mux(ShiftedN(i), ShiftedN(i - S), WordsBit);
715             end loop;
716             
717             -- Fill the emptiness
718             for i in ShiftedN'First             .. ShiftedN'First + S - 1 loop
719                ShiftedN(i) := W_Mux(ShiftedN(i), 0,               WordsBit);
720             end loop;
721             
722             -- Go to the next shiftness level
723             S     := S * 2;
724             Words := Shift_Right(Words, 1);
725             
726          end;
727          
728       end loop;
729       
730    end FZ_Quiet_ShiftLeft;
731    
732 end FZ_QShft;
-(0 . 0)(1 . 52)
737 ------------------------------------------------------------------------------
738 ------------------------------------------------------------------------------
739 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'.               --
740 --                                                                          --
741 -- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org )                      --
742 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
743 --                                                                          --
744 -- You do not have, nor can you ever acquire the right to use, copy or      --
745 -- distribute this software ; Should you use this software for any purpose, --
746 -- or copy and distribute it to anyone or in any manner, you are breaking   --
747 -- the laws of whatever soi-disant jurisdiction, and you promise to         --
748 -- continue doing so for the indefinite future. In any case, please         --
749 -- always : read and understand any software ; verify any PGP signatures    --
750 -- that you use - for any purpose.                                          --
751 --                                                                          --
752 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm .     --
753 ------------------------------------------------------------------------------
754 ------------------------------------------------------------------------------
755 
756 with Words;   use Words;
757 with FZ_Type; use FZ_Type;
758 
759 
760 package FZ_QShft is
761    
762    pragma Pure;
763    
764    -- Constant-time subword shift, for where there is no barrel shifter
765    procedure FZ_Quiet_ShiftRight_SubW_Soft(N        : in FZ;
766                                            ShiftedN : in out FZ;
767                                            Count    : in WBit_Index);
768    pragma Inline_Always(FZ_Quiet_ShiftRight_SubW_Soft);
769    
770    -- Constant-time subword shift, for where there is no barrel shifter
771    procedure FZ_Quiet_ShiftLeft_SubW_Soft(N        : in FZ;
772                                           ShiftedN : in out FZ;
773                                           Count    : in WBit_Index);
774    pragma Inline_Always(FZ_Quiet_ShiftLeft_SubW_Soft);
775    
776    -- Constant-time arbitrary right-shift.
777    procedure FZ_Quiet_ShiftRight(N        : in     FZ;
778                                  ShiftedN : in out FZ;
779                                  Count    : in     FZBit_Index);
780    pragma Inline_Always(FZ_Quiet_ShiftRight);
781    
782    -- Constant-time arbitrary left-shift.
783    procedure FZ_Quiet_ShiftLeft(N        : in     FZ;
784                                 ShiftedN : in out FZ;
785                                 Count    : in     FZBit_Index);
786    pragma Inline_Always(FZ_Quiet_ShiftLeft);
787    
788 end FZ_QShft;
- 9BE8930649F097919664873A6F502D6C0A2E67BB36DF1F61DB80B291162B2DE3644837694290FF253E045499F9EBD138D84CC7D127A3B7C91838E550DC01836D(38 . 4)(38 . 7)
793    -- Bits per Byte
794    ByteBits           : constant Positive := 8;
795    
796    -- Whether we have a barrel shifter:
797    HaveBarrelShifter : constant Boolean := True;
798    
799 end Iron;
- 2D76A6B3E1EA5A1719CFFE798CA719A0D80533EED7E4A87B553398DB655A5CAF2EA888BA48ED2FD700ED292CFD036CF1AA093D38E2C4A22A0154DBE90D7FA112(2 . 7)(2 . 7)
804 ------------------------------------------------------------------------------
805 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. --
806 -- --
807 -- (C) 2017 Stanislav Datskovskiy ( www.loper-os.org ) --
808 -- (C) 2018 Stanislav Datskovskiy ( www.loper-os.org ) --
809 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html --
810 -- --
811 -- You do not have, nor can you ever acquire the right to use, copy or --
(55 . 9)(55 . 10)
813 -- +-+-+-+-----+--------------+-----+----------------+
814 -- | | 'Carry' out: | | 'Borrow' out: |
815 -- +-+-+-+-----+--------------+-----+----------------+
816 -- | | | | |(a and b) or | |(~a and b) or |
817 -- |A|B|C|A+B+C| ((a or b) and|A-B-C| ((~a or b) and |
818 -- | | | | | ~(A+B+C)) | | (A-B-C)) |
819 -- | | | | |(a and b) or | |(b and (A-B-C)) |
820 -- |A|B|C|A+B+C| ((a or b) and|A-B-C| or |
821 -- | | | | | ~(A+B+C)) | |((b or (A-B-C)) |
822 -- | | | | | | | and ~a) |
823 -- +-+-+-+-----+--------------+-----+----------------+
824 -- |0|0|0| 0 | 0 | 0 | 0 |
825 -- +-+-+-+-----+--------------+-----+----------------+
(78 . 7)(79 . 6)
827 -- This base case extends to any N bit register, since
828 -- both equations depend ~strictly~ on A, B, and C.
829
830
831 -- Without any branching: if Sel == 0, return A; if Sel == 1, return B.
832 function W_Mux(A : in Word; B : in Word; Sel : in WBool) return Word is
833 begin