public static PubkeyScript GetPubScr(string scr) { var stream = new FastStream(scr.Length / 2 /*A good estimate of size*/); foreach (var item in scr.Split(' ', StringSplitOptions.RemoveEmptyEntries)) { // Handle any hex if (item.StartsWith("0x")) { stream.Write(Helper.HexToBytes(item.Substring(2))); } // All integers such as numbers in multi-sig 1, 2,... else if (long.TryParse(item, out long val)) { new PushDataOp(val).WriteToStream(stream); } // All OP codes that sometime are written as OP_XX and sometimes as XX without OP_ else if (Enum.TryParse(item.StartsWith("OP") ? item.Remove(0, 3) : item, true, out OP op)) { stream.Write((byte)op); } // Handles any OP code that fell through because the name starts with 1 (1DUP instead of DUP1) else if (Enum.TryParse(item.StartsWith("1") ? $"{item.Substring(1)}1" : item, true, out OP op2)) { stream.Write((byte)op2); } // Catch any script that is written badly and is not caught and parsed here else { Assert.True(false, item); } } return(new PubkeyScript(stream.ToByteArray())); }
/// <summary> /// Initializes a new instance of <see cref="ReturnOp"/> using the given <see cref="IScript"/>. /// </summary> /// <exception cref="ArgumentNullException"/> /// <param name="scr">Script to use</param> /// <param name="usePushOp"> /// [Default value = true] /// If true, the data will be included after <see cref="OP.RETURN"/> using <see cref="PushDataOp"/> scheme. /// </param> public ReturnOp(IScript scr, bool usePushOp = true) { if (scr == null) { throw new ArgumentNullException(nameof(scr), "Script can not be null."); } byte[] temp = scr.Data; if (usePushOp) { StackInt size = new StackInt(temp.Length); FastStream stream = new FastStream(temp.Length + 2); stream.Write((byte)OP.RETURN); size.WriteToStream(stream); stream.Write(temp); data = stream.ToByteArray(); } else { data = new byte[temp.Length + 1]; data[0] = (byte)OP.RETURN; Buffer.BlockCopy(temp, 0, data, 1, temp.Length); } }
/// <summary> /// Returns mnemonic (seed words) /// </summary> /// <exception cref="ObjectDisposedException"/> /// <returns>mnemonic (seed words)</returns> public string ToMnemonic() { if (entropy == null) { throw new ObjectDisposedException(nameof(BetterMnemonic)); } var stream = new FastStream(100); int version = 1; int depth = DerivationPath.Indexes.Length; Debug.Assert(version <= 0b00001111); Debug.Assert(depth <= 0b00001111); stream.Write((byte)(version << 4 | depth)); foreach (var item in DerivationPath.Indexes) { stream.Write(item); } stream.WriteWithCompactIntLength(entropy); uint[] wordIndexes = Convert8To11(stream); StringBuilder sb = new StringBuilder(wordIndexes.Length * 8); for (int i = 0; i < wordIndexes.Length; i++) { sb.Append($"{allWords[wordIndexes[i]]} "); } // no space at the end. sb.Length--; return(sb.ToString()); }
public void GetSizeTest() { var stream = new FastStream(); int s1 = stream.GetSize(); stream.Write((byte)1); int s2 = stream.GetSize(); stream.Write(1); int s3 = stream.GetSize(); Assert.Equal(0, s1); Assert.Equal(1, s2); Assert.Equal(5, s3); }
/// <summary> /// Writes <see cref="OP.CodeSeparator"/> to stream only if it was not executed. /// </summary> /// <param name="stream">Stream to use</param> public override void WriteToStreamForSigningSegWit(FastStream stream) { if (!IsExecuted) { stream.Write((byte)OpValue); } }
/// <summary> /// Returns base58-encoded string representation of this instance. /// </summary> /// <exception cref="ObjectDisposedException"/> /// <exception cref="ArgumentNullException"/> /// <param name="xType">Extended key type to return</param> /// <returns>Base58-encoded extended key</returns> public string ToBase58(XType xType) { if (isDisposed) { throw new ObjectDisposedException(nameof(BIP0032), "Instance was disposed."); } bool isPub = IsPublic(xType); if (!isPub && PrvKey is null) { throw new ArgumentNullException(nameof(PrvKey), "Can not get extended private key from public key."); } FastStream stream = new FastStream(ExtendedKeyLength); stream.WriteBigEndian((uint)xType); stream.Write(ExtendedKeyDepth); stream.Write(ParentFingerPrint); stream.Write(ChildNumber); stream.Write(ChainCode); if (isPub) { stream.Write(PubKey.ToByteArray(true)); } else { stream.Write((byte)0); stream.Write(PrvKey.ToBytes()); } return(Base58.EncodeWithChecksum(stream.ToByteArray())); }
public void Write_byte_ResizeTest() { var stream = new FastStream(1); Helper.ComparePrivateField(stream, "buffer", new byte[1]); stream.Write((byte)1); Helper.ComparePrivateField(stream, "buffer", new byte[1] { 1 }); stream.Write((byte)2); byte[] expBuffer = new byte[1 + FastStream.DefaultCapacity]; expBuffer[0] = 1; expBuffer[1] = 2; Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", sizeof(byte) * 2); }
public void ToByteArrayTest() { var stream = new FastStream(); byte[] ba1 = stream.ToByteArray(); stream.Write((byte)1); byte[] ba2 = stream.ToByteArray(); stream.Write(2); byte[] ba3 = stream.ToByteArray(); Assert.Equal(Array.Empty <byte>(), ba1); Assert.Equal(new byte[1] { 1 }, ba2); Assert.Equal(new byte[5] { 1, 2, 0, 0, 0 }, ba3); }
/// <summary> /// Returns the 256-bit result of double SHA-256 hash of the message with the added constant used in signing operation. /// </summary> /// <exception cref="ArgumentNullException"/> /// <param name="message"> /// UTF-8 encoded message to sign (will be normalized using full compatibility decomposition form). /// <para/>Note that trailing spaces, new line character,... will not be changed here. /// Caller has to decide whether to change those /// </param> /// <returns>256-bit hash</returns> public byte[] GetBytesToSign(string message) { if (message is null) { throw new ArgumentNullException(nameof(message), "Message can not be null."); } using Sha256 hash = new Sha256(); FastStream stream = new FastStream(); stream.Write((byte)Constants.MsgSignConst.Length); stream.Write(Encoding.UTF8.GetBytes(Constants.MsgSignConst)); byte[] messageBytes = Encoding.UTF8.GetBytes(message.Normalize(NormalizationForm.FormKD)); stream.WriteWithCompactIntLength(messageBytes); byte[] result = hash.ComputeHashTwice(stream.ToByteArray()); return(result); }
private uint[] Convert8To11(FastStream stream) { using Sha256 sha = new Sha256(); byte[] hash = sha.ComputeHash(stream.ToByteArray()); int bitSize = stream.GetSize() * 8; int cs = 11 - (bitSize % 11); if (cs < 4) { cs += 11; } Debug.Assert(cs >= 4 && cs <= 14); stream.Write(hash, 0, cs > 8 ? 2 : 1); bitSize += cs; int wordCount = bitSize / 11; Debug.Assert(bitSize % 11 == 0); byte[] ba = stream.ToByteArray(); uint[] bits = new uint[(int)Math.Ceiling((double)bitSize / 32)]; for (int i = 0, j = 0; j < bits.Length; i += 4, j++) { bits[j] = (uint)(ba[i + 3] | (ba[i + 2] << 8) | (ba[i + 1] << 16) | (ba[i] << 24)); } int itemIndex = 0; int bitIndex = 0; // Number of bits in a word int toTake = 11; // UInt32 is 32 bit! int maxBits = 32; uint[] wordIndexes = new uint[wordCount]; for (int i = 0; i < wordIndexes.Length; i++) { if (bitIndex + toTake <= maxBits) { wordIndexes[i] = (bits[itemIndex] << bitIndex) >> (maxBits - toTake); } else { wordIndexes[i] = ((bits[itemIndex] << bitIndex) >> (maxBits - toTake)) | (bits[itemIndex + 1] >> (maxBits - toTake + maxBits - bitIndex)); } bitIndex += toTake; if (bitIndex >= maxBits) { bitIndex -= maxBits; itemIndex++; } } return(wordIndexes); }
public void Write_bytesFromIndex_ZeroCount_test() { var stream = new FastStream(10); byte[] data = new byte[] { 1, 2, 3, 4, 5 }; stream.Write(data, 1, 0); Assert.Equal(Array.Empty <byte>(), stream.ToByteArray()); Helper.ComparePrivateField(stream, "position", 0); }
public void Write_bytesFromIndex_test() { var stream = new FastStream(10); byte[] data = new byte[] { 1, 2, 3, 4, 5 }; stream.Write(data, 1, 3); byte[] expBuffer = new byte[] { 2, 3, 4 }; Assert.Equal(expBuffer, stream.ToByteArray()); Helper.ComparePrivateField(stream, "position", expBuffer.Length); }
private bool CheckMessage(string message, out byte[] toSign) { try { FastStream stream = new FastStream(); byte[] msgBa = Encoding.UTF8.GetBytes(message); stream.Write((byte)MessageSignConstant.Length); stream.Write(Encoding.UTF8.GetBytes(MessageSignConstant)); new CompactInt((ulong)msgBa.Length).WriteToStream(stream); stream.Write(msgBa); toSign = hash.ComputeHash(stream.ToByteArray()); return(true); } catch (Exception) { toSign = null; return(false); } }
public void Write_ulongTest(ulong val, byte[] expected) { FastStream stream = new FastStream(); stream.Write(val); byte[] expBuffer = new byte[Capacity]; Buffer.BlockCopy(expected, 0, expBuffer, 0, expected.Length); Assert.Equal(expected, stream.ToByteArray()); Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", 8); }
public void Write_bytes_bigTest() { var stream = new FastStream(1); byte[] data = Helper.GetBytes(FastStream.DefaultCapacity + 10); stream.Write(data); byte[] expBuffer = data; Assert.Equal(data, stream.ToByteArray()); Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", data.Length); }
public void Write_intTest(int val, byte[] expected) { var stream = new FastStream(10); stream.Write(val); byte[] expBuffer = new byte[10]; Buffer.BlockCopy(expected, 0, expBuffer, 0, expected.Length); Assert.Equal(expected, stream.ToByteArray()); Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", 4); }
public void Write_bytes_smallTest(byte[] data) { FastStream stream = new FastStream(); stream.Write(data); byte[] expBuffer = new byte[Capacity]; Buffer.BlockCopy(data, 0, expBuffer, 0, data.Length); Assert.Equal(data, stream.ToByteArray()); Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", data.Length); }
public void Write_bytes_withPadTest(byte[] data, int pad, byte[] expBytes) { var stream = new FastStream(10); stream.Write(data, pad); byte[] expBuffer = new byte[10]; Buffer.BlockCopy(data, 0, expBuffer, 0, data.Length); Assert.Equal(expBytes, stream.ToByteArray()); Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", expBytes.Length); }
public void TrySetWordListTest() { var serv = new MnemonicSevice(null); Array wls = Enum.GetValues(typeof(BIP0039.WordLists)); byte[] space = Encoding.UTF8.GetBytes(" "); Assert.Single(space); foreach (BIP0039.WordLists item in wls) { bool b = serv.TrySetWordList(item, out string[] words, out int actualMaxWordLen); Assert.True(b); Assert.Equal(2048, words.Length); string bigSeed = string.Join(" ", words); int expectedMaxWordLen = 0; FastStream stream = new FastStream(37831); for (int i = 0; i < words.Length; i++) { byte[] wordBa = Encoding.UTF8.GetBytes(words[i]); stream.Write(wordBa); if (expectedMaxWordLen < wordBa.Length) { expectedMaxWordLen = wordBa.Length; } if (i != 2047) { stream.Write(space); } } byte[] actual = stream.ToByteArray(); byte[] expected = Encoding.UTF8.GetBytes(bigSeed); Assert.Equal(expected, actual); Assert.Equal(expectedMaxWordLen, actualMaxWordLen); } }
/// <inheritdoc/> public override void Serialize(FastStream stream) { CompactInt count = new CompactInt(Headers.Length); count.WriteToStream(stream); foreach (var hd in Headers) { hd.SerializeHeader(stream); // Block serialization of header doesn't add tx count since there is no need for it. // However, in a header payload (for unknown reason) one extra byte indicating zero tx count // is added to each block header. stream.Write((byte)0); } }
public void Write_ushort_ResizeTest() { var stream = new FastStream(1); Helper.ComparePrivateField(stream, "buffer", new byte[1]); stream.Write((ushort)31534); byte[] expBuffer = new byte[1 + FastStream.DefaultCapacity]; expBuffer[0] = 0x2e; expBuffer[1] = 0x7b; Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", sizeof(ushort)); }
public void Write_bytes_withPad_ResizeTest() { var stream = new FastStream(1); byte[] data = new byte[] { 1, 2 }; byte[] expBytes = new byte[] { 1, 2, 0 }; stream.Write(data, 3); byte[] expBuffer = new byte[FastStream.DefaultCapacity + 1]; Buffer.BlockCopy(data, 0, expBuffer, 0, data.Length); Assert.Equal(expBytes, stream.ToByteArray()); Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", expBytes.Length); }
public void Write_byteTest(byte val) { var stream = new FastStream(10); stream.Write(val); byte[] expBuffer = new byte[10]; expBuffer[0] = val; Assert.Equal(new byte[1] { val }, stream.ToByteArray()); Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", 1); }
/// <summary> /// Initializes a new instance of <see cref="ReturnOp"/> using the given data. /// </summary> /// <param name="ba">Data to use (can be null)</param> /// <param name="usePushOp"> /// [Default value = true] /// If true, the data will be included after <see cref="OP.RETURN"/> using <see cref="PushDataOp"/> scheme. /// </param> public ReturnOp(byte[] ba, bool usePushOp = true) { if (ba == null || ba.Length == 0) { data = new byte[1] { (byte)OP.RETURN }; } else if (usePushOp) { StackInt size = new StackInt(ba.Length); FastStream stream = new FastStream(ba.Length + 2); stream.Write((byte)OP.RETURN); size.WriteToStream(stream); stream.Write(ba); data = stream.ToByteArray(); } else { data = new byte[ba.Length + 1]; data[0] = (byte)OP.RETURN; Buffer.BlockCopy(ba, 0, data, 1, ba.Length); } }
public void Write_bytes_ResizeTest() { var stream = new FastStream(2); Helper.ComparePrivateField(stream, "buffer", new byte[2]); stream.Write(new byte[] { 1, 2, 3 }); byte[] expBuffer = new byte[2 + FastStream.DefaultCapacity]; expBuffer[0] = 1; expBuffer[1] = 2; expBuffer[2] = 3; Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", 3); }
public void Write_uint_ResizeTest() { var stream = new FastStream(1); Helper.ComparePrivateField(stream, "buffer", new byte[1]); stream.Write(1274051374U); byte[] expBuffer = new byte[1 + FastStream.DefaultCapacity]; expBuffer[0] = 0x2e; expBuffer[1] = 0x7b; expBuffer[2] = 0xf0; expBuffer[3] = 0x4b; Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", sizeof(uint)); }
public void Write_int_ResizeTest() { var stream = new FastStream(1); Helper.ComparePrivateField(stream, "buffer", new byte[1]); stream.Write(184104331); byte[] expBuffer = new byte[1 + FastStream.DefaultCapacity]; expBuffer[0] = 0x8b; expBuffer[1] = 0x35; expBuffer[2] = 0xf9; expBuffer[3] = 0x0a; Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", sizeof(int)); }
/// <inheritdoc/> public void Serialize(FastStream stream) { if (Items == null || Items.Length == 0) { stream.Write((byte)0); } else { CompactInt count = new CompactInt(Items.Length); count.WriteToStream(stream); foreach (var item in Items) { item.WriteToWitnessStream(stream); } } }
public void Resize_bigTest() { var stream = new FastStream(); int dataLen = FastStream.DefaultCapacity + (FastStream.DefaultCapacity + 5); byte[] data = Helper.GetBytes(dataLen); stream.Write(data); int actualSize = stream.GetSize(); int expectedSize = dataLen; byte[] expBuffer = new byte[dataLen]; Buffer.BlockCopy(data, 0, expBuffer, 0, data.Length); Assert.Equal(expectedSize, actualSize); Helper.ComparePrivateField(stream, "buffer", expBuffer); }
public void Write_stream_ResizeTest() { var stream = new FastStream(2); var toWrite = new FastStream(8); toWrite.Write(new byte[] { 1, 2, 3 }); stream.Write(toWrite); byte[] expBuffer = new byte[FastStream.DefaultCapacity + 2]; expBuffer[0] = 1; expBuffer[1] = 2; expBuffer[2] = 3; Assert.Equal(new byte[3] { 1, 2, 3 }, stream.ToByteArray()); Helper.ComparePrivateField(stream, "buffer", expBuffer); Helper.ComparePrivateField(stream, "position", 3); }