![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
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.