Esempio n. 1
0
        /// <summary>
        /// Return from ``indices`` a random index sampled by effective balance.
        /// </summary>
        public ValidatorIndex ComputeProposerIndex(BeaconState state, IList <ValidatorIndex> indices, Bytes32 seed)
        {
            if (!indices.Any())
            {
                throw new ArgumentException("Indices can not be empty", nameof(indices));
            }

            ulong          indexCount       = (ulong)indices.Count;
            ValidatorIndex index            = 0UL;
            Span <byte>    randomInputBytes = stackalloc byte[40];

            seed.AsSpan().CopyTo(randomInputBytes);
            while (true)
            {
                ValidatorIndex initialValidatorIndex = (ValidatorIndex)(index % indexCount);
                ValidatorIndex shuffledIndex         = ComputeShuffledIndex(initialValidatorIndex, indexCount, seed);
                ValidatorIndex candidateIndex        = indices[(int)shuffledIndex];

                BinaryPrimitives.WriteUInt64LittleEndian(randomInputBytes.Slice(32), index / 32);
                Bytes32 randomHash = _cryptographyService.Hash(randomInputBytes);
                byte    random     = randomHash.AsSpan()[(int)(index % 32)];

                Gwei effectiveBalance = state.Validators[(int)candidateIndex].EffectiveBalance;
                if ((effectiveBalance * byte.MaxValue) >=
                    (_gweiValueOptions.CurrentValue.MaximumEffectiveBalance * random))
                {
                    return(candidateIndex);
                }

                index++;
            }
        }
Esempio n. 2
0
        // FIXME: This is duplicate of beacon node, need to clean up
        public byte[] GeneratePrivateKey(ulong index)
        {
            Span <byte> input             = new Span <byte>(new byte[32]);
            BigInteger  bigIndex          = new BigInteger(index);
            bool        indexWriteSuccess = bigIndex.TryWriteBytes(input, out int indexBytesWritten, isUnsigned: true, isBigEndian: false);

            if (!indexWriteSuccess || indexBytesWritten == 0)
            {
                throw new Exception("Error getting input for quick start private key generation.");
            }

            Bytes32             bytes32 = Sha256.Compute(input);
            ReadOnlySpan <byte> hash    = bytes32.AsSpan();
            // Mocked start interop specifies to convert the hash as little endian (which is the default for BigInteger)
            BigInteger value      = new BigInteger(hash.ToArray(), isUnsigned: true);
            BigInteger privateKey = value % s_curveOrder;

            // Note that the private key is an *unsigned*, *big endian* number
            // However, we want to pad the big endian on the left to get 32 bytes.
            // So, write as little endian (will pad to right), then reverse.
            // NOTE: Alternative, write to Span 64, and then slice based on bytesWritten to get the padding.
            Span <byte> privateKeySpan  = new Span <byte>(new byte[32]);
            bool        keyWriteSuccess = privateKey.TryWriteBytes(privateKeySpan, out int keyBytesWritten, isUnsigned: true, isBigEndian: false);

            if (!keyWriteSuccess)
            {
                throw new Exception("Error generating quick start private key.");
            }
            privateKeySpan.Reverse();

            return(privateKeySpan.ToArray());
        }
Esempio n. 3
0
        /// <summary>
        /// Return the shuffled validator index corresponding to ``seed`` (and ``index_count``).
        /// </summary>
        public ValidatorIndex ComputeShuffledIndex(ValidatorIndex index, ulong indexCount, Bytes32 seed)
        {
            if (index >= indexCount)
            {
                throw new ArgumentOutOfRangeException(nameof(index), index,
                                                      $"Index should be less than indexCount {indexCount}");
            }

            // Swap or not (https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf)
            // See the 'generalized domain' algorithm on page 3

            Span <byte> pivotHashInput = stackalloc byte[33];

            seed.AsSpan().CopyTo(pivotHashInput);
            Span <byte> sourceHashInput = stackalloc byte[37];

            seed.AsSpan().CopyTo(sourceHashInput);
            for (int currentRound = 0;
                 currentRound < _miscellaneousParameterOptions.CurrentValue.ShuffleRoundCount;
                 currentRound++)
            {
                byte roundByte = (byte)(currentRound & 0xFF);
                pivotHashInput[32] = roundByte;
                Bytes32             pivotHash  = _cryptographyService.Hash(pivotHashInput);
                ReadOnlySpan <byte> pivotBytes = pivotHash.AsSpan().Slice(0, 8);
                ValidatorIndex      pivot      = BinaryPrimitives.ReadUInt64LittleEndian(pivotBytes) % indexCount;

                ValidatorIndex flip = (pivot + indexCount - index) % indexCount;

                ValidatorIndex position = ValidatorIndex.Max(index, flip);

                sourceHashInput[32] = roundByte;
                BinaryPrimitives.WriteUInt32LittleEndian(sourceHashInput.Slice(33), (uint)position / 256);
                Bytes32 source = _cryptographyService.Hash(sourceHashInput.ToArray());

                byte flipByte = source.AsSpan()[(int)((position % 256) / 8)];

                int flipBit = (flipByte >> (int)(position % 8)) % 2;

                if (flipBit == 1)
                {
                    index = flip;
                }
            }

            return(index);
        }
        public Bytes32 Hash(Bytes32 a, Bytes32 b)
        {
            Span <byte> input = new Span <byte>(new byte[Bytes32.Length * 2]);

            a.AsSpan().CopyTo(input);
            b.AsSpan().CopyTo(input.Slice(Bytes32.Length));
            return(Hash(input));
        }
        public Eth1Data GetEth1DataStub(BeaconState state, Epoch currentEpoch)
        {
            TimeParameters timeParameters = _timeParameterOptions.CurrentValue;

            uint        epochsPerPeriod   = timeParameters.SlotsPerEth1VotingPeriod / timeParameters.SlotsPerEpoch;
            ulong       votingPeriod      = (ulong)currentEpoch / epochsPerPeriod;
            Span <byte> votingPeriodBytes = stackalloc byte[32];

            BinaryPrimitives.WriteUInt64LittleEndian(votingPeriodBytes, votingPeriod);
            Bytes32 hashOfVotingPeriod = _cryptographyService.Hash(votingPeriodBytes);

            Root     depositRoot  = new Root(hashOfVotingPeriod.AsSpan());
            ulong    depositCount = state.Eth1DepositIndex;
            Bytes32  blockHash    = _cryptographyService.Hash(hashOfVotingPeriod.AsSpan());
            Eth1Data eth1Data     = new Eth1Data(depositRoot, depositCount, blockHash);

            return(eth1Data);
        }
