]>
Commit | Line | Data |
---|---|---|
7c068998 PW |
1 | /********************************************************************** |
2 | * Copyright (c) 2020 Pieter Wuille * | |
3 | * Distributed under the MIT software license, see the accompanying * | |
4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* | |
5 | **********************************************************************/ | |
6 | ||
7 | #ifndef SECP256K1_ASSUMPTIONS_H | |
8 | #define SECP256K1_ASSUMPTIONS_H | |
9 | ||
c0041b5c TR |
10 | #include <limits.h> |
11 | ||
7c068998 PW |
12 | #include "util.h" |
13 | ||
14 | /* This library, like most software, relies on a number of compiler implementation defined (but not undefined) | |
15 | behaviours. Although the behaviours we require are essentially universal we test them specifically here to | |
16 | reduce the odds of experiencing an unwelcome surprise. | |
17 | */ | |
18 | ||
19 | struct secp256k1_assumption_checker { | |
20 | /* This uses a trick to implement a static assertion in C89: a type with an array of negative size is not | |
21 | allowed. */ | |
22 | int dummy_array[( | |
23 | /* Bytes are 8 bits. */ | |
c0041b5c TR |
24 | (CHAR_BIT == 8) && |
25 | ||
26 | /* No integer promotion for uint32_t. This ensures that we can multiply uintXX_t values where XX >= 32 | |
27 | without signed overflow, which would be undefined behaviour. */ | |
28 | (UINT_MAX <= UINT32_MAX) && | |
7c068998 PW |
29 | |
30 | /* Conversions from unsigned to signed outside of the bounds of the signed type are | |
31 | implementation-defined. Verify that they function as reinterpreting the lower | |
32 | bits of the input in two's complement notation. Do this for conversions: | |
33 | - from uint(N)_t to int(N)_t with negative result | |
34 | - from uint(2N)_t to int(N)_t with negative result | |
35 | - from int(2N)_t to int(N)_t with negative result | |
36 | - from int(2N)_t to int(N)_t with positive result */ | |
37 | ||
38 | /* To int8_t. */ | |
39 | ((int8_t)(uint8_t)0xAB == (int8_t)-(int8_t)0x55) && | |
40 | ((int8_t)(uint16_t)0xABCD == (int8_t)-(int8_t)0x33) && | |
41 | ((int8_t)(int16_t)(uint16_t)0xCDEF == (int8_t)(uint8_t)0xEF) && | |
42 | ((int8_t)(int16_t)(uint16_t)0x9234 == (int8_t)(uint8_t)0x34) && | |
43 | ||
44 | /* To int16_t. */ | |
45 | ((int16_t)(uint16_t)0xBCDE == (int16_t)-(int16_t)0x4322) && | |
46 | ((int16_t)(uint32_t)0xA1B2C3D4 == (int16_t)-(int16_t)0x3C2C) && | |
47 | ((int16_t)(int32_t)(uint32_t)0xC1D2E3F4 == (int16_t)(uint16_t)0xE3F4) && | |
48 | ((int16_t)(int32_t)(uint32_t)0x92345678 == (int16_t)(uint16_t)0x5678) && | |
49 | ||
50 | /* To int32_t. */ | |
51 | ((int32_t)(uint32_t)0xB2C3D4E5 == (int32_t)-(int32_t)0x4D3C2B1B) && | |
52 | ((int32_t)(uint64_t)0xA123B456C789D012ULL == (int32_t)-(int32_t)0x38762FEE) && | |
53 | ((int32_t)(int64_t)(uint64_t)0xC1D2E3F4A5B6C7D8ULL == (int32_t)(uint32_t)0xA5B6C7D8) && | |
54 | ((int32_t)(int64_t)(uint64_t)0xABCDEF0123456789ULL == (int32_t)(uint32_t)0x23456789) && | |
55 | ||
56 | /* To int64_t. */ | |
57 | ((int64_t)(uint64_t)0xB123C456D789E012ULL == (int64_t)-(int64_t)0x4EDC3BA928761FEEULL) && | |
58 | #if defined(SECP256K1_WIDEMUL_INT128) | |
59 | ((int64_t)(((uint128_t)0xA1234567B8901234ULL << 64) + 0xC5678901D2345678ULL) == (int64_t)-(int64_t)0x3A9876FE2DCBA988ULL) && | |
60 | (((int64_t)(int128_t)(((uint128_t)0xB1C2D3E4F5A6B7C8ULL << 64) + 0xD9E0F1A2B3C4D5E6ULL)) == (int64_t)(uint64_t)0xD9E0F1A2B3C4D5E6ULL) && | |
61 | (((int64_t)(int128_t)(((uint128_t)0xABCDEF0123456789ULL << 64) + 0x0123456789ABCDEFULL)) == (int64_t)(uint64_t)0x0123456789ABCDEFULL) && | |
62 | ||
63 | /* To int128_t. */ | |
64 | ((int128_t)(((uint128_t)0xB1234567C8901234ULL << 64) + 0xD5678901E2345678ULL) == (int128_t)(-(int128_t)0x8E1648B3F50E80DCULL * 0x8E1648B3F50E80DDULL + 0x5EA688D5482F9464ULL)) && | |
65 | #endif | |
66 | ||
67 | /* Right shift on negative signed values is implementation defined. Verify that it | |
68 | acts as a right shift in two's complement with sign extension (i.e duplicating | |
69 | the top bit into newly added bits). */ | |
70 | ((((int8_t)0xE8) >> 2) == (int8_t)(uint8_t)0xFA) && | |
71 | ((((int16_t)0xE9AC) >> 4) == (int16_t)(uint16_t)0xFE9A) && | |
72 | ((((int32_t)0x937C918A) >> 9) == (int32_t)(uint32_t)0xFFC9BE48) && | |
73 | ((((int64_t)0xA8B72231DF9CF4B9ULL) >> 19) == (int64_t)(uint64_t)0xFFFFF516E4463BF3ULL) && | |
74 | #if defined(SECP256K1_WIDEMUL_INT128) | |
75 | ((((int128_t)(((uint128_t)0xCD833A65684A0DBCULL << 64) + 0xB349312F71EA7637ULL)) >> 39) == (int128_t)(((uint128_t)0xFFFFFFFFFF9B0674ULL << 64) + 0xCAD0941B79669262ULL)) && | |
76 | #endif | |
77 | 1) * 2 - 1]; | |
78 | }; | |
79 | ||
80 | #endif /* SECP256K1_ASSUMPTIONS_H */ |