1  /*
       2    Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
       3    Licensed under the Apache 2.0 License.
       4  */
       5  
       6  
       7  #ifndef __FStar_UInt128_Verified_H
       8  #define __FStar_UInt128_Verified_H
       9  
      10  #include "FStar_UInt_8_16_32_64.h"
      11  #include <inttypes.h>
      12  #include <stdbool.h>
      13  #include "krml/types.h"
      14  #include "krml/internal/target.h"
      15  
      16  static inline uint64_t FStar_UInt128_constant_time_carry(uint64_t a, uint64_t b)
      17  {
      18    return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (uint32_t)63U;
      19  }
      20  
      21  static inline uint64_t FStar_UInt128_carry(uint64_t a, uint64_t b)
      22  {
      23    return FStar_UInt128_constant_time_carry(a, b);
      24  }
      25  
      26  static inline FStar_UInt128_uint128
      27  FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      28  {
      29    FStar_UInt128_uint128 lit;
      30    lit.low = a.low + b.low;
      31    lit.high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low);
      32    return lit;
      33  }
      34  
      35  static inline FStar_UInt128_uint128
      36  FStar_UInt128_add_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      37  {
      38    FStar_UInt128_uint128 lit;
      39    lit.low = a.low + b.low;
      40    lit.high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low);
      41    return lit;
      42  }
      43  
      44  static inline FStar_UInt128_uint128
      45  FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      46  {
      47    FStar_UInt128_uint128 lit;
      48    lit.low = a.low + b.low;
      49    lit.high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low);
      50    return lit;
      51  }
      52  
      53  static inline FStar_UInt128_uint128
      54  FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      55  {
      56    FStar_UInt128_uint128 lit;
      57    lit.low = a.low - b.low;
      58    lit.high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low);
      59    return lit;
      60  }
      61  
      62  static inline FStar_UInt128_uint128
      63  FStar_UInt128_sub_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      64  {
      65    FStar_UInt128_uint128 lit;
      66    lit.low = a.low - b.low;
      67    lit.high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low);
      68    return lit;
      69  }
      70  
      71  static inline FStar_UInt128_uint128
      72  FStar_UInt128_sub_mod_impl(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      73  {
      74    FStar_UInt128_uint128 lit;
      75    lit.low = a.low - b.low;
      76    lit.high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low);
      77    return lit;
      78  }
      79  
      80  static inline FStar_UInt128_uint128
      81  FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      82  {
      83    return FStar_UInt128_sub_mod_impl(a, b);
      84  }
      85  
      86  static inline FStar_UInt128_uint128
      87  FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      88  {
      89    FStar_UInt128_uint128 lit;
      90    lit.low = a.low & b.low;
      91    lit.high = a.high & b.high;
      92    return lit;
      93  }
      94  
      95  static inline FStar_UInt128_uint128
      96  FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
      97  {
      98    FStar_UInt128_uint128 lit;
      99    lit.low = a.low ^ b.low;
     100    lit.high = a.high ^ b.high;
     101    return lit;
     102  }
     103  
     104  static inline FStar_UInt128_uint128
     105  FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
     106  {
     107    FStar_UInt128_uint128 lit;
     108    lit.low = a.low | b.low;
     109    lit.high = a.high | b.high;
     110    return lit;
     111  }
     112  
     113  static inline FStar_UInt128_uint128 FStar_UInt128_lognot(FStar_UInt128_uint128 a)
     114  {
     115    FStar_UInt128_uint128 lit;
     116    lit.low = ~a.low;
     117    lit.high = ~a.high;
     118    return lit;
     119  }
     120  
     121  static uint32_t FStar_UInt128_u32_64 = (uint32_t)64U;
     122  
     123  static inline uint64_t FStar_UInt128_add_u64_shift_left(uint64_t hi, uint64_t lo, uint32_t s)
     124  {
     125    return (hi << s) + (lo >> (FStar_UInt128_u32_64 - s));
     126  }
     127  
     128  static inline uint64_t
     129  FStar_UInt128_add_u64_shift_left_respec(uint64_t hi, uint64_t lo, uint32_t s)
     130  {
     131    return FStar_UInt128_add_u64_shift_left(hi, lo, s);
     132  }
     133  
     134  static inline FStar_UInt128_uint128
     135  FStar_UInt128_shift_left_small(FStar_UInt128_uint128 a, uint32_t s)
     136  {
     137    if (s == (uint32_t)0U)
     138    {
     139      return a;
     140    }
     141    else
     142    {
     143      FStar_UInt128_uint128 lit;
     144      lit.low = a.low << s;
     145      lit.high = FStar_UInt128_add_u64_shift_left_respec(a.high, a.low, s);
     146      return lit;
     147    }
     148  }
     149  
     150  static inline FStar_UInt128_uint128
     151  FStar_UInt128_shift_left_large(FStar_UInt128_uint128 a, uint32_t s)
     152  {
     153    FStar_UInt128_uint128 lit;
     154    lit.low = (uint64_t)0U;
     155    lit.high = a.low << (s - FStar_UInt128_u32_64);
     156    return lit;
     157  }
     158  
     159  static inline FStar_UInt128_uint128
     160  FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s)
     161  {
     162    if (s < FStar_UInt128_u32_64)
     163    {
     164      return FStar_UInt128_shift_left_small(a, s);
     165    }
     166    else
     167    {
     168      return FStar_UInt128_shift_left_large(a, s);
     169    }
     170  }
     171  
     172  static inline uint64_t FStar_UInt128_add_u64_shift_right(uint64_t hi, uint64_t lo, uint32_t s)
     173  {
     174    return (lo >> s) + (hi << (FStar_UInt128_u32_64 - s));
     175  }
     176  
     177  static inline uint64_t
     178  FStar_UInt128_add_u64_shift_right_respec(uint64_t hi, uint64_t lo, uint32_t s)
     179  {
     180    return FStar_UInt128_add_u64_shift_right(hi, lo, s);
     181  }
     182  
     183  static inline FStar_UInt128_uint128
     184  FStar_UInt128_shift_right_small(FStar_UInt128_uint128 a, uint32_t s)
     185  {
     186    if (s == (uint32_t)0U)
     187    {
     188      return a;
     189    }
     190    else
     191    {
     192      FStar_UInt128_uint128 lit;
     193      lit.low = FStar_UInt128_add_u64_shift_right_respec(a.high, a.low, s);
     194      lit.high = a.high >> s;
     195      return lit;
     196    }
     197  }
     198  
     199  static inline FStar_UInt128_uint128
     200  FStar_UInt128_shift_right_large(FStar_UInt128_uint128 a, uint32_t s)
     201  {
     202    FStar_UInt128_uint128 lit;
     203    lit.low = a.high >> (s - FStar_UInt128_u32_64);
     204    lit.high = (uint64_t)0U;
     205    return lit;
     206  }
     207  
     208  static inline FStar_UInt128_uint128
     209  FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s)
     210  {
     211    if (s < FStar_UInt128_u32_64)
     212    {
     213      return FStar_UInt128_shift_right_small(a, s);
     214    }
     215    else
     216    {
     217      return FStar_UInt128_shift_right_large(a, s);
     218    }
     219  }
     220  
     221  static inline bool FStar_UInt128_eq(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
     222  {
     223    return a.low == b.low && a.high == b.high;
     224  }
     225  
     226  static inline bool FStar_UInt128_gt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
     227  {
     228    return a.high > b.high || (a.high == b.high && a.low > b.low);
     229  }
     230  
     231  static inline bool FStar_UInt128_lt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
     232  {
     233    return a.high < b.high || (a.high == b.high && a.low < b.low);
     234  }
     235  
     236  static inline bool FStar_UInt128_gte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
     237  {
     238    return a.high > b.high || (a.high == b.high && a.low >= b.low);
     239  }
     240  
     241  static inline bool FStar_UInt128_lte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
     242  {
     243    return a.high < b.high || (a.high == b.high && a.low <= b.low);
     244  }
     245  
     246  static inline FStar_UInt128_uint128
     247  FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
     248  {
     249    FStar_UInt128_uint128 lit;
     250    lit.low = FStar_UInt64_eq_mask(a.low, b.low) & FStar_UInt64_eq_mask(a.high, b.high);
     251    lit.high = FStar_UInt64_eq_mask(a.low, b.low) & FStar_UInt64_eq_mask(a.high, b.high);
     252    return lit;
     253  }
     254  
     255  static inline FStar_UInt128_uint128
     256  FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
     257  {
     258    FStar_UInt128_uint128 lit;
     259    lit.low =
     260      (FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high))
     261      | (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low));
     262    lit.high =
     263      (FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high))
     264      | (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low));
     265    return lit;
     266  }
     267  
     268  static inline FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t a)
     269  {
     270    FStar_UInt128_uint128 lit;
     271    lit.low = a;
     272    lit.high = (uint64_t)0U;
     273    return lit;
     274  }
     275  
     276  static inline uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a)
     277  {
     278    return a.low;
     279  }
     280  
     281  static inline uint64_t FStar_UInt128_u64_mod_32(uint64_t a)
     282  {
     283    return a & (uint64_t)0xffffffffU;
     284  }
     285  
     286  static uint32_t FStar_UInt128_u32_32 = (uint32_t)32U;
     287  
     288  static inline uint64_t FStar_UInt128_u32_combine(uint64_t hi, uint64_t lo)
     289  {
     290    return lo + (hi << FStar_UInt128_u32_32);
     291  }
     292  
     293  static inline FStar_UInt128_uint128 FStar_UInt128_mul32(uint64_t x, uint32_t y)
     294  {
     295    FStar_UInt128_uint128 lit;
     296    lit.low =
     297      FStar_UInt128_u32_combine((x >> FStar_UInt128_u32_32)
     298        * (uint64_t)y
     299        + (FStar_UInt128_u64_mod_32(x) * (uint64_t)y >> FStar_UInt128_u32_32),
     300        FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * (uint64_t)y));
     301    lit.high =
     302      ((x >> FStar_UInt128_u32_32)
     303      * (uint64_t)y
     304      + (FStar_UInt128_u64_mod_32(x) * (uint64_t)y >> FStar_UInt128_u32_32))
     305      >> FStar_UInt128_u32_32;
     306    return lit;
     307  }
     308  
     309  static inline uint64_t FStar_UInt128_u32_combine_(uint64_t hi, uint64_t lo)
     310  {
     311    return lo + (hi << FStar_UInt128_u32_32);
     312  }
     313  
     314  static inline FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x, uint64_t y)
     315  {
     316    FStar_UInt128_uint128 lit;
     317    lit.low =
     318      FStar_UInt128_u32_combine_(FStar_UInt128_u64_mod_32(x)
     319        * (y >> FStar_UInt128_u32_32)
     320        +
     321          FStar_UInt128_u64_mod_32((x >> FStar_UInt128_u32_32)
     322            * FStar_UInt128_u64_mod_32(y)
     323            + (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32)),
     324        FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y)));
     325    lit.high =
     326      (x >> FStar_UInt128_u32_32)
     327      * (y >> FStar_UInt128_u32_32)
     328      +
     329        (((x >> FStar_UInt128_u32_32)
     330        * FStar_UInt128_u64_mod_32(y)
     331        + (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32))
     332        >> FStar_UInt128_u32_32)
     333      +
     334        ((FStar_UInt128_u64_mod_32(x)
     335        * (y >> FStar_UInt128_u32_32)
     336        +
     337          FStar_UInt128_u64_mod_32((x >> FStar_UInt128_u32_32)
     338            * FStar_UInt128_u64_mod_32(y)
     339            + (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32)))
     340        >> FStar_UInt128_u32_32);
     341    return lit;
     342  }
     343  
     344  
     345  #define __FStar_UInt128_Verified_H_DEFINED
     346  #endif