/* Autogenerated: 'src/ExtractionOCaml/dettman_multiplication' --inline --static --use-value-barrier secp256k1_dettman 64 5 48 2 '2^256 - 4294968273' mul square */
/* curve description: secp256k1_dettman */
/* machine_wordsize = 64 (from "64") */
/* requested operations: mul, square */
/* n = 5 (from "5") */
/* last_limb_width = 48 (from "48") */
/* last_reduction = 2 (from "2") */
/* s-c = 2^256 - [(1, 4294968273)] (from "2^256 - 4294968273") */
/* inbounds_multiplier: None (from "") */
/*  */
/* Computed values: */
/*  */
/*  */

#include <stdint.h>
#if defined(__GNUC__) || defined(__clang__)
#  define FIAT_SECP256K1_DETTMAN_FIAT_EXTENSION __extension__
#  define FIAT_SECP256K1_DETTMAN_FIAT_INLINE __inline__
#else
#  define FIAT_SECP256K1_DETTMAN_FIAT_EXTENSION
#  define FIAT_SECP256K1_DETTMAN_FIAT_INLINE
#endif

FIAT_SECP256K1_DETTMAN_FIAT_EXTENSION typedef signed __int128 fiat_secp256k1_dettman_int128;
FIAT_SECP256K1_DETTMAN_FIAT_EXTENSION typedef unsigned __int128 fiat_secp256k1_dettman_uint128;

#if (-1 & 3) != 3
#error "This code only works on a two's complement system"
#endif


/*
 * The function fiat_secp256k1_dettman_mul multiplies two field elements.
 *
 * Postconditions:
 *   eval out1 mod 115792089237316195423570985008687907853269984665640564039457584007908834671663 = (eval arg1 * eval arg2) mod 115792089237316195423570985008687907853269984665640564039457584007908834671663
 *
 * Input Bounds:
 *   arg1: [[0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1fffffffffffe]]
 *   arg2: [[0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1fffffffffffe]]
 * Output Bounds:
 *   out1: [[0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x17fffffffffff]]
 */
