xref: /btstack/3rd-party/micro-ecc/uECC.h (revision af03003c8ac55cf0eea9563b597879b24aee256f)
1*af03003cSMatthias Ringwald /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
2*af03003cSMatthias Ringwald 
3*af03003cSMatthias Ringwald #ifndef _MICRO_ECC_H_
4*af03003cSMatthias Ringwald #define _MICRO_ECC_H_
5*af03003cSMatthias Ringwald 
6*af03003cSMatthias Ringwald // BK
7*af03003cSMatthias Ringwald #include "btstack_config_uECC.h"
8*af03003cSMatthias Ringwald //
9*af03003cSMatthias Ringwald 
10*af03003cSMatthias Ringwald #include <stdint.h>
11*af03003cSMatthias Ringwald 
12*af03003cSMatthias Ringwald /* Platform selection options.
13*af03003cSMatthias Ringwald If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros.
14*af03003cSMatthias Ringwald Possible values for uECC_PLATFORM are defined below: */
15*af03003cSMatthias Ringwald #define uECC_arch_other 0
16*af03003cSMatthias Ringwald #define uECC_x86        1
17*af03003cSMatthias Ringwald #define uECC_x86_64     2
18*af03003cSMatthias Ringwald #define uECC_arm        3
19*af03003cSMatthias Ringwald #define uECC_arm_thumb  4
20*af03003cSMatthias Ringwald #define uECC_avr        5
21*af03003cSMatthias Ringwald #define uECC_arm_thumb2 6
22*af03003cSMatthias Ringwald 
23*af03003cSMatthias Ringwald /* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes).
24*af03003cSMatthias Ringwald If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your
25*af03003cSMatthias Ringwald platform. */
26*af03003cSMatthias Ringwald 
27*af03003cSMatthias Ringwald /* Inline assembly options.
28*af03003cSMatthias Ringwald uECC_asm_none  - Use standard C99 only.
29*af03003cSMatthias Ringwald uECC_asm_small - Use GCC inline assembly for the target platform (if available), optimized for
30*af03003cSMatthias Ringwald                  minimum size.
31*af03003cSMatthias Ringwald uECC_asm_fast  - Use GCC inline assembly optimized for maximum speed. */
32*af03003cSMatthias Ringwald #define uECC_asm_none  0
33*af03003cSMatthias Ringwald #define uECC_asm_small 1
34*af03003cSMatthias Ringwald #define uECC_asm_fast  2
35*af03003cSMatthias Ringwald #ifndef uECC_ASM
36*af03003cSMatthias Ringwald     #define uECC_ASM uECC_asm_fast
37*af03003cSMatthias Ringwald #endif
38*af03003cSMatthias Ringwald 
39*af03003cSMatthias Ringwald /* Curve selection options. */
40*af03003cSMatthias Ringwald #define uECC_secp160r1 1
41*af03003cSMatthias Ringwald #define uECC_secp192r1 2
42*af03003cSMatthias Ringwald #define uECC_secp256r1 3
43*af03003cSMatthias Ringwald #define uECC_secp256k1 4
44*af03003cSMatthias Ringwald #define uECC_secp224r1 5
45*af03003cSMatthias Ringwald #ifndef uECC_CURVE
46*af03003cSMatthias Ringwald     #define uECC_CURVE uECC_secp160r1
47*af03003cSMatthias Ringwald #endif
48*af03003cSMatthias Ringwald 
49*af03003cSMatthias Ringwald /* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be
50*af03003cSMatthias Ringwald used for (scalar) squaring instead of the generic multiplication function. This will make things
51*af03003cSMatthias Ringwald faster by about 8% but increases the code size. */
52*af03003cSMatthias Ringwald #ifndef uECC_SQUARE_FUNC
53*af03003cSMatthias Ringwald     #define uECC_SQUARE_FUNC 1
54*af03003cSMatthias Ringwald #endif
55*af03003cSMatthias Ringwald 
56*af03003cSMatthias Ringwald #define uECC_CONCAT1(a, b) a##b
57*af03003cSMatthias Ringwald #define uECC_CONCAT(a, b) uECC_CONCAT1(a, b)
58*af03003cSMatthias Ringwald 
59*af03003cSMatthias Ringwald #define uECC_size_1 20 /* secp160r1 */
60*af03003cSMatthias Ringwald #define uECC_size_2 24 /* secp192r1 */
61*af03003cSMatthias Ringwald #define uECC_size_3 32 /* secp256r1 */
62*af03003cSMatthias Ringwald #define uECC_size_4 32 /* secp256k1 */
63*af03003cSMatthias Ringwald #define uECC_size_5 28 /* secp224r1 */
64*af03003cSMatthias Ringwald 
65*af03003cSMatthias Ringwald #define uECC_BYTES uECC_CONCAT(uECC_size_, uECC_CURVE)
66*af03003cSMatthias Ringwald 
67*af03003cSMatthias Ringwald #ifdef __cplusplus
68*af03003cSMatthias Ringwald extern "C"
69*af03003cSMatthias Ringwald {
70*af03003cSMatthias Ringwald #endif
71*af03003cSMatthias Ringwald 
72*af03003cSMatthias Ringwald /* uECC_RNG_Function type
73*af03003cSMatthias Ringwald The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if
74*af03003cSMatthias Ringwald 'dest' was filled with random data, or 0 if the random data could not be generated.
75*af03003cSMatthias Ringwald The filled-in values should be either truly random, or from a cryptographically-secure PRNG.
76*af03003cSMatthias Ringwald 
77*af03003cSMatthias Ringwald A correctly functioning RNG function must be set (using uECC_set_rng()) before calling
78*af03003cSMatthias Ringwald uECC_make_key() or uECC_sign().
79*af03003cSMatthias Ringwald 
80*af03003cSMatthias Ringwald Setting a correctly functioning RNG function improves the resistance to side-channel attacks
81*af03003cSMatthias Ringwald for uECC_shared_secret() and uECC_sign_deterministic().
82*af03003cSMatthias Ringwald 
83*af03003cSMatthias Ringwald A correct RNG function is set by default when building for Windows, Linux, or OS X.
84*af03003cSMatthias Ringwald If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom,
85*af03003cSMatthias Ringwald you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined
86*af03003cSMatthias Ringwald RNG function; you must provide your own.
87*af03003cSMatthias Ringwald */
88*af03003cSMatthias Ringwald typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size);
89*af03003cSMatthias Ringwald 
90*af03003cSMatthias Ringwald /* uECC_set_rng() function.
91*af03003cSMatthias Ringwald Set the function that will be used to generate random bytes. The RNG function should
92*af03003cSMatthias Ringwald return 1 if the random data was generated, or 0 if the random data could not be generated.
93*af03003cSMatthias Ringwald 
94*af03003cSMatthias Ringwald On platforms where there is no predefined RNG function (eg embedded platforms), this must
95*af03003cSMatthias Ringwald be called before uECC_make_key() or uECC_sign() are used.
96*af03003cSMatthias Ringwald 
97*af03003cSMatthias Ringwald Inputs:
98*af03003cSMatthias Ringwald     rng_function - The function that will be used to generate random bytes.
99*af03003cSMatthias Ringwald */
100*af03003cSMatthias Ringwald void uECC_set_rng(uECC_RNG_Function rng_function);
101*af03003cSMatthias Ringwald 
102*af03003cSMatthias Ringwald /* uECC_make_key() function.
103*af03003cSMatthias Ringwald Create a public/private key pair.
104*af03003cSMatthias Ringwald 
105*af03003cSMatthias Ringwald Outputs:
106*af03003cSMatthias Ringwald     public_key  - Will be filled in with the public key.
107*af03003cSMatthias Ringwald     private_key - Will be filled in with the private key.
108*af03003cSMatthias Ringwald 
109*af03003cSMatthias Ringwald Returns 1 if the key pair was generated successfully, 0 if an error occurred.
110*af03003cSMatthias Ringwald */
111*af03003cSMatthias Ringwald int uECC_make_key(uint8_t public_key[uECC_BYTES*2], uint8_t private_key[uECC_BYTES]);
112*af03003cSMatthias Ringwald 
113*af03003cSMatthias Ringwald /* uECC_shared_secret() function.
114*af03003cSMatthias Ringwald Compute a shared secret given your secret key and someone else's public key.
115*af03003cSMatthias Ringwald Note: It is recommended that you hash the result of uECC_shared_secret() before using it for
116*af03003cSMatthias Ringwald symmetric encryption or HMAC.
117*af03003cSMatthias Ringwald 
118*af03003cSMatthias Ringwald Inputs:
119*af03003cSMatthias Ringwald     public_key  - The public key of the remote party.
120*af03003cSMatthias Ringwald     private_key - Your private key.
121*af03003cSMatthias Ringwald 
122*af03003cSMatthias Ringwald Outputs:
123*af03003cSMatthias Ringwald     secret - Will be filled in with the shared secret value.
124*af03003cSMatthias Ringwald 
125*af03003cSMatthias Ringwald Returns 1 if the shared secret was generated successfully, 0 if an error occurred.
126*af03003cSMatthias Ringwald */
127*af03003cSMatthias Ringwald int uECC_shared_secret(const uint8_t public_key[uECC_BYTES*2],
128*af03003cSMatthias Ringwald                        const uint8_t private_key[uECC_BYTES],
129*af03003cSMatthias Ringwald                        uint8_t secret[uECC_BYTES]);
130*af03003cSMatthias Ringwald 
131*af03003cSMatthias Ringwald /* uECC_sign() function.
132*af03003cSMatthias Ringwald Generate an ECDSA signature for a given hash value.
133*af03003cSMatthias Ringwald 
134*af03003cSMatthias Ringwald Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to
135*af03003cSMatthias Ringwald this function along with your private key.
136*af03003cSMatthias Ringwald 
137*af03003cSMatthias Ringwald Inputs:
138*af03003cSMatthias Ringwald     private_key  - Your private key.
139*af03003cSMatthias Ringwald     message_hash - The hash of the message to sign.
140*af03003cSMatthias Ringwald 
141*af03003cSMatthias Ringwald Outputs:
142*af03003cSMatthias Ringwald     signature - Will be filled in with the signature value.
143*af03003cSMatthias Ringwald 
144*af03003cSMatthias Ringwald Returns 1 if the signature generated successfully, 0 if an error occurred.
145*af03003cSMatthias Ringwald */
146*af03003cSMatthias Ringwald int uECC_sign(const uint8_t private_key[uECC_BYTES],
147*af03003cSMatthias Ringwald               const uint8_t message_hash[uECC_BYTES],
148*af03003cSMatthias Ringwald               uint8_t signature[uECC_BYTES*2]);
149*af03003cSMatthias Ringwald 
150*af03003cSMatthias Ringwald /* uECC_HashContext structure.
151*af03003cSMatthias Ringwald This is used to pass in an arbitrary hash function to uECC_sign_deterministic().
152*af03003cSMatthias Ringwald The structure will be used for multiple hash computations; each time a new hash
153*af03003cSMatthias Ringwald is computed, init_hash() will be called, followed by one or more calls to
154*af03003cSMatthias Ringwald update_hash(), and finally a call to finish_hash() to prudoce the resulting hash.
155*af03003cSMatthias Ringwald 
156*af03003cSMatthias Ringwald The intention is that you will create a structure that includes uECC_HashContext
157*af03003cSMatthias Ringwald followed by any hash-specific data. For example:
158*af03003cSMatthias Ringwald 
159*af03003cSMatthias Ringwald typedef struct SHA256_HashContext {
160*af03003cSMatthias Ringwald     uECC_HashContext uECC;
161*af03003cSMatthias Ringwald     SHA256_CTX ctx;
162*af03003cSMatthias Ringwald } SHA256_HashContext;
163*af03003cSMatthias Ringwald 
164*af03003cSMatthias Ringwald void init_SHA256(uECC_HashContext *base) {
165*af03003cSMatthias Ringwald     SHA256_HashContext *context = (SHA256_HashContext *)base;
166*af03003cSMatthias Ringwald     SHA256_Init(&context->ctx);
167*af03003cSMatthias Ringwald }
168*af03003cSMatthias Ringwald 
169*af03003cSMatthias Ringwald void update_SHA256(uECC_HashContext *base,
170*af03003cSMatthias Ringwald                    const uint8_t *message,
171*af03003cSMatthias Ringwald                    unsigned message_size) {
172*af03003cSMatthias Ringwald     SHA256_HashContext *context = (SHA256_HashContext *)base;
173*af03003cSMatthias Ringwald     SHA256_Update(&context->ctx, message, message_size);
174*af03003cSMatthias Ringwald }
175*af03003cSMatthias Ringwald 
176*af03003cSMatthias Ringwald void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) {
177*af03003cSMatthias Ringwald     SHA256_HashContext *context = (SHA256_HashContext *)base;
178*af03003cSMatthias Ringwald     SHA256_Final(hash_result, &context->ctx);
179*af03003cSMatthias Ringwald }
180*af03003cSMatthias Ringwald 
181*af03003cSMatthias Ringwald ... when signing ...
182*af03003cSMatthias Ringwald {
183*af03003cSMatthias Ringwald     uint8_t tmp[32 + 32 + 64];
184*af03003cSMatthias Ringwald     SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}};
185*af03003cSMatthias Ringwald     uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature);
186*af03003cSMatthias Ringwald }
187*af03003cSMatthias Ringwald */
188*af03003cSMatthias Ringwald typedef struct uECC_HashContext {
189*af03003cSMatthias Ringwald     void (*init_hash)(struct uECC_HashContext *context);
190*af03003cSMatthias Ringwald     void (*update_hash)(struct uECC_HashContext *context,
191*af03003cSMatthias Ringwald                         const uint8_t *message,
192*af03003cSMatthias Ringwald                         unsigned message_size);
193*af03003cSMatthias Ringwald     void (*finish_hash)(struct uECC_HashContext *context, uint8_t *hash_result);
194*af03003cSMatthias Ringwald     unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */
195*af03003cSMatthias Ringwald     unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */
196*af03003cSMatthias Ringwald     uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */
197*af03003cSMatthias Ringwald } uECC_HashContext;
198*af03003cSMatthias Ringwald 
199*af03003cSMatthias Ringwald /* uECC_sign_deterministic() function.
200*af03003cSMatthias Ringwald Generate an ECDSA signature for a given hash value, using a deterministic algorithm
201*af03003cSMatthias Ringwald (see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling
202*af03003cSMatthias Ringwald this function; however, if the RNG is defined it will improve resistance to side-channel
203*af03003cSMatthias Ringwald attacks.
204*af03003cSMatthias Ringwald 
205*af03003cSMatthias Ringwald Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to
206*af03003cSMatthias Ringwald this function along with your private key and a hash context.
207*af03003cSMatthias Ringwald 
208*af03003cSMatthias Ringwald Inputs:
209*af03003cSMatthias Ringwald     private_key  - Your private key.
210*af03003cSMatthias Ringwald     message_hash - The hash of the message to sign.
211*af03003cSMatthias Ringwald     hash_context - A hash context to use.
212*af03003cSMatthias Ringwald 
213*af03003cSMatthias Ringwald Outputs:
214*af03003cSMatthias Ringwald     signature - Will be filled in with the signature value.
215*af03003cSMatthias Ringwald 
216*af03003cSMatthias Ringwald Returns 1 if the signature generated successfully, 0 if an error occurred.
217*af03003cSMatthias Ringwald */
218*af03003cSMatthias Ringwald int uECC_sign_deterministic(const uint8_t private_key[uECC_BYTES],
219*af03003cSMatthias Ringwald                             const uint8_t message_hash[uECC_BYTES],
220*af03003cSMatthias Ringwald                             uECC_HashContext *hash_context,
221*af03003cSMatthias Ringwald                             uint8_t signature[uECC_BYTES*2]);
222*af03003cSMatthias Ringwald 
223*af03003cSMatthias Ringwald /* uECC_verify() function.
224*af03003cSMatthias Ringwald Verify an ECDSA signature.
225*af03003cSMatthias Ringwald 
226*af03003cSMatthias Ringwald Usage: Compute the hash of the signed data using the same hash as the signer and
227*af03003cSMatthias Ringwald pass it to this function along with the signer's public key and the signature values (r and s).
228*af03003cSMatthias Ringwald 
229*af03003cSMatthias Ringwald Inputs:
230*af03003cSMatthias Ringwald     public_key - The signer's public key
231*af03003cSMatthias Ringwald     hash       - The hash of the signed data.
232*af03003cSMatthias Ringwald     signature  - The signature value.
233*af03003cSMatthias Ringwald 
234*af03003cSMatthias Ringwald Returns 1 if the signature is valid, 0 if it is invalid.
235*af03003cSMatthias Ringwald */
236*af03003cSMatthias Ringwald int uECC_verify(const uint8_t public_key[uECC_BYTES*2],
237*af03003cSMatthias Ringwald                 const uint8_t hash[uECC_BYTES],
238*af03003cSMatthias Ringwald                 const uint8_t signature[uECC_BYTES*2]);
239*af03003cSMatthias Ringwald 
240*af03003cSMatthias Ringwald /* uECC_compress() function.
241*af03003cSMatthias Ringwald Compress a public key.
242*af03003cSMatthias Ringwald 
243*af03003cSMatthias Ringwald Inputs:
244*af03003cSMatthias Ringwald     public_key - The public key to compress.
245*af03003cSMatthias Ringwald 
246*af03003cSMatthias Ringwald Outputs:
247*af03003cSMatthias Ringwald     compressed - Will be filled in with the compressed public key.
248*af03003cSMatthias Ringwald */
249*af03003cSMatthias Ringwald void uECC_compress(const uint8_t public_key[uECC_BYTES*2], uint8_t compressed[uECC_BYTES+1]);
250*af03003cSMatthias Ringwald 
251*af03003cSMatthias Ringwald /* uECC_decompress() function.
252*af03003cSMatthias Ringwald Decompress a compressed public key.
253*af03003cSMatthias Ringwald 
254*af03003cSMatthias Ringwald Inputs:
255*af03003cSMatthias Ringwald     compressed - The compressed public key.
256*af03003cSMatthias Ringwald 
257*af03003cSMatthias Ringwald Outputs:
258*af03003cSMatthias Ringwald     public_key - Will be filled in with the decompressed public key.
259*af03003cSMatthias Ringwald */
260*af03003cSMatthias Ringwald void uECC_decompress(const uint8_t compressed[uECC_BYTES+1], uint8_t public_key[uECC_BYTES*2]);
261*af03003cSMatthias Ringwald 
262*af03003cSMatthias Ringwald /* uECC_valid_public_key() function.
263*af03003cSMatthias Ringwald Check to see if a public key is valid.
264*af03003cSMatthias Ringwald 
265*af03003cSMatthias Ringwald Note that you are not required to check for a valid public key before using any other uECC
266*af03003cSMatthias Ringwald functions. However, you may wish to avoid spending CPU time computing a shared secret or
267*af03003cSMatthias Ringwald verifying a signature using an invalid public key.
268*af03003cSMatthias Ringwald 
269*af03003cSMatthias Ringwald Inputs:
270*af03003cSMatthias Ringwald     public_key - The public key to check.
271*af03003cSMatthias Ringwald 
272*af03003cSMatthias Ringwald Returns 1 if the public key is valid, 0 if it is invalid.
273*af03003cSMatthias Ringwald */
274*af03003cSMatthias Ringwald int uECC_valid_public_key(const uint8_t public_key[uECC_BYTES*2]);
275*af03003cSMatthias Ringwald 
276*af03003cSMatthias Ringwald /* uECC_compute_public_key() function.
277*af03003cSMatthias Ringwald Compute the corresponding public key for a private key.
278*af03003cSMatthias Ringwald 
279*af03003cSMatthias Ringwald Inputs:
280*af03003cSMatthias Ringwald     private_key - The private key to compute the public key for
281*af03003cSMatthias Ringwald 
282*af03003cSMatthias Ringwald Outputs:
283*af03003cSMatthias Ringwald     public_key - Will be filled in with the corresponding public key
284*af03003cSMatthias Ringwald 
285*af03003cSMatthias Ringwald Returns 1 if the key was computed successfully, 0 if an error occurred.
286*af03003cSMatthias Ringwald */
287*af03003cSMatthias Ringwald int uECC_compute_public_key(const uint8_t private_key[uECC_BYTES],
288*af03003cSMatthias Ringwald                             uint8_t public_key[uECC_BYTES * 2]);
289*af03003cSMatthias Ringwald 
290*af03003cSMatthias Ringwald 
291*af03003cSMatthias Ringwald /* uECC_bytes() function.
292*af03003cSMatthias Ringwald Returns the value of uECC_BYTES. Helpful for foreign-interfaces to higher-level languages.
293*af03003cSMatthias Ringwald */
294*af03003cSMatthias Ringwald int uECC_bytes(void);
295*af03003cSMatthias Ringwald 
296*af03003cSMatthias Ringwald /* uECC_curve() function.
297*af03003cSMatthias Ringwald Returns the value of uECC_CURVE. Helpful for foreign-interfaces to higher-level languages.
298*af03003cSMatthias Ringwald */
299*af03003cSMatthias Ringwald int uECC_curve(void);
300*af03003cSMatthias Ringwald 
301*af03003cSMatthias Ringwald #ifdef __cplusplus
302*af03003cSMatthias Ringwald } /* end of extern "C" */
303*af03003cSMatthias Ringwald #endif
304*af03003cSMatthias Ringwald 
305*af03003cSMatthias Ringwald #endif /* _MICRO_ECC_H_ */
306