ReactOS 0.4.17-dev-1005-g171e1de
recoding.c
Go to the documentation of this file.
1//
2// recoding.c Algorithms for recoding the factors / exponents in various implementations
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6//
7
8#include "precomp.h"
9
10//
11// The following is an adaptation of algorithm 6: "Protected
12// odd-only recoding algorithm for the fixed-window representation"
13// from the paper
14// "Selecting Elliptic Curves for Cryptography: An Efficiency and
15// Security Analysis" by Bos, Costello, Longa, and Naehrig
16//
17// Input: odd integer k \in [1,GOrd], window width w>=2, and
18// t = ceil( GOrdBitsize / w-1 )
19//
20// Output: (k_t, ... , k_0) where k_i \in {+-1, +-3, ..., +-(2^(w-1) -1)}
21//
22// Algorithm:
23// for i=0 to (t-1) do
24// k_i = (k mod 2^w) - 2^(w-1)
25// k = (k-k_i)/2^(w-1)
26// k_t = k mod 2^(w-1)
27// return (k_t, ..., k_0)
28//
29// Remarks:
30// 1. An invariant of the main loop is that (k > 0 and k odd). This means
31// that all k_i's are odd and that k_t > 0.
32// 2. We will store the values of k_i's as absolute values and signs in
33// absofKIs and sigofKIs arrays, resp. The sigofKIs[i] is 0xffffffff if
34// k_i < 0, otherwise it is 0.
35// 3. In the multiplication algorithm we always access the precomputed point
36// P[(|k_i|-1)/2]. Therefore here we just shift the |k_i| value left by
37// one bit before storing it in absofKIs table.
38// 4. Caller should check k in range [1,GOrd] to ensure use of recoding will
39// give correct results. This algorithm always recodes the t * (w-1) least
40// significant bits of the provided k, interpreted as an unsigned integer.
41//
42VOID
45 UINT32 W,
48 _Out_writes_( nRecodedDigits )
49 PUINT32 absofKIs,
50 _Out_writes_( nRecodedDigits )
51 PUINT32 sigofKIs,
52 UINT32 nRecodedDigits )
53{
54 UINT32 T1 = 0;
55 UINT32 T2 = 0;
56 UINT32 mask = ~(0xffffffff << W); // Window mask = 2^w - 1 (e.g. 0x0000003f for w = 6)
57 UINT32 smask = 0x1 << (W-1); // Sign mask = 2^(w-1) (e.g. 0x00000020 for w = 6)
58
59 SYMCRYPT_ASSERT( W < 32 );
60
61 for (UINT32 i=0; i < nRecodedDigits - 1; i++)
62 {
63 T1 = SymCryptIntGetValueLsbits32( piK ) & mask; // T1 = k mod 2^W
64
65 // At this point if the w-th bit of T1 is 1 then we know that T1 > 2^(w-1)
66 // (Since k = odd is a loop invariant).
67 //
68 // In this case, (case A), T1 & ~smask is equal to (k mod 2^w) - 2^(w-1) = k_i = |k_i|.
69 //
70 // Otherwise, (case B), we know that T1 < 2^(w-1). Therefore 2^(w-1) - T1 = |k_i|.
71
72 sigofKIs[i] = SYMCRYPT_MASK32_ZERO( T1 & smask ); // If the sign of k_i is - this mask is set to 0xffffffff. (Case B)
73
74 T2 = T1 & ~smask; // |k_i| in case A
75 T1 = smask - T1; // |k_i| in case B
76
77 absofKIs[i] = ((T1 & sigofKIs[i]) | (T2 & ~sigofKIs[i])) >> 1; // Setting (masked) the absolute value of k_i in absofKIs (divided by 2)
78
79 SymCryptIntSubUint32( piK, T2, piTmp ); // This gives k - k_i in case (A)
80 SymCryptIntAddUint32( piK, T1, piK ); // This gives k - k_i in case (B)
81
82 SymCryptIntMaskedCopy( piTmp, piK, ~sigofKIs[i] ); // Copy the result to piK in case (B)
83
84 SymCryptIntDivPow2( piK, W-1, piK ); // k := k / 2^(w-1)
85 }
86
87 // The last sign is positive given k < GOrd => k_t < 2^w
88 sigofKIs[nRecodedDigits - 1] = 0;
89 // Belts and braces, select only the bottom w-1 bits (ensure all absofKIs represent odd values in range [1,2^(w-1)-1])
90 absofKIs[nRecodedDigits - 1] = (SymCryptIntGetValueLsbits32( piK ) & mask & ~smask) >> 1;
91}
92
93//
94// The following is an algorithm for computing the width-w NAF of a positive integer.
95//
96// Input: integer k \in [1,GOrd), window width w>=2, and nRecodedDigits = GOrdBitsize + 1
97//
98// Output: (k_(nRecodedDigits-1), ... , k_0) where k_i \in {0, +-1, +-3, ..., +-(2^(w-1) -1)}
99//
100// Algorithm:
101// for i = 0 to (nRecodedDigits-1)
102// if (k is odd)
103// k_i = (k mods 2^w)
104// k = k - k_i
105// else
106// k_i = 0
107// k = k/2
108// return (k_(nRecodedDigits-1), ..., k_0)
109//
110// Note: k mods 2^w is the integer u with (u == k mod 2^w) and (-2^(w-1) <= u < 2^(w-1) ).
111//
112// Remarks:
113// 1. The above algorithm and the implementation are NOT SIDE-CHANNEL SAFE.
114// Therefore, it should only be used when the SYMCRYPT_FLAG_DATA_PUBLIC is
115// specified.
116// 2. The multiplication algorithm uses |k_i|/2 as indexes. Therefore we will shift left
117// the absolute value of k_i by 1 bit and store only |k_i|/2.
118// 3. Since now the k_i's can be zero we will store the following in sigofKIs:
119// sigofKIs[i] = 0x00000001 if k_i > 0
120// sigofKIs[i] = 0x00000000 if k_i = 0
121// sigofKIs[i] = 0xffffffff if k_i < 0
122//
123VOID
126 UINT32 W,
128 _Out_writes_( nRecodedDigits )
129 PUINT32 absofKIs,
130 _Out_writes_( nRecodedDigits )
131 PUINT32 sigofKIs,
132 UINT32 nRecodedDigits )
133{
134 UINT32 T1 = 0;
135 UINT32 mask = ~(0xffffffff << W); // Window mask = 2^w - 1 (e.g. 0x0000003f for w = 6)
136 UINT32 modulus = mask + 1; // 2^w
137 UINT32 smask = 0x1 << (W-1); // Sign mask = 2^(w-1) (e.g. 0x00000020 for w = 6)
138
139 SYMCRYPT_ASSERT( W < 32 );
140
141 for (UINT32 i=0; i < nRecodedDigits; i++)
142 {
143 T1 = SymCryptIntGetValueLsbits32( piK ) & mask; // T1 = k mod 2^W
144
145 if (T1 & 0x1)
146 {
147 if (T1 > smask)
148 {
149 sigofKIs[i] = 0xffffffff;
150 absofKIs[i] = modulus - T1; // 2^W - T1 = |T1 - 2^W|
151 SymCryptIntAddUint32( piK, absofKIs[i], piK ); // k-k_i
152 }
153 else
154 {
155 // Here (k mod 2^W) is already in the specified range
156 sigofKIs[i] = 0x00000001;
157 absofKIs[i] = T1;
158 SymCryptIntSubUint32( piK, absofKIs[i], piK ); // k-k_i
159 }
160 }
161 else
162 {
163 absofKIs[i] = 0;
164 sigofKIs[i] = 0;
165 }
166
167 SymCryptIntDivPow2( piK, 1, piK ); // k := k / 2
168 }
169}
170
171//
172// The following is an algorithm similar to the above
173// but the output is only non-negative (odd) digits.
174//
175// Requirements:
176// nRecodedDigits == nBitsExp
177//
178VOID
181 UINT32 W,
183 UINT32 nBitsExp,
184 _Out_writes_( nRecodedDigits )
185 PUINT32 absofKIs,
186 UINT32 nRecodedDigits )
187{
188 UINT32 T1 = 0;
189 UINT32 cntrZ = W; // Counter that specifies when we filled the last non-zero NAF digit
190
191 SYMCRYPT_ASSERT( nRecodedDigits <= SymCryptIntBitsizeOfObject( piK ) );
192
193 for (UINT32 i=0; i < nRecodedDigits; i++)
194 {
195 T1 = SymCryptIntGetBits( piK, i, SYMCRYPT_MIN(W, nBitsExp-i) ); // Get a batch of W bits (but don't go over nBitsExp)
196
197 if ((cntrZ>=W) && ((T1 & 0x01) > 0)) // Only store odd digits
198 {
199 absofKIs[i] = T1;
200 cntrZ = 0;
201 }
202 else
203 {
204 absofKIs[i] = 0;
205 }
206
207 cntrZ++; // Prepare the counter for the next iteration
208 }
209}
unsigned int * PUINT32
Definition: basetsd.h:119
#define W(I)
GLenum GLint GLuint mask
Definition: glext.h:6028
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _In_
Definition: no_sal2.h:158
VOID SYMCRYPT_CALL SymCryptFixedWindowRecoding(UINT32 W, _Inout_ PSYMCRYPT_INT piK, _Inout_ PSYMCRYPT_INT piTmp, _Out_writes_(nRecodedDigits) PUINT32 absofKIs, _Out_writes_(nRecodedDigits) PUINT32 sigofKIs, UINT32 nRecodedDigits)
Definition: recoding.c:44
VOID SYMCRYPT_CALL SymCryptWidthNafRecoding(UINT32 W, _Inout_ PSYMCRYPT_INT piK, _Out_writes_(nRecodedDigits) PUINT32 absofKIs, _Out_writes_(nRecodedDigits) PUINT32 sigofKIs, UINT32 nRecodedDigits)
Definition: recoding.c:125
VOID SYMCRYPT_CALL SymCryptPositiveWidthNafRecoding(UINT32 W, _In_ PCSYMCRYPT_INT piK, UINT32 nBitsExp, _Out_writes_(nRecodedDigits) PUINT32 absofKIs, UINT32 nRecodedDigits)
Definition: recoding.c:180
Definition: polytest.cpp:36
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
#define SYMCRYPT_CALL
#define SYMCRYPT_MIN(_a, _b)
const SYMCRYPT_INT * PCSYMCRYPT_INT
#define SYMCRYPT_MASK32_ZERO(_v)
SYMCRYPT_INT * PSYMCRYPT_INT
UINT32 SYMCRYPT_CALL SymCryptIntGetValueLsbits32(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:270
VOID SYMCRYPT_CALL SymCryptIntDivPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:364
UINT32 SYMCRYPT_CALL SymCryptIntBitsizeOfObject(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:200
VOID SYMCRYPT_CALL SymCryptIntMaskedCopy(_In_ PCSYMCRYPT_INT piSrc, _Inout_ PSYMCRYPT_INT piDst, UINT32 mask)
Definition: a_dispatch.c:170
UINT32 SYMCRYPT_CALL SymCryptIntAddUint32(_In_ PCSYMCRYPT_INT piSrc1, UINT32 u32Src2, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:284
UINT32 SYMCRYPT_CALL SymCryptIntSubUint32(_In_ PCSYMCRYPT_INT piSrc1, UINT32 Src2, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:314
UINT32 SYMCRYPT_CALL SymCryptIntGetBits(_In_ PCSYMCRYPT_INT piSrc, UINT32 iBit, UINT32 nBits)
Definition: a_dispatch.c:403
uint32_t UINT32
Definition: typedefs.h:59