diff options
author | hiddenpath <hiddenpath@yandex-team.com> | 2024-04-02 23:50:23 +0300 |
---|---|---|
committer | hiddenpath <hiddenpath@yandex-team.com> | 2024-04-03 00:02:31 +0300 |
commit | 8923c6d2c438e0aeed2e06b8b0275e1864eeee33 (patch) | |
tree | 6b5e476699fc0be5091cb650654ef5f602c8afff /contrib/go/_std_1.22/src/hash | |
parent | d18afd09df2a08cd023012593b46109b77713a6c (diff) | |
download | ydb-8923c6d2c438e0aeed2e06b8b0275e1864eeee33.tar.gz |
Update golang to 1.22.1
2967d19c907adf59101a1f47b4208bd0b04a6186
Diffstat (limited to 'contrib/go/_std_1.22/src/hash')
-rw-r--r-- | contrib/go/_std_1.22/src/hash/adler32/adler32.go | 138 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/adler32/ya.make | 7 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/crc32/crc32.go | 268 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/crc32/crc32_amd64.go | 225 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/crc32/crc32_amd64.s | 279 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/crc32/crc32_arm64.go | 50 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/crc32/crc32_arm64.s | 97 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/crc32/crc32_generic.go | 89 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/crc32/ya.make | 17 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/fnv/fnv.go | 376 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/fnv/ya.make | 7 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/hash.go | 58 | ||||
-rw-r--r-- | contrib/go/_std_1.22/src/hash/ya.make | 7 |
13 files changed, 1618 insertions, 0 deletions
diff --git a/contrib/go/_std_1.22/src/hash/adler32/adler32.go b/contrib/go/_std_1.22/src/hash/adler32/adler32.go new file mode 100644 index 0000000000..07695e947a --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/adler32/adler32.go @@ -0,0 +1,138 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package adler32 implements the Adler-32 checksum. +// +// It is defined in RFC 1950: +// +// Adler-32 is composed of two sums accumulated per byte: s1 is +// the sum of all bytes, s2 is the sum of all s1 values. Both sums +// are done modulo 65521. s1 is initialized to 1, s2 to zero. The +// Adler-32 checksum is stored as s2*65536 + s1 in most- +// significant-byte first (network) order. +package adler32 + +import ( + "errors" + "hash" +) + +const ( + // mod is the largest prime that is less than 65536. + mod = 65521 + // nmax is the largest n such that + // 255 * n * (n+1) / 2 + (n+1) * (mod-1) <= 2^32-1. + // It is mentioned in RFC 1950 (search for "5552"). + nmax = 5552 +) + +// The size of an Adler-32 checksum in bytes. +const Size = 4 + +// digest represents the partial evaluation of a checksum. +// The low 16 bits are s1, the high 16 bits are s2. +type digest uint32 + +func (d *digest) Reset() { *d = 1 } + +// New returns a new hash.Hash32 computing the Adler-32 checksum. Its +// Sum method will lay the value out in big-endian byte order. The +// returned Hash32 also implements [encoding.BinaryMarshaler] and +// [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal +// state of the hash. +func New() hash.Hash32 { + d := new(digest) + d.Reset() + return d +} + +func (d *digest) Size() int { return Size } + +func (d *digest) BlockSize() int { return 4 } + +const ( + magic = "adl\x01" + marshaledSize = len(magic) + 4 +) + +func (d *digest) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize) + b = append(b, magic...) + b = appendUint32(b, uint32(*d)) + return b, nil +} + +func (d *digest) UnmarshalBinary(b []byte) error { + if len(b) < len(magic) || string(b[:len(magic)]) != magic { + return errors.New("hash/adler32: invalid hash state identifier") + } + if len(b) != marshaledSize { + return errors.New("hash/adler32: invalid hash state size") + } + *d = digest(readUint32(b[len(magic):])) + return nil +} + +// appendUint32 is semantically the same as [binary.BigEndian.AppendUint32] +// We copied this function because we can not import "encoding/binary" here. +func appendUint32(b []byte, x uint32) []byte { + return append(b, + byte(x>>24), + byte(x>>16), + byte(x>>8), + byte(x), + ) +} + +// readUint32 is semantically the same as [binary.BigEndian.Uint32] +// We copied this function because we can not import "encoding/binary" here. +func readUint32(b []byte) uint32 { + _ = b[3] + return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 +} + +// Add p to the running checksum d. +func update(d digest, p []byte) digest { + s1, s2 := uint32(d&0xffff), uint32(d>>16) + for len(p) > 0 { + var q []byte + if len(p) > nmax { + p, q = p[:nmax], p[nmax:] + } + for len(p) >= 4 { + s1 += uint32(p[0]) + s2 += s1 + s1 += uint32(p[1]) + s2 += s1 + s1 += uint32(p[2]) + s2 += s1 + s1 += uint32(p[3]) + s2 += s1 + p = p[4:] + } + for _, x := range p { + s1 += uint32(x) + s2 += s1 + } + s1 %= mod + s2 %= mod + p = q + } + return digest(s2<<16 | s1) +} + +func (d *digest) Write(p []byte) (nn int, err error) { + *d = update(*d, p) + return len(p), nil +} + +func (d *digest) Sum32() uint32 { return uint32(*d) } + +func (d *digest) Sum(in []byte) []byte { + s := uint32(*d) + return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s)) +} + +// Checksum returns the Adler-32 checksum of data. +func Checksum(data []byte) uint32 { return uint32(update(1, data)) } diff --git a/contrib/go/_std_1.22/src/hash/adler32/ya.make b/contrib/go/_std_1.22/src/hash/adler32/ya.make new file mode 100644 index 0000000000..228bc3fcfc --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/adler32/ya.make @@ -0,0 +1,7 @@ +GO_LIBRARY() +IF (TRUE) + SRCS( + adler32.go + ) +ENDIF() +END() diff --git a/contrib/go/_std_1.22/src/hash/crc32/crc32.go b/contrib/go/_std_1.22/src/hash/crc32/crc32.go new file mode 100644 index 0000000000..170f05cf8a --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/crc32/crc32.go @@ -0,0 +1,268 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package crc32 implements the 32-bit cyclic redundancy check, or CRC-32, +// checksum. See https://en.wikipedia.org/wiki/Cyclic_redundancy_check for +// information. +// +// Polynomials are represented in LSB-first form also known as reversed representation. +// +// See https://en.wikipedia.org/wiki/Mathematics_of_cyclic_redundancy_checks#Reversed_representations_and_reciprocal_polynomials +// for information. +package crc32 + +import ( + "errors" + "hash" + "sync" + "sync/atomic" +) + +// The size of a CRC-32 checksum in bytes. +const Size = 4 + +// Predefined polynomials. +const ( + // IEEE is by far and away the most common CRC-32 polynomial. + // Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, ... + IEEE = 0xedb88320 + + // Castagnoli's polynomial, used in iSCSI. + // Has better error detection characteristics than IEEE. + // https://dx.doi.org/10.1109/26.231911 + Castagnoli = 0x82f63b78 + + // Koopman's polynomial. + // Also has better error detection characteristics than IEEE. + // https://dx.doi.org/10.1109/DSN.2002.1028931 + Koopman = 0xeb31d82e +) + +// Table is a 256-word table representing the polynomial for efficient processing. +type Table [256]uint32 + +// This file makes use of functions implemented in architecture-specific files. +// The interface that they implement is as follows: +// +// // archAvailableIEEE reports whether an architecture-specific CRC32-IEEE +// // algorithm is available. +// archAvailableIEEE() bool +// +// // archInitIEEE initializes the architecture-specific CRC3-IEEE algorithm. +// // It can only be called if archAvailableIEEE() returns true. +// archInitIEEE() +// +// // archUpdateIEEE updates the given CRC32-IEEE. It can only be called if +// // archInitIEEE() was previously called. +// archUpdateIEEE(crc uint32, p []byte) uint32 +// +// // archAvailableCastagnoli reports whether an architecture-specific +// // CRC32-C algorithm is available. +// archAvailableCastagnoli() bool +// +// // archInitCastagnoli initializes the architecture-specific CRC32-C +// // algorithm. It can only be called if archAvailableCastagnoli() returns +// // true. +// archInitCastagnoli() +// +// // archUpdateCastagnoli updates the given CRC32-C. It can only be called +// // if archInitCastagnoli() was previously called. +// archUpdateCastagnoli(crc uint32, p []byte) uint32 + +// castagnoliTable points to a lazily initialized Table for the Castagnoli +// polynomial. MakeTable will always return this value when asked to make a +// Castagnoli table so we can compare against it to find when the caller is +// using this polynomial. +var castagnoliTable *Table +var castagnoliTable8 *slicing8Table +var updateCastagnoli func(crc uint32, p []byte) uint32 +var castagnoliOnce sync.Once +var haveCastagnoli atomic.Bool + +func castagnoliInit() { + castagnoliTable = simpleMakeTable(Castagnoli) + + if archAvailableCastagnoli() { + archInitCastagnoli() + updateCastagnoli = archUpdateCastagnoli + } else { + // Initialize the slicing-by-8 table. + castagnoliTable8 = slicingMakeTable(Castagnoli) + updateCastagnoli = func(crc uint32, p []byte) uint32 { + return slicingUpdate(crc, castagnoliTable8, p) + } + } + + haveCastagnoli.Store(true) +} + +// IEEETable is the table for the [IEEE] polynomial. +var IEEETable = simpleMakeTable(IEEE) + +// ieeeTable8 is the slicing8Table for IEEE +var ieeeTable8 *slicing8Table +var updateIEEE func(crc uint32, p []byte) uint32 +var ieeeOnce sync.Once + +func ieeeInit() { + if archAvailableIEEE() { + archInitIEEE() + updateIEEE = archUpdateIEEE + } else { + // Initialize the slicing-by-8 table. + ieeeTable8 = slicingMakeTable(IEEE) + updateIEEE = func(crc uint32, p []byte) uint32 { + return slicingUpdate(crc, ieeeTable8, p) + } + } +} + +// MakeTable returns a [Table] constructed from the specified polynomial. +// The contents of this [Table] must not be modified. +func MakeTable(poly uint32) *Table { + switch poly { + case IEEE: + ieeeOnce.Do(ieeeInit) + return IEEETable + case Castagnoli: + castagnoliOnce.Do(castagnoliInit) + return castagnoliTable + default: + return simpleMakeTable(poly) + } +} + +// digest represents the partial evaluation of a checksum. +type digest struct { + crc uint32 + tab *Table +} + +// New creates a new [hash.Hash32] computing the CRC-32 checksum using the +// polynomial represented by the [Table]. Its Sum method will lay the +// value out in big-endian byte order. The returned Hash32 also +// implements [encoding.BinaryMarshaler] and [encoding.BinaryUnmarshaler] to +// marshal and unmarshal the internal state of the hash. +func New(tab *Table) hash.Hash32 { + if tab == IEEETable { + ieeeOnce.Do(ieeeInit) + } + return &digest{0, tab} +} + +// NewIEEE creates a new [hash.Hash32] computing the CRC-32 checksum using +// the [IEEE] polynomial. Its Sum method will lay the value out in +// big-endian byte order. The returned Hash32 also implements +// [encoding.BinaryMarshaler] and [encoding.BinaryUnmarshaler] to marshal +// and unmarshal the internal state of the hash. +func NewIEEE() hash.Hash32 { return New(IEEETable) } + +func (d *digest) Size() int { return Size } + +func (d *digest) BlockSize() int { return 1 } + +func (d *digest) Reset() { d.crc = 0 } + +const ( + magic = "crc\x01" + marshaledSize = len(magic) + 4 + 4 +) + +func (d *digest) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize) + b = append(b, magic...) + b = appendUint32(b, tableSum(d.tab)) + b = appendUint32(b, d.crc) + return b, nil +} + +func (d *digest) UnmarshalBinary(b []byte) error { + if len(b) < len(magic) || string(b[:len(magic)]) != magic { + return errors.New("hash/crc32: invalid hash state identifier") + } + if len(b) != marshaledSize { + return errors.New("hash/crc32: invalid hash state size") + } + if tableSum(d.tab) != readUint32(b[4:]) { + return errors.New("hash/crc32: tables do not match") + } + d.crc = readUint32(b[8:]) + return nil +} + +// appendUint32 is semantically the same as [binary.BigEndian.AppendUint32] +// We copied this function because we can not import "encoding/binary" here. +func appendUint32(b []byte, x uint32) []byte { + return append(b, + byte(x>>24), + byte(x>>16), + byte(x>>8), + byte(x), + ) +} + +// readUint32 is semantically the same as [binary.BigEndian.Uint32] +// We copied this function because we can not import "encoding/binary" here. +func readUint32(b []byte) uint32 { + _ = b[3] + return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 +} + +func update(crc uint32, tab *Table, p []byte, checkInitIEEE bool) uint32 { + switch { + case haveCastagnoli.Load() && tab == castagnoliTable: + return updateCastagnoli(crc, p) + case tab == IEEETable: + if checkInitIEEE { + ieeeOnce.Do(ieeeInit) + } + return updateIEEE(crc, p) + default: + return simpleUpdate(crc, tab, p) + } +} + +// Update returns the result of adding the bytes in p to the crc. +func Update(crc uint32, tab *Table, p []byte) uint32 { + // Unfortunately, because IEEETable is exported, IEEE may be used without a + // call to MakeTable. We have to make sure it gets initialized in that case. + return update(crc, tab, p, true) +} + +func (d *digest) Write(p []byte) (n int, err error) { + // We only create digest objects through New() which takes care of + // initialization in this case. + d.crc = update(d.crc, d.tab, p, false) + return len(p), nil +} + +func (d *digest) Sum32() uint32 { return d.crc } + +func (d *digest) Sum(in []byte) []byte { + s := d.Sum32() + return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s)) +} + +// Checksum returns the CRC-32 checksum of data +// using the polynomial represented by the [Table]. +func Checksum(data []byte, tab *Table) uint32 { return Update(0, tab, data) } + +// ChecksumIEEE returns the CRC-32 checksum of data +// using the [IEEE] polynomial. +func ChecksumIEEE(data []byte) uint32 { + ieeeOnce.Do(ieeeInit) + return updateIEEE(0, data) +} + +// tableSum returns the IEEE checksum of table t. +func tableSum(t *Table) uint32 { + var a [1024]byte + b := a[:0] + if t != nil { + for _, x := range t { + b = appendUint32(b, x) + } + } + return ChecksumIEEE(b) +} diff --git a/contrib/go/_std_1.22/src/hash/crc32/crc32_amd64.go b/contrib/go/_std_1.22/src/hash/crc32/crc32_amd64.go new file mode 100644 index 0000000000..6be129f5dd --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/crc32/crc32_amd64.go @@ -0,0 +1,225 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// AMD64-specific hardware-assisted CRC32 algorithms. See crc32.go for a +// description of the interface that each architecture-specific file +// implements. + +package crc32 + +import ( + "internal/cpu" + "unsafe" +) + +// This file contains the code to call the SSE 4.2 version of the Castagnoli +// and IEEE CRC. + +// castagnoliSSE42 is defined in crc32_amd64.s and uses the SSE 4.2 CRC32 +// instruction. +// +//go:noescape +func castagnoliSSE42(crc uint32, p []byte) uint32 + +// castagnoliSSE42Triple is defined in crc32_amd64.s and uses the SSE 4.2 CRC32 +// instruction. +// +//go:noescape +func castagnoliSSE42Triple( + crcA, crcB, crcC uint32, + a, b, c []byte, + rounds uint32, +) (retA uint32, retB uint32, retC uint32) + +// ieeeCLMUL is defined in crc_amd64.s and uses the PCLMULQDQ +// instruction as well as SSE 4.1. +// +//go:noescape +func ieeeCLMUL(crc uint32, p []byte) uint32 + +const castagnoliK1 = 168 +const castagnoliK2 = 1344 + +type sse42Table [4]Table + +var castagnoliSSE42TableK1 *sse42Table +var castagnoliSSE42TableK2 *sse42Table + +func archAvailableCastagnoli() bool { + return cpu.X86.HasSSE42 +} + +func archInitCastagnoli() { + if !cpu.X86.HasSSE42 { + panic("arch-specific Castagnoli not available") + } + castagnoliSSE42TableK1 = new(sse42Table) + castagnoliSSE42TableK2 = new(sse42Table) + // See description in updateCastagnoli. + // t[0][i] = CRC(i000, O) + // t[1][i] = CRC(0i00, O) + // t[2][i] = CRC(00i0, O) + // t[3][i] = CRC(000i, O) + // where O is a sequence of K zeros. + var tmp [castagnoliK2]byte + for b := 0; b < 4; b++ { + for i := 0; i < 256; i++ { + val := uint32(i) << uint32(b*8) + castagnoliSSE42TableK1[b][i] = castagnoliSSE42(val, tmp[:castagnoliK1]) + castagnoliSSE42TableK2[b][i] = castagnoliSSE42(val, tmp[:]) + } + } +} + +// castagnoliShift computes the CRC32-C of K1 or K2 zeroes (depending on the +// table given) with the given initial crc value. This corresponds to +// CRC(crc, O) in the description in updateCastagnoli. +func castagnoliShift(table *sse42Table, crc uint32) uint32 { + return table[3][crc>>24] ^ + table[2][(crc>>16)&0xFF] ^ + table[1][(crc>>8)&0xFF] ^ + table[0][crc&0xFF] +} + +func archUpdateCastagnoli(crc uint32, p []byte) uint32 { + if !cpu.X86.HasSSE42 { + panic("not available") + } + + // This method is inspired from the algorithm in Intel's white paper: + // "Fast CRC Computation for iSCSI Polynomial Using CRC32 Instruction" + // The same strategy of splitting the buffer in three is used but the + // combining calculation is different; the complete derivation is explained + // below. + // + // -- The basic idea -- + // + // The CRC32 instruction (available in SSE4.2) can process 8 bytes at a + // time. In recent Intel architectures the instruction takes 3 cycles; + // however the processor can pipeline up to three instructions if they + // don't depend on each other. + // + // Roughly this means that we can process three buffers in about the same + // time we can process one buffer. + // + // The idea is then to split the buffer in three, CRC the three pieces + // separately and then combine the results. + // + // Combining the results requires precomputed tables, so we must choose a + // fixed buffer length to optimize. The longer the length, the faster; but + // only buffers longer than this length will use the optimization. We choose + // two cutoffs and compute tables for both: + // - one around 512: 168*3=504 + // - one around 4KB: 1344*3=4032 + // + // -- The nitty gritty -- + // + // Let CRC(I, X) be the non-inverted CRC32-C of the sequence X (with + // initial non-inverted CRC I). This function has the following properties: + // (a) CRC(I, AB) = CRC(CRC(I, A), B) + // (b) CRC(I, A xor B) = CRC(I, A) xor CRC(0, B) + // + // Say we want to compute CRC(I, ABC) where A, B, C are three sequences of + // K bytes each, where K is a fixed constant. Let O be the sequence of K zero + // bytes. + // + // CRC(I, ABC) = CRC(I, ABO xor C) + // = CRC(I, ABO) xor CRC(0, C) + // = CRC(CRC(I, AB), O) xor CRC(0, C) + // = CRC(CRC(I, AO xor B), O) xor CRC(0, C) + // = CRC(CRC(I, AO) xor CRC(0, B), O) xor CRC(0, C) + // = CRC(CRC(CRC(I, A), O) xor CRC(0, B), O) xor CRC(0, C) + // + // The castagnoliSSE42Triple function can compute CRC(I, A), CRC(0, B), + // and CRC(0, C) efficiently. We just need to find a way to quickly compute + // CRC(uvwx, O) given a 4-byte initial value uvwx. We can precompute these + // values; since we can't have a 32-bit table, we break it up into four + // 8-bit tables: + // + // CRC(uvwx, O) = CRC(u000, O) xor + // CRC(0v00, O) xor + // CRC(00w0, O) xor + // CRC(000x, O) + // + // We can compute tables corresponding to the four terms for all 8-bit + // values. + + crc = ^crc + + // If a buffer is long enough to use the optimization, process the first few + // bytes to align the buffer to an 8 byte boundary (if necessary). + if len(p) >= castagnoliK1*3 { + delta := int(uintptr(unsafe.Pointer(&p[0])) & 7) + if delta != 0 { + delta = 8 - delta + crc = castagnoliSSE42(crc, p[:delta]) + p = p[delta:] + } + } + + // Process 3*K2 at a time. + for len(p) >= castagnoliK2*3 { + // Compute CRC(I, A), CRC(0, B), and CRC(0, C). + crcA, crcB, crcC := castagnoliSSE42Triple( + crc, 0, 0, + p, p[castagnoliK2:], p[castagnoliK2*2:], + castagnoliK2/24) + + // CRC(I, AB) = CRC(CRC(I, A), O) xor CRC(0, B) + crcAB := castagnoliShift(castagnoliSSE42TableK2, crcA) ^ crcB + // CRC(I, ABC) = CRC(CRC(I, AB), O) xor CRC(0, C) + crc = castagnoliShift(castagnoliSSE42TableK2, crcAB) ^ crcC + p = p[castagnoliK2*3:] + } + + // Process 3*K1 at a time. + for len(p) >= castagnoliK1*3 { + // Compute CRC(I, A), CRC(0, B), and CRC(0, C). + crcA, crcB, crcC := castagnoliSSE42Triple( + crc, 0, 0, + p, p[castagnoliK1:], p[castagnoliK1*2:], + castagnoliK1/24) + + // CRC(I, AB) = CRC(CRC(I, A), O) xor CRC(0, B) + crcAB := castagnoliShift(castagnoliSSE42TableK1, crcA) ^ crcB + // CRC(I, ABC) = CRC(CRC(I, AB), O) xor CRC(0, C) + crc = castagnoliShift(castagnoliSSE42TableK1, crcAB) ^ crcC + p = p[castagnoliK1*3:] + } + + // Use the simple implementation for what's left. + crc = castagnoliSSE42(crc, p) + return ^crc +} + +func archAvailableIEEE() bool { + return cpu.X86.HasPCLMULQDQ && cpu.X86.HasSSE41 +} + +var archIeeeTable8 *slicing8Table + +func archInitIEEE() { + if !cpu.X86.HasPCLMULQDQ || !cpu.X86.HasSSE41 { + panic("not available") + } + // We still use slicing-by-8 for small buffers. + archIeeeTable8 = slicingMakeTable(IEEE) +} + +func archUpdateIEEE(crc uint32, p []byte) uint32 { + if !cpu.X86.HasPCLMULQDQ || !cpu.X86.HasSSE41 { + panic("not available") + } + + if len(p) >= 64 { + left := len(p) & 15 + do := len(p) - left + crc = ^ieeeCLMUL(^crc, p[:do]) + p = p[do:] + } + if len(p) == 0 { + return crc + } + return slicingUpdate(crc, archIeeeTable8, p) +} diff --git a/contrib/go/_std_1.22/src/hash/crc32/crc32_amd64.s b/contrib/go/_std_1.22/src/hash/crc32/crc32_amd64.s new file mode 100644 index 0000000000..6af6c253a7 --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/crc32/crc32_amd64.s @@ -0,0 +1,279 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +// castagnoliSSE42 updates the (non-inverted) crc with the given buffer. +// +// func castagnoliSSE42(crc uint32, p []byte) uint32 +TEXT ·castagnoliSSE42(SB),NOSPLIT,$0 + MOVL crc+0(FP), AX // CRC value + MOVQ p+8(FP), SI // data pointer + MOVQ p_len+16(FP), CX // len(p) + + // If there are fewer than 8 bytes to process, skip alignment. + CMPQ CX, $8 + JL less_than_8 + + MOVQ SI, BX + ANDQ $7, BX + JZ aligned + + // Process the first few bytes to 8-byte align the input. + + // BX = 8 - BX. We need to process this many bytes to align. + SUBQ $1, BX + XORQ $7, BX + + BTQ $0, BX + JNC align_2 + + CRC32B (SI), AX + DECQ CX + INCQ SI + +align_2: + BTQ $1, BX + JNC align_4 + + CRC32W (SI), AX + + SUBQ $2, CX + ADDQ $2, SI + +align_4: + BTQ $2, BX + JNC aligned + + CRC32L (SI), AX + + SUBQ $4, CX + ADDQ $4, SI + +aligned: + // The input is now 8-byte aligned and we can process 8-byte chunks. + CMPQ CX, $8 + JL less_than_8 + + CRC32Q (SI), AX + ADDQ $8, SI + SUBQ $8, CX + JMP aligned + +less_than_8: + // We may have some bytes left over; process 4 bytes, then 2, then 1. + BTQ $2, CX + JNC less_than_4 + + CRC32L (SI), AX + ADDQ $4, SI + +less_than_4: + BTQ $1, CX + JNC less_than_2 + + CRC32W (SI), AX + ADDQ $2, SI + +less_than_2: + BTQ $0, CX + JNC done + + CRC32B (SI), AX + +done: + MOVL AX, ret+32(FP) + RET + +// castagnoliSSE42Triple updates three (non-inverted) crcs with (24*rounds) +// bytes from each buffer. +// +// func castagnoliSSE42Triple( +// crc1, crc2, crc3 uint32, +// a, b, c []byte, +// rounds uint32, +// ) (retA uint32, retB uint32, retC uint32) +TEXT ·castagnoliSSE42Triple(SB),NOSPLIT,$0 + MOVL crcA+0(FP), AX + MOVL crcB+4(FP), CX + MOVL crcC+8(FP), DX + + MOVQ a+16(FP), R8 // data pointer + MOVQ b+40(FP), R9 // data pointer + MOVQ c+64(FP), R10 // data pointer + + MOVL rounds+88(FP), R11 + +loop: + CRC32Q (R8), AX + CRC32Q (R9), CX + CRC32Q (R10), DX + + CRC32Q 8(R8), AX + CRC32Q 8(R9), CX + CRC32Q 8(R10), DX + + CRC32Q 16(R8), AX + CRC32Q 16(R9), CX + CRC32Q 16(R10), DX + + ADDQ $24, R8 + ADDQ $24, R9 + ADDQ $24, R10 + + DECQ R11 + JNZ loop + + MOVL AX, retA+96(FP) + MOVL CX, retB+100(FP) + MOVL DX, retC+104(FP) + RET + +// CRC32 polynomial data +// +// These constants are lifted from the +// Linux kernel, since they avoid the costly +// PSHUFB 16 byte reversal proposed in the +// original Intel paper. +DATA r2r1<>+0(SB)/8, $0x154442bd4 +DATA r2r1<>+8(SB)/8, $0x1c6e41596 +DATA r4r3<>+0(SB)/8, $0x1751997d0 +DATA r4r3<>+8(SB)/8, $0x0ccaa009e +DATA rupoly<>+0(SB)/8, $0x1db710641 +DATA rupoly<>+8(SB)/8, $0x1f7011641 +DATA r5<>+0(SB)/8, $0x163cd6124 + +GLOBL r2r1<>(SB),RODATA,$16 +GLOBL r4r3<>(SB),RODATA,$16 +GLOBL rupoly<>(SB),RODATA,$16 +GLOBL r5<>(SB),RODATA,$8 + +// Based on https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf +// len(p) must be at least 64, and must be a multiple of 16. + +// func ieeeCLMUL(crc uint32, p []byte) uint32 +TEXT ·ieeeCLMUL(SB),NOSPLIT,$0 + MOVL crc+0(FP), X0 // Initial CRC value + MOVQ p+8(FP), SI // data pointer + MOVQ p_len+16(FP), CX // len(p) + + MOVOU (SI), X1 + MOVOU 16(SI), X2 + MOVOU 32(SI), X3 + MOVOU 48(SI), X4 + PXOR X0, X1 + ADDQ $64, SI // buf+=64 + SUBQ $64, CX // len-=64 + CMPQ CX, $64 // Less than 64 bytes left + JB remain64 + + MOVOA r2r1<>+0(SB), X0 +loopback64: + MOVOA X1, X5 + MOVOA X2, X6 + MOVOA X3, X7 + MOVOA X4, X8 + + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0, X0, X2 + PCLMULQDQ $0, X0, X3 + PCLMULQDQ $0, X0, X4 + + /* Load next early */ + MOVOU (SI), X11 + MOVOU 16(SI), X12 + MOVOU 32(SI), X13 + MOVOU 48(SI), X14 + + PCLMULQDQ $0x11, X0, X5 + PCLMULQDQ $0x11, X0, X6 + PCLMULQDQ $0x11, X0, X7 + PCLMULQDQ $0x11, X0, X8 + + PXOR X5, X1 + PXOR X6, X2 + PXOR X7, X3 + PXOR X8, X4 + + PXOR X11, X1 + PXOR X12, X2 + PXOR X13, X3 + PXOR X14, X4 + + ADDQ $0x40, DI + ADDQ $64, SI // buf+=64 + SUBQ $64, CX // len-=64 + CMPQ CX, $64 // Less than 64 bytes left? + JGE loopback64 + + /* Fold result into a single register (X1) */ +remain64: + MOVOA r4r3<>+0(SB), X0 + + MOVOA X1, X5 + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0x11, X0, X5 + PXOR X5, X1 + PXOR X2, X1 + + MOVOA X1, X5 + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0x11, X0, X5 + PXOR X5, X1 + PXOR X3, X1 + + MOVOA X1, X5 + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0x11, X0, X5 + PXOR X5, X1 + PXOR X4, X1 + + /* If there is less than 16 bytes left we are done */ + CMPQ CX, $16 + JB finish + + /* Encode 16 bytes */ +remain16: + MOVOU (SI), X10 + MOVOA X1, X5 + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0x11, X0, X5 + PXOR X5, X1 + PXOR X10, X1 + SUBQ $16, CX + ADDQ $16, SI + CMPQ CX, $16 + JGE remain16 + +finish: + /* Fold final result into 32 bits and return it */ + PCMPEQB X3, X3 + PCLMULQDQ $1, X1, X0 + PSRLDQ $8, X1 + PXOR X0, X1 + + MOVOA X1, X2 + MOVQ r5<>+0(SB), X0 + + /* Creates 32 bit mask. Note that we don't care about upper half. */ + PSRLQ $32, X3 + + PSRLDQ $4, X2 + PAND X3, X1 + PCLMULQDQ $0, X0, X1 + PXOR X2, X1 + + MOVOA rupoly<>+0(SB), X0 + + MOVOA X1, X2 + PAND X3, X1 + PCLMULQDQ $0x10, X0, X1 + PAND X3, X1 + PCLMULQDQ $0, X0, X1 + PXOR X2, X1 + + PEXTRD $1, X1, AX + MOVL AX, ret+32(FP) + + RET diff --git a/contrib/go/_std_1.22/src/hash/crc32/crc32_arm64.go b/contrib/go/_std_1.22/src/hash/crc32/crc32_arm64.go new file mode 100644 index 0000000000..9674b76a27 --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/crc32/crc32_arm64.go @@ -0,0 +1,50 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// ARM64-specific hardware-assisted CRC32 algorithms. See crc32.go for a +// description of the interface that each architecture-specific file +// implements. + +package crc32 + +import "internal/cpu" + +func castagnoliUpdate(crc uint32, p []byte) uint32 +func ieeeUpdate(crc uint32, p []byte) uint32 + +func archAvailableCastagnoli() bool { + return cpu.ARM64.HasCRC32 +} + +func archInitCastagnoli() { + if !cpu.ARM64.HasCRC32 { + panic("arch-specific crc32 instruction for Castagnoli not available") + } +} + +func archUpdateCastagnoli(crc uint32, p []byte) uint32 { + if !cpu.ARM64.HasCRC32 { + panic("arch-specific crc32 instruction for Castagnoli not available") + } + + return ^castagnoliUpdate(^crc, p) +} + +func archAvailableIEEE() bool { + return cpu.ARM64.HasCRC32 +} + +func archInitIEEE() { + if !cpu.ARM64.HasCRC32 { + panic("arch-specific crc32 instruction for IEEE not available") + } +} + +func archUpdateIEEE(crc uint32, p []byte) uint32 { + if !cpu.ARM64.HasCRC32 { + panic("arch-specific crc32 instruction for IEEE not available") + } + + return ^ieeeUpdate(^crc, p) +} diff --git a/contrib/go/_std_1.22/src/hash/crc32/crc32_arm64.s b/contrib/go/_std_1.22/src/hash/crc32/crc32_arm64.s new file mode 100644 index 0000000000..85a113f9de --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/crc32/crc32_arm64.s @@ -0,0 +1,97 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +// castagnoliUpdate updates the non-inverted crc with the given data. + +// func castagnoliUpdate(crc uint32, p []byte) uint32 +TEXT ·castagnoliUpdate(SB),NOSPLIT,$0-36 + MOVWU crc+0(FP), R9 // CRC value + MOVD p+8(FP), R13 // data pointer + MOVD p_len+16(FP), R11 // len(p) + +update: + CMP $16, R11 + BLT less_than_16 + LDP.P 16(R13), (R8, R10) + CRC32CX R8, R9 + CRC32CX R10, R9 + SUB $16, R11 + + JMP update + +less_than_16: + TBZ $3, R11, less_than_8 + + MOVD.P 8(R13), R10 + CRC32CX R10, R9 + +less_than_8: + TBZ $2, R11, less_than_4 + + MOVWU.P 4(R13), R10 + CRC32CW R10, R9 + +less_than_4: + TBZ $1, R11, less_than_2 + + MOVHU.P 2(R13), R10 + CRC32CH R10, R9 + +less_than_2: + TBZ $0, R11, done + + MOVBU (R13), R10 + CRC32CB R10, R9 + +done: + MOVWU R9, ret+32(FP) + RET + +// ieeeUpdate updates the non-inverted crc with the given data. + +// func ieeeUpdate(crc uint32, p []byte) uint32 +TEXT ·ieeeUpdate(SB),NOSPLIT,$0-36 + MOVWU crc+0(FP), R9 // CRC value + MOVD p+8(FP), R13 // data pointer + MOVD p_len+16(FP), R11 // len(p) + +update: + CMP $16, R11 + BLT less_than_16 + LDP.P 16(R13), (R8, R10) + CRC32X R8, R9 + CRC32X R10, R9 + SUB $16, R11 + + JMP update + +less_than_16: + TBZ $3, R11, less_than_8 + + MOVD.P 8(R13), R10 + CRC32X R10, R9 + +less_than_8: + TBZ $2, R11, less_than_4 + + MOVWU.P 4(R13), R10 + CRC32W R10, R9 + +less_than_4: + TBZ $1, R11, less_than_2 + + MOVHU.P 2(R13), R10 + CRC32H R10, R9 + +less_than_2: + TBZ $0, R11, done + + MOVBU (R13), R10 + CRC32B R10, R9 + +done: + MOVWU R9, ret+32(FP) + RET diff --git a/contrib/go/_std_1.22/src/hash/crc32/crc32_generic.go b/contrib/go/_std_1.22/src/hash/crc32/crc32_generic.go new file mode 100644 index 0000000000..abacbb663d --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/crc32/crc32_generic.go @@ -0,0 +1,89 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file contains CRC32 algorithms that are not specific to any architecture +// and don't use hardware acceleration. +// +// The simple (and slow) CRC32 implementation only uses a 256*4 bytes table. +// +// The slicing-by-8 algorithm is a faster implementation that uses a bigger +// table (8*256*4 bytes). + +package crc32 + +// simpleMakeTable allocates and constructs a Table for the specified +// polynomial. The table is suitable for use with the simple algorithm +// (simpleUpdate). +func simpleMakeTable(poly uint32) *Table { + t := new(Table) + simplePopulateTable(poly, t) + return t +} + +// simplePopulateTable constructs a Table for the specified polynomial, suitable +// for use with simpleUpdate. +func simplePopulateTable(poly uint32, t *Table) { + for i := 0; i < 256; i++ { + crc := uint32(i) + for j := 0; j < 8; j++ { + if crc&1 == 1 { + crc = (crc >> 1) ^ poly + } else { + crc >>= 1 + } + } + t[i] = crc + } +} + +// simpleUpdate uses the simple algorithm to update the CRC, given a table that +// was previously computed using simpleMakeTable. +func simpleUpdate(crc uint32, tab *Table, p []byte) uint32 { + crc = ^crc + for _, v := range p { + crc = tab[byte(crc)^v] ^ (crc >> 8) + } + return ^crc +} + +// Use slicing-by-8 when payload >= this value. +const slicing8Cutoff = 16 + +// slicing8Table is array of 8 Tables, used by the slicing-by-8 algorithm. +type slicing8Table [8]Table + +// slicingMakeTable constructs a slicing8Table for the specified polynomial. The +// table is suitable for use with the slicing-by-8 algorithm (slicingUpdate). +func slicingMakeTable(poly uint32) *slicing8Table { + t := new(slicing8Table) + simplePopulateTable(poly, &t[0]) + for i := 0; i < 256; i++ { + crc := t[0][i] + for j := 1; j < 8; j++ { + crc = t[0][crc&0xFF] ^ (crc >> 8) + t[j][i] = crc + } + } + return t +} + +// slicingUpdate uses the slicing-by-8 algorithm to update the CRC, given a +// table that was previously computed using slicingMakeTable. +func slicingUpdate(crc uint32, tab *slicing8Table, p []byte) uint32 { + if len(p) >= slicing8Cutoff { + crc = ^crc + for len(p) > 8 { + crc ^= uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 + crc = tab[0][p[7]] ^ tab[1][p[6]] ^ tab[2][p[5]] ^ tab[3][p[4]] ^ + tab[4][crc>>24] ^ tab[5][(crc>>16)&0xFF] ^ + tab[6][(crc>>8)&0xFF] ^ tab[7][crc&0xFF] + p = p[8:] + } + crc = ^crc + } + if len(p) == 0 { + return crc + } + return simpleUpdate(crc, &tab[0], p) +} diff --git a/contrib/go/_std_1.22/src/hash/crc32/ya.make b/contrib/go/_std_1.22/src/hash/crc32/ya.make new file mode 100644 index 0000000000..530c001e94 --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/crc32/ya.make @@ -0,0 +1,17 @@ +GO_LIBRARY() +IF (OS_DARWIN AND ARCH_ARM64 AND RACE AND CGO_ENABLED OR OS_DARWIN AND ARCH_ARM64 AND RACE AND NOT CGO_ENABLED OR OS_DARWIN AND ARCH_ARM64 AND NOT RACE AND CGO_ENABLED OR OS_DARWIN AND ARCH_ARM64 AND NOT RACE AND NOT CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND RACE AND NOT CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND NOT RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_AARCH64 AND NOT RACE AND NOT CGO_ENABLED) + SRCS( + crc32.go + crc32_arm64.go + crc32_arm64.s + crc32_generic.go + ) +ELSEIF (OS_DARWIN AND ARCH_X86_64 AND RACE AND CGO_ENABLED OR OS_DARWIN AND ARCH_X86_64 AND RACE AND NOT CGO_ENABLED OR OS_DARWIN AND ARCH_X86_64 AND NOT RACE AND CGO_ENABLED OR OS_DARWIN AND ARCH_X86_64 AND NOT RACE AND NOT CGO_ENABLED OR OS_LINUX AND ARCH_X86_64 AND RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_X86_64 AND RACE AND NOT CGO_ENABLED OR OS_LINUX AND ARCH_X86_64 AND NOT RACE AND CGO_ENABLED OR OS_LINUX AND ARCH_X86_64 AND NOT RACE AND NOT CGO_ENABLED OR OS_WINDOWS AND ARCH_X86_64 AND RACE AND CGO_ENABLED OR OS_WINDOWS AND ARCH_X86_64 AND RACE AND NOT CGO_ENABLED OR OS_WINDOWS AND ARCH_X86_64 AND NOT RACE AND CGO_ENABLED OR OS_WINDOWS AND ARCH_X86_64 AND NOT RACE AND NOT CGO_ENABLED) + SRCS( + crc32.go + crc32_amd64.go + crc32_amd64.s + crc32_generic.go + ) +ENDIF() +END() diff --git a/contrib/go/_std_1.22/src/hash/fnv/fnv.go b/contrib/go/_std_1.22/src/hash/fnv/fnv.go new file mode 100644 index 0000000000..29439e2c1d --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/fnv/fnv.go @@ -0,0 +1,376 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package fnv implements FNV-1 and FNV-1a, non-cryptographic hash functions +// created by Glenn Fowler, Landon Curt Noll, and Phong Vo. +// See +// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function. +// +// All the hash.Hash implementations returned by this package also +// implement encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to +// marshal and unmarshal the internal state of the hash. +package fnv + +import ( + "errors" + "hash" + "math/bits" +) + +type ( + sum32 uint32 + sum32a uint32 + sum64 uint64 + sum64a uint64 + sum128 [2]uint64 + sum128a [2]uint64 +) + +const ( + offset32 = 2166136261 + offset64 = 14695981039346656037 + offset128Lower = 0x62b821756295c58d + offset128Higher = 0x6c62272e07bb0142 + prime32 = 16777619 + prime64 = 1099511628211 + prime128Lower = 0x13b + prime128Shift = 24 +) + +// New32 returns a new 32-bit FNV-1 [hash.Hash]. +// Its Sum method will lay the value out in big-endian byte order. +func New32() hash.Hash32 { + var s sum32 = offset32 + return &s +} + +// New32a returns a new 32-bit FNV-1a [hash.Hash]. +// Its Sum method will lay the value out in big-endian byte order. +func New32a() hash.Hash32 { + var s sum32a = offset32 + return &s +} + +// New64 returns a new 64-bit FNV-1 [hash.Hash]. +// Its Sum method will lay the value out in big-endian byte order. +func New64() hash.Hash64 { + var s sum64 = offset64 + return &s +} + +// New64a returns a new 64-bit FNV-1a [hash.Hash]. +// Its Sum method will lay the value out in big-endian byte order. +func New64a() hash.Hash64 { + var s sum64a = offset64 + return &s +} + +// New128 returns a new 128-bit FNV-1 [hash.Hash]. +// Its Sum method will lay the value out in big-endian byte order. +func New128() hash.Hash { + var s sum128 + s[0] = offset128Higher + s[1] = offset128Lower + return &s +} + +// New128a returns a new 128-bit FNV-1a [hash.Hash]. +// Its Sum method will lay the value out in big-endian byte order. +func New128a() hash.Hash { + var s sum128a + s[0] = offset128Higher + s[1] = offset128Lower + return &s +} + +func (s *sum32) Reset() { *s = offset32 } +func (s *sum32a) Reset() { *s = offset32 } +func (s *sum64) Reset() { *s = offset64 } +func (s *sum64a) Reset() { *s = offset64 } +func (s *sum128) Reset() { s[0] = offset128Higher; s[1] = offset128Lower } +func (s *sum128a) Reset() { s[0] = offset128Higher; s[1] = offset128Lower } + +func (s *sum32) Sum32() uint32 { return uint32(*s) } +func (s *sum32a) Sum32() uint32 { return uint32(*s) } +func (s *sum64) Sum64() uint64 { return uint64(*s) } +func (s *sum64a) Sum64() uint64 { return uint64(*s) } + +func (s *sum32) Write(data []byte) (int, error) { + hash := *s + for _, c := range data { + hash *= prime32 + hash ^= sum32(c) + } + *s = hash + return len(data), nil +} + +func (s *sum32a) Write(data []byte) (int, error) { + hash := *s + for _, c := range data { + hash ^= sum32a(c) + hash *= prime32 + } + *s = hash + return len(data), nil +} + +func (s *sum64) Write(data []byte) (int, error) { + hash := *s + for _, c := range data { + hash *= prime64 + hash ^= sum64(c) + } + *s = hash + return len(data), nil +} + +func (s *sum64a) Write(data []byte) (int, error) { + hash := *s + for _, c := range data { + hash ^= sum64a(c) + hash *= prime64 + } + *s = hash + return len(data), nil +} + +func (s *sum128) Write(data []byte) (int, error) { + for _, c := range data { + // Compute the multiplication + s0, s1 := bits.Mul64(prime128Lower, s[1]) + s0 += s[1]<<prime128Shift + prime128Lower*s[0] + // Update the values + s[1] = s1 + s[0] = s0 + s[1] ^= uint64(c) + } + return len(data), nil +} + +func (s *sum128a) Write(data []byte) (int, error) { + for _, c := range data { + s[1] ^= uint64(c) + // Compute the multiplication + s0, s1 := bits.Mul64(prime128Lower, s[1]) + s0 += s[1]<<prime128Shift + prime128Lower*s[0] + // Update the values + s[1] = s1 + s[0] = s0 + } + return len(data), nil +} + +func (s *sum32) Size() int { return 4 } +func (s *sum32a) Size() int { return 4 } +func (s *sum64) Size() int { return 8 } +func (s *sum64a) Size() int { return 8 } +func (s *sum128) Size() int { return 16 } +func (s *sum128a) Size() int { return 16 } + +func (s *sum32) BlockSize() int { return 1 } +func (s *sum32a) BlockSize() int { return 1 } +func (s *sum64) BlockSize() int { return 1 } +func (s *sum64a) BlockSize() int { return 1 } +func (s *sum128) BlockSize() int { return 1 } +func (s *sum128a) BlockSize() int { return 1 } + +func (s *sum32) Sum(in []byte) []byte { + v := uint32(*s) + return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + +func (s *sum32a) Sum(in []byte) []byte { + v := uint32(*s) + return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + +func (s *sum64) Sum(in []byte) []byte { + v := uint64(*s) + return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + +func (s *sum64a) Sum(in []byte) []byte { + v := uint64(*s) + return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + +func (s *sum128) Sum(in []byte) []byte { + return append(in, + byte(s[0]>>56), byte(s[0]>>48), byte(s[0]>>40), byte(s[0]>>32), byte(s[0]>>24), byte(s[0]>>16), byte(s[0]>>8), byte(s[0]), + byte(s[1]>>56), byte(s[1]>>48), byte(s[1]>>40), byte(s[1]>>32), byte(s[1]>>24), byte(s[1]>>16), byte(s[1]>>8), byte(s[1]), + ) +} + +func (s *sum128a) Sum(in []byte) []byte { + return append(in, + byte(s[0]>>56), byte(s[0]>>48), byte(s[0]>>40), byte(s[0]>>32), byte(s[0]>>24), byte(s[0]>>16), byte(s[0]>>8), byte(s[0]), + byte(s[1]>>56), byte(s[1]>>48), byte(s[1]>>40), byte(s[1]>>32), byte(s[1]>>24), byte(s[1]>>16), byte(s[1]>>8), byte(s[1]), + ) +} + +const ( + magic32 = "fnv\x01" + magic32a = "fnv\x02" + magic64 = "fnv\x03" + magic64a = "fnv\x04" + magic128 = "fnv\x05" + magic128a = "fnv\x06" + marshaledSize32 = len(magic32) + 4 + marshaledSize64 = len(magic64) + 8 + marshaledSize128 = len(magic128) + 8*2 +) + +func (s *sum32) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize32) + b = append(b, magic32...) + b = appendUint32(b, uint32(*s)) + return b, nil +} + +func (s *sum32a) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize32) + b = append(b, magic32a...) + b = appendUint32(b, uint32(*s)) + return b, nil +} + +func (s *sum64) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize64) + b = append(b, magic64...) + b = appendUint64(b, uint64(*s)) + return b, nil +} + +func (s *sum64a) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize64) + b = append(b, magic64a...) + b = appendUint64(b, uint64(*s)) + return b, nil +} + +func (s *sum128) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize128) + b = append(b, magic128...) + b = appendUint64(b, s[0]) + b = appendUint64(b, s[1]) + return b, nil +} + +func (s *sum128a) MarshalBinary() ([]byte, error) { + b := make([]byte, 0, marshaledSize128) + b = append(b, magic128a...) + b = appendUint64(b, s[0]) + b = appendUint64(b, s[1]) + return b, nil +} + +func (s *sum32) UnmarshalBinary(b []byte) error { + if len(b) < len(magic32) || string(b[:len(magic32)]) != magic32 { + return errors.New("hash/fnv: invalid hash state identifier") + } + if len(b) != marshaledSize32 { + return errors.New("hash/fnv: invalid hash state size") + } + *s = sum32(readUint32(b[4:])) + return nil +} + +func (s *sum32a) UnmarshalBinary(b []byte) error { + if len(b) < len(magic32a) || string(b[:len(magic32a)]) != magic32a { + return errors.New("hash/fnv: invalid hash state identifier") + } + if len(b) != marshaledSize32 { + return errors.New("hash/fnv: invalid hash state size") + } + *s = sum32a(readUint32(b[4:])) + return nil +} + +func (s *sum64) UnmarshalBinary(b []byte) error { + if len(b) < len(magic64) || string(b[:len(magic64)]) != magic64 { + return errors.New("hash/fnv: invalid hash state identifier") + } + if len(b) != marshaledSize64 { + return errors.New("hash/fnv: invalid hash state size") + } + *s = sum64(readUint64(b[4:])) + return nil +} + +func (s *sum64a) UnmarshalBinary(b []byte) error { + if len(b) < len(magic64a) || string(b[:len(magic64a)]) != magic64a { + return errors.New("hash/fnv: invalid hash state identifier") + } + if len(b) != marshaledSize64 { + return errors.New("hash/fnv: invalid hash state size") + } + *s = sum64a(readUint64(b[4:])) + return nil +} + +func (s *sum128) UnmarshalBinary(b []byte) error { + if len(b) < len(magic128) || string(b[:len(magic128)]) != magic128 { + return errors.New("hash/fnv: invalid hash state identifier") + } + if len(b) != marshaledSize128 { + return errors.New("hash/fnv: invalid hash state size") + } + s[0] = readUint64(b[4:]) + s[1] = readUint64(b[12:]) + return nil +} + +func (s *sum128a) UnmarshalBinary(b []byte) error { + if len(b) < len(magic128a) || string(b[:len(magic128a)]) != magic128a { + return errors.New("hash/fnv: invalid hash state identifier") + } + if len(b) != marshaledSize128 { + return errors.New("hash/fnv: invalid hash state size") + } + s[0] = readUint64(b[4:]) + s[1] = readUint64(b[12:]) + return nil +} + +// readUint32 is semantically the same as [binary.BigEndian.Uint32] +// We copied this function because we can not import "encoding/binary" here. +func readUint32(b []byte) uint32 { + _ = b[3] + return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 +} + +// appendUint32 is semantically the same as [binary.BigEndian.AppendUint32] +// We copied this function because we can not import "encoding/binary" here. +func appendUint32(b []byte, x uint32) []byte { + return append(b, + byte(x>>24), + byte(x>>16), + byte(x>>8), + byte(x), + ) +} + +// appendUint64 is semantically the same as [binary.BigEndian.AppendUint64] +// We copied this function because we can not import "encoding/binary" here. +func appendUint64(b []byte, x uint64) []byte { + return append(b, + byte(x>>56), + byte(x>>48), + byte(x>>40), + byte(x>>32), + byte(x>>24), + byte(x>>16), + byte(x>>8), + byte(x), + ) +} + +// readUint64 is semantically the same as [binary.BigEndian.Uint64] +// We copied this function because we can not import "encoding/binary" here. +func readUint64(b []byte) uint64 { + _ = b[7] + return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | + uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 +} diff --git a/contrib/go/_std_1.22/src/hash/fnv/ya.make b/contrib/go/_std_1.22/src/hash/fnv/ya.make new file mode 100644 index 0000000000..a05c10008d --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/fnv/ya.make @@ -0,0 +1,7 @@ +GO_LIBRARY() +IF (TRUE) + SRCS( + fnv.go + ) +ENDIF() +END() diff --git a/contrib/go/_std_1.22/src/hash/hash.go b/contrib/go/_std_1.22/src/hash/hash.go new file mode 100644 index 0000000000..82c81034ff --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/hash.go @@ -0,0 +1,58 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package hash provides interfaces for hash functions. +package hash + +import "io" + +// Hash is the common interface implemented by all hash functions. +// +// Hash implementations in the standard library (e.g. [hash/crc32] and +// [crypto/sha256]) implement the [encoding.BinaryMarshaler] and +// [encoding.BinaryUnmarshaler] interfaces. Marshaling a hash implementation +// allows its internal state to be saved and used for additional processing +// later, without having to re-write the data previously written to the hash. +// The hash state may contain portions of the input in its original form, +// which users are expected to handle for any possible security implications. +// +// Compatibility: Any future changes to hash or crypto packages will endeavor +// to maintain compatibility with state encoded using previous versions. +// That is, any released versions of the packages should be able to +// decode data written with any previously released version, +// subject to issues such as security fixes. +// See the Go compatibility document for background: https://golang.org/doc/go1compat +type Hash interface { + // Write (via the embedded io.Writer interface) adds more data to the running hash. + // It never returns an error. + io.Writer + + // Sum appends the current hash to b and returns the resulting slice. + // It does not change the underlying hash state. + Sum(b []byte) []byte + + // Reset resets the Hash to its initial state. + Reset() + + // Size returns the number of bytes Sum will return. + Size() int + + // BlockSize returns the hash's underlying block size. + // The Write method must be able to accept any amount + // of data, but it may operate more efficiently if all writes + // are a multiple of the block size. + BlockSize() int +} + +// Hash32 is the common interface implemented by all 32-bit hash functions. +type Hash32 interface { + Hash + Sum32() uint32 +} + +// Hash64 is the common interface implemented by all 64-bit hash functions. +type Hash64 interface { + Hash + Sum64() uint64 +} diff --git a/contrib/go/_std_1.22/src/hash/ya.make b/contrib/go/_std_1.22/src/hash/ya.make new file mode 100644 index 0000000000..547724b9c1 --- /dev/null +++ b/contrib/go/_std_1.22/src/hash/ya.make @@ -0,0 +1,7 @@ +GO_LIBRARY() +IF (TRUE) + SRCS( + hash.go + ) +ENDIF() +END() |