Esempio n. 6
0
        public static void Ize(out UInt256 root, Bytes32 value)
        {
            ReadOnlySpan <byte> readOnlyBytes = value.AsSpan();

            unsafe
            {
                fixed(byte *buffer = &readOnlyBytes.GetPinnableReference())
                {
                    Span <byte> apiNeedsWriteableEvenThoughOnlyReading = new Span <byte>(buffer, readOnlyBytes.Length);

                    UInt256.CreateFromLittleEndian(out root, apiNeedsWriteableEvenThoughOnlyReading);
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Return the seed at ``epoch``.
        /// </summary>
        public Bytes32 GetSeed(BeaconState state, Epoch epoch, DomainType domainType)
        {
            Epoch mixEpoch = (Epoch)(epoch + _stateListLengthOptions.CurrentValue.EpochsPerHistoricalVector
                                     - _timeParameterOptions.CurrentValue.MinimumSeedLookahead - 1UL);
            // # Avoid underflow
            Bytes32 mix = GetRandaoMix(state, mixEpoch);

            Span <byte> seedHashInput = stackalloc byte[DomainType.Length + sizeof(ulong) + Bytes32.Length];

            domainType.AsSpan().CopyTo(seedHashInput);
            BinaryPrimitives.WriteUInt64LittleEndian(seedHashInput.Slice(DomainType.Length), epoch);
            mix.AsSpan().CopyTo(seedHashInput.Slice(DomainType.Length + sizeof(ulong)));
            Bytes32 seed = _cryptographyService.Hash(seedHashInput);

            return(seed);
        }
Esempio n. 8
0
        /// <summary>
        /// Return the beacon proposer index at the current slot.
        /// </summary>
        public ValidatorIndex GetBeaconProposerIndex(BeaconState state)
        {
            Epoch epoch = GetCurrentEpoch(state);

            Span <byte> seedBytes   = stackalloc byte[40];
            Bytes32     initialSeed = GetSeed(state, epoch, _signatureDomainOptions.CurrentValue.BeaconProposer);

            initialSeed.AsSpan().CopyTo(seedBytes);
            BinaryPrimitives.WriteUInt64LittleEndian(seedBytes.Slice(32), state.Slot);
            Bytes32 seed = _cryptographyService.Hash(seedBytes);

            IList <ValidatorIndex> indices       = GetActiveValidatorIndices(state, epoch);
            ValidatorIndex         proposerIndex = _beaconChainUtility.ComputeProposerIndex(state, indices, seed);

            return(proposerIndex);
        }
Esempio n. 9
0
        /// <summary>
        /// Check if 'leaf' at 'index' verifies against the Merkle 'root' and 'branch'
        /// </summary>
        public bool IsValidMerkleBranch(Bytes32 leaf, IReadOnlyList <Bytes32> branch, int depth, ulong index, Root root)
        {
            Bytes32 value = leaf;

            for (int testDepth = 0; testDepth < depth; testDepth++)
            {
                Bytes32 branchValue  = branch[testDepth];
                ulong   indexAtDepth = index / ((ulong)1 << testDepth);
                if (indexAtDepth % 2 == 0)
                {
                    // Branch on right
                    value = _cryptographyService.Hash(value, branchValue);
                }
                else
                {
                    // Branch on left
                    value = _cryptographyService.Hash(branchValue, value);
                }
            }

            return(value.AsSpan().SequenceEqual(root.AsSpan()));
        }
Esempio n. 10
0
 public static SszElement ToSszBasicVector(this Bytes32 item)
 {
     return(new SszBasicVector(item.AsSpan()));
 }
Esempio n. 11
0
 public static void Encode(Span <byte> span, Bytes32 value)
 {
     Encode(span, value.AsSpan());
 }