public void SignCompressedCompactTest()
        {
            var key  = Secp256K1Manager.GenerateRandomKey();
            var sw1  = new Stopwatch();
            var rand = new RNGCryptoServiceProvider();

            byte[] msg;
            for (int i = 1; i < 1000; i++)
            {
                msg = new byte[i];
                rand.GetBytes(msg);

                var hash = Sha256Manager.GetHash(msg);

                sw1.Start();
                var signature1 = Secp256K1Manager.SignCompressedCompact(hash, key);
                sw1.Stop();

                Assert.True(signature1.Length == 65);
                Assert.True(Secp256K1Manager.IsCanonical(signature1, 1));
                if (!Secp256K1Manager.IsCanonical(signature1, 1))
                {
                    WriteLine($"signature1 not canonical - skip [{i}]");
                }
            }

            WriteLine($"Secp256K1Manager time {sw1.ElapsedTicks}");
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="propertyApiObj"></param>
        /// <param name="userPrivateKeys"></param>
        /// <param name="token">Throws a <see cref="T:System.OperationCanceledException" /> if this token has had cancellation requested.</param>
        /// <param name="operations"></param>
        /// <returns></returns>
        /// <exception cref="T:System.OperationCanceledException">The token has had cancellation requested.</exception>
        public Task <SignedTransaction> CreateTransactionAsync(DynamicGlobalPropertyObject propertyApiObj, IList <byte[]> userPrivateKeys, BaseOperation[] operations, CancellationToken token)
        {
            return(Task.Run(() =>
            {
                var transaction = new SignedTransaction
                {
                    ChainId = ChainId,
                    RefBlockNum = (ushort)(propertyApiObj.HeadBlockNumber & 0xffff),
                    RefBlockPrefix = (uint)BitConverter.ToInt32(Hex.HexToBytes(propertyApiObj.HeadBlockId), 4),
                    Expiration = propertyApiObj.Time.Value.AddSeconds(30),
                    Operations = operations.Select(o => new Operation(o)).ToArray()
                };

                var msg = MessageSerializer.Serialize <SignedTransaction>(transaction);
                var data = Sha256Manager.GetHash(msg);

                transaction.Signatures = new string[userPrivateKeys.Count];
                for (var i = 0; i < userPrivateKeys.Count; i++)
                {
                    token.ThrowIfCancellationRequested();
                    var userPrivateKey = userPrivateKeys[i];
                    var sig = Secp256K1Manager.SignCompressedCompact(data, userPrivateKey);
                    transaction.Signatures[i] = Hex.ToString(sig);
                }

                return transaction;
            }, token));
        }
예제 #3
0
        public Task <IEnumerable <string> > Sign(string chainId, IEnumerable <string> requiredKeys, byte[] signBytes,
                                                 IEnumerable <string> abiNames = null)
        {
            var data = new List <byte[]>()
            {
                Hex.HexToBytes(chainId),
                signBytes,
                new byte[32]
            };

            var hash = Sha256Manager.GetHash(SerializationHelper.Combine(data));

            return(Task.FromResult(requiredKeys.Select(key =>
            {
                var sign = Secp256K1Manager.SignCompressedCompact(hash, Keys[key]);
                var check = new List <byte[]>()
                {
                    sign, KeyTypeBytes
                };
                var checksum = Ripemd160Manager.GetHash(SerializationHelper.Combine(check)).Take(4).ToArray();
                var signAndChecksum = new List <byte[]>()
                {
                    sign, checksum
                };

                return "SIG_K1_" + Base58.Encode(SerializationHelper.Combine(signAndChecksum));
            })));
        }
예제 #4
0
        public async Task <PushTransaction> PushTransactionAsync(Action[] actions, List <string> privateKeysInWIF)
        {
            logger.Debug("GetInfoAsync");
            //get info
            var info = await GetInfoAsync();

            logger.Debug("GetBlockAsync");
            //get head block
            var block = await GetBlockAsync(info.head_block_id);

            //prepare transaction object
            var transaction = new EOSNewYork.EOSCore.Params.Transaction {
                actions          = actions,
                ref_block_num    = (ushort)(block.block_num & 0xffff),
                ref_block_prefix = block.ref_block_prefix,
                expiration       = new TimePointSec(block.timestamp_datetime.AddSeconds(delaySec))
            };

            //pack the transaction
            var packedTransaction = new PackingSerializer().Serialize <EOSNewYork.EOSCore.Params.Transaction>(transaction);

            //get chain id
            var chainId = Hex.HexToBytes(info.chain_id);

            //combine chainId, packed transaction and 32 empty bytes
            var message = new byte[chainId.Length + packedTransaction.Length + 32];

            Array.Copy(chainId, message, chainId.Length);
            Array.Copy(packedTransaction, 0, message, chainId.Length, packedTransaction.Length);

            //calculate message hash
            var messageHash = Sha256Manager.GetHash(message);

            //get private keys in WIF format
            List <byte[]> privateKeys = new List <byte[]>();

            for (int i = 0; i < privateKeysInWIF.Count; i++)
            {
                privateKeys.Add(WifUtility.DecodePrivateWif(privateKeysInWIF[i]));
            }

            //get signatures for each private key by signing message hash with private key
            string[] signatures = new string[privateKeys.Count];
            for (int i = 0; i < privateKeys.Count; i++)
            {
                signatures[i] = WifUtility.EncodeSignature(Secp256K1Manager.SignCompressedCompact(messageHash, privateKeys[i]));
            }

            logger.Debug("push transaction - GetObjectsFromAPIAsync");
            //push transaction
            return(await new EOS_Object <PushTransaction>(HOST).GetObjectsFromAPIAsync(new PushTransactionParam {
                packed_trx = Hex.ToString(packedTransaction), signatures = signatures, packed_context_free_data = string.Empty, compression = "none"
            }));
        }
예제 #5
0
        public Signature Sign(IEnumerable <byte> data, PrivateKey privateKey)
        {
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data), "Data can not be null");
            }

            if (privateKey is null)
            {
                throw new ArgumentNullException(nameof(privateKey), "Private key can not be null");
            }

            var signature = Secp256K1Manager.SignCompressedCompact(data.ToArray(), privateKey.Bytes);

            return(new Signature(signature));
        }
