Skip to content

Commit

Permalink
Added inplace functions for += #157
Browse files Browse the repository at this point in the history
Added eq-operators for fields #157

Removed division operator

data[2] typo #157

Work on curve operations #157

Arithmetic errors fixed #157

Removed comments #157

Removed divisions from hash_to_curve #157

work in progress #157

Reworked dobule and add functions to inplace variants #157

Update for short weierstrass curves #157

Renamed functions to emphasise inplace operation #157

Added type traits and different implementations for curves that support mixed_add #157

twisted extended #157

Replace double with double_inplace for multiexp and wnaf #157

renamed typetrait, removed doubling and mixed_add from static tests #157

disable curves_static test, update on fields #157

Clear version conflict markers #157

work in progress

Good data for babyjubjub montgomery affine #157

Good data for jubjub montgomery affine #157

Fixed montgomery affine functions #157

remove space #157
  • Loading branch information
vo-nil committed May 17, 2024
1 parent e83514b commit e33676e
Show file tree
Hide file tree
Showing 62 changed files with 5,314 additions and 5,452 deletions.
37 changes: 21 additions & 16 deletions include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,14 @@ namespace nil {
* @return doubled element from group G2
*/
constexpr element_edwards_g2 doubled() const {
element_edwards_g2 result = *this;
result.doubled();
return result;
}

if (this->is_zero()) {
return (*this);
} else {
constexpr element_edwards_g2& doubled() {

if (!this->is_zero()) {
// NOTE: does not handle O and pts of order 2,4
// http://www.hyperelliptic.org/EFD/g1p/auto-twisted-inverted.html#doubling-dbl-2008-bbjlp

Expand All @@ -277,27 +281,28 @@ namespace nil {
const underlying_field_value_type D = A - U; // D = A-U
const underlying_field_value_type E =
(this->X + this->Y).squared() - A - B; // E = (X1+Y1)^2-A-B
const underlying_field_value_type X3 = C * D; // X3 = C*D
const underlying_field_value_type dZZ = mul_by_d(this->Z.squared());
const underlying_field_value_type Y3 = E * (C - dZZ - dZZ); // Y3 = E*(C-2*d*Z1^2)
const underlying_field_value_type Z3 = D * E; // Z3 = D*E

return element_edwards_g2(X3, Y3, Z3);
X = C * D; // X3 = C*D
Y = E * (C - dZZ - dZZ); // Y3 = E*(C-2*d*Z1^2)
Z = D * E; // Z3 = D*E
}
return *this;
}

/** @brief
*
* “Mixed addition” refers to the case Z2 known to be 1.
* @return addition of two elements from group G2
*/
constexpr element_edwards_g2 mixed_add(const element_edwards_g2 &other) const {
constexpr element_edwards_g2& mixed_add(const element_edwards_g2 &other) {

// handle special cases having to do with O
if (this->is_zero()) {
return other;
if (other.is_zero()) {
return *this;
}

if (other.is_zero()) {
if (this->is_zero()) {
*this = other;
return *this;
}

Expand All @@ -312,11 +317,11 @@ namespace nil {
const underlying_field_value_type H = C - mul_by_a(D); // H = C-a*D
const underlying_field_value_type I =
(this->X + this->Y) * (other.X + other.Y) - C - D; // I = (X1+Y1)*(X2+Y2)-C-D
const underlying_field_value_type X3 = (E + B) * H; // X3 = (E+B)*H
const underlying_field_value_type Y3 = (E - B) * I; // Y3 = (E-B)*I
const underlying_field_value_type Z3 = A * H * I; // Z3 = A*H*I
X = (E + B) * H; // X3 = (E+B)*H
Y = (E - B) * I; // Y3 = (E-B)*I
Z = A * H * I; // Z3 = A*H*I

return element_edwards_g2(X3, Y3, Z3);
return *this;
}

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace nil {
struct edwards_element_g1_inverted_add_2007_bl {

template<typename ElementType>
constexpr static inline ElementType process(const ElementType &first,
constexpr static inline ElementType& process(ElementType &first,
const ElementType &second) {

using field_value_type = typename ElementType::field_type::value_type;
Expand All @@ -54,11 +54,11 @@ namespace nil {
field_value_type H = C - D; // H = C-D
field_value_type I =
(first.X + first.Y) * (second.X + second.Y) - C - D; // I = (X1+Y1)*(X2+Y2)-C-D
field_value_type X3 = ElementType::params_type::c * (E + B) * H; // X3 = c*(E+B)*H
field_value_type Y3 = ElementType::params_type::c * (E - B) * I; // Y3 = c*(E-B)*I
field_value_type Z3 = A * H * I; // Z3 = A*H*I
first.X = ElementType::params_type::c * (E + B) * H; // X3 = c*(E+B)*H
first.Y = ElementType::params_type::c * (E - B) * I; // Y3 = c*(E-B)*I
first.Z = A * H * I; // Z3 = A*H*I

return ElementType(X3, Y3, Z3);
return first;
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,25 @@ namespace nil {
struct edwards_element_g1_inverted_dbl_2007_bl {

template<typename ElementType>
constexpr static inline ElementType process(const ElementType &first) {
constexpr static inline ElementType& process(ElementType &first) {

using field_value_type = typename ElementType::field_type::value_type;

if (first.is_zero()) {
return (first);
} else {
if (!first.is_zero()) {

field_value_type A = (first.X).squared(); // A = X1^2
field_value_type B = (first.Y).squared(); // B = Y1^2
field_value_type C = A + B; // C = A+B
field_value_type D = A - B; // D = A-B
field_value_type E = (first.X + first.Y).squared() - C; // E = (X1+Y1)^2-C
field_value_type X3 = C * D; // X3 = C*D
first.X = C * D; // X3 = C*D
field_value_type dZZ = ElementType::params_type::c * ElementType::params_type::c *
ElementType::params_type::d * first.Z.squared();
field_value_type Y3 = E * (C - dZZ - dZZ); // Y3 = E*(C-c*c*2*d*Z1^2)
field_value_type Z3 = ElementType::params_type::c * D * E; // Z3 = c*D*E

return ElementType(X3, Y3, Z3);
first.Y = E * (C - dZZ - dZZ); // Y3 = E*(C-c*c*2*d*Z1^2)
first.Z = ElementType::params_type::c * D * E; // Z3 = c*D*E
}

return first;
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,16 @@ namespace nil {
* @return true if element from group G1 lies on the elliptic curve
*/
constexpr bool is_well_formed() const {
assert(false && "Not implemented yet.");
if (this->is_zero()) {
return true;
} else {

const auto X2 = this->X.squared();
const auto Y2 = this->Y.squared();
const auto Z2 = this->Z.squared();

return (params_type::a * Z2*Y2 + Z2*X2 == X2*Y2 + params_type::d * Z2*Z2);
}
}

/************************* Reducing operations ***********************************/
Expand All @@ -182,7 +191,8 @@ namespace nil {
return result_type::zero();
}

return result_type(Z / X, Z / Y); // x=Z/X, y=Z/Y
// x=Z/X, y=Z/Y
return result_type(Z * X.inversed(), Z * Y.inversed());
}

/************************* Arithmetic operations ***********************************/
Expand All @@ -205,20 +215,24 @@ namespace nil {
}

constexpr curve_element operator+(const curve_element &other) const {
curve_element result = *this;
// handle special cases having to do with O
if (this->is_zero()) {
return other;
if (result.is_zero()) {
result = other;
return result;
}

if (other.is_zero()) {
return (*this);
return result;
}

if (*this == other) {
return this->doubled();
if (result == other) {
result.double_inplace();
return result;;
}

return common_addition_processor::process(*this, other);
common_addition_processor::process(result, other);
return result;
}

constexpr curve_element& operator+=(const curve_element &other) {
Expand All @@ -228,9 +242,9 @@ namespace nil {
} else if (other.is_zero()) {
// Do nothing.
} else if (*this == other) {
*this = this->doubled();
common_doubling_processor::process(*this);
} else {
*this = common_addition_processor::process(*this, other);
common_addition_processor::process(*this, other);
}
return *this;
}
Expand All @@ -247,26 +261,11 @@ namespace nil {
return (*this) += (-other);
}

template<typename Backend,
boost::multiprecision::expression_template_option ExpressionTemplates>
constexpr curve_element& operator*=(const boost::multiprecision::number<Backend, ExpressionTemplates> &right) {
(*this) = (*this) * right;
return *this;
}

template<typename FieldValueType>
typename std::enable_if<is_field<typename FieldValueType::field_type>::value &&
!is_extended_field<typename FieldValueType::field_type>::value,
curve_element>::type
operator*=(const FieldValueType &right) {
return (*this) *= right.data;
}

/** @brief
*
* @return doubled element from group G1
*/
constexpr curve_element doubled() const {
constexpr curve_element& double_inplace() {
return common_doubling_processor::process(*this);
}

Expand All @@ -275,7 +274,7 @@ namespace nil {
* “Mixed addition” refers to the case Z2 known to be 1.
* @return addition of two elements from group G1
*/
curve_element mixed_add(const curve_element &other) const {
curve_element& mixed_add(const curve_element &other) {

// handle special cases having to do with O
if (this->is_zero()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace nil {
struct edwards_element_g1_inverted_madd_2007_bl {

template<typename ElementType>
constexpr static inline ElementType process(const ElementType &first,
constexpr static inline ElementType& process(ElementType &first,
const ElementType &second) {

using field_value_type = typename ElementType::field_type::value_type;
Expand All @@ -57,11 +57,11 @@ namespace nil {
field_value_type H = C - D; // H = C-D
field_value_type I =
(first.X + first.Y) * (second.X + second.Y) - C - D; // I = (X1+Y1)*(X2+Y2)-C-D
field_value_type X3 = ElementType::params_type::c * (E + B) * H; // X3 = c*(E+B)*H
field_value_type Y3 = ElementType::params_type::c * (E - B) * I; // Y3 = c*(E-B)*I
field_value_type Z3 = A * H * I; // Z3 = A*H*I
first.X = ElementType::params_type::c * (E + B) * H; // X3 = c*(E+B)*H
first.Y = ElementType::params_type::c * (E - B) * I; // Y3 = c*(E-B)*I
first.Z = A * H * I; // Z3 = A*H*I

return ElementType(X3, Y3, Z3);
return first;
}
};

Expand Down
Loading

0 comments on commit e33676e

Please sign in to comment.