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))); }
private ExtendedKey GenerateKey(uint index) { Thrower.Condition <AddressException>((index & HardendIndex) != 0 && !this.Master.HasPrivateKey, "A public key can't derivate an hardened child"); byte[] extended; byte[] pub = this.Master.PublicKey.Bytes; if ((index & HardendIndex) == 0) { var sequenceBytes = BitHelper.GetBytes(index, false); extended = pub.ToArray().Concat(sequenceBytes).ToArray(); } else { var priv = this.Master.PrivateKey.Bytes; var sequenceBytes = BitHelper.GetBytes(index, false); extended = (new byte[] { 0 }).Concat(priv.ToArray()).Concat(sequenceBytes).ToArray(); } var leftRight = CryptoUtil.ComputeHmac512(this.ChainCode, extended); var leftKey = leftRight.Take(32).ToArray(); var rightKey = leftRight.Skip(32).ToArray(); BigInteger bigIntegerLeft = new BigInteger(1, leftKey); Thrower.Condition <AddressException>(bigIntegerLeft.CompareTo(EcKey.EcParams.N) >= 0, "This is rather unlikely, but it did just happen"); if (this.Master.HasPrivateKey) { BigInteger key = bigIntegerLeft.Add(new BigInteger(1, this.Master.PrivateKey.Bytes)).Mod(EcKey.EcParams.N); Thrower.Condition <AddressException>(key.Equals(BigInteger.Zero), "This is rather unlikely, but it did just happen"); //// fix the private key in case it needs padding var keyBytes = new EcKey(key).GetPrivKeyBytes(); return(new ExtendedKey(new BitcoinPrivateKey(keyBytes), rightKey, (byte)(this.Depth + 1), this.GenerateFingerPrint(), index)); } else { var qdecoded = EcKey.EcParams.Curve.DecodePoint(this.Master.PublicKey.Bytes); var key = new ECPublicKeyParameters("EC", qdecoded, EcKey.EcParams); var qkey = EcKey.EcParams.G.Multiply(bigIntegerLeft).Add(key.Q); Thrower.Condition <AddressException>(qkey.IsInfinity, "This is rather unlikely, but it did just happen"); var point = new FpPoint(EcKey.EcParams.Curve, qkey.Normalize().XCoord, qkey.Normalize().YCoord, true); return(new ExtendedKey(new BitcoinPublicKey(point.GetEncoded()), rightKey, (byte)(this.Depth + 1), this.GenerateFingerPrint(), index)); } }
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) { var 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; var 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."); } var 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 override byte[] ToByteArray() { return(point.GetEncoded()); }
public void OnClickCreateWalletButton() { if (nodeIP == null) { return; } // packet.GetString(); bool isVerify = false; while (!isVerify) { string sendJson = null; string sendJsonHeader = null; string sendJsonBody = null; JsonData packet = new JsonData(); JsonData header = new JsonData(); JsonData body = new JsonData(); packet["Header"] = header; packet["Body"] = body; //"secp256k1" 세부설정. X9ECParameters ec = SecNamedCurves.GetByName("secp256k1"); ECDomainParameters domainParams = new ECDomainParameters(ec.Curve, ec.G, ec.N, ec.H); SecureRandom random = new SecureRandom(); // Generate EC KeyPair ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); ECKeyGenerationParameters keyParams = new ECKeyGenerationParameters(domainParams, random); keyGen.Init(keyParams); AsymmetricCipherKeyPair keyPair = keyGen.GenerateKeyPair(); ECPublicKeyParameters publicKeyPara = keyPair.Public as ECPublicKeyParameters; ECPrivateKeyParameters privateKeyPara = keyPair.Private as ECPrivateKeyParameters; ECPoint q = publicKeyPara.Q; FpPoint fp = new FpPoint(ec.Curve, q.AffineXCoord, q.AffineYCoord); byte[] enc = fp.GetEncoded(true); string compressedPubKey = BitConverter.ToString(enc).Replace("-", ""); //HexStr으로 표현한 값. 이 publicKey로도 서명이 증명가능. SHA256 mySHA256 = SHA256Managed.Create(); byte[] hashPublicKey = mySHA256.ComputeHash(HexStringTobytes(compressedPubKey)); string hexHashPublicKey = bytesToHexString(hashPublicKey); sendJsonBody = " \"Body\" : { \"Transaction\" : { \"Type\" : 0, \"UserAddress\" : \"" + hexHashPublicKey + "\" } }"; JsonData transaction = new JsonData(); body["Transaction"] = transaction; transaction["Type"] = 0; transaction["UserAddress"] = hexHashPublicKey; //publicKey를 헥사String으로 변환 후 바이트형식으로 인코딩한걸 해쉬 ECDsaSigner privSigner = new ECDsaSigner(); privSigner.Init(true, privateKeyPara); BigInteger[] signature = privSigner.GenerateSignature(Encoding.ASCII.GetBytes(packet["Body"].ToJson())); BigInteger r = signature[0]; BigInteger s = signature[1]; sendJsonHeader = " \"Header\" : { \"Type\" : \"WalletRegist\", \"PublicKey\" : \"" + compressedPubKey + "\", \"EncryptR\" : \"" + bytesToHexString(r.ToByteArray()) + "\", \"EncryptS\" : \"" + bytesToHexString(s.ToByteArray()) + "\" }"; header["Type"] = "WalletRegist"; header["PublicKey"] = compressedPubKey; header["EncryptR"] = bytesToHexString(r.ToByteArray()); header["EncryptS"] = bytesToHexString(s.ToByteArray()); sendJson = "{ " + sendJsonHeader + ", " + sendJsonBody + " }"; byte[] walletRegistOutput = Encoding.ASCII.GetBytes(packet.ToJson()); //Json형식 Str를 byte Array로 해서 보낸다. /* * // 대칭키 인증서 인증이 맞는지 테스트. * BigInteger biPublicKey = new BigInteger(HexStringTobytes(compressedPubKey)); * ECPoint q2 = domainParams.Curve.DecodePoint(biPublicKey.ToByteArray()); * publicKeyPara = new ECPublicKeyParameters(q2, domainParams); * * ECDsaSigner pubSigner = new ECDsaSigner(); * pubSigner.Init(false, publicKeyPara); * Debug.Log(pubSigner.VerifySignature(Encoding.ASCII.GetBytes(packet["Body"].ToJson()), r, s)); */ Debug.Log(packet.ToJson()); TcpClient client = new TcpClient(nodeIP, nodePort); //TcpClient client = new TcpClient("13.209.78.154", 51166); NetworkStream stream = client.GetStream(); stream.Write(walletRegistOutput, 0, walletRegistOutput.Length); System.Array.Clear(buffer, 0, buffer.Length); stream.Read(buffer, 0, buffer.Length); JsonData registResponse = JsonMapper.ToObject(Encoding.ASCII.GetString(buffer)); Debug.Log(Encoding.ASCII.GetString(buffer)); if (registResponse["Body"]["Response"].GetNatural() == 1) { // 만약 등록되면 PlayerPrefs.SetString("PublicKey", compressedPubKey); PlayerPrefs.SetString("PrivateKey", bytesToHexString(privateKeyPara.D.ToByteArray())); PlayerPrefs.SetString("UserAddress", hexHashPublicKey); //지갑이 유효하면 while문을 벗어난다. isVerify = true; } client.Close(); //우선 소켓을 닫는다. } changeState(); OnClickHomeButton(); }
public static byte[] recoverPubBytesFromSignature(int recId, ECDSASignature sig, byte[] messageHash) { check(recId >= 0, "recId must be positive"); check(sig.r.SignValue >= 0, "r must be positive"); check(sig.s.SignValue >= 0, "s must be positive"); check(messageHash != null, "messageHash must not be null"); // 1.0 For j from 0 to h (h == recId here and the loop is outside // this function) // 1.1 Let x = r + jn BigInteger n = ECKey.Curve.N; // Curve order. BigInteger i = BigInteger.ValueOf((long)recId / 2); BigInteger x = sig.r.Add(i.Multiply(n)); // 1.2. Convert the integer x to an octet string X of length mlen // using the conversion routine // specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or // mlen = ⌈m/8⌉. // 1.3. Convert the octet string (16 set binary digits)||X to an // elliptic curve point R using the // conversion routine specified in Section 2.3.4. If this // conversion routine outputs “invalid”, then // do another iteration of Step 1. // // More concisely, what these points mean is to use X as a compressed // public key. Org.BouncyCastle.Math.EC.FpCurve curve = (Org.BouncyCastle.Math.EC.FpCurve)ECKey.Curve.Curve; BigInteger prime = curve.Q; // Bouncy Castle is not consistent // about the letter it uses for the prime. if (x.CompareTo(prime) >= 0) { // Cannot have point co-ordinates larger than this as everything // takes place modulo Q. return(null); } // Compressed allKeys require you to know an extra bit of data about the // y-coord as there are two possibilities. // So it's encoded in the recId. ECPoint R = decompressKey(x, (recId & 1) == 1); // 1.4. If nR != point at infinity, then do another iteration of // Step 1 (callers responsibility). if (!R.Multiply(n).IsInfinity) { return(null); } // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature // verification. BigInteger e = new BigInteger(1, messageHash); // 1.6. For k from 1 to 2 do the following. (loop is outside this // function via iterating recId) // 1.6.1. Compute a candidate public key as: // Q = mi(r) * (sR - eG) // // Where mi(x) is the modular multiplicative inverse. We transform // this into the following: // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) // Where -e is the modular additive inverse of e, that is z such that // z + e = 0 (mod n). In the above equation // ** is point multiplication and + is point addition (the EC group // operator). // // We can find the additive inverse by subtracting e from zero then // taking the mod. For example the additive // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod // 11 = 8. BigInteger eInv = BigInteger.Zero.Subtract(e).Mod(n); BigInteger rInv = sig.r.ModInverse(n); BigInteger srInv = rInv.Multiply(sig.s).Mod(n); BigInteger eInvrInv = rInv.Multiply(eInv).Mod(n); FpPoint q = (FpPoint)ECAlgorithms.SumOfTwoMultiplies(ECKey.Params.G, eInvrInv, R, srInv); return(q.GetEncoded(/* compressed */ false)); }