예제 #6
0
        public void VerifyKeyTypes()
        {
            var key = CryptoHelper.GenerateKeyPair();

            CryptoHelper.PrivKeyStringToBytes(key.PrivateKey);
            CryptoHelper.PubKeyStringToBytes(key.PublicKey);

            var helloBytes = Encoding.UTF8.GetBytes("Hello world!");

            var hash = Sha256Manager.GetHash(helloBytes);

            var sign  = Secp256K1Manager.SignCompressedCompact(hash, CryptoHelper.GetPrivateKeyBytesWithoutCheckSum(key.PrivateKey));
            var check = new List <byte[]>()
            {
                sign, Encoding.UTF8.GetBytes("K1")
            };
            var checksum        = Ripemd160Manager.GetHash(SerializationHelper.Combine(check)).Take(4).ToArray();
            var signAndChecksum = new List <byte[]>()
            {
                sign, checksum
            };

            CryptoHelper.SignStringToBytes("SIG_K1_" + Base58.Encode(SerializationHelper.Combine(signAndChecksum)));
        }
예제 #7
0
        public async Task <OperationResult <PushTransactionResults> > BroadcastActionsAsync(BaseAction[] baseActions, List <byte[]> privateKeys, CancellationToken token)
        {
            var initOpRez = await AbiJsonToBinAsync(baseActions, token).ConfigureAwait(false);

            if (initOpRez.IsError)
            {
                return(new OperationResult <PushTransactionResults>(initOpRez));
            }

            var infoResp = await GetInfoAsync(token).ConfigureAwait(false);

            if (infoResp.IsError)
            {
                return(new OperationResult <PushTransactionResults>(infoResp));
            }

            var info = infoResp.Result;

            var blockArgs = new GetBlockParams
            {
                BlockNumOrId = info.HeadBlockId
            };
            var getBlock = await GetBlockAsync(blockArgs, token).ConfigureAwait(false);

            if (getBlock.IsError)
            {
                return(new OperationResult <PushTransactionResults>(getBlock));
            }

            var block = getBlock.Result;

            var trx = new SignedTransaction
            {
                Actions        = baseActions,
                RefBlockNum    = (ushort)(block.BlockNum & 0xffff),
                RefBlockPrefix = block.RefBlockPrefix,
                Expiration     = block.Timestamp.Value.AddSeconds(30)
            };

            var packedTrx = MessageSerializer.Serialize <SignedTransaction>(trx);

            var chainId = Hex.HexToBytes(info.ChainId);
            var msg     = new byte[chainId.Length + packedTrx.Length + 32];

            Array.Copy(chainId, msg, chainId.Length);
            Array.Copy(packedTrx, 0, msg, chainId.Length, packedTrx.Length);
            var sha256 = Sha256Manager.GetHash(msg);

            var pack = new PackedTransaction
            {
                PackedTrx             = packedTrx,
                Signatures            = new string[privateKeys.Count],
                PackedContextFreeData = new Bytes(),
                Compression           = CompressionType.None
            };

            for (var i = 0; i < privateKeys.Count; i++)
            {
                var key    = privateKeys[i];
                var sig    = Secp256K1Manager.SignCompressedCompact(sha256, key);
                var sigHex = Base58.EncodeSig(sig);
                pack.Signatures[i] = sigHex;
            }

            return(await PushTransactionAsync(pack, token).ConfigureAwait(false));
        }
