// Digests hashes each segment of each key fragment 26 times and returns them.
// Optionally takes the SpongeFunction to use. Default is Kerl.
41
func Digests(key Trits, spongeFunc ...SpongeFunction) (Trits, error) {
	var err error
	fragments := int(math.Floor(float64(len(key)) / KeyFragmentLength))
	digests := make(Trits, fragments*HashTrinarySize)
	buf := make(Trits, HashTrinarySize)

	h := GetSpongeFunc(spongeFunc, kerl.NewKerl)
	defer h.Reset()

	// iterate through each key fragment
	for i := 0; i < fragments; i++ {
		keyFragment := key[i*KeyFragmentLength : (i+1)*KeyFragmentLength]

		// each fragment consists of 27 segments
		for j := 0; j < KeySegmentsPerFragment; j++ {
			copy(buf, keyFragment[j*HashTrinarySize:(j+1)*HashTrinarySize])

			// hash each segment 26 times
			for k := 0; k < KeySegmentHashRounds; k++ {
				h.Absorb(buf)
				buf, err = h.Squeeze(HashTrinarySize)
				if err != nil {
					return nil, err
				}
				h.Reset()
			}

			copy(keyFragment[j*HashTrinarySize:], buf)
		}

		// hash the key fragment (which now consists of hashed segments)
		if err := h.Absorb(keyFragment); err != nil {
			return nil, err
		}

		buf, err := h.Squeeze(HashTrinarySize)
		if err != nil {
			return nil, err
		}

		copy(digests[i*HashTrinarySize:], buf)

		h.Reset()
	}

	return digests, nil
}
1167377
func checkShards(shards [][]byte, nilok bool) error {
	size := shardSize(shards)
	if size == 0 {
		return ErrShardNoData
	}
	for _, shard := range shards {
		if len(shard) != size {
			if len(shard) != 0 || !nilok {
				return ErrShardSize
			}
		}
	}
	return nil
}
673929
func (f *fragment) Blocks() []FragmentBlock {
	f.mu.Lock()
	defer f.mu.Unlock()

	var a []FragmentBlock

	// Initialize the iterator.
	itr := f.storage.Iterator()
	itr.Seek(0)

	// Initialize block hasher.
	h := newBlockHasher()

	// Iterate over each value in the fragment.
	v, eof := itr.Next()
	if eof {
		return nil
	}
	blockID := int(v / (HashBlockSize * ShardWidth))
	for {
		// Check for multiple block checksums in a row.
		if n := f.readContiguousChecksums(&a, blockID); n > 0 {
			itr.Seek(uint64(blockID+n) * HashBlockSize * ShardWidth)
			v, eof = itr.Next()
			if eof {
				break
			}
			blockID = int(v / (HashBlockSize * ShardWidth))
			continue
		}

		// Reset hasher.
		h.blockID = blockID
		h.Reset()

		// Read all values for the block.
		for ; ; v, eof = itr.Next() {
			// Once we hit the next block, save the value for the next iteration.
			blockID = int(v / (HashBlockSize * ShardWidth))
			if blockID != h.blockID || eof {
				break
			}

			h.WriteValue(v)
		}

		// Cache checksum.
		chksum := h.Sum()
		f.checksums[h.blockID] = chksum

		// Append block.
		a = append(a, FragmentBlock{
			ID:       h.blockID,
			Checksum: chksum,
		})

		// Exit if we're at the end.
		if eof {
			break
		}
	}

	return a
}
545626
func (v *Version) Segments() []int {
	segmentSlice := make([]int, len(v.segments))
	for i, v := range v.segments {
		segmentSlice[i] = int(v)
	}
	return segmentSlice
}
929546
func (txs Txs) Hash() []byte {
	// These allocations will be removed once Txs is switched to [][]byte,
	// ref #2603. This is because golang does not allow type casting slices without unsafe
	txBzs := make([][]byte, len(txs))
	for i := 0; i < len(txs); i++ {
		txBzs[i] = txs[i].Hash()
	}
	return merkle.SimpleHashFromByteSlices(txBzs)
}
345436
func Digest(bundleHash []int8, signatureFragment Trits, startOffset int, spongeFunc ...SpongeFunction) (Trits, error) {
	sigLength := len(signatureFragment)

	secLvl, err := GetSecurityLevel(bundleHash)
	if err != nil {
		return nil, err
	}

	sigFrag := make(Trits, sigLength)
	copy(sigFrag, signatureFragment[:sigLength])

	h := GetSpongeFunc(spongeFunc, kerl.NewKerl)
	defer h.Reset()

	dig := make(Trits, HashTrinarySize)
	sig := make(Trits, HashTrinarySize)

	i := startOffset % int(secLvl)
	for digLength := 0; digLength < sigLength; {
		for j := i * ISSChunkLength; j < (i+1)*ISSChunkLength && digLength < sigLength; j += TrinaryRadix {
			copy(sig, sigFrag[digLength:digLength+HashTrinarySize])

			to := (bundleHash[j] + bundleHash[j+1]*3 + bundleHash[j+2]*9) - MinTryteValue

			for k := 0; k < int(to); k++ {
				err := h.Absorb(sig)
				if err != nil {
					return nil, err
				}
				sig, err = h.Squeeze(HashTrinarySize)
				if err != nil {
					return nil, err
				}
				h.Reset()
			}

			copy(sigFrag[digLength:], sig)
			digLength += HashTrinarySize
		}

		i = (i + 1) % int(secLvl)
	}

	err = h.Absorb(sigFrag)
	if err != nil {
		return nil, err
	}

	dig, err = h.Squeeze(HashTrinarySize)
	if err != nil {
		return nil, err
	}

	return dig, nil
}
323963
func Address(digests Trits, spongeFunc ...SpongeFunction) (Trits, error) {
	h := GetSpongeFunc(spongeFunc, kerl.NewKerl)
	defer h.Reset()

	if err := h.Absorb(digests); err != nil {
		return nil, err
	}
	return h.Squeeze(HashTrinarySize)
}
255822
func newDigest(size int, key []byte) *digest {
	if size != Size && size != Size128 {
		panic("size must be 8 or 16")
	}
	d := new(digest)
	d.k0 = uint64(key[0]) | uint64(key[1])<<8 | uint64(key[2])<<16 | uint64(key[3])<<24 |
		uint64(key[4])<<32 | uint64(key[5])<<40 | uint64(key[6])<<48 | uint64(key[7])<<56
	d.k1 = uint64(key[8]) | uint64(key[9])<<8 | uint64(key[10])<<16 | uint64(key[11])<<24 |
		uint64(key[12])<<32 | uint64(key[13])<<40 | uint64(key[14])<<48 | uint64(key[15])<<56
	d.size = size
	d.Reset()
	return d
}
429544
func (csp *CSP) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error) {
	// Validate arguments
	if opts == nil {
		return nil, errors.New("Invalid opts. It must not be nil.")
	}

	hasher, found := csp.Hashers[reflect.TypeOf(opts)]
	if !found {
		return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts)
	}

	digest, err = hasher.Hash(msg, opts)
	if err != nil {
		return nil, errors.Wrapf(err, "Failed hashing with opts [%v]", opts)
	}

	return
}
1281452
func (t *TxStructure) HKeys(key []byte) ([][]byte, error) {
	var keys [][]byte
	err := t.iterateHash(key, func(field []byte, value []byte) error {
		keys = append(keys, append([]byte{}, field...))
		return nil
	})

	return keys, errors.Trace(err)
}
543122
func HashByteSecret(secret []byte) []byte {
	var r [32]byte
	r = sha256.Sum256([]byte(secret))
	return r[:]
}
1099354
func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) {
	combined := make([]byte, len(in)+len(salt))
	copy(combined, salt)
	copy(combined[len(salt):], in)

	if count < len(combined) {
		count = len(combined)
	}

	done := 0
	var digest []byte
	for i := 0; done < len(out); i++ {
		h.Reset()
		for j := 0; j < i; j++ {
			h.Write(zero[:])
		}
		written := 0
		for written < count {
			if written+len(combined) > count {
				todo := count - written
				h.Write(combined[:todo])
				written = count
			} else {
				h.Write(combined)
				written += len(combined)
			}
		}
		digest = h.Sum(digest[:0])
		n := copy(out[done:], digest)
		done += n
	}
}
764140
func ValidateHashes(hashes ...Hash) Validatable {
	return func() error {
		for i := range hashes {
			if !IsHash(hashes[i]) {
				return errors.Wrapf(ErrInvalidHash, "%s at index %d", hashes[i], i)
			}
		}
		return nil
	}
}
1269637
func (da *DigestAuth) Purge(count int) {
	da.mutex.Lock()
	defer da.mutex.Unlock()
	entries := make([]digestCacheEntry, 0, len(da.clients))
	for nonce, client := range da.clients {
		entries = append(entries, digestCacheEntry{nonce, client.lastSeen})
	}
	cache := digestCache(entries)
	sort.Sort(cache)
	for _, client := range cache[:count] {
		delete(da.clients, client.nonce)
	}
}
1224894
func Key(subseed Trits, securityLevel SecurityLevel, spongeFunc ...SpongeFunction) (Trits, error) {
	h := GetSpongeFunc(spongeFunc, kerl.NewKerl)
	defer h.Reset()

	if err := h.Absorb(subseed); err != nil {
		return nil, err
	}

	key := make(Trits, KeyFragmentLength*int(securityLevel))

	for i := 0; i < int(securityLevel); i++ {
		for j := 0; j < KeySegmentsPerFragment; j++ {
			buf, err := h.Squeeze(HashTrinarySize)
			if err != nil {
				return nil, err
			}
			copy(key[(i*KeySegmentsPerFragment+j)*HashTrinarySize:], buf)
		}
	}

	return key, nil
}
761087
func (p *parser) isHashSegment() bool {
	return p.have(2) && (p.next().Kind == lexer.TokenID) && (p.nextAt(1).Kind == lexer.TokenEquals)
}
1348205
func (d *digest) Sum(in []byte) []byte {
	// Make a copy of d0 so that caller can keep writing and summing.
	d0 := *d
	hash := d0.checkSum()
	return append(in, hash[:]...)
}