blob: 88319f40588fd95b6733f8373eddca3d9d247f63 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
using System;
using System.Diagnostics;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Rfc8032
{
internal static class Wnaf
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
internal static void GetSignedVar(ReadOnlySpan<uint> n, int width, Span<sbyte> ws)
#else
internal static void GetSignedVar(uint[] n, int width, sbyte[] ws)
#endif
{
Debug.Assert(2 <= width && width <= 8);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
Span<uint> t = n.Length <= 64
? stackalloc uint[n.Length * 2]
: new uint[n.Length * 2];
#else
uint[] t = new uint[n.Length * 2];
#endif
{
uint c = 0U - (n[n.Length - 1] >> 31);
int tPos = t.Length, i = n.Length;
while (--i >= 0)
{
uint next = n[i];
t[--tPos] = (next >> 16) | (c << 16);
t[--tPos] = c = next;
}
}
int j = 0, lead = 32 - width, sign = 0;
for (int i = 0; i < t.Length; ++i, j -= 16)
{
uint word = t[i];
while (j < 16)
{
int word16 = (int)(word >> j);
int skip = Integers.NumberOfTrailingZeros((sign ^ word16) | 0x00010000);
if (skip > 0)
{
j += skip;
continue;
}
int digit = (word16 | 1) << lead;
sign = digit >> 31;
ws[(i << 4) + j] = (sbyte)(digit >> lead);
j += width;
}
}
Debug.Assert(sign == (int)n[n.Length - 1] >> 31);
}
}
}
|