summaryrefslogtreecommitdiff
path: root/crypto_libraries/inc/nx_crypto_huge_number.h
blob: 70440ed7e6990cf618b5e1def2cb888f3b139403 (plain)
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/***************************************************************************
 * Copyright (c) 2024 Microsoft Corporation
 * Copyright (c) 2025-present Eclipse ThreadX Contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * SPDX-License-Identifier: MIT
 **************************************************************************/


/**************************************************************************/
/**************************************************************************/
/**                                                                       */
/** NetX Crypto Component                                                 */
/**                                                                       */
/**   Huge Number                                                         */
/**                                                                       */
/**************************************************************************/
/**************************************************************************/


/**************************************************************************/
/*                                                                        */
/*  APPLICATION INTERFACE DEFINITION                       RELEASE        */
/*                                                                        */
/*    nx_crypto_huge_number.h                             PORTABLE C      */
/*                                                           6.4.3        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Timothy Stapko, Microsoft Corporation                               */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This file defines the basic Application Interface (API) to the      */
/*    NetX Crypto huge number module.                                     */
/*                                                                        */
/**************************************************************************/

#ifndef NX_CRYPTO_HUGE_NUMBER_H
#define NX_CRYPTO_HUGE_NUMBER_H

/* Determine if a C++ compiler is being used.  If so, ensure that standard
   C is used to process the API information.  */
#ifdef __cplusplus

