Esempio n. 1
0
        public FastECPoint Multiply(FastInteger b)
        {
            if (b.Sign == -1)
            {
                throw new FormatException("The multiplicator cannot be negative");
            }

            //b = b % Secp256k1.N;
            FastInteger exp      = (b * 3) ^ b;
            FastECPoint result   = FastECPoint.Infinity;
            FastECPoint affine   = this.Normalize();
            FastECPoint negative = affine.Negate();

            int         high = exp.BitsCount;
            FastInteger bit  = FastInteger.One << high;

            for (int i = high; --i >= 0; bit >>= 1)
            {
                result = result.Twice();
                if (!(exp & bit).IsZero)
                {
                    result = result.Add(!(b & bit).IsZero ? negative : affine);
                }
            }

            result = result.Normalize();
            return(result);
        }
Esempio n. 2
0
        public FastInteger ModPow(FastInteger power, FastInteger prime, Func <FastInteger, FastInteger> modPFunction)
        {
            FastInteger a = this;

            if (power.IsNegative)
            {
                a     = a.ModInverse(prime);
                power = -power;
            }
            int highestBitPosition = power.Digits * 31 - 1;

            while (highestBitPosition >= 0 && !power.GetBitAt(highestBitPosition))
            {
                highestBitPosition--;
            }
            FastInteger result = highestBitPosition < 0 ? One : a;

            for (int i = highestBitPosition; --i >= 0;)
            {
                result = modPFunction(result.Square());
                if (power.GetBitAt(i))
                {
                    result = modPFunction(result * a);
                }
            }
            var diff = result - prime;

            return(diff.IsNegative ? result : diff);
        }
Esempio n. 3
0
 private static void remodP(ref FastInteger x)
 {
     while (x >= Secp256k1.FP)
     {
         x -= Secp256k1.FP;
     }
     while (x < 0)
     {
         x += Secp256k1.FP;
     }
 }
Esempio n. 4
0
 private static FastInteger modP(FastInteger x)
 {
     while (true)
     {
         var high = x >> 256;
         if (high.IsZero)
         {
             return(x);
         }
         x = (x & LowMask) + high * 0x1000003D1;
     }
 }
Esempio n. 5
0
 public FastInteger ShanksSqrt(FastInteger p, Func <FastInteger, FastInteger> modPFunction)
 {
     if (this.ModPow((p - 1) >> 1, p, modPFunction) == (p - 1))
     {
         return(-1);
     }   //No Sqrt Exists
     if ((p.LowestByte & 3) == 3)
     {
         var result = this.ModPow((p + 1) >> 2, p, modPFunction);
         return(result);
     }
     throw new NotImplementedException("Not a special prime modulo.");
 }
Esempio n. 6
0
        /// <summary>
        /// return this / n modulo p.
        /// </summary>
        /// <param name="n"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        public FastInteger DivideModulo(FastInteger n, FastInteger p)
        {
            if (n.IsZero)
            {
                return(n);
            }
            if (p.IsZero)
            {
                return(p);
            }
            FastInteger a = this;   //x * a + u1 * b = n
            FastInteger c = 0;      //y * c + u2 * d = p
            FastInteger x = n;

            while (p.IsEven)
            {
                p >>= 1;
            }
            FastInteger y = p;

            while (x.IsEven)
            {
                x >>= 1;
                a   = a.IsEven ? a >> 1 : (a + p) >> 1;
            }
            while (!x.IsZero)
            {
                while (x.IsEven)
                {
                    x >>= 1;
                    a   = a.IsEven ? a >> 1 : (a + p) >> 1;
                }
                FastInteger diff = x - y;
                if (diff.IsNegative)
                {
                    y = x;
                    x = -diff;
                    FastInteger temp = a; a = c; c = temp;
                }
                else
                {
                    x = diff;
                }
                a -= c;
                if (a.IsNegative)
                {
                    a += p;
                }
            }
            return(c);
        }
Esempio n. 7
0
        public static byte[] ToByteArrayUnsigned(this FastInteger i, bool bigEndian)
        {
            byte[] bytes  = i.ToByteArray();
            int    length = bytes.Length;

            while (length > 1 && ((bytes[length - 1] == 0 && bytes[length - 2] < 128) || (bytes[length - 1] == 255 && bytes[length - 2] >= 128)))
            {
                length--;
            }
            Array.Resize(ref bytes, length);
            if (bigEndian)
            {
                Array.Reverse(bytes, 0, bytes.Length);
            }
            return(bytes);
        }
