Merge remote-tracking branch 'codeshark/master'
Add a constant-time Normalize().
This commit is contained in:
commit
3c5e388798
72
field.cpp
72
field.cpp
|
@ -34,40 +34,43 @@ FieldElem::FieldElem(const unsigned char *b32) {
|
||||||
|
|
||||||
void FieldElem::Normalize() {
|
void FieldElem::Normalize() {
|
||||||
uint64_t c;
|
uint64_t c;
|
||||||
if (n[0] > 0xFFFFFFFFFFFFFULL || n[1] > 0xFFFFFFFFFFFFFULL || n[2] > 0xFFFFFFFFFFFFFULL || n[3] > 0xFFFFFFFFFFFFFULL || n[4] > 0xFFFFFFFFFFFFULL) {
|
c = n[0];
|
||||||
c = n[0];
|
uint64_t t0 = c & 0xFFFFFFFFFFFFFULL;
|
||||||
uint64_t t0 = c & 0xFFFFFFFFFFFFFULL;
|
c = (c >> 52) + n[1];
|
||||||
c = (c >> 52) + n[1];
|
uint64_t t1 = c & 0xFFFFFFFFFFFFFULL;
|
||||||
uint64_t t1 = c & 0xFFFFFFFFFFFFFULL;
|
c = (c >> 52) + n[2];
|
||||||
c = (c >> 52) + n[2];
|
uint64_t t2 = c & 0xFFFFFFFFFFFFFULL;
|
||||||
uint64_t t2 = c & 0xFFFFFFFFFFFFFULL;
|
c = (c >> 52) + n[3];
|
||||||
c = (c >> 52) + n[3];
|
uint64_t t3 = c & 0xFFFFFFFFFFFFFULL;
|
||||||
uint64_t t3 = c & 0xFFFFFFFFFFFFFULL;
|
c = (c >> 52) + n[4];
|
||||||
c = (c >> 52) + n[4];
|
uint64_t t4 = c & 0x0FFFFFFFFFFFFULL;
|
||||||
uint64_t t4 = c & 0x0FFFFFFFFFFFFULL;
|
c >>= 48;
|
||||||
c >>= 48;
|
|
||||||
if (c) {
|
// The following code will not modify the t's if c is initially 0.
|
||||||
c = c * 0x1000003D1ULL + t0;
|
c = c * 0x1000003D1ULL + t0;
|
||||||
t0 = c & 0xFFFFFFFFFFFFFULL;
|
t0 = c & 0xFFFFFFFFFFFFFULL;
|
||||||
c = (c >> 52) + t1;
|
c = (c >> 52) + t1;
|
||||||
t1 = c & 0xFFFFFFFFFFFFFULL;
|
t1 = c & 0xFFFFFFFFFFFFFULL;
|
||||||
c = (c >> 52) + t2;
|
c = (c >> 52) + t2;
|
||||||
t2 = c & 0xFFFFFFFFFFFFFULL;
|
t2 = c & 0xFFFFFFFFFFFFFULL;
|
||||||
c = (c >> 52) + t3;
|
c = (c >> 52) + t3;
|
||||||
t3 = c & 0xFFFFFFFFFFFFFULL;
|
t3 = c & 0xFFFFFFFFFFFFFULL;
|
||||||
c = (c >> 52) + t4;
|
c = (c >> 52) + t4;
|
||||||
t4 = c & 0x0FFFFFFFFFFFFULL;
|
t4 = c & 0x0FFFFFFFFFFFFULL;
|
||||||
c >>= 48;
|
|
||||||
}
|
// Replace n's with t's if one of the n's overflows.
|
||||||
n[0] = t0; n[1] = t1; n[2] = t2; n[3] = t3; n[4] = t4;
|
// If none of the n's overflow to begin with, the t's will just be the n's already and
|
||||||
}
|
// we effectively ignore the results of the previous computations.
|
||||||
if (n[4] == 0xFFFFFFFFFFFFULL && n[3] == 0xFFFFFFFFFFFFFULL && n[2] == 0xFFFFFFFFFFFFFULL && n[1] == 0xFFFFFFFFFFFFF && n[0] >= 0xFFFFEFFFFFC2FULL) {
|
n[0] = t0; n[1] = t1; n[2] = t2; n[3] = t3; n[4] = t4;
|
||||||
n[4] = 0;
|
|
||||||
n[3] = 0;
|
// Subtract p if result >= p
|
||||||
n[2] = 0;
|
uint64_t mask = (uint64_t)~(-(int64_t)(n[4] == 0xFFFFFFFFFFFFULL && n[3] == 0xFFFFFFFFFFFFFULL && n[2] == 0xFFFFFFFFFFFFFULL && n[1] == 0xFFFFFFFFFFFFF && n[0] >= 0xFFFFEFFFFFC2FULL));
|
||||||
n[1] = 0;
|
n[4] &= mask;
|
||||||
n[0] -= 0xFFFFEFFFFFC2FULL;
|
n[3] &= mask;
|
||||||
}
|
n[2] &= mask;
|
||||||
|
n[1] &= mask;
|
||||||
|
n[0] -= (~mask & 0xFFFFEFFFFFC2FULL);
|
||||||
|
|
||||||
#ifdef VERIFY_MAGNITUDE
|
#ifdef VERIFY_MAGNITUDE
|
||||||
magnitude = 1;
|
magnitude = 1;
|
||||||
normalized = true;
|
normalized = true;
|
||||||
|
@ -354,6 +357,7 @@ const FieldConstants &GetFieldConst() {
|
||||||
return field_const;
|
return field_const;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nonbuiltin Field Inverse is not constant time.
|
||||||
void FieldElem::SetInverse(FieldElem &a) {
|
void FieldElem::SetInverse(FieldElem &a) {
|
||||||
#if defined(USE_FIELDINVERSE_BUILTIN)
|
#if defined(USE_FIELDINVERSE_BUILTIN)
|
||||||
// calculate a^p, with p={45,63,1019,1023}
|
// calculate a^p, with p={45,63,1019,1023}
|
||||||
|
|
6
field.h
6
field.h
|
@ -56,10 +56,10 @@ public:
|
||||||
|
|
||||||
void operator+=(const FieldElem &a);
|
void operator+=(const FieldElem &a);
|
||||||
|
|
||||||
/** Set this FieldElem to be the multiplication of two others. Magnitude=1 */
|
/** Set this FieldElem to be the multiplication of two others. Magnitude=1 (variable time) */
|
||||||
void SetMult(const FieldElem &a, const FieldElem &b);
|
void SetMult(const FieldElem &a, const FieldElem &b);
|
||||||
|
|
||||||
/** Set this FieldElem to be the square of another. Magnitude=1 */
|
/** Set this FieldElem to be the square of another. Magnitude=1 (variable time) */
|
||||||
void SetSquare(const FieldElem &a);
|
void SetSquare(const FieldElem &a);
|
||||||
|
|
||||||
/** Set this to be the (modular) square root of another FieldElem. Magnitude=1 */
|
/** Set this to be the (modular) square root of another FieldElem. Magnitude=1 */
|
||||||
|
@ -67,7 +67,7 @@ public:
|
||||||
|
|
||||||
bool IsOdd() const;
|
bool IsOdd() const;
|
||||||
|
|
||||||
/** Set this to be the (modular) inverse of another FieldElem. Magnitude=1 */
|
/** Set this to be the (modular) inverse of another FieldElem. Magnitude=1 (variable time) */
|
||||||
void SetInverse(FieldElem &a);
|
void SetInverse(FieldElem &a);
|
||||||
|
|
||||||
std::string ToString();
|
std::string ToString();
|
||||||
|
|
Loading…
Reference in New Issue