/src/trezor-firmware/crypto/bignum.h
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * Copyright (c) 2013-2014 Tomas Dzetkulic |
3 | | * Copyright (c) 2013-2014 Pavol Rusnak |
4 | | * Copyright (c) 2016 Alex Beregszaszi |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining |
7 | | * a copy of this software and associated documentation files (the "Software"), |
8 | | * to deal in the Software without restriction, including without limitation |
9 | | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
10 | | * and/or sell copies of the Software, and to permit persons to whom the |
11 | | * Software is furnished to do so, subject to the following conditions: |
12 | | * |
13 | | * The above copyright notice and this permission notice shall be included |
14 | | * in all copies or substantial portions of the Software. |
15 | | * |
16 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
17 | | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
19 | | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES |
20 | | * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
21 | | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
22 | | * OTHER DEALINGS IN THE SOFTWARE. |
23 | | */ |
24 | | |
25 | | #ifndef __BIGNUM_H__ |
26 | | #define __BIGNUM_H__ |
27 | | |
28 | | #include <stdbool.h> |
29 | | #include <stddef.h> |
30 | | #include <stdint.h> |
31 | | |
32 | | #include "options.h" |
33 | | |
34 | 8.25G | #define BN_LIMBS 9 |
35 | 12.0G | #define BN_BITS_PER_LIMB 29 |
36 | 3.15G | #define BN_BASE (1u << BN_BITS_PER_LIMB) |
37 | 3.83G | #define BN_LIMB_MASK ((1u << BN_BITS_PER_LIMB) - 1) |
38 | 624k | #define BN_EXTRA_BITS (32 - BN_BITS_PER_LIMB) |
39 | 10.0k | #define BN_BITS_LAST_LIMB (256 - (BN_LIMBS - 1) * BN_BITS_PER_LIMB) |
40 | | |
41 | | // Represents the number sum([val[i] * 2**(29*i) for i in range(9)) |
42 | | typedef struct { |
43 | | uint32_t val[BN_LIMBS]; |
44 | | } bignum256; |
45 | | |
46 | | // Represents the number sum([val[i] * 2**(29*i) for i in range(18)) |
47 | | typedef struct { |
48 | | uint32_t val[2 * BN_LIMBS]; |
49 | | } bignum512; |
50 | | |
51 | 201k | static inline uint32_t read_be(const uint8_t *data) { |
52 | 201k | return (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) | |
53 | 201k | (((uint32_t)data[2]) << 8) | (((uint32_t)data[3])); |
54 | 201k | } Unexecuted instantiation: module.cpp:read_be(unsigned char const*) Line | Count | Source | 51 | 201k | static inline uint32_t read_be(const uint8_t *data) { | 52 | 201k | return (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) | | 53 | 201k | (((uint32_t)data[2]) << 8) | (((uint32_t)data[3])); | 54 | 201k | } |
Unexecuted instantiation: ecdsa.c:read_be Unexecuted instantiation: nist256p1.c:read_be Unexecuted instantiation: rfc6979.c:read_be Unexecuted instantiation: secp256k1.c:read_be Unexecuted instantiation: address.c:read_be |
55 | | |
56 | 110k | static inline void write_be(uint8_t *data, uint32_t x) { |
57 | 110k | data[0] = x >> 24; |
58 | 110k | data[1] = x >> 16; |
59 | 110k | data[2] = x >> 8; |
60 | 110k | data[3] = x; |
61 | 110k | } Unexecuted instantiation: module.cpp:write_be(unsigned char*, unsigned int) Line | Count | Source | 56 | 110k | static inline void write_be(uint8_t *data, uint32_t x) { | 57 | 110k | data[0] = x >> 24; | 58 | 110k | data[1] = x >> 16; | 59 | 110k | data[2] = x >> 8; | 60 | 110k | data[3] = x; | 61 | 110k | } |
Unexecuted instantiation: ecdsa.c:write_be Unexecuted instantiation: nist256p1.c:write_be Unexecuted instantiation: rfc6979.c:write_be Unexecuted instantiation: secp256k1.c:write_be Unexecuted instantiation: address.c:write_be |
62 | | |
63 | 0 | static inline uint32_t read_le(const uint8_t *data) { |
64 | 0 | return (((uint32_t)data[3]) << 24) | (((uint32_t)data[2]) << 16) | |
65 | 0 | (((uint32_t)data[1]) << 8) | (((uint32_t)data[0])); |
66 | 0 | } Unexecuted instantiation: module.cpp:read_le(unsigned char const*) Unexecuted instantiation: bignum.c:read_le Unexecuted instantiation: ecdsa.c:read_le Unexecuted instantiation: nist256p1.c:read_le Unexecuted instantiation: rfc6979.c:read_le Unexecuted instantiation: secp256k1.c:read_le Unexecuted instantiation: address.c:read_le |
67 | | |
68 | 0 | static inline void write_le(uint8_t *data, uint32_t x) { |
69 | 0 | data[3] = x >> 24; |
70 | 0 | data[2] = x >> 16; |
71 | 0 | data[1] = x >> 8; |
72 | 0 | data[0] = x; |
73 | 0 | } Unexecuted instantiation: module.cpp:write_le(unsigned char*, unsigned int) Unexecuted instantiation: bignum.c:write_le Unexecuted instantiation: ecdsa.c:write_le Unexecuted instantiation: nist256p1.c:write_le Unexecuted instantiation: rfc6979.c:write_le Unexecuted instantiation: secp256k1.c:write_le Unexecuted instantiation: address.c:write_le |
74 | | |
75 | | void bn_copy_lower(const bignum512 *x, bignum256 *y); |
76 | | void bn_read_be(const uint8_t *in_number, bignum256 *out_number); |
77 | | void bn_read_be_512(const uint8_t *in_number, bignum512 *out_number); |
78 | | void bn_write_be(const bignum256 *in_number, uint8_t *out_number); |
79 | | void bn_read_le(const uint8_t *in_number, bignum256 *out_number); |
80 | | void bn_write_le(const bignum256 *in_number, uint8_t *out_number); |
81 | | void bn_read_uint32(uint32_t in_number, bignum256 *out_number); |
82 | | void bn_read_uint64(uint64_t in_number, bignum256 *out_number); |
83 | | int bn_bitcount(const bignum256 *x); |
84 | | unsigned int bn_digitcount(const bignum256 *x); |
85 | | void bn_zero(bignum256 *x); |
86 | | void bn_one(bignum256 *x); |
87 | | int bn_is_zero(const bignum256 *x); |
88 | | int bn_is_one(const bignum256 *x); |
89 | | int bn_is_less(const bignum256 *x, const bignum256 *y); |
90 | | int bn_is_equal(const bignum256 *x, const bignum256 *y); |
91 | | void bn_cmov(bignum256 *res, volatile uint32_t cond, const bignum256 *truecase, |
92 | | const bignum256 *falsecase); |
93 | | void bn_cnegate(volatile uint32_t cond, bignum256 *x, const bignum256 *prime); |
94 | | void bn_lshift(bignum256 *x); |
95 | | void bn_rshift(bignum256 *x); |
96 | | void bn_setbit(bignum256 *x, uint16_t i); |
97 | | void bn_clearbit(bignum256 *x, uint16_t i); |
98 | | uint32_t bn_testbit(const bignum256 *x, uint16_t i); |
99 | | void bn_xor(bignum256 *res, const bignum256 *x, const bignum256 *y); |
100 | | void bn_mult_half(bignum256 *x, const bignum256 *prime); |
101 | | void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime); |
102 | | void bn_mod(bignum256 *x, const bignum256 *prime); |
103 | | void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime); |
104 | | void bn_reduce(bignum512 *x, const bignum256 *prime); |
105 | | void bn_fast_mod(bignum256 *x, const bignum256 *prime); |
106 | | void bn_power_mod(const bignum256 *x, const bignum256 *e, |
107 | | const bignum256 *prime, bignum256 *res); |
108 | | void bn_sqrt(bignum256 *x, const bignum256 *prime); |
109 | | uint32_t inverse_mod_power_two(uint32_t a, uint32_t n); |
110 | | void bn_divide_base(bignum256 *x, const bignum256 *prime); |
111 | | void bn_normalize(bignum256 *x); |
112 | | void bn_add(bignum256 *x, const bignum256 *y); |
113 | | void bn_addmod(bignum256 *x, const bignum256 *y, const bignum256 *prime); |
114 | | void bn_addi(bignum256 *x, uint32_t y); |
115 | | void bn_subi(bignum256 *x, uint32_t y, const bignum256 *prime); |
116 | | void bn_subtractmod(const bignum256 *x, const bignum256 *y, bignum256 *res, |
117 | | const bignum256 *prime); |
118 | | void bn_subtract(const bignum256 *x, const bignum256 *y, bignum256 *res); |
119 | | int bn_legendre(const bignum256 *x, const bignum256 *prime); |
120 | | void bn_long_division(bignum256 *x, uint32_t d, bignum256 *q, uint32_t *r); |
121 | | void bn_divmod58(bignum256 *x, uint32_t *r); |
122 | | void bn_divmod1000(bignum256 *x, uint32_t *r); |
123 | | void bn_inverse(bignum256 *x, const bignum256 *prime); |
124 | | size_t bn_format(const bignum256 *amount, const char *prefix, |
125 | | const char *suffix, unsigned int decimals, int exponent, |
126 | | bool trailing, char thousands, char *output, |
127 | | size_t output_length); |
128 | | |
129 | | // Returns (uint32_t) in_number |
130 | | // Assumes in_number < 2**32 |
131 | | // Assumes in_number is normalized |
132 | 0 | static inline uint32_t bn_write_uint32(const bignum256 *in_number) { |
133 | 0 | return in_number->val[0] | (in_number->val[1] << BN_BITS_PER_LIMB); |
134 | 0 | } Unexecuted instantiation: module.cpp:bn_write_uint32(bignum256 const*) Unexecuted instantiation: bignum.c:bn_write_uint32 Unexecuted instantiation: ecdsa.c:bn_write_uint32 Unexecuted instantiation: nist256p1.c:bn_write_uint32 Unexecuted instantiation: rfc6979.c:bn_write_uint32 Unexecuted instantiation: secp256k1.c:bn_write_uint32 Unexecuted instantiation: address.c:bn_write_uint32 |
135 | | |
136 | | // Returns (uint64_t) in_number |
137 | | // Assumes in_number < 2**64 |
138 | | // Assumes in_number is normalized |
139 | 0 | static inline uint64_t bn_write_uint64(const bignum256 *in_number) { |
140 | 0 | uint64_t acc; |
141 | 0 | acc = in_number->val[2]; |
142 | 0 | acc <<= BN_BITS_PER_LIMB; |
143 | 0 | acc |= in_number->val[1]; |
144 | 0 | acc <<= BN_BITS_PER_LIMB; |
145 | 0 | acc |= in_number->val[0]; |
146 | 0 | return acc; |
147 | 0 | } Unexecuted instantiation: module.cpp:bn_write_uint64(bignum256 const*) Unexecuted instantiation: bignum.c:bn_write_uint64 Unexecuted instantiation: ecdsa.c:bn_write_uint64 Unexecuted instantiation: nist256p1.c:bn_write_uint64 Unexecuted instantiation: rfc6979.c:bn_write_uint64 Unexecuted instantiation: secp256k1.c:bn_write_uint64 Unexecuted instantiation: address.c:bn_write_uint64 |
148 | | |
149 | | // y = x |
150 | 4.10M | static inline void bn_copy(const bignum256 *x, bignum256 *y) { *y = *x; } Unexecuted instantiation: module.cpp:bn_copy(bignum256 const*, bignum256*) Line | Count | Source | 150 | 4.10M | static inline void bn_copy(const bignum256 *x, bignum256 *y) { *y = *x; } |
Unexecuted instantiation: ecdsa.c:bn_copy Unexecuted instantiation: nist256p1.c:bn_copy Unexecuted instantiation: rfc6979.c:bn_copy Unexecuted instantiation: secp256k1.c:bn_copy Unexecuted instantiation: address.c:bn_copy |
151 | | |
152 | | // Returns x % 2 == 0 |
153 | 87.5M | static inline int bn_is_even(const bignum256 *x) { |
154 | 87.5M | return (x->val[0] & 1) == 0; |
155 | 87.5M | } Unexecuted instantiation: module.cpp:bn_is_even(bignum256 const*) Line | Count | Source | 153 | 87.5M | static inline int bn_is_even(const bignum256 *x) { | 154 | 87.5M | return (x->val[0] & 1) == 0; | 155 | 87.5M | } |
Unexecuted instantiation: ecdsa.c:bn_is_even Unexecuted instantiation: nist256p1.c:bn_is_even Unexecuted instantiation: rfc6979.c:bn_is_even Unexecuted instantiation: secp256k1.c:bn_is_even Unexecuted instantiation: address.c:bn_is_even |
156 | | |
157 | | // Returns x % 2 == 0 |
158 | 0 | static inline int bn_is_odd(const bignum256 *x) { return (x->val[0] & 1) == 1; } Unexecuted instantiation: module.cpp:bn_is_odd(bignum256 const*) Unexecuted instantiation: bignum.c:bn_is_odd Unexecuted instantiation: ecdsa.c:bn_is_odd Unexecuted instantiation: nist256p1.c:bn_is_odd Unexecuted instantiation: rfc6979.c:bn_is_odd Unexecuted instantiation: secp256k1.c:bn_is_odd Unexecuted instantiation: address.c:bn_is_odd |
159 | | |
160 | | static inline size_t bn_format_uint64(uint64_t amount, const char *prefix, |
161 | | const char *suffix, unsigned int decimals, |
162 | | int exponent, bool trailing, |
163 | | char thousands, char *output, |
164 | 0 | size_t output_length) { |
165 | 0 | bignum256 bn_amount; |
166 | 0 | bn_read_uint64(amount, &bn_amount); |
167 | 0 |
|
168 | 0 | return bn_format(&bn_amount, prefix, suffix, decimals, exponent, trailing, |
169 | 0 | thousands, output, output_length); |
170 | 0 | } Unexecuted instantiation: module.cpp:bn_format_uint64(unsigned long, char const*, char const*, unsigned int, int, bool, char, char*, unsigned long) Unexecuted instantiation: bignum.c:bn_format_uint64 Unexecuted instantiation: ecdsa.c:bn_format_uint64 Unexecuted instantiation: nist256p1.c:bn_format_uint64 Unexecuted instantiation: rfc6979.c:bn_format_uint64 Unexecuted instantiation: secp256k1.c:bn_format_uint64 Unexecuted instantiation: address.c:bn_format_uint64 |
171 | | |
172 | | static inline size_t bn_format_amount(uint64_t amount, const char *prefix, |
173 | | const char *suffix, unsigned int decimals, |
174 | 0 | char *output, size_t output_length) { |
175 | 0 | return bn_format_uint64(amount, prefix, suffix, decimals, 0, false, ',', |
176 | 0 | output, output_length); |
177 | 0 | } Unexecuted instantiation: module.cpp:bn_format_amount(unsigned long, char const*, char const*, unsigned int, char*, unsigned long) Unexecuted instantiation: bignum.c:bn_format_amount Unexecuted instantiation: ecdsa.c:bn_format_amount Unexecuted instantiation: nist256p1.c:bn_format_amount Unexecuted instantiation: rfc6979.c:bn_format_amount Unexecuted instantiation: secp256k1.c:bn_format_amount Unexecuted instantiation: address.c:bn_format_amount |
178 | | |
179 | | #if USE_BN_PRINT |
180 | | void bn_print(const bignum256 *x); |
181 | | void bn_print_raw(const bignum256 *x); |
182 | | #endif |
183 | | |
184 | | #endif |