Exemple #1
0
        private async Task CollectPiecesWithSecretSharingAsync(SecretSharingInformation secretSharingInformation,
                                                               Hash newInValue, string selfPubkey)
        {
            var encryptedPieces = new Dictionary <string, byte[]>();
            var decryptedPieces = new Dictionary <string, byte[]>();

            var minersCount  = secretSharingInformation.PreviousRound.RealTimeMinersInformation.Count;
            var minimumCount = minersCount.Mul(2).Div(3);
            var secretShares =
                SecretSharingHelper.EncodeSecret(newInValue.ToByteArray(), minimumCount, minersCount);

            foreach (var pair in secretSharingInformation.PreviousRound.RealTimeMinersInformation
                     .OrderBy(m => m.Value.Order).ToDictionary(m => m.Key, m => m.Value.Order))
            {
                var pubkey = pair.Key;
                var order  = pair.Value;

                var plainMessage      = secretShares[order - 1];
                var receiverPublicKey = ByteArrayHelper.HexStringToByteArray(pubkey);
                var encryptedPiece    = await _accountService.EncryptMessageAsync(receiverPublicKey, plainMessage);

                encryptedPieces[pubkey] = encryptedPiece;
                if (secretSharingInformation.PreviousRound.RealTimeMinersInformation.ContainsKey(selfPubkey) &&
                    secretSharingInformation.PreviousRound.RealTimeMinersInformation[selfPubkey].EncryptedPieces
                    .ContainsKey(pubkey))
                {
                    secretSharingInformation.PreviousRound.RealTimeMinersInformation[selfPubkey]
                    .EncryptedPieces[pubkey]
                        = ByteString.CopyFrom(encryptedPiece);
                }
                else
                {
                    continue;
                }

                if (!secretSharingInformation.PreviousRound.RealTimeMinersInformation.ContainsKey(pubkey))
                {
                    continue;
                }

                var encryptedShares =
                    secretSharingInformation.PreviousRound.RealTimeMinersInformation[pubkey].EncryptedPieces;
                if (!encryptedShares.Any())
                {
                    continue;
                }
                var interestingMessage = encryptedShares[selfPubkey];
                var senderPublicKey    = ByteArrayHelper.HexStringToByteArray(pubkey);

                var decryptedPiece =
                    await _accountService.DecryptMessageAsync(senderPublicKey, interestingMessage.ToByteArray());

                decryptedPieces[pubkey] = decryptedPiece;
                secretSharingInformation.PreviousRound.RealTimeMinersInformation[pubkey].DecryptedPieces[selfPubkey]
                    = ByteString.CopyFrom(decryptedPiece);
            }

            _encryptedPieces[secretSharingInformation.CurrentRoundId] = encryptedPieces;
            _decryptedPieces[secretSharingInformation.CurrentRoundId] = decryptedPieces;
        }
Exemple #2
0
        public async Task AddSharingInformationAsync(LogEvent logEvent)
        {
            try
            {
                var selfPubkey = (await _accountService.GetPublicKeyAsync()).ToHex();

                var secretSharingInformation = new SecretSharingInformation();
                secretSharingInformation.MergeFrom(logEvent);

                if (!secretSharingInformation.PreviousRound.RealTimeMinersInformation.ContainsKey(selfPubkey))
                {
                    return;
                }

                var newInValue = await GenerateInValueAsync(secretSharingInformation);

                Logger.LogInformation(
                    $"Add in value {newInValue} for round id {secretSharingInformation.CurrentRoundId}");
                _inValueCache.AddInValue(secretSharingInformation.CurrentRoundId, newInValue);

                if (secretSharingInformation.PreviousRound.RealTimeMinersInformation.Count == 1)
                {
                    return;
                }

                await CollectPiecesWithSecretSharingAsync(secretSharingInformation, newInValue, selfPubkey);

                RevealPreviousInValues(secretSharingInformation, selfPubkey);
            }
            catch (Exception e)
            {
                Logger.LogError($"Error in AddSharingInformationAsync.\n{e.Message}\n{e.StackTrace}");
            }
        }
Exemple #3
0
        protected override async Task ProcessLogEventAsync(Block block, LogEvent logEvent)
        {
            var secretSharingInformation = new SecretSharingInformation();

            secretSharingInformation.MergeFrom(logEvent);
            await _secretSharingService.AddSharingInformationAsync(secretSharingInformation);
        }