/* Yes, C++ compiler is present.  Use standard C.  */
extern   "C" {

#endif

/* Include the ThreadX and port-specific data type file.  */

#include "nx_crypto.h"

/* Return values for _nx_crypto_huge_number_compare */
#define NX_CRYPTO_HUGE_NUMBER_EQUAL   (0x0)
#define NX_CRYPTO_HUGE_NUMBER_LESS    (0x1)
#define NX_CRYPTO_HUGE_NUMBER_GREATER (0x2)
#define NX_CRYPTO_HUGE_NUMBER_ERROR   (0x3)


/* Define the base exponent of 2 for huge number.
 * Only 16 and 32 are supported. */
#ifndef NX_CRYPTO_HUGE_NUMBER_BITS
#define NX_CRYPTO_HUGE_NUMBER_BITS    32
#endif /* NX_CRYPTO_HUGE_NUMBER_BITS */

#if (NX_CRYPTO_HUGE_NUMBER_BITS == 32)
#ifndef ULONG64_DEFINED
#define ULONG64_DEFINED
#define ULONG64                       unsigned long long
#define LONG64                        long long
#endif
#define HN_BASE                       LONG
#define HN_BASE2                      LONG64
#define HN_UBASE                      ULONG
#define HN_UBASE2                     ULONG64
#define HN_MASK                       0xFFFFFFFF
#define HN_RADIX                      0x100000000
#define HN_SHIFT                      (sizeof(HN_BASE) << 3)
#define HN_SIZE_ROUND                 (sizeof(HN_BASE) - 1)
#define HN_SIZE_SHIFT                 2
#define HN_ULONG_TO_UBASE(v)          v
#elif (NX_CRYPTO_HUGE_NUMBER_BITS == 16)
#define HN_BASE                       SHORT
#define HN_BASE2                      LONG
#define HN_UBASE                      USHORT
#define HN_UBASE2                     ULONG
#define HN_MASK                       0xFFFF
#define HN_RADIX                      0x10000
#define HN_SHIFT                      (sizeof(HN_BASE) << 3)
#define HN_SIZE_ROUND                 (sizeof(HN_BASE) - 1)
#define HN_SIZE_SHIFT                 1
#define HN_ULONG_TO_UBASE(v)          (v) & HN_MASK, (v) >> HN_SHIFT
#else
#error "NX_CRYPTO_HUGE_NUMBER_BITS supports 16 and 32 only!"
#endif


/* Huge number structure - contains data pointer and size. */
typedef struct NX_CRYPTO_HUGE_NUMBER_STRUCT
{
    /* Stores a pointer to the number data which may be of arbitrary size. */
    HN_UBASE *nx_crypto_huge_number_data;

    /* The size of the data stored in the buffer, in number of digit. */
    UINT nx_crypto_huge_number_size;

    /* The size of the buffer itself, in number of bytes. */
    UINT nx_crypto_huge_buffer_size;

    /* Flag to indicate positive or negative value. */
    UINT nx_crypto_huge_number_is_negative;
} NX_CRYPTO_HUGE_NUMBER;


/* Misc macros for huge number. */

/* Initialize the buffer of huge number. */
#define NX_CRYPTO_HUGE_NUMBER_INITIALIZE(hn, buff, size)     \
    (hn) -> nx_crypto_huge_number_data = (HN_UBASE *)(buff); \
    (hn) -> nx_crypto_huge_number_size = 0;                  \
    (hn) -> nx_crypto_huge_buffer_size = (((size) + HN_SIZE_ROUND) >> HN_SIZE_SHIFT) << HN_SIZE_SHIFT;\
    (hn) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;    \
    (buff) = (buff) + (((size) + HN_SIZE_ROUND) >> HN_SIZE_SHIFT);

/* Is it an even huge number? */
#define NX_CRYPTO_HUGE_NUMBER_IS_EVEN(hn) \
    !((hn) -> nx_crypto_huge_number_data[0] & 1)

/* Set value of huge number between 0 and (HN_RADIX - 1). */
#define NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(hn, val)          \
    (hn) -> nx_crypto_huge_number_data[0] = (val);        \
    (hn) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE; \
    (hn) -> nx_crypto_huge_number_size = 1;

/* Initialize the buffer of huge number to variable between 0 and (HN_RADIX - 1). */
#define NX_CRYPTO_HUGE_NUMBER_INITIALIZE_DIGIT(hn, buff, val) \
    (hn) -> nx_crypto_huge_number_data = (HN_UBASE *)(buff);  \
    (hn) -> nx_crypto_huge_buffer_size = sizeof(HN_UBASE);        \
    NX_CRYPTO_HUGE_NUMBER_SET_DIGIT(hn, val)

/* Copy huge number from src to dst. */
#define NX_CRYPTO_HUGE_NUMBER_COPY(dst, src)                                                 \
    (dst) -> nx_crypto_huge_number_size = (src) -> nx_crypto_huge_number_size;               \
    (dst) -> nx_crypto_huge_number_is_negative = (src) -> nx_crypto_huge_number_is_negative; \
    NX_CRYPTO_MEMCPY((dst) -> nx_crypto_huge_number_data,                                              \
           (src) -> nx_crypto_huge_number_data,                                              \
           (src) -> nx_crypto_huge_number_size << HN_SIZE_SHIFT);


/* Function prototypes */

VOID _nx_crypto_huge_number_adjust_size(NX_CRYPTO_HUGE_NUMBER *val);
UINT _nx_crypto_huge_number_setup(NX_CRYPTO_HUGE_NUMBER *number, const UCHAR *byte_stream, UINT size);
UINT _nx_crypto_huge_number_extract(NX_CRYPTO_HUGE_NUMBER *number, UCHAR *byte_stream,
                                    UINT byte_stream_size, UINT *huge_number_size);
UINT _nx_crypto_huge_number_extract_fixed_size(NX_CRYPTO_HUGE_NUMBER *number,
                                               UCHAR *byte_stream, UINT byte_stream_size);
UINT _nx_crypto_huge_number_rbg(UINT bits, UCHAR *result);
UINT _nx_crypto_huge_number_compare(NX_CRYPTO_HUGE_NUMBER *left, NX_CRYPTO_HUGE_NUMBER *right);
UINT _nx_crypto_huge_number_compare_unsigned(NX_CRYPTO_HUGE_NUMBER *left,
                                             NX_CRYPTO_HUGE_NUMBER *right);
UINT _nx_crypto_huge_number_is_zero(NX_CRYPTO_HUGE_NUMBER *x);
VOID _nx_crypto_huge_number_add(NX_CRYPTO_HUGE_NUMBER *left, NX_CRYPTO_HUGE_NUMBER *right);
VOID _nx_crypto_huge_number_add_unsigned(NX_CRYPTO_HUGE_NUMBER *left, NX_CRYPTO_HUGE_NUMBER *right);
VOID _nx_crypto_huge_number_subtract(NX_CRYPTO_HUGE_NUMBER *left, NX_CRYPTO_HUGE_NUMBER *right);
VOID _nx_crypto_huge_number_subtract_unsigned(NX_CRYPTO_HUGE_NUMBER *left,
                                              NX_CRYPTO_HUGE_NUMBER *right,
                                              NX_CRYPTO_HUGE_NUMBER *result);
VOID _nx_crypto_huge_number_add_digit(NX_CRYPTO_HUGE_NUMBER *value, HN_UBASE digit);
VOID _nx_crypto_huge_number_subtract_digit(NX_CRYPTO_HUGE_NUMBER *value, HN_UBASE digit);
VOID _nx_crypto_huge_number_add_digit_unsigned(NX_CRYPTO_HUGE_NUMBER *value, HN_UBASE digit);
VOID _nx_crypto_huge_number_subtract_digit_unsigned(NX_CRYPTO_HUGE_NUMBER *value, HN_UBASE digit);
VOID _nx_crypto_huge_number_multiply(NX_CRYPTO_HUGE_NUMBER *left,
                                     NX_CRYPTO_HUGE_NUMBER *right,
                                     NX_CRYPTO_HUGE_NUMBER *result);
VOID _nx_crypto_huge_number_multiply_digit(NX_CRYPTO_HUGE_NUMBER *value,
                                           HN_UBASE digit,
                                           NX_CRYPTO_HUGE_NUMBER *result);
VOID _nx_crypto_huge_number_square(NX_CRYPTO_HUGE_NUMBER *value, NX_CRYPTO_HUGE_NUMBER *result);
VOID _nx_crypto_huge_number_modulus(NX_CRYPTO_HUGE_NUMBER *dividend, NX_CRYPTO_HUGE_NUMBER *divisor);
VOID _nx_crypto_huge_number_shift_left(NX_CRYPTO_HUGE_NUMBER *x, UINT shift);
VOID _nx_crypto_huge_number_shift_right(NX_CRYPTO_HUGE_NUMBER *x, UINT shift);
UINT _nx_crypto_huge_number_inverse_modulus_prime(NX_CRYPTO_HUGE_NUMBER *a,
                                                  NX_CRYPTO_HUGE_NUMBER *p,
                                                  NX_CRYPTO_HUGE_NUMBER *r,
                                                  HN_UBASE *scratch);
UINT _nx_crypto_huge_number_inverse_modulus(NX_CRYPTO_HUGE_NUMBER *a,
                                            NX_CRYPTO_HUGE_NUMBER *m,
                                            NX_CRYPTO_HUGE_NUMBER *r,
                                            HN_UBASE *scratch);
VOID _nx_crypto_huge_number_mont(NX_CRYPTO_HUGE_NUMBER *m, UINT mi,
                                 NX_CRYPTO_HUGE_NUMBER *x,
                                 NX_CRYPTO_HUGE_NUMBER *y,
                                 NX_CRYPTO_HUGE_NUMBER *result);
VOID _nx_crypto_huge_number_power_modulus(NX_CRYPTO_HUGE_NUMBER *number,
                                          NX_CRYPTO_HUGE_NUMBER *exponent,
                                          NX_CRYPTO_HUGE_NUMBER *modulus,
                                          NX_CRYPTO_HUGE_NUMBER *result,
                                          HN_UBASE *scratch);
VOID _nx_crypto_huge_number_mont_power_modulus(NX_CRYPTO_HUGE_NUMBER *x,
                                               NX_CRYPTO_HUGE_NUMBER *e,
                                               NX_CRYPTO_HUGE_NUMBER *m,
                                               NX_CRYPTO_HUGE_NUMBER *result,
                                               HN_UBASE *scratch);
VOID _nx_crypto_huge_number_crt_power_modulus(NX_CRYPTO_HUGE_NUMBER *x,
                                              NX_CRYPTO_HUGE_NUMBER *e,
                                              NX_CRYPTO_HUGE_NUMBER *p,
                                              NX_CRYPTO_HUGE_NUMBER *q,
                                              NX_CRYPTO_HUGE_NUMBER *m,
                                              NX_CRYPTO_HUGE_NUMBER *result,
                                              HN_UBASE *scratch);


#ifdef __cplusplus
}
#endif

#endif /* NX_CRYPTO_HUGE_NUMBER_H */