private static ECPoint ImplShamirsTrick(ECPoint p, IBigInteger k, ECPoint q, IBigInteger l) { var m = System.Math.Max(k.BitLength, l.BitLength); var z = p.Add(q); var r = p.Curve.Infinity; for (var i = m - 1; i >= 0; --i) { r = r.Twice(); if (k.TestBit(i)) { r = r.Add(l.TestBit(i) ? z : p); } else { if (l.TestBit(i)) { r = r.Add(q); } } } return r; }
public void TestSumOfTwoMultiplies() { foreach (X9ECParameters x9 in GetTestCurves()) { ECPoint p = GetRandomPoint(x9); BigInteger a = GetRandomScalar(x9); for (int i = 0; i < SCALE; ++i) { ECPoint q = GetRandomPoint(x9); BigInteger b = GetRandomScalar(x9); ECPoint u = p.Multiply(a).Add(q.Multiply(b)); ECPoint v = ECAlgorithms.ShamirsTrick(p, a, q, b); ECPoint w = ECAlgorithms.SumOfTwoMultiplies(p, a, q, b); ECPoint[] results = new ECPoint[] { u, v, w }; x9.Curve.NormalizeAll(results); AssertPointsEqual("ECAlgorithms.ShamirsTrick is incorrect", results[0], results[1]); AssertPointsEqual("ECAlgorithms.SumOfTwoMultiplies is incorrect", results[0], results[2]); p = q; a = b; } } }
public void TestSumOfMultiplies() { foreach (X9ECParameters x9 in GetTestCurves()) { ECPoint[] points = new ECPoint[SCALE]; BigInteger[] scalars = new BigInteger[SCALE]; for (int i = 0; i < SCALE; ++i) { points[i] = GetRandomPoint(x9); scalars[i] = GetRandomScalar(x9); } ECPoint u = x9.Curve.Infinity; for (int i = 0; i < SCALE; ++i) { u = u.Add(points[i].Multiply(scalars[i])); ECPoint v = ECAlgorithms.SumOfMultiplies(CopyPoints(points, i + 1), CopyScalars(scalars, i + 1)); ECPoint[] results = new ECPoint[] { u, v }; x9.Curve.NormalizeAll(results); AssertPointsEqual("ECAlgorithms.SumOfMultiplies is incorrect", results[0], results[1]); } } }
protected ECPublicBcpgKey( DerObjectIdentifier oid, ECPoint point) { this.point = new BigInteger(1, point.GetEncoded()); this.oid = oid; }
/* * "Shamir's Trick", originally due to E. G. Straus * (Addition chains of vectors. American Mathematical Monthly, * 71(7):806-808, Aug./Sept. 1964) * * Input: The points P, Q, scalar k = (km?, ... , k1, k0) * and scalar l = (lm?, ... , l1, l0). * Output: R = k * P + l * Q. * 1: Z <- P + Q * 2: R <- O * 3: for i from m-1 down to 0 do * 4: R <- R + R {point doubling} * 5: if (ki = 1) and (li = 0) then R <- R + P end if * 6: if (ki = 0) and (li = 1) then R <- R + Q end if * 7: if (ki = 1) and (li = 1) then R <- R + Z end if * 8: end for * 9: return R */ public static ECPoint ShamirsTrick(ECPoint p, BigInteger k, ECPoint q, BigInteger l) { if (!p.Curve.Equals(q.Curve)) throw new ArgumentException("P and Q must be on same curve"); return ImplShamirsTrick(p, k, q, l); }
/// <summary> /// Initializes a new instance of the <see cref="ECDHPublicKeyParameters" /> class. /// </summary> /// <param name="q">The q.</param> /// <param name="parameters">The parameters.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> public ECDHPublicKeyParameters(ECPoint q, ECDomainParameters parameters, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : base("ECDH", q, parameters) { this.HashAlgorithm = hashAlgorithm; this.SymmetricKeyAlgorithm = symmetricKeyAlgorithm; }
private static ECPoint ImplShamirsTrick(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { int m = System.Math.Max(k.BitLength, l.BitLength); ECPoint Z = P.Add(Q); ECPoint R = P.Curve.Infinity; for (int i = m - 1; i >= 0; --i) { R = R.Twice(); if (k.TestBit(i)) { if (l.TestBit(i)) { R = R.Add(Z); } else { R = R.Add(P); } } else { if (l.TestBit(i)) { R = R.Add(Q); } } } return R; }
/// <summary> /// Computes the public key from the private key. /// </summary> protected override byte[] ComputePublicKey() { var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1"); Org.BouncyCastle.Math.EC.ECPoint point = ps.G; Org.BouncyCastle.Math.BigInteger Db = new Org.BouncyCastle.Math.BigInteger(1, _privKey); Org.BouncyCastle.Math.EC.ECPoint dd = point.Multiply(Db); if (IsCompressedPoint) { dd = ps.Curve.CreatePoint(dd.X.ToBigInteger(), dd.Y.ToBigInteger(), true); return(dd.GetEncoded()); } else { byte[] pubaddr = new byte[65]; byte[] Y = dd.Y.ToBigInteger().ToByteArray(); Array.Copy(Y, 0, pubaddr, 64 - Y.Length + 1, Y.Length); byte[] X = dd.X.ToBigInteger().ToByteArray(); Array.Copy(X, 0, pubaddr, 32 - X.Length + 1, X.Length); pubaddr[0] = 4; return(pubaddr); } }
protected void SetVerifier(ECPoint pub) { Verifier = new ECDsaSigner(); ECPublicKeyParameters parameters = new ECPublicKeyParameters( pub, Secp256K1.Parameters()); Verifier.Init(false, parameters); }
public static ECPoint SumOfMultiplies(ECPoint[] ps, BigInteger[] ks) { if (ps == null || ks == null || ps.Length != ks.Length || ps.Length < 1) throw new ArgumentException("point and scalar arrays should be non-null, and of equal, non-zero, length"); int count = ps.Length; switch (count) { case 1: return ps[0].Multiply(ks[0]); case 2: return SumOfTwoMultiplies(ps[0], ks[0], ps[1], ks[1]); default: break; } ECPoint p = ps[0]; ECCurve c = p.Curve; ECPoint[] imported = new ECPoint[count]; imported[0] = p; for (int i = 1; i < count; ++i) { imported[i] = ImportPoint(c, ps[i]); } GlvEndomorphism glvEndomorphism = c.GetEndomorphism() as GlvEndomorphism; if (glvEndomorphism != null) { return ImplSumOfMultipliesGlv(imported, ks, glvEndomorphism); } return ImplSumOfMultiplies(imported, ks); }
public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n) : this(curve, g, n, BigInteger.One, null) { }
public bool VerifySignature(byte[] message, byte[] signature, byte[] pubkey) { if (pubkey.Length == 33 && (pubkey[0] == 0x02 || pubkey[0] == 0x03)) { try { pubkey = ECPoint.DecodePoint(pubkey, ECCurve.Secp256r1).EncodePoint(false).Skip(1).ToArray(); } catch { return false; } } else if (pubkey.Length == 65 && pubkey[0] == 0x04) { pubkey = pubkey.Skip(1).ToArray(); } else if (pubkey.Length != 64) { throw new ArgumentException(); } BigInteger x = new BigInteger(1, pubkey.Take(32).ToArray()); BigInteger y = new BigInteger(1, pubkey.Skip(32).ToArray()); X9ECParameters ecParams = NistNamedCurves.GetByName("P-256"); ECDomainParameters domainParameters = new ECDomainParameters(ecParams.Curve, ecParams.G, ecParams.N, ecParams.H, ecParams.GetSeed()); var G = ecParams.G; Org.BouncyCastle.Math.EC.ECCurve curve = ecParams.Curve; Org.BouncyCastle.Math.EC.ECPoint q = curve.CreatePoint(x, y); ECPublicKeyParameters pubkeyParam = new ECPublicKeyParameters(q, domainParameters); var verifier = SignerUtilities.GetSigner("SHA-256withECDSA"); verifier.Init(false, pubkeyParam); verifier.BlockUpdate(message, 0, message.Length); // expected format is SEQUENCE {INTEGER r, INTEGER s} var derSignature = new DerSequence( // first 32 bytes is "r" number new DerInteger(new BigInteger(1, signature.Take(32).ToArray())), // last 32 bytes is "s" number new DerInteger(new BigInteger(1, signature.Skip(32).ToArray()))) .GetDerEncoded(); ///old verify method /// /* const int ECDSA_PUBLIC_P256_MAGIC = 0x31534345; pubkey = BitConverter.GetBytes(ECDSA_PUBLIC_P256_MAGIC).Concat(BitConverter.GetBytes(32)).Concat(pubkey).ToArray(); using (CngKey key = CngKey.Import(pubkey, CngKeyBlobFormat.EccPublicBlob)) using (ECDsaCng ecdsa = new ECDsaCng(key)) { var result = ecdsa.VerifyData(message, signature, HashAlgorithmName.SHA256); } */ /////////////////// return verifier.VerifySignature(derSignature); }
public ECDomainParameters( ECCurve curve, ECPoint g, BigInteger n) : this(curve, g, n, BigInteger.One) { }
/** * @param privateKey hex string without 0x * @return */ public static string GetPublicKeyFromPrivateKey(string privateKey, bool compressed) { BigInteger bigInteger = new BigInteger(privateKey, 16); ECPoint point = GetPublicPointFromPrivate(bigInteger); return(ByteUtil.ByteArrayToHexString(point.GetEncoded(compressed))); }
/// <summary> /// Initializes a new instance of the <see cref="ECDHPublicKeyParameters" /> class. /// </summary> /// <param name="q">The q.</param> /// <param name="publicKeyParamSet">The public key param set.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> public ECDHPublicKeyParameters(ECPoint q, DerObjectIdentifier publicKeyParamSet, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : base("ECDH", q, publicKeyParamSet) { this.HashAlgorithm = hashAlgorithm; this.SymmetricKeyAlgorithm = symmetricKeyAlgorithm; }
public ECPublicKeyParameters(string algorithm, ECPoint q, DerObjectIdentifier publicKeyParamSet) : base(algorithm, false, publicKeyParamSet) { if (q == null) throw new ArgumentNullException("q"); _q = q; }
public ECPublicKeyParameters(string algorithm, ECPoint q, ECDomainParameters parameters) : base(algorithm, false, parameters) { if (q == null) throw new ArgumentNullException("q"); _q = q; }
public ECPublicKeyParameters(ECPoint q, DerObjectIdentifier publicKeyParamSet) : base("ECGOST3410", false, publicKeyParamSet) { if (q == null) throw new ArgumentNullException("q"); _q = q; }
public static byte[] CreateKey(PublicKeyPacket pubKeyData, ECPoint s) { byte[] userKeyingMaterial = CreateUserKeyingMaterial(pubKeyData); ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)pubKeyData.Key; return Kdf(ecKey.HashAlgorithm, s, GetKeyLength(ecKey.SymmetricKeyAlgorithm), userKeyingMaterial); }
static Secp256K1Curve() { X9ECParameters parameters = SecNamedCurves.GetByName("secp256k1"); g = parameters.G; n = parameters.N; fieldSize = ((FpCurve)parameters.Curve).Q; groupSize = parameters.N; }
public X9ECParameters( ECCurve curve, ECPoint g, IBigInteger n, IBigInteger h) : this(curve, g, n, h, null) { }
public ECDomainParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h) : this(curve, g, n, h, null) { }
public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h, byte[] seed) : this(curve, new X9ECPoint(g), n, h, seed) { }
public static byte[] PubKeyToByteArray(ECPoint point) { byte[] pubaddr = new byte[65]; byte[] Y = point.Y.ToBigInteger().ToByteArray(); Array.Copy(Y, 0, pubaddr, 64 - Y.Length + 1, Y.Length); byte[] X = point.X.ToBigInteger().ToByteArray(); Array.Copy(X, 0, pubaddr, 32 - X.Length + 1, X.Length); pubaddr[0] = 4; return(pubaddr); }
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); }
/* * "Shamir's Trick", originally due to E. G. Straus * (Addition chains of vectors. American Mathematical Monthly, * 71(7):806–808, Aug./Sept. 1964) * * Input: The points P, Q, scalar k = (km?, ... , k1, k0) * and scalar l = (lm?, ... , l1, l0). * Output: R = k * P + l * Q. * 1: Z <- P + Q * 2: R <- O * 3: for i from m-1 down to 0 do * 4: R <- R + R {point doubling} * 5: if (ki = 1) and (li = 0) then R <- R + P end if * 6: if (ki = 0) and (li = 1) then R <- R + Q end if * 7: if (ki = 1) and (li = 1) then R <- R + Z end if * 8: end for * 9: return R */ public static ECPoint ShamirsTrick( ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { if (!P.Curve.Equals(Q.Curve)) throw new ArgumentException("P and Q must be on same curve"); return ImplShamirsTrick(P, k, Q, l); }
/// <summary> /// Initializes a new instance of the <see cref="ECDHPublicBcpgKey"/> class. /// </summary> /// <param name="point">The point.</param> /// <param name="oid">The oid.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> public ECDHPublicBcpgKey(ECPoint point, DerObjectIdentifier oid, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : base(point, oid) { _reserved = 1; _hashFunctionId = (byte)hashAlgorithm; _symAlgorithmId = (byte)symmetricKeyAlgorithm; this.VerifyHashAlgorithm(); this.VerifySymmetricKeyAlgorithm(); }
public X9ECParameters ( ECCurve curve, ECPoint g, BigInteger n, BigInteger h, byte[] seed) { this.curve = curve; this.g = g; this.n = n; this.h = h; this.seed = seed; }
public ECDHPublicBcpgKey( DerObjectIdentifier oid, ECPoint point, int hashAlgorithm, int symmetricKeyAlgorithm) : base(oid, point) { reserved = 1; hashFunctionId = (byte)hashAlgorithm; symAlgorithmId = (byte)symmetricKeyAlgorithm; VerifyHashAlgorithm(); VerifySymmetricKeyAlgorithm(); }
public static string PrivHexToPubHex(string PrivHex, ECPoint point) { byte[] hex = ValidateAndGetHexPrivateKey(0x00, PrivHex, 33); if (hex == null) { throw new ApplicationException("Invalid private hex key"); } Org.BouncyCastle.Math.BigInteger Db = new Org.BouncyCastle.Math.BigInteger(hex); ECPoint dd = point.Multiply(Db); byte[] pubaddr = PubKeyToByteArray(dd); return(ByteArrayToString(pubaddr)); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve cp = P.Curve; Q = ImportPoint(cp, Q); // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick if (cp is F2mCurve) { F2mCurve f2mCurve = (F2mCurve) cp; if (f2mCurve.IsKoblitz) { return P.Multiply(a).Add(Q.Multiply(b)); } } return ImplShamirsTrickWNaf(P, a, Q, b); }
public ECDomainParameters(ECCurve curve, ECPoint g, IBigInteger n, IBigInteger h, byte[] seed) { if (curve == null) throw new ArgumentNullException("curve"); if (g == null) throw new ArgumentNullException("g"); if (n == null) throw new ArgumentNullException("n"); if (h == null) throw new ArgumentNullException("h"); _curve = curve; _g = g; _n = n; _h = h; _seed = Arrays.Clone(seed); }
//public static bool VerifySignature(AsymmetricKeyParameter pubKey, string signature, string msg) //{ // try // { // byte[] msgBytes = Encoding.UTF8.GetBytes(msg); // byte[] sigBytes = Convert.FromBase64String(signature); // ISigner signer = SignerUtilities.GetSigner("SHA384withECDSA"); // signer.Init(false, pubKey); // signer.BlockUpdate(msgBytes, 0, msgBytes.Length); // return signer.VerifySignature(sigBytes); // } // catch (Exception exc) // { // Console.WriteLine("Verification failed with the error: " + exc.ToString()); // return false; // } //} /// <summary> /// NOT WORKING cause of SHA 256 /// </summary> /// <param name="pubK"></param> /// <returns></returns> //public static AsymmetricKeyParameter GetPublicKeyObjectRepresentation(string pubK) //{ // //byte[] recoveredPublic = Convert.FromBase64String(pubK); // byte[] recoveredPublic = Base58Encoding.Decode(pubK); // var publicKey = PublicKeyFactory.CreateKey(recoveredPublic); // return publicKey; //} //public static string GetPublicKeyStringRepresentation(AsymmetricKeyParameter pubK) //{ // SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubK); // byte[] serializedPublicBytes = subjectPublicKeyInfo.ToAsn1Object().GetDerEncoded(); // var base64 = Convert.ToBase64String(serializedPublicBytes); // var sha256 = ComputeSha256HashB(base64); // var result = Base58Encoding.Encode(sha256); // return result; //} /// <summary> /// Not gonna be used /// </summary> /// <param name="priK"></param> /// <returns></returns> //public static string GetPrivateKeyStringRepresentation(AsymmetricKeyParameter priK) //{ // PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(priK); // byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetDerEncoded(); // //var result = Convert.ToBase64String(serializedPrivateBytes); // var result = Base58Encoding.Encode(serializedPrivateBytes); // return result; //} //private static string ComputeSha256Hash(string rawData) //{ // // Create a SHA256 // using (SHA256 sha256Hash = SHA256.Create()) // { // // ComputeHash - returns byte array // byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData)); // // Convert byte array to a string // StringBuilder builder = new StringBuilder(); // for (int i = 0; i < bytes.Length; i++) // { // builder.Append(bytes[i].ToString("x2")); // } // return builder.ToString(); // } //} /** * Converts a private key into its corresponding public key. */ public static byte[] GetPublicKey(byte[] privateKey) { try { //ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1"); X9ECParameters spec = ECNamedCurveTable.GetByName("secp256k1"); ECPoint pointQ = spec.G.Multiply(new BigInteger(1, privateKey)); return(pointQ.GetEncoded(false)); } catch (Exception e) { Console.WriteLine(" Failed: GET public key"); return(new byte[0]); } }
public X9ECParameters( Asn1Sequence seq) { if (!(seq[0] is DerInteger) || !((DerInteger) seq[0]).Value.Equals(BigInteger.One)) { throw new ArgumentException("bad version in X9ECParameters"); } X9Curve x9c = null; if (seq[2] is X9Curve) { x9c = (X9Curve) seq[2]; } else { x9c = new X9Curve( new X9FieldID( (Asn1Sequence) seq[1]), (Asn1Sequence) seq[2]); } this.curve = x9c.Curve; if (seq[3] is X9ECPoint) { this.g = ((X9ECPoint) seq[3]).Point; } else { this.g = new X9ECPoint(curve, (Asn1OctetString) seq[3]).Point; } this.n = ((DerInteger) seq[4]).Value; this.seed = x9c.GetSeed(); if (seq.Count == 6) { this.h = ((DerInteger) seq[5]).Value; } else { this.h = BigInteger.One; } }
public SymmetricKey ExchangeKey(PublicKey publicKey) { ECPoint p = CalculatePoint(publicKey.KeyParam); BigInteger x = p.AffineXCoord.ToBigInteger(); BigInteger y = p.AffineYCoord.ToBigInteger(); byte[] xbuf = x.ToByteArrayUnsigned(); var ybuf = new byte[] { (byte)(y.TestBit(0) ? 0x03 : 0x02) }; var hash = new Sha256Digest(); var result = new byte[hash.GetDigestSize()]; hash.BlockUpdate(ybuf, 0, ybuf.Length); hash.BlockUpdate(xbuf, 0, xbuf.Length); hash.DoFinal(result, 0); return(new SymmetricKey(result)); }
public static ECPoint SumOfTwoMultiplies(ECPoint p, IBigInteger a, ECPoint q, IBigInteger b) { var c = p.Curve; if (!c.Equals(q.Curve)) throw new ArgumentException("P and Q must be on same curve"); // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick var f2MCurve = c as F2MCurve; if (f2MCurve != null) { if (f2MCurve.IsKoblitz) { return p.Multiply(a).Add(q.Multiply(b)); } } return ImplShamirsTrick(p, a, q, b); }
public string GetSign(byte[] msg) { //Org.BouncyCastle.Math.BigInteger d = new Org.BouncyCastle.Math.BigInteger(Convert.FromBase64String(privKey)); byte[] prvB = StringToByteArray(prv); byte[] pubB = StringToByteArray(pub); //byte[] prvB = StringToByteArray(prvTmp); //byte[] pubB = StringToByteArray(pubTmp); Org.BouncyCastle.Math.BigInteger sk = new Org.BouncyCastle.Math.BigInteger(+1, prvB); Org.BouncyCastle.Math.EC.ECPoint q = domain.G.Multiply(sk); byte[] pubKeyX = q.Normalize().AffineXCoord.GetEncoded(); byte[] pubKeyY = q.Normalize().AffineYCoord.GetEncoded(); BigInteger k = GenerateRandom(); //BigInteger k = new BigInteger(+1,StringToByteArray("015B931D9C7BF3A7A70E57868BF29712377E74355FC59032CD7547C80E179010")); //Debug.Log("kv:" + BitConverter.ToString(kv.ToByteArray()).Replace("-", "")); Debug.Log("K:" + BitConverter.ToString(k.ToByteArray()).Replace("-", "")); ECPoint Q = domain.G.Multiply(k); Org.BouncyCastle.Crypto.Digests.Sha256Digest digester = new Org.BouncyCastle.Crypto.Digests.Sha256Digest(); byte[] h = new byte[digester.GetDigestSize()]; digester.BlockUpdate(Q.GetEncoded(true), 0, Q.GetEncoded(true).Length); digester.BlockUpdate(pubB, 0, pubB.Length); digester.BlockUpdate(msg, 0, msg.Length); digester.DoFinal(h, 0); Org.BouncyCastle.Math.BigInteger r = new Org.BouncyCastle.Math.BigInteger(+1, h); BigInteger s = r.Multiply(sk); s = k.Subtract(s); s = s.Mod(domain.n); string rt = BitConverter.ToString(r.ToByteArray()).Replace("-", ""); if (rt.Length > 32) { rt = rt.Remove(0, 2); } string st = BitConverter.ToString(s.ToByteArray()).Replace("-", ""); return(rt + st); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve c = P.Curve; if (!c.Equals(Q.Curve)) throw new ArgumentException("P and Q must be on same curve"); // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick if (c is F2mCurve) { F2mCurve f2mCurve = (F2mCurve) c; if (f2mCurve.IsKoblitz) { return P.Multiply(a).Add(Q.Multiply(b)); } } return ImplShamirsTrick(P, a, Q, b); }
public string GetPublicKey(byte[] privKey) { var privHex = BitConverter.ToString(privKey).Replace("-", ""); privHex = privHex.Substring(104, (privHex.Length - 104)); privKey = StringToByteArray(privHex); Org.BouncyCastle.Math.BigInteger d = new Org.BouncyCastle.Math.BigInteger(privKey); this.privateKeyParameters = new Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters(d, domain); Org.BouncyCastle.Math.EC.ECPoint q = domain.G.Multiply(d); this.pubKeyParameters = new Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters(q, domain); //strip first byte var pubBytes = this.pubKeyParameters.Q.GetEncoded(); var pubHex = BitConverter.ToString(pubBytes).Replace("-", ""); var strippedPubBytes = StringToByteArray(pubHex.Substring(2, (pubHex.Length - 2))); return("MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE" + Convert.ToBase64String(strippedPubBytes)); }
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); }
public ECDomainParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h, byte[] seed) { if (curve == null) throw new ArgumentNullException("curve"); if (g == null) throw new ArgumentNullException("g"); if (n == null) throw new ArgumentNullException("n"); if (h == null) throw new ArgumentNullException("h"); this.curve = curve; this.g = g; this.n = n; this.h = h; this.seed = Arrays.Clone(seed); }
/// <summary> /// Hashes a seed t into a point T on the curve. Returns null if t is unsuitable. /// </summary> /// <param name="curve">The elliptic curve in Weierstrass form</param> /// <param name="t">The seed</param> /// <returns>A random point T uniquely determined by seed t, otherwise null</returns> public static ECPoint?HashToWeierstrassCurve(ECCurve curve, byte[] t) { ECFieldElement x, ax, x3, y, y2; BigInteger P = curve.Field.Characteristic; SHA256? sha256 = SHA256.Create(); BigInteger hash = new BigInteger(sha256.ComputeHash(t)); // Check that the hash is within valid range if (hash.CompareTo(BigInteger.One) < 0 || hash.CompareTo(P) >= 0) { return(null); } // A valid point (x,y) must satisfy: y^2 = x^3 + Ax + B mod P // Convert hash from BigInt to FieldElement x modulo P x = curve.FromBigInteger(hash); // x ax = x.Multiply(curve.A); // Ax x3 = x.Square().Multiply(x); // x^3 = x^2 * x y2 = x3.Add(ax).Add(curve.B); // y^2 = x^3 + Ax + B y = y2.Sqrt(); // y = sqrt(x^3 + Ax + B) // y == null if square root mod P does not exist if (y == null) { return(null); } ECPoint T = curve.CreatePoint(x.ToBigInteger(), y.ToBigInteger()); // Use the built-in point validator, which also checks for membership // in weak subgroups if (!T.IsValid()) { return(null); } return(T); }
/// <summary> /// Used by the token service. Signs the point submitted by the initiator in order to create a token, and outputs a proof of validity. /// </summary> /// <param name="k">The private key for the token scheme</param> /// <param name="K">The public key for the token scheme</param> /// <param name="ecParameters">Curve parameters</param> /// <param name="P">Point submitted by the app</param> /// <returns>A signed point Q and a Chaum-Pedersen proof (c,z) proving that the point is signed correctly</returns> public (ECPoint Q, BigInteger c, BigInteger z) GenerateToken( BigInteger k, ECPoint K, X9ECParameters ecParameters, ECPoint P) { ECCurve?curve = ecParameters.Curve; // Check that P is a valid point on the currect curve if (ECPointVerifier.PointIsValid(P, curve) == false) { throw new AnonymousTokensException("P is not a valid point on the curve"); } // Compute Q = k*P ECPoint?Q = P.Multiply(k); // Chaum-Pedersen proof of correct signature var(c, z) = CreateProof(ecParameters, k, K, P, Q); return(Q, c, z); }
/// <summary> /// Used by the token service. Creates a full transcript of a Chaum-Pedersen protocol instance, using the strong Fiat-Shamir transform. /// The Chaum-Pedersen proof proves that the same secret key k is used to compute K = k*G and Q = k*P, without revealing k. /// </summary> /// <param name="ecParameters">Curve parameters</param> /// <param name="k">The private key of the token scheme</param> /// <param name="K">The public key of the token scheme</param> /// <param name="P">Point submitted by the initiator</param> /// <param name="Q">Point signed using the secret key</param> /// <returns></returns> private (BigInteger c, BigInteger z) CreateProof( X9ECParameters ecParameters, BigInteger k, ECPoint K, ECPoint P, ECPoint Q) { // Sample a random integer 0 < r < N BigInteger r = ECCurveRandomNumberGenerator.GenerateRandomNumber(ecParameters.Curve, _random); // Computes X = r*G ECPoint X = ecParameters.G.Multiply(r); // Computes Y = r*P ECPoint Y = P.Multiply(r); BigInteger c = CPChallengeGenerator.CreateChallenge(ecParameters.G, P, K, Q, X, Y); // Compute proof z = r - ck mod N BigInteger z = r.Subtract(c.Multiply(k)).Mod(ecParameters.Curve.Order); return(c, z); }
/** * Recover the public key that corresponds to the private key, which signed this message. */ public static byte[] RecoverPublicKey(byte[] sigR, byte[] sigS, byte[] sigV, byte[] message) { //ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1"); X9ECParameters spec = ECNamedCurveTable.GetByName("secp256k1"); BigInteger pointN = spec.N; try { BigInteger pointX = new BigInteger(1, sigR); byte[] compEnc = X9IntegerConverter.IntegerToBytes(pointX, 1 + X9IntegerConverter.GetByteLength(spec.Curve)); compEnc[0] = (byte)((sigV[0] & 1) == 1 ? 0x03 : 0x02); ECPoint pointR = spec.Curve.DecodePoint(compEnc); if (!pointR.Multiply(pointN).IsInfinity) { return(new byte[0]); } 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); return(pointQBytes); } catch (Exception e) { } return(new byte[0]); }
internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, BigInteger[] ks) { int count = ps.Length; int[] widths = new int[count]; WNafPreCompInfo[] infos = new WNafPreCompInfo[count]; byte[][] wnafs = new byte[count][]; int len = 0; for (int i = 0; i < count; ++i) { widths[i] = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(ks[i].BitLength))); infos[i] = WNafUtilities.Precompute(ps[i], widths[i], true); wnafs[i] = WNafUtilities.GenerateWindowNaf(widths[i], ks[i]); len = System.Math.Max(len, wnafs[i].Length); } ECCurve curve = ps[0].Curve; ECPoint infinity = curve.Infinity; ECPoint R = infinity; int zeroes = 0; for (int i = len - 1; i >= 0; --i) { ECPoint r = infinity; for (int j = 0; j < count; ++j) { byte[] wnaf = wnafs[j]; int wi = i < wnaf.Length ? (int)(sbyte)wnaf[i] : 0; if (wi != 0) { int n = System.Math.Abs(wi); WNafPreCompInfo info = infos[j]; ECPoint[] table = wi < 0 ? info.PreCompNeg : info.PreComp; r = r.Add(table[n >> 1]); } } if (r == infinity) { ++zeroes; continue; } if (zeroes > 0) { R = R.TimesPow2(zeroes); zeroes = 0; } R = R.TwicePlus(r); } if (zeroes > 0) { R = R.TimesPow2(zeroes); } return(R); }
public override ECPoint Add(ECPoint b) { if (base.IsInfinity) { return(b); } if (b.IsInfinity) { return(this); } ECCurve curve = this.Curve; int coordinateSystem = curve.CoordinateSystem; ECFieldElement rawXCoord = base.RawXCoord; ECFieldElement rawXCoord2 = b.RawXCoord; int num = coordinateSystem; switch (num) { case 0: { ECFieldElement rawYCoord = base.RawYCoord; ECFieldElement rawYCoord2 = b.RawYCoord; ECFieldElement eCFieldElement = rawXCoord.Add(rawXCoord2); ECFieldElement eCFieldElement2 = rawYCoord.Add(rawYCoord2); if (!eCFieldElement.IsZero) { ECFieldElement eCFieldElement3 = eCFieldElement2.Divide(eCFieldElement); ECFieldElement eCFieldElement4 = eCFieldElement3.Square().Add(eCFieldElement3).Add(eCFieldElement).Add(curve.A); ECFieldElement y = eCFieldElement3.Multiply(rawXCoord.Add(eCFieldElement4)).Add(eCFieldElement4).Add(rawYCoord); return(new F2mPoint(curve, eCFieldElement4, y, base.IsCompressed)); } if (eCFieldElement2.IsZero) { return(this.Twice()); } return(curve.Infinity); } case 1: { ECFieldElement rawYCoord3 = base.RawYCoord; ECFieldElement eCFieldElement5 = base.RawZCoords[0]; ECFieldElement rawYCoord4 = b.RawYCoord; ECFieldElement eCFieldElement6 = b.RawZCoords[0]; bool isOne = eCFieldElement5.IsOne; ECFieldElement eCFieldElement7 = rawYCoord4; ECFieldElement eCFieldElement8 = rawXCoord2; if (!isOne) { eCFieldElement7 = eCFieldElement7.Multiply(eCFieldElement5); eCFieldElement8 = eCFieldElement8.Multiply(eCFieldElement5); } bool isOne2 = eCFieldElement6.IsOne; ECFieldElement eCFieldElement9 = rawYCoord3; ECFieldElement eCFieldElement10 = rawXCoord; if (!isOne2) { eCFieldElement9 = eCFieldElement9.Multiply(eCFieldElement6); eCFieldElement10 = eCFieldElement10.Multiply(eCFieldElement6); } ECFieldElement eCFieldElement11 = eCFieldElement7.Add(eCFieldElement9); ECFieldElement eCFieldElement12 = eCFieldElement8.Add(eCFieldElement10); if (!eCFieldElement12.IsZero) { ECFieldElement eCFieldElement13 = eCFieldElement12.Square(); ECFieldElement eCFieldElement14 = eCFieldElement13.Multiply(eCFieldElement12); ECFieldElement b2 = isOne ? eCFieldElement6 : (isOne2 ? eCFieldElement5 : eCFieldElement5.Multiply(eCFieldElement6)); ECFieldElement eCFieldElement15 = eCFieldElement11.Add(eCFieldElement12); ECFieldElement eCFieldElement16 = eCFieldElement15.MultiplyPlusProduct(eCFieldElement11, eCFieldElement13, curve.A).Multiply(b2).Add(eCFieldElement14); ECFieldElement x = eCFieldElement12.Multiply(eCFieldElement16); ECFieldElement b3 = isOne2 ? eCFieldElement13 : eCFieldElement13.Multiply(eCFieldElement6); ECFieldElement y2 = eCFieldElement11.MultiplyPlusProduct(rawXCoord, eCFieldElement12, rawYCoord3).MultiplyPlusProduct(b3, eCFieldElement15, eCFieldElement16); ECFieldElement eCFieldElement17 = eCFieldElement14.Multiply(b2); return(new F2mPoint(curve, x, y2, new ECFieldElement[] { eCFieldElement17 }, base.IsCompressed)); } if (eCFieldElement11.IsZero) { return(this.Twice()); } return(curve.Infinity); } default: if (num != 6) { throw new InvalidOperationException("unsupported coordinate system"); } if (rawXCoord.IsZero) { if (rawXCoord2.IsZero) { return(curve.Infinity); } return(b.Add(this)); } else { ECFieldElement rawYCoord5 = base.RawYCoord; ECFieldElement eCFieldElement18 = base.RawZCoords[0]; ECFieldElement rawYCoord6 = b.RawYCoord; ECFieldElement eCFieldElement19 = b.RawZCoords[0]; bool isOne3 = eCFieldElement18.IsOne; ECFieldElement eCFieldElement20 = rawXCoord2; ECFieldElement eCFieldElement21 = rawYCoord6; if (!isOne3) { eCFieldElement20 = eCFieldElement20.Multiply(eCFieldElement18); eCFieldElement21 = eCFieldElement21.Multiply(eCFieldElement18); } bool isOne4 = eCFieldElement19.IsOne; ECFieldElement eCFieldElement22 = rawXCoord; ECFieldElement eCFieldElement23 = rawYCoord5; if (!isOne4) { eCFieldElement22 = eCFieldElement22.Multiply(eCFieldElement19); eCFieldElement23 = eCFieldElement23.Multiply(eCFieldElement19); } ECFieldElement eCFieldElement24 = eCFieldElement23.Add(eCFieldElement21); ECFieldElement eCFieldElement25 = eCFieldElement22.Add(eCFieldElement20); if (!eCFieldElement25.IsZero) { ECFieldElement eCFieldElement27; ECFieldElement y3; ECFieldElement eCFieldElement29; if (rawXCoord2.IsZero) { ECPoint eCPoint = this.Normalize(); rawXCoord = eCPoint.RawXCoord; ECFieldElement yCoord = eCPoint.YCoord; ECFieldElement b4 = rawYCoord6; ECFieldElement eCFieldElement26 = yCoord.Add(b4).Divide(rawXCoord); eCFieldElement27 = eCFieldElement26.Square().Add(eCFieldElement26).Add(rawXCoord).Add(curve.A); if (eCFieldElement27.IsZero) { return(new F2mPoint(curve, eCFieldElement27, curve.B.Sqrt(), base.IsCompressed)); } ECFieldElement eCFieldElement28 = eCFieldElement26.Multiply(rawXCoord.Add(eCFieldElement27)).Add(eCFieldElement27).Add(yCoord); y3 = eCFieldElement28.Divide(eCFieldElement27).Add(eCFieldElement27); eCFieldElement29 = curve.FromBigInteger(BigInteger.One); } else { eCFieldElement25 = eCFieldElement25.Square(); ECFieldElement eCFieldElement30 = eCFieldElement24.Multiply(eCFieldElement22); ECFieldElement eCFieldElement31 = eCFieldElement24.Multiply(eCFieldElement20); eCFieldElement27 = eCFieldElement30.Multiply(eCFieldElement31); if (eCFieldElement27.IsZero) { return(new F2mPoint(curve, eCFieldElement27, curve.B.Sqrt(), base.IsCompressed)); } ECFieldElement eCFieldElement32 = eCFieldElement24.Multiply(eCFieldElement25); if (!isOne4) { eCFieldElement32 = eCFieldElement32.Multiply(eCFieldElement19); } y3 = eCFieldElement31.Add(eCFieldElement25).SquarePlusProduct(eCFieldElement32, rawYCoord5.Add(eCFieldElement18)); eCFieldElement29 = eCFieldElement32; if (!isOne3) { eCFieldElement29 = eCFieldElement29.Multiply(eCFieldElement18); } } return(new F2mPoint(curve, eCFieldElement27, y3, new ECFieldElement[] { eCFieldElement29 }, base.IsCompressed)); } if (eCFieldElement24.IsZero) { return(this.Twice()); } return(curve.Infinity); } break; } }
/** * Decode a point on this curve from its ASN.1 encoding. The different * encodings are taken account of, including point compression for * <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17). * @return The decoded point. */ public virtual ECPoint DecodePoint(byte[] encoded) { ECPoint p = null; int expectedLength = (FieldSize + 7) / 8; byte type = encoded[0]; switch (type) { case 0x00: // infinity { if (encoded.Length != 1) { throw new ArgumentException("Incorrect length for infinity encoding", "encoded"); } p = Infinity; break; } case 0x02: // compressed case 0x03: // compressed { if (encoded.Length != (expectedLength + 1)) { throw new ArgumentException("Incorrect length for compressed encoding", "encoded"); } int yTilde = type & 1; BigInteger X = new BigInteger(1, encoded, 1, expectedLength); p = DecompressPoint(yTilde, X); if (!p.SatisfiesCofactor()) { throw new ArgumentException("Invalid point"); } break; } case 0x04: // uncompressed { if (encoded.Length != (2 * expectedLength + 1)) { throw new ArgumentException("Incorrect length for uncompressed encoding", "encoded"); } BigInteger X = new BigInteger(1, encoded, 1, expectedLength); BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength); p = ValidatePoint(X, Y); break; } case 0x06: // hybrid case 0x07: // hybrid { if (encoded.Length != (2 * expectedLength + 1)) { throw new ArgumentException("Incorrect length for hybrid encoding", "encoded"); } BigInteger X = new BigInteger(1, encoded, 1, expectedLength); BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength); if (Y.TestBit(0) != (type == 0x07)) { throw new ArgumentException("Inconsistent Y coordinate in hybrid encoding", "encoded"); } p = ValidatePoint(X, Y); break; } default: throw new FormatException("Invalid point encoding " + type); } if (type != 0x00 && p.IsInfinity) { throw new ArgumentException("Invalid infinity encoding", "encoded"); } return(p); }
public override ECPoint TwicePlus(ECPoint b) { if (base.IsInfinity) { return(b); } if (b.IsInfinity) { return(this.Twice()); } ECCurve curve = this.Curve; ECFieldElement rawXCoord = base.RawXCoord; if (rawXCoord.IsZero) { return(b); } int coordinateSystem = curve.CoordinateSystem; int num = coordinateSystem; if (num != 6) { return(this.Twice().Add(b)); } ECFieldElement rawXCoord2 = b.RawXCoord; ECFieldElement eCFieldElement = b.RawZCoords[0]; if (rawXCoord2.IsZero || !eCFieldElement.IsOne) { return(this.Twice().Add(b)); } ECFieldElement rawYCoord = base.RawYCoord; ECFieldElement eCFieldElement2 = base.RawZCoords[0]; ECFieldElement rawYCoord2 = b.RawYCoord; ECFieldElement x = rawXCoord.Square(); ECFieldElement b2 = rawYCoord.Square(); ECFieldElement eCFieldElement3 = eCFieldElement2.Square(); ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2); ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3); ECFieldElement eCFieldElement4 = rawYCoord2.AddOne(); ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2).MultiplyPlusProduct(b4, x, eCFieldElement3); ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3); ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square(); if (eCFieldElement7.IsZero) { if (eCFieldElement5.IsZero) { return(b.Twice()); } return(curve.Infinity); } else { if (eCFieldElement5.IsZero) { return(new F2mPoint(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed)); } ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6); ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3); ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8); return(new F2mPoint(curve, x2, y, new ECFieldElement[] { eCFieldElement8 }, base.IsCompressed)); } }
private static ECPoint ImplShamirsTrickFixedPoint(ECPoint p, BigInteger k, ECPoint q, BigInteger l) { ECCurve c = p.Curve; int combSize = FixedPointUtilities.GetCombSize(c); if (k.BitLength > combSize || l.BitLength > combSize) { /* * TODO The comb works best when the scalars are less than the (possibly unknown) order. * Still, if we want to handle larger scalars, we could allow customization of the comb * size, or alternatively we could deal with the 'extra' bits either by running the comb * multiple times as necessary, or by using an alternative multiplier as prelude. */ throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order"); } FixedPointPreCompInfo infoP = FixedPointUtilities.Precompute(p); FixedPointPreCompInfo infoQ = FixedPointUtilities.Precompute(q); ECLookupTable lookupTableP = infoP.LookupTable; ECLookupTable lookupTableQ = infoQ.LookupTable; int widthP = infoP.Width; int widthQ = infoQ.Width; // TODO This shouldn't normally happen, but a better "solution" is desirable anyway if (widthP != widthQ) { FixedPointCombMultiplier m = new FixedPointCombMultiplier(); ECPoint r1 = m.Multiply(p, k); ECPoint r2 = m.Multiply(q, l); return(r1.Add(r2)); } int width = widthP; int d = (combSize + width - 1) / width; ECPoint R = c.Infinity; int fullComb = d * width; uint[] K = Nat.FromBigInteger(fullComb, k); uint[] L = Nat.FromBigInteger(fullComb, l); int top = fullComb - 1; for (int i = 0; i < d; ++i) { uint secretIndexK = 0, secretIndexL = 0; for (int j = top - i; j >= 0; j -= d) { uint secretBitK = K[j >> 5] >> (j & 0x1F); secretIndexK ^= secretBitK >> 1; secretIndexK <<= 1; secretIndexK ^= secretBitK; uint secretBitL = L[j >> 5] >> (j & 0x1F); secretIndexL ^= secretBitL >> 1; secretIndexL <<= 1; secretIndexL ^= secretBitL; } ECPoint addP = lookupTableP.LookupVar((int)secretIndexK); ECPoint addQ = lookupTableQ.LookupVar((int)secretIndexL); ECPoint T = addP.Add(addQ); R = R.TwicePlus(T); } return(R.Add(infoP.Offset).Add(infoQ.Offset)); }
public abstract ECPoint Add(ECPoint b);
/* (non-Javadoc) * @see org.bouncycastle.math.ec.ECPoint#subtract(org.bouncycastle.math.ec.ECPoint) */ public override ECPoint Subtract( ECPoint b) { CheckPoints(this, b); return(SubtractSimple((F2mPoint)b)); }
/* (non-Javadoc) * @see org.bouncycastle.math.ec.ECPoint#add(org.bouncycastle.math.ec.ECPoint) */ public override ECPoint Add(ECPoint b) { CheckPoints(this, b); return(AddSimple((F2mPoint)b)); }
public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature) { if (!CertificateKeyAlgorithm.Equals(publicKey.Oid)) { throw new Exception("ECDSA signature verification requires ECDSA public key"); } // Decode the public key parameters string curveOid = DER2OID(publicKey.Parameters); if (curveOid == null) { throw new Exception("Unsupported ECDSA public key parameters"); } // Get parameters from the curve OID X9ECParameters ecParams = SecNamedCurves.GetByOid(new DerObjectIdentifier(curveOid)); if (ecParams == null) { throw new Exception("Unsupported ECC curve type OID: " + curveOid); } // Construct domain parameters ECDomainParameters domainParameters = new ECDomainParameters(ecParams.Curve, ecParams.G, ecParams.N, ecParams.H, ecParams.GetSeed()); // Decode the public key data byte[] ecPointData = publicKey.KeyValue; if (ecPointData[0] != 0x04) { throw new Exception("Only uncompressed ECDSA keys supported, format: " + ecPointData[0]); } Org.BouncyCastle.Math.EC.ECPoint ecPoint = domainParameters.Curve.DecodePoint(ecPointData); ECPublicKeyParameters theirPublicKey = new ECPublicKeyParameters(ecPoint, domainParameters); // Hash input data buffer byte[] dataHash; if (hashAlgorithm == null) { dataHash = TLSv1HashData(data); } else { dataHash = hashAlgorithm.ComputeHash(data); } // Actually verify the signature BigInteger[] sig = DERDecodeSignature(signature); var r = sig[0]; var s = sig[1]; Log.Trace("Hashed data (V): " + BitConverter.ToString(dataHash)); Log.Trace("Public Key Q (V): " + BitConverter.ToString(theirPublicKey.Q.GetEncoded())); Log.Trace("Signature R (V): " + BitConverter.ToString(r.ToByteArrayUnsigned())); Log.Trace("Signature S (V): " + BitConverter.ToString(s.ToByteArrayUnsigned())); Log.Trace("R value: " + sig[0].SignValue + " " + sig[0].LongValue); Log.Trace("S value: " + sig[1].SignValue + " " + sig[1].LongValue); ECDsaSigner signer = new ECDsaSigner(); signer.Init(false, theirPublicKey); var result = signer.VerifySignature(dataHash, r, s); Log.Debug("Signature verification status: {0}.", result); return(result); }
public abstract ECPoint Subtract(ECPoint b);
internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { int widthP = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(k.BitLength))); int widthQ = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(l.BitLength))); WNafPreCompInfo infoP = WNafUtilities.Precompute(P, widthP, true); WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, widthQ, true); ECPoint[] preCompP = infoP.PreComp; ECPoint[] preCompQ = infoQ.PreComp; ECPoint[] preCompNegP = infoP.PreCompNeg; ECPoint[] preCompNegQ = infoQ.PreCompNeg; byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k); byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l); int len = System.Math.Max(wnafP.Length, wnafQ.Length); ECCurve curve = P.Curve; ECPoint infinity = curve.Infinity; ECPoint R = infinity; int zeroes = 0; for (int i = len - 1; i >= 0; --i) { int wiP = i < wnafP.Length ? (int)(sbyte)wnafP[i] : 0; int wiQ = i < wnafQ.Length ? (int)(sbyte)wnafQ[i] : 0; if ((wiP | wiQ) == 0) { ++zeroes; continue; } ECPoint r = infinity; if (wiP != 0) { int nP = System.Math.Abs(wiP); ECPoint[] tableP = wiP < 0 ? preCompNegP : preCompP; r = r.Add(tableP[nP >> 1]); } if (wiQ != 0) { int nQ = System.Math.Abs(wiQ); ECPoint[] tableQ = wiQ < 0 ? preCompNegQ : preCompQ; r = r.Add(tableQ[nQ >> 1]); } if (zeroes > 0) { R = R.TimesPow2(zeroes); zeroes = 0; } R = R.TwicePlus(r); } if (zeroes > 0) { R = R.TimesPow2(zeroes); } return(R); }