Exemple #4
0
        private void RevealPreviousInValues(SecretSharingInformation secretSharingInformation, string selfPubkey)
        {
            var round        = secretSharingInformation.PreviousRound;
            var minersCount  = round.RealTimeMinersInformation.Count;
            var minimumCount = minersCount.Mul(2).Div(3);

            minimumCount = minimumCount == 0 ? 1 : minimumCount;

            var revealedInValues = new Dictionary <string, Hash>();

            foreach (var pair in round.RealTimeMinersInformation.OrderBy(m => m.Value.Order))
            {
                // Skip himself.
                if (pair.Key == selfPubkey)
                {
                    continue;
                }

                var pubkey       = pair.Key;
                var minerInRound = pair.Value;

                if (minerInRound.EncryptedPieces.Count < minimumCount)
                {
                    continue;
                }
                if (minerInRound.DecryptedPieces.Count < minersCount)
                {
                    continue;
                }

                // Reveal another miner's in value for target round:

                var orders = minerInRound.DecryptedPieces.Select((t, i) =>
                                                                 round.RealTimeMinersInformation.Values
                                                                 .First(m => m.Pubkey ==
                                                                        minerInRound.DecryptedPieces.Keys.ToList()[i]).Order)
                             .ToList();

                var sharedParts = minerInRound.DecryptedPieces.Values.ToList()
                                  .Select(s => s.ToByteArray()).ToList();

                var revealedInValue =
                    Hash.FromRawBytes(SecretSharingHelper.DecodeSecret(sharedParts, orders, minimumCount));

                Logger.LogDebug($"Revealed in value of {pubkey} of round {round.RoundNumber}: {revealedInValue}");

                revealedInValues[pubkey] = revealedInValue;
            }

            _revealedInValues[secretSharingInformation.CurrentRoundId] = revealedInValues;
        }
Exemple #5
0
        public Task AddSharingInformationAsync(LogEvent logEvent)
        {
            try
            {
                var secretSharingInformation = new SecretSharingInformation();
                secretSharingInformation.MergeFrom(logEvent);

                var newInValue = GenerateInValue(secretSharingInformation);
                _inValueCacheService.AddInValue(secretSharingInformation.CurrentRoundId, newInValue);

                //Logger.LogTrace(
                //$"Handling sharing information: {secretSharingInformation}. New in value: {newInValue}");

                if (secretSharingInformation.PreviousRound.RealTimeMinersInformation.Count == 1)
                {
                    return(Task.CompletedTask);
                }

                var encryptedPieces = new Dictionary <string, byte[]>();
                var decryptedPieces = new Dictionary <string, byte[]>();

                var minersCount  = secretSharingInformation.PreviousRound.RealTimeMinersInformation.Count;
                var minimumCount = minersCount.Mul(2).Div(3);
                var secretShares =
                    SecretSharingHelper.EncodeSecret(newInValue.ToByteArray(), minimumCount, minersCount);
                var selfPubkey = AsyncHelper.RunSync(_accountService.GetPublicKeyAsync).ToHex();
                foreach (var pair in secretSharingInformation.PreviousRound.RealTimeMinersInformation
                         .OrderBy(m => m.Value.Order).ToDictionary(m => m.Key, m => m.Value.Order))
                {
                    var pubkey = pair.Key;
                    var order  = pair.Value;

                    var plainMessage      = secretShares[order - 1];
                    var receiverPublicKey = ByteArrayHelper.HexStringToByteArray(pubkey);
                    var encryptedPiece    = AsyncHelper.RunSync(() =>
                                                                _accountService.EncryptMessageAsync(receiverPublicKey, plainMessage));
                    encryptedPieces[pubkey] = encryptedPiece;
                    if (secretSharingInformation.PreviousRound.RealTimeMinersInformation.ContainsKey(selfPubkey) &&
                        secretSharingInformation.PreviousRound.RealTimeMinersInformation[selfPubkey].EncryptedPieces
                        .ContainsKey(pubkey))
                    {
                        secretSharingInformation.PreviousRound.RealTimeMinersInformation[selfPubkey]
                        .EncryptedPieces[pubkey]
                            = ByteString.CopyFrom(encryptedPiece);
                    }
                    else
                    {
                        continue;
                    }

                    if (!secretSharingInformation.PreviousRound.RealTimeMinersInformation.ContainsKey(pubkey))
                    {
                        continue;
                    }

                    var encryptedShares =
                        secretSharingInformation.PreviousRound.RealTimeMinersInformation[pubkey].EncryptedPieces;
                    if (!encryptedShares.Any())
                    {
                        continue;
                    }
                    var interestingMessage = encryptedShares[selfPubkey];
                    var senderPublicKey    = ByteArrayHelper.HexStringToByteArray(pubkey);

                    var decryptedPiece = AsyncHelper.RunSync(() =>
                                                             _accountService.DecryptMessageAsync(senderPublicKey, interestingMessage.ToByteArray()));
                    decryptedPieces[pubkey] = decryptedPiece;
                    secretSharingInformation.PreviousRound.RealTimeMinersInformation[pubkey].DecryptedPieces[selfPubkey]
                        = ByteString.CopyFrom(decryptedPiece);
                }

                _encryptedPieces[secretSharingInformation.CurrentRoundId] = encryptedPieces;
                _decryptedPieces[secretSharingInformation.CurrentRoundId] = decryptedPieces;

                RevealPreviousInValues(secretSharingInformation, selfPubkey);

                Logger.LogTrace($"Final secret sharing information: {secretSharingInformation}");
            }
            catch (Exception e)
            {
                Logger.LogError($"Error in AddSharingInformationAsync.\n{e.Message}\n{e.StackTrace}");
            }

            return(Task.CompletedTask);
        }