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

Reworked add/dbl/madd to return void #157

void mixed_add for element_g2 #157

Reverted EC_INF define, updated addition and doubling function for g2 #157

Revert "Reverted EC_INF define, updated addition and doubling function for g2 #157"

This reverts commit 46824d3.

reverted g2 operations #157

rewrite for clarity #157

updates for blueprint compatibility #157

reworked operator+ #157
  • Loading branch information
vo-nil committed May 22, 2024
1 parent d7ab7c7 commit a0e078f
Show file tree
Hide file tree
Showing 62 changed files with 5,311 additions and 5,504 deletions.
57 changes: 27 additions & 30 deletions include/nil/crypto3/algebra/curves/detail/edwards/element_g2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ namespace nil {
}

constexpr element_edwards_g2 operator+(const element_edwards_g2 &other) const {
// handle special cases having to do with O
if (this->is_zero()) {
return other;
}
Expand All @@ -210,11 +209,15 @@ namespace nil {
return (*this);
}

element_edwards_g2 result = *this;

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

return this->add(other);
result.add(other);
return result;
}

constexpr element_edwards_g2& operator+=(const element_edwards_g2 &other) {
Expand All @@ -224,9 +227,9 @@ namespace nil {
} else if (other.is_zero()) {
// Do nothing.
} else if (*this == other) {
*this = this->doubled();
this->double_inplace();
} else {
*this = this->add(other);
this->add(other);
}
return *this;
}
Expand Down Expand Up @@ -262,11 +265,9 @@ namespace nil {
*
* @return doubled element from group G2
*/
constexpr element_edwards_g2 doubled() const {
constexpr void double_inplace() {

if (this->is_zero()) {
return (*this);
} else {
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,28 +278,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
}
}

/** @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 void 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;
}

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

// NOTE: does not handle O and pts of order 2,4
Expand All @@ -312,15 +313,13 @@ 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

return element_edwards_g2(X3, Y3, Z3);
X = (E + B) * H; // X3 = (E+B)*H
Y = (E - B) * I; // Y3 = (E-B)*I
Z = A * H * I; // Z3 = A*H*I
}

private:
constexpr element_edwards_g2 add(const element_edwards_g2 &other) const {
constexpr void add(const element_edwards_g2 &other) {
// NOTE: does not handle O and pts of order 2,4
// http://www.hyperelliptic.org/EFD/g1p/auto-twisted-inverted.html#addition-add-2008-bbjlp

Expand All @@ -332,11 +331,9 @@ namespace nil {
const underlying_field_value_type H = C - this->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

return element_edwards_g2(X3, Y3, Z3);
X = (E + B) * H; // X3 = (E+B)*H
Y = (E - B) * I; // Y3 = (E-B)*I
Z = A * H * I; // Z3 = A*H*I
}

public:
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 void process(ElementType &first,
const ElementType &second) {

using field_value_type = typename ElementType::field_type::value_type;
Expand All @@ -54,11 +54,10 @@ 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);
}
};

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

template<typename ElementType>
constexpr static inline ElementType process(const ElementType &first) {
constexpr static inline void 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
}
}
};
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,7 +215,6 @@ namespace nil {
}

constexpr curve_element operator+(const curve_element &other) const {
// handle special cases having to do with O
if (this->is_zero()) {
return other;
}
Expand All @@ -214,11 +223,15 @@ namespace nil {
return (*this);
}

curve_element result = *this;

if (*this == other) {
return this->doubled();
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 +241,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,46 +260,28 @@ 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 {
return common_doubling_processor::process(*this);
constexpr void double_inplace() {
common_doubling_processor::process(*this);
}

/** @brief
*
* “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 {

constexpr void mixed_add(const curve_element &other) {
// handle special cases having to do with O
if (this->is_zero()) {
return other;
return;
}

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

return mixed_addition_processor::process(*this, other);
mixed_addition_processor::process(*this, other);
}

friend std::ostream& operator<<(std::ostream& os, curve_element const& e)
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 void process(ElementType &first,
const ElementType &second) {

using field_value_type = typename ElementType::field_type::value_type;
Expand All @@ -57,11 +57,9 @@ 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

return ElementType(X3, Y3, Z3);
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
}
};

Expand Down
Loading

0 comments on commit a0e078f

Please sign in to comment.