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