| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /*
- 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
- Hisil–Wong–Carter–Dawson 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
|