bitcoin/field.h

99 lines
2.8 KiB
C
Raw Normal View History

2013-03-07 21:20:41 -03:00
#ifndef _SECP256K1_FIELD_
#define _SECP256K1_FIELD_
2013-03-09 18:47:40 -03:00
using namespace std;
2013-03-07 21:20:41 -03:00
#include <stdint.h>
#include <string>
#include "num.h"
// #define VERIFY_MAGNITUDE 1
namespace secp256k1 {
/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F,
* represented as 5 uint64_t's in base 2^52. The values are allowed to contain >52 each. In particular,
* each FieldElem has a 'magnitude' associated with it. Internally, a magnitude M means each element
* is at most M*(2^53-1), except the most significant one, which is limited to M*(2^49-1). All operations
* accept any input with magnitude at most M, and have different rules for propagating magnitude to their
* output.
*
* There are two implementations of the Normalize method, NormalizeCT executing in constant time.
* Similarly, a second version of all the other methods that call Normalize have been added which
* NormalizeCT instead to prevent sidechannel leaks.
2013-03-07 21:20:41 -03:00
*/
class FieldElem {
private:
2013-03-15 10:47:07 -03:00
// X = sum(i=0..4, elem[i]*2^52) mod n
2013-03-07 21:20:41 -03:00
uint64_t n[5];
#ifdef VERIFY_MAGNITUDE
int magnitude;
#endif
public:
/** Creates a constant field element. Magnitude=1 */
2013-03-15 10:47:07 -03:00
FieldElem(int x = 0);
2013-03-07 21:20:41 -03:00
2013-03-15 10:47:07 -03:00
FieldElem(const unsigned char *b32);
2013-03-09 18:47:40 -03:00
2013-03-07 21:20:41 -03:00
/** Normalizes the internal representation entries. Magnitude=1 */
2013-03-15 10:47:07 -03:00
void Normalize();
void NormalizeCT();
2013-03-07 21:20:41 -03:00
2013-03-15 10:47:07 -03:00
bool IsZero();
bool IsZeroCT();
2013-03-07 21:20:41 -03:00
2013-03-15 10:47:07 -03:00
bool friend operator==(FieldElem &a, FieldElem &b);
bool friend EqualCT(FieldElem &a, FieldElem &b);
2013-03-07 21:20:41 -03:00
/** extract as 32-byte big endian array */
2013-03-15 10:47:07 -03:00
void GetBytes(unsigned char *o);
void GetBytesCT(unsigned char *o);
2013-03-07 21:20:41 -03:00
/** set value of 32-byte big endian array */
2013-03-15 10:47:07 -03:00
void SetBytes(const unsigned char *in);
2013-03-07 21:20:41 -03:00
/** Set a FieldElem to be the negative of another. Increases magnitude by one. */
2013-03-15 10:47:07 -03:00
void SetNeg(const FieldElem &a, int magnitudeIn);
2013-03-07 21:20:41 -03:00
/** Multiplies this FieldElem with an integer constant. Magnitude is multiplied by v */
2013-03-15 10:47:07 -03:00
void operator*=(int v);
2013-03-07 21:20:41 -03:00
2013-03-15 10:47:07 -03:00
void operator+=(const FieldElem &a);
2013-03-07 21:20:41 -03:00
/** Set this FieldElem to be the multiplication of two others. Magnitude=1 */
2013-03-15 10:47:07 -03:00
void SetMult(const FieldElem &a, const FieldElem &b);
2013-03-07 21:20:41 -03:00
/** Set this FieldElem to be the square of another. Magnitude=1 */
2013-03-15 10:47:07 -03:00
void SetSquare(const FieldElem &a);
2013-03-07 21:20:41 -03:00
/** Set this to be the (modular) square root of another FieldElem. Magnitude=1 */
2013-03-15 10:47:07 -03:00
void SetSquareRoot(const FieldElem &a);
2013-03-07 21:20:41 -03:00
2013-03-15 10:47:07 -03:00
bool IsOdd();
bool IsOddCT();
2013-03-07 21:20:41 -03:00
/** Set this to be the (modular) inverse of another FieldElem. Magnitude=1 */
void SetInverse(FieldElem &a);
2013-03-07 21:20:41 -03:00
2013-03-15 10:47:07 -03:00
std::string ToString();
std::string ToStringCT();
2013-03-07 21:20:41 -03:00
2013-03-15 10:47:07 -03:00
void SetHex(const std::string &str);
2013-03-07 21:20:41 -03:00
};
2013-03-09 18:47:40 -03:00
class FieldConstants {
public:
const Number field_p;
2013-03-15 10:47:07 -03:00
FieldConstants();
2013-03-09 18:47:40 -03:00
};
2013-03-15 10:47:07 -03:00
const FieldConstants &GetFieldConst();
2013-03-10 23:09:07 -03:00
2013-03-07 21:20:41 -03:00
}
#endif