BitCount() 공개 메소드

public BitCount ( ) : int
리턴 int
예제 #1
0
파일: DSA.cs 프로젝트: yiyi99/poderosa
 private static ulong AsUInt64(BigInteger num)
 {
     int bits = num.BitCount();
     if (bits >= 64)
         throw new ArgumentException("too large BigInteger value");
     byte[] data = num.GetBytes();
     ulong val = 0;
     foreach (byte b in data) {
         val = (val << 8) | b;
     }
     return val;
 }
예제 #2
0
파일: DSA.cs 프로젝트: yiyi99/poderosa
        private static BigInteger findRandomGenerator(BigInteger order, BigInteger modulo, Rng random)
        {
            BigInteger one = new BigInteger(1);
            BigInteger aux = modulo - new BigInteger(1);
            BigInteger t = aux % order;
            BigInteger generator;

            if (AsUInt64(t) != 0) {
                return null;
            }

            t = aux / order;

            while (true) {
                generator = BigInteger.GenerateRandom(modulo.BitCount());
                generator = generator % modulo;
                generator = generator.ModPow(t, modulo);
                if (generator != one)
                    break;
            }

            aux = generator.ModPow(order, modulo);

            if (aux != one) {
                return null;
            }

            return generator;
        }
예제 #3
0
 /// <summary>
 /// Point multiplication
 /// </summary>
 /// <param name="k">scalar value</param>
 /// <param name="p">point</param>
 /// <returns>result</returns>
 private Ed25519Point PointMul(BigInteger k, Ed25519Point p)
 {
     Ed25519Point mp = p;
     Ed25519Point q = new Ed25519Point(0, 1, 1, 0);  // Neutral element
     int kBitCount = k.BitCount();
     byte[] kBytes = k.GetBytes();
     int kOffset = kBytes.Length - 1;
     for (int i = 0; i < kBitCount; ++i) {
         if (i > 0) {
             mp = PointAdd(mp, mp);
         }
         if ((kBytes[kOffset - i / 8] & (byte)(1 << (i % 8))) != 0) {
             q = PointAdd(q, mp);
         }
     }
     return q;
 }
예제 #4
0
        /// <summary>
        /// Point multiplication over the curve
        /// </summary>
        private bool PointMul(
                BigInteger.ModulusRing ring,
                ECPoint p1,
                BigInteger k,
                out ECPoint p2) {

            //
            // Uses Width-w NAF method
            //

            if (p1 is ECPointAtInfinity) {
                p2 = p1;
                return true;
            }

            const int W = 6;
            const uint TPW = 1u << W;   // 2^W
            const uint TPWD = 1u << (W - 1);   // 2^(W-1)

            // precompute point multiplication : {1 .. 2^(W-1)-1}P.
            // array is allocated for {0 .. 2^(W-1)-1}P, and only elements at the odd index are used.
            ECPoint[] precomp = new ECPoint[TPWD];
            ECPoint[] precompNeg = new ECPoint[TPWD];   // -{1 .. 2^(W-1)-1}P; points are set on demand.

            {
                ECPoint t = p1;
                ECPoint t2;
                if (!PointDouble(ring, t, out t2)) {
                    goto Failure;
                }
                for (uint i = 1; i < TPWD; i += 2) {
                    if (i != 1) {
                        if (!PointAdd(ring, t, t2, out t)) {
                            goto Failure;
                        }
                    }
                    precomp[i] = t;
                }
            }

            Stack<sbyte> precompIndex;

            {
                byte[] d = k.GetBytes();
                int bitCount = k.BitCount();
                int bitIndex = 0;
                int byteOffset = d.Length - 1;
                bool noMoreBits = false;
                uint bitBuffer = 0;
                const uint WMASK = (1u << W) - 1;

                precompIndex = new Stack<sbyte>(bitCount + 1);

                if (bitIndex < bitCount) {
                    bitBuffer = (uint)(d[byteOffset] & WMASK);
                    bitIndex += W;
                }
                else {
                    noMoreBits = true;
                }

                while (!noMoreBits || bitBuffer != 0) {
                    if ((bitBuffer & 1) != 0) { // bits % 2 == 1
                        uint m = bitBuffer & WMASK; // m = bits % TPW;
                        if ((m & TPWD) != 0) {  // test m >= 2^(W-1)
                            // m is odd; thus
                            // (2^(W-1) + 1) <= m <= (2^W - 1)
                            sbyte index = (sbyte)((int)m - (int)TPW);  // -2^(W-1)+1 .. -1
                            precompIndex.Push(index);
                            bitBuffer = (bitBuffer & ~WMASK) + TPW; // bits -= m - 2^W
                            // a carried bit by adding 2^W is retained in the bit buffer
                        }
                        else {
                            // 1 <= m <= (2^(W-1) - 1)
                            sbyte index = (sbyte)m; // odd index
                            precompIndex.Push(index);
                            bitBuffer = (bitBuffer & ~WMASK); // bits -= m
                        }
                    }
                    else {
                        precompIndex.Push(0);
                    }

                    // shift bits
                    if (bitIndex < bitCount) {
                        // load next bit into the bit buffer (add to the carried bits in the bit buffer)
                        bitBuffer += (uint)((d[byteOffset - bitIndex / 8] >> (bitIndex % 8)) & 1) << W;
                        ++bitIndex;
                    }
                    else {
                        noMoreBits = true;
                    }
                    bitBuffer >>= 1;
                }
            }

            {
                ECPoint p = null;

                while (precompIndex.Count > 0) {
                    if (p != null) {
                        if (!PointDouble(ring, p, out p)) {
                            goto Failure;
                        }
                    }

                    ECPoint pre;
                    int index = precompIndex.Pop();
                    if (index > 0) {
                        pre = precomp[index];
                    }
                    else if (index < 0) {
                        pre = precompNeg[-index];
                        if (pre == null) {
                            // on EC over Fp, P={x, y} and -P={x, -y}
                            pre = precomp[-index];
                            if (!(pre is ECPointAtInfinity)) {
                                pre = new ECPoint(pre.X, ring.Difference(0, pre.Y));
                            }
                            precompNeg[-index] = pre;
                        }
                    }
                    else {
                        continue;
                    }

                    if (p != null) {
                        if (!PointAdd(ring, p, pre, out p)) {
                            goto Failure;
                        }
                    }
                    else {
                        p = pre;
                    }
                }

                if (p == null) {
                    // case of k = 0
                    goto Failure;
                }

                // succeeded
                p2 = p;
                return true;
            }

        Failure:
            p2 = null;
            return false;
        }