Esempio n. 8
0
        public static FastInteger operator +(FastInteger number1, FastInteger number2)
        {
            int digits1 = number1.Digits;
            int digits2 = number2.Digits;

            if (digits1 < digits2)
            {
                int         temp1 = digits1; digits1 = digits2; digits2 = temp1;
                FastInteger temp2 = number1; number1 = number2; number2 = temp2;
            }
            if (number2.IsZero)
            {
                return(number1);
            }
            int bitcount = 1 + Math.Max(number1.BitsCount, number2.BitsCount);

            int[] result = new int[(bitcount + 30) / 31];
            int   carry  = 0;

            for (int i = 0; i < digits2; i++)
            {
                carry    += (number1.bits[i] & LowMask) + (number2.bits[i] & LowMask);
                result[i] = carry & LowMask;
                carry     = (carry >> 31) & 1;
            }
            for (int i = digits2; i < digits1; i++)
            {
                carry    += (number1.bits[i] & LowMask) + number2.Extender;
                result[i] = carry & LowMask;
                carry     = (carry >> 31) & 1;
            }
            carry += (number1.IsNegative ? -1 : 0) + (number2.IsNegative ? -1 : 0);
            if (carry == -1)
            {
                result[digits1 - 1] |= -1 << 31;
            }
            if (digits1 < result.Length)
            {
                result[digits1] = carry;
            }
            return(new FastInteger(result));
        }
Esempio n. 9
0
 public static FastInteger operator ^(FastInteger x, FastInteger y)
 {
     if (x.Digits < y.Digits)
     {
         FastInteger temp = x; x = y; y = temp;
     }
     if (y.IsZero)
     {
         return(x);
     }
     int[] result = new int[x.Digits];
     for (int i = y.Digits; --i >= 0;)
     {
         result[i] = (x.bits[i] ^ y.bits[i]) & LowMask;
     }
     for (int i = y.Digits; i < x.Digits; i++)
     {
         result[i] = (x.bits[i] ^ y.Extender) & LowMask;
     }
     result[result.Length - 1] |= (x.Extender ^ y.Extender) << 31;
     return(new FastInteger(result));
 }
Esempio n. 10
0
 public FastECPoint(byte[] bytes, bool isCompressed)
 {
     this._x = bytes.Take(256 / 8).ToFastIntegerUnsigned(false);
     if (isCompressed)
     {
         var x2 = modP(this.X.Square());
         var x3 = modP(x2 * this.X);
         this._y = (x3 + 7).ShanksSqrt(Secp256k1.FP, modP);
         byte lowerY = this._y.LowestByte;
         if (lowerY != bytes[256 / 8])
         {
             this._y = Secp256k1.FP - this._y;
             lowerY  = this._y.LowestByte;
             if (lowerY != bytes[256 / 8])
             {
                 throw new InvalidOperationException("Compressed bytes verification byte failed.");
             }
         }
     }
     else
     {
         this._y = bytes.Skip(256 / 8).Take(256 / 8).ToFastIntegerUnsigned(false);
     }
 }
Esempio n. 11
0
        public override string ToString()
        {
            FastInteger x        = this;
            bool        negative = x.IsNegative;

            if (negative)
            {
                x = -x;
            }
            StringBuilder sb = new StringBuilder();

            int[] bits = new int[x.bits.Length];
            x.bits.CopyTo(bits, 0);

            do
            {
                long mod = 0;
                for (int i = bits.Length; --i >= 0;)
                {
                    mod     = (mod << 31) + bits[i];
                    bits[i] = (int)Math.DivRem(mod, 10L, out mod);
                }
                sb.Append((char)('0' + mod));
            } while (bits.Any(b => b != 0));
            if (negative)
            {
                sb.Append('-');
            }
            for (int i = 0, j = sb.Length - 1; i < j; i++, j--)
            {
                char c = sb[i];
                sb[i] = sb[j];
                sb[j] = c;
            }
            return(sb.ToString());
        }
