#include # if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) /* even with gcc, the typedef won't work for 32-bit platforms */ typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit * platforms */ typedef __int128_t int128_t; # else # error "Need GCC 3.1 or later to define type uint128_t" # endif typedef uint8_t u8; typedef uint32_t u32; typedef uint64_t u64; typedef int64_t s64; /* * The representation of field elements. * ------------------------------------ * * We represent field elements with either four 128-bit values, eight 128-bit * values, or four 64-bit values. The field element represented is: * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p) * or: * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p) * * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits * apart, but are 128-bits wide, the most significant bits of each limb overlap * with the least significant bits of the next. * * A field element with four limbs is an 'felem'. One with eight limbs is a * 'longfelem' * * A field element with four, 64-bit values is called a 'smallfelem'. Small * values are used as intermediate values before multiplication. */ # define NLIMBS 4 typedef uint128_t limb; typedef limb felem[NLIMBS]; typedef limb longfelem[NLIMBS * 2]; typedef u64 smallfelem[NLIMBS]; /* * The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We * can serialise an element of this field into 32 bytes. We call this an * felem_bytearray. */ typedef u8 felem_bytearray[32]; void point_add(felem x3, felem y3, felem z3, const felem x1, const felem y1, const felem z1, const int mixed, const smallfelem x2, const smallfelem y2, const smallfelem z2);