/** * Checks, if the point multiplication algorithm of the given point yields * the same result as point multiplication done by the reference * implementation given in <code>multiply()</code>. This method chooses a * random number by which the given point <code>p</code> is multiplied. * * @param p * The point to be multiplied. * @param numBits * The bitlength of the random number by which <code>p</code> * is multiplied. */ private void ImplTestMultiply(ECPoint p, int numBits) { BigInteger k = new BigInteger(numBits, secRand); ECPoint reff = ECAlgorithms.ReferenceMultiply(p, k); ECPoint q = p.Multiply(k); AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q); }
public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, byte[] message, bool compressed) { if (recId \ throw new ArgumentException("recId should be positive"); if (sig.R.SignValue \ throw new ArgumentException("r should be positive"); if (sig.S.SignValue \ throw new ArgumentException("s should be positive"); if (message == null) throw new ArgumentNullException("message"); var curve = Secp256k1; // 1.0 For j from 0 to h (h == recId here and the loop is outside this function) // 1.1 Let x = r + jn var n = curve.N; var i = BigInteger.ValueOf((long)recId / 2); var x = sig.R.Add(i.Multiply(n)); // 1.2. Convert the integer x to an octet string X of length mlen using the conversion routine // specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉. // 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the // conversion routine specified in Section 2.3.4. If this conversion routine outputs “invalid”, then // do another iteration of Step 1. // // More concisely, what these points mean is to use X as a compressed public key. //using bouncy and Q value of Point var prime = new BigInteger(1, Org.BouncyCastle.Utilities.Encoders.Hex.Decode( "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")); if (x.CompareTo(prime) \>\= 0) return null; // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities. // So it's encoded in the recId. var R = DecompressKey(x, (recId & 1) == 1); // 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility). if (!R.Multiply(n).IsInfinity) return null; // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification. var e = new BigInteger(1, message); // 1.6. For k from 1 to 2 do the following. (loop is outside this function via iterating recId) // 1.6.1. Compute a candidate public key as: // Q = mi(r) * (sR - eG) // // Where mi(x) is the modular multiplicative inverse. We transform this into the following: // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n). In the above equation // ** is point multiplication and + is point addition (the EC group operator). // // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8. var eInv = BigInteger.Zero.Subtract(e).Mod(n); var rInv = sig.R.ModInverse(n); var srInv = rInv.Multiply(sig.S).Mod(n); var eInvrInv = rInv.Multiply(eInv).Mod(n); var q = ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv); q = q.Normalize(); if (compressed) { q = Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()); return new ECKey(q.GetEncoded(true), false); } return new ECKey(q.GetEncoded(), false); }
protected internal bool SatisfiesCofactor() { BigInteger cofactor = Curve.Cofactor; if (cofactor != null && !cofactor.Equals(BigInteger.One)) { return(!ECAlgorithms.ReferenceMultiply(this, cofactor).IsInfinity); } return(true); }
public static byte GetRecoveryId(byte[] sigR, byte[] sigS, byte[] message, byte[] publicKey) { //ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1"); X9ECParameters spec = ECNamedCurveTable.GetByName("secp256k1"); BigInteger pointN = spec.N; for (int recoveryId = 0; recoveryId < 2; recoveryId++) { try { BigInteger pointX = new BigInteger(1, sigR); byte[] compEnc = X9IntegerConverter.IntegerToBytes(pointX, 1 + X9IntegerConverter.GetByteLength(spec.Curve)); compEnc[0] = (byte)((recoveryId & 1) == 1 ? 0x03 : 0x02); ECPoint pointR = spec.Curve.DecodePoint(compEnc); if (!pointR.Multiply(pointN).IsInfinity) { continue; } BigInteger pointE = new BigInteger(1, message); BigInteger pointEInv = BigInteger.Zero.Subtract(pointE).Mod(pointN); BigInteger pointRInv = new BigInteger(1, sigR).ModInverse(pointN); BigInteger srInv = pointRInv.Multiply(new BigInteger(1, sigS)).Mod(pointN); BigInteger pointEInvRInv = pointRInv.Multiply(pointEInv).Mod(pointN); ECPoint pointQ = ECAlgorithms.SumOfTwoMultiplies(spec.G, pointEInvRInv, pointR, srInv); byte[] pointQBytes = pointQ.GetEncoded(false); bool matchedKeys = true; for (int j = 0; j < publicKey.Length; j++) { if (pointQBytes[j] != publicKey[j]) { matchedKeys = false; break; } } if (!matchedKeys) { continue; } return((byte)(0xFF & recoveryId)); } catch (Exception e) { continue; Console.WriteLine(" Failed: GET recoveryID"); } } return((byte)0xFF); }
private BigInteger ExtractUsersPrivateKey( ECPoint G, BigInteger N, string message1, string message2, BigInteger r1, BigInteger s1, BigInteger r2, BigInteger s2, BigInteger attackersPrivate, ECPoint attackersPublic, ECPoint usersPublic) { var m1 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message1))); // hash of m1 var m2 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message2))); // hash of m2 //calculate the result of verifying signature 1 var w = s1.ModInverse(N); var u1 = m1.Multiply(w).Mod(N); var u2 = r1.Multiply(w).Mod(N); var verifyPoint = ECAlgorithms.SumOfTwoMultiplies(G, u1, usersPublic, u2).Normalize(); //reinit K calculator to reproduce a,b,h,e var kCalc = new RandomDsaKCalculator(); kCalc.Init(N, new SecureRandom(new SeededGenerator(Hash(Encoding.UTF8.GetBytes(message2))))); var a = kCalc.NextK(); var b = kCalc.NextK(); var h = kCalc.NextK(); var e = kCalc.NextK(); var Z1 = verifyPoint.Multiply(a).Add(verifyPoint.Multiply(attackersPrivate).Multiply(b)); //cycle through all possible j & u for (int i = 0; i < 2; i++) { for (int l = 0; l < 2; l++) { var j = new BigInteger(i.ToString()); var u = new BigInteger(l.ToString()); var Z2 = Z1.Add(G.Multiply(j).Multiply(h)).Add(attackersPublic.Multiply(u).Multiply(e)).Normalize(); var zX = Z2.AffineXCoord.ToBigInteger().ToByteArray(); var hash = Hash(zX); var kCandidate = new BigInteger(1, hash); var verifyPointCandidate = G.Multiply(kCandidate).Normalize(); var rCandidate = verifyPointCandidate.AffineXCoord.ToBigInteger().Mod(N); if (rCandidate.Equals(r2)) // Gotcha! { return(s2.Multiply(kCandidate).Subtract(m2).Multiply(r2.ModInverse(N)).Mod(N)); } } } return(null); }
// Section 7.2.6 ECVP-NR, pg 35 /** * return true if the value r and s represent a signature for the * message passed in. Generally, the order of the curve should be at * least as long as the hash of the message of interest, and with * ECNR, it *must* be at least as long. But just in case the signer * applied mod(n) to the longer digest, this implementation will * apply mod(n) during verification. * * @param digest the digest to be verified. * @param r the r value of the signature. * @param s the s value of the signature. * @exception DataLengthException if the digest is longer than the key allows */ public bool VerifySignature( byte[] message, BigInteger r, BigInteger s) { if (this.forSigning) { // not properly initilaized... deal with it throw new InvalidOperationException("not initialised for verifying"); } ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key; BigInteger n = pubKey.Parameters.N; int nBitLength = n.BitLength; BigInteger e = new BigInteger(1, message); int eBitLength = e.BitLength; if (eBitLength > nBitLength) { throw new DataLengthException("input too large for ECNR key."); } // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return(false); } // TODO So why is this different from the spec? // s in the range [0,n-1] NB: ECNR spec says 0 if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0) { return(false); } // compute P = sG + rW ECPoint G = pubKey.Parameters.G; ECPoint W = pubKey.Q; // calculate P using Bouncy math ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r); if (P.IsInfinity) { return(false); } BigInteger x = P.X.ToBigInteger(); BigInteger t = r.Subtract(x).Mod(n); return(t.Equals(e)); }
public virtual ECPoint Multiply(ECPoint p, BigInteger k) { int signValue = k.SignValue; if (signValue == 0 || p.IsInfinity) { return(p.Curve.Infinity); } ECPoint eCPoint = MultiplyPositive(p, k.Abs()); ECPoint p2 = (signValue <= 0) ? eCPoint.Negate() : eCPoint; return(ECAlgorithms.ValidatePoint(p2)); }
protected virtual ECPoint CalculateU(SM2KeyExchangePublicParameters otherPub) { ECPoint p1 = otherPub.StaticPublicKey.Q; ECPoint p2 = otherPub.EphemeralPublicKey.Q; BigInteger x1 = Reduce(mEphemeralPubPoint.AffineXCoord.ToBigInteger()); BigInteger x2 = Reduce(p2.AffineXCoord.ToBigInteger()); BigInteger tA = mStaticKey.D.Add(x1.Multiply(mEphemeralKey.D)); BigInteger k1 = mECParams.H.Multiply(tA).Mod(mECParams.N); BigInteger k2 = k1.Multiply(x2).Mod(mECParams.N); return(ECAlgorithms.SumOfTwoMultiplies(p1, k1, p2, k2).Normalize()); }
/** * Checks, if the point multiplication algorithm of the given point yields * the same result as point multiplication done by the reference * implementation given in <code>multiply()</code>. This method tests * multiplication of <code>p</code> by every number of bitlength * <code>numBits</code> or less. * * @param p * The point to be multiplied. * @param numBits * Try every multiplier up to this bitlength */ private void ImplTestMultiplyAll(ECPoint p, int numBits) { BigInteger bound = BigInteger.One.ShiftLeft(numBits); BigInteger k = BigInteger.Zero; do { ECPoint reff = ECAlgorithms.ReferenceMultiply(p, k); ECPoint q = p.Multiply(k); AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q); k = k.Add(BigInteger.One); }while (k.CompareTo(bound) < 0); }
public static ECPoint DeserializeECPoint(byte[] ecPointFormats, ECCurve curve, byte[] encoding) { if (encoding == null || encoding.Length < 1) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } byte actualFormat; switch (encoding[0]) { case 0x02: // compressed case 0x03: // compressed { if (ECAlgorithms.IsF2mCurve(curve)) { actualFormat = ECPointFormat.ansiX962_compressed_char2; } else if (ECAlgorithms.IsFpCurve(curve)) { actualFormat = ECPointFormat.ansiX962_compressed_prime; } else { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } break; } case 0x04: // uncompressed { actualFormat = ECPointFormat.uncompressed; break; } case 0x00: // infinity case 0x06: // hybrid case 0x07: // hybrid default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } if (actualFormat != ECPointFormat.uncompressed && (ecPointFormats == null || !Arrays.Contains(ecPointFormats, actualFormat))) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } return(curve.DecodePoint(encoding)); }
/** * return true if the value r and s represent a GOST3410 signature for * the passed in message (for standard GOST3410 the message should be * a GOST3411 hash of the real message to be verified). */ public virtual bool VerifySignature( byte[] message, BigInteger r, BigInteger s) { if (forSigning) { throw new InvalidOperationException("not initialized for verification"); } 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 e = new BigInteger(1, mRev); BigInteger n = key.Parameters.N; // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return(false); } // s in the range [1,n-1] if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) { return(false); } BigInteger v = e.ModInverse(n); BigInteger z1 = s.Multiply(v).Mod(n); BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n); ECPoint G = key.Parameters.G; // P ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize(); if (point.IsInfinity) { return(false); } BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n); return(R.Equals(r)); }
public static void WriteExplicitECParameters(byte[] ecPointFormats, ECDomainParameters ecParameters, Stream output) { ECCurve curve = ecParameters.Curve; if (ECAlgorithms.IsFpCurve(curve)) { TlsUtilities.WriteUint8(ECCurveType.explicit_prime, output); WriteECParameter(curve.Field.Characteristic, output); } else if (ECAlgorithms.IsF2mCurve(curve)) { IPolynomialExtensionField field = (IPolynomialExtensionField)curve.Field; int[] exponents = field.MinimalPolynomial.GetExponentsPresent(); TlsUtilities.WriteUint8(ECCurveType.explicit_char2, output); int m = exponents[exponents.Length - 1]; TlsUtilities.CheckUint16(m); TlsUtilities.WriteUint16(m, output); if (exponents.Length == 3) { TlsUtilities.WriteUint8(ECBasisType.ec_basis_trinomial, output); WriteECExponent(exponents[1], output); } else if (exponents.Length == 5) { TlsUtilities.WriteUint8(ECBasisType.ec_basis_pentanomial, output); WriteECExponent(exponents[1], output); WriteECExponent(exponents[2], output); WriteECExponent(exponents[3], output); } else { throw new ArgumentException("Only trinomial and pentomial curves are supported"); } } else { throw new ArgumentException("'ecParameters' not a known curve type"); } WriteECFieldElement(curve.A, output); WriteECFieldElement(curve.B, output); TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, ecParameters.G), output); WriteECParameter(ecParameters.N, output); WriteECParameter(ecParameters.H, output); }
public static byte[] SerializeECPoint(byte[] ecPointFormats, ECPoint point) { ECCurve curve = point.Curve; bool compressed = false; if (ECAlgorithms.IsFpCurve(curve)) { compressed = IsCompressionPreferred(ecPointFormats, 1); } else if (ECAlgorithms.IsF2mCurve(curve)) { compressed = IsCompressionPreferred(ecPointFormats, 2); } return(point.GetEncoded(compressed)); }
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) { BigInteger n = key.Parameters.N; if (r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0) { return(false); } BigInteger bigInteger = CalculateE(n, message); BigInteger val = s.ModInverse(n); BigInteger a = bigInteger.Multiply(val).Mod(n); BigInteger b = r.Multiply(val).Mod(n); ECPoint g = key.Parameters.G; ECPoint q = ((ECPublicKeyParameters)key).Q; ECPoint eCPoint = ECAlgorithms.SumOfTwoMultiplies(g, a, q, b); if (eCPoint.IsInfinity) { return(false); } ECCurve curve = eCPoint.Curve; if (curve != null) { BigInteger cofactor = curve.Cofactor; if (cofactor != null && cofactor.CompareTo(Eight) <= 0) { ECFieldElement denominator = GetDenominator(curve.CoordinateSystem, eCPoint); if (denominator != null && !denominator.IsZero) { ECFieldElement xCoord = eCPoint.XCoord; while (curve.IsValidFieldElement(r)) { ECFieldElement eCFieldElement = curve.FromBigInteger(r).Multiply(denominator); if (eCFieldElement.Equals(xCoord)) { return(true); } r = r.Add(n); } return(false); } } } BigInteger bigInteger2 = eCPoint.Normalize().AffineXCoord.ToBigInteger().Mod(n); return(bigInteger2.Equals(r)); }
private void ImplValidityTest(ECCurve c, ECPoint g) { Assert.IsTrue(g.IsValid()); BigInteger h = c.Cofactor; if (h != null && h.CompareTo(BigInteger.One) > 0) { if (ECAlgorithms.IsF2mCurve(c)) { ECPoint order2 = c.CreatePoint(BigInteger.Zero, c.B.Sqrt().ToBigInteger()); ECPoint bad = g.Add(order2); Assert.IsFalse(bad.IsValid()); } } }
// The ECMQV Primitive as described in SEC-1, 3.4 private static ECPoint calculateMqvAgreement( ECDomainParameters parameters, ECPrivateKeyParameters d1U, ECPrivateKeyParameters d2U, ECPublicKeyParameters Q2U, ECPublicKeyParameters Q1V, ECPublicKeyParameters Q2V) { BigInteger n = parameters.N; int e = (n.BitLength + 1) / 2; BigInteger powE = BigInteger.One.ShiftLeft(e); // The Q2U public key is optional ECPoint q; if (Q2U == null) { q = parameters.G.Multiply(d2U.D); } else { q = Q2U.Q; } BigInteger x = q.X.ToBigInteger(); BigInteger xBar = x.Mod(powE); BigInteger Q2UBar = xBar.SetBit(e); BigInteger s = d1U.D.Multiply(Q2UBar).Mod(n).Add(d2U.D).Mod(n); BigInteger xPrime = Q2V.Q.X.ToBigInteger(); BigInteger xPrimeBar = xPrime.Mod(powE); BigInteger Q2VBar = xPrimeBar.SetBit(e); BigInteger hs = parameters.H.Multiply(s).Mod(n); //ECPoint p = Q1V.Q.Multiply(Q2VBar).Add(Q2V.Q).Multiply(hs); ECPoint p = ECAlgorithms.SumOfTwoMultiplies( Q1V.Q, Q2VBar.Multiply(hs).Mod(n), Q2V.Q, hs); if (p.IsInfinity) { throw new InvalidOperationException("Infinity is not a valid agreement value for MQV"); } return(p); }
public static void WriteExplicitECParameters(byte[] ecPointFormats, ECDomainParameters ecParameters, Stream output) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) ECCurve curve = ecParameters.Curve; if (ECAlgorithms.IsFpCurve(curve)) { TlsUtilities.WriteUint8(1, output); WriteECParameter(curve.Field.Characteristic, output); } else { if (!ECAlgorithms.IsF2mCurve(curve)) { throw new ArgumentException("'ecParameters' not a known curve type"); } IPolynomialExtensionField polynomialExtensionField = (IPolynomialExtensionField)curve.Field; int[] exponentsPresent = polynomialExtensionField.MinimalPolynomial.GetExponentsPresent(); TlsUtilities.WriteUint8(2, output); int i = exponentsPresent[exponentsPresent.Length - 1]; TlsUtilities.CheckUint16(i); TlsUtilities.WriteUint16(i, output); if (exponentsPresent.Length == 3) { TlsUtilities.WriteUint8(1, output); WriteECExponent(exponentsPresent[1], output); } else { if (exponentsPresent.Length != 5) { throw new ArgumentException("Only trinomial and pentomial curves are supported"); } TlsUtilities.WriteUint8(2, output); WriteECExponent(exponentsPresent[1], output); WriteECExponent(exponentsPresent[2], output); WriteECExponent(exponentsPresent[3], output); } } WriteECFieldElement(curve.A, output); WriteECFieldElement(curve.B, output); TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, ecParameters.G), output); WriteECParameter(ecParameters.N, output); WriteECParameter(ecParameters.H, output); }
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) { BigInteger n = this.key.Parameters.N; if (((r.SignValue < 1) || (s.SignValue < 1)) || ((r.CompareTo(n) >= 0) || (s.CompareTo(n) >= 0))) { return(false); } BigInteger integer2 = this.CalculateE(n, message); BigInteger val = s.ModInverse(n); BigInteger a = integer2.Multiply(val).Mod(n); BigInteger b = r.Multiply(val).Mod(n); ECPoint g = this.key.Parameters.G; ECPoint q = ((ECPublicKeyParameters)this.key).Q; ECPoint p = ECAlgorithms.SumOfTwoMultiplies(g, a, q, b); if (p.IsInfinity) { return(false); } ECCurve curve = p.Curve; if (curve != null) { BigInteger cofactor = curve.Cofactor; if ((cofactor != null) && (cofactor.CompareTo(Eight) <= 0)) { ECFieldElement denominator = this.GetDenominator(curve.CoordinateSystem, p); if ((denominator != null) && !denominator.IsZero) { ECFieldElement xCoord = p.XCoord; while (curve.IsValidFieldElement(r)) { if (curve.FromBigInteger(r).Multiply(denominator).Equals(xCoord)) { return(true); } r = r.Add(n); } return(false); } } } return(p.Normalize().AffineXCoord.ToBigInteger().Mod(n).Equals(r)); }
public virtual ECPoint Multiply(ECPoint p, BigInteger k) { int sign = k.SignValue; if (sign == 0 || p.IsInfinity) { return(p.Curve.Infinity); } ECPoint positive = MultiplyPositive(p, k.Abs()); ECPoint result = sign > 0 ? positive : positive.Negate(); /* * Although the various multipliers ought not to produce invalid output under normal * circumstances, a final check here is advised to guard against fault attacks. */ return(ECAlgorithms.ValidatePoint(result)); }
private bool VerifySignature(BigInteger r, BigInteger s) { BigInteger n = ecParams.N; // 5.3.1 Draft RFC: SM2 Public Key Algorithms // B1 if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return(false); } // B2 if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) { return(false); } // B3 byte[] eHash = DigestUtilities.DoFinal(digest); // B4 BigInteger e = CalculateE(n, eHash); // B5 BigInteger t = r.Add(s).Mod(n); if (t.SignValue == 0) { return(false); } // B6 ECPoint q = ((ECPublicKeyParameters)ecKey).Q; ECPoint x1y1 = ECAlgorithms.SumOfTwoMultiplies(ecParams.G, s, q, t).Normalize(); if (x1y1.IsInfinity) { return(false); } // B7 return(r.Equals(e.Add(x1y1.AffineXCoord.ToBigInteger()).Mod(n))); }
private void ImplValidityTest(ECCurve c, ECPoint g) { Assert.IsTrue(g.IsValid()); if (ECAlgorithms.IsF2mCurve(c)) { BigInteger h = c.Cofactor; if (null != h) { if (!h.TestBit(0)) { ECFieldElement sqrtB = c.B.Sqrt(); ECPoint order2 = c.CreatePoint(BigInteger.Zero, sqrtB.ToBigInteger()); Assert.IsTrue(order2.Twice().IsInfinity); Assert.IsFalse(order2.IsValid()); ECPoint bad2 = g.Add(order2); Assert.IsFalse(bad2.IsValid()); ECPoint good2 = bad2.Add(order2); Assert.IsTrue(good2.IsValid()); if (!h.TestBit(1)) { ECFieldElement L = SolveQuadraticEquation(c, c.A); Assert.IsNotNull(L); ECFieldElement T = sqrtB; ECFieldElement x = T.Sqrt(); ECFieldElement y = T.Add(x.Multiply(L)); ECPoint order4 = c.CreatePoint(x.ToBigInteger(), y.ToBigInteger()); Assert.IsTrue(order4.Twice().Equals(order2)); Assert.IsFalse(order4.IsValid()); ECPoint bad4_1 = g.Add(order4); Assert.IsFalse(bad4_1.IsValid()); ECPoint bad4_2 = bad4_1.Add(order4); Assert.IsFalse(bad4_2.IsValid()); ECPoint bad4_3 = bad4_2.Add(order4); Assert.IsFalse(bad4_3.IsValid()); ECPoint good4 = bad4_3.Add(order4); Assert.IsTrue(good4.IsValid()); } } } } }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { if (!this.curve.Equals(p.Curve)) { throw new InvalidOperationException(); } BigInteger order = p.Curve.Order; BigInteger[] array = this.glvEndomorphism.DecomposeScalar(k.Mod(order)); BigInteger k2 = array[0]; BigInteger l = array[1]; ECPointMap pointMap = this.glvEndomorphism.PointMap; if (this.glvEndomorphism.HasEfficientPointMap) { return(ECAlgorithms.ImplShamirsTrickWNaf(p, k2, pointMap, l)); } return(ECAlgorithms.ImplShamirsTrickWNaf(p, k2, pointMap.Map(p), l)); }
public static ECKey RecoverFromSignature(int rec_id, ECDSASignature signautre, byte[] message, bool compressed) { if (rec_id < 0) throw new ArgumentException("rec_id must be positive"); if (signautre.R.SignValue < 0) throw new ArgumentException("ECDSASignature R must be positive"); if (signautre.S.SignValue < 0) throw new ArgumentException("ECDSASignature S must be positive"); if (message == null) throw new ArgumentNullException("Recovery signature message is null"); var curve = Secp256k1; var n = curve.N; var i = BigInteger.ValueOf((long)rec_id / 2); var x = signautre.R.Add(i.Multiply(n)); var prime = new BigInteger(1, Org.BouncyCastle.Utilities.Encoders.Hex.Decode( "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")); if (x.CompareTo(prime) >= 0) return null; var R = DecompressKey(x, (rec_id & 1) == 1); if (!R.Multiply(n).IsInfinity) return null; var e = new BigInteger(1, message); var e_inv = BigInteger.Zero.Subtract(e).Mod(n); var r_inv = signautre.R.ModInverse(n); var sr_inv = r_inv.Multiply(signautre.S).Mod(n); var e_invr_inv = r_inv.Multiply(e_inv).Mod(n); var q = ECAlgorithms.SumOfTwoMultiplies(curve.G, e_invr_inv, R, sr_inv); q = q.Normalize(); if (compressed) { q = Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()); return new ECKey(q.GetEncoded(true), false); } return new ECKey(q.GetEncoded(), false); }
/** * Recover the public key from signature and message. * @param recId recovery id which 0 or 1. * @param sig {@link ECDSASignature} a signature object * @param message message bytes array. * @return public key represented by {@link BigInteger} */ public static BigInteger RecoverFromSignature(int recId, ECDSASignature sig, byte[] message) { if (!(recId == 0 || recId == 1)) { throw new ArgumentOutOfRangeException(nameof(recId), "recId must be 0 or 1"); } if (message == null) { throw new ArgumentNullException(nameof(message), "message cannot be null"); } BigInteger n = ECKeyPair.Curve.N; // Curve order. BigInteger i = BigInteger.ValueOf((long)recId / 2); BigInteger x = sig.R.Add(i.Multiply(n)); // TODO SecP256K1Curve //BigInteger prime = SecP256K1Curve.q; //if (x.CompareTo(prime) >= 0) //{ // return null; //} ECPoint R = DecompressKey(x, (recId & 1) == 1); if (!R.Multiply(n).IsInfinity) { return(null); } BigInteger e = new BigInteger(1, message); BigInteger eInv = BigInteger.Zero.Subtract(e).Mod(n); BigInteger rInv = sig.R.ModInverse(n); BigInteger srInv = rInv.Multiply(sig.S).Mod(n); BigInteger eInvrInv = rInv.Multiply(eInv).Mod(n); ECPoint q = ECAlgorithms.SumOfTwoMultiplies(ECKeyPair.Curve.G, eInvrInv, R, srInv); byte[] qBytes = q.GetEncoded(false); // We remove the prefix return(new BigInteger(1, Arrays.CopyOfRange(qBytes, 1, qBytes.Length))); }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { if (!this.curve.Equals(p.Curve)) { throw new InvalidOperationException(); } var n = p.Curve.Order; var ab = this.glvEndomorphism.DecomposeScalar(k.Mod(n)); BigInteger a = ab[0], b = ab[1]; var pointMap = this.glvEndomorphism.PointMap; if (this.glvEndomorphism.HasEfficientPointMap) { return(ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap, b)); } return(ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap.Map(p), b)); }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!curve.Equals(p.Curve)) { throw new InvalidOperationException(); } BigInteger order = p.Curve.Order; BigInteger[] array = glvEndomorphism.DecomposeScalar(k.Mod(order)); BigInteger k2 = array[0]; BigInteger l = array[1]; ECPointMap pointMap = glvEndomorphism.PointMap; if (glvEndomorphism.HasEfficientPointMap) { return(ECAlgorithms.ImplShamirsTrickWNaf(p, k2, pointMap, l)); } return(ECAlgorithms.ImplShamirsTrickWNaf(p, k2, pointMap.Map(p), l)); }
public X9Curve(ECCurve curve, byte[] seed) { if (curve == null) { throw new ArgumentNullException("curve"); } this.curve = curve; this.seed = Arrays.Clone(seed); if (ECAlgorithms.IsFpCurve(curve)) { this.fieldIdentifier = X9ObjectIdentifiers.PrimeField; return; } if (ECAlgorithms.IsF2mCurve(curve)) { this.fieldIdentifier = X9ObjectIdentifiers.CharacteristicTwoField; return; } throw new ArgumentException("This type of ECCurve is not implemented"); }
private ECPoint CalculatePoint(ECPublicKeyParameters pubKeyParams) { ECDomainParameters dp = keyParam.Parameters; if (!dp.Equals(pubKeyParams.Parameters)) { throw new InvalidOperationException( "ECDH public key has wrong domain parameters" ); } BigInteger d = keyParam.D; ECPoint q = dp.Curve.DecodePoint(pubKeyParams.Q.GetEncoded(true)); if (q.IsInfinity) { throw new InvalidOperationException( "Infinity is not a valid public key for ECDH" ); } BigInteger h = dp.H; if (!h.Equals(BigInteger.One)) { d = dp.H.ModInverse(dp.N).Multiply(d).Mod(dp.N); q = ECAlgorithms.ReferenceMultiply(q, h); } ECPoint p = q.Multiply(d).Normalize(); if (p.IsInfinity) { throw new InvalidOperationException( "Infinity is not a valid agreement value for ECDH" ); } return(p); }
internal static ECPoint Validate(ECCurve c, ECPoint q) { if (q == null) { throw new ArgumentException("Point has null value", "q"); } q = ECAlgorithms.ImportPoint(c, q).Normalize(); if (q.IsInfinity) { throw new ArgumentException("Point at infinity", "q"); } if (!q.IsValid()) { throw new ArgumentException("Point not on curve", "q"); } return(q); }
internal static ECPoint ValidatePublicPoint(ECCurve c, ECPoint q) { if (null == q) { throw new ArgumentNullException("q", "Point cannot be null"); } q = ECAlgorithms.ImportPoint(c, q).Normalize(); if (q.IsInfinity) { throw new ArgumentException("Point at infinity", "q"); } if (!q.IsValid()) { throw new ArgumentException("Point not on curve", "q"); } return(q); }