예제 #1
0
        private static IEnumerable <SszElement> GetValues(AttestationDataAndCustodyBit item)
        {
            yield return(item.Data.ToSszContainer());

            // Challengeable bit (SSZ-bool, 1 byte) for the custody of crosslink data
            yield return(item.CustodyBit.ToSszBasicElement());
        }
예제 #2
0
        public static BlsSignature GetAttestationSignature(IServiceProvider testServiceProvider, BeaconState state, AttestationData attestationData, byte[] privateKey, bool custodyBit)
        {
            var signatureDomains    = testServiceProvider.GetService <IOptions <SignatureDomains> >().Value;
            var beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();

            var message     = new AttestationDataAndCustodyBit(attestationData, custodyBit);
            var messageHash = message.HashTreeRoot();
            var domain      = beaconStateAccessor.GetDomain(state, signatureDomains.BeaconAttester, attestationData.Target.Epoch);
            var signature   = TestSecurity.BlsSign(messageHash, privateKey, domain);

            return(signature);
        }
예제 #3
0
        /// <summary>
        /// Check if ``indexed_attestation`` has valid indices and signature.
        /// </summary>
        public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain)
        {
            MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue;
            IList <ValidatorIndex>  bit0Indices             = indexedAttestation.CustodyBit0Indices;
            IList <ValidatorIndex>  bit1Indices             = indexedAttestation.CustodyBit1Indices;

            // Verify no index has custody bit equal to 1 [to be removed in phase 1]
            if (bit1Indices.Count != 0) // [to be removed in phase 1]
            {
                if (_logger.IsWarn())
                {
                    _logger.LogWarning(Event.InvalidIndexedAttestation,
                                       "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has {BitIndicesCount} bit 1 indices.",
                                       indexedAttestation.Data.Index, indexedAttestation.Data.Slot, bit1Indices.Count());
                }
                return(false); //[to be removed in phase 1]
            }

            // Verify max number of indices
            int totalIndices = bit0Indices.Count + bit1Indices.Count;

            if ((ulong)totalIndices > miscellaneousParameters.MaximumValidatorsPerCommittee)
            {
                if (_logger.IsWarn())
                {
                    _logger.LogWarning(Event.InvalidIndexedAttestation,
                                       "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has total indices {TotalIndices}, more than the maximum validators per committe {MaximumValidatorsPerCommittee}.",
                                       indexedAttestation.Data.Index, indexedAttestation.Data.Slot, totalIndices, miscellaneousParameters.MaximumValidatorsPerCommittee);
                }
                return(false);
            }

            // Verify index sets are disjoint
            IEnumerable <ValidatorIndex> intersect = bit0Indices.Intersect(bit1Indices);

            if (intersect.Count() != 0)
            {
                if (_logger.IsWarn())
                {
                    _logger.LogWarning(Event.InvalidIndexedAttestation,
                                       "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has {IntersectingValidatorCount} validator indexes in common between custody bit 0 and custody bit 1.",
                                       indexedAttestation.Data.Index, indexedAttestation.Data.Slot, intersect.Count());
                }
                return(false);
            }

            // Verify indices are sorted
            if (bit0Indices.Count() > 1)
            {
                for (int index = 0; index < bit0Indices.Count() - 1; index++)
                {
                    if (!(bit0Indices[index] < bit0Indices[index + 1]))
                    {
                        if (_logger.IsWarn())
                        {
                            _logger.LogWarning(Event.InvalidIndexedAttestation,
                                               "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because custody bit 0 index {IndexNumber} is not sorted.",
                                               indexedAttestation.Data.Index, indexedAttestation.Data.Slot, index);
                        }
                        return(false);
                    }
                }
            }

            if (bit1Indices.Count() > 1)
            {
                for (int index = 0; index < bit1Indices.Count() - 1; index++)
                {
                    if (!(bit1Indices[index] < bit1Indices[index + 1]))
                    {
                        if (_logger.IsWarn())
                        {
                            _logger.LogWarning(Event.InvalidIndexedAttestation,
                                               "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because custody bit 1 index {IndexNumber} is not sorted.",
                                               indexedAttestation.Data.Index, indexedAttestation.Data.Slot, index);
                        }
                        return(false);
                    }
                }
            }

            // Verify aggregate signature
            IEnumerable <BlsPublicKey> bit0PublicKeys = bit0Indices.Select(x => state.Validators[(int)(ulong)x].PublicKey);
            BlsPublicKey bit0AggregatePublicKey       = _cryptographyService.BlsAggregatePublicKeys(bit0PublicKeys);
            IEnumerable <BlsPublicKey> bit1PublicKeys = bit1Indices.Select(x => state.Validators[(int)(ulong)x].PublicKey);
            BlsPublicKey bit1AggregatePublicKey       = _cryptographyService.BlsAggregatePublicKeys(bit1PublicKeys);

            BlsPublicKey[] publicKeys = new[] { bit0AggregatePublicKey, bit1AggregatePublicKey };

            AttestationDataAndCustodyBit attestationDataAndCustodyBit0 = new AttestationDataAndCustodyBit(indexedAttestation.Data, false);
            Hash32 messageHashBit0 = attestationDataAndCustodyBit0.HashTreeRoot();
            AttestationDataAndCustodyBit attestationDataAndCustodyBit1 = new AttestationDataAndCustodyBit(indexedAttestation.Data, true);
            Hash32 messageHashBit1 = attestationDataAndCustodyBit1.HashTreeRoot();

            Hash32[] messageHashes = new[] { messageHashBit0, messageHashBit1 };

            BlsSignature signature = indexedAttestation.Signature;

            bool isValid = _cryptographyService.BlsVerifyMultiple(publicKeys, messageHashes, signature, domain);

            if (!isValid)
            {
                if (_logger.IsWarn())
                {
                    _logger.LogWarning(Event.InvalidIndexedAttestation,
                                       "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because the aggregate signature does not match.",
                                       indexedAttestation.Data.Index, indexedAttestation.Data.Slot);
                }
                return(false);
            }

            return(true);
        }
예제 #4
0
        public static Hash32 HashTreeRoot(this AttestationDataAndCustodyBit item)
        {
            var tree = new SszTree(item.ToSszContainer());

            return(new Hash32(tree.HashTreeRoot()));
        }
예제 #5
0
 public static SszContainer ToSszContainer(this AttestationDataAndCustodyBit item)
 {
     return(new SszContainer(GetValues(item)));
 }