static FIAT_SECP256K1_DETTMAN_FIAT_INLINE void fiat_secp256k1_dettman_mul(uint64_t out1[5], const uint64_t arg1[5], const uint64_t arg2[5]) {
  fiat_secp256k1_dettman_uint128 x1;
  uint64_t x2;
  uint64_t x3;
  fiat_secp256k1_dettman_uint128 x4;
  uint64_t x5;
  uint64_t x6;
  fiat_secp256k1_dettman_uint128 x7;
  uint64_t x8;
  uint64_t x9;
  fiat_secp256k1_dettman_uint128 x10;
  uint64_t x11;
  uint64_t x12;
  uint64_t x13;
  uint64_t x14;
  fiat_secp256k1_dettman_uint128 x15;
  uint64_t x16;
  uint64_t x17;
  fiat_secp256k1_dettman_uint128 x18;
  uint64_t x19;
  uint64_t x20;
  fiat_secp256k1_dettman_uint128 x21;
  uint64_t x22;
  uint64_t x23;
  fiat_secp256k1_dettman_uint128 x24;
  uint64_t x25;
  uint64_t x26;
  fiat_secp256k1_dettman_uint128 x27;
  uint64_t x28;
  uint64_t x29;
  fiat_secp256k1_dettman_uint128 x30;
  uint64_t x31;
  uint64_t x32;
  uint64_t x33;
  x1 = ((fiat_secp256k1_dettman_uint128)(arg1[4]) * (arg2[4]));
  x2 = (uint64_t)(x1 >> 64);
  x3 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff));
  x4 = ((((fiat_secp256k1_dettman_uint128)(arg1[0]) * (arg2[3])) + (((fiat_secp256k1_dettman_uint128)(arg1[1]) * (arg2[2])) + (((fiat_secp256k1_dettman_uint128)(arg1[2]) * (arg2[1])) + ((fiat_secp256k1_dettman_uint128)(arg1[3]) * (arg2[0]))))) + ((fiat_secp256k1_dettman_uint128)x3 * UINT64_C(0x1000003d10)));
  x5 = (uint64_t)(x4 >> 52);
  x6 = (uint64_t)(x4 & UINT64_C(0xfffffffffffff));
  x7 = ((x5 + (((fiat_secp256k1_dettman_uint128)(arg1[0]) * (arg2[4])) + (((fiat_secp256k1_dettman_uint128)(arg1[1]) * (arg2[3])) + (((fiat_secp256k1_dettman_uint128)(arg1[2]) * (arg2[2])) + (((fiat_secp256k1_dettman_uint128)(arg1[3]) * (arg2[1])) + ((fiat_secp256k1_dettman_uint128)(arg1[4]) * (arg2[0]))))))) + ((fiat_secp256k1_dettman_uint128)x2 * UINT64_C(0x1000003d10000)));
  x8 = (uint64_t)(x7 >> 52);
  x9 = (uint64_t)(x7 & UINT64_C(0xfffffffffffff));
  x10 = (x8 + (((fiat_secp256k1_dettman_uint128)(arg1[1]) * (arg2[4])) + (((fiat_secp256k1_dettman_uint128)(arg1[2]) * (arg2[3])) + (((fiat_secp256k1_dettman_uint128)(arg1[3]) * (arg2[2])) + ((fiat_secp256k1_dettman_uint128)(arg1[4]) * (arg2[1]))))));
  x11 = (uint64_t)(x10 >> 52);
  x12 = (uint64_t)(x10 & UINT64_C(0xfffffffffffff));
  x13 = (x9 >> 48);
  x14 = (x9 & UINT64_C(0xffffffffffff));
  x15 = (((fiat_secp256k1_dettman_uint128)(arg1[0]) * (arg2[0])) + ((fiat_secp256k1_dettman_uint128)(x13 + (x12 << 4)) * UINT64_C(0x1000003d1)));
  x16 = (uint64_t)(x15 >> 52);
  x17 = (uint64_t)(x15 & UINT64_C(0xfffffffffffff));
  x18 = (x11 + (((fiat_secp256k1_dettman_uint128)(arg1[2]) * (arg2[4])) + (((fiat_secp256k1_dettman_uint128)(arg1[3]) * (arg2[3])) + ((fiat_secp256k1_dettman_uint128)(arg1[4]) * (arg2[2])))));
  x19 = (uint64_t)(x18 >> 52);
  x20 = (uint64_t)(x18 & UINT64_C(0xfffffffffffff));
  x21 = ((x16 + (((fiat_secp256k1_dettman_uint128)(arg1[0]) * (arg2[1])) + ((fiat_secp256k1_dettman_uint128)(arg1[1]) * (arg2[0])))) + ((fiat_secp256k1_dettman_uint128)x20 * UINT64_C(0x1000003d10)));
  x22 = (uint64_t)(x21 >> 52);
  x23 = (uint64_t)(x21 & UINT64_C(0xfffffffffffff));
  x24 = (x19 + (((fiat_secp256k1_dettman_uint128)(arg1[3]) * (arg2[4])) + ((fiat_secp256k1_dettman_uint128)(arg1[4]) * (arg2[3]))));
  x25 = (uint64_t)(x24 >> 64);
  x26 = (uint64_t)(x24 & UINT64_C(0xffffffffffffffff));
  x27 = ((x22 + (((fiat_secp256k1_dettman_uint128)(arg1[0]) * (arg2[2])) + (((fiat_secp256k1_dettman_uint128)(arg1[1]) * (arg2[1])) + ((fiat_secp256k1_dettman_uint128)(arg1[2]) * (arg2[0]))))) + ((fiat_secp256k1_dettman_uint128)x26 * UINT64_C(0x1000003d10)));
  x28 = (uint64_t)(x27 >> 52);
  x29 = (uint64_t)(x27 & UINT64_C(0xfffffffffffff));
  x30 = ((x28 + x6) + ((fiat_secp256k1_dettman_uint128)x25 * UINT64_C(0x1000003d10000)));
  x31 = (uint64_t)(x30 >> 52);
  x32 = (uint64_t)(x30 & UINT64_C(0xfffffffffffff));
  x33 = (x31 + x14);
  out1[0] = x17;
  out1[1] = x23;
  out1[2] = x29;
  out1[3] = x32;
  out1[4] = x33;
}

/*
 * The function fiat_secp256k1_dettman_square squares a field element.
 *
 * Postconditions:
 *   eval out1 mod 115792089237316195423570985008687907853269984665640564039457584007908834671663 = (eval arg1 * eval arg1) mod 115792089237316195423570985008687907853269984665640564039457584007908834671663
 *
 * Input Bounds:
 *   arg1: [[0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1fffffffffffe]]
 * Output Bounds:
 *   out1: [[0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x1ffffffffffffe], [0x0 ~> 0x17fffffffffff]]
 */
