protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { ECCurve curveOrig = p.Curve; ECCurve curveAdd = ConfigureCurve(curveOrig, additionCoord); ECCurve curveDouble = ConfigureCurve(curveOrig, doublingCoord); int[] naf = WNafUtilities.GenerateCompactNaf(k); ECPoint Ra = curveAdd.Infinity; ECPoint Td = curveDouble.ImportPoint(p); int zeroes = 0; for (int i = 0; i < naf.Length; ++i) { int ni = naf[i]; int digit = ni >> 16; zeroes += ni & 0xFFFF; Td = Td.TimesPow2(zeroes); ECPoint Tj = curveAdd.ImportPoint(Td); if (digit < 0) { Tj = Tj.Negate(); } Ra = Ra.Add(Tj); zeroes = 1; } return curveOrig.ImportPoint(Ra); }
public byte[] DecipherKey(BigInteger privateKey, ECPoint tag) { var keyPoint = tag.Multiply(privateKey); var key = SHA256.DoubleHash(keyPoint.EncodePoint(false)); return key; }
public ECPoint GenerateKey(ECPoint publicKey, out byte[] key, BigInteger? k) { for (int i = 0; i < 100; i++) { if (k == null) { byte[] kBytes = new byte[33]; rngCsp.GetBytes(kBytes); kBytes[32] = 0; k = new BigInteger(kBytes); } if (k.Value.IsZero || k.Value >= Secp256k1.N) continue; var tag = Secp256k1.G.Multiply(k.Value); var keyPoint = publicKey.Multiply(k.Value); if (keyPoint.IsInfinity || tag.IsInfinity) continue; key = SHA256.DoubleHash(keyPoint.EncodePoint(false)); return tag; } throw new Exception("Unable to generate key"); }
/// <summary> /// Parses an elliptic curve point. /// </summary> /// <param name="data">octet data</param> /// <param name="ec">elliptic curve domain parameters</param> /// <param name="p">an elliptic curve point object</param> /// <returns>true if parsing and validation succeeded</returns> public static bool Parse(byte[] data, EllipticCurve ec, out ECPoint p) { if (IsZero(data)) { // point at infinity p = null; return false; } if (data.Length < 2) { // invalid length p = null; return false; } if (data[0] == 0x04) { ECPoint tmp = ParseUncompressed(data); if (tmp == null) { p = null; return false; } if (!ec.ValidatePoint(tmp)) { p = null; return false; } p = tmp; p.Validated = true; return true; } // Compressed form of EC point is not supported. // OpenSSL, which is used by OpenSSH for cryptography, disables // EC point compression by default due to the patent reason. p = null; return false; }
public PublicKey(ECPoint point) { this.IsCompressedPoint = point.IsCompressed; this.point = point; this.PublicKeyBytes = point.GetEncoded(); if (validatePoint() == false) throw new ArgumentException("Not a valid public key"); }
public byte[] Encrypt(ECPoint publicKey, byte[] data) { byte[] key; var tag = ecElGamal.GenerateKey(publicKey, out key); var tagBytes = tag.EncodePoint(false); byte[] iv = new byte[16]; rngCsp.GetBytes(iv); aesEncryption.IV = iv; aesEncryption.Key = key; ICryptoTransform crypto = aesEncryption.CreateEncryptor(); byte[] cipherData = crypto.TransformFinalBlock(data, 0, data.Length); byte[] cipher = new byte[cipherData.Length + 65 + 16]; Buffer.BlockCopy(tagBytes, 0, cipher, 0, 65); Buffer.BlockCopy(aesEncryption.IV, 0, cipher, 65, 16); Buffer.BlockCopy(cipherData, 0, cipher, 65 + 16, cipherData.Length); return cipher; }
/** * D.3.2 pg 101 * @see org.bouncycastle.math.ec.multiplier.ECMultiplier#multiply(org.bouncycastle.math.ec.ECPoint, java.math.BigInteger) */ public ECPoint Multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo) { // TODO Probably should try to add this // BigInteger e = k.Mod(n); // n == order of p BigInteger e = k; BigInteger h = e.Multiply(BigInteger.Three); ECPoint neg = p.Negate(); ECPoint R = p; for (int i = h.BitLength - 2; i > 0; --i) { R = R.Twice(); bool hBit = h.TestBit(i); bool eBit = e.TestBit(i); if (hBit != eBit) { R = R.Add(hBit ? p : neg); } } return R; }
public static SignatureContract Create(ECPoint publicKey) { return new SignatureContract { RedeemScript = CreateSignatureRedeemScript(publicKey), PublicKeyHash = publicKey.EncodePoint(true).ToScriptHash(), publicKey = publicKey }; }
private ECCurve(BigInteger Q, BigInteger A, BigInteger B, BigInteger N, byte[] G) { this.Q = Q; this.A = new ECFieldElement(A, this); this.B = new ECFieldElement(B, this); this.N = N; this.Infinity = new ECPoint(null, null, this); this.G = ECPoint.DecodePoint(G, this); }
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()); return sign > 0 ? positive : positive.Negate(); }
public static byte[] CreateSignatureRedeemScript(ECPoint publicKey) { using (ScriptBuilder sb = new ScriptBuilder()) { sb.Push(publicKey.EncodePoint(true)); sb.Add(ScriptOp.OP_CHECKSIG); return sb.ToArray(); } }
public void PointDoubling( BigInteger x1, BigInteger y1, BigInteger x2, BigInteger y2) { var p = new ECPoint(x1, y1); var expected = new ECPoint(x2, y2); Assert.True(expected == 2*p); }
public void PointAddition( BigInteger x1, BigInteger y1, BigInteger x2, BigInteger y2, BigInteger x3, BigInteger y3) { var p1 = new ECPoint(x1, y1); var p2 = new ECPoint(x2, y2); var expected = new ECPoint(x3, y3); Assert.True(expected == p1 + p2); }
public void Sign(Block block, ECPoint[] miners) { SignatureContext context = new SignatureContext(block); Contract contract = MultiSigContract.Create(null, miners.Length / 2 + 1, miners); foreach (ECPoint pubKey in miners) { UInt160 publicKeyHash = pubKey.EncodePoint(true).ToScriptHash(); Account account = GetAccount(publicKeyHash); if (account == null) continue; byte[] signature = block.Sign(account); context.Add(contract, account.PublicKey, signature); } block.Script = context.GetScripts()[0]; }
/** * Joye's double-add algorithm. */ protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { ECPoint[] R = new ECPoint[]{ p.Curve.Infinity, p }; int n = k.BitLength; for (int i = 0; i < n; ++i) { int b = k.TestBit(i) ? 1 : 0; int bp = 1 - b; R[bp] = R[bp].TwicePlus(R[b]); } return R[0]; }
public bool Add(byte[] redeemScript, ECPoint pubkey, byte[] signature) { UInt160 scriptHash = redeemScript.ToScriptHash(); for (int i = 0; i < ScriptHashes.Length; i++) { if (ScriptHashes[i] == scriptHash) { if (signatures[i] == null) signatures[i] = new MultiSigContext(redeemScript); return signatures[i].Add(pubkey, signature); } } return false; }
/** * Simple shift-and-add multiplication. Serves as reference implementation * to verify (possibly faster) implementations in * {@link org.bouncycastle.math.ec.ECPoint ECPoint}. * * @param p The point to multiply. * @param k The factor by which to multiply. * @return The result of the point multiplication <code>k * p</code>. */ public ECPoint Multiply(ECPoint p, BigInteger k, PreCompInfo preCompInfo) { ECPoint q = p.Curve.Infinity; int t = k.BitLength; for (int i = 0; i < t; i++) { if (k.TestBit(i)) { q = q.Add(p); } p = p.Twice(); } return q; }
void ISignable.DeserializeUnsigned(BinaryReader reader) { PrevHash = reader.ReadSerializable<UInt256>(); Miner = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1); NoncePieces.Clear(); int count = (int)reader.ReadVarInt(); for (int i = 0; i < count; i++) { ECPoint key = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1); byte[] value = reader.ReadBytes((int)reader.ReadVarInt()); NoncePieces.Add(key, value); } MerkleRoot = reader.ReadSerializable<UInt256>(); }
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); }
/** * Montgomery ladder. */ protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { ECPoint[] R = new ECPoint[]{ p.Curve.Infinity, p }; int n = k.BitLength; int i = n; while (--i >= 0) { int b = k.TestBit(i) ? 1 : 0; int bp = 1 - b; R[bp] = R[bp].Add(R[b]); R[b] = R[b].Twice(); } return R[0]; }
protected override void DeserializeExclusiveData(BinaryReader reader) { this.AssetType = (AssetType)reader.ReadByte(); if (!Enum.IsDefined(typeof(AssetType), AssetType)) throw new FormatException(); this.Name = reader.ReadVarString(); this.Amount = reader.ReadSerializable<Fixed8>(); if (Amount == Fixed8.Zero || Amount < -Fixed8.Satoshi) throw new FormatException(); if (AssetType == AssetType.Share && Amount <= Fixed8.Zero) throw new FormatException(); if (AssetType == AssetType.Currency && Amount != -Fixed8.Satoshi) throw new FormatException(); this.Issuer = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1); this.Admin = reader.ReadSerializable<UInt160>(); }
public bool Add(ECPoint pubkey, byte[] signature) { if (signature.Length != 64) throw new ArgumentException(); for (int i = 0; i < pubkeys.Length; i++) { if (pubkeys[i] == pubkey) { if (signatures[i] != null) return false; signatures[i] = signature; return true; } } return false; }
/** * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} * by <code>k</code> using the reduced <code>τ</code>-adic NAF (RTNAF) * method. * @param p The AbstractF2mPoint to multiply. * @param k The integer by which to multiply <code>k</code>. * @return <code>p</code> multiplied by <code>k</code>. */ protected override ECPoint MultiplyPositive(ECPoint point, BigInteger k) { if (!(point is AbstractF2mPoint)) throw new ArgumentException("Only AbstractF2mPoint can be used in WTauNafMultiplier"); AbstractF2mPoint p = (AbstractF2mPoint)point; AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; int m = curve.FieldSize; sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; sbyte mu = Tnaf.GetMu(a); BigInteger[] s = curve.GetSi(); ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10); return MultiplyWTnaf(p, rho, curve.GetPreCompInfo(p, PRECOMP_NAME), a, mu); }
void ISignable.DeserializeUnsigned(BinaryReader reader) { PrevHash = reader.ReadSerializable<UInt256>(); Miner = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1); IV = reader.ReadBytes(16); NoncePieces.Clear(); int count = (int)reader.ReadVarInt(); for (int i = 0; i < count; i++) { ECPoint key = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1); if (key == Miner) throw new FormatException(); byte[] value = reader.ReadBytes((int)reader.ReadVarInt()); NoncePieces.Add(key, value); } NonceHash = reader.ReadSerializable<UInt256>(); TransactionHashes = reader.ReadSerializableArray<UInt256>(); }
/** * Multiplies a {@link org.bouncycastle.math.ec.F2mPoint F2mPoint} * by <code>k</code> using the reduced <code>τ</code>-adic NAF (RTNAF) * method. * @param p The F2mPoint to multiply. * @param k The integer by which to multiply <code>k</code>. * @return <code>p</code> multiplied by <code>k</code>. */ public ECPoint Multiply(ECPoint point, BigInteger k, PreCompInfo preCompInfo) { if (!(point is F2mPoint)) throw new ArgumentException("Only F2mPoint can be used in WTauNafMultiplier"); F2mPoint p = (F2mPoint)point; F2mCurve curve = (F2mCurve) p.Curve; int m = curve.M; sbyte a = (sbyte) curve.A.ToBigInteger().IntValue; sbyte mu = curve.GetMu(); BigInteger[] s = curve.GetSi(); ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10); return MultiplyWTnaf(p, rho, preCompInfo, a, mu); }
public static FixedPointPreCompInfo Precompute(ECPoint p, int minWidth) { ECCurve c = p.Curve; int n = 1 << minWidth; FixedPointPreCompInfo info = GetFixedPointPreCompInfo(c.GetPreCompInfo(p, PRECOMP_NAME)); ECPoint[] lookupTable = info.PreComp; if (lookupTable == null || lookupTable.Length < n) { int bits = GetCombSize(c); int d = (bits + minWidth - 1) / minWidth; ECPoint[] pow2Table = new ECPoint[minWidth]; pow2Table[0] = p; for (int i = 1; i < minWidth; ++i) { pow2Table[i] = pow2Table[i - 1].TimesPow2(d); } c.NormalizeAll(pow2Table); lookupTable = new ECPoint[n]; lookupTable[0] = c.Infinity; for (int bit = minWidth - 1; bit >= 0; --bit) { ECPoint pow2 = pow2Table[bit]; int step = 1 << bit; for (int i = step; i < n; i += (step << 1)) { lookupTable[i] = lookupTable[i - step].Add(pow2); } } c.NormalizeAll(lookupTable); info.PreComp = lookupTable; info.Width = minWidth; c.SetPreCompInfo(p, PRECOMP_NAME, info); } return info; }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { if (!curve.Equals(p.Curve)) throw new InvalidOperationException(); BigInteger n = p.Curve.Order; BigInteger[] ab = glvEndomorphism.DecomposeScalar(k.Mod(n)); BigInteger a = ab[0], b = ab[1]; ECPointMap pointMap = glvEndomorphism.PointMap; if (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) { ECCurve c = p.Curve; int size = FixedPointUtilities.GetCombSize(c); if (k.BitLength > size) { /* * 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"); } int minWidth = GetWidthForCombSize(size); FixedPointPreCompInfo info = FixedPointUtilities.Precompute(p, minWidth); ECPoint[] lookupTable = info.PreComp; int width = info.Width; int d = (size + width - 1) / width; ECPoint R = c.Infinity; int top = d * width - 1; for (int i = 0; i < d; ++i) { int index = 0; for (int j = top - i; j >= 0; j -= d) { index <<= 1; if (k.TestBit(j)) { index |= 1; } } R = R.TwicePlus(lookupTable[index]); } return R; }
/** * '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; }
public static AsymmetricKeyParameter CreateKey( SubjectPublicKeyInfo keyInfo) { AlgorithmIdentifier algID = keyInfo.AlgorithmID; DerObjectIdentifier algOid = algID.Algorithm; // TODO See RSAUtil.isRsaOid in Java build if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) || algOid.Equals(X509ObjectIdentifiers.IdEARsa) || algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) { RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance( keyInfo.GetPublicKey()); return(new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent)); } else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber)) { Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()); DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.GetPublicKey()); BigInteger y = dhPublicKey.Y.Value; if (IsPkcsDHParam(seq)) { return(ReadPkcsDHParam(algOid, y, seq)); } DHDomainParameters dhParams = DHDomainParameters.GetInstance(seq); BigInteger p = dhParams.P.Value; BigInteger g = dhParams.G.Value; BigInteger q = dhParams.Q.Value; BigInteger j = null; if (dhParams.J != null) { j = dhParams.J.Value; } DHValidationParameters validation = null; DHValidationParms dhValidationParms = dhParams.ValidationParms; if (dhValidationParms != null) { byte[] seed = dhValidationParms.Seed.GetBytes(); BigInteger pgenCounter = dhValidationParms.PgenCounter.Value; // TODO Check pgenCounter size? validation = new DHValidationParameters(seed, pgenCounter.IntValue); } return(new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation))); } else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement)) { Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()); DerInteger derY = (DerInteger)keyInfo.GetPublicKey(); return(ReadPkcsDHParam(algOid, derY.Value, seq)); } else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm)) { ElGamalParameter para = new ElGamalParameter( Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object())); DerInteger derY = (DerInteger)keyInfo.GetPublicKey(); return(new ElGamalPublicKeyParameters( derY.Value, new ElGamalParameters(para.P, para.G))); } else if (algOid.Equals(X9ObjectIdentifiers.IdDsa) || algOid.Equals(OiwObjectIdentifiers.DsaWithSha1)) { DerInteger derY = (DerInteger)keyInfo.GetPublicKey(); Asn1Encodable ae = algID.Parameters; DsaParameters parameters = null; if (ae != null) { DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object()); parameters = new DsaParameters(para.P, para.Q, para.G); } return(new DsaPublicKeyParameters(derY.Value, parameters)); } else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey)) { X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object()); X9ECParameters x9; if (para.IsNamedCurve) { x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters); } else { x9 = new X9ECParameters((Asn1Sequence)para.Parameters); } Asn1OctetString key = new DerOctetString(keyInfo.PublicKeyData.GetBytes()); X9ECPoint derQ = new X9ECPoint(x9.Curve, key); ECPoint q = derQ.Point; if (para.IsNamedCurve) { return(new ECPublicKeyParameters("EC", q, (DerObjectIdentifier)para.Parameters)); } ECDomainParameters dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); return(new ECPublicKeyParameters(q, dParams)); } else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) { Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( (Asn1Sequence)algID.Parameters); Asn1OctetString key; try { key = (Asn1OctetString)keyInfo.GetPublicKey(); } catch (IOException) { throw new ArgumentException("invalid info structure in GOST3410 public key"); } byte[] keyEnc = key.GetOctets(); byte[] x = new byte[32]; byte[] y = new byte[32]; for (int i = 0; i != y.Length; i++) { x[i] = keyEnc[32 - 1 - i]; } for (int i = 0; i != x.Length; i++) { y[i] = keyEnc[64 - 1 - i]; } ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet); if (ecP == null) { return(null); } ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y)); return(new ECPublicKeyParameters("ECGOST3410", q, gostParams.PublicKeyParamSet)); } else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94)) { Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( (Asn1Sequence)algID.Parameters); DerOctetString derY; try { derY = (DerOctetString)keyInfo.GetPublicKey(); } catch (IOException) { throw new ArgumentException("invalid info structure in GOST3410 public key"); } byte[] keyEnc = derY.GetOctets(); byte[] keyBytes = new byte[keyEnc.Length]; for (int i = 0; i != keyEnc.Length; i++) { keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian } BigInteger y = new BigInteger(1, keyBytes); return(new Gost3410PublicKeyParameters(y, algParams.PublicKeyParamSet)); } else if (algOid.Equals(EdECObjectIdentifiers.id_X25519)) { return(new X25519PublicKeyParameters(GetRawKey(keyInfo, X25519PublicKeyParameters.KeySize), 0)); } else if (algOid.Equals(EdECObjectIdentifiers.id_X448)) { return(new X448PublicKeyParameters(GetRawKey(keyInfo, X448PublicKeyParameters.KeySize), 0)); } else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519)) { return(new Ed25519PublicKeyParameters(GetRawKey(keyInfo, Ed25519PublicKeyParameters.KeySize), 0)); } else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448)) { return(new Ed448PublicKeyParameters(GetRawKey(keyInfo, Ed448PublicKeyParameters.KeySize), 0)); } else if ( algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) || algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)) { byte[] keyEnc = ((DerOctetString)Asn1Object.FromByteArray(keyInfo.PublicKeyData.GetOctets())).str; int fieldSize = 32; if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)) { fieldSize = 64; } int keySize = 2 * fieldSize; byte[] x9Encoding = new byte[1 + keySize]; x9Encoding[0] = 0x04; for (int i = 1; i <= fieldSize; ++i) { x9Encoding[i] = keyEnc[fieldSize - i]; x9Encoding[i + fieldSize] = keyEnc[keySize - i]; } Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(keyInfo.AlgorithmID.Parameters); ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters( new ECNamedDomainParameters(gostParams.PublicKeyParamSet, ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet)), gostParams.PublicKeyParamSet, gostParams.DigestParamSet, gostParams.EncryptionParamSet); return(new ECPublicKeyParameters(ecDomainParameters.Curve.DecodePoint(x9Encoding), ecDomainParameters)); } else { throw new SecurityUtilityException("algorithm identifier in public key not recognised: " + algOid); } }
public static CertificateQueryResult Query(ECPoint pubkey, string url) { return(Query(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash(), url)); }
internal PrecomputeCallback(ECPoint p, int minWidth, bool includeNegated) { this.m_p = p; this.m_minWidth = minWidth; this.m_includeNegated = includeNegated; }
private void EncodePublicKey() { X9ECParameters ecP = X962NamedCurves.GetByOid(X9ObjectIdentifiers.Prime239v3); if (X9IntegerConverter.GetByteLength(ecP.Curve) != 30) { Fail("wrong byte length reported for curve"); } if (ecP.Curve.FieldSize != 239) { Fail("wrong field size reported for curve"); } // // named curve // X962Parameters _params = new X962Parameters(X9ObjectIdentifiers.Prime192v1); ECPoint point = ecP.G.Multiply(BigInteger.ValueOf(100)); DerOctetString p = new DerOctetString(point.GetEncoded(true)); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), p.GetOctets()); if (!Arrays.AreEqual(info.GetEncoded(), namedPub)) { Fail("failed public named generation"); } X9ECPoint x9P = new X9ECPoint(ecP.Curve, p); if (!Arrays.AreEqual(p.GetOctets(), x9P.Point.GetEncoded())) { Fail("point encoding not preserved"); } Asn1Object o = Asn1Object.FromByteArray(namedPub); if (!info.Equals(o)) { Fail("failed public named equality"); } // // explicit curve parameters // _params = new X962Parameters(ecP); info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), p.GetOctets()); if (!Arrays.AreEqual(info.GetEncoded(), expPub)) { Fail("failed public explicit generation"); } o = Asn1Object.FromByteArray(expPub); if (!info.Equals(o)) { Fail("failed public explicit equality"); } }
public void TestAlgorithms() { SecureRandom RANDOM = new SecureRandom(); // // RSA parameters // BigInteger rsaMod = new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16); BigInteger rsaPubExp = new BigInteger("10001", 16); BigInteger rsaPrivExp = new BigInteger("65dad56ac7df7abb434e4cb5eeadb16093aa6da7f0033aad3815289b04757d32bfee6ade7749c8e4a323b5050a2fb9e2a99e23469e1ed4ba5bab54336af20a5bfccb8b3424cc6923db2ffca5787ed87aa87aa614cd04cedaebc8f623a2d2063017910f436dff18bb06f01758610787f8b258f0a8efd8bd7de30007c47b2a1031696c7d6523bc191d4d918927a7e0b09584ed205bd2ff4fc4382678df82353f7532b3bbb81d69e3f39070aed3fb64fce032a089e8e64955afa5213a6eb241231bd98d702fba725a9b205952fda186412d9e0d9344d2998c455ad8c2bae85ee672751466d5288304032b5b7e02f7e558c7af82c7fbf58eea0bb4ef0f001e6cd0a9", 16); BigInteger rsaPrivP = new BigInteger("d4fd9ac3474fb83aaf832470643609659e511b322632b239b688f3cd2aad87527d6cf652fb9c9ca67940e84789444f2e99b0cb0cfabbd4de95396106c865f38e2fb7b82b231260a94df0e01756bf73ce0386868d9c41645560a81af2f53c18e4f7cdf3d51d80267372e6e0216afbf67f655c9450769cca494e4f6631b239ce1b", 16); BigInteger rsaPrivQ = new BigInteger("c8eaa0e2a1b3a4412a702bccda93f4d150da60d736c99c7c566fdea4dd1b401cbc0d8c063daaf0b579953d36343aa18b33dbf8b9eae94452490cc905245f8f7b9e29b1a288bc66731a29e1dd1a45c9fd7f8238ff727adc49fff73991d0dc096206b9d3a08f61e7462e2b804d78cb8c5eccdb9b7fbd2ad6a8fea46c1053e1be75", 16); BigInteger rsaPrivDP = new BigInteger("10edcb544421c0f9e123624d1099feeb35c72a8b34e008ac6fa6b90210a7543f293af4e5299c8c12eb464e70092805c7256e18e5823455ba0f504d36f5ccacac1b7cd5c58ff710f9c3f92646949d88fdd1e7ea5fed1081820bb9b0d2a8cd4b093fecfdb96dabd6e28c3a6f8c186dc86cddc89afd3e403e0fcf8a9e0bcb27af0b", 16); BigInteger rsaPrivDQ = new BigInteger("97fc25484b5a415eaa63c03e6efa8dafe9a1c8b004d9ee6e80548fefd6f2ce44ee5cb117e77e70285798f57d137566ce8ea4503b13e0f1b5ed5ca6942537c4aa96b2a395782a4cb5b58d0936e0b0fa63b1192954d39ced176d71ef32c6f42c84e2e19f9d4dd999c2151b032b97bd22aa73fd8c5bcd15a2dca4046d5acc997021", 16); BigInteger rsaPrivQinv = new BigInteger("4bb8064e1eff7e9efc3c4578fcedb59ca4aef0993a8312dfdcb1b3decf458aa6650d3d0866f143cbf0d3825e9381181170a0a1651eefcd7def786b8eb356555d9fa07c85b5f5cbdd74382f1129b5e36b4166b6cc9157923699708648212c484958351fdc9cf14f218dbe7fbf7cbd93a209a4681fe23ceb44bab67d66f45d1c9d", 16); RsaKeyParameters rsaPublic = new RsaKeyParameters(false, rsaMod, rsaPubExp); RsaPrivateCrtKeyParameters rsaPrivate = new RsaPrivateCrtKeyParameters( rsaMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv); // // ECDSA parameters // BigInteger ECParraGX = new BigInteger(Base64.Decode("D/qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqv")); BigInteger ECParraGY = new BigInteger(Base64.Decode("AhQXGxb1olGRv6s1LPRfuatMF+cx3ZTGgzSE/Q5R")); BigInteger ECParraH = new BigInteger(Base64.Decode("AQ==")); BigInteger ECParraN = new BigInteger(Base64.Decode("f///////////////f///nl6an12QcfvRUiaIkJ0L")); BigInteger ECPubQX = new BigInteger(Base64.Decode("HWWi17Yb+Bm3PYr/DMjLOYNFhyOwX1QY7ZvqqM+l")); BigInteger ECPubQY = new BigInteger(Base64.Decode("JrlJfxu3WGhqwtL/55BOs/wsUeiDFsvXcGhB8DGx")); BigInteger ECPrivD = new BigInteger(Base64.Decode("GYQmd/NF1B+He1iMkWt3by2Az6Eu07t0ynJ4YCAo")); FpCurve curve = new FpCurve( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16), // b ECParraN, ECParraH); ECDomainParameters ecDomain = new ECDomainParameters( curve, curve.ValidatePoint(ECParraGX, ECParraGY), ECParraN, ECParraH); ECPublicKeyParameters ecPub = new ECPublicKeyParameters( curve.ValidatePoint(ECPubQX, ECPubQY), ecDomain); ECPrivateKeyParameters ecPriv = new ECPrivateKeyParameters(ECPrivD, ecDomain); // // DSA parameters // BigInteger DSAParaG = new BigInteger(Base64.Decode("AL0fxOTq10OHFbCf8YldyGembqEu08EDVzxyLL29Zn/t4It661YNol1rnhPIs+cirw+yf9zeCe+KL1IbZ/qIMZM=")); BigInteger DSAParaP = new BigInteger(Base64.Decode("AM2b/UeQA+ovv3dL05wlDHEKJ+qhnJBsRT5OB9WuyRC830G79y0R8wuq8jyIYWCYcTn1TeqVPWqiTv6oAoiEeOs=")); BigInteger DSAParaQ = new BigInteger(Base64.Decode("AIlJT7mcKL6SUBMmvm24zX1EvjNx")); BigInteger DSAPublicY = new BigInteger(Base64.Decode("TtWy2GuT9yGBWOHi1/EpCDa/bWJCk2+yAdr56rAcqP0eHGkMnA9s9GJD2nGU8sFjNHm55swpn6JQb8q0agrCfw==")); BigInteger DsaPrivateX = new BigInteger(Base64.Decode("MMpBAxNlv7eYfxLTZ2BItJeD31A=")); DsaParameters para = new DsaParameters(DSAParaP, DSAParaQ, DSAParaG); DsaPrivateKeyParameters dsaPriv = new DsaPrivateKeyParameters(DsaPrivateX, para); DsaPublicKeyParameters dsaPub = new DsaPublicKeyParameters(DSAPublicY, para); // // ECGOST3410 parameters // IAsymmetricCipherKeyPairGenerator ecGostKpg = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410"); ecGostKpg.Init( new ECKeyGenerationParameters( CryptoProObjectIdentifiers.GostR3410x2001CryptoProA, RANDOM)); AsymmetricCipherKeyPair ecGostPair = ecGostKpg.GenerateKeyPair(); IAsymmetricCipherKeyPairGenerator ed25519Kpg = GeneratorUtilities.GetKeyPairGenerator("Ed25519"); ed25519Kpg.Init(new Ed25519KeyGenerationParameters(RANDOM)); AsymmetricCipherKeyPair ed25519Pair = ed25519Kpg.GenerateKeyPair(); IAsymmetricCipherKeyPairGenerator ed448Kpg = GeneratorUtilities.GetKeyPairGenerator("Ed448"); ed448Kpg.Init(new Ed448KeyGenerationParameters(RANDOM)); AsymmetricCipherKeyPair ed448Pair = ed448Kpg.GenerateKeyPair(); // // GOST3410 parameters // IAsymmetricCipherKeyPairGenerator gostKpg = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); gostKpg.Init(new Gost3410KeyGenerationParameters(RANDOM, CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); AsymmetricCipherKeyPair gostPair = gostKpg.GenerateKeyPair(); // // SM2 parameters // BigInteger SM2_ECC_P = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", 16); BigInteger SM2_ECC_A = new BigInteger("787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", 16); BigInteger SM2_ECC_B = new BigInteger("63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", 16); BigInteger SM2_ECC_N = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", 16); BigInteger SM2_ECC_H = BigInteger.One; BigInteger SM2_ECC_GX = new BigInteger("421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 16); BigInteger SM2_ECC_GY = new BigInteger("0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 16); ECCurve sm2Curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H); ECPoint sm2G = sm2Curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY); ECDomainParameters sm2Domain = new ECDomainParameters(sm2Curve, sm2G, SM2_ECC_N, SM2_ECC_H); ECKeyPairGenerator sm2Kpg = new ECKeyPairGenerator(); sm2Kpg.Init(new ECKeyGenerationParameters(sm2Domain, RANDOM)); AsymmetricCipherKeyPair sm2Pair = sm2Kpg.GenerateKeyPair(); // // signer loop // byte[] shortMsg = new byte[] { 1, 4, 5, 6, 8, 8, 4, 2, 1, 3 }; byte[] longMsg = new byte[100]; RANDOM.NextBytes(longMsg); foreach (string algorithm in SignerUtilities.Algorithms) { ISigner signer = SignerUtilities.GetSigner(algorithm); string upper = algorithm.ToUpper(CultureInfo.InvariantCulture); int withPos = upper.LastIndexOf("WITH"); string cipherName = withPos < 0 ? upper : upper.Substring(withPos + "WITH".Length); ICipherParameters signParams = null, verifyParams = null; if (cipherName == "RSA" || cipherName == "RSAANDMGF1") { signParams = rsaPrivate; verifyParams = rsaPublic; } else if (cipherName == "ECDSA" || cipherName == "CVC-ECDSA" || cipherName == "PLAIN-ECDSA") { signParams = ecPriv; verifyParams = ecPub; } else if (cipherName == "DSA") { signParams = dsaPriv; verifyParams = dsaPub; } else if (cipherName == "ECGOST3410") { signParams = ecGostPair.Private; verifyParams = ecGostPair.Public; } else if (cipherName == "ED25519") { signParams = ed25519Pair.Private; verifyParams = ed25519Pair.Public; } else if (cipherName == "ED448") { signParams = ed448Pair.Private; verifyParams = ed448Pair.Public; } else if (cipherName == "GOST3410") { signParams = gostPair.Private; verifyParams = gostPair.Public; } else if (cipherName == "SM2") { signParams = sm2Pair.Private; verifyParams = sm2Pair.Public; } else { Assert.Fail("Unknown algorithm encountered: " + cipherName); } signer.Init(true, signParams); foreach (byte b in shortMsg) { signer.Update(b); } signer.BlockUpdate(longMsg, 0, longMsg.Length); byte[] sig = signer.GenerateSignature(); signer.Init(false, verifyParams); foreach (byte b in shortMsg) { signer.Update(b); } signer.BlockUpdate(longMsg, 0, longMsg.Length); Assert.IsTrue(signer.VerifySignature(sig), cipherName + " signer " + algorithm + " failed."); } }
public static WNafPreCompInfo GetWNafPreCompInfo(ECPoint p) { return(GetWNafPreCompInfo(p.Curve.GetPreCompInfo(p, PRECOMP_NAME))); }
private static bool IsMultiSigContract(byte[] script, out int m, out int n, List <ECPoint> points) { m = 0; n = 0; int i = 0; if (script.Length < 43) { return(false); } switch (script[i]) { case (byte)OpCode.PUSHINT8: m = script[++i]; ++i; break; case (byte)OpCode.PUSHINT16: m = BinaryPrimitives.ReadUInt16LittleEndian(script.AsSpan(++i)); i += 2; break; case byte b when b >= (byte)OpCode.PUSH1 && b <= (byte)OpCode.PUSH16: m = b - (byte)OpCode.PUSH0; ++i; break; default: return(false); } if (m < 1 || m > 1024) { return(false); } while (script[i] == (byte)OpCode.PUSHDATA1) { if (script.Length <= i + 35) { return(false); } if (script[++i] != 33) { return(false); } points?.Add(ECPoint.DecodePoint(script.AsSpan(i + 1, 33), ECCurve.Secp256r1)); i += 34; ++n; } if (n < m || n > 1024) { return(false); } switch (script[i]) { case (byte)OpCode.PUSHINT8: if (script.Length <= i + 1 || n != script[++i]) { return(false); } ++i; break; case (byte)OpCode.PUSHINT16: if (script.Length < i + 3 || n != BinaryPrimitives.ReadUInt16LittleEndian(script.AsSpan(++i))) { return(false); } i += 2; break; case byte b when b >= (byte)OpCode.PUSH1 && b <= (byte)OpCode.PUSH16: if (n != b - (byte)OpCode.PUSH0) { return(false); } ++i; break; default: return(false); } if (script.Length != i + 6) { return(false); } if (script[i++] != (byte)OpCode.PUSHNULL) { return(false); } if (script[i++] != (byte)OpCode.SYSCALL) { return(false); } if (BitConverter.ToUInt32(script, i) != ApplicationEngine.Neo_Crypto_CheckMultisigWithECDsaSecp256r1) { return(false); } return(true); }
public bool ContainsAccount(ECPoint publicKey) { return(ContainsAccount(publicKey.EncodePoint(true).ToScriptHash())); }
public override ECPoint Add(ECPoint b) { if (this.IsInfinity) { return(b); } if (b.IsInfinity) { return(this); } if (this == b) { return(Twice()); } ECCurve curve = this.Curve; SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Y1 = (SecP160R2FieldElement)this.RawYCoord; SecP160R2FieldElement X2 = (SecP160R2FieldElement)b.RawXCoord, Y2 = (SecP160R2FieldElement)b.RawYCoord; SecP160R2FieldElement Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; SecP160R2FieldElement Z2 = (SecP160R2FieldElement)b.RawZCoords[0]; uint c; uint[] tt1 = Nat160.CreateExt(); uint[] t2 = Nat160.Create(); uint[] t3 = Nat160.Create(); uint[] t4 = Nat160.Create(); bool Z1IsOne = Z1.IsOne; uint[] U2, S2; if (Z1IsOne) { U2 = X2.x; S2 = Y2.x; } else { S2 = t3; SecP160R2Field.Square(Z1.x, S2); U2 = t2; SecP160R2Field.Multiply(S2, X2.x, U2); SecP160R2Field.Multiply(S2, Z1.x, S2); SecP160R2Field.Multiply(S2, Y2.x, S2); } bool Z2IsOne = Z2.IsOne; uint[] U1, S1; if (Z2IsOne) { U1 = X1.x; S1 = Y1.x; } else { S1 = t4; SecP160R2Field.Square(Z2.x, S1); U1 = tt1; SecP160R2Field.Multiply(S1, X1.x, U1); SecP160R2Field.Multiply(S1, Z2.x, S1); SecP160R2Field.Multiply(S1, Y1.x, S1); } uint[] H = Nat160.Create(); SecP160R2Field.Subtract(U1, U2, H); uint[] R = t2; SecP160R2Field.Subtract(S1, S2, R); // Check if b == this or b == -this if (Nat160.IsZero(H)) { if (Nat160.IsZero(R)) { // this == b, i.e. this must be doubled return(this.Twice()); } // this == -b, i.e. the result is the point at infinity return(curve.Infinity); } uint[] HSquared = t3; SecP160R2Field.Square(H, HSquared); uint[] G = Nat160.Create(); SecP160R2Field.Multiply(HSquared, H, G); uint[] V = t3; SecP160R2Field.Multiply(HSquared, U1, V); SecP160R2Field.Negate(G, G); Nat160.Mul(S1, G, tt1); c = Nat160.AddBothTo(V, V, G); SecP160R2Field.Reduce32(c, G); SecP160R2FieldElement X3 = new SecP160R2FieldElement(t4); SecP160R2Field.Square(R, X3.x); SecP160R2Field.Subtract(X3.x, G, X3.x); SecP160R2FieldElement Y3 = new SecP160R2FieldElement(G); SecP160R2Field.Subtract(V, X3.x, Y3.x); SecP160R2Field.MultiplyAddToExt(Y3.x, R, tt1); SecP160R2Field.Reduce(tt1, Y3.x); SecP160R2FieldElement Z3 = new SecP160R2FieldElement(H); if (!Z1IsOne) { SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); } if (!Z2IsOne) { SecP160R2Field.Multiply(Z3.x, Z2.x, Z3.x); } ECFieldElement[] zs = new ECFieldElement[] { Z3 }; return(new SecP160R2Point(curve, X3, Y3, zs)); }
public override ECPoint Add(ECPoint b) { if (base.IsInfinity) { return(b); } if (b.IsInfinity) { return(this); } ECCurve curve = this.Curve; ECFieldElement eCFieldElement = base.RawXCoord; ECFieldElement rawXCoord = b.RawXCoord; if (eCFieldElement.IsZero) { if (rawXCoord.IsZero) { return(curve.Infinity); } return(b.Add(this)); } else { ECFieldElement rawYCoord = base.RawYCoord; ECFieldElement eCFieldElement2 = base.RawZCoords[0]; ECFieldElement rawYCoord2 = b.RawYCoord; ECFieldElement eCFieldElement3 = b.RawZCoords[0]; bool isOne = eCFieldElement2.IsOne; ECFieldElement eCFieldElement4 = rawXCoord; ECFieldElement eCFieldElement5 = rawYCoord2; if (!isOne) { eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement2); eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2); } bool isOne2 = eCFieldElement3.IsOne; ECFieldElement eCFieldElement6 = eCFieldElement; ECFieldElement eCFieldElement7 = rawYCoord; if (!isOne2) { eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement3); eCFieldElement7 = eCFieldElement7.Multiply(eCFieldElement3); } ECFieldElement eCFieldElement8 = eCFieldElement7.Add(eCFieldElement5); ECFieldElement eCFieldElement9 = eCFieldElement6.Add(eCFieldElement4); if (!eCFieldElement9.IsZero) { ECFieldElement eCFieldElement11; ECFieldElement y; ECFieldElement eCFieldElement13; if (rawXCoord.IsZero) { ECPoint eCPoint = this.Normalize(); eCFieldElement = eCPoint.XCoord; ECFieldElement yCoord = eCPoint.YCoord; ECFieldElement b2 = rawYCoord2; ECFieldElement eCFieldElement10 = yCoord.Add(b2).Divide(eCFieldElement); eCFieldElement11 = eCFieldElement10.Square().Add(eCFieldElement10).Add(eCFieldElement); if (eCFieldElement11.IsZero) { return(new SecT233K1Point(curve, eCFieldElement11, curve.B, base.IsCompressed)); } ECFieldElement eCFieldElement12 = eCFieldElement10.Multiply(eCFieldElement.Add(eCFieldElement11)).Add(eCFieldElement11).Add(yCoord); y = eCFieldElement12.Divide(eCFieldElement11).Add(eCFieldElement11); eCFieldElement13 = curve.FromBigInteger(BigInteger.One); } else { eCFieldElement9 = eCFieldElement9.Square(); ECFieldElement eCFieldElement14 = eCFieldElement8.Multiply(eCFieldElement6); ECFieldElement eCFieldElement15 = eCFieldElement8.Multiply(eCFieldElement4); eCFieldElement11 = eCFieldElement14.Multiply(eCFieldElement15); if (eCFieldElement11.IsZero) { return(new SecT233K1Point(curve, eCFieldElement11, curve.B, base.IsCompressed)); } ECFieldElement eCFieldElement16 = eCFieldElement8.Multiply(eCFieldElement9); if (!isOne2) { eCFieldElement16 = eCFieldElement16.Multiply(eCFieldElement3); } y = eCFieldElement15.Add(eCFieldElement9).SquarePlusProduct(eCFieldElement16, rawYCoord.Add(eCFieldElement2)); eCFieldElement13 = eCFieldElement16; if (!isOne) { eCFieldElement13 = eCFieldElement13.Multiply(eCFieldElement2); } } return(new SecT233K1Point(curve, eCFieldElement11, y, new ECFieldElement[] { eCFieldElement13 }, base.IsCompressed)); } if (eCFieldElement8.IsZero) { return(this.Twice()); } return(curve.Infinity); } }
public Account GetAccount(ECPoint publicKey) { return(GetAccount(publicKey.EncodePoint(true).ToScriptHash())); }
protected override void DeserializeExclusiveData(BinaryReader reader) { PublicKey = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1); }
public override ECPoint TwicePlus(ECPoint b) { if (this.IsInfinity) { return(b); } if (b.IsInfinity) { return(Twice()); } ECCurve curve = this.Curve; ECFieldElement X1 = this.RawXCoord; if (X1.IsZero) { // A point with X == 0 is it's own Additive inverse return(b); } // NOTE: TwicePlus() only optimized for lambda-affine argument ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; if (X2.IsZero || !Z2.IsOne) { return(Twice().Add(b)); } ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; ECFieldElement L2 = b.RawYCoord; ECFieldElement X1Sq = X1.Square(); ECFieldElement L1Sq = L1.Square(); ECFieldElement Z1Sq = Z1.Square(); ECFieldElement L1Z1 = L1.Multiply(Z1); //ECFieldElement T = curve.getA().Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); ECFieldElement L2plus1 = L2.AddOne(); //ECFieldElement A = curve.getA().Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); ECFieldElement B = X2Z1Sq.Add(T).Square(); if (B.IsZero) { if (A.IsZero) { return(b.Twice()); } return(curve.Infinity); } if (A.IsZero) { //return new SecT163K1Point(curve, A, curve.B.sqrt(), withCompression); return(new SecT163K1Point(curve, A, curve.B, IsCompressed)); } ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); return(new SecT163K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed)); }
public override ECPoint Add(ECPoint b) { if (this.IsInfinity) { return(b); } if (b.IsInfinity) { return(this); } ECCurve curve = this.Curve; ECFieldElement X1 = this.RawXCoord; ECFieldElement X2 = b.RawXCoord; if (X1.IsZero) { if (X2.IsZero) { return(curve.Infinity); } return(b.Add(this)); } ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; bool Z1IsOne = Z1.IsOne; ECFieldElement U2 = X2, S2 = L2; if (!Z1IsOne) { U2 = U2.Multiply(Z1); S2 = S2.Multiply(Z1); } bool Z2IsOne = Z2.IsOne; ECFieldElement U1 = X1, S1 = L1; if (!Z2IsOne) { U1 = U1.Multiply(Z2); S1 = S1.Multiply(Z2); } ECFieldElement A = S1.Add(S2); ECFieldElement B = U1.Add(U2); if (B.IsZero) { if (A.IsZero) { return(Twice()); } return(curve.Infinity); } ECFieldElement X3, L3, Z3; if (X2.IsZero) { // TODO This can probably be optimized quite a bit ECPoint p = this.Normalize(); X1 = p.XCoord; ECFieldElement Y1 = p.YCoord; ECFieldElement Y2 = L2; ECFieldElement L = Y1.Add(Y2).Divide(X1); //X3 = L.Square().Add(L).Add(X1).Add(curve.getA()); X3 = L.Square().Add(L).Add(X1).AddOne(); if (X3.IsZero) { //return new SecT163K1Point(curve, X3, curve.B.sqrt(), IsCompressed); return(new SecT163K1Point(curve, X3, curve.B, IsCompressed)); } ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); L3 = Y3.Divide(X3).Add(X3); Z3 = curve.FromBigInteger(BigInteger.One); } else { B = B.Square(); ECFieldElement AU1 = A.Multiply(U1); ECFieldElement AU2 = A.Multiply(U2); X3 = AU1.Multiply(AU2); if (X3.IsZero) { //return new SecT163K1Point(curve, X3, curve.B.sqrt(), IsCompressed); return(new SecT163K1Point(curve, X3, curve.B, IsCompressed)); } ECFieldElement ABZ2 = A.Multiply(B); if (!Z2IsOne) { ABZ2 = ABZ2.Multiply(Z2); } L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); Z3 = ABZ2; if (!Z1IsOne) { Z3 = Z3.Multiply(Z1); } } return(new SecT163K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed)); }
private static ECPoint[] ResizeTable(ECPoint[] a, int length) { ECPoint[] result = new ECPoint[length]; Array.Copy(a, 0, result, 0, a.Length); return(result); }
public void TestIsAllowed() { ContractManifest contractManifest1 = TestUtils.CreateDefaultManifest(); ContractPermission contractPermission1 = ContractPermission.DefaultPermission; contractPermission1.Contract = ContractPermissionDescriptor.Create(UInt160.Zero); Assert.AreEqual(true, contractPermission1.IsAllowed(new ContractState() { Hash = UInt160.Zero, Manifest = contractManifest1 }, "AAA")); contractPermission1.Contract = ContractPermissionDescriptor.CreateWildcard(); ContractManifest contractManifest2 = TestUtils.CreateDefaultManifest(); ContractPermission contractPermission2 = ContractPermission.DefaultPermission; contractPermission2.Contract = ContractPermissionDescriptor.Create(UInt160.Parse("0x0000000000000000000000000000000000000001")); Assert.AreEqual(false, contractPermission2.IsAllowed(new ContractState() { Hash = UInt160.Zero, Manifest = contractManifest2 }, "AAA")); contractPermission2.Contract = ContractPermissionDescriptor.CreateWildcard(); Random random = new(); byte[] privateKey3 = new byte[32]; random.NextBytes(privateKey3); ECPoint publicKey3 = ECCurve.Secp256r1.G * privateKey3; ContractManifest contractManifest3 = TestUtils.CreateDefaultManifest(); contractManifest3.Groups = new ContractGroup[] { new ContractGroup() { PubKey = publicKey3 } }; ContractPermission contractPermission3 = ContractPermission.DefaultPermission; contractPermission3.Contract = ContractPermissionDescriptor.Create(publicKey3); Assert.AreEqual(true, contractPermission3.IsAllowed(new ContractState() { Hash = UInt160.Zero, Manifest = contractManifest3 }, "AAA")); contractPermission3.Contract = ContractPermissionDescriptor.CreateWildcard(); byte[] privateKey41 = new byte[32]; random.NextBytes(privateKey41); ECPoint publicKey41 = ECCurve.Secp256r1.G * privateKey41; byte[] privateKey42 = new byte[32]; random.NextBytes(privateKey42); ECPoint publicKey42 = ECCurve.Secp256r1.G * privateKey42; ContractManifest contractManifest4 = TestUtils.CreateDefaultManifest(); contractManifest4.Groups = new ContractGroup[] { new ContractGroup() { PubKey = publicKey42 } }; ContractPermission contractPermission4 = ContractPermission.DefaultPermission; contractPermission4.Contract = ContractPermissionDescriptor.Create(publicKey41); Assert.AreEqual(false, contractPermission4.IsAllowed(new ContractState() { Hash = UInt160.Zero, Manifest = contractManifest4 }, "AAA")); contractPermission4.Contract = ContractPermissionDescriptor.CreateWildcard(); }
public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated) { ECCurve c = p.Curve; WNafPreCompInfo wnafPreCompInfo = GetWNafPreCompInfo(c.GetPreCompInfo(p, PRECOMP_NAME)); ECPoint[] preComp = wnafPreCompInfo.PreComp; if (preComp == null) { preComp = new ECPoint[] { p }; } int preCompLen = preComp.Length; int reqPreCompLen = 1 << System.Math.Max(0, width - 2); if (preCompLen < reqPreCompLen) { preComp = ResizeTable(preComp, reqPreCompLen); if (reqPreCompLen == 2) { preComp[1] = preComp[0].ThreeTimes(); } else { ECPoint twiceP = wnafPreCompInfo.Twice; if (twiceP == null) { twiceP = preComp[0].Twice(); wnafPreCompInfo.Twice = twiceP; } for (int i = preCompLen; i < reqPreCompLen; i++) { /* * Compute the new ECPoints for the precomputation array. The values 1, 3, 5, ..., * 2^(width-1)-1 times p are computed */ preComp[i] = twiceP.Add(preComp[i - 1]); } } /* * Having oft-used operands in affine form makes operations faster. */ c.NormalizeAll(preComp); } 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); }
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { return(ECAlgorithms.ReferenceMultiply(p, k)); }
private static bool CheckWitness(ApplicationEngine engine, ECPoint pubkey) { return(CheckWitness(engine, Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash())); }
/** * 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); }
private bool Asset_Create(ExecutionEngine engine) { if (Trigger != TriggerType.Application) { return(false); } InvocationTransaction tx = (InvocationTransaction)engine.ScriptContainer; AssetType asset_type = (AssetType)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger(); if (!Enum.IsDefined(typeof(AssetType), asset_type) || asset_type == AssetType.CreditFlag || asset_type == AssetType.DutyFlag || asset_type == AssetType.GoverningToken || asset_type == AssetType.UtilityToken) { return(false); } if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 1024) { return(false); } string name = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray()); Fixed8 amount = new Fixed8((long)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger()); if (amount == Fixed8.Zero || amount < -Fixed8.Penny) { return(false); } if (asset_type == AssetType.Invoice && amount != -Fixed8.Penny) { return(false); } byte precision = (byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger(); if (precision > 8) { return(false); } if (asset_type == AssetType.Share && precision != 0) { return(false); } if (amount != -Fixed8.Penny && amount.GetData() % (long)Math.Pow(10, 8 - precision) != 0) { return(false); } ECPoint owner = ECPoint.DecodePoint(engine.CurrentContext.EvaluationStack.Pop().GetByteArray(), ECCurve.Secp256r1); if (owner.IsInfinity) { return(false); } if (!CheckWitness(engine, owner)) { return(false); } UInt160 admin = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray()); UInt160 issuer = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray()); AssetState asset = Snapshot.Assets.GetOrAdd(tx.Hash, () => new AssetState { AssetId = tx.Hash, AssetType = asset_type, Name = name, Amount = amount, Available = Fixed8.Zero, Precision = precision, Fee = Fixed8.Zero, FeeAddress = new UInt160(), Owner = owner, Admin = admin, Issuer = issuer, Expiration = Snapshot.Height + 1 + 2000000, IsFrozen = false }); engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(asset)); return(true); }
public static void WriteECPoint(byte[] ecPointFormats, ECPoint point, Stream output) { TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, point), output); }
public virtual ECPoint Map(ECPoint p) { return(p.ScaleY(scale)); }
public static ECDomainParameters ReadECParameters(int[] namedCurves, byte[] ecPointFormats, Stream input) { try { byte curveType = TlsUtilities.ReadUint8(input); switch (curveType) { case ECCurveType.explicit_prime: { CheckNamedCurve(namedCurves, NamedCurve.arbitrary_explicit_prime_curves); BigInteger prime_p = ReadECParameter(input); BigInteger a = ReadECFieldElement(prime_p.BitLength, input); BigInteger b = ReadECFieldElement(prime_p.BitLength, input); byte[] baseEncoding = TlsUtilities.ReadOpaque8(input); BigInteger order = ReadECParameter(input); BigInteger cofactor = ReadECParameter(input); ECCurve curve = new FpCurve(prime_p, a, b, order, cofactor); ECPoint basePoint = DeserializeECPoint(ecPointFormats, curve, baseEncoding); return(new ECDomainParameters(curve, basePoint, order, cofactor)); } case ECCurveType.explicit_char2: { CheckNamedCurve(namedCurves, NamedCurve.arbitrary_explicit_char2_curves); int m = TlsUtilities.ReadUint16(input); byte basis = TlsUtilities.ReadUint8(input); if (!ECBasisType.IsValid(basis)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } int k1 = ReadECExponent(m, input), k2 = -1, k3 = -1; if (basis == ECBasisType.ec_basis_pentanomial) { k2 = ReadECExponent(m, input); k3 = ReadECExponent(m, input); } BigInteger a = ReadECFieldElement(m, input); BigInteger b = ReadECFieldElement(m, input); byte[] baseEncoding = TlsUtilities.ReadOpaque8(input); BigInteger order = ReadECParameter(input); BigInteger cofactor = ReadECParameter(input); ECCurve curve = (basis == ECBasisType.ec_basis_pentanomial) ? new F2mCurve(m, k1, k2, k3, a, b, order, cofactor) : new F2mCurve(m, k1, a, b, order, cofactor); ECPoint basePoint = DeserializeECPoint(ecPointFormats, curve, baseEncoding); return(new ECDomainParameters(curve, basePoint, order, cofactor)); } case ECCurveType.named_curve: { int namedCurve = TlsUtilities.ReadUint16(input); if (!NamedCurve.RefersToASpecificNamedCurve(namedCurve)) { /* * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a * specific curve. Values of NamedCurve that indicate support for a class of * explicitly defined curves are not allowed here [...]. */ throw new TlsFatalAlert(AlertDescription.illegal_parameter); } CheckNamedCurve(namedCurves, namedCurve); return(GetParametersForNamedCurve(namedCurve)); } default: throw new TlsFatalAlert(AlertDescription.illegal_parameter); } } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); } }
public Contract GetContract() { publicKeys = listBox1.Items.OfType <string>().Select(p => ECPoint.DecodePoint(p.HexToBytes(), ECCurve.Secp256r1)).ToArray(); return(Contract.CreateMultiSigContract((int)numericUpDown2.Value, publicKeys)); }
private void setupAccountStateWithValues(AccountState accState, out UInt160 scriptHashVal, out ECPoint votesVal, out UInt256 key, out Fixed8 dictVal) { scriptHashVal = new UInt160(); accState.ScriptHash = scriptHashVal; accState.IsFrozen = true; votesVal = new ECPoint(); ECPoint[] array = new ECPoint[] { votesVal }; accState.Votes = array; key = new UInt256(); dictVal = new Fixed8(); Dictionary <UInt256, Fixed8> dict = new Dictionary <UInt256, Fixed8>(); dict.Add(key, dictVal); accState.Balances = dict; }
public PreCompInfo Precompute(PreCompInfo existing) { WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo; int width = System.Math.Max(2, System.Math.Min(MAX_WIDTH, m_minWidth)); int reqPreCompLen = 1 << (width - 2); if (CheckExisting(existingWNaf, width, reqPreCompLen, m_includeNegated)) { existingWNaf.DecrementPromotionCountdown(); return(existingWNaf); } WNafPreCompInfo result = new WNafPreCompInfo(); ECCurve c = m_p.Curve; ECPoint[] preComp = null, preCompNeg = null; ECPoint twiceP = null; if (null != existingWNaf) { int promotionCountdown = existingWNaf.DecrementPromotionCountdown(); result.PromotionCountdown = promotionCountdown; int confWidth = existingWNaf.ConfWidth; result.ConfWidth = confWidth; preComp = existingWNaf.PreComp; preCompNeg = existingWNaf.PreCompNeg; twiceP = existingWNaf.Twice; } width = System.Math.Min(MAX_WIDTH, System.Math.Max(result.ConfWidth, width)); reqPreCompLen = 1 << (width - 2); int iniPreCompLen = 0; if (null == preComp) { preComp = EMPTY_POINTS; } else { iniPreCompLen = preComp.Length; } if (iniPreCompLen < reqPreCompLen) { preComp = WNafUtilities.ResizeTable(preComp, reqPreCompLen); if (reqPreCompLen == 1) { preComp[0] = m_p.Normalize(); } else { int curPreCompLen = iniPreCompLen; if (curPreCompLen == 0) { preComp[0] = m_p; curPreCompLen = 1; } ECFieldElement iso = null; if (reqPreCompLen == 2) { preComp[1] = m_p.ThreeTimes(); } else { ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1]; if (null == isoTwiceP) { isoTwiceP = preComp[0].Twice(); twiceP = isoTwiceP; /* * 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 (!twiceP.IsInfinity && 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); isoTwiceP = 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(isoTwiceP); } } /* * Having oft-used operands in affine form makes operations faster. */ c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso); } } if (m_includeNegated) { int pos; if (null == preCompNeg) { pos = 0; preCompNeg = new ECPoint[reqPreCompLen]; } else { pos = preCompNeg.Length; if (pos < reqPreCompLen) { preCompNeg = WNafUtilities.ResizeTable(preCompNeg, reqPreCompLen); } } while (pos < reqPreCompLen) { preCompNeg[pos] = preComp[pos].Negate(); ++pos; } } result.PreComp = preComp; result.PreCompNeg = preCompNeg; result.Twice = twiceP; result.Width = width; return(result); }
public ECPublicKeyParameters( ECPoint q, ECDomainParameters parameters) : this("EC", q, parameters) { }
// 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)); }
private static byte[] MarshalCurvePoint(ECPoint point) => new X9ECPoint(point, false).GetPointEncoding();