Shadowrun: Awakened 29 September 2011 - Build 871
BigTwistedEdwards.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2009-2010 Christopher A. Taylor.  All rights reserved.
00003 
00004     Redistribution and use in source and binary forms, with or without
00005     modification, are permitted provided that the following conditions are met:
00006 
00007     * Redistributions of source code must retain the above copyright notice,
00008       this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice,
00010       this list of conditions and the following disclaimer in the documentation
00011       and/or other materials provided with the distribution.
00012     * Neither the name of LibCat nor the names of its contributors may be used
00013       to endorse or promote products derived from this software without
00014       specific prior written permission.
00015 
00016     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00020     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026     POSSIBILITY OF SUCH DAMAGE.
00027 */
00028 
00029 /*
00030     Addition and doubling formulas using Extended Twisted Edwards coordinates from
00031     Hisil–Wong–Carter–Dawson paper "Twisted Edwards Curves Revisited" (Asiacrypt 2008)
00032 
00033     w-MOF scalar multiplication from http://www.sdl.hitachi.co.jp/crypto/mof/index-e.html
00034 
00035     Scalar multiplication precomputation with "conjugate addition" inspired by
00036     Longa-Gebotys paper "Novel Precomputation Schemes for Elliptic Curve Cryptosystems" (2008)
00037 */
00038 
00039 /*
00040     Twisted Edwards E(p) Curve: a * x^2 + y^2 = 1 + d * x^2 * y^2, a = -1, p = 2^256 - c, c small
00041 
00042     Edwards coordinates: (X : Y : Z)
00043     Extended Edwards coordinates: (X : Y : T : Z), T = XY
00044     Edwards to Extended Edwards: (X : Y : Z) -> (XZ : YZ : XY : ZZ)
00045     Extended Edwards to Edwards: (X : Y : T : Z) -> (X : Y : Z)
00046 
00047     -(X : Y : T : Z) = (-X : Y : -T : Z)
00048 
00049     Additive Identity element: X = 0
00050 
00051     When Z = 1, a multiplication can be omitted
00052 
00053     Mixing operations for more speed:
00054         doubling, doubling -> E = 2E
00055         doubling, add      -> Ee = 2E, E = Ee + Ee
00056 */
00057 
00058 #ifndef CAT_BIG_TWISTED_EDWARDS_HPP
00059 #define CAT_BIG_TWISTED_EDWARDS_HPP
00060 
00061 #include <cat/math/BigPseudoMersenne.hpp>
00062 #include <cat/rand/IRandom.hpp>
00063 
00064 namespace cat {
00065 
00066 
00067 class BigTwistedEdwards : public BigPseudoMersenne
00068 {
00069     static const int POINT_REGS = 4;
00070     static const int XOFF = 0;
00071     int YOFF, TOFF, ZOFF, POINT_STRIDE;
00072 
00073     // Point multiplication default window
00074     static const int WINDOW_BITS = 6;
00075     static const int PRECOMP_POINTS = 1 << (WINDOW_BITS-1);
00076     static const int PRECOMP_NEG_OFFSET = PRECOMP_POINTS / 2;
00077 
00078     static const int TE_OVERHEAD = (1 + PRECOMP_POINTS) * POINT_REGS + 9 + POINT_REGS * 2;
00079     int te_regs;
00080 
00081     // Local workspace
00082     Leg *A, *B, *C, *D, *E, *F, *G, *H, *CurveQ, *Generator;
00083     Leg *TempPt;
00084 
00085 protected:
00086     Leg curve_d;
00087 
00088     // Simultaneous Add and Subtract for efficient precomputation (A +/- B) in 14M 1D 11a (versus 16M 2D 16a)
00089     void PtPrecompAddSub(const Leg *in_a, const Leg *in_b, Leg *sum, Leg *diff, int neg_offset);
00090 
00091 public:
00092     BigTwistedEdwards(int regs, int bits, int C, int D, const u8 *Q, const u8 *GenPt);
00093 
00094     int PtLegs() { return Legs() * POINT_REGS; }
00095 
00096     Leg GetCurveD() { return curve_d; }
00097     const Leg *GetCurveQ() { return CurveQ; }
00098     const Leg *GetGenerator() { return Generator; }
00099 
00100 public:
00101     // Unpack an Extended Projective point (X,Y,T,Z) from affine point (x,y)
00102     void PtUnpack(Leg *inout);
00103 
00104     // Set a point to the identity
00105     void PtIdentity(Leg *inout);
00106 
00107     // Check if the affine point (x,y) is the additive identity x=0
00108     bool IsAffineIdentity(const Leg *in);
00109 
00110 public:
00111     void PtCopy(const Leg *in, Leg *out);
00112 
00113     // Fill the X coordinate of the point with a random value
00114     void PtFillRandomX(IRandom *prng, Leg *out);
00115 
00116     // Generate a random point on the curve that is not part of a small subgroup
00117     void PtGenerate(IRandom *prng, Leg *out);
00118 
00119 public:
00120     // Solve for Y given the X point on a curve
00121     void PtSolveAffineY(Leg *inout);
00122 
00123     // Verify that the point (x,y) exists on the given curve
00124     bool PtValidAffine(const Leg *in);
00125 
00126 public:
00127     // out(x) = X/Z
00128     void SaveAffineX(const Leg *in, void *out_x);
00129 
00130     // out(x,y) = (X/Z,Y/Z)
00131     void SaveAffineXY(const Leg *in, void *out_x, void *out_y);
00132 
00133     // out(X,Y) = (X,Y) without attempting to convert to affine from projective
00134     void SaveProjectiveXY(const Leg *in, void *out_x, void *out_y);
00135 
00136     // out(X,Y,Z,T) = (in_x,in_y), returns false if the coordinates are invalid
00137     bool LoadVerifyAffineXY(const void *in_x, const void *in_y, Leg *out);
00138 
00139     // Compute affine coordinates for (X,Y), set Z=1, and compute T = xy
00140     void PtNormalize(const Leg *in, Leg *out);
00141 
00142 public:
00143     // Extended Twisted Edwards Negation Formula
00144     void PtNegate(const Leg *in, Leg *out);
00145 
00146     // Extended Twisted Edwards Unified Addition Formula (works when both inputs are the same) in 8M 1D 9a
00147     void PtEAdd(const Leg *in_a, const Leg *in_b, Leg *out);
00148     void PtAdd(const Leg *in_a, const Leg *in_b, Leg *out); // -1M, cannot be followed by PtAdd
00149 
00150     // Extended Twisted Edwards Unified Subtraction Formula (works when both inputs are the same) in 8M 1D 9a
00151     void PtESubtract(const Leg *in_a, const Leg *in_b, Leg *out);
00152     void PtSubtract(const Leg *in_a, const Leg *in_b, Leg *out); // -1M, cannot be followed by PtAdd
00153 
00154     // Extended Twisted Edwards Dedicated Doubling Formula in 4M 4S 5a
00155     void PtEDouble(const Leg *in, Leg *out);
00156     void PtDouble(const Leg *in, Leg *out); // -1M, cannot be followed by PtAdd
00157 
00158     // Extended Twisted Edwards Dedicated Doubling Formula Assuming Z=1, in 4M 3S 4a
00159     void PtEDoubleZ1(const Leg *in, Leg *out);
00160     void PtDoubleZ1(const Leg *in, Leg *out); // -1M, cannot be followed by PtAdd
00161 
00162 public:
00163     // Allocate a table for use with PtMultiplyPrecomp()
00164     // Free the table with Aligned::Delete()
00165     Leg *PtMultiplyPrecompAlloc(int w);
00166 
00167     // Precompute odd multiples of input point
00168     void PtMultiplyPrecomp(const Leg *in, int w, Leg *table);
00169 
00170 public:
00171     // Extended Twisted Edwards Scalar Multiplication k*p
00172     // Requires precomputation with PtMultiplyPrecomp()
00173     // CAN *NOT* BE followed by a Pt[E]Add()
00174     void PtMultiply(const Leg *in_precomp, int w, const Leg *in_k, u8 msb_k, Leg *out);
00175 
00176     // Extended Twisted Edwards Scalar Multiplication k*p
00177     // Uses default precomputation
00178     // CAN *NOT* BE followed by a Pt[E]Add()
00179     void PtMultiply(const Leg *in_p, const Leg *in_k, u8 msb_k, Leg *out);
00180 
00181     // A reference multiplier to verify that PtMultiply() is functionally the same
00182     void RefMul(const Leg *in_p, const Leg *in_k, u8 msb_k, Leg *out);
00183 
00184 public:
00185     // Extended Twisted Edwards Simultaneous Scalar Multiplication k*P + l*Q
00186     // Requires precomputation with PtMultiplyPrecomp()
00187     // CAN *NOT* BE followed by a Pt[E]Add()
00188     void PtSiMultiply(const Leg *precomp_p, const Leg *precomp_q, int w,
00189                       const Leg *in_k, u8 msb_k, const Leg *in_l, u8 msb_l, Leg *out);
00190 };
00191 
00192 
00193 } // namespace cat
00194 
00195 #endif // CAT_BIG_TWISTED_EDWARDS_HPP

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net