public void Ok() { BigInteger seed = new BigInteger(DateTime.Now.Ticks) << DateTime.Now.Second; var rnd = new Random(BitConverter.ToInt32(seed.ToByteArray().Take(4).ToArray())); var publicKey = new byte[32]; var secretKey = new byte[64]; var payload = new byte[64]; rnd.NextBytes(publicKey); rnd.NextBytes(secretKey); rnd.NextBytes(payload); var pk = AddressUtils.GetPublicKeyFromAddr("5GWYBLjRtCQLXQmcyyRa6KaF1ihuqLjvVDE2gswJsEMxd9Qm"); var kp = new SR25519Keypair(pk.Bytes, secretKey); var sig = SR25519.Sign(payload, (ulong)payload.Length, kp); var arrayNotSame = new Func <byte[], bool>((btArr) => { return(btArr.GroupBy((i) => i).Count() > 50); }); Assert.True(sig.Length == 64); Assert.True(arrayNotSame(sig)); }
public void ShouldGenerateKeypair() { // Arrange. var seed = "fac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"; var expectedPublic = "46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a"; // Act. var derived = SR25519.GenerateKeypairFromSeed(seed); // Assert. Assert.AreEqual(expectedPublic, Utils.ByteArrayToHexString(derived.Public)); }
public void ShouldSoftDerivePublicKey() { // Arrange. var publicKey = "46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a"; var cc = "0c666f6f00000000000000000000000000000000000000000000000000000000"; var expectedPublic = "40b9675df90efa6069ff623b0fdfcf706cd47ca7452a5056c7ad58194d23440a"; // Act. var derived = SR25519.SoftDerivePublicKey(publicKey, cc); // Assert. Assert.AreEqual(expectedPublic, Utils.ByteArrayToHexString(derived)); }
public void ShouldVrfSignAndVerifyMessageBytes() { // Arrange. var message1 = "Hello, world!"; var message2 = "Hello, Earth!"; // Act. var keys = SR25519.GenerateKeypairFromSeed( "f6dbe0604959f8d4f53ef58754f44391c69cfc87f1b97872abef63161e18c885"); var threshold = Enumerable.Repeat((byte)0xFF, 16).ToArray(); VrfSignResult signResult; var signVerification = SR25519.VrfSignIfLess( Encoding.UTF8.GetBytes(message1), keys, threshold, out signResult ); Assert.IsTrue(signVerification); Assert.AreEqual(Sr25519SignatureResult.Ok, signResult.Result); Assert.IsTrue(signResult.IsLess); VrfVerifyResult verifyResult; var verification1 = SR25519.VrfVerify( Encoding.UTF8.GetBytes(message1), keys.Public, signResult.Output, signResult.Proof, threshold, out verifyResult ); Assert.IsTrue(verification1); Assert.AreEqual(Sr25519SignatureResult.Ok, verifyResult.Result); Assert.IsTrue(verifyResult.IsLess); var verification2 = SR25519.VrfVerify( Encoding.UTF8.GetBytes(message2), keys.Public, signResult.Output, signResult.Proof, threshold, out verifyResult ); Assert.IsFalse(verification2); Assert.AreEqual(Sr25519SignatureResult.EquationFalse, verifyResult.Result); Assert.IsFalse(verifyResult.IsLess); }
public void ShouldSoftDeriveKeypair() { // Arrange. var keys = SR25519.GenerateKeypairFromSeed( "fac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"); var cc = "0c666f6f00000000000000000000000000000000000000000000000000000000"; var expectedPublic = "40b9675df90efa6069ff623b0fdfcf706cd47ca7452a5056c7ad58194d23440a"; // Act. var derived = SR25519.SoftDeriveKeypair(keys, cc); // Assert. Assert.AreEqual(expectedPublic, Utils.ByteArrayToHexString(derived.Public)); }
public void ShouldHardDeriveKeypair() { // Arrange. var keys = SR25519.GenerateKeypairFromSeed( "fac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"); var cc = "14416c6963650000000000000000000000000000000000000000000000000000"; var expectedPublic = "d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"; // Act. var derived = SR25519.HardDeriveKeypair(keys, cc); // Assert. Assert.AreEqual(expectedPublic, Utils.ByteArrayToHexString(derived.Public)); }
public void ShouldSignAndVerifyMessageString() { // Arrange. var message1 = "positive test message"; var message2 = "negative test message"; // Act. var keys = SR25519.GenerateKeypairFromSeed( "f6dbe0604959f8d4f53ef58754f44391c69cfc87f1b97872abef63161e18c885"); var sig = SR25519.Sign(message1, keys); var verification1 = SR25519.Verify(message1, sig, keys.Public); var verification2 = SR25519.Verify(message2, sig, keys.Public); // Assert. Assert.IsTrue(verification1); Assert.IsFalse(verification2); }
public void ShouldSignAndVerifyMessageBytes() { // Arrange. var message1 = "010203040506070809"; var message2 = "090807060504030201"; // Act. var keys = SR25519.GenerateKeypairFromSeed( "f6dbe0604959f8d4f53ef58754f44391c69cfc87f1b97872abef63161e18c885"); var sig = SR25519.Sign(Utils.HexStringToByteArray(message1), keys); var verification1 = SR25519.Verify(Utils.HexStringToByteArray(message1), sig, keys.Public); var verification2 = SR25519.Verify(Utils.HexStringToByteArray(message2), sig, keys.Public); // Assert. Assert.IsTrue(verification1); Assert.IsFalse(verification2); }
private string ExtrinsicQueryString(byte[] encodedMethodBytes, string module, string method, Address sender, string privateKey) { _logger.Info("=== Started Invoking Extrinsic ==="); // Get account Nonce var nonce = GetAccountNonce(sender); var compactNonce = Scale.EncodeCompactInteger(nonce); _logger.Info($"sender nonce: {nonce}"); byte[] mmBuf = new byte[3]; // Module + Method var absoluteIndex = _protocolParams.Metadata.GetModuleIndex(module, false); mmBuf[0] = (byte)_protocolParams.Metadata.GetModuleIndex(module, true); mmBuf[1] = (byte)_protocolParams.Metadata.GetCallMethodIndex(absoluteIndex, method); // Address separator mmBuf[2] = Consts.ADDRESS_SEPARATOR; Extrinsic ce = new Extrinsic(); var completeMessage = new byte[encodedMethodBytes.Length + 3]; mmBuf.CopyTo(completeMessage.AsMemory()); encodedMethodBytes.CopyTo(completeMessage.AsMemory(3)); // memcpy(completeMessage + 3, encodedMethodBytes, encodedMethodBytesSize); ce.Signature.Version = Consts.SIGNATURE_VERSION; var senderPK = _protocolParams.Metadata.GetPublicKeyFromAddr(sender); ce.Signature.SignerPublicKey = senderPK.Bytes; ce.Signature.Nonce = nonce; ce.Signature.Era = ExtrinsicEra.IMMORTAL_ERA; // Format signature payload SignaturePayload sp = new SignaturePayload(); sp.Nonce = nonce; sp.MethodBytesLength = encodedMethodBytes.Length + 3; sp.MethodBytes = completeMessage; sp.Era = ExtrinsicEra.IMMORTAL_ERA; sp.AuthoringBlockHash = _protocolParams.GenesisBlockHash; // Serialize and Sign payload var signaturePayloadBytes = new byte[Consts.MAX_METHOD_BYTES_SZ]; long payloadLength = sp.SerializeBinary(ref signaturePayloadBytes); var secretKeyVec = Converters.StringToByteArray(privateKey); // p/invoke version var kp = new SR25519Keypair(ce.Signature.SignerPublicKey, secretKeyVec); var sig = SR25519.Sign(signaturePayloadBytes, (ulong)payloadLength, kp); ce.Signature.Sr25519Signature = sig; //// adopted version //var sr25519 = new Sr25519(); //var message = signaturePayloadBytes.AsMemory().Slice(0, (int)payloadLength).ToArray(); //var sig2 = sr25519.Sign(secretKeyVec, te.Signature.SignerPublicKey, message); //te.Signature.Sr25519Signature = sig2.ToBytes(); // Copy signature bytes to transaction ce.Signature.Sr25519Signature = sig; var length = Consts.DEFAULT_FIXED_EXSTRINSIC_SIZE + encodedMethodBytes.Length + compactNonce.Length - 1; var compactLength = Scale.EncodeCompactInteger(length); ///////////////////////////////////////// // Serialize message signature and write to buffer long writtenLength = 0; var buf = new byte[2048]; var buf2 = new List <byte>(); // Length writtenLength += Scale.WriteCompactToBuf(compactLength, ref buf, writtenLength); // Signature version buf[writtenLength++] = ce.Signature.Version; // Address separator buf[writtenLength++] = Consts.ADDRESS_SEPARATOR; // Signer public key ce.Signature.SignerPublicKey.CopyTo(buf.AsMemory((int)writtenLength)); writtenLength += Consts.SR25519_PUBLIC_SIZE; // SR25519 Signature ce.Signature.Sr25519Signature.CopyTo(buf.AsMemory((int)writtenLength)); writtenLength += Consts.SR25519_SIGNATURE_SIZE; // Nonce writtenLength += Scale.WriteCompactToBuf(compactNonce, ref buf, writtenLength); // Extrinsic Era buf[writtenLength++] = (byte)ce.Signature.Era; // Serialize and send transaction var teBytes = new byte[Consts.MAX_METHOD_BYTES_SZ]; teBytes = buf; completeMessage.AsMemory().CopyTo(teBytes.AsMemory((int)writtenLength)); long teByteLength = writtenLength + encodedMethodBytes.Length + 3; return($"0x{Converters.ByteArrayToString(teBytes, (int)teByteLength)}"); }
public int SignAndSendTransfer(string sender, string privateKey, string recipient, BigInteger amount, Action <string> callback) { _logger.Info("=== Starting a Transfer Extrinsic ==="); // Get account Nonce var address = new Address { Symbols = sender }; var nonce = GetAccountNonce(address); _logger.Info($"sender nonce: {nonce} "); // Format transaction TransferExtrinsic te = new TransferExtrinsic(); te.Method.ModuleIndex = _protocolParams.BalanceModuleIndex; te.Method.MethodIndex = _protocolParams.TransferMethodIndex; var recipientPK = _protocolParams.Metadata.GetPublicKeyFromAddr(new Address(recipient)); te.Method.ReceiverPublicKey = recipientPK.Bytes; te.Method.Amount = amount; te.Signature.Version = Consts.SIGNATURE_VERSION; var senderPK = _protocolParams.Metadata.GetPublicKeyFromAddr(new Address(sender)); te.Signature.SignerPublicKey = senderPK.Bytes; te.Signature.Nonce = nonce; te.Signature.Era = ExtrinsicEra.IMMORTAL_ERA; // Format signature payload SignaturePayload sp = new SignaturePayload(); sp.Nonce = nonce; var methodBytes = new byte[Consts.MAX_METHOD_BYTES_SZ]; sp.MethodBytesLength = (int)te.SerializeMethodBinary(ref methodBytes); sp.MethodBytes = methodBytes; sp.Era = ExtrinsicEra.IMMORTAL_ERA; sp.AuthoringBlockHash = _protocolParams.GenesisBlockHash; // Serialize and Sign payload var signaturePayloadBytes = new byte[Consts.MAX_METHOD_BYTES_SZ]; long payloadLength = sp.SerializeBinary(ref signaturePayloadBytes); byte[] secretKeyVec = Converters.StringToByteArray(privateKey); // p/invoke version var kp = new SR25519Keypair(te.Signature.SignerPublicKey, secretKeyVec); var sig = SR25519.Sign(signaturePayloadBytes, (ulong)payloadLength, kp); te.Signature.Sr25519Signature = sig; //// adopted version //var sr25519 = new Sr25519(); //var message = signaturePayloadBytes.AsMemory().Slice(0, (int)payloadLength).ToArray(); //var sig2 = sr25519.Sign(secretKeyVec, te.Signature.SignerPublicKey, message); //te.Signature.Sr25519Signature = sig2.ToBytes(); // Serialize and send transaction var teBytes = new byte[Consts.MAX_METHOD_BYTES_SZ]; long teByteLength = te.SerializeBinary(ref teBytes); string teStr = $"0x{Converters.ByteArrayToString(teBytes, (int)teByteLength)}"; var query = new JObject { { "method", "author_submitAndWatchExtrinsic" }, { "params", new JArray { teStr } } }; // Send == Subscribe callback to completion return(Subscribe(query, (json) => { callback(json.ToString()); })); }