private void InitSigner(BigInteger priv) { _signer = new ECDSASigner(new HMacDsaKCalculator(new Sha256Digest())); ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(priv, Secp256K1.Parameters()); _signer.Init(true, privKey); }
protected void SetVerifier(ECPoint pub) { Verifier = new ECDsaSigner(); ECPublicKeyParameters parameters = new ECPublicKeyParameters( pub, Secp256K1.Parameters()); Verifier.Init(false, parameters); }
public static byte[] ComputePublicKey(byte[] publicGenBytes, uint accountNumber) { ECPoint rootPubPoint = Secp256K1.Curve().DecodePoint(publicGenBytes); BigInteger scalar = ComputeScalar(publicGenBytes, accountNumber); ECPoint point = Secp256K1.BasePoint().Multiply(scalar); ECPoint offset = rootPubPoint.Add(point); return(offset.GetEncoded(true)); }
public static BigInteger ComputeSecretKey( BigInteger privateGen, uint accountNumber) { ECPoint publicGen = ComputePublicGenerator(privateGen); return(ComputeScalar(publicGen.GetEncoded(true), accountNumber) .Add(privateGen).Mod(Secp256K1.Order())); }
private EcdsaSignature CreateEcdsaSignature(byte[] hash) { BigInteger[] sigs = _signer.GenerateSignature(hash); var r = sigs[0]; var s = sigs[1]; var otherS = Secp256K1.Order().Subtract(s); if (s.CompareTo(otherS) == 1) { s = otherS; } return(new EcdsaSignature(r, s)); }
/// <param name="seedBytes"> - a bytes sequence of arbitrary length which will be hashed </param> /// <param name="discriminator"> - nullable optional uint32 to hash </param> /// <returns> a number between [1, order -1] suitable as a private key /// </returns> public static BigInteger ComputeScalar(byte[] seedBytes, uint?discriminator) { BigInteger key = null; for (uint i = 0; i <= 0xFFFFFFFFL; i++) { var sha512 = new Sha512(seedBytes); if (discriminator != null) { sha512.AddU32(discriminator.Value); } sha512.AddU32(i); byte[] keyBytes = sha512.Finish256(); key = Misc.UBigInt(keyBytes); if (key.CompareTo(BigInteger.Zero) == 1 && key.CompareTo(Secp256K1.Order()) == -1) { break; } } return(key); }
/// /// <param name="secretKey"> secret point on the curve as BigInteger </param> /// <returns> corresponding public point </returns> public static ECPoint ComputePublicKey(BigInteger secretKey) { return(Secp256K1.BasePoint().Multiply(secretKey)); }
public static bool CheckIsCanonical(byte[] sig, bool strict) { // Make sure signature is canonical // To protect against signature morphing attacks // Signature should be: // <30> <len> [ <02> <lenR> <R> ] [ <02> <lenS> <S> ] // where // 6 <= len <= 70 // 1 <= lenR <= 33 // 1 <= lenS <= 33 int sigLen = sig.Length; if ((sigLen < 8) || (sigLen > 72)) { return(false); } if ((sig[0] != 0x30) || (sig[1] != (sigLen - 2))) { return(false); } // Find R and check its length int rPos = 4, rLen = sig[rPos - 1]; if ((rLen < 1) || (rLen > 33) || ((rLen + 7) > sigLen)) { return(false); } // Find S and check its length int sPos = rLen + 6, sLen = sig[sPos - 1]; if ((sLen < 1) || (sLen > 33) || ((rLen + sLen + 6) != sigLen)) { return(false); } if ((sig[rPos - 2] != 0x02) || (sig[sPos - 2] != 0x02)) { return(false); // R or S have wrong type } if ((sig[rPos] & 0x80) != 0) { return(false); // R is negative } if ((sig[rPos] == 0) && rLen == 1) { return(false); // R is zero } if ((sig[rPos] == 0) && ((sig[rPos + 1] & 0x80) == 0)) { return(false); // R is padded } if ((sig[sPos] & 0x80) != 0) { return(false); // S is negative } if ((sig[sPos] == 0) && sLen == 1) { return(false); // S is zero } if ((sig[sPos] == 0) && ((sig[sPos + 1] & 0x80) == 0)) { return(false); // S is padded } byte[] rBytes = new byte[rLen]; byte[] bytes = new byte[sLen]; Array.Copy(sig, rPos, rBytes, 0, rLen); Array.Copy(sig, sPos, bytes, 0, sLen); BigInteger r = new BigInteger(1, rBytes), s = new BigInteger(1, bytes); BigInteger order = Secp256K1.Order(); if (r.CompareTo(order) != -1 || s.CompareTo(order) != -1) { return(false); // R or S greater than modulus } if (strict) { return(order.Subtract(s).CompareTo(s) != -1); } else { return(true); } }