# Finite Field Arithmetic

```   1 ------------------------------------------------------------------------------
2 ------------------------------------------------------------------------------
3 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'.               --
4 --                                                                          --
5 -- (C) 2019 Stanislav Datskovskiy ( www.loper-os.org )                      --
6 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     --
7 --                                                                          --
8 -- You do not have, nor can you ever acquire the right to use, copy or      --
9 -- distribute this software ; Should you use this software for any purpose, --
10 -- or copy and distribute it to anyone or in any manner, you are breaking   --
11 -- the laws of whatever soi-disant jurisdiction, and you promise to         --
12 -- continue doing so for the indefinite future. In any case, please         --
13 -- always : read and understand any software ; verify any PGP signatures    --
14 -- that you use - for any purpose.                                          --
15 --                                                                          --
17 ------------------------------------------------------------------------------
18 ------------------------------------------------------------------------------
19
20 with Words;   use Words;
21 with FZ_Type; use FZ_Type;
22
23
24 -- Fundamental Arithmetic operators on FZ:
25 package FZ_Arith is
26
27    pragma Pure;
28
29    -- Destructive Add: X := X + Y; Overflow := Carry; optional OF_In
30    procedure FZ_Add_D(X          : in out FZ;
31                       Y          : in     FZ;
32                       Overflow   : out    WBool;
33                       OF_In      : in     WBool := 0);
35
36    -- Destructive Add: X := X + W; Overflow := Carry
37    procedure FZ_Add_D_W(X        : in out FZ;
38                         W        : in     Word;
39                         Overflow : out    WBool);
41
42    -- Sum := X + Y; Overflow := Carry
43    procedure FZ_Add(X          : in    FZ;
44                     Y          : in    FZ;
45                     Sum        : out   FZ;
46                     Overflow   : out   WBool);
48
49    -- Gate = 1: Sum := X + Y; Overflow := Carry
50    -- Gate = 0: Sum := X;     Overflow := 0
51    procedure FZ_Add_Gated_O(X          : in  FZ;
52                             Y          : in  FZ;
53                             Gate       : in  WBool;
54                             Sum        : out FZ;
55                             Overflow   : out WBool);
57
58    -- Same as FZ_Add_Gated_O, but without Overflow output
59    procedure FZ_Add_Gated(X          : in  FZ;
60                           Y          : in  FZ;
61                           Gate       : in  WBool;
62                           Sum        : out FZ);
64
65    -- Destructive Subtract: X := X - Y; Underflow := Borrow
66    procedure FZ_Sub_D(X          : in out FZ;
67                       Y          : in     FZ;
68                       Underflow  : out    WBool);
69    pragma Inline_Always(FZ_Sub_D);
70
71    -- Difference := X - W; Underflow := Borrow
72    procedure FZ_Sub_W(X          : in  FZ;
73                       W          : in  Word;
74                       Difference : out FZ;
75                       Underflow  : out WBool);
76    pragma Inline_Always(FZ_Sub_W);
77
78    -- Difference := X - Y; Underflow := Borrow
79    procedure FZ_Sub(X          : in  FZ;
80                     Y          : in  FZ;
81                     Difference : out FZ;
82                     Underflow  : out WBool);
83    pragma Inline_Always(FZ_Sub);
84
85    -- Destructive: If Cond is 1, NotN := ~N; otherwise NotN := N.
86    procedure FZ_Not_Cond_D(N    : in out FZ;
87                            Cond : in     WBool);
88    pragma Inline_Always(FZ_Not_Cond_D);
89
90    -- Subtractor that gets absolute value if underflowed, in const. time
91    procedure FZ_Sub_Abs(X          : in FZ;
92                         Y          : in FZ;
93                         Difference : out FZ;
94                         Underflow  : out WBool);
95    pragma Inline_Always(FZ_Sub_Abs);
96
97 end FZ_Arith;
```