private TransactionSignature MakeHighS(TransactionSignature sig) { var curveOrder = new NBitcoin.BouncyCastle.Math.BigInteger("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10); var ecdsa = new ECDSASignature(sig.Signature.R, sig.Signature.S.Negate().Mod(curveOrder)); return(new TransactionSignature(ecdsa, sig.SigHash)); }
private string EncodeTarget(double difficulty) { var diff = BigInteger.ValueOf((long)(difficulty * 255d)); var quotient = ZCashConstants.Diff1.Divide(diff).Multiply(BigInteger.ValueOf(255)); var bytes = quotient.ToByteArray(); var padded = ArrayPool <byte> .Shared.Rent(ZCashConstants.TargetPaddingLength); try { Array.Clear(padded, 0, ZCashConstants.TargetPaddingLength); var padLength = ZCashConstants.TargetPaddingLength - bytes.Length; if (padLength > 0) { Array.Copy(bytes, 0, padded, padLength, bytes.Length); bytes = padded; } var result = bytes.ToHexString(0, ZCashConstants.TargetPaddingLength); return(result); } finally { ArrayPool <byte> .Shared.Return(padded); } }
private static ECPoint DecompressKey(NBitcoin.BouncyCastle.Math.BigInteger xBN, bool yBit) { var curve = ECKey.Secp256k1.Curve; byte[] compEnc = X9IntegerConverter.IntegerToBytes(xBN, 1 + X9IntegerConverter.GetByteLength(curve)); compEnc[0] = (byte)(yBit ? 0x03 : 0x02); return(curve.DecodePoint(compEnc)); }
internal static Array BigIntegerToBytes(NBitcoin.BouncyCastle.Math.BigInteger b, int numBytes) { if (b == null) { return(null); } byte[] bytes = new byte[numBytes]; byte[] biBytes = b.ToByteArray(); int start = (biBytes.Length == numBytes + 1) ? 1 : 0; int length = Math.Min(biBytes.Length, numBytes); Array.Copy(biBytes, start, bytes, numBytes - length, length); return(bytes); }
private string EncodeTarget(double difficulty) { var diff = BigInteger.ValueOf((long)(difficulty * 255d)); var quotient = ZCashConstants.Diff1.Divide(diff).Multiply(BigInteger.ValueOf(255)); var bytes = quotient.ToByteArray(); var padded = Enumerable.Repeat((byte)0, 32).ToArray(); if (padded.Length - bytes.Length > 0) { Buffer.BlockCopy(bytes, 0, padded, padded.Length - bytes.Length, bytes.Length); bytes = padded; } var result = bytes.ToHexString(); return(result); }
internal Target ChangeDifficulty(ChainedHeader header, int difficultyAdjustmentDivisor) { NBitcoin.BouncyCastle.Math.BigInteger newTarget = header.Header.Bits.ToBigInteger(); newTarget = newTarget.Divide(NBitcoin.BouncyCastle.Math.BigInteger.ValueOf(difficultyAdjustmentDivisor)); return(new Target(newTarget)); }
public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 message, bool compressed) { if (recId < 0) { throw new ArgumentException("recId should be positive"); } if (sig.R.SignValue < 0) { throw new ArgumentException("r should be positive"); } if (sig.S.SignValue < 0) { throw new ArgumentException("s should be positive"); } if (message == null) { throw new ArgumentNullException(nameof(message)); } var curve = ECKey.Secp256k1; // 1.0 For j from 0 to h (h == recId here and the loop is outside this function) // 1.1 Let x = r + jn var n = curve.N; var i = NBitcoin.BouncyCastle.Math.BigInteger.ValueOf((long)recId / 2); var 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. var prime = ((SecP256K1Curve)curve.Curve).QQ; if (x.CompareTo(prime) >= 0) { return(null); } // Compressed keys 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. var e = new NBitcoin.BouncyCastle.Math.BigInteger(1, message.ToBytes()); // 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. var eInv = NBitcoin.BouncyCastle.Math.BigInteger.Zero.Subtract(e).Mod(n); var rInv = sig.R.ModInverse(n); var srInv = rInv.Multiply(sig.S).Mod(n); var eInvrInv = rInv.Multiply(eInv).Mod(n); ECPoint q = ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv); q = q.Normalize(); if (compressed) { q = new SecP256K1Point(curve.Curve, q.XCoord, q.YCoord, true); } return(new ECKey(q.GetEncoded(), false)); }