I haven't found many other fixed-point or 256-bit classes. So what are you guys using?
The function I use to compute a subtraction between 2 256-bit numbers (mod p):
##############################################################
#compute r = (a - b) mod p
void sub (uint64_t *r, const uint64_t *a, const uint64_t *b) {
uint64_t a0, a1, a2, a3, b0, b1, b2, b3, p;
a0 = a[0];
a1 = a[1];
a2 = a[2];
a3 = a[3];
b0 = b[0];
b1 = b[1];
b2 = b[2];
b3 = b[3];
size_t borrow = 0;
//compute: (a0, a1, a2, a3) = (a0, a1, a2, a3) - (b0, b1, b2, b3) with borrow //
asm("subq %5, %1\n\t"
"sbbq %6, %2\n\t"
"sbbq %7, %3\n\t"
"sbbq %8, %4\n\t"
"sbbq $0, %0"
: "+r" (borrow), "+r" (a0), "+r" (a1), "+r" (a2), "+r" (a3)
: "r" (b0), "r" (b1), "r" (b2), "r" (b3)
: "cc");
if(borrow == 0){ //if a >= b
r[0] = a0;
r[1] = a1;
r[2] = a2;
r[3] = a3;
return;
}
//if a < b
p = 0x1000003d1;
//compute: (a0, a1, a2, a3) = (a0, a1, a2, a3) - p
asm("subq %4, %0\n\t"
"sbbq $0, %1\n\t"
"sbbq $0, %2\n\t"
"sbbq $0, %3"
: "+r" (a0), "+r" (a1), "+r" (a2), "+r" (a3)
: "r" (p)
: "cc");
r[0] = a0;
r[1] = a1;
r[2] = a2;
r[3] = a3;
return;
}
##################################################################
in the main function:
//a = a0 + a1*(2^64) + a2*(2^128) + a3*(2^196)
uint64_t a = {0x59f2815b16f81798, 0x029bfcdb2dce28d9, 0x55a06295ce870b07, 0x79be667ef9dcbbac};
uint64_t b = {0x9c47d08ffb10d4b8, 0xfd17b448a6855419, 0x5da4fbfc0e1108a8, 0x483ada7726a3c465};
uint64_t c [4];
uint64_t* ptra = &a[0];
uint64_t* ptrb = &b[0];
uint64_t* ptrb = &c[0];
sub(ptrc, ptra, ptrb); //compute c = a - b mod p