/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2017-2019 Telegram Systems LLP */ #pragma once #include #include #include "openssl/bignum.h" #include "openssl/residue.h" #include "ellcurve/Fp25519.h" namespace ellcurve { using namespace arith; class MontgomeryCurve { td::Ref ring; int A_short; // v^2 = u^2 + Au + 1 int Gu_short; // u(G) int a_short; // (A+2)/4 Residue A_; Residue Gu; Bignum P_; Bignum L; Bignum Order; Bignum cofactor; int cofactor_short; void init(); public: MontgomeryCurve(int _A, int _Gu, td::Ref _R) : ring(_R) , A_short(_A) , Gu_short(_Gu) , a_short((_A + 2) / 4) , A_(_A, _R) , Gu(_Gu, _R) , P_(_R->get_modulus()) , cofactor_short(0) { init(); } const Residue& get_gen_u() const { return Gu; } const Bignum& get_ell() const { return L; } const Bignum& get_order() const { return Order; } td::Ref get_base_ring() const { return ring; } const Bignum& get_p() const { return P_; } void set_order_cofactor(const Bignum& order, int cof); struct PointXZ { Residue X, Z; PointXZ(Residue x, Residue z) : X(x), Z(z) { x.same_ring(z); } PointXZ(td::Ref r) : X(r->one()), Z(r->zero()) { } explicit PointXZ(Residue u) : X(u), Z(u.ring_of().one()) { } explicit PointXZ(Residue y, bool) : X(y.ring_of().one() + y), Z(y.ring_of().one() - y) { } PointXZ(const PointXZ& P) : X(P.X), Z(P.Z) { } PointXZ& operator=(const PointXZ& P) { X = P.X; Z = P.Z; return *this; } Residue get_u() const { return X * inverse(Z); } Residue get_v(bool sign_v = false) const; bool is_infty() const { return Z.is_zero(); } Residue get_y() const { return (X - Z) * inverse(X + Z); } bool export_point_y(unsigned char buffer[32]) const; bool export_point_u(unsigned char buffer[32]) const; void zeroize() { X = Z = Z.ring_of().zero(); } }; PointXZ power_gen_xz(const Bignum& n) const; PointXZ power_xz(const Residue& u, const Bignum& n) const; PointXZ power_xz(const PointXZ& P, const Bignum& n) const; PointXZ add_xz(const PointXZ& P, const PointXZ& Q) const; PointXZ double_xz(const PointXZ& P) const; PointXZ import_point_u(const unsigned char point[32]) const; PointXZ import_point_y(const unsigned char point[32]) const; }; const MontgomeryCurve& Curve25519(); } // namespace ellcurve