mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-09 13:37:58 -05:00
179 lines
3.8 KiB
C++
179 lines
3.8 KiB
C++
/*
|
|
* P256Element.cpp
|
|
*
|
|
*/
|
|
|
|
#include "P256Element.h"
|
|
|
|
#include "Math/gfp.hpp"
|
|
|
|
EC_GROUP* P256Element::curve;
|
|
|
|
void P256Element::init()
|
|
{
|
|
curve = EC_GROUP_new_by_curve_name(NID_secp256k1);
|
|
assert(curve != 0);
|
|
auto modulus = EC_GROUP_get0_order(curve);
|
|
auto mod = BN_bn2dec(modulus);
|
|
Scalar::init_field(mod, false);
|
|
free(mod);
|
|
}
|
|
|
|
void P256Element::finish()
|
|
{
|
|
EC_GROUP_free(curve);
|
|
}
|
|
|
|
P256Element::P256Element()
|
|
{
|
|
point = EC_POINT_new(curve);
|
|
assert(point != 0);
|
|
assert(EC_POINT_set_to_infinity(curve, point) != 0);
|
|
}
|
|
|
|
P256Element::P256Element(const Scalar& other) :
|
|
P256Element()
|
|
{
|
|
BIGNUM* exp = BN_new();
|
|
BN_dec2bn(&exp, bigint(other).get_str().c_str());
|
|
assert(EC_POINT_mul(curve, point, exp, 0, 0, 0) != 0);
|
|
BN_free(exp);
|
|
}
|
|
|
|
P256Element::P256Element(word other) :
|
|
P256Element()
|
|
{
|
|
BIGNUM* exp = BN_new();
|
|
BN_dec2bn(&exp, to_string(other).c_str());
|
|
assert(EC_POINT_mul(curve, point, exp, 0, 0, 0) != 0);
|
|
BN_free(exp);
|
|
}
|
|
|
|
P256Element::~P256Element()
|
|
{
|
|
EC_POINT_free(point);
|
|
}
|
|
|
|
P256Element& P256Element::operator =(const P256Element& other)
|
|
{
|
|
assert(EC_POINT_copy(point, other.point) != 0);
|
|
return *this;
|
|
}
|
|
|
|
void P256Element::check()
|
|
{
|
|
assert(EC_POINT_is_on_curve(curve, point, 0) == 1);
|
|
}
|
|
|
|
P256Element::Scalar P256Element::x() const
|
|
{
|
|
BIGNUM* x = BN_new();
|
|
#if OPENSSL_VERSION_MAJOR >= 3
|
|
assert(EC_POINT_get_affine_coordinates(curve, point, x, 0, 0) != 0);
|
|
#else
|
|
assert(EC_POINT_get_affine_coordinates_GFp(curve, point, x, 0, 0) != 0);
|
|
#endif
|
|
char* xx = BN_bn2dec(x);
|
|
Scalar res((bigint(xx)));
|
|
OPENSSL_free(xx);
|
|
BN_free(x);
|
|
return res;
|
|
}
|
|
|
|
P256Element P256Element::operator +(const P256Element& other) const
|
|
{
|
|
P256Element res;
|
|
assert(EC_POINT_add(curve, res.point, point, other.point, 0) != 0);
|
|
return res;
|
|
}
|
|
|
|
P256Element P256Element::operator -(const P256Element& other) const
|
|
{
|
|
P256Element tmp = other;
|
|
assert(EC_POINT_invert(curve, tmp.point, 0) != 0);
|
|
return *this + tmp;
|
|
}
|
|
|
|
P256Element P256Element::operator *(const Scalar& other) const
|
|
{
|
|
P256Element res;
|
|
BIGNUM* exp = BN_new();
|
|
BN_dec2bn(&exp, bigint(other).get_str().c_str());
|
|
assert(EC_POINT_mul(curve, res.point, 0, point, exp, 0) != 0);
|
|
BN_free(exp);
|
|
return res;
|
|
}
|
|
|
|
bool P256Element::operator ==(const P256Element& other) const
|
|
{
|
|
int cmp = EC_POINT_cmp(curve, point, other.point, 0);
|
|
assert(cmp == 0 or cmp == 1);
|
|
return not cmp;
|
|
}
|
|
|
|
void P256Element::pack(octetStream& os, int) const
|
|
{
|
|
octet* buffer;
|
|
size_t length = EC_POINT_point2buf(curve, point,
|
|
POINT_CONVERSION_COMPRESSED, &buffer, 0);
|
|
assert(length != 0);
|
|
os.store_int(length, 8);
|
|
os.append(buffer, length);
|
|
free(buffer);
|
|
}
|
|
|
|
void P256Element::unpack(octetStream& os, int)
|
|
{
|
|
size_t length = os.get_int(8);
|
|
assert(
|
|
EC_POINT_oct2point(curve, point, os.consume(length), length, 0)
|
|
!= 0);
|
|
}
|
|
|
|
ostream& operator <<(ostream& s, const P256Element& x)
|
|
{
|
|
char* hex = EC_POINT_point2hex(x.curve, x.point,
|
|
POINT_CONVERSION_COMPRESSED, 0);
|
|
s << hex;
|
|
OPENSSL_free(hex);
|
|
return s;
|
|
}
|
|
|
|
P256Element::P256Element(const P256Element& other) :
|
|
P256Element()
|
|
{
|
|
*this = other;
|
|
}
|
|
|
|
P256Element operator*(const P256Element::Scalar& x, const P256Element& y)
|
|
{
|
|
return y * x;
|
|
}
|
|
|
|
P256Element& P256Element::operator +=(const P256Element& other)
|
|
{
|
|
*this = *this + other;
|
|
return *this;
|
|
}
|
|
|
|
P256Element& P256Element::operator /=(const Scalar& other)
|
|
{
|
|
*this = *this * other.invert();
|
|
return *this;
|
|
}
|
|
|
|
bool P256Element::operator !=(const P256Element& other) const
|
|
{
|
|
return not (*this == other);
|
|
}
|
|
|
|
octetStream P256Element::hash(size_t n_bytes) const
|
|
{
|
|
octetStream os;
|
|
pack(os);
|
|
auto res = os.hash();
|
|
assert(n_bytes >= res.get_length());
|
|
res.resize_precise(n_bytes);
|
|
return res;
|
|
}
|