Files
SLikeNet/DependentExtensions/cat/math/BigTwistedEdwards.hpp
2025-11-24 14:19:51 +05:30

196 lines
7.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Copyright (c) 2009-2010 Christopher A. Taylor. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of LibCat nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Addition and doubling formulas using Extended Twisted Edwards coordinates from
HisilWongCarterDawson paper "Twisted Edwards Curves Revisited" (Asiacrypt 2008)
w-MOF scalar multiplication from http://www.sdl.hitachi.co.jp/crypto/mof/index-e.html
Scalar multiplication precomputation with "conjugate addition" inspired by
Longa-Gebotys paper "Novel Precomputation Schemes for Elliptic Curve Cryptosystems" (2008)
*/
/*
Twisted Edwards E(p) Curve: a * x^2 + y^2 = 1 + d * x^2 * y^2, a = -1, p = 2^256 - c, c small
Edwards coordinates: (X : Y : Z)
Extended Edwards coordinates: (X : Y : T : Z), T = XY
Edwards to Extended Edwards: (X : Y : Z) -> (XZ : YZ : XY : ZZ)
Extended Edwards to Edwards: (X : Y : T : Z) -> (X : Y : Z)
-(X : Y : T : Z) = (-X : Y : -T : Z)
Additive Identity element: X = 0
When Z = 1, a multiplication can be omitted
Mixing operations for more speed:
doubling, doubling -> E = 2E
doubling, add -> Ee = 2E, E = Ee + Ee
*/
#ifndef CAT_BIG_TWISTED_EDWARDS_HPP
#define CAT_BIG_TWISTED_EDWARDS_HPP
#include <cat/math/BigPseudoMersenne.hpp>
#include <cat/rand/IRandom.hpp>
namespace cat {
class BigTwistedEdwards : public BigPseudoMersenne
{
static const int POINT_REGS = 4;
static const int XOFF = 0;
int YOFF, TOFF, ZOFF, POINT_STRIDE;
// Point multiplication default window
static const int WINDOW_BITS = 6;
static const int PRECOMP_POINTS = 1 << (WINDOW_BITS-1);
static const int PRECOMP_NEG_OFFSET = PRECOMP_POINTS / 2;
static const int TE_OVERHEAD = (1 + PRECOMP_POINTS) * POINT_REGS + 9 + POINT_REGS * 2;
int te_regs;
// Local workspace
Leg *A, *B, *C, *D, *E, *F, *G, *H, *CurveQ, *Generator;
Leg *TempPt;
protected:
Leg curve_d;
// Simultaneous Add and Subtract for efficient precomputation (A +/- B) in 14M 1D 11a (versus 16M 2D 16a)
void PtPrecompAddSub(const Leg *in_a, const Leg *in_b, Leg *sum, Leg *diff, int neg_offset);
public:
BigTwistedEdwards(int regs, int bits, int C, int D, const u8 *Q, const u8 *GenPt);
int PtLegs() { return Legs() * POINT_REGS; }
Leg GetCurveD() { return curve_d; }
const Leg *GetCurveQ() { return CurveQ; }
const Leg *GetGenerator() { return Generator; }
public:
// Unpack an Extended Projective point (X,Y,T,Z) from affine point (x,y)
void PtUnpack(Leg *inout);
// Set a point to the identity
void PtIdentity(Leg *inout);
// Check if the affine point (x,y) is the additive identity x=0
bool IsAffineIdentity(const Leg *in);
public:
void PtCopy(const Leg *in, Leg *out);
// Fill the X coordinate of the point with a random value
void PtFillRandomX(IRandom *prng, Leg *out);
// Generate a random point on the curve that is not part of a small subgroup
void PtGenerate(IRandom *prng, Leg *out);
public:
// Solve for Y given the X point on a curve
void PtSolveAffineY(Leg *inout);
// Verify that the point (x,y) exists on the given curve
bool PtValidAffine(const Leg *in);
public:
// out(x) = X/Z
void SaveAffineX(const Leg *in, void *out_x);
// out(x,y) = (X/Z,Y/Z)
void SaveAffineXY(const Leg *in, void *out_x, void *out_y);
// out(X,Y) = (X,Y) without attempting to convert to affine from projective
void SaveProjectiveXY(const Leg *in, void *out_x, void *out_y);
// out(X,Y,Z,T) = (in_x,in_y), returns false if the coordinates are invalid
bool LoadVerifyAffineXY(const void *in_x, const void *in_y, Leg *out);
// Compute affine coordinates for (X,Y), set Z=1, and compute T = xy
void PtNormalize(const Leg *in, Leg *out);
public:
// Extended Twisted Edwards Negation Formula
void PtNegate(const Leg *in, Leg *out);
// Extended Twisted Edwards Unified Addition Formula (works when both inputs are the same) in 8M 1D 9a
void PtEAdd(const Leg *in_a, const Leg *in_b, Leg *out);
void PtAdd(const Leg *in_a, const Leg *in_b, Leg *out); // -1M, cannot be followed by PtAdd
// Extended Twisted Edwards Unified Subtraction Formula (works when both inputs are the same) in 8M 1D 9a
void PtESubtract(const Leg *in_a, const Leg *in_b, Leg *out);
void PtSubtract(const Leg *in_a, const Leg *in_b, Leg *out); // -1M, cannot be followed by PtAdd
// Extended Twisted Edwards Dedicated Doubling Formula in 4M 4S 5a
void PtEDouble(const Leg *in, Leg *out);
void PtDouble(const Leg *in, Leg *out); // -1M, cannot be followed by PtAdd
// Extended Twisted Edwards Dedicated Doubling Formula Assuming Z=1, in 4M 3S 4a
void PtEDoubleZ1(const Leg *in, Leg *out);
void PtDoubleZ1(const Leg *in, Leg *out); // -1M, cannot be followed by PtAdd
public:
// Allocate a table for use with PtMultiplyPrecomp()
// Free the table with Aligned::Delete()
Leg *PtMultiplyPrecompAlloc(int w);
// Precompute odd multiples of input point
void PtMultiplyPrecomp(const Leg *in, int w, Leg *table);
public:
// Extended Twisted Edwards Scalar Multiplication k*p
// Requires precomputation with PtMultiplyPrecomp()
// CAN *NOT* BE followed by a Pt[E]Add()
void PtMultiply(const Leg *in_precomp, int w, const Leg *in_k, u8 msb_k, Leg *out);
// Extended Twisted Edwards Scalar Multiplication k*p
// Uses default precomputation
// CAN *NOT* BE followed by a Pt[E]Add()
void PtMultiply(const Leg *in_p, const Leg *in_k, u8 msb_k, Leg *out);
// A reference multiplier to verify that PtMultiply() is functionally the same
void RefMul(const Leg *in_p, const Leg *in_k, u8 msb_k, Leg *out);
public:
// Extended Twisted Edwards Simultaneous Scalar Multiplication k*P + l*Q
// Requires precomputation with PtMultiplyPrecomp()
// CAN *NOT* BE followed by a Pt[E]Add()
void PtSiMultiply(const Leg *precomp_p, const Leg *precomp_q, int w,
const Leg *in_k, u8 msb_k, const Leg *in_l, u8 msb_l, Leg *out);
};
} // namespace cat
#endif // CAT_BIG_TWISTED_EDWARDS_HPP