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