예제 #5
0
			private unsafe BigInteger OddModTwoPow (BigInteger exp)
			{

				uint [] wkspace = new uint [mod.length << 1 + 1];

				BigInteger resultNum = Montgomery.ToMont ((BigInteger)2, this.mod);
				resultNum = new BigInteger (resultNum, mod.length << 1 +1);

				uint mPrime = Montgomery.Inverse (mod.data [0]);

				//
				// TODO: eat small bits, the ones we can do with no modular reduction
				//
				uint pos = (uint)exp.BitCount () - 2;

				do {
					Kernel.SquarePositive (resultNum, ref wkspace);
					resultNum = Montgomery.Reduce (resultNum, mod, mPrime);

					if (exp.TestBit (pos)) {
						//
						// resultNum = (resultNum * 2) % mod
						//

						fixed (uint* u = resultNum.data) {
							//
							// Double
							//
							uint* uu = u;
							uint* uuE = u + resultNum.length;
							uint x, carry = 0;
							while (uu < uuE) {
								x = *uu;
								*uu = (x << 1) | carry;
								carry = x >> (32 - 1);
								uu++;
							}

							// subtraction inlined because we know it is square
							if (carry != 0 || resultNum >= mod) {
								fixed (uint* s = mod.data) {
									uu = u;
									uint c = 0;
									uint* ss = s;
									do {
										uint a = *ss++;
										if (((a += c) < c) | ((* (uu++) -= a) > ~a))
											c = 1;
										else
											c = 0;
									} while (uu < uuE);
								}
							}
						}
					}
				} while (pos-- > 0);

				resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;
			}
