Line data Source code
1 : #ifndef HEADER_fd_src_ballet_bigint_uint256_h 2 : #define HEADER_fd_src_ballet_bigint_uint256_h 3 : 4 : /* Implementation of uint256. */ 5 : 6 : #include "../fd_ballet_base.h" 7 : 8 : /* Align at most at 32 bytes. 9 : This way a struct containing multiple fd_uint256_t doesn't waste space 10 : (e.g., on avx512 FD_ALIGNED would be 64, causing each fd_uint256_t to 11 : consume 64 bytes instead of 32). 12 : Note: FD_ALIGNED implies FD_UINT256_ALIGNED, so a struct containing 1+ 13 : fd_uint256_t can be simply defined as FD_ALIGNED, and it's also implicitly 14 : FD_UINT256_ALIGNED. */ 15 : #if FD_ALIGN > 32 16 : #define FD_UINT256_ALIGNED __attribute__((aligned(32))) 17 : #else 18 : #define FD_UINT256_ALIGNED FD_ALIGNED 19 : #endif 20 : 21 : /* fd_uint256_t represents a uint256 as a buffer of 32 bytes, 22 : or equivalently (on little endian platforms) an array of 4 ulong. */ 23 : union FD_UINT256_ALIGNED fd_uint256 { 24 : ulong limbs[4]; 25 : uchar buf[32]; 26 : }; 27 : typedef union fd_uint256 fd_uint256_t; 28 : 29 : /* fd_uint256_bswap swaps 32 bytes. Useful to convert from/to 30 : little and big endian. */ 31 : static inline fd_uint256_t * 32 : fd_uint256_bswap( fd_uint256_t * r, 33 21081 : fd_uint256_t const * a ) { 34 21081 : ulong r3 = fd_ulong_bswap( a->limbs[0] ); 35 21081 : ulong r2 = fd_ulong_bswap( a->limbs[1] ); 36 21081 : ulong r1 = fd_ulong_bswap( a->limbs[2] ); 37 21081 : ulong r0 = fd_ulong_bswap( a->limbs[3] ); 38 21081 : r->limbs[3] = r3; 39 21081 : r->limbs[2] = r2; 40 21081 : r->limbs[1] = r1; 41 21081 : r->limbs[0] = r0; 42 21081 : return r; 43 21081 : } 44 : 45 : /* fd_uint256_eq returns 1 is a == b, 0 otherwise. */ 46 : static inline int 47 : fd_uint256_eq( fd_uint256_t const * a, 48 104196 : fd_uint256_t const * b ) { 49 104196 : return ( a->limbs[0] == b->limbs[0] ) 50 104196 : && ( a->limbs[1] == b->limbs[1] ) 51 104196 : && ( a->limbs[2] == b->limbs[2] ) 52 104196 : && ( a->limbs[3] == b->limbs[3] ); 53 104196 : } 54 : 55 : /* fd_uint256_cmp returns 0 is a == b, -1 if a < b, 1 if a > b. */ 56 : static inline int 57 : fd_uint256_cmp( fd_uint256_t const * a, 58 8168760 : fd_uint256_t const * b ) { 59 8174289 : for( int i=3; i>=0; i-- ) { 60 8173746 : if( a->limbs[i] != b->limbs[i] ) { 61 8168217 : return a->limbs[i] > b->limbs[i] ? 1 : -1; 62 8168217 : } 63 8173746 : } 64 543 : return 0; 65 8168760 : } 66 : 67 : /* fd_uint256_bit returns the i-th bit of a. 68 : Important: the return value is 0, non-zero, it's NOT 0, 1. */ 69 : static inline ulong 70 : fd_uint256_bit( fd_uint256_t const * a, 71 891855 : int i ) { 72 891855 : return a->limbs[i / 64] & (1UL << (i % 64)); 73 891855 : } 74 : 75 : #include "./fd_uint256_mul.h" 76 : 77 : #endif /* HEADER_fd_src_ballet_bigint_uint256_h */