![]() |
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 Several algorithms based on ideas from the "Handbook of Applied Cryptography" 00031 http://www.cacr.math.uwaterloo.ca/hac/ 00032 00033 Several algorithms based on ideas from the 00034 "Handbook of Elliptic and Hyperelliptic Curve Cryptography" 00035 http://www.hyperelliptic.org/HEHCC/ 00036 */ 00037 00038 #ifndef CAT_BIG_RTL_HPP 00039 #define CAT_BIG_RTL_HPP 00040 00041 #include <cat/math/Legs.hpp> 00042 00043 namespace cat { 00044 00045 00046 // Implements a register transfer language (RTL) for big integer arithmetic 00047 class BigRTL 00048 { 00049 static const int BIG_OVERHEAD = 7; // overhead for ModularInverse() 00050 int library_regs; 00051 00052 protected: 00053 int library_legs; 00054 Leg *library_memory; 00055 00056 protected: 00057 static Leg CAT_FASTCALL ShiftRight(int legs, const Leg *in, int shift, Leg *out); 00058 static Leg CAT_FASTCALL ShiftLeft(int legs, const Leg *in, int shift, Leg *out); 00059 00060 protected: 00061 static u8 CAT_FASTCALL Add(int legs, const Leg *in_a, const Leg *in_b, Leg *out); 00062 static u8 CAT_FASTCALL Add(int legs_a, const Leg *in_a, int legs_b, const Leg *in_b, Leg *out); // legs_b <= legs_a 00063 static u8 CAT_FASTCALL Subtract(int legs, const Leg *in_a, const Leg *in_b, Leg *out); 00064 00065 protected: 00066 static Leg CAT_FASTCALL MultiplyX(int legs, const Leg *in_a, Leg in_b, Leg *out); 00067 static Leg CAT_FASTCALL MultiplyXAdd(int legs, const Leg *in_a, Leg in_b, const Leg *in_c, Leg *out); 00068 static Leg CAT_FASTCALL DoubleAdd(int legs, const Leg *in_a, const Leg *in_b, Leg *out); 00069 00070 protected: 00071 static void CAT_FASTCALL DivideCore(int A_used, Leg A_overflow, Leg *A, int B_used, Leg *B, Leg *Q); // A = remainder 00072 00073 public: 00074 BigRTL(int regs, int bits); 00075 ~BigRTL(); 00076 00077 public: 00078 Leg * CAT_FASTCALL Get(int reg_index); 00079 CAT_INLINE int Legs() { return library_legs; } 00080 CAT_INLINE int RegBytes() { return library_legs * sizeof(Leg); } 00081 00082 public: 00083 // Save one single register to an endian-neutral byte array 00084 void CAT_FASTCALL Save(const Leg *in, void *out, int bytes); 00085 00086 // Load one single register from an endian-neutral byte array 00087 void CAT_FASTCALL Load(const void *in, int bytes, Leg *out); 00088 00089 bool CAT_FASTCALL LoadFromString(const char *in, int base, Leg *out); 00090 00091 public: 00092 void CAT_FASTCALL Copy(const Leg *in, Leg *out); 00093 void CAT_FASTCALL CopyX(Leg in, Leg *out); 00094 00095 public: 00096 int CAT_FASTCALL LegsUsed(const Leg *in); 00097 00098 public: 00099 bool CAT_FASTCALL Greater(const Leg *in_a, const Leg *in_b); 00100 bool CAT_FASTCALL GreaterX(const Leg *in, Leg x); 00101 bool CAT_FASTCALL Less(const Leg *in_a, const Leg *in_b); 00102 bool CAT_FASTCALL LessX(const Leg *in, Leg x); 00103 bool CAT_FASTCALL Equal(const Leg *in_a, const Leg *in_b); 00104 bool CAT_FASTCALL EqualX(const Leg *in, Leg x); 00105 bool CAT_FASTCALL IsZero(const Leg *in); 00106 00107 public: 00108 Leg CAT_FASTCALL ShiftLeft(const Leg *in, int shift, Leg *out); 00109 void CAT_FASTCALL MoveLegsRight(const Leg *in, int legs, Leg *out); 00110 00111 public: 00112 u8 CAT_FASTCALL Add(const Leg *in_a, const Leg *in_b, Leg *out); 00113 u8 CAT_FASTCALL AddX(Leg *inout, Leg x); 00114 u8 CAT_FASTCALL Subtract(const Leg *in_a, const Leg *in_b, Leg *out); 00115 u8 CAT_FASTCALL SubtractX(Leg *inout, Leg x); 00116 void CAT_FASTCALL Negate(const Leg *in, Leg *out); 00117 00118 public: 00119 u8 CAT_FASTCALL Double(const Leg *in, Leg *out); 00120 00121 public: 00122 // Eat all trailing least significant zeroes from the argument and return the number eatten 00123 int CAT_FASTCALL EatTrailingZeroes(Leg *inout); 00124 00125 public: 00126 Leg CAT_FASTCALL MultiplyX(const Leg *in_a, Leg in_b, Leg *out); // out = a[] * b 00127 Leg CAT_FASTCALL MultiplyXAdd(const Leg *in_a, Leg in_b, const Leg *in_c, Leg *out); // out = a[] * b + c[] 00128 Leg CAT_FASTCALL DoubleAdd(const Leg *in_a, const Leg *in_b, Leg *out); // out = a[] * 2 + b[] 00129 00130 public: 00131 void CAT_FASTCALL MultiplyLow(const Leg *in_a, const Leg *in_b, Leg *out); // out = a[] * b[], low half 00132 00133 public: 00134 // out[] gets the low part of the product, next reg gets high part 00135 // note: in_a != out, in_b != out 00136 void CAT_FASTCALL Multiply(const Leg *in_a, const Leg *in_b, Leg *out); // out+1:out = a[] * b[] 00137 void CAT_FASTCALL Square(const Leg *in, Leg *out); // out+1:out = in[] * in[] 00138 00139 public: 00140 Leg CAT_FASTCALL DivideX(const Leg *in_a, Leg in_b, Leg *out); // out = a[] / b, returns modulus 00141 Leg CAT_FASTCALL ModulusX(const Leg *in_a, Leg in_b); // returns a[] % b 00142 00143 public: 00144 bool CAT_FASTCALL Divide(const Leg *in_a, const Leg *in_b, Leg *out_q, Leg *out_r); 00145 00146 // Divide the product of two registers (a+1:a) by single register (b) 00147 // Resulting quotient is two registers (q+1:q) and remainder is one register (r) 00148 bool CAT_FASTCALL DivideProduct(const Leg *in_a, const Leg *in_b, Leg *out_q, Leg *out_r); 00149 00150 public: 00151 // r = a * b (mod m) 00152 void CAT_FASTCALL MulMod(const Leg *in_a, const Leg *in_b, const Leg *in_m, Leg *r); 00153 00154 public: 00155 void CAT_FASTCALL ModularInverse(const Leg *x, const Leg *modulus, Leg *inverse); 00156 00157 public: 00158 Leg CAT_FASTCALL MultiplicativeInverseX(Leg x); 00159 }; 00160 00161 00162 } // namespace cat 00163 00164 #endif // CAT_BIG_RTL_HPP
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.