/** * Return a random BigInteger not less than 'min' and not greater than 'max' * * @param min the least value that may be generated * @param max the greatest value that may be generated * @param random the source of randomness * @return a random BigInteger value in the range [min,max] */ public static BigInteger CreateRandomInRange( BigInteger min, BigInteger max, // TODO Should have been just Random class SecureRandom random) { int cmp = min.CompareTo(max); if (cmp >= 0) { if (cmp > 0) throw new ArgumentException("'min' may not be greater than 'max'"); return min; } if (min.BitLength > max.BitLength / 2) { return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min); } for (int i = 0; i < MaxIterations; ++i) { BigInteger x = new BigInteger(max.BitLength, random); if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0) { return x; } } // fall back to a faster (restricted) method return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min); }
public RsaSecretBcpgKey( BigInteger d, BigInteger p, BigInteger q) { // PGP requires (p < q) int cmp = p.CompareTo(q); if (cmp >= 0) { if (cmp == 0) throw new ArgumentException("p and q cannot be equal"); BigInteger tmp = p; p = q; q = tmp; } this.d = new MPInteger(d); this.p = new MPInteger(p); this.q = new MPInteger(q); this.u = new MPInteger(p.ModInverse(q)); this.expP = d.Remainder(p.Subtract(BigInteger.One)); this.expQ = d.Remainder(q.Subtract(BigInteger.One)); this.crt = q.ModInverse(p); }
/** * generate a signature for the given message using the key we were * initialised with. For conventional Gost3410 the message should be a Gost3411 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] GenerateSignature( byte[] message) { byte[] mRev = new byte[message.Length]; // conversion is little-endian for (int i = 0; i != mRev.Length; i++) { mRev[i] = message[mRev.Length - 1 - i]; } BigInteger m = new BigInteger(1, mRev); Gost3410Parameters parameters = key.Parameters; BigInteger k; do { k = new BigInteger(parameters.Q.BitLength, random); } while (k.CompareTo(parameters.Q) >= 0); BigInteger r = parameters.A.ModPow(k, parameters.P).Mod(parameters.Q); BigInteger s = k.Multiply(m). Add(((Gost3410PrivateKeyParameters)key).X.Multiply(r)). Mod(parameters.Q); return new BigInteger[]{ r, s }; }
public AsymmetricCipherKeyPair GenerateKeyPair() { SecureRandom random = param.Random; Gost3410Parameters gost3410Params = param.Parameters; BigInteger q = gost3410Params.Q; BigInteger x; do { x = new BigInteger(256, random); } while (x.Sign < 1 || x.CompareTo(q) >= 0); BigInteger p = gost3410Params.P; BigInteger a = gost3410Params.A; // calculate the public key. BigInteger y = a.ModPow(x, p); if (param.PublicKeyParamSet != null) { return new AsymmetricCipherKeyPair( new Gost3410PublicKeyParameters(y, param.PublicKeyParamSet), new Gost3410PrivateKeyParameters(x, param.PublicKeyParamSet)); } return new AsymmetricCipherKeyPair( new Gost3410PublicKeyParameters(y, gost3410Params), new Gost3410PrivateKeyParameters(x, gost3410Params)); }
public SecP384R1FieldElement(BigInteger x) { if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) throw new ArgumentException("value invalid for SecP384R1FieldElement", "x"); this.x = SecP384R1Field.FromBigInteger(x); }
public Gost3410PublicKeyParameters( BigInteger y, DerObjectIdentifier publicKeyParamSet) : base(false, publicKeyParamSet) { if (y.Sign < 1 || y.CompareTo(Parameters.P) >= 0) throw new ArgumentException("Invalid y for GOST3410 public key", "y"); this.y = y; }
public FpFieldElement( BigInteger q, BigInteger x) { if (x.CompareTo(q) >= 0) throw new ArgumentException("x value too large in field element"); this.q = q; this.x = x; }
public Gost3410PrivateKeyParameters( BigInteger x, DerObjectIdentifier publicKeyParamSet) : base(true, publicKeyParamSet) { if (x.Sign < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0) throw new ArgumentException("Invalid x for GOST3410 private key", "x"); this.x = x; }
public DHParameters( BigInteger p, BigInteger g, BigInteger q, int m, int l, BigInteger j, DHValidationParameters validation) { if (p == null) throw new ArgumentNullException("p"); if (g == null) throw new ArgumentNullException("g"); if (!p.TestBit(0)) throw new ArgumentException("field must be an odd prime", "p"); if (g.CompareTo(BigInteger.Two) < 0 || g.CompareTo(p.Subtract(BigInteger.Two)) > 0) throw new ArgumentException("generator must in the range [2, p - 2]", "g"); if (q != null && q.BitLength >= p.BitLength) throw new ArgumentException("q too big to be a factor of (p-1)", "q"); if (m >= p.BitLength) throw new ArgumentException("m value must be < bitlength of p", "m"); if (l != 0) { if (l >= p.BitLength) throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l"); if (l < m) throw new ArgumentException("when l value specified, it may not be less than m value", "l"); } if (j != null && j.CompareTo(BigInteger.Two) < 0) throw new ArgumentException("subgroup factor must be >= 2", "j"); // TODO If q, j both provided, validate p = jq + 1 ? this.p = p; this.g = g; this.q = q; this.m = m; this.l = l; this.j = j; this.validation = validation; }
public override Number Calculate(BigInteger bigint1, BigInteger bigint2) { if (bigint1 == null || bigint2 == null) { return 0; } var comp = bigint2.CompareTo(BigInteger.Zero); if (comp == 0) { return 0; } if (comp < 0) { return bigint1.Negate().Mod(bigint2).Negate(); } return bigint1.Mod(bigint2); }
// 5.3 pg 28 /** * Generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] GenerateSignature( byte[] message) { BigInteger n = key.Parameters.N; BigInteger e = calculateE(n, message); BigInteger r = null; BigInteger s = null; // 5.3.2 do // Generate s { BigInteger k = null; do // Generate r { do { k = new BigInteger(n.BitLength, random); } while (k.Sign == 0 || k.CompareTo(n) >= 0); ECPoint p = key.Parameters.G.Multiply(k); // 5.3.3 BigInteger x = p.X.ToBigInteger(); r = x.Mod(n); } while (r.Sign == 0); BigInteger d = ((ECPrivateKeyParameters)key).D; s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n); } while (s.Sign == 0); return new BigInteger[]{ r, s }; }
/** * Generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] GenerateSignature( byte[] message) { DsaParameters parameters = key.Parameters; BigInteger q = parameters.Q; BigInteger m = calculateE(q, message); BigInteger k; do { k = new BigInteger(q.BitLength, random); } while (k.CompareTo(q) >= 0); BigInteger r = parameters.G.ModPow(k, parameters.P).Mod(q); k = k.ModInverse(q).Multiply( m.Add(((DsaPrivateKeyParameters)key).X.Multiply(r))); BigInteger s = k.Mod(q); return new BigInteger[]{ r, s }; }
/// <summary> /// Proving algorithm as specified in section 2.6.2 of the setup /// </summary> /// <param name="privKey">The secret key</param> /// <param name="setup">The setup parameters</param> /// <returns>List of signatures</returns> public static PermutationTestProof ProvePermutationTest(this RsaPrivateCrtKeyParameters privKey, PermutationTestSetup setup) { if (privKey == null) { throw new ArgumentNullException(nameof(privKey)); } if (setup == null) { throw new ArgumentNullException(nameof(setup)); } BigInteger p = privKey.P; BigInteger q = privKey.Q; BigInteger e = privKey.PublicExponent; BigInteger Modulus = privKey.Modulus; var keyLength = Modulus.BitLength; var alpha = setup.Alpha; BigInteger Two = BigInteger.Two; // 2^{|N| - 1} BigInteger lowerLimit = Two.Pow(keyLength - 1); // 2^{|N|} BigInteger upperLimit = Two.Pow(keyLength); // if N < 2^{KeySize-1} if (Modulus.CompareTo(lowerLimit) < 0) { throw new ArgumentOutOfRangeException("RSA modulus smaller than expected"); } // if N >= 2^{KeySize} if (Modulus.CompareTo(upperLimit) >= 0) { throw new ArgumentOutOfRangeException("RSA modulus larger than expected"); } // Verify alpha and N if (!CheckAlphaN(alpha, Modulus)) { throw new ArgumentException("RSA modulus has a small prime factor"); } var psBytes = setup.PublicString; var k = setup.SecurityParameter; byte[][] sigs; // Generate m1 and m2 Get_m1_m2((decimal)alpha, e.IntValue, k, out int m1, out int m2); // Calculate eN var eN = Modulus.Multiply(e); // Generate a pair (pub, sec) of keys with eN as e. var keyPrimePair = Utils.GeneratePrivate(p, q, eN); // Extract public key (N, e) from private key. var pubKey = privKey.ToPublicKey(); // Generate list of rho values GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues); // Signing the Rho values sigs = new byte[m2][]; for (int i = 0; i < m2; i++) { if (i <= m1) { sigs[i] = ((RsaPrivateCrtKeyParameters)keyPrimePair.Private).Decrypt(rhoValues[i]); } else { sigs[i] = privKey.Decrypt(rhoValues[i]); } } return(new PermutationTestProof(sigs)); }
/** * Procedure C * procedure generates the a value from the given p,q, * returning the a value. */ private BigInteger procedure_C(BigInteger p, BigInteger q) { BigInteger pSub1 = p.Subtract(BigInteger.One); BigInteger pSub1Divq = pSub1.Divide(q); for(;;) { BigInteger d = new BigInteger(p.BitLength, init_random); // 1 < d < p-1 if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0) { BigInteger a = d.ModPow(pSub1Divq, p); if (a.CompareTo(BigInteger.One) != 0) { return a; } } } }
/** * which Generates the p and g values from the given parameters, * returning the DsaParameters object. * <p> * Note: can take a while...</p> */ public DsaParameters GenerateParameters() { byte[] seed = new byte[20]; byte[] part1 = new byte[20]; byte[] part2 = new byte[20]; byte[] u = new byte[20]; Sha1Digest sha1 = new Sha1Digest(); int n = (size - 1) / 160; byte[] w = new byte[size / 8]; BigInteger q = null, p = null, g = null; int counter = 0; bool primesFound = false; while (!primesFound) { do { random.NextBytes(seed); sha1.BlockUpdate(seed, 0, seed.Length); sha1.DoFinal(part1, 0); Array.Copy(seed, 0, part2, 0, seed.Length); Add(part2, seed, 1); sha1.BlockUpdate(part2, 0, part2.Length); sha1.DoFinal(part2, 0); for (int i = 0; i != u.Length; i++) { u[i] = (byte)(part1[i] ^ part2[i]); } u[0] |= (byte)0x80; u[19] |= (byte)0x01; q = new BigInteger(1, u); }while (!q.IsProbablePrime(certainty)); counter = 0; int offset = 2; while (counter < 4096) { for (int k = 0; k < n; k++) { Add(part1, seed, offset + k); sha1.BlockUpdate(part1, 0, part1.Length); sha1.DoFinal(part1, 0); Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length); } Add(part1, seed, offset + n); sha1.BlockUpdate(part1, 0, part1.Length); sha1.DoFinal(part1, 0); Array.Copy(part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length); w[0] |= (byte)0x80; BigInteger x = new BigInteger(1, w); BigInteger c = x.Mod(q.ShiftLeft(1)); p = x.Subtract(c.Subtract(BigInteger.One)); if (p.TestBit(size - 1)) { if (p.IsProbablePrime(certainty)) { primesFound = true; break; } } counter += 1; offset += n + 1; } } // // calculate the generator g // BigInteger pMinusOneOverQ = p.Subtract(BigInteger.One).Divide(q); for (;;) { BigInteger h = new BigInteger(size, random); if (h.CompareTo(BigInteger.One) <= 0 || h.CompareTo(p.Subtract(BigInteger.One)) >= 0) { continue; } g = h.ModPow(pMinusOneOverQ, p); if (g.CompareTo(BigInteger.One) <= 0) { continue; } break; } return(new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter))); }
public static int Compare(BigInteger x, BigInteger y) { return x.CompareTo(y); }
private static void VerifyComparison(BigInteger x, bool IsXNegative, BigInteger y, bool IsYNegative, int expectedResult) { bool expectedEquals = 0 == expectedResult; bool expectedLessThan = expectedResult < 0; bool expectedGreaterThan = expectedResult > 0; if (IsXNegative == true) { x = x * -1; } if (IsYNegative == true) { y = y * -1; } Assert.Equal(expectedEquals, x == y); Assert.Equal(expectedEquals, y == x); Assert.Equal(!expectedEquals, x != y); Assert.Equal(!expectedEquals, y != x); Assert.Equal(expectedEquals, x.Equals(y)); Assert.Equal(expectedEquals, y.Equals(x)); Assert.Equal(expectedEquals, x.Equals((Object)y)); Assert.Equal(expectedEquals, y.Equals((Object)x)); VerifyCompareResult(expectedResult, x.CompareTo(y), "x.CompareTo(y)"); VerifyCompareResult(-expectedResult, y.CompareTo(x), "y.CompareTo(x)"); if (expectedEquals) { Assert.Equal(x.GetHashCode(), y.GetHashCode()); Assert.Equal(x.ToString(), y.ToString()); } Assert.Equal(x.GetHashCode(), x.GetHashCode()); Assert.Equal(y.GetHashCode(), y.GetHashCode()); Assert.Equal(expectedLessThan, x < y); Assert.Equal(expectedGreaterThan, y < x); Assert.Equal(expectedGreaterThan, x > y); Assert.Equal(expectedLessThan, y > x); Assert.Equal(expectedLessThan || expectedEquals, x <= y); Assert.Equal(expectedGreaterThan || expectedEquals, y <= x); Assert.Equal(expectedGreaterThan || expectedEquals, x >= y); Assert.Equal(expectedLessThan || expectedEquals, y >= x); }
/// <summary> /// Extract the truncated square root of a BigInteger /// </summary> /// /// <param name="X">A value out of which we extract the square root</param> /// /// <returns>Returns the truncated square root of <c>a</c></returns> public static BigInteger SquareRoot(BigInteger X) { int bl; BigInteger result, remainder, b; if (X.CompareTo(ZERO) < 0) throw new ArithmeticException("Cannot extract root of negative number" + X + "!"); bl = X.BitLength; result = ZERO; remainder = ZERO; // if the bit length is odd then extra step if ((bl & 1) != 0) { result = result.Add(ONE); bl--; } while (bl > 0) { remainder = remainder.Multiply(FOUR); remainder = remainder.Add(BigInteger.ValueOf((X.TestBit(--bl) ? 2 : 0) + (X.TestBit(--bl) ? 1 : 0))); b = result.Multiply(FOUR).Add(ONE); result = result.Multiply(TWO); if (remainder.CompareTo(b) != -1) { result = result.Add(ONE); remainder = remainder.Subtract(b); } } return result; }
//проверка простоты методом Миллера — Рабина public static bool checkSimplicity(BigInteger n, KeyAmount keyAmount) { int k = (int)keyAmount; //размерность ключа //исключаем числа делимые на простые числа от 2 до 256 либо к int[] simpleNumberForCheck = getSimplicityNumbers(k <= 256 ? 256 : k); for (int i = 0; i < simpleNumberForCheck.Length; i++) { BigInteger remainder; BigInteger.DivRem(n, new BigInteger(simpleNumberForCheck[i]), out remainder); if (remainder.IsZero || n.CompareTo(new BigInteger(simpleNumberForCheck[i])) == 0) { return(false); } } Random rnd = new Random(); int s = 0; BigInteger nmm = BigInteger.Subtract(n, BigInteger.One); BigInteger t = nmm; //вычисляем коэффициенты t и s do { t = BigInteger.Divide(t, new BigInteger(2)); s++; BigInteger remainder; BigInteger.DivRem(t, new BigInteger(2), out remainder); if (remainder != 0) { break; } } while (true); //проверяем условия простоты int kk = 30720 / k; for (int i = 0; i < kk; i++) { BigInteger a; for (;;) { a = rnd.NextBigInteger(n); if (nmm.CompareTo(a) > 0 && a.CompareTo(new BigInteger(2)) >= 0) { break; } } //проверяем сравнимость по модулю BigInteger x = BigInteger.ModPow(a, t, n); if (x.IsOne || x.CompareTo(nmm) == 0) { continue; } for (int j = 1; j < s; j++) { x = BigInteger.ModPow(x, new BigInteger(2), n); if (x.IsOne) { return(false); //составное } if (x.CompareTo(nmm) == 0) { goto ff; //перейти на следующую проверку } } return(false); //составное ff :; } return(true); }
// Stratis kernel protocol // coinstake must meet hash target according to the protocol: // kernel (input 0) must meet the formula // hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight // this ensures that the chance of getting a coinstake is proportional to the // amount of coins one owns. // The reason this hash is chosen is the following: // nStakeModifier: scrambles computation to make it very difficult to precompute // future proof-of-stake // txPrev.block.nTime: prevent nodes from guessing a good timestamp to // generate transaction for future advantage, // obsolete since v3 // txPrev.nTime: slightly scrambles computation // txPrev.vout.hash: hash of txPrev, to reduce the chance of nodes // generating coinstake at the same time // txPrev.vout.n: output number of txPrev, to reduce the chance of nodes // generating coinstake at the same time // nTime: current timestamp // block/tx hash should not be used here as they can be generated in vast // quantities so as to generate blocks faster, degrading the system back into // a proof-of-work situation. // private void CheckStakeKernelHashV2(ContextInformation context, ChainedBlock pindexPrev, uint nBits, uint nTimeBlockFrom, BlockStake prevBlockStake, UnspentOutputs txPrev, OutPoint prevout, uint nTimeTx) { if (nTimeTx < txPrev.Time) { ConsensusErrors.StakeTimeViolation.Throw(); } // Base target var bnTarget = new Target(nBits).ToBigInteger(); // TODO: Investigate: // The POS protocol should probably put a limit on the max amount that can be staked // not a hard limit but a limit that allow any amount to be staked with a max weight value. // the max weight should not exceed the max uint256 array size (array siez = 32) // Weighted target var nValueIn = txPrev._Outputs[prevout.N].Value.Satoshi; var bnWeight = BigInteger.ValueOf(nValueIn); bnTarget = bnTarget.Multiply(bnWeight); context.Stake.TargetProofOfStake = ToUInt256(bnTarget); var nStakeModifier = prevBlockStake.StakeModifier; //pindexPrev.Header.BlockStake.StakeModifier; uint256 bnStakeModifierV2 = prevBlockStake.StakeModifierV2; //pindexPrev.Header.BlockStake.StakeModifierV2; int nStakeModifierHeight = pindexPrev.Height; var nStakeModifierTime = pindexPrev.Header.Time; // Calculate hash using (var ms = new MemoryStream()) { var serializer = new BitcoinStream(ms, true); if (IsProtocolV3((int)nTimeTx)) { serializer.ReadWrite(bnStakeModifierV2); } else { serializer.ReadWrite(nStakeModifier); serializer.ReadWrite(nTimeBlockFrom); } serializer.ReadWrite(txPrev.Time); serializer.ReadWrite(prevout.Hash); serializer.ReadWrite(prevout.N); serializer.ReadWrite(nTimeTx); context.Stake.HashProofOfStake = Hashes.Hash256(ms.ToArray()); } //LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n", // nStakeModifier, nStakeModifierHeight, // DateTimeStrFormat(nStakeModifierTime), // DateTimeStrFormat(nTimeBlockFrom)); //LogPrintf("CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", // nStakeModifier, // nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx, // hashProofOfStake.ToString()); // Now check if proof-of-stake hash meets target protocol var hashProofOfStakeTarget = new BigInteger(1, context.Stake.HashProofOfStake.ToBytes(false)); if (hashProofOfStakeTarget.CompareTo(bnTarget) > 0) { ConsensusErrors.StakeHashInvalidTarget.Throw(); } // if (fDebug && !fPrintProofOfStake) // { // LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n", // nStakeModifier, nStakeModifierHeight, // DateTimeStrFormat(nStakeModifierTime), // DateTimeStrFormat(nTimeBlockFrom)); // LogPrintf("CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", // nStakeModifier, // nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx, // hashProofOfStake.ToString()); // } }
/** * Process a single block using the basic ElGamal algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param length the length of the data to be processed. * @return the result of the ElGamal process. * @exception DataLengthException the input block is too large. */ public byte[] ProcessBlock( byte[] input, int inOff, int length) { if (key == null) { throw new InvalidOperationException("ElGamal engine not initialised"); } int maxLength = forEncryption ? (bitSize - 1 + 7) / 8 : GetInputBlockSize(); if (length > maxLength) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } BigInteger p = key.Parameters.P; byte[] output; if (key is ElGamalPrivateKeyParameters) // decryption { int halfLength = length / 2; BigInteger gamma = new BigInteger(1, input, inOff, halfLength); BigInteger phi = new BigInteger(1, input, inOff + halfLength, halfLength); ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)key; // a shortcut, which generally relies on p being prime amongst other things. // if a problem with this shows up, check the p and g values! BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p); output = m.ToByteArrayUnsigned(); } else // encryption { BigInteger tmp = new BigInteger(1, input, inOff, length); if (tmp.BitLength >= p.BitLength) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)key; BigInteger pSub2 = p.Subtract(BigInteger.Two); // TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated BigInteger k; do { k = new BigInteger(p.BitLength, random); }while (k.SignValue == 0 || k.CompareTo(pSub2) > 0); BigInteger g = key.Parameters.G; BigInteger gamma = g.ModPow(k, p); BigInteger phi = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p); output = new byte[this.GetOutputBlockSize()]; // TODO Add methods to allow writing BigInteger to existing byte array? byte[] out1 = gamma.ToByteArrayUnsigned(); byte[] out2 = phi.ToByteArrayUnsigned(); out1.CopyTo(output, output.Length / 2 - out1.Length); out2.CopyTo(output, output.Length - out2.Length); } return(output); }
public static int Compare(BigInteger x, BigInteger y) { return(x.CompareTo(y)); }
/** * FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test * * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. This is an * alternative to {@link #isMRProbablePrime(BigInteger, SecureRandom, int)} that provides more * information about a composite candidate, which may be useful when generating or validating * RSA moduli. * * @param candidate * the {@link BigInteger} instance to test for primality. * @param random * the source of randomness to use to choose bases. * @param iterations * the number of randomly-chosen bases to perform the test for. * @return an {@link MROutput} instance that can be further queried for details. */ public static MROutput EnhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations) { CheckCandidate(candidate, "candidate"); if (random == null) { throw new ArgumentNullException("random"); } if (iterations < 1) { throw new ArgumentException("must be > 0", "iterations"); } if (candidate.BitLength == 2) { return(MROutput.ProbablyPrime()); } if (!candidate.TestBit(0)) { return(MROutput.ProvablyCompositeWithFactor(Two)); } BigInteger w = candidate; BigInteger wSubOne = candidate.Subtract(One); BigInteger wSubTwo = candidate.Subtract(Two); int a = wSubOne.GetLowestSetBit(); BigInteger m = wSubOne.ShiftRight(a); for (int i = 0; i < iterations; ++i) { BigInteger b = BigIntegers.CreateRandomInRange(Two, wSubTwo, random); BigInteger g = b.Gcd(w); if (g.CompareTo(One) > 0) { return(MROutput.ProvablyCompositeWithFactor(g)); } BigInteger z = b.ModPow(m, w); if (z.Equals(One) || z.Equals(wSubOne)) { continue; } bool primeToBase = false; BigInteger x = z; for (int j = 1; j < a; ++j) { z = z.ModPow(Two, w); if (z.Equals(wSubOne)) { primeToBase = true; break; } if (z.Equals(One)) { break; } x = z; } if (!primeToBase) { if (!z.Equals(One)) { x = z; z = z.ModPow(Two, w); if (!z.Equals(One)) { x = z; } } g = x.Subtract(One).Gcd(w); if (g.CompareTo(One) > 0) { return(MROutput.ProvablyCompositeWithFactor(g)); } return(MROutput.ProvablyCompositeNotPrimePower()); } } return(MROutput.ProbablyPrime()); }
/// <summary> /// Returns true if this objects chainWork is higher than the others. /// </summary> public bool MoreWorkThan(StoredBlock other) { return(_chainWork.CompareTo(other._chainWork) > 0); }
/** * return a sqrt root - the routine verifies that the calculation * returns the right value - if none exists it returns null. */ public override ECFieldElement Sqrt() { if (IsZero || IsOne) { return(this); } if (!q.TestBit(0)) { throw Platform.CreateNotImplementedException("even value of q"); } if (q.TestBit(1)) // q == 4m + 3 { BigInteger e = q.ShiftRight(2).Add(BigInteger.One); return(CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q)))); } if (q.TestBit(2)) // q == 8m + 5 { BigInteger t1 = x.ModPow(q.ShiftRight(3), q); BigInteger t2 = ModMult(t1, x); BigInteger t3 = ModMult(t2, t1); if (t3.Equals(BigInteger.One)) { return(CheckSqrt(new FpFieldElement(q, r, t2))); } // TODO This is constant and could be precomputed BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q); BigInteger y = ModMult(t2, t4); return(CheckSqrt(new FpFieldElement(q, r, y))); } // q == 8m + 1 BigInteger legendreExponent = q.ShiftRight(1); if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) { return(null); } BigInteger X = this.x; BigInteger fourX = ModDouble(ModDouble(X));; BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One); BigInteger U, V; Random rand = new Random(); do { BigInteger P; do { P = new BigInteger(q.BitLength, rand); }while (P.CompareTo(q) >= 0 || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne)); BigInteger[] result = LucasSequence(P, X, k); U = result[0]; V = result[1]; if (ModMult(V, V).Equals(fourX)) { return(new FpFieldElement(q, r, ModHalfAbs(V))); } }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return(null); }
/** * return a sqrt root - the routine verifies that the calculation * returns the right value - if none exists it returns null. */ public override ECFieldElement Sqrt() { if (IsZero || IsOne) return this; if (!q.TestBit(0)) throw Platform.CreateNotImplementedException("even value of q"); if (q.TestBit(1)) // q == 4m + 3 { BigInteger e = q.ShiftRight(2).Add(BigInteger.One); return CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q))); } if (q.TestBit(2)) // q == 8m + 5 { BigInteger t1 = x.ModPow(q.ShiftRight(3), q); BigInteger t2 = ModMult(t1, x); BigInteger t3 = ModMult(t2, t1); if (t3.Equals(BigInteger.One)) { return CheckSqrt(new FpFieldElement(q, r, t2)); } // TODO This is constant and could be precomputed BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q); BigInteger y = ModMult(t2, t4); return CheckSqrt(new FpFieldElement(q, r, y)); } // q == 8m + 1 BigInteger legendreExponent = q.ShiftRight(1); if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) return null; BigInteger X = this.x; BigInteger fourX = ModDouble(ModDouble(X)); ; BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One); BigInteger U, V; Random rand = new Random(); do { BigInteger P; do { P = new BigInteger(q.BitLength, rand); } while (P.CompareTo(q) >= 0 || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne)); BigInteger[] result = LucasSequence(P, X, k); U = result[0]; V = result[1]; if (ModMult(V, V).Equals(fourX)) { return new FpFieldElement(q, r, ModHalfAbs(V)); } } while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return null; }
/// <summary> /// Create a random BigInteger /// </summary> /// /// <param name="UpperBound">The upper bound</param> /// <param name="SecRnd">An instance of the SecureRandom class</param> /// /// <returns>A random BigInteger</returns> public static BigInteger Randomize(BigInteger UpperBound, SecureRandom SecRnd) { int blen = UpperBound.BitLength; BigInteger randomNum = BigInteger.ValueOf(0); if (SecRnd == null) SecRnd = _secRnd != null ? _secRnd : new SecureRandom(); for (int i = 0; i < 20; i++) { randomNum = new BigInteger(blen, SecRnd); if (randomNum.CompareTo(UpperBound) < 0) return randomNum; } return randomNum.Mod(UpperBound); }
/** * @return true if the S component is "low", that means it is below * {@link ECKeyPair#HALF_CURVE_ORDER}. See * <a href="https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#Low_S_values_in_signatures"> * BIP62</a>. */ private bool IsCanonical() { return(S.CompareTo(ECKeyPair.HalfCurveOrder) <= 0); }
/* ---------------------------------------------------------------------------- DblToRgbPrecise() Uses big integer arithmetic to get the sequence of digits. */ public static void DblToRgbPrecise(double dbl, byte[] mantissa, out int exponent, out int mantissaSize) { BigInteger biNum = new BigInteger(); BigInteger biDen = new BigInteger(); BigInteger biHi = new BigInteger(); BigInteger biLo = new BigInteger(); BigInteger biT = new BigInteger(); BigInteger biHiLo; byte bT; bool fPow2; int ib, cu; int wExp10, wExp2, w1, w2; int c2Num, c2Den, c5Num, c5Den; double dblT; //uint *rgu = stackalloc uint[2]; uint rgu0, rgu1; uint dblHi, dblLo; dblHi = DblHi(dbl); dblLo = DblLo(dbl); // Caller should take care of 0, negative and non-finite values. Debug.Assert(!IsSpecial(dbl)); Debug.Assert(0 < dbl); // Init the Denominator, Hi error and Lo error bigints. biDen.InitFromDigits(1, 0, 1); biHi.InitFromDigits(1, 0, 1); wExp2 = (int)(((dblHi & 0x7FF00000) >> 20) - 1075); rgu1 = dblHi & 0x000FFFFF; rgu0 = dblLo; cu = 2; fPow2 = false; if (wExp2 == -1075) { // dbl is denormalized. Debug.Assert(0 == (dblHi & 0x7FF00000)); if (0 == rgu1) { cu = 1; } // Get dblT such that dbl / dblT is a power of 2 and 1 <= dblT < 2. // First multiply by a power of 2 to get a normalized value. dblT = BitConverter.Int64BitsToDouble(0x4FF00000L << 32); dblT *= dbl; Debug.Assert(0 != (DblHi(dblT) & 0x7FF00000)); // This is the power of 2. w1 = (int)((DblHi(dblT) & 0x7FF00000) >> 20) - (256 + 1023); dblHi = DblHi(dblT); dblHi &= 0x000FFFFF; dblHi |= 0x3FF00000; dblT = BitConverter.Int64BitsToDouble((long)dblHi << 32 | DblLo(dblT)); // Adjust wExp2 because we don't have the implicit bit. wExp2++; } else { // Get dblT such that dbl / dblT is a power of 2 and 1 <= dblT < 2. // First multiply by a power of 2 to get a normalized value. dblHi &= 0x000FFFFF; dblHi |= 0x3FF00000; dblT = BitConverter.Int64BitsToDouble((long)dblHi << 32 | dblLo); // This is the power of 2. w1 = wExp2 + 52; if (0 == rgu0 && 0 == rgu1 && wExp2 > -1074) { // Power of 2 bigger than smallest normal. The next smaller // representable value is closer than the next larger value. rgu1 = 0x00200000; wExp2--; fPow2 = true; } else { // Normalized and not a power of 2 or the smallest normal. The // representable values on either side are the same distance away. rgu1 |= 0x00100000; } } // Compute an approximation to the base 10 log. This is borrowed from // David ----'s paper. Debug.Assert(1 <= dblT && dblT < 2); dblT = (dblT - 1.5) * 0.289529654602168 + 0.1760912590558 + w1 * 0.301029995663981; wExp10 = (int)dblT; if (dblT < 0 && dblT != wExp10) { wExp10--; } if (wExp2 >= 0) { c2Num = wExp2; c2Den = 0; } else { c2Num = 0; c2Den = -wExp2; } if (wExp10 >= 0) { c5Num = 0; c5Den = wExp10; c2Den += wExp10; } else { c2Num -= wExp10; c5Num = -wExp10; c5Den = 0; } if (c2Num > 0 && c2Den > 0) { w1 = c2Num < c2Den ? c2Num : c2Den; c2Num -= w1; c2Den -= w1; } // We need a bit for the Hi and Lo values. c2Num++; c2Den++; // Initialize biNum and multiply by powers of 5. if (c5Num > 0) { Debug.Assert(0 == c5Den); biHi.MulPow5(c5Num); biNum.InitFromBigint(biHi); if (1 == cu) { biNum.MulAdd(rgu0, 0); } else { biNum.MulAdd(rgu1, 0); biNum.ShiftLeft(32); if (0 != rgu0) { biT.InitFromBigint(biHi); biT.MulAdd(rgu0, 0); biNum.Add(biT); } } } else { Debug.Assert(cu <= 2); biNum.InitFromDigits(rgu0, rgu1, cu); if (c5Den > 0) { biDen.MulPow5(c5Den); } } // BigInteger.DivRem only works if the 4 high bits of the divisor are 0. // It works most efficiently if there are exactly 4 zero high bits. // Adjust c2Den and c2Num to guarantee this. w1 = CbitZeroLeft(biDen[biDen.Length - 1]); w1 = (w1 + 28 - c2Den) & 0x1F; c2Num += w1; c2Den += w1; // Multiply by powers of 2. Debug.Assert(c2Num > 0 && c2Den > 0); biNum.ShiftLeft(c2Num); if (c2Num > 1) { biHi.ShiftLeft(c2Num - 1); } biDen.ShiftLeft(c2Den); Debug.Assert(0 == (biDen[biDen.Length - 1] & 0xF0000000)); Debug.Assert(0 != (biDen[biDen.Length - 1] & 0x08000000)); // Get biHiLo and handle the power of 2 case where biHi needs to be doubled. if (fPow2) { biHiLo = biLo; biHiLo.InitFromBigint(biHi); biHi.ShiftLeft(1); } else { biHiLo = biHi; } for (ib = 0; ; ) { bT = (byte)biNum.DivRem(biDen); if (0 == ib && 0 == bT) { // Our estimate of wExp10 was too big. Oh well. wExp10--; goto LSkip; } // w1 = sign(biNum - biHiLo). w1 = biNum.CompareTo(biHiLo); // w2 = sign(biNum + biHi - biDen). if (biDen.CompareTo(biHi) < 0) { w2 = 1; } else { // biT.InitFromBigint(biDen); biT.Subtract(biHi); w2 = biNum.CompareTo(biT); } // if (biNum + biHi == biDen && even) if (0 == w2 && 0 == (dblLo & 1)) { // Rounding up this digit produces exactly (biNum + biHi) which // StrToDbl will round down to dbl. if (bT == 9) { goto LRoundUp9; } if (w1 > 0) { bT++; } mantissa[ib++] = bT; break; } // if (biNum < biHiLo || biNum == biHiLo && even) if (w1 < 0 || 0 == w1 && 0 == (dblLo & 1)) { // if (biNum + biHi > biDen) if (w2 > 0) { // Decide whether to round up. biNum.ShiftLeft(1); w2 = biNum.CompareTo(biDen); if ((w2 > 0 || 0 == w2 && (0 != (bT & 1))) && bT++ == 9) { goto LRoundUp9; } } mantissa[ib++] = bT; break; } // if (biNum + biHi > biDen) if (w2 > 0) { // Round up and be done with it. if (bT != 9) { mantissa[ib++] = (byte)(bT + 1); break; } goto LRoundUp9; } // Save the digit. mantissa[ib++] = bT; LSkip: biNum.MulAdd(10, 0); biHi.MulAdd(10, 0); if ((object) biHiLo != (object) biHi) { biHiLo.MulAdd(10, 0); } continue; LRoundUp9: while (ib > 0) { if (mantissa[--ib] != 9) { mantissa[ib++]++; goto LReturn; } } wExp10++; mantissa[ib++] = 1; break; } LReturn: exponent = wExp10 + 1; mantissaSize = ib; }
// D.1.4 91 /** * return a sqrt root - the routine verifies that the calculation * returns the right value - if none exists it returns null. */ public override ECFieldElement Sqrt() { if (!q.TestBit(0)) { throw Platform.CreateNotImplementedException("even value of q"); } // p mod 4 == 3 if (q.TestBit(1)) { // TODO Can this be optimised (inline the Square?) // z = g^(u+1) + p, p = 4u + 3 ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q)); return(z.Square().Equals(this) ? z : null); } // p mod 4 == 1 BigInteger qMinusOne = q.Subtract(BigInteger.One); BigInteger legendreExponent = qMinusOne.ShiftRight(1); if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) { return(null); } BigInteger u = qMinusOne.ShiftRight(2); BigInteger k = u.ShiftLeft(1).Add(BigInteger.One); BigInteger Q = this.x; BigInteger fourQ = Q.ShiftLeft(2).Mod(q); BigInteger U, V; do { Random rand = new Random(); BigInteger P; do { P = new BigInteger(q.BitLength, rand); }while (P.CompareTo(q) >= 0 || !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne))); BigInteger[] result = fastLucasSequence(q, P, Q, k); U = result[0]; V = result[1]; if (V.Multiply(V).Mod(q).Equals(fourQ)) { // Integer division by 2, mod q if (V.TestBit(0)) { V = V.Add(q); } V = V.ShiftRight(1); Debug.Assert(V.Multiply(V).Mod(q).Equals(x)); return(new FpFieldElement(q, V)); } }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return(null); // BigInteger qMinusOne = q.Subtract(BigInteger.One); // // BigInteger legendreExponent = qMinusOne.ShiftRight(1); // if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) // return null; // // Random rand = new Random(); // BigInteger fourX = x.ShiftLeft(2); // // BigInteger r; // do // { // r = new BigInteger(q.BitLength, rand); // } // while (r.CompareTo(q) >= 0 // || !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne))); // // BigInteger n1 = qMinusOne.ShiftRight(2); // BigInteger n2 = n1.Add(BigInteger.One); // // BigInteger wOne = WOne(r, x, q); // BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q); // BigInteger twoR = r.ShiftLeft(1); // // BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q) // .Multiply(x).Mod(q) // .Multiply(wSum).Mod(q); // // return new FpFieldElement(q, root); }
/// <summary> /// Get a pseudo random 64bit integer /// </summary> /// /// <returns>Random Int64</returns> public Int64 NextLong() { // Xi+1 = (2Xi pow 2) + 3Xi + (1 mod P) _G = _G.Multiply(_G.Add(_G).Add(_BI3)).Add(BigInteger.One).Mod(_P); // set G to 2 if G <= 1 if (_G.CompareTo(BigInteger.One) < 1) _G = BigInteger.ValueOf(2); return _G.ToInt64(); }
/// <summary> /// Compares token to the object /// </summary> public int CompareTo(object obj) { return(value.CompareTo(((Token)obj).value)); }
// Stratis kernel protocol // coinstake must meet hash target according to the protocol: // kernel (input 0) must meet the formula // hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight // this ensures that the chance of getting a coinstake is proportional to the // amount of coins one owns. // The reason this hash is chosen is the following: // nStakeModifier: scrambles computation to make it very difficult to precompute // future proof-of-stake // txPrev.block.nTime: prevent nodes from guessing a good timestamp to // generate transaction for future advantage, // obsolete since v3 // txPrev.nTime: slightly scrambles computation // txPrev.vout.hash: hash of txPrev, to reduce the chance of nodes // generating coinstake at the same time // txPrev.vout.n: output number of txPrev, to reduce the chance of nodes // generating coinstake at the same time // nTime: current timestamp // block/tx hash should not be used here as they can be generated in vast // quantities so as to generate blocks faster, degrading the system back into // a proof-of-work situation. // private static bool CheckStakeKernelHashV2(ChainedBlock pindexPrev, uint nBits, uint nTimeBlockFrom, Transaction txPrev, OutPoint prevout, uint nTimeTx, out uint256 hashProofOfStake, out uint256 targetProofOfStake, bool fPrintProofOfStake) { targetProofOfStake = null; hashProofOfStake = null; if (nTimeTx < txPrev.Time) // Transaction timestamp violation { return(false); //error("CheckStakeKernelHash() : nTime violation"); } // Base target var bnTarget = new Target(nBits).ToBigInteger(); // Weighted target var nValueIn = txPrev.Outputs[prevout.N].Value.Satoshi; var bnWeight = BigInteger.ValueOf(nValueIn); bnTarget = bnTarget.Multiply(bnWeight); // todo: investigate this issue, is the convertion to uint256 similar to the c++ implementation //targetProofOfStake = Target.ToUInt256(bnTarget); var nStakeModifier = pindexPrev.Header.PosParameters.StakeModifier; uint256 bnStakeModifierV2 = pindexPrev.Header.PosParameters.StakeModifierV2; int nStakeModifierHeight = pindexPrev.Height; var nStakeModifierTime = pindexPrev.Header.Time; // Calculate hash using (var ms = new MemoryStream()) { var serializer = new BitcoinStream(ms, true); if (IsProtocolV3((int)nTimeTx)) { serializer.ReadWrite(bnStakeModifierV2); } else { serializer.ReadWrite(nStakeModifier); serializer.ReadWrite(nTimeBlockFrom); } serializer.ReadWrite(txPrev.Time); serializer.ReadWrite(prevout.Hash); serializer.ReadWrite(prevout.N); serializer.ReadWrite(nTimeTx); hashProofOfStake = Hashes.Hash256(ms.ToArray()); } if (fPrintProofOfStake) { //LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n", // nStakeModifier, nStakeModifierHeight, // DateTimeStrFormat(nStakeModifierTime), // DateTimeStrFormat(nTimeBlockFrom)); //LogPrintf("CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", // nStakeModifier, // nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx, // hashProofOfStake.ToString()); } // Now check if proof-of-stake hash meets target protocol var hashProofOfStakeTarget = new BigInteger(hashProofOfStake.ToBytes(false)); if (hashProofOfStakeTarget.CompareTo(bnTarget) > 0) { return(false); } // if (fDebug && !fPrintProofOfStake) // { // LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n", // nStakeModifier, nStakeModifierHeight, // DateTimeStrFormat(nStakeModifierTime), // DateTimeStrFormat(nTimeBlockFrom)); // LogPrintf("CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", // nStakeModifier, // nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx, // hashProofOfStake.ToString()); // } return(true); }
/** * Compute the pseudorandom k for signature generation, * using the process specified for deterministic DSA. * * @param h1 the hashed message * @return the pseudorandom k to use */ private BigInteger computek(byte[] h1) { /* * Convert hash value into an appropriately truncated * and/or expanded sequence of octets. The private * key was already processed (into field bx[]). */ byte[] bh = bits2octets(h1); /* * HMAC is always used with K as key. * Whenever K is updated, we reset the * current HMAC key. */ /* step b. */ byte[] V = new byte[holen]; for (int i = 0; i < holen; i++) { V[i] = 0x01; } /* step c. */ byte[] K = new byte[holen]; setHmacKey(K); /* step d. */ hmac.Update(V); hmac.Update((byte)0x00); hmac.Update(bx); hmac.Update(bh); K = hmac.DoFinal(); setHmacKey(K); /* step e. */ hmac.Update(V); V = hmac.DoFinal(); /* step f. */ hmac.Update(V); hmac.Update((byte)0x01); hmac.Update(bx); hmac.Update(bh); K = hmac.DoFinal(); setHmacKey(K); /* step g. */ hmac.Update(V); V = hmac.DoFinal(); /* step h. */ byte[] T = new byte[rolen]; for ( ; ;) { /* * We want qlen bits, but we support only * hash functions with an output length * multiple of 8;acd hence, we will gather * rlen bits, i.e., rolen octets. */ int toff = 0; while (toff < rolen) { hmac.Update(V); V = hmac.DoFinal(); int cc = Math.Min(V.Length, T.Length - toff); Array.Copy(V, 0, T, toff, cc); toff += cc; } BigInteger k = bits2int(T); if (k.SignValue > 0 && k.CompareTo(q) < 0) { return(k); } /* * k is not in the proper range; update * K and V, and loop. */ hmac.Update(V); hmac.Update((byte)0x00); K = hmac.DoFinal(); setHmacKey(K); hmac.Update(V); V = hmac.DoFinal(); } }
public int CompareTo(Money other) { return(_Satoshis.CompareTo(other._Satoshis)); }
/// <summary> /// Get a pseudo random 64bit integer /// </summary> /// /// <returns>Random Int64</returns> public Int64 NextLong() { // Xi+1 = (Xi pow 2) mod P _G = _G.Multiply(_G).Mod(_P); // set g to 2 if g <= 1. if (_G.CompareTo(BigInteger.One) < 1) _G = BigInteger.ValueOf(2); return _G.ToInt64(); }
public Key Derivate(byte[] cc, uint nChild, out byte[] ccChild) { AssertNotDisposed(); #if HAS_SPAN if (!IsCompressed) { throw new InvalidOperationException("The key must be compressed"); } Span <byte> vout = stackalloc byte[64]; vout.Clear(); if ((nChild >> 31) == 0) { Span <byte> pubkey = stackalloc byte[33]; this.PubKey.ToBytes(pubkey, out _); Hashes.BIP32Hash(cc, nChild, pubkey[0], pubkey.Slice(1), vout); } else { Span <byte> privkey = stackalloc byte[32]; this._ECKey.WriteToSpan(privkey); Hashes.BIP32Hash(cc, nChild, 0, privkey, vout); privkey.Fill(0); } ccChild = new byte[32]; vout.Slice(32, 32).CopyTo(ccChild); Secp256k1.ECPrivKey keyChild = _ECKey.TweakAdd(vout.Slice(0, 32)); vout.Clear(); return(new Key(keyChild, true)); #else byte[]? l = null; if ((nChild >> 31) == 0) { var pubKey = PubKey.ToBytes(); l = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.SafeSubarray(1)); } else { l = Hashes.BIP32Hash(cc, nChild, 0, this.ToBytes()); } var ll = l.SafeSubarray(0, 32); var lr = l.SafeSubarray(32, 32); ccChild = lr; var parse256LL = new BigInteger(1, ll); var kPar = new BigInteger(1, vch); var N = ECKey.CURVE.N; if (parse256LL.CompareTo(N) >= 0) { throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again."); } var key = parse256LL.Add(kPar).Mod(N); if (key == BigInteger.Zero) { throw new InvalidOperationException("You won the big prize ! this has probability lower than 1 in 2^127. Take a screenshot, and roll the dice again."); } var keyBytes = key.ToByteArrayUnsigned(); if (keyBytes.Length < 32) { keyBytes = new byte[32 - keyBytes.Length].Concat(keyBytes).ToArray(); } return(new Key(keyBytes)); #endif }
public bool VerifySignature(byte[] data, string signature) { if (!signature.StartsWith(Signature.K1Prefix) && !signature.StartsWith(Signature.R1Prefix)) { return(false); } byte[] buf = Base58.Decode(signature.Substring(Signature.PrefixLength)); if (buf.Length != Signature.Length + ChecksumLength) { return(false); } byte[] signatureBuf = new byte[buf.Length - ChecksumLength]; Array.Copy(buf, 0, signatureBuf, 0, Signature.Length); byte[] checksum; if (signature.StartsWith(Signature.R1Prefix)) { checksum = RIPEMD160.ComputeHash(signatureBuf.Concat(R1Salt)).TakePart(0, 4); } else { checksum = RIPEMD160.ComputeHash(signatureBuf.Concat(K1Salt)).TakePart(0, 4); } if (!CheckChecksum(buf, checksum)) { return(false); } byte[] hash; using (SHA256 sha = SHA256.Create()) { hash = sha.ComputeHash(data, 0, data.Length); } byte recoveryId = (byte)(signatureBuf[0] - 31); BigInteger r = signatureBuf.ToInt256(1); BigInteger s = signatureBuf.ToInt256(33); var q = RecoverPublicKey(hash, r, s, recoveryId, Curve); if (q.X.Value != Q.X.Value && q.Y.Value != Q.Y.Value) { return(false); } if (r.Sign < 1 || s.Sign < 1 || r.CompareTo(Curve.N) >= 0 || s.CompareTo(Curve.N) >= 0) { return(false); } BigInteger e = hash.ToInt256(); BigInteger c = s.ModInverse(Curve.N); BigInteger u1 = (e * c).Mod(Curve.N); BigInteger u2 = (r * c).Mod(Curve.N); Point R = Curve.G.MultiplyTwo(u1, q, u2); BigInteger v = R.X.Value.Mod(Curve.N); return(v.Equals(r)); }
/// <summary> /// Calculates the difficulty target for the next block. /// </summary> /// <param name="stakeChain">Database of stake related data for the current blockchain.</param> /// <param name="chainedBlock">Block header for which to calculate the target difficulty.</param> /// <param name="consensus">Consensus rules for the current network.</param> /// <param name="proofOfStake"><c>true</c> for calculation of PoS difficulty target, <c>false</c> for calculation of PoW difficulty target.</param> /// <returns>The difficulty target for the next block after <paramref name="chainedBlock"/>.</returns> /// <remarks> /// The calculation of the next target is based on the last target value and the block time (aka spacing) of <paramref name="chainedBlock"/> /// (i.e. difference in time stamp of this block and its immediate predecessor). The target changes every block and it is adjusted /// down (i.e. towards harder to reach, or more difficult) if the time to mine last block was lower than the target block time. /// And it is adjusted up if it took longer than the target block time. The adjustments are done in a way the target is moving towards /// the target spacing exponentially, so even a big change in the mining power on the network will be fixed by retargeting relatively quickly. /// <para> /// Over <see cref="RetargetIntervalMinutes"/> minutes there are certain number (say <c>N</c>) of blocks expected to be mined if the target block time /// of <see cref="TargetSpacingSeconds"/> was reached every time. Then the next target is calculated as follows:</para> /// <code> /// NewTarget = PrevTarget * ((N - 1) * TargetSpacingSeconds + 2 * LastBlockTime) / ((N + 1) * TargetSpacingSeconds) /// </code> /// <para> /// Which basically says that the block time of the last block is counted twice instead of two optimal block times. /// And the <c>N</c> determines how strongly will the deviation of the last block time affect the difficulty. /// </para> /// </remarks> public static Target GetNextTargetRequired(StakeChain stakeChain, ChainedBlock chainedBlock, NBitcoin.Consensus consensus, bool proofOfStake) { clogger.LogTrace("({0}:'{1}',{2}:{3})", nameof(chainedBlock), chainedBlock, nameof(proofOfStake), proofOfStake); // Genesis block. if (chainedBlock == null) { clogger.LogTrace("(-)[GENESIS]:'{0}'", consensus.PowLimit); return(consensus.PowLimit); } // Find the last two blocks that correspond to the mining algo // (i.e if this is a POS block we need to find the last two POS blocks). BigInteger targetLimit = proofOfStake ? consensus.ProofOfStakeLimitV2 : consensus.PowLimit.ToBigInteger(); // First block. ChainedBlock pindexPrev = GetLastBlockIndex(stakeChain, chainedBlock, proofOfStake); if (pindexPrev.Previous == null) { var res = new Target(targetLimit); clogger.LogTrace("(-)[FIRST_BLOCK]:'{0}'", res); return(res); } // Second block. ChainedBlock pindexPrevPrev = GetLastBlockIndex(stakeChain, pindexPrev.Previous, proofOfStake); if (pindexPrevPrev.Previous == null) { var res = new Target(targetLimit); clogger.LogTrace("(-)[SECOND_BLOCK]:'{0}'", res); return(res); } // This is used in tests to allow quickly mining blocks. if (consensus.PowNoRetargeting) { clogger.LogTrace("(-)[NO_POW_RETARGET]:'{0}'", pindexPrev.Header.Bits); return(pindexPrev.Header.Bits); } int targetSpacing = TargetSpacingSeconds; int actualSpacing = (int)(pindexPrev.Header.Time - pindexPrevPrev.Header.Time); if (actualSpacing < 0) { actualSpacing = targetSpacing; } if (actualSpacing > targetSpacing * 10) { actualSpacing = targetSpacing * 10; } int targetTimespan = RetargetIntervalMinutes * 60; int interval = targetTimespan / targetSpacing; BigInteger target = pindexPrev.Header.Bits.ToBigInteger(); long multiplyBy = (interval - 1) * targetSpacing + actualSpacing + actualSpacing; target = target.Multiply(BigInteger.ValueOf(multiplyBy)); long divideBy = (interval + 1) * targetSpacing; target = target.Divide(BigInteger.ValueOf(divideBy)); clogger.LogTrace("The next target difficulty will be {0} times higher (easier to satisfy) than the previous target.", (double)multiplyBy / (double)divideBy); if ((target.CompareTo(BigInteger.Zero) <= 0) || (target.CompareTo(targetLimit) >= 1)) { target = targetLimit; } var finalTarget = new Target(target); clogger.LogTrace("(-):'{0}'", finalTarget); return(finalTarget); }
/// <summary> /// Verifying algorithm as specified in section 2.6.3 of the setup /// </summary> /// <param name="pubKey">Public Key used to verify the proof</param> /// <param name="proof">Proof</param> /// <param name="setup">Setup parameters</param> /// <returns> true if the signatures verify, false otherwise</returns> public static bool VerifyPermutationTest(this RsaKeyParameters pubKey, PermutationTestProof proof, PermutationTestSetup setup) { if (setup == null) { throw new ArgumentNullException(nameof(setup)); } if (proof == null) { throw new ArgumentNullException(nameof(proof)); } byte[][] sigs = proof.Signatures; int alpha = setup.Alpha; int keyLength = setup.KeySize; byte[] psBytes = setup.PublicString; int k = setup.SecurityParameter; BigInteger Modulus = pubKey.Modulus; BigInteger Exponent = pubKey.Exponent; BigInteger Two = BigInteger.Two; // 2^{|N| - 1} BigInteger lowerLimit = Two.Pow(keyLength - 1); // 2^{|N|} BigInteger upperLimit = Two.Pow(keyLength); // if N < 2^{KeySize-1} if (Modulus.CompareTo(lowerLimit) < 0) { return(false); } // if N >= 2^{KeySize} if (Modulus.CompareTo(upperLimit) >= 0) { return(false); } // Generate m1 and m2 Get_m1_m2((decimal)alpha, Exponent.IntValue, k, out int m1, out int m2); // Verifying m2 if (!m2.Equals(sigs.Length)) { return(false); } // Verify alpha and N if (!CheckAlphaN(alpha, Modulus)) { return(false); } // Generate a "weird" public key var eN = Modulus.Multiply(Exponent); var pubKeyPrime = new RsaKeyParameters(false, Modulus, eN); // Generate list of rho values GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues); // Verifying the signatures for (int i = 0; i < m2; i++) { if (i <= m1) { var dec_sig = pubKeyPrime.Encrypt(sigs[i]); if (!dec_sig.SequenceEqual(rhoValues[i])) { return(false); } } else { var dec_sig = pubKey.Encrypt(sigs[i]); if (!dec_sig.SequenceEqual(rhoValues[i])) { return(false); } } } return(true); }
/// <summary> /// Encode a number between 0 and (n|t) (binomial coefficient) into a binary vector of length n with weight t. /// <para>The number is given as a byte array. Only the first s bits are used, where s = floor[log(n|t)].</para> /// </summary> /// /// <param name="N">The "n" integer</param> /// <param name="T">The "t" integer</param> /// <param name="M">The message as a byte array</param> /// /// <returns>The encoded message as GF2Vector</returns> public static GF2Vector Encode(int N, int T, byte[] M) { if (N < T) throw new ArgumentException("n < t"); // compute the binomial c = (n|t) BigInteger c = BigMath.Binomial(N, T); // get the number encoded in m BigInteger i = new BigInteger(1, M); // compare if (i.CompareTo(c) >= 0) throw new ArgumentException("Encoded number too large."); GF2Vector result = new GF2Vector(N); int nn = N; int tt = T; for (int j = 0; j < N; j++) { c = c.Multiply(BigInteger.ValueOf(nn - tt)).Divide(BigInteger.ValueOf(nn)); nn--; if (c.CompareTo(i) <= 0) { result.SetBit(j); i = i.Subtract(c); tt--; if (nn == tt) c = ONE; else c = (c.Multiply(BigInteger.ValueOf(tt + 1))).Divide(BigInteger.ValueOf(nn - tt)); } } return result; }
public virtual bool Match( object obj) { X509Crl c = obj as X509Crl; if (c == null) { return(false); } if (dateAndTime != null) { DateTime dt = dateAndTime.Value; DateTime tu = c.ThisUpdate; DateTimeObject nu = c.NextUpdate; if (dt.CompareTo(tu) < 0 || nu == null || dt.CompareTo(nu.Value) >= 0) { return(false); } } if (issuers != null) { X509Name i = c.IssuerDN; bool found = false; foreach (X509Name issuer in issuers) { if (issuer.Equivalent(i, true)) { found = true; break; } } if (!found) { return(false); } } if (maxCrlNumber != null || minCrlNumber != null) { Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CrlNumber); if (extVal == null) { return(false); } BigInteger cn = CrlNumber.GetInstance( X509ExtensionUtilities.FromExtensionValue(extVal)).PositiveValue; if (maxCrlNumber != null && cn.CompareTo(maxCrlNumber) > 0) { return(false); } if (minCrlNumber != null && cn.CompareTo(minCrlNumber) < 0) { return(false); } } DerInteger dci = null; try { Asn1OctetString bytes = c.GetExtensionValue(X509Extensions.DeltaCrlIndicator); if (bytes != null) { dci = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(bytes)); } } catch (Exception) { return(false); } if (dci == null) { if (DeltaCrlIndicatorEnabled) { return(false); } } else { if (CompleteCrlEnabled) { return(false); } if (maxBaseCrlNumber != null && dci.PositiveValue.CompareTo(maxBaseCrlNumber) > 0) { return(false); } } if (issuingDistributionPointEnabled) { Asn1OctetString idp = c.GetExtensionValue(X509Extensions.IssuingDistributionPoint); if (issuingDistributionPoint == null) { if (idp != null) { return(false); } } else { if (!Arrays.AreEqual(idp.GetOctets(), issuingDistributionPoint)) { return(false); } } } return(true); }
// D.1.4 91 /** * return a sqrt root - the routine verifies that the calculation * returns the right value - if none exists it returns null. */ public override ECFieldElement Sqrt() { if (!q.TestBit(0)) throw Platform.CreateNotImplementedException("even value of q"); // p mod 4 == 3 if (q.TestBit(1)) { // TODO Can this be optimised (inline the Square?) // z = g^(u+1) + p, p = 4u + 3 ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q)); return this.Equals(z.Square()) ? z : null; } // p mod 4 == 1 BigInteger qMinusOne = q.Subtract(BigInteger.One); BigInteger legendreExponent = qMinusOne.ShiftRight(1); if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) return null; BigInteger u = qMinusOne.ShiftRight(2); BigInteger k = u.ShiftLeft(1).Add(BigInteger.One); BigInteger Q = this.x; BigInteger fourQ = Q.ShiftLeft(2).Mod(q); BigInteger U, V; do { Random rand = new Random(); BigInteger P; do { P = new BigInteger(q.BitLength, rand); } while (P.CompareTo(q) >= 0 || !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne))); BigInteger[] result = fastLucasSequence(q, P, Q, k); U = result[0]; V = result[1]; if (V.Multiply(V).Mod(q).Equals(fourQ)) { // Integer division by 2, mod q if (V.TestBit(0)) { V = V.Add(q); } V = V.ShiftRight(1); Debug.Assert(V.Multiply(V).Mod(q).Equals(x)); return new FpFieldElement(q, V); } } while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return null; // BigInteger qMinusOne = q.Subtract(BigInteger.One); // // BigInteger legendreExponent = qMinusOne.ShiftRight(1); // if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) // return null; // // Random rand = new Random(); // BigInteger fourX = x.ShiftLeft(2); // // BigInteger r; // do // { // r = new BigInteger(q.BitLength, rand); // } // while (r.CompareTo(q) >= 0 // || !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne))); // // BigInteger n1 = qMinusOne.ShiftRight(2); // BigInteger n2 = n1.Add(BigInteger.One); // // BigInteger wOne = WOne(r, x, q); // BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q); // BigInteger twoR = r.ShiftLeft(1); // // BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q) // .Multiply(x).Mod(q) // .Multiply(wSum).Mod(q); // // return new FpFieldElement(q, root); }
public virtual AsymmetricCipherKeyPair GenerateKeyPair() { for (;;) { // // p and q values should have a length of half the strength in bits // int strength = parameters.Strength; int pBitlength = (strength + 1) / 2; int qBitlength = strength - pBitlength; int mindiffbits = strength / 3; int minWeight = strength >> 2; BigInteger e = parameters.PublicExponent; // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") BigInteger p = ChooseRandomPrime(pBitlength, e); BigInteger q, n; // // generate a modulus of the required length // for (;;) { q = ChooseRandomPrime(qBitlength, e); // p and q should not be too close together (or equal!) BigInteger diff = q.Subtract(p).Abs(); if (diff.BitLength < mindiffbits) { continue; } // // calculate the modulus // n = p.Multiply(q); if (n.BitLength != strength) { // // if we get here our primes aren't big enough, make the largest // of the two p and try again // p = p.Max(q); continue; } /* * Require a minimum weight of the NAF representation, since low-weight composites may * be weak against a version of the number-field-sieve for factoring. * * See "The number field sieve for integers of low weight", Oliver Schirokauer. */ if (WNafUtilities.GetNafWeight(n) < minWeight) { p = ChooseRandomPrime(pBitlength, e); continue; } break; } if (p.CompareTo(q) < 0) { BigInteger tmp = p; p = q; q = tmp; } BigInteger pSub1 = p.Subtract(One); BigInteger qSub1 = q.Subtract(One); //BigInteger phi = pSub1.Multiply(qSub1); BigInteger gcd = pSub1.Gcd(qSub1); BigInteger lcm = pSub1.Divide(gcd).Multiply(qSub1); // // calculate the private exponent // BigInteger d = e.ModInverse(lcm); if (d.BitLength <= qBitlength) { continue; } // // calculate the CRT factors // BigInteger dP = d.Remainder(pSub1); BigInteger dQ = d.Remainder(qSub1); BigInteger qInv = BigIntegers.ModOddInverse(p, q); return(new AsymmetricCipherKeyPair( new RsaKeyParameters(false, n, e), new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv))); } }
internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x) { if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0) throw new ArgumentException("value invalid in Fp field element", "x"); this.q = q; this.r = r; this.x = x; }
public static bool CheckIsCanonical(byte[] sig, bool strict) { // Make sure signature is canonical // To protect against signature morphing attacks // Signature should be: // <30> <len> [ <02> <lenR> <R> ] [ <02> <lenS> <S> ] // where // 6 <= len <= 70 // 1 <= lenR <= 33 // 1 <= lenS <= 33 int sigLen = sig.Length; if ((sigLen < 8) || (sigLen > 72)) { return(false); } if ((sig[0] != 0x30) || (sig[1] != (sigLen - 2))) { return(false); } // Find R and check its length int rPos = 4, rLen = sig[rPos - 1]; if ((rLen < 1) || (rLen > 33) || ((rLen + 7) > sigLen)) { return(false); } // Find S and check its length int sPos = rLen + 6, sLen = sig[sPos - 1]; if ((sLen < 1) || (sLen > 33) || ((rLen + sLen + 6) != sigLen)) { return(false); } if ((sig[rPos - 2] != 0x02) || (sig[sPos - 2] != 0x02)) { return(false); // R or S have wrong type } if ((sig[rPos] & 0x80) != 0) { return(false); // R is negative } if ((sig[rPos] == 0) && rLen == 1) { return(false); // R is zero } if ((sig[rPos] == 0) && ((sig[rPos + 1] & 0x80) == 0)) { return(false); // R is padded } if ((sig[sPos] & 0x80) != 0) { return(false); // S is negative } if ((sig[sPos] == 0) && sLen == 1) { return(false); // S is zero } if ((sig[sPos] == 0) && ((sig[sPos + 1] & 0x80) == 0)) { return(false); // S is padded } byte[] rBytes = new byte[rLen]; byte[] bytes = new byte[sLen]; Array.Copy(sig, rPos, rBytes, 0, rLen); Array.Copy(sig, sPos, bytes, 0, sLen); BigInteger r = new BigInteger(1, rBytes), s = new BigInteger(1, bytes); BigInteger order = Secp256K1.Order(); if (r.CompareTo(order) != -1 || s.CompareTo(order) != -1) { return(false); // R or S greater than modulus } if (strict) { return(order.Subtract(s).CompareTo(s) != -1); } else { return(true); } }
protected virtual BigInteger ModReduce(BigInteger x) { if (r == null) { x = x.Mod(q); } else { bool negative = x.SignValue < 0; if (negative) { x = x.Abs(); } int qLen = q.BitLength; if (r.SignValue > 0) { BigInteger qMod = BigInteger.One.ShiftLeft(qLen); bool rIsOne = r.Equals(BigInteger.One); while (x.BitLength > (qLen + 1)) { BigInteger u = x.ShiftRight(qLen); BigInteger v = x.Remainder(qMod); if (!rIsOne) { u = u.Multiply(r); } x = u.Add(v); } } else { int d = ((qLen - 1) & 31) + 1; BigInteger mu = r.Negate(); BigInteger u = mu.Multiply(x.ShiftRight(qLen - d)); BigInteger quot = u.ShiftRight(qLen + d); BigInteger v = quot.Multiply(q); BigInteger bk1 = BigInteger.One.ShiftLeft(qLen + d); v = v.Remainder(bk1); x = x.Remainder(bk1); x = x.Subtract(v); if (x.SignValue < 0) { x = x.Add(bk1); } } while (x.CompareTo(q) >= 0) { x = x.Subtract(q); } if (negative && x.SignValue != 0) { x = q.Subtract(x); } } return x; }
/** * Computes the <code>[τ]</code>-adic window NAF of an element * <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter μ of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code> of which to compute the * <code>[τ]</code>-adic NAF. * @param width The window width of the resulting WNAF. * @param pow2w 2<sup>width</sup>. * @param tw The auxiliary value <code>t<sub>w</sub></code>. * @param alpha The <code>α<sub>u</sub></code>'s for the window width. * @return The <code>[τ]</code>-adic window NAF of * <code>λ</code>. */ public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda, sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha) { if (!((mu == 1) || (mu == -1))) { throw new ArgumentException("mu must be 1 or -1"); } BigInteger norm = Norm(mu, lambda); // Ceiling of log2 of the norm int log2Norm = norm.BitLength; // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width; // The array holding the TNAF var u = new sbyte[maxLength]; // 2^(width - 1) BigInteger pow2wMin1 = pow2w.ShiftRight(1); // Split lambda into two BigIntegers to simplify calculations BigInteger r0 = lambda.u; BigInteger r1 = lambda.v; int i = 0; // while lambda <> (0, 0) while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) { // if r0 is odd if (r0.TestBit(0)) { // uUnMod = r0 + r1*tw Mod 2^width BigInteger uUnMod = r0.Add(r1.Multiply(tw)).Mod(pow2w); sbyte uLocal; // if uUnMod >= 2^(width - 1) if (uUnMod.CompareTo(pow2wMin1) >= 0) { uLocal = (sbyte)uUnMod.Subtract(pow2w).IntValue; } else { uLocal = (sbyte)uUnMod.IntValue; } // uLocal is now in [-2^(width-1), 2^(width-1)-1] u[i] = uLocal; bool s = true; if (uLocal < 0) { s = false; uLocal = (sbyte)-uLocal; } // uLocal is now >= 0 if (s) { r0 = r0.Subtract(alpha[uLocal].u); r1 = r1.Subtract(alpha[uLocal].v); } else { r0 = r0.Add(alpha[uLocal].u); r1 = r1.Add(alpha[uLocal].v); } } else { u[i] = 0; } BigInteger t = r0; if (mu == 1) { r0 = r1.Add(r0.ShiftRight(1)); } else { // mu == -1 r0 = r1.Subtract(r0.ShiftRight(1)); } r1 = t.ShiftRight(1).Negate(); i++; } return(u); }
/// <summary> /// Computes the square root of a BigInteger modulo a prime employing the Shanks-Tonelli algorithm /// </summary> /// /// <param name="X">The value out of which we extract the square root</param> /// <param name="P">The prime modulus that determines the underlying field</param> /// /// <returns>Returns a number <c>B</c> such that B^2 = A (mod P) if <c>A</c> is a quadratic residue modulo <c>P</c></returns> public static BigInteger Ressol(BigInteger X, BigInteger P) { BigInteger v = null; if (X.CompareTo(ZERO) < 0) X = X.Add(P); if (X.Equals(ZERO)) return ZERO; if (P.Equals(TWO)) return X; // p = 3 mod 4 if (P.TestBit(0) && P.TestBit(1)) { if (Jacobi(X, P) == 1) { // a quadr. residue mod p v = P.Add(ONE); // v = p+1 v = v.ShiftRight(2); // v = v/4 return X.ModPow(v, P); // return a^v mod p } throw new ArgumentException("No quadratic residue: " + X + ", " + P); } long t = 0; // initialization // compute k and s, where p = 2^s (2k+1) +1 BigInteger k = P.Subtract(ONE); // k = p-1 long s = 0; while (!k.TestBit(0)) { // while k is even s++; // s = s+1 k = k.ShiftRight(1); // k = k/2 } k = k.Subtract(ONE); // k = k - 1 k = k.ShiftRight(1); // k = k/2 // initial values BigInteger r = X.ModPow(k, P); // r = a^k mod p BigInteger n = r.Multiply(r).Remainder(P); // n = r^2 % p n = n.Multiply(X).Remainder(P); // n = n * a % p r = r.Multiply(X).Remainder(P); // r = r * a %p if (n.Equals(ONE)) { return r; } // non-quadratic residue BigInteger z = TWO; // z = 2 while (Jacobi(z, P) == 1) { // while z quadratic residue z = z.Add(ONE); // z = z + 1 } v = k; v = v.Multiply(TWO); // v = 2k v = v.Add(ONE); // v = 2k + 1 BigInteger c = z.ModPow(v, P); // c = z^v mod p // iteration while (n.CompareTo(ONE) == 1) { // n > 1 k = n; // k = n t = s; // t = s s = 0; while (!k.Equals(ONE)) { // k != 1 k = k.Multiply(k).Mod(P); // k = k^2 % p s++; // s = s + 1 } t -= s; // t = t - s if (t == 0) { throw new ArgumentException("No quadratic residue: " + X + ", " + P); } v = ONE; for (long i = 0; i < t - 1; i++) { v = v.ShiftLeft(1); // v = 1 * 2^(t - 1) } c = c.ModPow(v, P); // c = c^v mod p r = r.Multiply(c).Remainder(P); // r = r * c % p c = c.Multiply(c).Remainder(P); // c = c^2 % p n = n.Multiply(c).Mod(P); // n = n * c % p } return r; }
public int CompareTo(SimpleBigDecimal val) { CheckScale(val); return(bigInt.CompareTo(val.bigInt)); }
/// <summary> /// Computes the value of the Jacobi symbol (A|B). /// </summary> /// /// <param name="A">The integer value</param> /// <param name="B">The integer value</param> /// /// <returns>Returns value of the jacobi symbol (A|B)</returns> public static int Jacobi(BigInteger A, BigInteger B) { BigInteger a, b, v; long k = 1; // test trivial cases if (B.Equals(ZERO)) { a = A.Abs(); return a.Equals(ONE) ? 1 : 0; } if (!A.TestBit(0) && !B.TestBit(0)) return 0; a = A; b = B; if (b.Signum() == -1) { // b < 0 b = b.Negate(); if (a.Signum() == -1) k = -1; } v = ZERO; while (!b.TestBit(0)) { v = v.Add(ONE); b = b.Divide(TWO); } if (v.TestBit(0)) k = k * _jacobiTable[a.ToInt32() & 7]; if (a.Signum() < 0) { if (b.TestBit(1)) k = -k; a = a.Negate(); } // main loop while (a.Signum() != 0) { v = ZERO; while (!a.TestBit(0)) { // a is even v = v.Add(ONE); a = a.Divide(TWO); } if (v.TestBit(0)) k = k * _jacobiTable[b.ToInt32() & 7]; if (a.CompareTo(b) < 0) { // swap and correct intermediate result BigInteger x = a; a = b; b = x; if (a.TestBit(1) && b.TestBit(1)) k = -k; } a = a.Subtract(b); } return b.Equals(ONE) ? (int)k : 0; }
public override bool IsValidFieldElement(BigInteger x) { return(x != null && x.SignValue >= 0 && x.CompareTo(Field.Characteristic) < 0); }
private static void VerifyComparison(BigInteger x, UInt64 y, int expectedResult) { bool expectedEquals = 0 == expectedResult; bool expectedLessThan = expectedResult < 0; bool expectedGreaterThan = expectedResult > 0; Assert.Equal(expectedEquals, x == y); Assert.Equal(expectedEquals, y == x); Assert.Equal(!expectedEquals, x != y); Assert.Equal(!expectedEquals, y != x); Assert.Equal(expectedEquals, x.Equals(y)); VerifyCompareResult(expectedResult, x.CompareTo(y), "x.CompareTo(y)"); if (expectedEquals) { Assert.Equal(x.GetHashCode(), ((BigInteger)y).GetHashCode()); Assert.Equal(x.ToString(), ((BigInteger)y).ToString()); } Assert.Equal(x.GetHashCode(), x.GetHashCode()); Assert.Equal(((BigInteger)y).GetHashCode(), ((BigInteger)y).GetHashCode()); Assert.Equal(expectedLessThan, x < y); Assert.Equal(expectedGreaterThan, y < x); Assert.Equal(expectedGreaterThan, x > y); Assert.Equal(expectedLessThan, y > x); Assert.Equal(expectedLessThan || expectedEquals, x <= y); Assert.Equal(expectedGreaterThan || expectedEquals, y <= x); Assert.Equal(expectedGreaterThan || expectedEquals, x >= y); Assert.Equal(expectedLessThan || expectedEquals, y >= x); }
public static MROutput EnhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations) { CheckCandidate(candidate, "candidate"); if (random == null) { throw new ArgumentNullException("random"); } if (iterations < 1) { throw new ArgumentException("must be > 0", "iterations"); } if (candidate.BitLength == 2) { return(MROutput.ProbablyPrime()); } if (!candidate.TestBit(0)) { return(MROutput.ProvablyCompositeWithFactor(Two)); } BigInteger bigInteger = candidate.Subtract(One); BigInteger max = candidate.Subtract(Two); int lowestSetBit = bigInteger.GetLowestSetBit(); BigInteger e = bigInteger.ShiftRight(lowestSetBit); for (int i = 0; i < iterations; i++) { BigInteger bigInteger2 = BigIntegers.CreateRandomInRange(Two, max, random); BigInteger bigInteger3 = bigInteger2.Gcd(candidate); if (bigInteger3.CompareTo(One) > 0) { return(MROutput.ProvablyCompositeWithFactor(bigInteger3)); } BigInteger bigInteger4 = bigInteger2.ModPow(e, candidate); if (bigInteger4.Equals(One) || bigInteger4.Equals(bigInteger)) { continue; } bool flag = false; BigInteger bigInteger5 = bigInteger4; for (int j = 1; j < lowestSetBit; j++) { bigInteger4 = bigInteger4.ModPow(Two, candidate); if (bigInteger4.Equals(bigInteger)) { flag = true; break; } if (bigInteger4.Equals(One)) { break; } bigInteger5 = bigInteger4; } if (flag) { continue; } if (!bigInteger4.Equals(One)) { bigInteger5 = bigInteger4; bigInteger4 = bigInteger4.ModPow(Two, candidate); if (!bigInteger4.Equals(One)) { bigInteger5 = bigInteger4; } } bigInteger3 = bigInteger5.Subtract(One).Gcd(candidate); if (bigInteger3.CompareTo(One) > 0) { return(MROutput.ProvablyCompositeWithFactor(bigInteger3)); } return(MROutput.ProvablyCompositeNotPrimePower()); } return(MROutput.ProbablyPrime()); }
/** * The Miller-Rabin primality test. * * @param n the input number to be tested. * @param t the number of trials. * @return {@code false} if the number is definitely compose, otherwise * {@code true} with probability {@code 1 - 4<sup>(-t)</sup>}. * @ar.org.fitc.ref "D. Knuth, The Art of Computer Programming Vo.2, Section * 4.5.4., Algorithm P" */ private static bool MillerRabin(BigInteger n, int t) { // PRE: n >= 0, t >= 0 BigInteger x; // x := UNIFORM{2...n-1} BigInteger y; // y := x^(q * 2^j) mod n BigInteger n_minus_1 = n.Subtract(BigInteger.One); // n-1 int bitLength = n_minus_1.BitLength; // ~ log2(n-1) // (q,k) such that: n-1 = q * 2^k and q is odd int k = n_minus_1.LowestSetBit; BigInteger q = n_minus_1.ShiftRight(k); Random rnd = new Random(); for (int i = 0; i < t; i++) { // To generate a witness 'x', first it use the primes of table if (i < primes.Length) { x = BIprimes[i]; } else {/* * It generates random witness only if it's necesssary. Note * that all methods would call Miller-Rabin with t <= 50 so * this part is only to do more robust the algorithm */ do { x = new BigInteger(bitLength, rnd); } while ((x.CompareTo(n) >= BigInteger.EQUALS) || (x.Sign == 0) || x.IsOne); } y = x.ModPow(q, n); if (y.IsOne || y.Equals(n_minus_1)) { continue; } for (int j = 1; j < k; j++) { if (y.Equals(n_minus_1)) { continue; } y = y.Multiply(y).Mod(n); if (y.IsOne) { return false; } } if (!y.Equals(n_minus_1)) { return false; } } return true; }
public DHParameters( BigInteger p, BigInteger g, BigInteger q, int m, int l, BigInteger j, DHValidationParameters validation) { if (p == null) { throw new ArgumentNullException("p"); } if (g == null) { throw new ArgumentNullException("g"); } if (!p.TestBit(0)) { throw new ArgumentException("field must be an odd prime", "p"); } if (g.CompareTo(BigInteger.Two) < 0 || g.CompareTo(p.Subtract(BigInteger.Two)) > 0) { throw new ArgumentException("generator must in the range [2, p - 2]", "g"); } if (q != null && q.BitLength >= p.BitLength) { throw new ArgumentException("q too big to be a factor of (p-1)", "q"); } if (m >= p.BitLength) { throw new ArgumentException("m value must be < bitlength of p", "m"); } if (l != 0) { // TODO Check this against the Java version, which has 'l > p.BitLength' here if (l >= p.BitLength) { throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l"); } if (l < m) { throw new ArgumentException("when l value specified, it may not be less than m value", "l"); } } if (j != null && j.CompareTo(BigInteger.Two) < 0) { throw new ArgumentException("subgroup factor must be >= 2", "j"); } // TODO If q, j both provided, validate p = jq + 1 ? this.p = p; this.g = g; this.q = q; this.m = m; this.l = l; this.j = j; this.validation = validation; }
private void Initialize(int BitLength) { _P = BigInteger.ProbablePrime(BitLength, _secRand); _G = BigInteger.ProbablePrime(BitLength, _secRand); // if G >= P swap(G, P) if (_G.CompareTo(_P) > -1) { BigInteger temp = _G; _G = _P; _P = temp; } _G0 = _G; }
/// <summary> /// Calculates x.modInverse(p) Based on: Savas, E; Koc, C "The Montgomery Modular Inverse - Revised" /// </summary> /// /// <param name="X">BigInteger X</param> /// <param name="P">BigInteger P</param> /// /// <returns>Returns <c>1/X Mod M</c></returns> internal static BigInteger ModInverseMontgomery(BigInteger X, BigInteger P) { // ZERO hasn't inverse if (X._sign == 0) { throw new ArithmeticException("BigInteger not invertible!"); } // montgomery inverse require even modulo if (!P.TestBit(0)) { return(ModInverseLorencz(X, P)); } int m = P._numberLength * 32; // PRE: a \in [1, p - 1] BigInteger u, v, r, s; u = P.Copy(); // make copy to use inplace method v = X.Copy(); int max = System.Math.Max(v._numberLength, u._numberLength); r = new BigInteger(1, 1, new int[max + 1]); s = new BigInteger(1, 1, new int[max + 1]); s._digits[0] = 1; int k = 0; int lsbu = u.LowestSetBit; int lsbv = v.LowestSetBit; int toShift; if (lsbu > lsbv) { BitLevel.InplaceShiftRight(u, lsbu); BitLevel.InplaceShiftRight(v, lsbv); BitLevel.InplaceShiftLeft(r, lsbv); k += lsbu - lsbv; } else { BitLevel.InplaceShiftRight(u, lsbu); BitLevel.InplaceShiftRight(v, lsbv); BitLevel.InplaceShiftLeft(s, lsbu); k += lsbv - lsbu; } r._sign = 1; while (v.Signum() > 0) { // INV v >= 0, u >= 0, v odd, u odd (except last iteration when v is even (0)) while (u.CompareTo(v) > BigInteger.EQUALS) { Elementary.InplaceSubtract(u, v); toShift = u.LowestSetBit; BitLevel.InplaceShiftRight(u, toShift); Elementary.InplaceAdd(r, s); BitLevel.InplaceShiftLeft(s, toShift); k += toShift; } while (u.CompareTo(v) <= BigInteger.EQUALS) { Elementary.InplaceSubtract(v, u); if (v.Signum() == 0) { break; } toShift = v.LowestSetBit; BitLevel.InplaceShiftRight(v, toShift); Elementary.InplaceAdd(s, r); BitLevel.InplaceShiftLeft(r, toShift); k += toShift; } } // in u is stored the gcd if (!u.IsOne()) { throw new ArithmeticException("BigInteger not invertible."); } if (r.CompareTo(P) >= BigInteger.EQUALS) { Elementary.InplaceSubtract(r, P); } r = P.Subtract(r); // Have pair: ((BigInteger)r, (Integer)k) where r == a^(-1) * 2^k mod (module) int n1 = CalcN(P); if (k > m) { r = MonPro(r, BigInteger.One, P, n1); k = k - m; } r = MonPro(r, BigInteger.GetPowerOfTwo(m - k), P, n1); return(r); }
// 5.4 pg 29 /** * return true if the value r and s represent a DSA signature for * the passed in message (for standard DSA the message should be * a SHA-1 hash of the real message to be verified). */ public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) { BigInteger n = key.Parameters.N; // r and s should both in the range [1,n-1] if (r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0) { return(false); } BigInteger e = CalculateE(n, message); BigInteger c = s.ModInverse(n); BigInteger u1 = e.Multiply(c).Mod(n); BigInteger u2 = r.Multiply(c).Mod(n); ECPoint G = key.Parameters.G; ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); if (point.IsInfinity) { return(false); } /* * If possible, avoid normalizing the point (to save a modular inversion in the curve field). * * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'. * If the cofactor is known and small, we generate those possible field values and project each * of them to the same "denominator" (depending on the particular projective coordinates in use) * as the calculated point.X. If any of the projected values matches point.X, then we have: * (point.X / Denominator mod p) mod n == r * as required, and verification succeeds. * * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in * the libsecp256k1 project (https://github.com/bitcoin/secp256k1). */ ECCurve curve = point.Curve; if (curve != null) { BigInteger cofactor = curve.Cofactor; if (cofactor != null && cofactor.CompareTo(Eight) <= 0) { ECFieldElement D = GetDenominator(curve.CoordinateSystem, point); if (D != null && !D.IsZero) { ECFieldElement X = point.XCoord; while (curve.IsValidFieldElement(r)) { ECFieldElement R = curve.FromBigInteger(r).Multiply(D); if (R.Equals(X)) { return(true); } r = r.Add(n); } return(false); } } } BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n); return(v.Equals(r)); }
public IAsymmetricCipherKeyPair GenerateKeyPair() { IBigInteger p, q, n, phi; // // p and q values should have a length of half the strength in bits // var strength = _param.Strength; var pbitlength = (strength + 1) / 2; var qbitlength = (strength - pbitlength); var mindiffbits = strength / 3; var e = _param.PublicExponent; // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") // // Generate p, prime and (p-1) relatively prime to e // for (; ;) { p = new BigInteger(pbitlength, 1, _param.Random); if (p.Mod(e).Equals(BigInteger.One)) { continue; } if (!p.IsProbablePrime(_param.Certainty)) { continue; } if (e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One)) { break; } } // // Generate a modulus of the required length // for (; ;) { // Generate q, prime and (q-1) relatively prime to e, // and not equal to p // for (; ;) { q = new BigInteger(qbitlength, 1, _param.Random); if (q.Subtract(p).Abs().BitLength < mindiffbits) { continue; } if (q.Mod(e).Equals(BigInteger.One)) { continue; } if (!q.IsProbablePrime(_param.Certainty)) { continue; } if (e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One)) { break; } } // // calculate the modulus // n = p.Multiply(q); if (n.BitLength == _param.Strength) { break; } // // if we Get here our primes aren't big enough, make the largest // of the two p and try again // p = p.Max(q); } if (p.CompareTo(q) < 0) { phi = p; p = q; q = phi; } var pSub1 = p.Subtract(BigInteger.One); var qSub1 = q.Subtract(BigInteger.One); phi = pSub1.Multiply(qSub1); // // calculate the private exponent // var d = e.ModInverse(phi); // // calculate the CRT factors // var dP = d.Remainder(pSub1); var dQ = d.Remainder(qSub1); var qInv = q.ModInverse(p); return(new AsymmetricCipherKeyPair( new RsaKeyParameters(false, n, e), new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv))); }