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.Normalize(); this._n = n; this._h = h; this._seed = seed.DeepCopy(); }
/// <summary> /// 验签 /// </summary> /// <param name="md">sm3摘要</param> /// <param name="userKey">根据公钥decode一个ecpoint对象</param> /// <param name="r">没有特殊含义</param> /// <param name="s">没有特殊含义</param> /// <param name="sm2Result">sm2Result 接收参数的对象</param> public void sm2Verify(byte[] md, ECPoint userKey, BigInteger r, BigInteger s, SM2Result sm2Result) { sm2Result.R = null; BigInteger e = new BigInteger(1, md); BigInteger t = r.Add(s).Mod(this.ecc_n); if (t.Equals(BigInteger.Zero)) { return; } else { ECPoint x1y1 = ecc_point_g.Multiply(sm2Result.s); //System.out.println("计算曲线点X0: "+ x1y1.normalize().getXCoord().toBigInteger().toString(16)); //System.out.println("计算曲线点Y0: "+ x1y1.normalize().getYCoord().toBigInteger().toString(16)); //System.out.println(""); x1y1 = x1y1.Add(userKey.Multiply(t)); //System.out.println("计算曲线点X1: "+ x1y1.normalize().getXCoord().toBigInteger().toString(16)); //System.out.println("计算曲线点Y1: "+ x1y1.normalize().getYCoord().toBigInteger().toString(16)); //System.out.println(""); sm2Result.R = e.Add(x1y1.Normalize().XCoord.ToBigInteger()).Mod(this.ecc_n); //System.out.println("R: " + sm2Result.R.toString(16)); return; } }
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.Normalize(); this.n = n; this.h = h; this.seed = Arrays.Clone(seed); }
public static byte[] encodePoint(ECPoint Q) { /*if (!Q.isCompressed()) * Q=new ECPoint.F2m(Q.getCurve(),Q.getX(),Q.getY(),true); * * byte[] bytes=Q.getEncoded(); * * if (bytes[0]==0x02) * bytes[bytes.length-1]&=0xFE; * else if (bytes[0]==0x02) * bytes[bytes.length-1]|=0x01; * * return Arrays.copyOfRange(bytes, 1, bytes.length);*/ Q = Q.Normalize(); ECFieldElement x = Q.AffineXCoord; byte[] bytes = x.GetEncoded(); if (!x.IsZero) { ECFieldElement z = Q.AffineYCoord.Divide(x); if (trace(z).IsOne) { bytes[bytes.Length - 1] |= 0x01; } else { bytes[bytes.Length - 1] &= 0xFE; } } return(bytes); }
public ECPublicKeyParameters(string algorithm, ECPoint q, ECDomainParameters parameters) : base(algorithm, false, parameters) { if (q == null) { throw new ArgumentNullException("q"); } this.q = q.Normalize(); }
public ECPublicKeyParameters(string algorithm, ECPoint q, DerObjectIdentifier publicKeyParamSet) : base(algorithm, false, publicKeyParamSet) { if (q == null) { throw new ArgumentNullException("q"); } this.q = q.Normalize(); }
public ECPublicKeyParameters(ECPoint q, DerObjectIdentifier publicKeyParamSet) : base("ECGOST3410", false, publicKeyParamSet) { if (q == null) { throw new ArgumentNullException("q"); } this.q = q.Normalize(); }
public static bool IsSameAs(this OwnECPoint point1, ECPoint point2) { if (point1.IsInfinity || point2.IsInfinity) { return(point1.IsInfinity && point2.IsInfinity); } point2 = point2.Normalize(); return(point1.X.ToBigInteger() == point2.X && point1.Y.ToBigInteger() == point2.Y); }
private ECPrivateKeyParameters ParseKey(string data) { Dictionary<string, string> values = ToDictionnary(data); var curveName = values["curve"].Replace("NIST", ""); var curve = SecNamedCurves.GetByOid(curves[curveName]); var domain = new ECDomainParameters(curve.Curve, curve.G, new BigInteger(values["q"], 16), curve.H); Assert.Equal(domain.N, curve.N); var key = new ECPrivateKeyParameters(new BigInteger(values["x"], 16), domain); ECPoint pub = curve.G.Multiply(key.D); Assert.Equal(pub.Normalize().XCoord.ToBigInteger(), new BigInteger(values["Ux"], 16)); Assert.Equal(pub.Normalize().YCoord.ToBigInteger(), new BigInteger(values["Uy"], 16)); return key; }
public PubKey GetPubKey(bool isCompressed) { ECPoint q = GetPublicKeyParameters().Q; //Pub key (q) is composed into X and Y, the compressed form only include X, which can derive Y along with 02 or 03 prepent depending on whether Y in even or odd. q = q.Normalize(); byte[] result = Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()).GetEncoded(isCompressed); return(new PubKey(result)); }
public ECPublicKeyParameters(string algorithm, ECPoint q, DerObjectIdentifier publicKeyParamSet) : base(algorithm, isPrivate: false, publicKeyParamSet) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (q == null) { throw new ArgumentNullException("q"); } this.q = q.Normalize(); }
private void Reset() { sm3keybase = new SM3Digest(); sm3c3 = new SM3Digest(); byte[] p; p = p2.Normalize().XCoord.ToBigInteger().ToByteArray(); sm3keybase.BlockUpdate(p, 0, p.Length); sm3c3.BlockUpdate(p, 0, p.Length); p = p2.Normalize().YCoord.ToBigInteger().ToByteArray(); sm3keybase.BlockUpdate(p, 0, p.Length); ct = 1; NextKey(); }
/// <summary> /// Constructor with explicit co-factor and generation seed. /// </summary> /// <param name="curve">The curve for these domain parameters.</param> /// <param name="G">The base point G for the domain parameters.</param> /// <param name="n">The order for the domain parameters.</param> /// <param name="h">The co-factor.</param> /// <param name="seed">The seed value used to generate the domain parameters.</param> public ECDomainParameters( ECCurve curve, ECPoint G, BigInteger n, BigInteger h, byte[] seed) { this.curve = curve; this.g = G.Normalize(); this.n = n; this.h = h; this.seed = Arrays.Clone(seed); }
public virtual ECPoint ImportPoint(ECPoint p) { if (this == p.Curve) { return(p); } if (p.IsInfinity) { return(Infinity); } p = p.Normalize(); return(ValidatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed)); }
public static string GenerateSecp256k1PublicKey(string privateKey, bool useCompression) { var Ecc = SecNamedCurves.GetByName("secp256k1"); var DomainParams = new ECDomainParameters(Ecc.Curve, Ecc.G, Ecc.N, Ecc.H); var bytes = Hex.Hex2Bytes(privateKey); BigInteger d = new BigInteger(bytes); ECPoint q = DomainParams.G.Multiply(d); q = q.Normalize(); var publicParams = new ECPublicKeyParameters(q, DomainParams); FpPoint fp = new FpPoint(Ecc.Curve, q.AffineXCoord, q.AffineYCoord); return(Hex.Bytes2Hex(fp.GetEncoded(useCompression))); }
/// <summary> /// 获取Z值 /// Z=SM3(ENTL∣∣userId∣∣a∣∣b∣∣gx∣∣gy ∣∣x∣∣y) /// </summary> /// <param name="userId">签名方的用户身份标识</param> /// <param name="userKey">签名方公钥</param> /// <returns></returns> public virtual byte[] Sm2GetZ(byte[] userId, ECPoint userKey) { SM3Digest sm3 = new SM3Digest(); byte[] p; // ENTL由2个字节标识的ID的比特长度 int len = userId.Length * 8; sm3.Update((byte)(len >> 8 & 0x00ff)); sm3.Update((byte)(len & 0x00ff)); // userId用户身份标识ID sm3.BlockUpdate(userId, 0, userId.Length); // a,b为系统曲线参数; p = EccA.ToByteArray(); sm3.BlockUpdate(p, 0, p.Length); p = EccB.ToByteArray(); sm3.BlockUpdate(p, 0, p.Length); // gx、gy为基点 p = EccGx.ToByteArray(); sm3.BlockUpdate(p, 0, p.Length); p = EccGy.ToByteArray(); sm3.BlockUpdate(p, 0, p.Length); // x,y用户的公钥的X和Y p = userKey.Normalize().XCoord.ToBigInteger().ToByteArray(); sm3.BlockUpdate(p, 0, p.Length); p = userKey.Normalize().YCoord.ToBigInteger().ToByteArray(); sm3.BlockUpdate(p, 0, p.Length); // Z byte[] md = new byte[sm3.GetDigestSize()]; sm3.DoFinal(md, 0); return(md); }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { ECPoint eCPoint = p.Normalize(); ECPoint eCPoint2 = eCPoint.Negate(); ECPoint eCPoint3 = eCPoint; int bitLength = k.BitLength; int lowestSetBit = k.GetLowestSetBit(); int num = bitLength; while (--num > lowestSetBit) { eCPoint3 = eCPoint3.TwicePlus(k.TestBit(num) ? eCPoint : eCPoint2); } return(eCPoint3.TimesPow2(lowestSetBit)); }
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)); }
public virtual ECPoint ImportPoint(ECPoint p) { if (this == p.Curve) { return(p); } if (p.IsInfinity) { return(Infinity); } // TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates. p = p.Normalize(); return(CreatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed)); }
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)); }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { int[] array = WNafUtilities.GenerateCompactNaf(k); ECPoint eCPoint = p.Normalize(); ECPoint eCPoint2 = eCPoint.Negate(); ECPoint eCPoint3 = p.Curve.Infinity; int num = array.Length; while (--num >= 0) { int num2 = array[num]; int num3 = num2 >> 16; int e = num2 & 65535; eCPoint3 = eCPoint3.TwicePlus((num3 < 0) ? eCPoint2 : eCPoint); eCPoint3 = eCPoint3.TimesPow2(e); } return(eCPoint3); }
/** * 'Zeroless' Signed Digit Left-to-Right. */ protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { ECPoint addP = p.Normalize(), subP = addP.Negate(); ECPoint R0 = addP; int n = k.BitLength; int s = k.GetLowestSetBit(); int i = n; while (--i > s) { R0 = R0.TwicePlus(k.TestBit(i) ? addP : subP); } R0 = R0.TimesPow2(s); return R0; }
/** * 'Zeroless' Signed Digit Left-to-Right. */ protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { ECPoint addP = p.Normalize(), subP = addP.Negate(); ECPoint R0 = addP; int n = k.BitLength; int s = k.GetLowestSetBit(); int i = n; while (--i > s) { R0 = R0.TwicePlus(k.TestBit(i) ? addP : subP); } R0 = R0.TimesPow2(s); return(R0); }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { int[] naf = WNafUtilities.GenerateCompactNaf(k); ECPoint addP = p.Normalize(), subP = addP.Negate(); ECPoint R = p.Curve.Infinity; int i = naf.Length; while (--i >= 0) { int ni = naf[i]; int digit = ni >> 16, zeroes = ni & 0xFFFF; R = R.TwicePlus(digit < 0 ? subP : addP); R = R.TimesPow2(zeroes); } return R; }
private static ECPoint Validate(ECPoint q) { if (q == null) { throw new ArgumentNullException("q"); } if (q.IsInfinity) { throw new ArgumentException("point at infinity", "q"); } q = q.Normalize(); if (!q.IsValid()) { throw new ArgumentException("point not on curve", "q"); } return(q); }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { int[] naf = WNafUtilities.GenerateCompactNaf(k); ECPoint addP = p.Normalize(), subP = addP.Negate(); ECPoint R = p.Curve.Infinity; int i = naf.Length; while (--i >= 0) { int ni = naf[i]; int digit = ni >> 16, zeroes = ni & 0xFFFF; R = R.TwicePlus(digit < 0 ? subP : addP); R = R.TimesPow2(zeroes); } return(R); }
public PubKey Derivate(byte[] cc, uint nChild, out byte[] ccChild) { byte[] lr = null; var l = new byte[32]; var r = new byte[32]; if ((nChild >> 31) == 0) { byte[] pubKey = ToBytes(); lr = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray()); } else { throw new InvalidOperationException("A public key can't derivate an hardened child"); } Array.Copy(lr, l, 32); Array.Copy(lr, 32, r, 0, 32); ccChild = r; BigInteger N = ECKey.CURVE.N; var parse256LL = new BigInteger(1, l); 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."); } ECPoint q = ECKey.CURVE.G.Multiply(parse256LL).Add(this.ECKey.GetPublicKeyParameters().Q); if (q.IsInfinity) { throw new InvalidOperationException("You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again."); } q = q.Normalize(); var p = new FpPoint(ECKey.CURVE.Curve, q.XCoord, q.YCoord, true); return(new PubKey(p.GetEncoded())); }
public X9ECParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h, byte[] seed) { this.curve = curve; this.g = g.Normalize(); this.n = n; this.h = h; this.seed = seed; if (ECAlgorithms.IsFpCurve(curve)) { this.fieldID = new X9FieldID(curve.Field.Characteristic); } else if (ECAlgorithms.IsF2mCurve(curve)) { IPolynomialExtensionField field = (IPolynomialExtensionField)curve.Field; int[] exponents = field.MinimalPolynomial.GetExponentsPresent(); if (exponents.Length == 3) { this.fieldID = new X9FieldID(exponents[2], exponents[1]); } else if (exponents.Length == 5) { this.fieldID = new X9FieldID(exponents[4], exponents[1], exponents[2], exponents[3]); } else { throw new ArgumentException("Only trinomial and pentomial curves are supported"); } } else { throw new ArgumentException("'curve' is of an unsupported type"); } }
/// <summary> /// Exchange shared secret through ECDH /// </summary> /// <param name="key">Private key</param> /// <returns>Shared pubkey</returns> public PubKey GetSharedPubkey(Key key) { ECPublicKeyParameters pub = this._ECKey.GetPublicKeyParameters(); ECPrivateKeyParameters privKey = key._ECKey.PrivateKey; if (!pub.Parameters.Equals(privKey.Parameters)) { throw new InvalidOperationException("ECDH public key has wrong domain parameters"); } ECPoint q = pub.Q.Multiply(privKey.D).Normalize(); if (q.IsInfinity) { throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH"); } ECPoint pubkey = ECKey.Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()); pubkey = pubkey.Normalize(); return(new ECKey(pubkey.GetEncoded(true), false).GetPubKey(true)); }
internal static ECPoint Validated(ECPoint q) { // FSM_STATE:5.8, "FIPS 186-3/SP 800-89 ASSURANCES", "The module is performing FIPS 186-3/SP 800-89 Assurances self-test" // FSM_TRANS:5.9, "CONDITIONAL TEST", "FIPS 186-3/SP 800-89 ASSURANCES CHECK", "Invoke FIPS 186-3/SP 800-89 Assurances test" if (q == null) { throw new ArgumentException("Point has null value"); } if (q.IsInfinity) { throw new ArgumentException("Point at infinity"); } q = q.Normalize(); if (!q.IsValid()) { throw new ArgumentException("Point not on curve"); } // FSM_TRANS:5.10, "FIPS 186-3/SP 800-89 ASSURANCES CHECK", "CONDITIONAL TEST", "FIPS 186-3/SP 800-89 Assurances test successful" return(q); }
public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated) { ECCurve c = p.Curve; WNafPreCompInfo wnafPreCompInfo = GetWNafPreCompInfo(c.GetPreCompInfo(p, PRECOMP_NAME)); int iniPreCompLen = 0, reqPreCompLen = 1 << System.Math.Max(0, width - 2); ECPoint[] preComp = wnafPreCompInfo.PreComp; if (preComp == null) { preComp = EMPTY_POINTS; } else { iniPreCompLen = preComp.Length; } if (iniPreCompLen < reqPreCompLen) { preComp = ResizeTable(preComp, reqPreCompLen); if (reqPreCompLen == 1) { preComp[0] = p.Normalize(); } else { int curPreCompLen = iniPreCompLen; if (curPreCompLen == 0) { preComp[0] = p; curPreCompLen = 1; } ECFieldElement iso = null; if (reqPreCompLen == 2) { preComp[1] = p.ThreeTimes(); } else { ECPoint twiceP = wnafPreCompInfo.Twice, last = preComp[curPreCompLen - 1]; if (twiceP == null) { twiceP = preComp[0].Twice(); wnafPreCompInfo.Twice = twiceP; /* * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This * also requires scaling the initial point's X, Y coordinates, and reversing the * isomorphism as part of the subsequent normalization. * * NOTE: The correctness of this optimization depends on: * 1) additions do not use the curve's A, B coefficients. * 2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ... */ if (ECAlgorithms.IsFpCurve(c) && c.FieldSize >= 64) { switch (c.CoordinateSystem) { case ECCurve.COORD_JACOBIAN: case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: case ECCurve.COORD_JACOBIAN_MODIFIED: { iso = twiceP.GetZCoord(0); twiceP = c.CreatePoint(twiceP.XCoord.ToBigInteger(), twiceP.YCoord.ToBigInteger()); ECFieldElement iso2 = iso.Square(), iso3 = iso2.Multiply(iso); last = last.ScaleX(iso2).ScaleY(iso3); if (iniPreCompLen == 0) { preComp[0] = last; } break; } } } } while (curPreCompLen < reqPreCompLen) { /* * Compute the new ECPoints for the precomputation array. The values 1, 3, * 5, ..., 2^(width-1)-1 times p are computed */ preComp[curPreCompLen++] = last = last.Add(twiceP); } } /* * Having oft-used operands in affine form makes operations faster. */ c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso); } } wnafPreCompInfo.PreComp = preComp; if (includeNegated) { ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg; int pos; if (preCompNeg == null) { pos = 0; preCompNeg = new ECPoint[reqPreCompLen]; } else { pos = preCompNeg.Length; if (pos < reqPreCompLen) { preCompNeg = ResizeTable(preCompNeg, reqPreCompLen); } } while (pos < reqPreCompLen) { preCompNeg[pos] = preComp[pos].Negate(); ++pos; } wnafPreCompInfo.PreCompNeg = preCompNeg; } c.SetPreCompInfo(p, PRECOMP_NAME, wnafPreCompInfo); return wnafPreCompInfo; }
public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated) { ECCurve c = p.Curve; WNafPreCompInfo wnafPreCompInfo = GetWNafPreCompInfo(c.GetPreCompInfo(p, PRECOMP_NAME)); int iniPreCompLen = 0, reqPreCompLen = 1 << System.Math.Max(0, width - 2); ECPoint[] preComp = wnafPreCompInfo.PreComp; if (preComp == null) { preComp = EMPTY_POINTS; } else { iniPreCompLen = preComp.Length; } if (iniPreCompLen < reqPreCompLen) { preComp = ResizeTable(preComp, reqPreCompLen); if (reqPreCompLen == 1) { preComp[0] = p.Normalize(); } else { int curPreCompLen = iniPreCompLen; if (curPreCompLen == 0) { preComp[0] = p; curPreCompLen = 1; } ECFieldElement iso = null; if (reqPreCompLen == 2) { preComp[1] = p.ThreeTimes(); } else { ECPoint twiceP = wnafPreCompInfo.Twice, last = preComp[curPreCompLen - 1]; if (twiceP == null) { twiceP = preComp[0].Twice(); wnafPreCompInfo.Twice = twiceP; /* * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This * also requires scaling the initial point's X, Y coordinates, and reversing the * isomorphism as part of the subsequent normalization. * * NOTE: The correctness of this optimization depends on: * 1) additions do not use the curve's A, B coefficients. * 2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ... */ if (ECAlgorithms.IsFpCurve(c) && c.FieldSize >= 64) { switch (c.CoordinateSystem) { case ECCurve.COORD_JACOBIAN: case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: case ECCurve.COORD_JACOBIAN_MODIFIED: { iso = twiceP.GetZCoord(0); twiceP = c.CreatePoint(twiceP.XCoord.ToBigInteger(), twiceP.YCoord.ToBigInteger()); ECFieldElement iso2 = iso.Square(), iso3 = iso2.Multiply(iso); last = last.ScaleX(iso2).ScaleY(iso3); if (iniPreCompLen == 0) { preComp[0] = last; } break; } } } } while (curPreCompLen < reqPreCompLen) { /* * Compute the new ECPoints for the precomputation array. The values 1, 3, * 5, ..., 2^(width-1)-1 times p are computed */ preComp[curPreCompLen++] = last = last.Add(twiceP); } } /* * Having oft-used operands in affine form makes operations faster. */ c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso); } } wnafPreCompInfo.PreComp = preComp; if (includeNegated) { ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg; int pos; if (preCompNeg == null) { pos = 0; preCompNeg = new ECPoint[reqPreCompLen]; } else { pos = preCompNeg.Length; if (pos < reqPreCompLen) { preCompNeg = ResizeTable(preCompNeg, reqPreCompLen); } } while (pos < reqPreCompLen) { preCompNeg[pos] = preComp[pos].Negate(); ++pos; } wnafPreCompInfo.PreCompNeg = preCompNeg; } c.SetPreCompInfo(p, PRECOMP_NAME, wnafPreCompInfo); return(wnafPreCompInfo); }
// 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)); }