init commit
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Utilities;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Math.Raw;
|
||||
|
||||
internal abstract class Mod
|
||||
{
|
||||
private static readonly SecureRandom RandomSource = new SecureRandom();
|
||||
|
||||
public static void Invert(uint[] p, uint[] x, uint[] z)
|
||||
{
|
||||
int num = p.Length;
|
||||
if (Nat.IsZero(num, x))
|
||||
{
|
||||
throw new ArgumentException("cannot be 0", "x");
|
||||
}
|
||||
if (Nat.IsOne(num, x))
|
||||
{
|
||||
Array.Copy(x, 0, z, 0, num);
|
||||
return;
|
||||
}
|
||||
uint[] array = Nat.Copy(num, x);
|
||||
uint[] array2 = Nat.Create(num);
|
||||
array2[0] = 1u;
|
||||
int xc = 0;
|
||||
if ((array[0] & 1) == 0)
|
||||
{
|
||||
InversionStep(p, array, num, array2, ref xc);
|
||||
}
|
||||
if (Nat.IsOne(num, array))
|
||||
{
|
||||
InversionResult(p, xc, array2, z);
|
||||
return;
|
||||
}
|
||||
uint[] array3 = Nat.Copy(num, p);
|
||||
uint[] array4 = Nat.Create(num);
|
||||
int xc2 = 0;
|
||||
int num2 = num;
|
||||
while (true)
|
||||
{
|
||||
if (array[num2 - 1] == 0 && array3[num2 - 1] == 0)
|
||||
{
|
||||
num2--;
|
||||
}
|
||||
else if (Nat.Gte(num, array, array3))
|
||||
{
|
||||
Nat.SubFrom(num, array3, array);
|
||||
xc += Nat.SubFrom(num, array4, array2) - xc2;
|
||||
InversionStep(p, array, num2, array2, ref xc);
|
||||
if (Nat.IsOne(num, array))
|
||||
{
|
||||
InversionResult(p, xc, array2, z);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Nat.SubFrom(num, array, array3);
|
||||
xc2 += Nat.SubFrom(num, array2, array4) - xc;
|
||||
InversionStep(p, array3, num2, array4, ref xc2);
|
||||
if (Nat.IsOne(num, array3))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
InversionResult(p, xc2, array4, z);
|
||||
}
|
||||
|
||||
public static uint[] Random(uint[] p)
|
||||
{
|
||||
int num = p.Length;
|
||||
uint[] array = Nat.Create(num);
|
||||
uint num2 = p[num - 1];
|
||||
num2 |= num2 >> 1;
|
||||
num2 |= num2 >> 2;
|
||||
num2 |= num2 >> 4;
|
||||
num2 |= num2 >> 8;
|
||||
num2 |= num2 >> 16;
|
||||
do
|
||||
{
|
||||
byte[] array2 = new byte[num << 2];
|
||||
RandomSource.NextBytes(array2);
|
||||
Pack.BE_To_UInt32(array2, 0, array);
|
||||
uint[] array4;
|
||||
uint[] array3 = (array4 = array);
|
||||
int num3 = num - 1;
|
||||
nint num4 = num3;
|
||||
array3[num3] = array4[num4] & num2;
|
||||
}
|
||||
while (Nat.Gte(num, array, p));
|
||||
return array;
|
||||
}
|
||||
|
||||
public static void Add(uint[] p, uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
int len = p.Length;
|
||||
if (Nat.Add(len, x, y, z) != 0)
|
||||
{
|
||||
Nat.SubFrom(len, p, z);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Subtract(uint[] p, uint[] x, uint[] y, uint[] z)
|
||||
{
|
||||
int len = p.Length;
|
||||
if (Nat.Sub(len, x, y, z) != 0)
|
||||
{
|
||||
Nat.AddTo(len, p, z);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InversionResult(uint[] p, int ac, uint[] a, uint[] z)
|
||||
{
|
||||
if (ac < 0)
|
||||
{
|
||||
Nat.Add(p.Length, a, p, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(a, 0, z, 0, p.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x, ref int xc)
|
||||
{
|
||||
int len = p.Length;
|
||||
int num = 0;
|
||||
while (u[0] == 0)
|
||||
{
|
||||
Nat.ShiftDownWord(uLen, u, 0u);
|
||||
num += 32;
|
||||
}
|
||||
int trailingZeroes = GetTrailingZeroes(u[0]);
|
||||
if (trailingZeroes > 0)
|
||||
{
|
||||
Nat.ShiftDownBits(uLen, u, trailingZeroes, 0u);
|
||||
num += trailingZeroes;
|
||||
}
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
if ((x[0] & 1) != 0)
|
||||
{
|
||||
if (xc < 0)
|
||||
{
|
||||
xc += (int)Nat.AddTo(len, p, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
xc += Nat.SubFrom(len, p, x);
|
||||
}
|
||||
}
|
||||
Nat.ShiftDownBit(len, x, (uint)xc);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetTrailingZeroes(uint x)
|
||||
{
|
||||
int num = 0;
|
||||
while ((x & 1) == 0)
|
||||
{
|
||||
x >>= 1;
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user