Skip to content

Commit 7fe6e0d

Browse files
author
CHMZ Developer
authored
CoinBase Library
1 parent fa8c9de commit 7fe6e0d

41 files changed

Lines changed: 38573 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CoinBase-Wallet-Python-API-Wallet-Storage-Web Browser-Multi-Crypto-SDK/CoinBase Wallet/libraries/ECC/ECC.c

Lines changed: 1634 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
2+
3+
#ifndef _UECC_H_
4+
#define _UECC_H_
5+
6+
#include <stdint.h>
7+
8+
/* Platform selection options.
9+
If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros.
10+
Possible values for uECC_PLATFORM are defined below: */
11+
#define uECC_arch_other 0
12+
#define uECC_x86 1
13+
#define uECC_x86_64 2
14+
#define uECC_arm 3
15+
#define uECC_arm_thumb 4
16+
#define uECC_arm_thumb2 5
17+
#define uECC_arm64 6
18+
#define uECC_avr 7
19+
20+
/* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes).
21+
If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your
22+
platform. */
23+
24+
/* Optimization level; trade speed for code size.
25+
Larger values produce code that is faster but larger.
26+
Currently supported values are 0 - 4; 0 is unusably slow for most applications.
27+
Optimization level 4 currently only has an effect ARM platforms where more than one
28+
curve is enabled. */
29+
#ifndef uECC_OPTIMIZATION_LEVEL
30+
#define uECC_OPTIMIZATION_LEVEL 2
31+
#endif
32+
33+
/* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be
34+
used for (scalar) squaring instead of the generic multiplication function. This can make things
35+
faster somewhat faster, but increases the code size. */
36+
#ifndef uECC_SQUARE_FUNC
37+
#define uECC_SQUARE_FUNC 0
38+
#endif
39+
40+
/* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native
41+
little-endian format for *all* arrays passed in and out of the public API. This includes public
42+
and private keys, shared secrets, signatures and message hashes.
43+
Using this switch reduces the amount of call stack memory used by uECC, since less intermediate
44+
translations are required.
45+
Note that this will *only* work on native little-endian processors and it will treat the uint8_t
46+
arrays passed into the public API as word arrays, therefore requiring the provided byte arrays
47+
to be word aligned on architectures that do not support unaligned accesses.
48+
IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible
49+
with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use
50+
the same endianness. */
51+
#ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN
52+
#define uECC_VLI_NATIVE_LITTLE_ENDIAN 0
53+
#endif
54+
55+
/* Curve support selection. Set to 0 to remove that curve. */
56+
#ifndef uECC_SUPPORTS_secp160r1
57+
#define uECC_SUPPORTS_secp160r1 1
58+
#endif
59+
#ifndef uECC_SUPPORTS_secp192r1
60+
#define uECC_SUPPORTS_secp192r1 0
61+
#endif
62+
#ifndef uECC_SUPPORTS_secp224r1
63+
#define uECC_SUPPORTS_secp224r1 0
64+
#endif
65+
#ifndef uECC_SUPPORTS_secp256r1
66+
#define uECC_SUPPORTS_secp256r1 0
67+
#endif
68+
#ifndef uECC_SUPPORTS_secp256k1
69+
#define uECC_SUPPORTS_secp256k1 1
70+
#endif
71+
72+
/* Specifies whether compressed point format is supported.
73+
Set to 0 to disable point compression/decompression functions. */
74+
#ifndef uECC_SUPPORT_COMPRESSED_POINT
75+
#define uECC_SUPPORT_COMPRESSED_POINT 0
76+
#endif
77+
78+
struct uECC_Curve_t;
79+
typedef const struct uECC_Curve_t * uECC_Curve;
80+
81+
#ifdef __cplusplus
82+
extern "C"
83+
{
84+
#endif
85+
86+
#if uECC_SUPPORTS_secp160r1
87+
uECC_Curve uECC_secp160r1(void);
88+
#endif
89+
#if uECC_SUPPORTS_secp192r1
90+
uECC_Curve uECC_secp192r1(void);
91+
#endif
92+
#if uECC_SUPPORTS_secp224r1
93+
uECC_Curve uECC_secp224r1(void);
94+
#endif
95+
#if uECC_SUPPORTS_secp256r1
96+
uECC_Curve uECC_secp256r1(void);
97+
#endif
98+
#if uECC_SUPPORTS_secp256k1
99+
uECC_Curve uECC_secp256k1(void);
100+
#endif
101+
102+
/* uECC_RNG_Function type
103+
The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if
104+
'dest' was filled with random data, or 0 if the random data could not be generated.
105+
The filled-in values should be either truly random, or from a cryptographically-secure PRNG.
106+
107+
A correctly functioning RNG function must be set (using uECC_set_rng()) before calling
108+
uECC_make_key() or uECC_sign().
109+
110+
Setting a correctly functioning RNG function improves the resistance to side-channel attacks
111+
for uECC_shared_secret() and uECC_sign_deterministic().
112+
113+
A correct RNG function is set by default when building for Windows, Linux, or OS X.
114+
If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom,
115+
you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined
116+
RNG function; you must provide your own.
117+
*/
118+
typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size);
119+
120+
/* uECC_set_rng() function.
121+
Set the function that will be used to generate random bytes. The RNG function should
122+
return 1 if the random data was generated, or 0 if the random data could not be generated.
123+
124+
On platforms where there is no predefined RNG function (eg embedded platforms), this must
125+
be called before uECC_make_key() or uECC_sign() are used.
126+
127+
Inputs:
128+
rng_function - The function that will be used to generate random bytes.
129+
*/
130+
void uECC_set_rng(uECC_RNG_Function rng_function);
131+
132+
/* uECC_get_rng() function.
133+
134+
Returns the function that will be used to generate random bytes.
135+
*/
136+
uECC_RNG_Function uECC_get_rng(void);
137+
138+
/* uECC_curve_private_key_size() function.
139+
140+
Returns the size of a private key for the curve in bytes.
141+
*/
142+
int uECC_curve_private_key_size(uECC_Curve curve);
143+
144+
/* uECC_curve_public_key_size() function.
145+
146+
Returns the size of a public key for the curve in bytes.
147+
*/
148+
int uECC_curve_public_key_size(uECC_Curve curve);
149+
150+
/* uECC_make_key() function.
151+
Create a public/private key pair.
152+
153+
Outputs:
154+
public_key - Will be filled in with the public key. Must be at least 2 * the curve size
155+
(in bytes) long. For example, if the curve is secp256r1, public_key must be 64
156+
bytes long.
157+
private_key - Will be filled in with the private key. Must be as long as the curve order; this
158+
is typically the same as the curve size, except for secp160r1. For example, if the
159+
curve is secp256r1, private_key must be 32 bytes long.
160+
161+
For secp160r1, private_key must be 21 bytes long! Note that the first byte will
162+
almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero).
163+
164+
Returns 1 if the key pair was generated successfully, 0 if an error occurred.
165+
*/
166+
int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve);
167+
168+
/* uECC_shared_secret() function.
169+
Compute a shared secret given your secret key and someone else's public key.
170+
Note: It is recommended that you hash the result of uECC_shared_secret() before using it for
171+
symmetric encryption or HMAC.
172+
173+
Inputs:
174+
public_key - The public key of the remote party.
175+
private_key - Your private key.
176+
177+
Outputs:
178+
secret - Will be filled in with the shared secret value. Must be the same size as the
179+
curve size; for example, if the curve is secp256r1, secret must be 32 bytes long.
180+
181+
Returns 1 if the shared secret was generated successfully, 0 if an error occurred.
182+
*/
183+
int uECC_shared_secret(const uint8_t *public_key,
184+
const uint8_t *private_key,
185+
uint8_t *secret,
186+
uECC_Curve curve);
187+
188+
#if uECC_SUPPORT_COMPRESSED_POINT
189+
/* uECC_compress() function.
190+
Compress a public key.
191+
192+
Inputs:
193+
public_key - The public key to compress.
194+
195+
Outputs:
196+
compressed - Will be filled in with the compressed public key. Must be at least
197+
(curve size + 1) bytes long; for example, if the curve is secp256r1,
198+
compressed must be 33 bytes long.
199+
*/
200+
void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve);
201+
202+
/* uECC_decompress() function.
203+
Decompress a compressed public key.
204+
205+
Inputs:
206+
compressed - The compressed public key.
207+
208+
Outputs:
209+
public_key - Will be filled in with the decompressed public key.
210+
*/
211+
void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve);
212+
#endif /* uECC_SUPPORT_COMPRESSED_POINT */
213+
214+
/* uECC_valid_public_key() function.
215+
Check to see if a public key is valid.
216+
217+
Note that you are not required to check for a valid public key before using any other uECC
218+
functions. However, you may wish to avoid spending CPU time computing a shared secret or
219+
verifying a signature using an invalid public key.
220+
221+
Inputs:
222+
public_key - The public key to check.
223+
224+
Returns 1 if the public key is valid, 0 if it is invalid.
225+
*/
226+
int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve);
227+
228+
/* uECC_compute_public_key() function.
229+
Compute the corresponding public key for a private key.
230+
231+
Inputs:
232+
private_key - The private key to compute the public key for
233+
234+
Outputs:
235+
public_key - Will be filled in with the corresponding public key
236+
237+
Returns 1 if the key was computed successfully, 0 if an error occurred.
238+
*/
239+
int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);
240+
241+
/* uECC_sign() function.
242+
Generate an ECDSA signature for a given hash value.
243+
244+
Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to
245+
this function along with your private key.
246+
247+
Inputs:
248+
private_key - Your private key.
249+
message_hash - The hash of the message to sign.
250+
hash_size - The size of message_hash in bytes.
251+
252+
Outputs:
253+
signature - Will be filled in with the signature value. Must be at least 2 * curve size long.
254+
For example, if the curve is secp256r1, signature must be 64 bytes long.
255+
256+
Returns 1 if the signature generated successfully, 0 if an error occurred.
257+
*/
258+
int uECC_sign(const uint8_t *private_key,
259+
const uint8_t *message_hash,
260+
unsigned hash_size,
261+
uint8_t *signature,
262+
uECC_Curve curve);
263+
264+
/* uECC_HashContext structure.
265+
This is used to pass in an arbitrary hash function to uECC_sign_deterministic().
266+
The structure will be used for multiple hash computations; each time a new hash
267+
is computed, init_hash() will be called, followed by one or more calls to
268+
update_hash(), and finally a call to finish_hash() to produce the resulting hash.
269+
270+
The intention is that you will create a structure that includes uECC_HashContext
271+
followed by any hash-specific data. For example:
272+
273+
typedef struct SHA256_HashContext {
274+
uECC_HashContext uECC;
275+
SHA256_CTX ctx;
276+
} SHA256_HashContext;
277+
278+
void init_SHA256(uECC_HashContext *base) {
279+
SHA256_HashContext *context = (SHA256_HashContext *)base;
280+
SHA256_Init(&context->ctx);
281+
}
282+
283+
void update_SHA256(uECC_HashContext *base,
284+
const uint8_t *message,
285+
unsigned message_size) {
286+
SHA256_HashContext *context = (SHA256_HashContext *)base;
287+
SHA256_Update(&context->ctx, message, message_size);
288+
}
289+
290+
void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) {
291+
SHA256_HashContext *context = (SHA256_HashContext *)base;
292+
SHA256_Final(hash_result, &context->ctx);
293+
}
294+
295+
... when signing ...
296+
{
297+
uint8_t tmp[32 + 32 + 64];
298+
SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}};
299+
uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature);
300+
}
301+
*/
302+
typedef struct uECC_HashContext {
303+
void (*init_hash)(const struct uECC_HashContext *context);
304+
void (*update_hash)(const struct uECC_HashContext *context,
305+
const uint8_t *message,
306+
unsigned message_size);
307+
void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result);
308+
unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */
309+
unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */
310+
uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */
311+
} uECC_HashContext;
312+
313+
/* uECC_sign_deterministic() function.
314+
Generate an ECDSA signature for a given hash value, using a deterministic algorithm
315+
(see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling
316+
this function; however, if the RNG is defined it will improve resistance to side-channel
317+
attacks.
318+
319+
Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to
320+
this function along with your private key and a hash context. Note that the message_hash
321+
does not need to be computed with the same hash function used by hash_context.
322+
323+
Inputs:
324+
private_key - Your private key.
325+
message_hash - The hash of the message to sign.
326+
hash_size - The size of message_hash in bytes.
327+
hash_context - A hash context to use.
328+
329+
Outputs:
330+
signature - Will be filled in with the signature value.
331+
332+
Returns 1 if the signature generated successfully, 0 if an error occurred.
333+
*/
334+
int uECC_sign_deterministic(const uint8_t *private_key,
335+
const uint8_t *message_hash,
336+
unsigned hash_size,
337+
const uECC_HashContext *hash_context,
338+
uint8_t *signature,
339+
uECC_Curve curve);
340+
341+
/* uECC_verify() function.
342+
Verify an ECDSA signature.
343+
344+
Usage: Compute the hash of the signed data using the same hash as the signer and
345+
pass it to this function along with the signer's public key and the signature values (r and s).
346+
347+
Inputs:
348+
public_key - The signer's public key.
349+
message_hash - The hash of the signed data.
350+
hash_size - The size of message_hash in bytes.
351+
signature - The signature value.
352+
353+
Returns 1 if the signature is valid, 0 if it is invalid.
354+
*/
355+
int uECC_verify(const uint8_t *public_key,
356+
const uint8_t *message_hash,
357+
unsigned hash_size,
358+
const uint8_t *signature,
359+
uECC_Curve curve);
360+
361+
#ifdef __cplusplus
362+
} /* end of extern "C" */
363+
#endif
364+
365+
#endif /* _UECC_H_ */

0 commit comments

Comments
 (0)