예제 #6
0
			private unsafe BigInteger EvenPow (uint b, BigInteger exp)
			{
				exp.Normalize ();
				uint [] wkspace = new uint [mod.length << 1 + 1];
				BigInteger resultNum = new BigInteger ((BigInteger)b, mod.length << 1 + 1);

				uint pos = (uint)exp.BitCount () - 2;

				//
				// We know that the first itr will make the val b
				//

				do {
					//
					// r = r ^ 2 % m
					//
					Kernel.SquarePositive (resultNum, ref wkspace);
					if (!(resultNum.length < mod.length))
						BarrettReduction (resultNum);

					if (exp.TestBit (pos)) {

						//
						// r = r * b % m
						//

						// TODO: Is Unsafe really speeding things up?
						fixed (uint* u = resultNum.data) {

							uint i = 0;
							ulong mc = 0;

							do {
								mc += (ulong)u [i] * (ulong)b;
								u [i] = (uint)mc;
								mc >>= 32;
							} while (++i < resultNum.length);

							if (resultNum.length < mod.length) {
								if (mc != 0) {
									u [i] = (uint)mc;
									resultNum.length++;
									while (resultNum >= mod)
										Kernel.MinusEq (resultNum, mod);
								}
							} else if (mc != 0) {

								//
								// First, we estimate the quotient by dividing
								// the first part of each of the numbers. Then
								// we correct this, if necessary, with a subtraction.
								//

								uint cc = (uint)mc;

								// We would rather have this estimate overshoot,
								// so we add one to the divisor
								uint divEstimate = (uint) ((((ulong)cc << 32) | (ulong) u [i -1]) /
									(mod.data [mod.length-1] + 1));

								uint t;

								i = 0;
								mc = 0;
								do {
									mc += (ulong)mod.data [i] * (ulong)divEstimate;
									t = u [i];
									u [i] -= (uint)mc;
									mc >>= 32;
									if (u [i] > t) mc++;
									i++;
								} while (i < resultNum.length);
								cc -= (uint)mc;

								if (cc != 0) {

									uint sc = 0, j = 0;
									uint [] s = mod.data;
									do {
										uint a = s [j];
										if (((a += sc) < sc) | ((u [j] -= a) > ~a)) sc = 1;
										else sc = 0;
										j++;
									} while (j < resultNum.length);
									cc -= sc;
								}
								while (resultNum >= mod)
									Kernel.MinusEq (resultNum, mod);
							} else {
								while (resultNum >= mod)
									Kernel.MinusEq (resultNum, mod);
							}
						}
					}
				} while (pos-- > 0);

				return resultNum;
			}
예제 #7
0
			private BigInteger OddPow (BigInteger b, BigInteger exp)
			{
				BigInteger resultNum = new BigInteger (Montgomery.ToMont (1, mod), mod.length << 1);
				BigInteger tempNum = new BigInteger (Montgomery.ToMont (b, mod), mod.length << 1);  // ensures (tempNum * tempNum) < b^ (2k)
				uint mPrime = Montgomery.Inverse (mod.data [0]);
				uint totalBits = (uint)exp.BitCount ();

				uint [] wkspace = new uint [mod.length << 1];

				// perform squaring and multiply exponentiation
				for (uint pos = 0; pos < totalBits; pos++) {
					if (exp.TestBit (pos)) {

						Array.Clear (wkspace, 0, wkspace.Length);
						Kernel.Multiply (resultNum.data, 0, resultNum.length, tempNum.data, 0, tempNum.length, wkspace, 0);
						resultNum.length += tempNum.length;
						uint [] t = wkspace;
						wkspace = resultNum.data;
						resultNum.data = t;

						Montgomery.Reduce (resultNum, mod, mPrime);
					}

					// the value of tempNum is required in the last loop
					if (pos < totalBits - 1) {
						Kernel.SquarePositive (tempNum, ref wkspace);
						Montgomery.Reduce (tempNum, mod, mPrime);
					}
				}

				Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;
			}
예제 #8
0
			public BigInteger EvenPow (BigInteger b, BigInteger exp)
			{
				BigInteger resultNum = new BigInteger ((BigInteger)1, mod.length << 1);
				BigInteger tempNum = new BigInteger (b % mod, mod.length << 1);  // ensures (tempNum * tempNum) < b^ (2k)

				uint totalBits = (uint)exp.BitCount ();

				uint [] wkspace = new uint [mod.length << 1];

				// perform squaring and multiply exponentiation
				for (uint pos = 0; pos < totalBits; pos++) {
					if (exp.TestBit (pos)) {

						Array.Clear (wkspace, 0, wkspace.Length);
						Kernel.Multiply (resultNum.data, 0, resultNum.length, tempNum.data, 0, tempNum.length, wkspace, 0);
						resultNum.length += tempNum.length;
						uint [] t = wkspace;
						wkspace = resultNum.data;
						resultNum.data = t;

						BarrettReduction (resultNum);
					}

					Kernel.SquarePositive (tempNum, ref wkspace);
					BarrettReduction (tempNum);

					if (tempNum == 1) {
						return resultNum;
					}
				}

				return resultNum;
			}
예제 #9
0
			public BigInteger Pow (BigInteger a, BigInteger k)
			{
				BigInteger b = new BigInteger (1);
				if (k == 0)
					return b;

				BigInteger A = a;
				if (k.TestBit (0))
					b = a;

				for (int i = 1; i < k.BitCount (); i++) {
					A = Multiply (A, A);
					if (k.TestBit (i))
						b = Multiply (A, b);
				}
				return b;
			}