public byte[] PerformKeyAgreement (byte[] otherPublicKey1, byte[] otherPublicKey2, int keyDataLength) { ECPoint otherQ1 = new ECPoint (_params.Domain.Group, otherPublicKey1); ECPoint otherQ2 = new ECPoint (_params.Domain.Group, otherPublicKey2); IFiniteField ff = _params.Domain.FieldN; // MQV Primitives if (_params.KeyPair1.D == null) _params.KeyPair1.CreateNewPrivateKey (); if (_params.KeyPair2.D == null) _params.KeyPair2.CreateNewPrivateKey (); if (_params.KeyPair2.Q == null) _params.KeyPair2.CreatePublicKeyFromPrivateKey (); int logBits = _params.Domain.N.BitCount (); logBits = (logBits >> 1) + ((logBits & 1) == 0 ? 0 : 1); Number mod = Number.One << logBits; Number mask = mod - Number.One; Number q2u = (_params.KeyPair2.Q.Export ().X & mask) + mod; Number s = ff.Add (_params.KeyPair2.D, ff.Multiply (q2u, _params.KeyPair1.D)); Number q2v = (otherQ2.Export ().X & mask) + mod; ECPoint P = otherQ2.Add (otherQ1.Multiply (q2v)).Multiply (s * new Number (new uint[] {_params.Domain.H})); if (P.IsInifinity ()) throw new CryptographicException (); int keyBytes = (int)((_params.Domain.Bits >> 3) + ((_params.Domain.Bits & 7) == 0 ? 0 : 1)); byte[] sharedSecretValue = P.Export ().X.ToByteArray (keyBytes, false); // KDF _kdf.SharedInfo = _sharedInfo; return _kdf.Calculate (sharedSecretValue, keyDataLength); }
public byte[] GetAesKey(ECPoint pubkey) { byte[] prikey = new byte[32]; ProtectedMemory.Unprotect(key_exported, MemoryProtectionScope.SameProcess); Buffer.BlockCopy(key_exported, 8 + 64, prikey, 0, 32); ProtectedMemory.Protect(key_exported, MemoryProtectionScope.SameProcess); byte[] aeskey = (pubkey * prikey).EncodePoint(false).Skip(1).Sha256(); Array.Clear(prikey, 0, prikey.Length); return aeskey; }
byte[] PerformKeyAgreement (ECPoint other, int keyDataLength) { // Diffie-Hellman Primitives if (_params.D == null) _params.CreateNewPrivateKey (); Number sharedSecretField = other.Multiply (_params.D).Export ().X; byte[] sharedSecretValue = new byte[(_params.Domain.Bits >> 3) + ((_params.Domain.Bits & 7) == 0 ? 0 : 1)]; sharedSecretField.CopyToBigEndian (sharedSecretValue, 0, sharedSecretValue.Length); // KDF if (_kdf == null) return sharedSecretValue; _kdf.SharedInfo = _sharedInfo; return _kdf.Calculate (sharedSecretValue, keyDataLength); }
public static CertificateQueryResult Query(ECPoint pubkey) { if (pubkey.Equals(Blockchain.AntShare.Issuer) || pubkey.Equals(Blockchain.AntCoin.Issuer)) return new CertificateQueryResult { Type = CertificateQueryResultType.System }; Directory.CreateDirectory(Settings.Default.CertCachePath); string path = Path.Combine(Settings.Default.CertCachePath, $"{pubkey}.cer"); if (!File.Exists(path)) { //TODO: 本地缓存中找不到证书的情况下,去公共服务器上查询 } if (!File.Exists(path)) return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; X509Certificate2 cert; try { cert = new X509Certificate2(path); } catch (CryptographicException) { return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; } if (cert.PublicKey.Oid.Value != "1.2.840.10045.2.1") return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; if (!pubkey.Equals(ECPoint.DecodePoint(cert.PublicKey.EncodedKeyValue.RawData, ECCurve.Secp256r1))) return new CertificateQueryResult { Type = CertificateQueryResultType.Missing }; using (X509Chain chain = new X509Chain()) { CertificateQueryResult result = new CertificateQueryResult { Certificate = cert }; if (chain.Build(cert)) { result.Type = CertificateQueryResultType.Good; } else if (chain.ChainStatus.Length == 1 && chain.ChainStatus[0].Status == X509ChainStatusFlags.NotTimeValid) { result.Type = CertificateQueryResultType.Expired; } else { result.Type = CertificateQueryResultType.Invalid; } return result; } }
private static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { int m = Math.Max(k.GetBitLength(), l.GetBitLength()); ECPoint Z = P + 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 + Z; else R = R + P; } else { if (l.TestBit(i)) R = R + Q; } } return R; }
public byte[] Decrypt (byte[] value) { if (_params.Q == null) { if (_params.D == null) throw new CryptographicException (); _params.CreatePublicKeyFromPrivateKey (); } int domainLen = (int)((_domain.Bits >> 3) + ((_domain.Bits & 7) == 0 ? 0 : 1)); int macKeyLen = _mac.HashSize >> 3; // Step.1 if (value[0] != 2 && value[0] != 3 && value[0] != 4) throw new CryptographicException (); byte[] RBytes = new byte[domainLen + 1]; byte[] EM = new byte[value.Length - RBytes.Length - macKeyLen]; byte[] D = new byte[macKeyLen]; if (value.Length != RBytes.Length + EM.Length + D.Length) throw new CryptographicException (); Array.Copy (value, 0, RBytes, 0, RBytes.Length); Array.Copy (value, RBytes.Length, EM, 0, EM.Length); Array.Copy (value, RBytes.Length + EM.Length, D, 0, D.Length); int encKeyLen = (_symmetricAlgo == null ? EM.Length : _symmetricAlgo.KeySize >> 3);; // Step.2 ECPoint R = new ECPoint (_domain.Group, RBytes); // Step.3 // TODO: Step.3 // Step.4 & 5 // TODO: Cofactor Diffie-Hellmanプリミティブを利用するオプションを追加する byte[] Z = R.Multiply (_params.D).Export ().X.ToByteArray (domainLen, false); // Step.6 byte[] K = _kdf.Calculate (Z, encKeyLen + macKeyLen); // Step.7 byte[] EK = null; if (_symmetricAlgo != null) { EK = new byte[encKeyLen]; for (int i = 0; i < EK.Length; i ++) EK[i] = K[i]; } byte[] MK = new byte[macKeyLen]; for (int i = 0; i < MK.Length; i++) MK[i] = K[K.Length - MK.Length + i]; // Step.8 // TODO: HMAC-SHA1-80への対応 _mac.Key = MK; _mac.Initialize (); _mac.TransformBlock (EM, 0, EM.Length, null, 0); if (_sharedInfo == null) _mac.TransformFinalBlock (EM, 0, 0); else _mac.TransformFinalBlock (_sharedInfo, 0, _sharedInfo.Length); byte[] hash = _mac.Hash; for (int i = 0; i < hash.Length; i ++) if (hash[i] != D[i]) throw new CryptographicException (); // Step.9 byte[] result = new byte[EM.Length]; if (_symmetricAlgo == null) { for (int i = 0; i < result.Length; i ++) result[i] = (byte)(EM[i] ^ K[i]); } else { int blockBytes = _symmetricAlgo.BlockSize >> 3; using (ICryptoTransform transform = _symmetricAlgo.CreateDecryptor (EK, new byte[blockBytes])) { int i = 0; for (; i < result.Length - blockBytes; i += blockBytes) transform.TransformBlock (EM, i, blockBytes, result, i); byte[] temp = transform.TransformFinalBlock (EM, i, EM.Length - i); Buffer.BlockCopy (temp, 0, result, i, temp.Length); if (temp.Length != blockBytes) Array.Resize<byte> (ref result, i + temp.Length); } } return result; }
public BlockConsensusContext(ECPoint my_pubkey) { this.my_pubkey = my_pubkey; Reset(); this.action_request = new TimeoutAction(CreateResponse, TimeSpan.FromSeconds(Blockchain.SecondsPerBlock), () => NoncePieces.Count > Miners.Length * (2.0 / 3.0), () => NoncePieces.Count == Miners.Length - 1); }
public ECDsa(ECPoint publicKey) { this.publicKey = publicKey; this.curve = publicKey.Curve; }
private MinerWallet(byte[] key_exported) { this.key_exported = key_exported; this.PublicKey = ECPoint.FromBytes(key_exported, ECCurve.Secp256r1); ProtectedMemory.Protect(key_exported, MemoryProtectionScope.SameProcess); }