From af19da5605ca11f85776ef7af3384a02a315a52b Mon Sep 17 00:00:00 2001 From: Bas Westerbaan Date: Fri, 6 Sep 2024 15:00:02 +0200 Subject: [PATCH] Add support for X25519MLKEM768. (#179) --- src/crypto/tls/cfkem.go | 3 + src/crypto/tls/cfkem_test.go | 1 + src/go.mod | 2 +- src/go.sum | 4 +- src/go/build/deps_test.go | 6 +- .../cloudflare/circl/dh/x25519/curve_amd64.s | 3 +- .../cloudflare/circl/dh/x448/curve_amd64.s | 3 +- .../cloudflare/circl/ecc/p384/arith.go | 4 +- .../cloudflare/circl/ecc/p384/arith_amd64.go | 4 +- .../cloudflare/circl/ecc/p384/arith_amd64.s | 2 +- .../cloudflare/circl/ecc/p384/arith_arm64.s | 2 +- .../cloudflare/circl/ecc/p384/p384_generic.go | 4 +- .../cloudflare/circl/ecc/p384/p384opt.go | 4 +- .../cloudflare/circl/ecc/p384/point.go | 4 +- .../cloudflare/circl/ecc/p384/tableBase.go | 4 +- .../cloudflare/circl/kem/hybrid/hybrid.go | 21 +- .../github.com/cloudflare/circl/kem/kem.go | 3 + .../circl/kem/kyber/kyber1024/kyber.go | 9 +- .../circl/kem/kyber/kyber512/kyber.go | 9 +- .../circl/kem/kyber/kyber768/kyber.go | 9 +- .../circl/kem/mlkem/mlkem768/kyber.go | 407 +++++++++++++++++ .../cloudflare/circl/math/fp25519/fp_amd64.s | 3 +- .../cloudflare/circl/math/fp448/fp_amd64.s | 3 +- .../circl/pke/kyber/internal/common/amd64.go | 4 +- .../circl/pke/kyber/internal/common/amd64.s | 2 +- .../pke/kyber/internal/common/generic.go | 4 +- .../pke/kyber/internal/common/stubs_amd64.go | 2 +- .../pke/kyber/kyber1024/internal/cpapke.go | 16 + .../circl/pke/kyber/kyber1024/kyber.go | 32 +- .../pke/kyber/kyber512/internal/cpapke.go | 16 + .../circl/pke/kyber/kyber512/kyber.go | 32 +- .../pke/kyber/kyber768/internal/cpapke.go | 16 + .../circl/pke/kyber/kyber768/kyber.go | 32 +- .../sign/dilithium/internal/common/amd64.go | 4 +- .../sign/dilithium/internal/common/amd64.s | 2 +- .../sign/dilithium/internal/common/generic.go | 4 +- .../dilithium/internal/common/stubs_amd64.go | 2 +- .../circl/sign/eddilithium3/eddilithium.go | 6 +- .../circl/simd/keccakf1600/f1600x2_arm64.go | 4 +- .../circl/simd/keccakf1600/f1600x2_arm64.s | 2 +- .../circl/simd/keccakf1600/f1600x4_amd64.go | 3 + .../circl/simd/keccakf1600/f1600x4_amd64.s | 2 +- .../simd/keccakf1600/f1600x4stubs_amd64.go | 2 +- .../circl/simd/keccakf1600/fallback.go | 4 +- src/vendor/golang.org/x/crypto/sha3/doc.go | 62 +++ src/vendor/golang.org/x/crypto/sha3/hashes.go | 97 ++++ .../x/crypto/sha3/hashes_generic.go | 27 ++ .../golang.org/x/crypto/sha3/keccakf.go | 414 ++++++++++++++++++ .../golang.org/x/crypto/sha3/keccakf_amd64.go | 13 + .../golang.org/x/crypto/sha3/keccakf_amd64.s | 390 +++++++++++++++++ .../golang.org/x/crypto/sha3/register.go | 18 + src/vendor/golang.org/x/crypto/sha3/sha3.go | 197 +++++++++ .../golang.org/x/crypto/sha3/sha3_s390x.go | 288 ++++++++++++ .../golang.org/x/crypto/sha3/sha3_s390x.s | 33 ++ src/vendor/golang.org/x/crypto/sha3/shake.go | 172 ++++++++ .../golang.org/x/crypto/sha3/shake_generic.go | 19 + src/vendor/golang.org/x/crypto/sha3/xor.go | 23 + .../golang.org/x/crypto/sha3/xor_generic.go | 28 ++ .../golang.org/x/crypto/sha3/xor_unaligned.go | 66 +++ src/vendor/modules.txt | 6 +- 60 files changed, 2492 insertions(+), 66 deletions(-) create mode 100644 src/vendor/github.com/cloudflare/circl/kem/mlkem/mlkem768/kyber.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/doc.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/hashes.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/hashes_generic.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/keccakf.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s create mode 100644 src/vendor/golang.org/x/crypto/sha3/register.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/sha3.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/sha3_s390x.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/sha3_s390x.s create mode 100644 src/vendor/golang.org/x/crypto/sha3/shake.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/shake_generic.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/xor.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/xor_generic.go create mode 100644 src/vendor/golang.org/x/crypto/sha3/xor_unaligned.go diff --git a/src/crypto/tls/cfkem.go b/src/crypto/tls/cfkem.go index d3f54987616..7f1bb6cd5bf 100644 --- a/src/crypto/tls/cfkem.go +++ b/src/crypto/tls/cfkem.go @@ -42,6 +42,7 @@ var ( X25519Kyber768Draft00 = CurveID(0x6399) X25519Kyber768Draft00Old = CurveID(0xfe31) P256Kyber768Draft00 = CurveID(0xfe32) + X25519MLKEM768 = CurveID(0x11ec) invalidCurveID = CurveID(0) // A key agreeement similar in size but purposefully incompatible with @@ -64,6 +65,8 @@ func curveIdToCirclScheme(id CurveID) kem.Scheme { return hybrid.Kyber768X25519() case P256Kyber768Draft00: return hybrid.P256Kyber768Draft00() + case X25519MLKEM768: + return hybrid.X25519MLKEM768() case DummyKex: return hpke.KEM_X25519_HKDF_SHA256.Scheme() } diff --git a/src/crypto/tls/cfkem_test.go b/src/crypto/tls/cfkem_test.go index b8f57a4f4de..cf59ac5f3af 100644 --- a/src/crypto/tls/cfkem_test.go +++ b/src/crypto/tls/cfkem_test.go @@ -95,6 +95,7 @@ func TestHybridKEX(t *testing.T) { X25519Kyber768Draft00, X25519Kyber768Draft00Old, P256Kyber768Draft00, + X25519MLKEM768, DummyKex, } { run(curveID, true, true, false, false) diff --git a/src/go.mod b/src/go.mod index c82ed2bf9f0..24f3d5946e0 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,7 +3,7 @@ module std go 1.22 require ( - github.com/cloudflare/circl v1.3.8-0.20240208083452-454cfdc0f6c7 + github.com/cloudflare/circl v1.4.1-0.20240905130006-2d6cd9871f69 golang.org/x/crypto v0.16.1-0.20231129163542-152cdb1503eb golang.org/x/net v0.19.1-0.20240412193750-db050b07227e ) diff --git a/src/go.sum b/src/go.sum index a373acaa66d..4e86797268f 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,5 +1,5 @@ -github.com/cloudflare/circl v1.3.8-0.20240208083452-454cfdc0f6c7 h1:nRedc5Iqg+cBRSKkA3c7+IUFgK9qdw87kz/McP3HnLs= -github.com/cloudflare/circl v1.3.8-0.20240208083452-454cfdc0f6c7/go.mod h1:uAwUTm6m3uQF5fuJKR6LvFqgxn2wyID+kF6KJAUcZl8= +github.com/cloudflare/circl v1.4.1-0.20240905130006-2d6cd9871f69 h1:AYiEIB+pGooAgRNMQtk3dCcp+D2x0UioEaKELFIxkx4= +github.com/cloudflare/circl v1.4.1-0.20240905130006-2d6cd9871f69/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= golang.org/x/crypto v0.16.1-0.20231129163542-152cdb1503eb h1:1ceSY7sk6sJuiDREHpfyrqDnDljsLfEP2GuTClhBBfI= golang.org/x/crypto v0.16.1-0.20231129163542-152cdb1503eb/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/net v0.19.1-0.20240412193750-db050b07227e h1:oDnvqaqHo3ho8OChMtkQbQAyp9eqnm3J7JRtt0+Cabc= diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go index eeb5c88b2a0..c4f877e3396 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -455,6 +455,9 @@ var depsRules = ` crypto/boring, crypto/internal/edwards25519/field < crypto/ecdh; + # Unfortunately, stuck with reflect via encoding/binary. + encoding/binary, crypto/boring < golang.org/x/crypto/sha3; + crypto/aes, crypto/des, crypto/ecdh, @@ -464,7 +467,8 @@ var depsRules = ` crypto/rc4, crypto/sha1, crypto/sha256, - crypto/sha512 + crypto/sha512, + golang.org/x/crypto/sha3 < CRYPTO; CGO, fmt, net !< CRYPTO; diff --git a/src/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s b/src/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s index b7723185b61..ce9f062894a 100644 --- a/src/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s +++ b/src/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s @@ -1,4 +1,5 @@ -// +build amd64 +//go:build amd64 && !purego +// +build amd64,!purego #include "textflag.h" diff --git a/src/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s b/src/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s index 810aa9e6481..ed33ba3d032 100644 --- a/src/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s +++ b/src/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s @@ -1,4 +1,5 @@ -// +build amd64 +//go:build amd64 && !purego +// +build amd64,!purego #include "textflag.h" diff --git a/src/vendor/github.com/cloudflare/circl/ecc/p384/arith.go b/src/vendor/github.com/cloudflare/circl/ecc/p384/arith.go index 1b742de871a..889e7771f1d 100644 --- a/src/vendor/github.com/cloudflare/circl/ecc/p384/arith.go +++ b/src/vendor/github.com/cloudflare/circl/ecc/p384/arith.go @@ -1,5 +1,5 @@ -//go:build (!noasm && arm64) || (!noasm && amd64) -// +build !noasm,arm64 !noasm,amd64 +//go:build (!purego && arm64) || (!purego && amd64) +// +build !purego,arm64 !purego,amd64 package p384 diff --git a/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.go b/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.go index 1ea343b5daa..2e9d8fddb5e 100644 --- a/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.go +++ b/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.go @@ -1,5 +1,5 @@ -//go:build amd64 && !noasm -// +build amd64,!noasm +//go:build amd64 && !purego +// +build amd64,!purego package p384 diff --git a/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.s b/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.s index 5f53c637d06..eaf6fb7a771 100644 --- a/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.s +++ b/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.s @@ -1,4 +1,4 @@ -// +build amd64,!noasm +// +build amd64,!purego #include "textflag.h" diff --git a/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_arm64.s b/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_arm64.s index ec93991d426..a02e76d576e 100644 --- a/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_arm64.s +++ b/src/vendor/github.com/cloudflare/circl/ecc/p384/arith_arm64.s @@ -1,4 +1,4 @@ -// +build arm64,!noasm +// +build arm64,!purego #include "textflag.h" diff --git a/src/vendor/github.com/cloudflare/circl/ecc/p384/p384_generic.go b/src/vendor/github.com/cloudflare/circl/ecc/p384/p384_generic.go index 8444a59e204..9b14feaec08 100644 --- a/src/vendor/github.com/cloudflare/circl/ecc/p384/p384_generic.go +++ b/src/vendor/github.com/cloudflare/circl/ecc/p384/p384_generic.go @@ -1,5 +1,5 @@ -//go:build noasm || (!amd64 && !arm64) -// +build noasm !amd64,!arm64 +//go:build purego || (!amd64 && !arm64) +// +build purego !amd64,!arm64 package p384 diff --git a/src/vendor/github.com/cloudflare/circl/ecc/p384/p384opt.go b/src/vendor/github.com/cloudflare/circl/ecc/p384/p384opt.go index 91d17705175..5f744eac89b 100644 --- a/src/vendor/github.com/cloudflare/circl/ecc/p384/p384opt.go +++ b/src/vendor/github.com/cloudflare/circl/ecc/p384/p384opt.go @@ -1,5 +1,5 @@ -//go:build (!noasm && arm64) || (!noasm && amd64) -// +build !noasm,arm64 !noasm,amd64 +//go:build (!purego && arm64) || (!purego && amd64) +// +build !purego,arm64 !purego,amd64 package p384 diff --git a/src/vendor/github.com/cloudflare/circl/ecc/p384/point.go b/src/vendor/github.com/cloudflare/circl/ecc/p384/point.go index 0ba1da8bdb3..e20b57b0176 100644 --- a/src/vendor/github.com/cloudflare/circl/ecc/p384/point.go +++ b/src/vendor/github.com/cloudflare/circl/ecc/p384/point.go @@ -1,5 +1,5 @@ -//go:build (!noasm && arm64) || (!noasm && amd64) -// +build !noasm,arm64 !noasm,amd64 +//go:build (!purego && arm64) || (!purego && amd64) +// +build !purego,arm64 !purego,amd64 package p384 diff --git a/src/vendor/github.com/cloudflare/circl/ecc/p384/tableBase.go b/src/vendor/github.com/cloudflare/circl/ecc/p384/tableBase.go index 59cd319f321..5132565ef34 100644 --- a/src/vendor/github.com/cloudflare/circl/ecc/p384/tableBase.go +++ b/src/vendor/github.com/cloudflare/circl/ecc/p384/tableBase.go @@ -1,5 +1,5 @@ -//go:build (!noasm && arm64) || (!noasm && amd64) -// +build !noasm,arm64 !noasm,amd64 +//go:build (!purego && arm64) || (!purego && amd64) +// +build !purego,arm64 !purego,amd64 package p384 diff --git a/src/vendor/github.com/cloudflare/circl/kem/hybrid/hybrid.go b/src/vendor/github.com/cloudflare/circl/kem/hybrid/hybrid.go index be8251c7f74..8be85d70c81 100644 --- a/src/vendor/github.com/cloudflare/circl/kem/hybrid/hybrid.go +++ b/src/vendor/github.com/cloudflare/circl/kem/hybrid/hybrid.go @@ -1,13 +1,13 @@ -// Package hybrid defines several hybrid classical/quantum KEMs. +// Package hybrid defines several hybrid classical/quantum KEMs for use in TLS. // -// KEMs are combined by simple concatenation of shared secrets, cipher texts, -// public keys, etc, see +// Hybrid KEMs in TLS are created by simple concatenation +// of shared secrets, cipher texts, public keys, etc. +// This is safe for TLS, see eg. // // https://datatracker.ietf.org/doc/draft-ietf-tls-hybrid-design/ // https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Cr2.pdf // -// Note that this is only fine if the shared secret is used in its entirety -// in a next step, such as being hashed or used as key. +// Note that this approach is not proven secure in broader context. // // For deriving a KEM keypair deterministically and encapsulating // deterministically, we expand a single seed to both using SHAKE256, @@ -38,6 +38,7 @@ import ( "github.com/cloudflare/circl/kem/kyber/kyber1024" "github.com/cloudflare/circl/kem/kyber/kyber512" "github.com/cloudflare/circl/kem/kyber/kyber768" + "github.com/cloudflare/circl/kem/mlkem/mlkem768" ) var ErrUninitialized = errors.New("public or private key not initialized") @@ -57,6 +58,10 @@ func Kyber1024X448() kem.Scheme { return kyber1024X } // Returns the hybrid KEM of Kyber768Draft00 and P-256. func P256Kyber768Draft00() kem.Scheme { return p256Kyber768Draft00 } +// Returns the hybrid KEM of ML-KEM-768 and X25519. +// https://www.ietf.org/archive/id/draft-kwiatkowski-tls-ecdhe-mlkem-01.html +func X25519MLKEM768() kem.Scheme { return xmlkem768 } + var p256Kyber768Draft00 kem.Scheme = &scheme{ "P256Kyber768Draft00", p256Kem, @@ -87,6 +92,12 @@ var kyber1024X kem.Scheme = &scheme{ kyber1024.Scheme(), } +var xmlkem768 kem.Scheme = &scheme{ + "X25519MLKEM768", + mlkem768.Scheme(), + x25519Kem, +} + // Public key of a hybrid KEM. type publicKey struct { scheme *scheme diff --git a/src/vendor/github.com/cloudflare/circl/kem/kem.go b/src/vendor/github.com/cloudflare/circl/kem/kem.go index 6ab0aa3bad3..a2f6a2aae7a 100644 --- a/src/vendor/github.com/cloudflare/circl/kem/kem.go +++ b/src/vendor/github.com/cloudflare/circl/kem/kem.go @@ -113,6 +113,9 @@ var ( // ErrPubKey is the error used if the provided public key is invalid. ErrPubKey = errors.New("invalid public key") + // ErrPrivKey is the error used if the provided private key is invalid. + ErrPrivKey = errors.New("invalid private key") + // ErrCipherText is the error used if the provided ciphertext is invalid. ErrCipherText = errors.New("invalid ciphertext") ) diff --git a/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go b/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go index 428584528ea..c2f767cbe72 100644 --- a/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go +++ b/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go @@ -123,10 +123,10 @@ func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) { panic("ss must be of length SharedKeySize") } - // m = H(seed) var m [32]byte + // m = H(seed), the hash of shame h := sha3.New256() - h.Write(seed[:]) + h.Write(seed) h.Read(m[:]) // (K', r) = G(m ‖ H(pk)) @@ -194,7 +194,7 @@ func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) { // K = KDF(K''/z, H(c)) kdf := sha3.NewShake256() kdf.Write(kr2[:]) - kdf.Read(ss[:SharedKeySize]) + kdf.Read(ss) } // Packs sk to buf. @@ -258,6 +258,7 @@ func (pk *PublicKey) Unpack(buf []byte) { h := sha3.New256() h.Write(buf) h.Read(pk.hpk[:]) + } // Boilerplate down below for the KEM scheme API. @@ -386,10 +387,10 @@ func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) { } func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) { + var ret PublicKey if len(buf) != PublicKeySize { return nil, kem.ErrPubKeySize } - var ret PublicKey ret.Unpack(buf) return &ret, nil } diff --git a/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber512/kyber.go b/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber512/kyber.go index c250d78c673..e60ca0fe58b 100644 --- a/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber512/kyber.go +++ b/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber512/kyber.go @@ -123,10 +123,10 @@ func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) { panic("ss must be of length SharedKeySize") } - // m = H(seed) var m [32]byte + // m = H(seed), the hash of shame h := sha3.New256() - h.Write(seed[:]) + h.Write(seed) h.Read(m[:]) // (K', r) = G(m ‖ H(pk)) @@ -194,7 +194,7 @@ func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) { // K = KDF(K''/z, H(c)) kdf := sha3.NewShake256() kdf.Write(kr2[:]) - kdf.Read(ss[:SharedKeySize]) + kdf.Read(ss) } // Packs sk to buf. @@ -258,6 +258,7 @@ func (pk *PublicKey) Unpack(buf []byte) { h := sha3.New256() h.Write(buf) h.Read(pk.hpk[:]) + } // Boilerplate down below for the KEM scheme API. @@ -386,10 +387,10 @@ func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) { } func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) { + var ret PublicKey if len(buf) != PublicKeySize { return nil, kem.ErrPubKeySize } - var ret PublicKey ret.Unpack(buf) return &ret, nil } diff --git a/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber768/kyber.go b/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber768/kyber.go index 832d9b371ad..0e03c40ddd6 100644 --- a/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber768/kyber.go +++ b/src/vendor/github.com/cloudflare/circl/kem/kyber/kyber768/kyber.go @@ -123,10 +123,10 @@ func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) { panic("ss must be of length SharedKeySize") } - // m = H(seed) var m [32]byte + // m = H(seed), the hash of shame h := sha3.New256() - h.Write(seed[:]) + h.Write(seed) h.Read(m[:]) // (K', r) = G(m ‖ H(pk)) @@ -194,7 +194,7 @@ func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) { // K = KDF(K''/z, H(c)) kdf := sha3.NewShake256() kdf.Write(kr2[:]) - kdf.Read(ss[:SharedKeySize]) + kdf.Read(ss) } // Packs sk to buf. @@ -258,6 +258,7 @@ func (pk *PublicKey) Unpack(buf []byte) { h := sha3.New256() h.Write(buf) h.Read(pk.hpk[:]) + } // Boilerplate down below for the KEM scheme API. @@ -386,10 +387,10 @@ func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) { } func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) { + var ret PublicKey if len(buf) != PublicKeySize { return nil, kem.ErrPubKeySize } - var ret PublicKey ret.Unpack(buf) return &ret, nil } diff --git a/src/vendor/github.com/cloudflare/circl/kem/mlkem/mlkem768/kyber.go b/src/vendor/github.com/cloudflare/circl/kem/mlkem/mlkem768/kyber.go new file mode 100644 index 00000000000..afa48315671 --- /dev/null +++ b/src/vendor/github.com/cloudflare/circl/kem/mlkem/mlkem768/kyber.go @@ -0,0 +1,407 @@ +// Code generated from pkg.templ.go. DO NOT EDIT. + +// Package mlkem768 implements the IND-CCA2 secure key encapsulation mechanism +// ML-KEM-768 as defined in FIPS203. +package mlkem768 + +import ( + "bytes" + "crypto/subtle" + "io" + + cryptoRand "crypto/rand" + "github.com/cloudflare/circl/internal/sha3" + "github.com/cloudflare/circl/kem" + cpapke "github.com/cloudflare/circl/pke/kyber/kyber768" +) + +const ( + // Size of seed for NewKeyFromSeed + KeySeedSize = cpapke.KeySeedSize + 32 + + // Size of seed for EncapsulateTo. + EncapsulationSeedSize = 32 + + // Size of the established shared key. + SharedKeySize = 32 + + // Size of the encapsulated shared key. + CiphertextSize = cpapke.CiphertextSize + + // Size of a packed public key. + PublicKeySize = cpapke.PublicKeySize + + // Size of a packed private key. + PrivateKeySize = cpapke.PrivateKeySize + cpapke.PublicKeySize + 64 +) + +// Type of a ML-KEM-768 public key +type PublicKey struct { + pk *cpapke.PublicKey + + hpk [32]byte // H(pk) +} + +// Type of a ML-KEM-768 private key +type PrivateKey struct { + sk *cpapke.PrivateKey + pk *cpapke.PublicKey + hpk [32]byte // H(pk) + z [32]byte +} + +// NewKeyFromSeed derives a public/private keypair deterministically +// from the given seed. +// +// Panics if seed is not of length KeySeedSize. +func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) { + var sk PrivateKey + var pk PublicKey + + if len(seed) != KeySeedSize { + panic("seed must be of length KeySeedSize") + } + + pk.pk, sk.sk = cpapke.NewKeyFromSeedMLKEM(seed[:cpapke.KeySeedSize]) + sk.pk = pk.pk + copy(sk.z[:], seed[cpapke.KeySeedSize:]) + + // Compute H(pk) + var ppk [cpapke.PublicKeySize]byte + sk.pk.Pack(ppk[:]) + h := sha3.New256() + h.Write(ppk[:]) + h.Read(sk.hpk[:]) + copy(pk.hpk[:], sk.hpk[:]) + + return &pk, &sk +} + +// GenerateKeyPair generates public and private keys using entropy from rand. +// If rand is nil, crypto/rand.Reader will be used. +func GenerateKeyPair(rand io.Reader) (*PublicKey, *PrivateKey, error) { + var seed [KeySeedSize]byte + if rand == nil { + rand = cryptoRand.Reader + } + _, err := io.ReadFull(rand, seed[:]) + if err != nil { + return nil, nil, err + } + pk, sk := NewKeyFromSeed(seed[:]) + return pk, sk, nil +} + +// EncapsulateTo generates a shared key and ciphertext that contains it +// for the public key using randomness from seed and writes the shared key +// to ss and ciphertext to ct. +// +// Panics if ss, ct or seed are not of length SharedKeySize, CiphertextSize +// and EncapsulationSeedSize respectively. +// +// seed may be nil, in which case crypto/rand.Reader is used to generate one. +func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) { + if seed == nil { + seed = make([]byte, EncapsulationSeedSize) + if _, err := cryptoRand.Read(seed[:]); err != nil { + panic(err) + } + } else { + if len(seed) != EncapsulationSeedSize { + panic("seed must be of length EncapsulationSeedSize") + } + } + + if len(ct) != CiphertextSize { + panic("ct must be of length CiphertextSize") + } + + if len(ss) != SharedKeySize { + panic("ss must be of length SharedKeySize") + } + + var m [32]byte + copy(m[:], seed) + + // (K', r) = G(m ‖ H(pk)) + var kr [64]byte + g := sha3.New512() + g.Write(m[:]) + g.Write(pk.hpk[:]) + g.Read(kr[:]) + + // c = Kyber.CPAPKE.Enc(pk, m, r) + pk.pk.EncryptTo(ct, m[:], kr[32:]) + + copy(ss, kr[:SharedKeySize]) +} + +// DecapsulateTo computes the shared key which is encapsulated in ct +// for the private key. +// +// Panics if ct or ss are not of length CiphertextSize and SharedKeySize +// respectively. +func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) { + if len(ct) != CiphertextSize { + panic("ct must be of length CiphertextSize") + } + + if len(ss) != SharedKeySize { + panic("ss must be of length SharedKeySize") + } + + // m' = Kyber.CPAPKE.Dec(sk, ct) + var m2 [32]byte + sk.sk.DecryptTo(m2[:], ct) + + // (K'', r') = G(m' ‖ H(pk)) + var kr2 [64]byte + g := sha3.New512() + g.Write(m2[:]) + g.Write(sk.hpk[:]) + g.Read(kr2[:]) + + // c' = Kyber.CPAPKE.Enc(pk, m', r') + var ct2 [CiphertextSize]byte + sk.pk.EncryptTo(ct2[:], m2[:], kr2[32:]) + + var ss2 [SharedKeySize]byte + + // Compute shared secret in case of rejection: ss₂ = PRF(z ‖ c) + prf := sha3.NewShake256() + prf.Write(sk.z[:]) + prf.Write(ct[:CiphertextSize]) + prf.Read(ss2[:]) + + // Set ss2 to the real shared secret if c = c'. + subtle.ConstantTimeCopy( + subtle.ConstantTimeCompare(ct, ct2[:]), + ss2[:], + kr2[:SharedKeySize], + ) + + copy(ss, ss2[:]) +} + +// Packs sk to buf. +// +// Panics if buf is not of size PrivateKeySize. +func (sk *PrivateKey) Pack(buf []byte) { + if len(buf) != PrivateKeySize { + panic("buf must be of length PrivateKeySize") + } + + sk.sk.Pack(buf[:cpapke.PrivateKeySize]) + buf = buf[cpapke.PrivateKeySize:] + sk.pk.Pack(buf[:cpapke.PublicKeySize]) + buf = buf[cpapke.PublicKeySize:] + copy(buf, sk.hpk[:]) + buf = buf[32:] + copy(buf, sk.z[:]) +} + +// Unpacks sk from buf. +// +// Panics if buf is not of size PrivateKeySize. +// +// Returns an error if buf is not of size PrivateKeySize, or private key +// doesn't pass the ML-KEM decapsulation key check. +func (sk *PrivateKey) Unpack(buf []byte) error { + if len(buf) != PrivateKeySize { + return kem.ErrPrivKeySize + } + + sk.sk = new(cpapke.PrivateKey) + sk.sk.Unpack(buf[:cpapke.PrivateKeySize]) + buf = buf[cpapke.PrivateKeySize:] + sk.pk = new(cpapke.PublicKey) + sk.pk.Unpack(buf[:cpapke.PublicKeySize]) + var hpk [32]byte + h := sha3.New256() + h.Write(buf[:cpapke.PublicKeySize]) + h.Read(hpk[:]) + buf = buf[cpapke.PublicKeySize:] + copy(sk.hpk[:], buf[:32]) + copy(sk.z[:], buf[32:]) + if !bytes.Equal(hpk[:], sk.hpk[:]) { + return kem.ErrPrivKey + } + return nil +} + +// Packs pk to buf. +// +// Panics if buf is not of size PublicKeySize. +func (pk *PublicKey) Pack(buf []byte) { + if len(buf) != PublicKeySize { + panic("buf must be of length PublicKeySize") + } + + pk.pk.Pack(buf) +} + +// Unpacks pk from buf. +// +// Returns an error if buf is not of size PublicKeySize, or the public key +// is not normalized. +func (pk *PublicKey) Unpack(buf []byte) error { + if len(buf) != PublicKeySize { + return kem.ErrPubKeySize + } + + pk.pk = new(cpapke.PublicKey) + if err := pk.pk.UnpackMLKEM(buf); err != nil { + return err + } + + // Compute cached H(pk) + h := sha3.New256() + h.Write(buf) + h.Read(pk.hpk[:]) + + return nil +} + +// Boilerplate down below for the KEM scheme API. + +type scheme struct{} + +var sch kem.Scheme = &scheme{} + +// Scheme returns a KEM interface. +func Scheme() kem.Scheme { return sch } + +func (*scheme) Name() string { return "ML-KEM-768" } +func (*scheme) PublicKeySize() int { return PublicKeySize } +func (*scheme) PrivateKeySize() int { return PrivateKeySize } +func (*scheme) SeedSize() int { return KeySeedSize } +func (*scheme) SharedKeySize() int { return SharedKeySize } +func (*scheme) CiphertextSize() int { return CiphertextSize } +func (*scheme) EncapsulationSeedSize() int { return EncapsulationSeedSize } + +func (sk *PrivateKey) Scheme() kem.Scheme { return sch } +func (pk *PublicKey) Scheme() kem.Scheme { return sch } + +func (sk *PrivateKey) MarshalBinary() ([]byte, error) { + var ret [PrivateKeySize]byte + sk.Pack(ret[:]) + return ret[:], nil +} + +func (sk *PrivateKey) Equal(other kem.PrivateKey) bool { + oth, ok := other.(*PrivateKey) + if !ok { + return false + } + if sk.pk == nil && oth.pk == nil { + return true + } + if sk.pk == nil || oth.pk == nil { + return false + } + if !bytes.Equal(sk.hpk[:], oth.hpk[:]) || + subtle.ConstantTimeCompare(sk.z[:], oth.z[:]) != 1 { + return false + } + return sk.sk.Equal(oth.sk) +} + +func (pk *PublicKey) Equal(other kem.PublicKey) bool { + oth, ok := other.(*PublicKey) + if !ok { + return false + } + if pk.pk == nil && oth.pk == nil { + return true + } + if pk.pk == nil || oth.pk == nil { + return false + } + return bytes.Equal(pk.hpk[:], oth.hpk[:]) +} + +func (sk *PrivateKey) Public() kem.PublicKey { + pk := new(PublicKey) + pk.pk = sk.pk + copy(pk.hpk[:], sk.hpk[:]) + return pk +} + +func (pk *PublicKey) MarshalBinary() ([]byte, error) { + var ret [PublicKeySize]byte + pk.Pack(ret[:]) + return ret[:], nil +} + +func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) { + return GenerateKeyPair(cryptoRand.Reader) +} + +func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) { + if len(seed) != KeySeedSize { + panic(kem.ErrSeedSize) + } + return NewKeyFromSeed(seed[:]) +} + +func (*scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) { + ct = make([]byte, CiphertextSize) + ss = make([]byte, SharedKeySize) + + pub, ok := pk.(*PublicKey) + if !ok { + return nil, nil, kem.ErrTypeMismatch + } + pub.EncapsulateTo(ct, ss, nil) + return +} + +func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) ( + ct, ss []byte, err error) { + if len(seed) != EncapsulationSeedSize { + return nil, nil, kem.ErrSeedSize + } + + ct = make([]byte, CiphertextSize) + ss = make([]byte, SharedKeySize) + + pub, ok := pk.(*PublicKey) + if !ok { + return nil, nil, kem.ErrTypeMismatch + } + pub.EncapsulateTo(ct, ss, seed) + return +} + +func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) { + if len(ct) != CiphertextSize { + return nil, kem.ErrCiphertextSize + } + + priv, ok := sk.(*PrivateKey) + if !ok { + return nil, kem.ErrTypeMismatch + } + ss := make([]byte, SharedKeySize) + priv.DecapsulateTo(ss, ct) + return ss, nil +} + +func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) { + var ret PublicKey + if err := ret.Unpack(buf); err != nil { + return nil, err + } + return &ret, nil +} + +func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) { + if len(buf) != PrivateKeySize { + return nil, kem.ErrPrivKeySize + } + var ret PrivateKey + if err := ret.Unpack(buf); err != nil { + return nil, err + } + return &ret, nil +} diff --git a/src/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s b/src/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s index 5c4aeddecb4..1fcc2dee17f 100644 --- a/src/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s +++ b/src/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s @@ -1,4 +1,5 @@ -// +build amd64 +//go:build amd64 && !purego +// +build amd64,!purego #include "textflag.h" #include "fp_amd64.h" diff --git a/src/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s b/src/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s index 435addf5e6c..3f1f07c9862 100644 --- a/src/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s +++ b/src/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s @@ -1,4 +1,5 @@ -// +build amd64 +//go:build amd64 && !purego +// +build amd64,!purego #include "textflag.h" #include "fp_amd64.h" diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go index 6ffd94b1fc2..2c96563c7dc 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go @@ -1,5 +1,5 @@ -//go:build amd64 -// +build amd64 +//go:build amd64 && !purego +// +build amd64,!purego package common diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s b/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s index f721482fb9d..5c7536b7013 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s @@ -1,6 +1,6 @@ // Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT. -//go:build amd64 +//go:build amd64 && !purego #include "textflag.h" diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go index 2b742b95a38..66e0e86dc8c 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go @@ -1,5 +1,5 @@ -//go:build !amd64 -// +build !amd64 +//go:build !amd64 || purego +// +build !amd64 purego package common diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go index cf14cff912d..4b4700dfd9d 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go @@ -1,6 +1,6 @@ // Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT. -//go:build amd64 +//go:build amd64 && !purego package common diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go index 01ef88b2f60..bea07e87438 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go @@ -3,7 +3,10 @@ package internal import ( + "bytes" + "github.com/cloudflare/circl/internal/sha3" + "github.com/cloudflare/circl/kem" "github.com/cloudflare/circl/pke/kyber/internal/common" ) @@ -38,6 +41,19 @@ func (pk *PublicKey) Pack(buf []byte) { copy(buf[K*common.PolySize:], pk.rho[:]) } +// Unpacks the public key from buf. Checks if the public key is normalized. +func (pk *PublicKey) UnpackMLKEM(buf []byte) error { + pk.Unpack(buf) + + // FIPS 203 §7.2 "encapsulation key check" (2). + var buf2 [K * common.PolySize]byte + pk.th.Pack(buf2[:]) + if !bytes.Equal(buf[:len(buf2)], buf2[:]) { + return kem.ErrPubKey + } + return nil +} + // Unpacks the public key from buf. func (pk *PublicKey) Unpack(buf []byte) { pk.th.Unpack(buf) diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/kyber.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/kyber.go index fb5911facd4..86cc6c6dbcd 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/kyber.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/kyber.go @@ -1,4 +1,4 @@ -// Code generated from modePkg.templ.go. DO NOT EDIT. +// Code generated from pkg.templ.go. DO NOT EDIT. // kyber1024 implements the IND-CPA-secure Public Key Encryption // scheme Kyber1024.CPAPKE as submitted to round 3 of the NIST PQC competition @@ -11,6 +11,7 @@ import ( cryptoRand "crypto/rand" "io" + "github.com/cloudflare/circl/kem" "github.com/cloudflare/circl/pke/kyber/kyber1024/internal" ) @@ -57,6 +58,9 @@ func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) { // NewKeyFromSeed derives a public/private key pair using the given seed. // +// Note: does not include the domain separation of ML-KEM (line 1, algorithm 13 +// of FIPS 203). For that use NewKeyFromSeedMLKEM(). +// // Panics if seed is not of length KeySeedSize. func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) { if len(seed) != KeySeedSize { @@ -66,6 +70,21 @@ func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) { return (*PublicKey)(pk), (*PrivateKey)(sk) } +// NewKeyFromSeedMLKEM derives a public/private key pair using the given seed +// using the domain separation of ML-KEM. +// +// Panics if seed is not of length KeySeedSize. +func NewKeyFromSeedMLKEM(seed []byte) (*PublicKey, *PrivateKey) { + if len(seed) != KeySeedSize { + panic("seed must be of length KeySeedSize") + } + var seed2 [33]byte + copy(seed2[:32], seed) + seed2[32] = byte(internal.K) + pk, sk := internal.NewKeyFromSeed(seed2[:]) + return (*PublicKey)(pk), (*PrivateKey)(sk) +} + // EncryptTo encrypts message pt for the public key and writes the ciphertext // to ct using randomness from seed. // @@ -129,6 +148,17 @@ func (pk *PublicKey) Unpack(buf []byte) { (*internal.PublicKey)(pk).Unpack(buf) } +// Unpacks pk from the given buffer. +// +// Returns an error if the buffer is not of the right size, or the public +// key is not normalized. +func (pk *PublicKey) UnpackMLKEM(buf []byte) error { + if len(buf) != PublicKeySize { + return kem.ErrPubKeySize + } + return (*internal.PublicKey)(pk).UnpackMLKEM(buf) +} + // Unpacks sk from the given buffer. // // Panics if buf is not of length PrivateKeySize. diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go index 80ab2501c2f..be9bd6eafd5 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go @@ -1,7 +1,10 @@ package internal import ( + "bytes" + "github.com/cloudflare/circl/internal/sha3" + "github.com/cloudflare/circl/kem" "github.com/cloudflare/circl/pke/kyber/internal/common" ) @@ -36,6 +39,19 @@ func (pk *PublicKey) Pack(buf []byte) { copy(buf[K*common.PolySize:], pk.rho[:]) } +// Unpacks the public key from buf. Checks if the public key is normalized. +func (pk *PublicKey) UnpackMLKEM(buf []byte) error { + pk.Unpack(buf) + + // FIPS 203 §7.2 "encapsulation key check" (2). + var buf2 [K * common.PolySize]byte + pk.th.Pack(buf2[:]) + if !bytes.Equal(buf[:len(buf2)], buf2[:]) { + return kem.ErrPubKey + } + return nil +} + // Unpacks the public key from buf. func (pk *PublicKey) Unpack(buf []byte) { pk.th.Unpack(buf) diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/kyber.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/kyber.go index ea9248487e1..d4b166a5244 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/kyber.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/kyber.go @@ -1,4 +1,4 @@ -// Code generated from modePkg.templ.go. DO NOT EDIT. +// Code generated from pkg.templ.go. DO NOT EDIT. // kyber512 implements the IND-CPA-secure Public Key Encryption // scheme Kyber512.CPAPKE as submitted to round 3 of the NIST PQC competition @@ -11,6 +11,7 @@ import ( cryptoRand "crypto/rand" "io" + "github.com/cloudflare/circl/kem" "github.com/cloudflare/circl/pke/kyber/kyber512/internal" ) @@ -57,6 +58,9 @@ func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) { // NewKeyFromSeed derives a public/private key pair using the given seed. // +// Note: does not include the domain separation of ML-KEM (line 1, algorithm 13 +// of FIPS 203). For that use NewKeyFromSeedMLKEM(). +// // Panics if seed is not of length KeySeedSize. func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) { if len(seed) != KeySeedSize { @@ -66,6 +70,21 @@ func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) { return (*PublicKey)(pk), (*PrivateKey)(sk) } +// NewKeyFromSeedMLKEM derives a public/private key pair using the given seed +// using the domain separation of ML-KEM. +// +// Panics if seed is not of length KeySeedSize. +func NewKeyFromSeedMLKEM(seed []byte) (*PublicKey, *PrivateKey) { + if len(seed) != KeySeedSize { + panic("seed must be of length KeySeedSize") + } + var seed2 [33]byte + copy(seed2[:32], seed) + seed2[32] = byte(internal.K) + pk, sk := internal.NewKeyFromSeed(seed2[:]) + return (*PublicKey)(pk), (*PrivateKey)(sk) +} + // EncryptTo encrypts message pt for the public key and writes the ciphertext // to ct using randomness from seed. // @@ -129,6 +148,17 @@ func (pk *PublicKey) Unpack(buf []byte) { (*internal.PublicKey)(pk).Unpack(buf) } +// Unpacks pk from the given buffer. +// +// Returns an error if the buffer is not of the right size, or the public +// key is not normalized. +func (pk *PublicKey) UnpackMLKEM(buf []byte) error { + if len(buf) != PublicKeySize { + return kem.ErrPubKeySize + } + return (*internal.PublicKey)(pk).UnpackMLKEM(buf) +} + // Unpacks sk from the given buffer. // // Panics if buf is not of length PrivateKeySize. diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go index 01ef88b2f60..bea07e87438 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go @@ -3,7 +3,10 @@ package internal import ( + "bytes" + "github.com/cloudflare/circl/internal/sha3" + "github.com/cloudflare/circl/kem" "github.com/cloudflare/circl/pke/kyber/internal/common" ) @@ -38,6 +41,19 @@ func (pk *PublicKey) Pack(buf []byte) { copy(buf[K*common.PolySize:], pk.rho[:]) } +// Unpacks the public key from buf. Checks if the public key is normalized. +func (pk *PublicKey) UnpackMLKEM(buf []byte) error { + pk.Unpack(buf) + + // FIPS 203 §7.2 "encapsulation key check" (2). + var buf2 [K * common.PolySize]byte + pk.th.Pack(buf2[:]) + if !bytes.Equal(buf[:len(buf2)], buf2[:]) { + return kem.ErrPubKey + } + return nil +} + // Unpacks the public key from buf. func (pk *PublicKey) Unpack(buf []byte) { pk.th.Unpack(buf) diff --git a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/kyber.go b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/kyber.go index 4cecbb1b871..75bb7bd34db 100644 --- a/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/kyber.go +++ b/src/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/kyber.go @@ -1,4 +1,4 @@ -// Code generated from modePkg.templ.go. DO NOT EDIT. +// Code generated from pkg.templ.go. DO NOT EDIT. // kyber768 implements the IND-CPA-secure Public Key Encryption // scheme Kyber768.CPAPKE as submitted to round 3 of the NIST PQC competition @@ -11,6 +11,7 @@ import ( cryptoRand "crypto/rand" "io" + "github.com/cloudflare/circl/kem" "github.com/cloudflare/circl/pke/kyber/kyber768/internal" ) @@ -57,6 +58,9 @@ func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) { // NewKeyFromSeed derives a public/private key pair using the given seed. // +// Note: does not include the domain separation of ML-KEM (line 1, algorithm 13 +// of FIPS 203). For that use NewKeyFromSeedMLKEM(). +// // Panics if seed is not of length KeySeedSize. func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) { if len(seed) != KeySeedSize { @@ -66,6 +70,21 @@ func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) { return (*PublicKey)(pk), (*PrivateKey)(sk) } +// NewKeyFromSeedMLKEM derives a public/private key pair using the given seed +// using the domain separation of ML-KEM. +// +// Panics if seed is not of length KeySeedSize. +func NewKeyFromSeedMLKEM(seed []byte) (*PublicKey, *PrivateKey) { + if len(seed) != KeySeedSize { + panic("seed must be of length KeySeedSize") + } + var seed2 [33]byte + copy(seed2[:32], seed) + seed2[32] = byte(internal.K) + pk, sk := internal.NewKeyFromSeed(seed2[:]) + return (*PublicKey)(pk), (*PrivateKey)(sk) +} + // EncryptTo encrypts message pt for the public key and writes the ciphertext // to ct using randomness from seed. // @@ -129,6 +148,17 @@ func (pk *PublicKey) Unpack(buf []byte) { (*internal.PublicKey)(pk).Unpack(buf) } +// Unpacks pk from the given buffer. +// +// Returns an error if the buffer is not of the right size, or the public +// key is not normalized. +func (pk *PublicKey) UnpackMLKEM(buf []byte) error { + if len(buf) != PublicKeySize { + return kem.ErrPubKeySize + } + return (*internal.PublicKey)(pk).UnpackMLKEM(buf) +} + // Unpacks sk from the given buffer. // // Panics if buf is not of length PrivateKeySize. diff --git a/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.go b/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.go index a58e4bf46a9..11f0e3dcf6b 100644 --- a/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.go +++ b/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.go @@ -1,5 +1,5 @@ -//go:build amd64 -// +build amd64 +//go:build amd64 && !purego +// +build amd64,!purego package common diff --git a/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.s b/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.s index 90953ac1ebe..94180fb7344 100644 --- a/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.s +++ b/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.s @@ -1,6 +1,6 @@ // Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT. -//go:build amd64 +//go:build amd64 && !purego #include "textflag.h" diff --git a/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/generic.go b/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/generic.go index f10545246ab..2736e1617f4 100644 --- a/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/generic.go +++ b/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/generic.go @@ -1,5 +1,5 @@ -//go:build !amd64 -// +build !amd64 +//go:build !amd64 || purego +// +build !amd64 purego package common diff --git a/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/stubs_amd64.go b/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/stubs_amd64.go index 97451507f8d..3afeda4ddbb 100644 --- a/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/stubs_amd64.go +++ b/src/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/stubs_amd64.go @@ -1,6 +1,6 @@ // Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT. -//go:build amd64 +//go:build amd64 && !purego package common diff --git a/src/vendor/github.com/cloudflare/circl/sign/eddilithium3/eddilithium.go b/src/vendor/github.com/cloudflare/circl/sign/eddilithium3/eddilithium.go index d1c8d629d64..aa05c689c31 100644 --- a/src/vendor/github.com/cloudflare/circl/sign/eddilithium3/eddilithium.go +++ b/src/vendor/github.com/cloudflare/circl/sign/eddilithium3/eddilithium.go @@ -162,7 +162,7 @@ func (sk *PrivateKey) MarshalBinary() ([]byte, error) { // UnmarshalBinary the public key from data. func (pk *PublicKey) UnmarshalBinary(data []byte) error { if len(data) != PublicKeySize { - return errors.New("packed public key must be of eddilithium4.PublicKeySize bytes") + return errors.New("packed public key must be of eddilithium3.PublicKeySize bytes") } var buf [PublicKeySize]byte copy(buf[:], data) @@ -173,7 +173,7 @@ func (pk *PublicKey) UnmarshalBinary(data []byte) error { // UnmarshalBinary unpacks the private key from data. func (sk *PrivateKey) UnmarshalBinary(data []byte) error { if len(data) != PrivateKeySize { - return errors.New("packed private key must be of eddilithium4.PrivateKeySize bytes") + return errors.New("packed private key must be of eddilithium3.PrivateKeySize bytes") } var buf [PrivateKeySize]byte copy(buf[:], data) @@ -215,7 +215,7 @@ func (sk *PrivateKey) Sign( var sig [SignatureSize]byte if opts.HashFunc() != crypto.Hash(0) { - return nil, errors.New("eddilithium4: cannot sign hashed message") + return nil, errors.New("eddilithium3: cannot sign hashed message") } SignTo(sk, msg, sig[:]) diff --git a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go index 44f05436a84..0cb9692c327 100644 --- a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go +++ b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go @@ -1,5 +1,5 @@ -//go:build arm64 && go1.16 -// +build arm64,go1.16 +//go:build arm64 && go1.16 && !purego +// +build arm64,go1.16,!purego package keccakf1600 diff --git a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s index 68dd0e37bc0..998aeca5b4c 100644 --- a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s +++ b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s @@ -1,4 +1,4 @@ -// +build arm64,go1.16 +// +build arm64,go1.16,!purego // Taken from https://github.com/bwesterb/armed-keccak diff --git a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go index 669ce65f4db..bf5b865d0b6 100644 --- a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go +++ b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go @@ -1,3 +1,6 @@ +//go:build amd64 && !purego +// +build amd64,!purego + package keccakf1600 import "github.com/cloudflare/circl/internal/sha3" diff --git a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s index 314a8555330..67b64550c26 100644 --- a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s +++ b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s @@ -1,6 +1,6 @@ // Code generated by command: go run src.go -out ../../f1600x4_amd64.s -stubs ../../f1600x4stubs_amd64.go -pkg keccakf1600. DO NOT EDIT. -//go:build amd64 +//go:build amd64 && !purego #include "textflag.h" diff --git a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go index de289441ef5..102fdd04d16 100644 --- a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go +++ b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go @@ -1,6 +1,6 @@ // Code generated by command: go run src.go -out ../../f1600x4_amd64.s -stubs ../../f1600x4stubs_amd64.go -pkg keccakf1600. DO NOT EDIT. -//go:build amd64 +//go:build amd64 && !purego package keccakf1600 diff --git a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/fallback.go b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/fallback.go index 5287c1f5d7b..0da75e9b776 100644 --- a/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/fallback.go +++ b/src/vendor/github.com/cloudflare/circl/simd/keccakf1600/fallback.go @@ -1,5 +1,5 @@ -//go:build (!amd64 && !arm64) || (arm64 && !go1.16) -// +build !amd64,!arm64 arm64,!go1.16 +//go:build (!amd64 && !arm64) || (arm64 && !go1.16) || purego +// +build !amd64,!arm64 arm64,!go1.16 purego package keccakf1600 diff --git a/src/vendor/golang.org/x/crypto/sha3/doc.go b/src/vendor/golang.org/x/crypto/sha3/doc.go new file mode 100644 index 00000000000..decd8cf9bf7 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/doc.go @@ -0,0 +1,62 @@ +// Copyright 2014 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 sha3 implements the SHA-3 fixed-output-length hash functions and +// the SHAKE variable-output-length hash functions defined by FIPS-202. +// +// Both types of hash function use the "sponge" construction and the Keccak +// permutation. For a detailed specification see http://keccak.noekeon.org/ +// +// # Guidance +// +// If you aren't sure what function you need, use SHAKE256 with at least 64 +// bytes of output. The SHAKE instances are faster than the SHA3 instances; +// the latter have to allocate memory to conform to the hash.Hash interface. +// +// If you need a secret-key MAC (message authentication code), prepend the +// secret key to the input, hash with SHAKE256 and read at least 32 bytes of +// output. +// +// # Security strengths +// +// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security +// strength against preimage attacks of x bits. Since they only produce "x" +// bits of output, their collision-resistance is only "x/2" bits. +// +// The SHAKE-256 and -128 functions have a generic security strength of 256 and +// 128 bits against all attacks, provided that at least 2x bits of their output +// is used. Requesting more than 64 or 32 bytes of output, respectively, does +// not increase the collision-resistance of the SHAKE functions. +// +// # The sponge construction +// +// A sponge builds a pseudo-random function from a public pseudo-random +// permutation, by applying the permutation to a state of "rate + capacity" +// bytes, but hiding "capacity" of the bytes. +// +// A sponge starts out with a zero state. To hash an input using a sponge, up +// to "rate" bytes of the input are XORed into the sponge's state. The sponge +// is then "full" and the permutation is applied to "empty" it. This process is +// repeated until all the input has been "absorbed". The input is then padded. +// The digest is "squeezed" from the sponge in the same way, except that output +// is copied out instead of input being XORed in. +// +// A sponge is parameterized by its generic security strength, which is equal +// to half its capacity; capacity + rate is equal to the permutation's width. +// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means +// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2. +// +// # Recommendations +// +// The SHAKE functions are recommended for most new uses. They can produce +// output of arbitrary length. SHAKE256, with an output length of at least +// 64 bytes, provides 256-bit security against all attacks. The Keccak team +// recommends it for most applications upgrading from SHA2-512. (NIST chose a +// much stronger, but much slower, sponge instance for SHA3-512.) +// +// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions. +// They produce output of the same length, with the same security strengths +// against all attacks. This means, in particular, that SHA3-256 only has +// 128-bit collision resistance, because its output length is 32 bytes. +package sha3 // import "golang.org/x/crypto/sha3" diff --git a/src/vendor/golang.org/x/crypto/sha3/hashes.go b/src/vendor/golang.org/x/crypto/sha3/hashes.go new file mode 100644 index 00000000000..0d8043fd2a1 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/hashes.go @@ -0,0 +1,97 @@ +// Copyright 2014 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 sha3 + +// This file provides functions for creating instances of the SHA-3 +// and SHAKE hash functions, as well as utility functions for hashing +// bytes. + +import ( + "hash" +) + +// New224 creates a new SHA3-224 hash. +// Its generic security strength is 224 bits against preimage attacks, +// and 112 bits against collision attacks. +func New224() hash.Hash { + if h := new224Asm(); h != nil { + return h + } + return &state{rate: 144, outputLen: 28, dsbyte: 0x06} +} + +// New256 creates a new SHA3-256 hash. +// Its generic security strength is 256 bits against preimage attacks, +// and 128 bits against collision attacks. +func New256() hash.Hash { + if h := new256Asm(); h != nil { + return h + } + return &state{rate: 136, outputLen: 32, dsbyte: 0x06} +} + +// New384 creates a new SHA3-384 hash. +// Its generic security strength is 384 bits against preimage attacks, +// and 192 bits against collision attacks. +func New384() hash.Hash { + if h := new384Asm(); h != nil { + return h + } + return &state{rate: 104, outputLen: 48, dsbyte: 0x06} +} + +// New512 creates a new SHA3-512 hash. +// Its generic security strength is 512 bits against preimage attacks, +// and 256 bits against collision attacks. +func New512() hash.Hash { + if h := new512Asm(); h != nil { + return h + } + return &state{rate: 72, outputLen: 64, dsbyte: 0x06} +} + +// NewLegacyKeccak256 creates a new Keccak-256 hash. +// +// Only use this function if you require compatibility with an existing cryptosystem +// that uses non-standard padding. All other users should use New256 instead. +func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} } + +// NewLegacyKeccak512 creates a new Keccak-512 hash. +// +// Only use this function if you require compatibility with an existing cryptosystem +// that uses non-standard padding. All other users should use New512 instead. +func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} } + +// Sum224 returns the SHA3-224 digest of the data. +func Sum224(data []byte) (digest [28]byte) { + h := New224() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum256 returns the SHA3-256 digest of the data. +func Sum256(data []byte) (digest [32]byte) { + h := New256() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum384 returns the SHA3-384 digest of the data. +func Sum384(data []byte) (digest [48]byte) { + h := New384() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum512 returns the SHA3-512 digest of the data. +func Sum512(data []byte) (digest [64]byte) { + h := New512() + h.Write(data) + h.Sum(digest[:0]) + return +} diff --git a/src/vendor/golang.org/x/crypto/sha3/hashes_generic.go b/src/vendor/golang.org/x/crypto/sha3/hashes_generic.go new file mode 100644 index 00000000000..fe8c84793c0 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/hashes_generic.go @@ -0,0 +1,27 @@ +// 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. + +//go:build !gc || purego || !s390x + +package sha3 + +import ( + "hash" +) + +// new224Asm returns an assembly implementation of SHA3-224 if available, +// otherwise it returns nil. +func new224Asm() hash.Hash { return nil } + +// new256Asm returns an assembly implementation of SHA3-256 if available, +// otherwise it returns nil. +func new256Asm() hash.Hash { return nil } + +// new384Asm returns an assembly implementation of SHA3-384 if available, +// otherwise it returns nil. +func new384Asm() hash.Hash { return nil } + +// new512Asm returns an assembly implementation of SHA3-512 if available, +// otherwise it returns nil. +func new512Asm() hash.Hash { return nil } diff --git a/src/vendor/golang.org/x/crypto/sha3/keccakf.go b/src/vendor/golang.org/x/crypto/sha3/keccakf.go new file mode 100644 index 00000000000..ce48b1dd3ed --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/keccakf.go @@ -0,0 +1,414 @@ +// Copyright 2014 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. + +//go:build !amd64 || purego || !gc + +package sha3 + +import "math/bits" + +// rc stores the round constants for use in the ι step. +var rc = [24]uint64{ + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808A, + 0x8000000080008000, + 0x000000000000808B, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008A, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000A, + 0x000000008000808B, + 0x800000000000008B, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800A, + 0x800000008000000A, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, +} + +// keccakF1600 applies the Keccak permutation to a 1600b-wide +// state represented as a slice of 25 uint64s. +func keccakF1600(a *[25]uint64) { + // Implementation translated from Keccak-inplace.c + // in the keccak reference code. + var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64 + + for i := 0; i < 24; i += 4 { + // Combines the 5 steps in each round into 2 steps. + // Unrolls 4 rounds per loop and spreads some steps across rounds. + + // Round 1 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[6] ^ d1 + bc1 = bits.RotateLeft64(t, 44) + t = a[12] ^ d2 + bc2 = bits.RotateLeft64(t, 43) + t = a[18] ^ d3 + bc3 = bits.RotateLeft64(t, 21) + t = a[24] ^ d4 + bc4 = bits.RotateLeft64(t, 14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i] + a[6] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc2 = bits.RotateLeft64(t, 3) + t = a[16] ^ d1 + bc3 = bits.RotateLeft64(t, 45) + t = a[22] ^ d2 + bc4 = bits.RotateLeft64(t, 61) + t = a[3] ^ d3 + bc0 = bits.RotateLeft64(t, 28) + t = a[9] ^ d4 + bc1 = bits.RotateLeft64(t, 20) + a[10] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc4 = bits.RotateLeft64(t, 18) + t = a[1] ^ d1 + bc0 = bits.RotateLeft64(t, 1) + t = a[7] ^ d2 + bc1 = bits.RotateLeft64(t, 6) + t = a[13] ^ d3 + bc2 = bits.RotateLeft64(t, 25) + t = a[19] ^ d4 + bc3 = bits.RotateLeft64(t, 8) + a[20] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc1 = bits.RotateLeft64(t, 36) + t = a[11] ^ d1 + bc2 = bits.RotateLeft64(t, 10) + t = a[17] ^ d2 + bc3 = bits.RotateLeft64(t, 15) + t = a[23] ^ d3 + bc4 = bits.RotateLeft64(t, 56) + t = a[4] ^ d4 + bc0 = bits.RotateLeft64(t, 27) + a[5] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc3 = bits.RotateLeft64(t, 41) + t = a[21] ^ d1 + bc4 = bits.RotateLeft64(t, 2) + t = a[2] ^ d2 + bc0 = bits.RotateLeft64(t, 62) + t = a[8] ^ d3 + bc1 = bits.RotateLeft64(t, 55) + t = a[14] ^ d4 + bc2 = bits.RotateLeft64(t, 39) + a[15] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + // Round 2 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[16] ^ d1 + bc1 = bits.RotateLeft64(t, 44) + t = a[7] ^ d2 + bc2 = bits.RotateLeft64(t, 43) + t = a[23] ^ d3 + bc3 = bits.RotateLeft64(t, 21) + t = a[14] ^ d4 + bc4 = bits.RotateLeft64(t, 14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1] + a[16] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc2 = bits.RotateLeft64(t, 3) + t = a[11] ^ d1 + bc3 = bits.RotateLeft64(t, 45) + t = a[2] ^ d2 + bc4 = bits.RotateLeft64(t, 61) + t = a[18] ^ d3 + bc0 = bits.RotateLeft64(t, 28) + t = a[9] ^ d4 + bc1 = bits.RotateLeft64(t, 20) + a[20] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc4 = bits.RotateLeft64(t, 18) + t = a[6] ^ d1 + bc0 = bits.RotateLeft64(t, 1) + t = a[22] ^ d2 + bc1 = bits.RotateLeft64(t, 6) + t = a[13] ^ d3 + bc2 = bits.RotateLeft64(t, 25) + t = a[4] ^ d4 + bc3 = bits.RotateLeft64(t, 8) + a[15] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc1 = bits.RotateLeft64(t, 36) + t = a[1] ^ d1 + bc2 = bits.RotateLeft64(t, 10) + t = a[17] ^ d2 + bc3 = bits.RotateLeft64(t, 15) + t = a[8] ^ d3 + bc4 = bits.RotateLeft64(t, 56) + t = a[24] ^ d4 + bc0 = bits.RotateLeft64(t, 27) + a[10] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc3 = bits.RotateLeft64(t, 41) + t = a[21] ^ d1 + bc4 = bits.RotateLeft64(t, 2) + t = a[12] ^ d2 + bc0 = bits.RotateLeft64(t, 62) + t = a[3] ^ d3 + bc1 = bits.RotateLeft64(t, 55) + t = a[19] ^ d4 + bc2 = bits.RotateLeft64(t, 39) + a[5] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + // Round 3 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[11] ^ d1 + bc1 = bits.RotateLeft64(t, 44) + t = a[22] ^ d2 + bc2 = bits.RotateLeft64(t, 43) + t = a[8] ^ d3 + bc3 = bits.RotateLeft64(t, 21) + t = a[19] ^ d4 + bc4 = bits.RotateLeft64(t, 14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2] + a[11] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc2 = bits.RotateLeft64(t, 3) + t = a[1] ^ d1 + bc3 = bits.RotateLeft64(t, 45) + t = a[12] ^ d2 + bc4 = bits.RotateLeft64(t, 61) + t = a[23] ^ d3 + bc0 = bits.RotateLeft64(t, 28) + t = a[9] ^ d4 + bc1 = bits.RotateLeft64(t, 20) + a[15] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc4 = bits.RotateLeft64(t, 18) + t = a[16] ^ d1 + bc0 = bits.RotateLeft64(t, 1) + t = a[2] ^ d2 + bc1 = bits.RotateLeft64(t, 6) + t = a[13] ^ d3 + bc2 = bits.RotateLeft64(t, 25) + t = a[24] ^ d4 + bc3 = bits.RotateLeft64(t, 8) + a[5] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc1 = bits.RotateLeft64(t, 36) + t = a[6] ^ d1 + bc2 = bits.RotateLeft64(t, 10) + t = a[17] ^ d2 + bc3 = bits.RotateLeft64(t, 15) + t = a[3] ^ d3 + bc4 = bits.RotateLeft64(t, 56) + t = a[14] ^ d4 + bc0 = bits.RotateLeft64(t, 27) + a[20] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc3 = bits.RotateLeft64(t, 41) + t = a[21] ^ d1 + bc4 = bits.RotateLeft64(t, 2) + t = a[7] ^ d2 + bc0 = bits.RotateLeft64(t, 62) + t = a[18] ^ d3 + bc1 = bits.RotateLeft64(t, 55) + t = a[4] ^ d4 + bc2 = bits.RotateLeft64(t, 39) + a[10] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + // Round 4 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[1] ^ d1 + bc1 = bits.RotateLeft64(t, 44) + t = a[2] ^ d2 + bc2 = bits.RotateLeft64(t, 43) + t = a[3] ^ d3 + bc3 = bits.RotateLeft64(t, 21) + t = a[4] ^ d4 + bc4 = bits.RotateLeft64(t, 14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3] + a[1] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc2 = bits.RotateLeft64(t, 3) + t = a[6] ^ d1 + bc3 = bits.RotateLeft64(t, 45) + t = a[7] ^ d2 + bc4 = bits.RotateLeft64(t, 61) + t = a[8] ^ d3 + bc0 = bits.RotateLeft64(t, 28) + t = a[9] ^ d4 + bc1 = bits.RotateLeft64(t, 20) + a[5] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc4 = bits.RotateLeft64(t, 18) + t = a[11] ^ d1 + bc0 = bits.RotateLeft64(t, 1) + t = a[12] ^ d2 + bc1 = bits.RotateLeft64(t, 6) + t = a[13] ^ d3 + bc2 = bits.RotateLeft64(t, 25) + t = a[14] ^ d4 + bc3 = bits.RotateLeft64(t, 8) + a[10] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc1 = bits.RotateLeft64(t, 36) + t = a[16] ^ d1 + bc2 = bits.RotateLeft64(t, 10) + t = a[17] ^ d2 + bc3 = bits.RotateLeft64(t, 15) + t = a[18] ^ d3 + bc4 = bits.RotateLeft64(t, 56) + t = a[19] ^ d4 + bc0 = bits.RotateLeft64(t, 27) + a[15] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc3 = bits.RotateLeft64(t, 41) + t = a[21] ^ d1 + bc4 = bits.RotateLeft64(t, 2) + t = a[22] ^ d2 + bc0 = bits.RotateLeft64(t, 62) + t = a[23] ^ d3 + bc1 = bits.RotateLeft64(t, 55) + t = a[24] ^ d4 + bc2 = bits.RotateLeft64(t, 39) + a[20] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + } +} diff --git a/src/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go b/src/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go new file mode 100644 index 00000000000..b908696be58 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go @@ -0,0 +1,13 @@ +// Copyright 2015 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. + +//go:build amd64 && !purego && gc + +package sha3 + +// This function is implemented in keccakf_amd64.s. + +//go:noescape + +func keccakF1600(a *[25]uint64) diff --git a/src/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s b/src/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s new file mode 100644 index 00000000000..1f539388619 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s @@ -0,0 +1,390 @@ +// Copyright 2015 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. + +//go:build amd64 && !purego && gc + +// This code was translated into a form compatible with 6a from the public +// domain sources at https://github.com/gvanas/KeccakCodePackage + +// Offsets in state +#define _ba (0*8) +#define _be (1*8) +#define _bi (2*8) +#define _bo (3*8) +#define _bu (4*8) +#define _ga (5*8) +#define _ge (6*8) +#define _gi (7*8) +#define _go (8*8) +#define _gu (9*8) +#define _ka (10*8) +#define _ke (11*8) +#define _ki (12*8) +#define _ko (13*8) +#define _ku (14*8) +#define _ma (15*8) +#define _me (16*8) +#define _mi (17*8) +#define _mo (18*8) +#define _mu (19*8) +#define _sa (20*8) +#define _se (21*8) +#define _si (22*8) +#define _so (23*8) +#define _su (24*8) + +// Temporary registers +#define rT1 AX + +// Round vars +#define rpState DI +#define rpStack SP + +#define rDa BX +#define rDe CX +#define rDi DX +#define rDo R8 +#define rDu R9 + +#define rBa R10 +#define rBe R11 +#define rBi R12 +#define rBo R13 +#define rBu R14 + +#define rCa SI +#define rCe BP +#define rCi rBi +#define rCo rBo +#define rCu R15 + +#define MOVQ_RBI_RCE MOVQ rBi, rCe +#define XORQ_RT1_RCA XORQ rT1, rCa +#define XORQ_RT1_RCE XORQ rT1, rCe +#define XORQ_RBA_RCU XORQ rBa, rCu +#define XORQ_RBE_RCU XORQ rBe, rCu +#define XORQ_RDU_RCU XORQ rDu, rCu +#define XORQ_RDA_RCA XORQ rDa, rCa +#define XORQ_RDE_RCE XORQ rDe, rCe + +#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \ + /* Prepare round */ \ + MOVQ rCe, rDa; \ + ROLQ $1, rDa; \ + \ + MOVQ _bi(iState), rCi; \ + XORQ _gi(iState), rDi; \ + XORQ rCu, rDa; \ + XORQ _ki(iState), rCi; \ + XORQ _mi(iState), rDi; \ + XORQ rDi, rCi; \ + \ + MOVQ rCi, rDe; \ + ROLQ $1, rDe; \ + \ + MOVQ _bo(iState), rCo; \ + XORQ _go(iState), rDo; \ + XORQ rCa, rDe; \ + XORQ _ko(iState), rCo; \ + XORQ _mo(iState), rDo; \ + XORQ rDo, rCo; \ + \ + MOVQ rCo, rDi; \ + ROLQ $1, rDi; \ + \ + MOVQ rCu, rDo; \ + XORQ rCe, rDi; \ + ROLQ $1, rDo; \ + \ + MOVQ rCa, rDu; \ + XORQ rCi, rDo; \ + ROLQ $1, rDu; \ + \ + /* Result b */ \ + MOVQ _ba(iState), rBa; \ + MOVQ _ge(iState), rBe; \ + XORQ rCo, rDu; \ + MOVQ _ki(iState), rBi; \ + MOVQ _mo(iState), rBo; \ + MOVQ _su(iState), rBu; \ + XORQ rDe, rBe; \ + ROLQ $44, rBe; \ + XORQ rDi, rBi; \ + XORQ rDa, rBa; \ + ROLQ $43, rBi; \ + \ + MOVQ rBe, rCa; \ + MOVQ rc, rT1; \ + ORQ rBi, rCa; \ + XORQ rBa, rT1; \ + XORQ rT1, rCa; \ + MOVQ rCa, _ba(oState); \ + \ + XORQ rDu, rBu; \ + ROLQ $14, rBu; \ + MOVQ rBa, rCu; \ + ANDQ rBe, rCu; \ + XORQ rBu, rCu; \ + MOVQ rCu, _bu(oState); \ + \ + XORQ rDo, rBo; \ + ROLQ $21, rBo; \ + MOVQ rBo, rT1; \ + ANDQ rBu, rT1; \ + XORQ rBi, rT1; \ + MOVQ rT1, _bi(oState); \ + \ + NOTQ rBi; \ + ORQ rBa, rBu; \ + ORQ rBo, rBi; \ + XORQ rBo, rBu; \ + XORQ rBe, rBi; \ + MOVQ rBu, _bo(oState); \ + MOVQ rBi, _be(oState); \ + B_RBI_RCE; \ + \ + /* Result g */ \ + MOVQ _gu(iState), rBe; \ + XORQ rDu, rBe; \ + MOVQ _ka(iState), rBi; \ + ROLQ $20, rBe; \ + XORQ rDa, rBi; \ + ROLQ $3, rBi; \ + MOVQ _bo(iState), rBa; \ + MOVQ rBe, rT1; \ + ORQ rBi, rT1; \ + XORQ rDo, rBa; \ + MOVQ _me(iState), rBo; \ + MOVQ _si(iState), rBu; \ + ROLQ $28, rBa; \ + XORQ rBa, rT1; \ + MOVQ rT1, _ga(oState); \ + G_RT1_RCA; \ + \ + XORQ rDe, rBo; \ + ROLQ $45, rBo; \ + MOVQ rBi, rT1; \ + ANDQ rBo, rT1; \ + XORQ rBe, rT1; \ + MOVQ rT1, _ge(oState); \ + G_RT1_RCE; \ + \ + XORQ rDi, rBu; \ + ROLQ $61, rBu; \ + MOVQ rBu, rT1; \ + ORQ rBa, rT1; \ + XORQ rBo, rT1; \ + MOVQ rT1, _go(oState); \ + \ + ANDQ rBe, rBa; \ + XORQ rBu, rBa; \ + MOVQ rBa, _gu(oState); \ + NOTQ rBu; \ + G_RBA_RCU; \ + \ + ORQ rBu, rBo; \ + XORQ rBi, rBo; \ + MOVQ rBo, _gi(oState); \ + \ + /* Result k */ \ + MOVQ _be(iState), rBa; \ + MOVQ _gi(iState), rBe; \ + MOVQ _ko(iState), rBi; \ + MOVQ _mu(iState), rBo; \ + MOVQ _sa(iState), rBu; \ + XORQ rDi, rBe; \ + ROLQ $6, rBe; \ + XORQ rDo, rBi; \ + ROLQ $25, rBi; \ + MOVQ rBe, rT1; \ + ORQ rBi, rT1; \ + XORQ rDe, rBa; \ + ROLQ $1, rBa; \ + XORQ rBa, rT1; \ + MOVQ rT1, _ka(oState); \ + K_RT1_RCA; \ + \ + XORQ rDu, rBo; \ + ROLQ $8, rBo; \ + MOVQ rBi, rT1; \ + ANDQ rBo, rT1; \ + XORQ rBe, rT1; \ + MOVQ rT1, _ke(oState); \ + K_RT1_RCE; \ + \ + XORQ rDa, rBu; \ + ROLQ $18, rBu; \ + NOTQ rBo; \ + MOVQ rBo, rT1; \ + ANDQ rBu, rT1; \ + XORQ rBi, rT1; \ + MOVQ rT1, _ki(oState); \ + \ + MOVQ rBu, rT1; \ + ORQ rBa, rT1; \ + XORQ rBo, rT1; \ + MOVQ rT1, _ko(oState); \ + \ + ANDQ rBe, rBa; \ + XORQ rBu, rBa; \ + MOVQ rBa, _ku(oState); \ + K_RBA_RCU; \ + \ + /* Result m */ \ + MOVQ _ga(iState), rBe; \ + XORQ rDa, rBe; \ + MOVQ _ke(iState), rBi; \ + ROLQ $36, rBe; \ + XORQ rDe, rBi; \ + MOVQ _bu(iState), rBa; \ + ROLQ $10, rBi; \ + MOVQ rBe, rT1; \ + MOVQ _mi(iState), rBo; \ + ANDQ rBi, rT1; \ + XORQ rDu, rBa; \ + MOVQ _so(iState), rBu; \ + ROLQ $27, rBa; \ + XORQ rBa, rT1; \ + MOVQ rT1, _ma(oState); \ + M_RT1_RCA; \ + \ + XORQ rDi, rBo; \ + ROLQ $15, rBo; \ + MOVQ rBi, rT1; \ + ORQ rBo, rT1; \ + XORQ rBe, rT1; \ + MOVQ rT1, _me(oState); \ + M_RT1_RCE; \ + \ + XORQ rDo, rBu; \ + ROLQ $56, rBu; \ + NOTQ rBo; \ + MOVQ rBo, rT1; \ + ORQ rBu, rT1; \ + XORQ rBi, rT1; \ + MOVQ rT1, _mi(oState); \ + \ + ORQ rBa, rBe; \ + XORQ rBu, rBe; \ + MOVQ rBe, _mu(oState); \ + \ + ANDQ rBa, rBu; \ + XORQ rBo, rBu; \ + MOVQ rBu, _mo(oState); \ + M_RBE_RCU; \ + \ + /* Result s */ \ + MOVQ _bi(iState), rBa; \ + MOVQ _go(iState), rBe; \ + MOVQ _ku(iState), rBi; \ + XORQ rDi, rBa; \ + MOVQ _ma(iState), rBo; \ + ROLQ $62, rBa; \ + XORQ rDo, rBe; \ + MOVQ _se(iState), rBu; \ + ROLQ $55, rBe; \ + \ + XORQ rDu, rBi; \ + MOVQ rBa, rDu; \ + XORQ rDe, rBu; \ + ROLQ $2, rBu; \ + ANDQ rBe, rDu; \ + XORQ rBu, rDu; \ + MOVQ rDu, _su(oState); \ + \ + ROLQ $39, rBi; \ + S_RDU_RCU; \ + NOTQ rBe; \ + XORQ rDa, rBo; \ + MOVQ rBe, rDa; \ + ANDQ rBi, rDa; \ + XORQ rBa, rDa; \ + MOVQ rDa, _sa(oState); \ + S_RDA_RCA; \ + \ + ROLQ $41, rBo; \ + MOVQ rBi, rDe; \ + ORQ rBo, rDe; \ + XORQ rBe, rDe; \ + MOVQ rDe, _se(oState); \ + S_RDE_RCE; \ + \ + MOVQ rBo, rDi; \ + MOVQ rBu, rDo; \ + ANDQ rBu, rDi; \ + ORQ rBa, rDo; \ + XORQ rBi, rDi; \ + XORQ rBo, rDo; \ + MOVQ rDi, _si(oState); \ + MOVQ rDo, _so(oState) \ + +// func keccakF1600(a *[25]uint64) +TEXT ·keccakF1600(SB), 0, $200-8 + MOVQ a+0(FP), rpState + + // Convert the user state into an internal state + NOTQ _be(rpState) + NOTQ _bi(rpState) + NOTQ _go(rpState) + NOTQ _ki(rpState) + NOTQ _mi(rpState) + NOTQ _sa(rpState) + + // Execute the KeccakF permutation + MOVQ _ba(rpState), rCa + MOVQ _be(rpState), rCe + MOVQ _bu(rpState), rCu + + XORQ _ga(rpState), rCa + XORQ _ge(rpState), rCe + XORQ _gu(rpState), rCu + + XORQ _ka(rpState), rCa + XORQ _ke(rpState), rCe + XORQ _ku(rpState), rCu + + XORQ _ma(rpState), rCa + XORQ _me(rpState), rCe + XORQ _mu(rpState), rCu + + XORQ _sa(rpState), rCa + XORQ _se(rpState), rCe + MOVQ _si(rpState), rDi + MOVQ _so(rpState), rDo + XORQ _su(rpState), rCu + + mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) + mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP) + + // Revert the internal state to the user state + NOTQ _be(rpState) + NOTQ _bi(rpState) + NOTQ _go(rpState) + NOTQ _ki(rpState) + NOTQ _mi(rpState) + NOTQ _sa(rpState) + + RET diff --git a/src/vendor/golang.org/x/crypto/sha3/register.go b/src/vendor/golang.org/x/crypto/sha3/register.go new file mode 100644 index 00000000000..addfd5049bb --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/register.go @@ -0,0 +1,18 @@ +// Copyright 2014 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. + +//go:build go1.4 + +package sha3 + +import ( + "crypto" +) + +func init() { + crypto.RegisterHash(crypto.SHA3_224, New224) + crypto.RegisterHash(crypto.SHA3_256, New256) + crypto.RegisterHash(crypto.SHA3_384, New384) + crypto.RegisterHash(crypto.SHA3_512, New512) +} diff --git a/src/vendor/golang.org/x/crypto/sha3/sha3.go b/src/vendor/golang.org/x/crypto/sha3/sha3.go new file mode 100644 index 00000000000..4884d172a49 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/sha3.go @@ -0,0 +1,197 @@ +// Copyright 2014 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 sha3 + +// spongeDirection indicates the direction bytes are flowing through the sponge. +type spongeDirection int + +const ( + // spongeAbsorbing indicates that the sponge is absorbing input. + spongeAbsorbing spongeDirection = iota + // spongeSqueezing indicates that the sponge is being squeezed. + spongeSqueezing +) + +const ( + // maxRate is the maximum size of the internal buffer. SHAKE-256 + // currently needs the largest buffer. + maxRate = 168 +) + +type state struct { + // Generic sponge components. + a [25]uint64 // main state of the hash + buf []byte // points into storage + rate int // the number of bytes of state to use + + // dsbyte contains the "domain separation" bits and the first bit of + // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the + // SHA-3 and SHAKE functions by appending bitstrings to the message. + // Using a little-endian bit-ordering convention, these are "01" for SHA-3 + // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the + // padding rule from section 5.1 is applied to pad the message to a multiple + // of the rate, which involves adding a "1" bit, zero or more "0" bits, and + // a final "1" bit. We merge the first "1" bit from the padding into dsbyte, + // giving 00000110b (0x06) and 00011111b (0x1f). + // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf + // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and + // Extendable-Output Functions (May 2014)" + dsbyte byte + + storage storageBuf + + // Specific to SHA-3 and SHAKE. + outputLen int // the default output size in bytes + state spongeDirection // whether the sponge is absorbing or squeezing +} + +// BlockSize returns the rate of sponge underlying this hash function. +func (d *state) BlockSize() int { return d.rate } + +// Size returns the output size of the hash function in bytes. +func (d *state) Size() int { return d.outputLen } + +// Reset clears the internal state by zeroing the sponge state and +// the byte buffer, and setting Sponge.state to absorbing. +func (d *state) Reset() { + // Zero the permutation's state. + for i := range d.a { + d.a[i] = 0 + } + d.state = spongeAbsorbing + d.buf = d.storage.asBytes()[:0] +} + +func (d *state) clone() *state { + ret := *d + if ret.state == spongeAbsorbing { + ret.buf = ret.storage.asBytes()[:len(ret.buf)] + } else { + ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate] + } + + return &ret +} + +// permute applies the KeccakF-1600 permutation. It handles +// any input-output buffering. +func (d *state) permute() { + switch d.state { + case spongeAbsorbing: + // If we're absorbing, we need to xor the input into the state + // before applying the permutation. + xorIn(d, d.buf) + d.buf = d.storage.asBytes()[:0] + keccakF1600(&d.a) + case spongeSqueezing: + // If we're squeezing, we need to apply the permutation before + // copying more output. + keccakF1600(&d.a) + d.buf = d.storage.asBytes()[:d.rate] + copyOut(d, d.buf) + } +} + +// pads appends the domain separation bits in dsbyte, applies +// the multi-bitrate 10..1 padding rule, and permutes the state. +func (d *state) padAndPermute(dsbyte byte) { + if d.buf == nil { + d.buf = d.storage.asBytes()[:0] + } + // Pad with this instance's domain-separator bits. We know that there's + // at least one byte of space in d.buf because, if it were full, + // permute would have been called to empty it. dsbyte also contains the + // first one bit for the padding. See the comment in the state struct. + d.buf = append(d.buf, dsbyte) + zerosStart := len(d.buf) + d.buf = d.storage.asBytes()[:d.rate] + for i := zerosStart; i < d.rate; i++ { + d.buf[i] = 0 + } + // This adds the final one bit for the padding. Because of the way that + // bits are numbered from the LSB upwards, the final bit is the MSB of + // the last byte. + d.buf[d.rate-1] ^= 0x80 + // Apply the permutation + d.permute() + d.state = spongeSqueezing + d.buf = d.storage.asBytes()[:d.rate] + copyOut(d, d.buf) +} + +// Write absorbs more data into the hash's state. It panics if any +// output has already been read. +func (d *state) Write(p []byte) (written int, err error) { + if d.state != spongeAbsorbing { + panic("sha3: Write after Read") + } + if d.buf == nil { + d.buf = d.storage.asBytes()[:0] + } + written = len(p) + + for len(p) > 0 { + if len(d.buf) == 0 && len(p) >= d.rate { + // The fast path; absorb a full "rate" bytes of input and apply the permutation. + xorIn(d, p[:d.rate]) + p = p[d.rate:] + keccakF1600(&d.a) + } else { + // The slow path; buffer the input until we can fill the sponge, and then xor it in. + todo := d.rate - len(d.buf) + if todo > len(p) { + todo = len(p) + } + d.buf = append(d.buf, p[:todo]...) + p = p[todo:] + + // If the sponge is full, apply the permutation. + if len(d.buf) == d.rate { + d.permute() + } + } + } + + return +} + +// Read squeezes an arbitrary number of bytes from the sponge. +func (d *state) Read(out []byte) (n int, err error) { + // If we're still absorbing, pad and apply the permutation. + if d.state == spongeAbsorbing { + d.padAndPermute(d.dsbyte) + } + + n = len(out) + + // Now, do the squeezing. + for len(out) > 0 { + n := copy(out, d.buf) + d.buf = d.buf[n:] + out = out[n:] + + // Apply the permutation if we've squeezed the sponge dry. + if len(d.buf) == 0 { + d.permute() + } + } + + return +} + +// Sum applies padding to the hash state and then squeezes out the desired +// number of output bytes. It panics if any output has already been read. +func (d *state) Sum(in []byte) []byte { + if d.state != spongeAbsorbing { + panic("sha3: Sum after Read") + } + + // Make a copy of the original hash so that caller can keep writing + // and summing. + dup := d.clone() + hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation + dup.Read(hash) + return append(in, hash...) +} diff --git a/src/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/src/vendor/golang.org/x/crypto/sha3/sha3_s390x.go new file mode 100644 index 00000000000..d861bca5286 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/sha3_s390x.go @@ -0,0 +1,288 @@ +// 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. + +//go:build gc && !purego + +package sha3 + +// This file contains code for using the 'compute intermediate +// message digest' (KIMD) and 'compute last message digest' (KLMD) +// instructions to compute SHA-3 and SHAKE hashes on IBM Z. + +import ( + "hash" + + "golang.org/x/sys/cpu" +) + +// codes represent 7-bit KIMD/KLMD function codes as defined in +// the Principles of Operation. +type code uint64 + +const ( + // function codes for KIMD/KLMD + sha3_224 code = 32 + sha3_256 = 33 + sha3_384 = 34 + sha3_512 = 35 + shake_128 = 36 + shake_256 = 37 + nopad = 0x100 +) + +// kimd is a wrapper for the 'compute intermediate message digest' instruction. +// src must be a multiple of the rate for the given function code. +// +//go:noescape +func kimd(function code, chain *[200]byte, src []byte) + +// klmd is a wrapper for the 'compute last message digest' instruction. +// src padding is handled by the instruction. +// +//go:noescape +func klmd(function code, chain *[200]byte, dst, src []byte) + +type asmState struct { + a [200]byte // 1600 bit state + buf []byte // care must be taken to ensure cap(buf) is a multiple of rate + rate int // equivalent to block size + storage [3072]byte // underlying storage for buf + outputLen int // output length for full security + function code // KIMD/KLMD function code + state spongeDirection // whether the sponge is absorbing or squeezing +} + +func newAsmState(function code) *asmState { + var s asmState + s.function = function + switch function { + case sha3_224: + s.rate = 144 + s.outputLen = 28 + case sha3_256: + s.rate = 136 + s.outputLen = 32 + case sha3_384: + s.rate = 104 + s.outputLen = 48 + case sha3_512: + s.rate = 72 + s.outputLen = 64 + case shake_128: + s.rate = 168 + s.outputLen = 32 + case shake_256: + s.rate = 136 + s.outputLen = 64 + default: + panic("sha3: unrecognized function code") + } + + // limit s.buf size to a multiple of s.rate + s.resetBuf() + return &s +} + +func (s *asmState) clone() *asmState { + c := *s + c.buf = c.storage[:len(s.buf):cap(s.buf)] + return &c +} + +// copyIntoBuf copies b into buf. It will panic if there is not enough space to +// store all of b. +func (s *asmState) copyIntoBuf(b []byte) { + bufLen := len(s.buf) + s.buf = s.buf[:len(s.buf)+len(b)] + copy(s.buf[bufLen:], b) +} + +// resetBuf points buf at storage, sets the length to 0 and sets cap to be a +// multiple of the rate. +func (s *asmState) resetBuf() { + max := (cap(s.storage) / s.rate) * s.rate + s.buf = s.storage[:0:max] +} + +// Write (via the embedded io.Writer interface) adds more data to the running hash. +// It never returns an error. +func (s *asmState) Write(b []byte) (int, error) { + if s.state != spongeAbsorbing { + panic("sha3: Write after Read") + } + length := len(b) + for len(b) > 0 { + if len(s.buf) == 0 && len(b) >= cap(s.buf) { + // Hash the data directly and push any remaining bytes + // into the buffer. + remainder := len(b) % s.rate + kimd(s.function, &s.a, b[:len(b)-remainder]) + if remainder != 0 { + s.copyIntoBuf(b[len(b)-remainder:]) + } + return length, nil + } + + if len(s.buf) == cap(s.buf) { + // flush the buffer + kimd(s.function, &s.a, s.buf) + s.buf = s.buf[:0] + } + + // copy as much as we can into the buffer + n := len(b) + if len(b) > cap(s.buf)-len(s.buf) { + n = cap(s.buf) - len(s.buf) + } + s.copyIntoBuf(b[:n]) + b = b[n:] + } + return length, nil +} + +// Read squeezes an arbitrary number of bytes from the sponge. +func (s *asmState) Read(out []byte) (n int, err error) { + n = len(out) + + // need to pad if we were absorbing + if s.state == spongeAbsorbing { + s.state = spongeSqueezing + + // write hash directly into out if possible + if len(out)%s.rate == 0 { + klmd(s.function, &s.a, out, s.buf) // len(out) may be 0 + s.buf = s.buf[:0] + return + } + + // write hash into buffer + max := cap(s.buf) + if max > len(out) { + max = (len(out)/s.rate)*s.rate + s.rate + } + klmd(s.function, &s.a, s.buf[:max], s.buf) + s.buf = s.buf[:max] + } + + for len(out) > 0 { + // flush the buffer + if len(s.buf) != 0 { + c := copy(out, s.buf) + out = out[c:] + s.buf = s.buf[c:] + continue + } + + // write hash directly into out if possible + if len(out)%s.rate == 0 { + klmd(s.function|nopad, &s.a, out, nil) + return + } + + // write hash into buffer + s.resetBuf() + if cap(s.buf) > len(out) { + s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate] + } + klmd(s.function|nopad, &s.a, s.buf, nil) + } + return +} + +// Sum appends the current hash to b and returns the resulting slice. +// It does not change the underlying hash state. +func (s *asmState) Sum(b []byte) []byte { + if s.state != spongeAbsorbing { + panic("sha3: Sum after Read") + } + + // Copy the state to preserve the original. + a := s.a + + // Hash the buffer. Note that we don't clear it because we + // aren't updating the state. + klmd(s.function, &a, nil, s.buf) + return append(b, a[:s.outputLen]...) +} + +// Reset resets the Hash to its initial state. +func (s *asmState) Reset() { + for i := range s.a { + s.a[i] = 0 + } + s.resetBuf() + s.state = spongeAbsorbing +} + +// Size returns the number of bytes Sum will return. +func (s *asmState) Size() int { + return s.outputLen +} + +// 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. +func (s *asmState) BlockSize() int { + return s.rate +} + +// Clone returns a copy of the ShakeHash in its current state. +func (s *asmState) Clone() ShakeHash { + return s.clone() +} + +// new224Asm returns an assembly implementation of SHA3-224 if available, +// otherwise it returns nil. +func new224Asm() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_224) + } + return nil +} + +// new256Asm returns an assembly implementation of SHA3-256 if available, +// otherwise it returns nil. +func new256Asm() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_256) + } + return nil +} + +// new384Asm returns an assembly implementation of SHA3-384 if available, +// otherwise it returns nil. +func new384Asm() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_384) + } + return nil +} + +// new512Asm returns an assembly implementation of SHA3-512 if available, +// otherwise it returns nil. +func new512Asm() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_512) + } + return nil +} + +// newShake128Asm returns an assembly implementation of SHAKE-128 if available, +// otherwise it returns nil. +func newShake128Asm() ShakeHash { + if cpu.S390X.HasSHA3 { + return newAsmState(shake_128) + } + return nil +} + +// newShake256Asm returns an assembly implementation of SHAKE-256 if available, +// otherwise it returns nil. +func newShake256Asm() ShakeHash { + if cpu.S390X.HasSHA3 { + return newAsmState(shake_256) + } + return nil +} diff --git a/src/vendor/golang.org/x/crypto/sha3/sha3_s390x.s b/src/vendor/golang.org/x/crypto/sha3/sha3_s390x.s new file mode 100644 index 00000000000..826b862c779 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/sha3_s390x.s @@ -0,0 +1,33 @@ +// 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. + +//go:build gc && !purego + +#include "textflag.h" + +// func kimd(function code, chain *[200]byte, src []byte) +TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40 + MOVD function+0(FP), R0 + MOVD chain+8(FP), R1 + LMG src+16(FP), R2, R3 // R2=base, R3=len + +continue: + WORD $0xB93E0002 // KIMD --, R2 + BVS continue // continue if interrupted + MOVD $0, R0 // reset R0 for pre-go1.8 compilers + RET + +// func klmd(function code, chain *[200]byte, dst, src []byte) +TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64 + // TODO: SHAKE support + MOVD function+0(FP), R0 + MOVD chain+8(FP), R1 + LMG dst+16(FP), R2, R3 // R2=base, R3=len + LMG src+40(FP), R4, R5 // R4=base, R5=len + +continue: + WORD $0xB93F0024 // KLMD R2, R4 + BVS continue // continue if interrupted + MOVD $0, R0 // reset R0 for pre-go1.8 compilers + RET diff --git a/src/vendor/golang.org/x/crypto/sha3/shake.go b/src/vendor/golang.org/x/crypto/sha3/shake.go new file mode 100644 index 00000000000..bb69984027f --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/shake.go @@ -0,0 +1,172 @@ +// Copyright 2014 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 sha3 + +// This file defines the ShakeHash interface, and provides +// functions for creating SHAKE and cSHAKE instances, as well as utility +// functions for hashing bytes to arbitrary-length output. +// +// +// SHAKE implementation is based on FIPS PUB 202 [1] +// cSHAKE implementations is based on NIST SP 800-185 [2] +// +// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf +// [2] https://doi.org/10.6028/NIST.SP.800-185 + +import ( + "encoding/binary" + "hash" + "io" +) + +// ShakeHash defines the interface to hash functions that support +// arbitrary-length output. When used as a plain [hash.Hash], it +// produces minimum-length outputs that provide full-strength generic +// security. +type ShakeHash interface { + hash.Hash + + // Read reads more output from the hash; reading affects the hash's + // state. (ShakeHash.Read is thus very different from Hash.Sum) + // It never returns an error, but subsequent calls to Write or Sum + // will panic. + io.Reader + + // Clone returns a copy of the ShakeHash in its current state. + Clone() ShakeHash +} + +// cSHAKE specific context +type cshakeState struct { + *state // SHA-3 state context and Read/Write operations + + // initBlock is the cSHAKE specific initialization set of bytes. It is initialized + // by newCShake function and stores concatenation of N followed by S, encoded + // by the method specified in 3.3 of [1]. + // It is stored here in order for Reset() to be able to put context into + // initial state. + initBlock []byte +} + +// Consts for configuring initial SHA-3 state +const ( + dsbyteShake = 0x1f + dsbyteCShake = 0x04 + rate128 = 168 + rate256 = 136 +) + +func bytepad(input []byte, w int) []byte { + // leftEncode always returns max 9 bytes + buf := make([]byte, 0, 9+len(input)+w) + buf = append(buf, leftEncode(uint64(w))...) + buf = append(buf, input...) + padlen := w - (len(buf) % w) + return append(buf, make([]byte, padlen)...) +} + +func leftEncode(value uint64) []byte { + var b [9]byte + binary.BigEndian.PutUint64(b[1:], value) + // Trim all but last leading zero bytes + i := byte(1) + for i < 8 && b[i] == 0 { + i++ + } + // Prepend number of encoded bytes + b[i-1] = 9 - i + return b[i-1:] +} + +func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash { + c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}} + + // leftEncode returns max 9 bytes + c.initBlock = make([]byte, 0, 9*2+len(N)+len(S)) + c.initBlock = append(c.initBlock, leftEncode(uint64(len(N)*8))...) + c.initBlock = append(c.initBlock, N...) + c.initBlock = append(c.initBlock, leftEncode(uint64(len(S)*8))...) + c.initBlock = append(c.initBlock, S...) + c.Write(bytepad(c.initBlock, c.rate)) + return &c +} + +// Reset resets the hash to initial state. +func (c *cshakeState) Reset() { + c.state.Reset() + c.Write(bytepad(c.initBlock, c.rate)) +} + +// Clone returns copy of a cSHAKE context within its current state. +func (c *cshakeState) Clone() ShakeHash { + b := make([]byte, len(c.initBlock)) + copy(b, c.initBlock) + return &cshakeState{state: c.clone(), initBlock: b} +} + +// Clone returns copy of SHAKE context within its current state. +func (c *state) Clone() ShakeHash { + return c.clone() +} + +// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash. +// Its generic security strength is 128 bits against all attacks if at +// least 32 bytes of its output are used. +func NewShake128() ShakeHash { + if h := newShake128Asm(); h != nil { + return h + } + return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake} +} + +// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash. +// Its generic security strength is 256 bits against all attacks if +// at least 64 bytes of its output are used. +func NewShake256() ShakeHash { + if h := newShake256Asm(); h != nil { + return h + } + return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake} +} + +// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash, +// a customizable variant of SHAKE128. +// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is +// desired. S is a customization byte string used for domain separation - two cSHAKE +// computations on same input with different S yield unrelated outputs. +// When N and S are both empty, this is equivalent to NewShake128. +func NewCShake128(N, S []byte) ShakeHash { + if len(N) == 0 && len(S) == 0 { + return NewShake128() + } + return newCShake(N, S, rate128, 32, dsbyteCShake) +} + +// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash, +// a customizable variant of SHAKE256. +// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is +// desired. S is a customization byte string used for domain separation - two cSHAKE +// computations on same input with different S yield unrelated outputs. +// When N and S are both empty, this is equivalent to NewShake256. +func NewCShake256(N, S []byte) ShakeHash { + if len(N) == 0 && len(S) == 0 { + return NewShake256() + } + return newCShake(N, S, rate256, 64, dsbyteCShake) +} + +// ShakeSum128 writes an arbitrary-length digest of data into hash. +func ShakeSum128(hash, data []byte) { + h := NewShake128() + h.Write(data) + h.Read(hash) +} + +// ShakeSum256 writes an arbitrary-length digest of data into hash. +func ShakeSum256(hash, data []byte) { + h := NewShake256() + h.Write(data) + h.Read(hash) +} diff --git a/src/vendor/golang.org/x/crypto/sha3/shake_generic.go b/src/vendor/golang.org/x/crypto/sha3/shake_generic.go new file mode 100644 index 00000000000..8d31cf5be2d --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/shake_generic.go @@ -0,0 +1,19 @@ +// 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. + +//go:build !gc || purego || !s390x + +package sha3 + +// newShake128Asm returns an assembly implementation of SHAKE-128 if available, +// otherwise it returns nil. +func newShake128Asm() ShakeHash { + return nil +} + +// newShake256Asm returns an assembly implementation of SHAKE-256 if available, +// otherwise it returns nil. +func newShake256Asm() ShakeHash { + return nil +} diff --git a/src/vendor/golang.org/x/crypto/sha3/xor.go b/src/vendor/golang.org/x/crypto/sha3/xor.go new file mode 100644 index 00000000000..7337cca88ed --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/xor.go @@ -0,0 +1,23 @@ +// Copyright 2015 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. + +//go:build (!amd64 && !386 && !ppc64le) || purego + +package sha3 + +// A storageBuf is an aligned array of maxRate bytes. +type storageBuf [maxRate]byte + +func (b *storageBuf) asBytes() *[maxRate]byte { + return (*[maxRate]byte)(b) +} + +var ( + xorIn = xorInGeneric + copyOut = copyOutGeneric + xorInUnaligned = xorInGeneric + copyOutUnaligned = copyOutGeneric +) + +const xorImplementationUnaligned = "generic" diff --git a/src/vendor/golang.org/x/crypto/sha3/xor_generic.go b/src/vendor/golang.org/x/crypto/sha3/xor_generic.go new file mode 100644 index 00000000000..8d947711272 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/xor_generic.go @@ -0,0 +1,28 @@ +// Copyright 2015 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 sha3 + +import "encoding/binary" + +// xorInGeneric xors the bytes in buf into the state; it +// makes no non-portable assumptions about memory layout +// or alignment. +func xorInGeneric(d *state, buf []byte) { + n := len(buf) / 8 + + for i := 0; i < n; i++ { + a := binary.LittleEndian.Uint64(buf) + d.a[i] ^= a + buf = buf[8:] + } +} + +// copyOutGeneric copies uint64s to a byte buffer. +func copyOutGeneric(d *state, b []byte) { + for i := 0; len(b) >= 8; i++ { + binary.LittleEndian.PutUint64(b, d.a[i]) + b = b[8:] + } +} diff --git a/src/vendor/golang.org/x/crypto/sha3/xor_unaligned.go b/src/vendor/golang.org/x/crypto/sha3/xor_unaligned.go new file mode 100644 index 00000000000..870e2d16e07 --- /dev/null +++ b/src/vendor/golang.org/x/crypto/sha3/xor_unaligned.go @@ -0,0 +1,66 @@ +// Copyright 2015 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. + +//go:build (amd64 || 386 || ppc64le) && !purego + +package sha3 + +import "unsafe" + +// A storageBuf is an aligned array of maxRate bytes. +type storageBuf [maxRate / 8]uint64 + +func (b *storageBuf) asBytes() *[maxRate]byte { + return (*[maxRate]byte)(unsafe.Pointer(b)) +} + +// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a +// XOR buf. +func xorInUnaligned(d *state, buf []byte) { + n := len(buf) + bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8] + if n >= 72 { + d.a[0] ^= bw[0] + d.a[1] ^= bw[1] + d.a[2] ^= bw[2] + d.a[3] ^= bw[3] + d.a[4] ^= bw[4] + d.a[5] ^= bw[5] + d.a[6] ^= bw[6] + d.a[7] ^= bw[7] + d.a[8] ^= bw[8] + } + if n >= 104 { + d.a[9] ^= bw[9] + d.a[10] ^= bw[10] + d.a[11] ^= bw[11] + d.a[12] ^= bw[12] + } + if n >= 136 { + d.a[13] ^= bw[13] + d.a[14] ^= bw[14] + d.a[15] ^= bw[15] + d.a[16] ^= bw[16] + } + if n >= 144 { + d.a[17] ^= bw[17] + } + if n >= 168 { + d.a[18] ^= bw[18] + d.a[19] ^= bw[19] + d.a[20] ^= bw[20] + } +} + +func copyOutUnaligned(d *state, buf []byte) { + ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0])) + copy(buf, ab[:]) +} + +var ( + xorIn = xorInUnaligned + copyOut = copyOutUnaligned +) + +const xorImplementationUnaligned = "unaligned" diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt index dd4540d7e4e..b52c02e61c0 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,5 +1,5 @@ -# github.com/cloudflare/circl v1.3.8-0.20240208083452-454cfdc0f6c7 -## explicit; go 1.19 +# github.com/cloudflare/circl v1.4.1-0.20240905130006-2d6cd9871f69 +## explicit; go 1.21 github.com/cloudflare/circl/dh/x25519 github.com/cloudflare/circl/dh/x448 github.com/cloudflare/circl/ecc/goldilocks @@ -12,6 +12,7 @@ github.com/cloudflare/circl/kem/hybrid github.com/cloudflare/circl/kem/kyber/kyber1024 github.com/cloudflare/circl/kem/kyber/kyber512 github.com/cloudflare/circl/kem/kyber/kyber768 +github.com/cloudflare/circl/kem/mlkem/mlkem768 github.com/cloudflare/circl/math github.com/cloudflare/circl/math/fp25519 github.com/cloudflare/circl/math/fp448 @@ -51,6 +52,7 @@ golang.org/x/crypto/cryptobyte/asn1 golang.org/x/crypto/hkdf golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 +golang.org/x/crypto/sha3 # golang.org/x/net v0.19.1-0.20240412193750-db050b07227e ## explicit; go 1.18 golang.org/x/net/dns/dnsmessage