blob: cc6e3704f2819a9ed5cba31b58e8f81193d9e70c (
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
65
|
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;
}
}
uint sign = 0U;
int j = 0, lead = 32 - width;
for (int i = 0; i < t.Length; ++i, j -= 16)
{
uint word = t[i];
while (j < 16)
{
uint word16 = word >> j;
int skip = Integers.NumberOfTrailingZeros((int)((sign ^ word16) | 0xFFFF0000U));
if (skip > 0)
{
j += skip;
continue;
}
int digit = ((int)word16 | 1) << lead;
sign = (uint)(digit >> 31);
ws[(i << 4) + j] = (sbyte)(digit >> lead);
j += width;
}
}
Debug.Assert(sign == n[n.Length - 1] >> 31);
}
}
}
|