예제 #8
0
        public async Task <PackedTransaction> CreatePackedTransaction(CreateTransactionArgs args, CancellationToken token)
        {
            //1
            var infoResp = await GetInfo(token);

            if (infoResp.IsError)
            {
                return(null);
            }

            var info = infoResp.Result;

            //2
            var blockArgs = new GetBlockParams
            {
                BlockNumOrId = info.HeadBlockId
            };
            var getBlock = await GetBlock(blockArgs, token);

            if (getBlock.IsError)
            {
                return(null);
            }

            var block = getBlock.Result;

            //3
            var transaction = new SignedTransaction
            {
                RefBlockNum    = (ushort)(block.BlockNum & 0xffff),
                RefBlockPrefix = block.RefBlockPrefix,
                Expiration     = block.Timestamp.Value.AddSeconds(30),
                Actions        = args.Actions
            };

            var packedTrx = MessageSerializer.Serialize <SignedTransaction>(transaction);

            var chainId = Hex.HexToBytes(info.ChainId);
            var msg     = new byte[chainId.Length + packedTrx.Length + 32];

            Array.Copy(chainId, msg, chainId.Length);
            Array.Copy(packedTrx, 0, msg, chainId.Length, packedTrx.Length);
            var sha256 = Sha256Manager.GetHash(msg);

            transaction.Signatures = new string[args.PrivateKeys.Count];
            for (var i = 0; i < args.PrivateKeys.Count; i++)
            {
                var key    = args.PrivateKeys[i];
                var sig    = Secp256K1Manager.SignCompressedCompact(sha256, key);
                var sigHex = Base58.EncodeSig(sig);
                transaction.Signatures[i] = sigHex;
            }

            return(new PackedTransaction
            {
                PackedTrx = Hex.ToString(packedTrx),
                Signatures = transaction.Signatures,
                PackedContextFreeData = "",
                Compression = "none"
            });
        }
