// out is the counter on entry, the output when done. void philox(unsigned int out[4], const unsigned int key[2]) { const unsigned int mult[2] = {0xCD9E8D57, 0xD2511F53}; int rnd, i; // Iterate and do each round in turn, updating the counter before we finally return it (Indexing from 1 is conveniant for the Weyl sequence.)... for (rnd=1;rnd<=10;rnd++) { // Calculate key for this step, by applying the Weyl sequence on it... unsigned int keyWeyl[2]; keyWeyl[0] = key[0] * rnd; keyWeyl[1] = key[1] * rnd; // Apply the s-blocks, also swap the r values between the s-blocks... unsigned int next[4]; next[0] = out[1] * mult[0]; next[2] = out[3] * mult[1]; next[3] = mul_hi(out[1],mult[0]) ^ keyWeyl[0] ^ out[0]; next[1] = mul_hi(out[3],mult[1]) ^ keyWeyl[1] ^ out[2]; // Prepare for the next step... for (i=0;i<4;i++) out[i] = next[i]; } }
INTERVAL mulDDI(double a, double b) { INTERVAL c; if ((a==0) || (b == 0)) { c.lo = c.hi = 0; return(c);} c.lo = mul_lo(a,b); c.hi = mul_hi(a,b); return(c); }