#ifndef __SCALAR_HPP #define __SCALAR_HPP #include #include #include #include #include extern "C" { #include "scalar.h" #include "curvepoint_fp.h" #include "twistpoint_fp2.h" #include "fp12e.h" } class Scalar { public: Scalar(); Scalar(const scalar_t& input); Scalar(mpz_class input); static void init(); void set(const scalar_t& input); void set(mpz_class input); void set_random(); void set_field_random(); mpz_class toInt() const; Scalar operator+(const Scalar& b) const; Scalar operator-(const Scalar& b) const; Scalar operator*(const Scalar& b) const; Scalar operator/(const Scalar& b) const; Scalar operator-() const; Scalar& operator++(); Scalar operator++(int); Scalar& operator--(); Scalar operator--(int); Scalar fieldAdd(const Scalar& b) const; Scalar fieldSub(const Scalar& b) const; Scalar fieldMult(const Scalar& b) const; Scalar fieldMultInverse() const; Scalar curveAdd(const Scalar& b) const; Scalar curveSub(const Scalar& b) const; Scalar curveMult(const Scalar& b) const; Scalar curveMultInverse() const; void mult(curvepoint_fp_t rop, const curvepoint_fp_t& op1) const; void mult(twistpoint_fp2_t rop, const twistpoint_fp2_t& op1) const; void mult(fp12e_t rop, const fp12e_t& op1) const; bool operator==(const Scalar& b) const; bool operator<(const Scalar& b) const; bool operator<=(const Scalar& b) const; bool operator>(const Scalar& b) const; bool operator>=(const Scalar& b) const; bool operator!=(const Scalar& b) const; friend std::ostream& operator<<(std::ostream& os, const Scalar& output); friend std::istream& operator>>(std::istream& is, Scalar& input); private: class SecretScalar { public: SecretScalar(); SecretScalar(const Scalar& input); SecretScalar(mpz_class input); /* Problem: thanks to the magic of weird typedefs, scalar_t is actually an array, which complicates returning it * Solution: make the return value a reference * * This feels bad, I know, but it will only be used in places where the variable remains in scope for the duration of usage * That's also why this class is private -- so it cannot be misused. */ const scalar_t& expose() const; private: void set(mpz_class input); scalar_t element; }; SecretScalar to_scalar_t() const; /* This is the thing everything else is modulused of; * whenever we do arithmetic of scalars, * we're doing arithmetic on field elements (\in F_p), * not directly on curvepoints, so we want p, not n. * Do keep in mind, though, that this means Scalars shouldn't in general * have arithmetic done on them prior to interacting with curvepoints, * if you're calculating something like an exponentiation of products * of Scalars (or similar). */ static mpz_class mpz_bn_p; static mpz_class mpz_bn_n; mpz_class element; }; #endif