예제 #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="propertyApiObj"></param>
        /// <param name="userPrivateKeys"></param>
        /// <param name="token">Throws a <see cref="T:System.OperationCanceledException" /> if this token has had cancellation requested.</param>
        /// <param name="operations"></param>
        /// <returns></returns>
        /// <exception cref="T:System.OperationCanceledException">The token has had cancellation requested.</exception>
        public SignedTransaction CreateTransaction(DynamicGlobalPropertyObject propertyApiObj, IList <byte[]> userPrivateKeys, CancellationToken token, params BaseOperation[] operations)
        {
            var transaction = new SignedTransaction
            {
                //ChainId = ChainId,
                RefBlockNum    = (ushort)(propertyApiObj.HeadBlockNumber & 0xffff),
                RefBlockPrefix = (uint)BitConverter.ToInt32(Hex.HexToBytes(propertyApiObj.HeadBlockId), 4),
                Expiration     = propertyApiObj.Time.AddSeconds(30),
                BaseOperations = operations
            };

            var reqRez = GetRequiredFees(transaction.BaseOperations, (operations[0] as AccountCreateOperation).Fee.AssetId, CancellationToken.None);

            if (!reqRez.IsError)
            {
                (operations[0] as AccountCreateOperation).Fee.Amount = JsonConvert.DeserializeObject <RequiredFees>(reqRez.Result[0].ToString()).amount * 5000;
            }

            VerifyAccountAuthority(
                "nano-blockchain",
                new PublicKeyType[] {
                new PublicKeyType("TEST6HWVwXazrgS3MsWZvvSV6qdRbc8GS7KpdfDw8mAcNug4RcPv3v"),
                //new PublicKeyType("TEST7AX8Ewg85sudNVfwqGcCDEAGnhwyVMgvrWW6bkQT5aDm5fdELM")
            },
                CancellationToken.None
                );

            GetPotentialSignatures(transaction, CancellationToken.None);

            GetRequiredSignatures(
                transaction,
                new PublicKeyType[] {
                new PublicKeyType("TEST6HWVwXazrgS3MsWZvvSV6qdRbc8GS7KpdfDw8mAcNug4RcPv3v"),
                new PublicKeyType("TEST7AX8Ewg85sudNVfwqGcCDEAGnhwyVMgvrWW6bkQT5aDm5fdELM")
            },
                CancellationToken.None
                );

            var remoteHex = Hex.HexToBytes(GetTransactionHex(transaction, CancellationToken.None).Result);
            var localHex  = MessageSerializer.Serialize <SignedTransaction>(transaction);

            string strRez = string.Empty;
            int    limit;

            if (remoteHex.Length > localHex.Length)
            {
                limit = remoteHex.Length;
            }
            else
            {
                limit = localHex.Length;
            }

            for (int i = 0; i < limit; i++)
            {
                if (i >= remoteHex.Length || i >= localHex.Length)
                {
                    if (remoteHex.Length > localHex.Length)
                    {
                        strRez += "[" + i.ToString() + "] " + Hex.HexToInteger(new byte[] { remoteHex[i] }).ToString() + "\n";
                    }
                    else
                    {
                        strRez += "[" + i.ToString() + "]     " + Hex.HexToInteger(new byte[] { localHex[i] }).ToString() + "\n";
                    }
                }
                else
                {
                    strRez += "[" + i.ToString() + "] " + Hex.HexToInteger(new byte[] { remoteHex[i] }).ToString() + " " + Hex.HexToInteger(new byte[] { localHex[i] }).ToString() + "\n";
                }
            }

            UnityEngine.Debug.Log(strRez);
            UnityEngine.Debug.Log("LOCAL HEX =  " + Hex.ToString(localHex));
            UnityEngine.Debug.Log("REMOTE HEX = " + Hex.ToString(remoteHex));

            //for (int i = 0; i < localHex.Length; i++)
            //{
            //    localHex[i] = 0;
            //}

            var data = Sha256Manager.GetHash(Hex.Join(ChainId, localHex));

            transaction.Signatures = new string[userPrivateKeys.Count];
            for (int i = 0; i < userPrivateKeys.Count; i++)
            {
                token.ThrowIfCancellationRequested();
                var userPrivateKey = userPrivateKeys[i];
                var sig            = Secp256K1Manager.SignCompressedCompact(data, userPrivateKey);

                transaction.Signatures[i] = Hex.ToString(sig);
            }

            return(transaction);
        }
예제 #10
0
        /// <summary>
        /// ECDSA with secp256k1
        /// </summary>
        /// <param name="message">message</param>
        /// <param name="privateKey">Private key</param>
        /// <returns></returns>
        public static Signature SignBytes(byte[] message, PrivateKey privateKey)
        {
            var sign = Secp256K1Manager.SignCompressedCompact(Sha256Manager.GetHash(message), privateKey.D.ToByteArrayUnsigned(true));

            return(Signature.FromBytes(sign));
        }