Esempio n. 12
0
 public FastInteger ModInverse(FastInteger p)
 {
     return(One.DivideModulo(this, p));
 }
Esempio n. 13
0
        public static FastInteger ToFastInteger(this ulong[] bits)
        {
            FastInteger result = new FastInteger(bits.SelectMany(l => BitConverter.GetBytes(l)).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());

            return(result);
        }
Esempio n. 14
0
 public FastECPoint(FastInteger x, FastInteger y, bool isInfinity)
 {
     _x          = x;
     _y          = y;
     _isInfinity = isInfinity;
 }
Esempio n. 15
0
 public static FastInteger Abs(FastInteger number)
 {
     return(number.IsNegative ? -number : number);
 }
Esempio n. 16
0
        public static bool UnitTest()
        {
            Random random = new Random(1001);

            for (int i = 10000; --i >= 0;)
            {
                byte[] bytes1 = new byte[31 + random.Next(2)];
                byte[] bytes2 = new byte[31 + random.Next(2)];
                random.NextBytes(bytes1);
                random.NextBytes(bytes2);

                BigInteger  n1 = new BigInteger(bytes1);
                BigInteger  n2 = new BigInteger(bytes2);
                FastInteger f1 = new FastInteger(bytes1);
                FastInteger f2 = new FastInteger(bytes2);
                if (n1.ToString() != f1.ToString())
                {
                    System.Diagnostics.Debugger.Break();
                }
                if (n2.ToString() != f2.ToString())
                {
                    System.Diagnostics.Debugger.Break();
                }
                BigInteger  a1 = n1 + n2;
                FastInteger a2 = f1 + f2;
                if (a1.ToString() != a2.ToString())
                {
                    var by1 = a1.ToByteArray();
                    var by2 = a2.ToByteArray();
                    System.Diagnostics.Debugger.Break();
                }
                BigInteger  s1 = n1 - n2;
                FastInteger s2 = f1 - f2;
                if (s1.ToString() != s2.ToString())
                {
                    var by1 = s1.ToByteArray();
                    var by2 = s2.ToByteArray();
                    System.Diagnostics.Debugger.Break();
                }
                BigInteger  m1 = n1 * n2;
                FastInteger m2 = f1 * f2;
                if (m1.ToString() != m2.ToString())
                {
                    System.Diagnostics.Debugger.Break();
                }
                int         shrvalue = random.Next(256) + 1;
                BigInteger  sh1      = n1 >> shrvalue;
                FastInteger sh2      = f1 >> shrvalue;
                if (sh1.ToString() != sh2.ToString())
                {
                    System.Diagnostics.Debugger.Break();
                }
                if ((-f1).ToString() != (-n1).ToString() || (-f2).ToString() != (-n2).ToString())
                {
                    System.Diagnostics.Debugger.Break();
                }
                int         shlvalue = random.Next(256) + 1;
                BigInteger  shl1     = n1 << shlvalue;
                FastInteger shl2     = f1 << shlvalue;
                if (shl1.ToString() != shl2.ToString())
                {
                    System.Diagnostics.Debugger.Break();
                }
                BigInteger  and1 = n1 & n2;
                FastInteger and2 = f1 & f2;
                if (and1.ToString() != and2.ToString())
                {
                    System.Diagnostics.Debugger.Break();
                }
                BigInteger  xor1 = n1 ^ n2;
                FastInteger xor2 = f1 ^ f2;
                if (xor1.ToString() != xor2.ToString())
                {
                    System.Diagnostics.Debugger.Break();
                }
            }
            return(true);
        }
Esempio n. 17
0
 public static FastInteger Square(this FastInteger x)
 {
     return(x * x);
 }
Esempio n. 18
0
 public FastECPoint(FastInteger x, FastInteger y)
 {
     _x = x;
     _y = y;
 }
Esempio n. 19
0
 public FastECPoint(FastInteger x, FastInteger y, FastInteger z, bool isInfinity) : this(x, y, isInfinity)
 {
     _z = z;
 }
Esempio n. 20
0
 public static string FastIntegerToHex(FastInteger value)
 {
     return(BytesToHex(value.ToByteArrayUnsigned(true)));
 }
Esempio n. 21
0
 public static string ToHex(this FastInteger b)
 {
     return(Hex.FastIntegerToHex(b));
 }