static FIAT_SECP256K1_DETTMAN_FIAT_INLINE void fiat_secp256k1_dettman_square(uint64_t out1[5], const uint64_t arg1[5]) {
  uint64_t x1;
  uint64_t x2;
  uint64_t x3;
  uint64_t x4;
  fiat_secp256k1_dettman_uint128 x5;
  uint64_t x6;
  uint64_t x7;
  fiat_secp256k1_dettman_uint128 x8;
  uint64_t x9;
  uint64_t x10;
  fiat_secp256k1_dettman_uint128 x11;
  uint64_t x12;
  uint64_t x13;
  fiat_secp256k1_dettman_uint128 x14;
  uint64_t x15;
  uint64_t x16;
  uint64_t x17;
  uint64_t x18;
  fiat_secp256k1_dettman_uint128 x19;
  uint64_t x20;
  uint64_t x21;
  fiat_secp256k1_dettman_uint128 x22;
  uint64_t x23;
  uint64_t x24;
  fiat_secp256k1_dettman_uint128 x25;
  uint64_t x26;
  uint64_t x27;
  fiat_secp256k1_dettman_uint128 x28;
  uint64_t x29;
  uint64_t x30;
  fiat_secp256k1_dettman_uint128 x31;
  uint64_t x32;
  uint64_t x33;
  fiat_secp256k1_dettman_uint128 x34;
  uint64_t x35;
  uint64_t x36;
  uint64_t x37;
  x1 = ((arg1[3]) * 0x2);
  x2 = ((arg1[2]) * 0x2);
  x3 = ((arg1[1]) * 0x2);
  x4 = ((arg1[0]) * 0x2);
  x5 = ((fiat_secp256k1_dettman_uint128)(arg1[4]) * (arg1[4]));
  x6 = (uint64_t)(x5 >> 64);
  x7 = (uint64_t)(x5 & UINT64_C(0xffffffffffffffff));
  x8 = ((((fiat_secp256k1_dettman_uint128)x4 * (arg1[3])) + ((fiat_secp256k1_dettman_uint128)x3 * (arg1[2]))) + ((fiat_secp256k1_dettman_uint128)x7 * UINT64_C(0x1000003d10)));
  x9 = (uint64_t)(x8 >> 52);
  x10 = (uint64_t)(x8 & UINT64_C(0xfffffffffffff));
  x11 = ((x9 + (((fiat_secp256k1_dettman_uint128)x4 * (arg1[4])) + (((fiat_secp256k1_dettman_uint128)x3 * (arg1[3])) + ((fiat_secp256k1_dettman_uint128)(arg1[2]) * (arg1[2]))))) + ((fiat_secp256k1_dettman_uint128)x6 * UINT64_C(0x1000003d10000)));
  x12 = (uint64_t)(x11 >> 52);
  x13 = (uint64_t)(x11 & UINT64_C(0xfffffffffffff));
  x14 = (x12 + (((fiat_secp256k1_dettman_uint128)x3 * (arg1[4])) + ((fiat_secp256k1_dettman_uint128)x2 * (arg1[3]))));
  x15 = (uint64_t)(x14 >> 52);
  x16 = (uint64_t)(x14 & UINT64_C(0xfffffffffffff));
  x17 = (x13 >> 48);
  x18 = (x13 & UINT64_C(0xffffffffffff));
  x19 = (((fiat_secp256k1_dettman_uint128)(arg1[0]) * (arg1[0])) + ((fiat_secp256k1_dettman_uint128)(x17 + (x16 << 4)) * UINT64_C(0x1000003d1)));
  x20 = (uint64_t)(x19 >> 52);
  x21 = (uint64_t)(x19 & UINT64_C(0xfffffffffffff));
  x22 = (x15 + (((fiat_secp256k1_dettman_uint128)x2 * (arg1[4])) + ((fiat_secp256k1_dettman_uint128)(arg1[3]) * (arg1[3]))));
  x23 = (uint64_t)(x22 >> 52);
  x24 = (uint64_t)(x22 & UINT64_C(0xfffffffffffff));
  x25 = ((x20 + ((fiat_secp256k1_dettman_uint128)x4 * (arg1[1]))) + ((fiat_secp256k1_dettman_uint128)x24 * UINT64_C(0x1000003d10)));
  x26 = (uint64_t)(x25 >> 52);
  x27 = (uint64_t)(x25 & UINT64_C(0xfffffffffffff));
  x28 = (x23 + ((fiat_secp256k1_dettman_uint128)x1 * (arg1[4])));
  x29 = (uint64_t)(x28 >> 64);
  x30 = (uint64_t)(x28 & UINT64_C(0xffffffffffffffff));
  x31 = ((x26 + (((fiat_secp256k1_dettman_uint128)x4 * (arg1[2])) + ((fiat_secp256k1_dettman_uint128)(arg1[1]) * (arg1[1])))) + ((fiat_secp256k1_dettman_uint128)x30 * UINT64_C(0x1000003d10)));
  x32 = (uint64_t)(x31 >> 52);
  x33 = (uint64_t)(x31 & UINT64_C(0xfffffffffffff));
  x34 = ((x32 + x10) + ((fiat_secp256k1_dettman_uint128)x29 * UINT64_C(0x1000003d10000)));
  x35 = (uint64_t)(x34 >> 52);
  x36 = (uint64_t)(x34 & UINT64_C(0xfffffffffffff));
  x37 = (x35 + x18);
  out1[0] = x21;
  out1[1] = x27;
  out1[2] = x33;
  out1[3] = x36;
  out1[4] = x37;
}
