Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ModulusP.cs
1using System;
2using System.Numerics;
3
5{
9 public class ModulusP
10 {
14 protected readonly BigInteger p;
15
20 public ModulusP(BigInteger Prime)
21 {
22 this.p = Prime;
23 }
24
31 public BigInteger Add(BigInteger a, BigInteger b)
32 {
33 BigInteger Sum = a + b;
34
35 if (Sum >= this.p)
36 {
37 Sum -= this.p;
38 if (Sum >= this.p)
39 Sum %= this.p;
40 }
41
42 return Sum;
43 }
44
51 public BigInteger Subtract(BigInteger a, BigInteger b)
52 {
53 BigInteger Diff = a - b;
54 if (Diff.Sign < 0)
55 {
56 Diff += this.p;
57 if (Diff.Sign < 0)
58 {
59 Diff %= this.p;
60 if (Diff.Sign < 0)
61 Diff += this.p;
62 }
63 }
64 else if (Diff >= this.p)
65 {
66 Diff -= this.p;
67 if (Diff >= this.p)
68 Diff %= this.p;
69 }
70
71 return Diff;
72 }
73
80 public BigInteger Multiply(BigInteger a, BigInteger b)
81 {
82 return BigInteger.Remainder(a * b, this.p);
83 }
84
91 public BigInteger Divide(BigInteger a, BigInteger b)
92 {
93 b = this.Invert(b);
94 return BigInteger.Remainder(a * b, this.p);
95 }
96
102 public BigInteger Negate(BigInteger x)
103 {
104 return this.p - x;
105 }
106
112 public BigInteger Invert(BigInteger x)
113 {
114 if (x.Sign < 0)
115 {
116 x = BigInteger.Remainder(x, p);
117 if (x.Sign < 0)
118 x += p;
119 }
120 else if (x >= p)
121 x = BigInteger.Remainder(x, p);
122
123 BigInteger i = this.p;
124 BigInteger j = x;
125 BigInteger y1 = BigInteger.One;
126 BigInteger y2 = BigInteger.Zero;
127 BigInteger q, y;
128
129 do
130 {
131 q = BigInteger.DivRem(i, j, out BigInteger r);
132 y = y2 - y1 * q;
133 i = j;
134 j = r;
135 y2 = y1;
136 y1 = y;
137 }
138 while (!j.IsZero);
139
140 if (!i.IsOne)
141 throw new ArgumentException("Number not invertible.", nameof(x));
142
143 BigInteger Result = BigInteger.Remainder(y2, this.p);
144 if (Result.Sign < 0)
145 Result += this.p;
146
147 return Result;
148 }
149
155 public BigInteger Sqrt(BigInteger N)
156 {
157 return SqrtModP(N, this.p);
158 }
159
166 public static BigInteger SqrtModP(BigInteger N, BigInteger p)
167 {
168 // See: https://en.wikipedia.org/wiki/Tonelli–Shanks_algorithm
169
170 if (N.Sign < 0)
171 {
172 N = BigInteger.Remainder(N, p);
173 if (N.Sign < 0)
174 N += p;
175 }
176 else if (N >= p)
177 N = BigInteger.Remainder(N, p);
178
179 BigInteger pm1d2 = (p - 1) / 2;
180 if (BigInteger.ModPow(N, pm1d2, p) != BigInteger.One)
181 throw new ArgumentException("No root available.", nameof(N));
182
183 BigInteger z = p - 1;
184 BigInteger m = z;
185 int s = 0;
186
187 while (m.IsEven)
188 {
189 s++;
190 m >>= 1;
191 }
192
193 while (BigInteger.ModPow(z, pm1d2, p) == BigInteger.One)
194 {
195 z--;
196 if (z.IsZero)
197 throw new InvalidOperationException("Nonresidue not found.");
198 }
199
200 BigInteger c = BigInteger.ModPow(z, m, p);
201 BigInteger c2 = BigInteger.Remainder(c * c, p);
202 BigInteger u = BigInteger.ModPow(N, m, p);
203 BigInteger v = BigInteger.ModPow(N, (m + 1) / 2, p);
204
205 while (--s > 0)
206 {
207 if (BigInteger.ModPow(u, BigInteger.Pow(2, s - 1), p) != BigInteger.One)
208 {
209 u = BigInteger.Remainder(u * c2, p);
210 v = BigInteger.Remainder(v * c, p);
211 }
212
213 c = c2;
214 c2 = BigInteger.Remainder(c * c, p);
215 }
216
217 return v;
218 }
219
225 public static int CalcBits(BigInteger n)
226 {
227 if (n.IsZero)
228 return 0;
229
230 return CalcBits(n.ToByteArray());
231 }
232
238 public static int CalcBits(byte[] A)
239 {
240 int c = A.Length - 1;
241 int i = c << 3;
242 byte b = A[c];
243
244 while (b > 0)
245 {
246 i++;
247 b >>= 1;
248 }
249
250 return i;
251 }
252
253 }
254}
Integer arithmetic, modulus a prime.
Definition: ModulusP.cs:10
BigInteger Sqrt(BigInteger N)
Computes sqrt(N) mod p.
Definition: ModulusP.cs:155
ModulusP(BigInteger Prime)
Integer arithmetic, modulus a prime.
Definition: ModulusP.cs:20
readonly BigInteger p
Base prime.
Definition: ModulusP.cs:14
BigInteger Invert(BigInteger x)
Inverts a number in the field Z[p].
Definition: ModulusP.cs:112
BigInteger Multiply(BigInteger a, BigInteger b)
Multiplies two numbers, modulus p
Definition: ModulusP.cs:80
static int CalcBits(BigInteger n)
Calculates the number of bits used.
Definition: ModulusP.cs:225
BigInteger Add(BigInteger a, BigInteger b)
Adds two numbers, modulus p
Definition: ModulusP.cs:31
static BigInteger SqrtModP(BigInteger N, BigInteger p)
Computes sqrt(N) mod p.
Definition: ModulusP.cs:166
BigInteger Divide(BigInteger a, BigInteger b)
Divides two numbers, modulus p
Definition: ModulusP.cs:91
BigInteger Subtract(BigInteger a, BigInteger b)
Subtracts two numbers, modulus p
Definition: ModulusP.cs:51
BigInteger Negate(BigInteger x)
Negates a number in the field Z[p].
Definition: ModulusP.cs:102
static int CalcBits(byte[] A)
Calculates the number of bits used in a binary encoded big integer.
Definition: ModulusP.cs:238