typedef unsigned short u16;
typedef unsigned char u8;

static const u8 x[32] = {
  0x6b,0x17,0xd1,0xf2,0xe1,0x2c,0x42,0x47,
  0xf8,0xbc,0xe6,0xe5,0x63,0xa4,0x40,0xf2,
  0x77,0x03,0x7d,0x81,0x2d,0xeb,0x33,0xa0,
  0xf4,0xa1,0x39,0x45,0xd8,0x98,0xc2,0x96
};

static const u8 n[32] = {
  0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xbc,0xe6,0xfa,0xad,0xa7,0x17,0x9e,0x84,
  0xf3,0xb9,0xca,0xc2,0xfc,0x63,0x25,0x51
};

static const u8 rd[32] = {
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,
};

static int add (u8 *r, const u8 *a, const u8 *b)
{
  int i;
  u16 t = 0;
  for (i = 0; i < 32; i++)
    {
      t = (u16) a[31 - i] + b[31 - i] + t;
      r[31 - i] = t;
      t >>= 8;
    }
  return t;
}

static void mod (u8 *r, const u8 *a, int c)
{
  int i;
  u16 t = 0;
  if (!c)
    {
      for (i = 0; i < 32; i++)
        {
          if (a[i] < n[i])
            return;
        }
    }
  for (i = 0; i < 32; i++)
    {
      t = (u16) a[31 - i] - n[31 - i] - t;
      r[31 - i] = t;
      t >>= 15;
    }
}

static void cpy (u8 *dst, const u8 *src)
{
  int i;
  for (i = 0; i < 32; i++)
    dst[i] = src[i];
}

void ECDSA_256_sign (u8 *sig, const u8 *hash)
{
  int c;
  cpy (sig, x);
  c = add (sig + 32, hash, rd);
  mod (sig + 32, sig + 32, c);
}
