Shadowrun: Awakened 29 September 2011 - Build 871
BigRTL.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     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.

GNU Lesser General Public License 3 Sourceforge.net