From 5616553ee04a7c2c21f54d7291a0134ef6b4a3ee Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 9 Aug 2023 08:04:38 +0200 Subject: [PATCH] Remove liboqs support Signed-off-by: Steffen Vogel --- .config-static/liboqs.pc | 12 ------ .github/workflows/test.yaml | 27 +------------ .golangci.yaml | 1 - README.md | 17 -------- crypto.go | 71 +++++++++++++++++++++++++++++++-- crypto_circl.go | 79 ------------------------------------- crypto_oqs.go | 58 --------------------------- go.mod | 1 - go.sum | 2 - handshake.go | 6 ++- oqs_test.go | 22 ----------- 11 files changed, 73 insertions(+), 223 deletions(-) delete mode 100644 .config-static/liboqs.pc delete mode 100644 crypto_circl.go delete mode 100644 crypto_oqs.go delete mode 100644 oqs_test.go diff --git a/.config-static/liboqs.pc b/.config-static/liboqs.pc deleted file mode 100644 index 7efd380..0000000 --- a/.config-static/liboqs.pc +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Steffen Vogel -# SPDX-License-Identifier: Apache-2.0 - -LIBOQS_INCLUDE_DIR=/usr/local/include -LIBOQS_LIB_DIR=/usr/local/lib - -Name: liboqs -Description: C library for quantum resistant cryptography -Version: 0.7.2 -Cflags: -I${LIBOQS_INCLUDE_DIR} -Ldflags: '-extldflags "-Wl,-stack_size -Wl,0x1000000"' -Libs: -L${LIBOQS_LIB_DIR} -Wl,-Bstatic -loqs -lcrypto -Wl,-Bdynamic \ No newline at end of file diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 0f507a9..ac189d7 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,15 +13,11 @@ on: jobs: test: - name: Test ${{ matrix.cgo && 'with' || 'without' }} Cgo + name: Test runs-on: ubuntu-latest - strategy: - matrix: - cgo: [true, false] - env: - CGO_ENABLED: ${{ matrix.cgo && '1' || '0' }} + CGO_ENABLED: '0' steps: - name: Checkout @@ -42,25 +38,6 @@ jobs: git: https://github.com/rosenpass/rosenpass commit: a2b177470c689c39ee9be01dced124f8d0053f9f - - name: Checkout liboqs - uses: actions/checkout@v3 - with: - repository: open-quantum-safe/liboqs - ref: 0.8.0 - path: liboqs - if: ${{ matrix.cgo }} - - - name: Install liboqs - run: | - mkdir -p liboqs/build && cd liboqs/build - cmake -GNinja \ - -DOQS_BUILD_ONLY_LIB=ON \ - -DOQS_MINIMAL_BUILD="KEM_kyber_512;KEM_classic_mceliece_460896" \ - -DBUILD_SHARED_LIBS=ON \ - -DCMAKE_INSTALL_PREFIX=/usr .. - sudo ninja install - if: ${{ matrix.cgo }} - - name: Set up Go uses: actions/setup-go@v4 with: diff --git a/.golangci.yaml b/.golangci.yaml index 89e014a..3bf52b5 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -24,7 +24,6 @@ linters-settings: allow: - $gostd - github.com/stv0g/go-rosenpass - - github.com/open-quantum-safe/liboqs-go/oqs - github.com/pelletier/go-toml/v2 - github.com/spf13/cobra - golang.org/x/crypto/blake2b diff --git a/README.md b/README.md index 486341f..9daa9e8 100644 --- a/README.md +++ b/README.md @@ -23,23 +23,6 @@ The implementation aims to be compatible with the reference implementation in Ru _go-rosenpass_ distributes builds via [GitHub Releases](https://github.com/stv0g/go-rosenpass/releases). You can download a pre-built binary from there. -### Building from source - -_go-rosenpass_ requires [liboqs](https://github.com/open-quantum-safe/liboqs) (**v0.8.0**) for Post-Quantum crypto primitives. -Please have a look the [liboqs-go](https://github.com/open-quantum-safe/liboqs-go) bindings for details build instructions. - -#### Linking statically against liboqs & libcrypto - -In addition to the instruction provided by liboqs-go, its also possible to link _go-rosenpass_ statically against liboqs using the following commands: - -```bash -git clone https://github.com/stv0g/go-rosenpass -cd go-rosenpass -PKG_CONFIG_PATH=.config-static go build -o go-rosenpass ./cmd/ -``` - -The resulting `go-rosenpass` binary can be redistributed without requiring `liboqs.so` or `libcrypto.so` as external dependencies. - ## References - diff --git a/crypto.go b/crypto.go index 7507124..2243fbf 100644 --- a/crypto.go +++ b/crypto.go @@ -8,14 +8,17 @@ import ( "crypto/rand" "fmt" + "github.com/cloudflare/circl/kem" + "github.com/cloudflare/circl/kem/kyber/kyber512" + "github.com/cloudflare/circl/kem/mceliece/mceliece460896" "golang.org/x/crypto/blake2b" "golang.org/x/crypto/chacha20poly1305" ) -type keyEncapsulation interface { - EncapSecret(pk []byte) (ct []byte, ss []byte, err error) - DecapSecret(ct []byte) (ss []byte, err error) -} +var ( + kemStatic kem.Scheme = mceliece460896.Scheme() + kemEphemeral kem.Scheme = kyber512.Scheme() +) // GenerateKeyPair generates a new Classic McEliece key pair. func GenerateKeyPair() (PublicKey, SecretKey, error) { //nolint:revive @@ -135,3 +138,63 @@ func generateKey(l int) ([]byte, error) { return p, nil } + +func generateStaticKeyPair() (spk, ssk, error) { + pk, sk, err := generateKeyPair(kemStatic) + if err != nil { + return nil, nil, err + } + + return spk(pk), ssk(sk), nil +} + +func generateEphemeralKeyPair() (epk, esk, error) { + pk, sk, err := generateKeyPair(kemEphemeral) + if err != nil { + return nil, nil, err + } + + return epk(pk), esk(sk), nil +} + +func generateKeyPair(typ kem.Scheme) ([]byte, []byte, error) { + pk, sk, err := typ.GenerateKeyPair() + if err != nil { + return nil, nil, err + } + + pk2, _ := pk.MarshalBinary() + sk2, _ := sk.MarshalBinary() + + return pk2, sk2, nil +} + +func newKEM(typ kem.Scheme, key []byte) (*keyEncapsulation, error) { + return &keyEncapsulation{ + key: key, + scheme: typ, + }, nil +} + +type keyEncapsulation struct { + scheme kem.Scheme + key []byte +} + +func (ke *keyEncapsulation) EncapSecret(pk []byte) (ct []byte, ss []byte, err error) { + cpk, err := ke.scheme.UnmarshalBinaryPublicKey(pk) + if err != nil { + return nil, nil, err + } + + return ke.scheme.Encapsulate(cpk) +} + +func (ke *keyEncapsulation) DecapSecret(ct []byte) (ss []byte, err error) { + csk, err := ke.scheme.UnmarshalBinaryPrivateKey(ke.key) + if err != nil { + return nil, err + } + + return ke.scheme.Decapsulate(csk, ct) +} diff --git a/crypto_circl.go b/crypto_circl.go deleted file mode 100644 index c02abaf..0000000 --- a/crypto_circl.go +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Steffen Vogel -// SPDX-License-Identifier: Apache-2.0 - -//go:build !cgo - -package rosenpass - -import ( - "github.com/cloudflare/circl/kem" - "github.com/cloudflare/circl/kem/kyber/kyber512" - "github.com/cloudflare/circl/kem/mceliece/mceliece460896" -) - -type kemType = kem.Scheme - -var ( - kemStatic kemType = mceliece460896.Scheme() - kemEphemeral kemType = kyber512.Scheme() -) - -func generateStaticKeyPair() (spk, ssk, error) { - pk, sk, err := generateKeyPair(kemStatic) - if err != nil { - return nil, nil, err - } - - return spk(pk), ssk(sk), nil -} - -func generateEphemeralKeyPair() (epk, esk, error) { - pk, sk, err := generateKeyPair(kemEphemeral) - if err != nil { - return nil, nil, err - } - - return epk(pk), esk(sk), nil -} - -func generateKeyPair(typ kem.Scheme) ([]byte, []byte, error) { - pk, sk, err := typ.GenerateKeyPair() - if err != nil { - return nil, nil, err - } - - pk2, _ := pk.MarshalBinary() - sk2, _ := sk.MarshalBinary() - - return pk2, sk2, nil -} - -func newKEM(typ kemType, key []byte) (keyEncapsulation, error) { - return &circlKeyEncapsulation{ - key: key, - scheme: typ, - }, nil -} - -type circlKeyEncapsulation struct { - scheme kem.Scheme - key []byte -} - -func (ke *circlKeyEncapsulation) EncapSecret(pk []byte) (ct []byte, ss []byte, err error) { - cpk, err := ke.scheme.UnmarshalBinaryPublicKey(pk) - if err != nil { - return nil, nil, err - } - - return ke.scheme.Encapsulate(cpk) -} - -func (ke *circlKeyEncapsulation) DecapSecret(ct []byte) (ss []byte, err error) { - csk, err := ke.scheme.UnmarshalBinaryPrivateKey(ke.key) - if err != nil { - return nil, err - } - - return ke.scheme.Decapsulate(csk, ct) -} diff --git a/crypto_oqs.go b/crypto_oqs.go deleted file mode 100644 index 940a44c..0000000 --- a/crypto_oqs.go +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Steffen Vogel -// SPDX-License-Identifier: Apache-2.0 - -//go:build cgo - -package rosenpass - -import ( - "github.com/open-quantum-safe/liboqs-go/oqs" -) - -type kemType = string - -const ( - kemStatic kemType = "Classic-McEliece-460896" - kemEphemeral kemType = "Kyber512" -) - -func generateStaticKeyPair() ([]byte, []byte, error) { - pk, sk, err := generateKeyPair(kemStatic) - if err != nil { - return nil, nil, err - } - - return spk(pk), ssk(sk), nil -} - -func generateEphemeralKeyPair() (epk, esk, error) { - pk, sk, err := generateKeyPair(kemEphemeral) - if err != nil { - return nil, nil, err - } - - return epk(pk), esk(sk), nil -} - -func generateKeyPair(alg kemType) ([]byte, []byte, error) { - kem := &oqs.KeyEncapsulation{} - if err := kem.Init(alg, nil); err != nil { - return nil, nil, err - } - - pk, err := kem.GenerateKeyPair() - if err != nil { - return nil, nil, err - } - - return pk, kem.ExportSecretKey(), nil -} - -func newKEM(typ kemType, key []byte) (keyEncapsulation, error) { - kem := &oqs.KeyEncapsulation{} - if err := kem.Init(string(typ), key); err != nil { - return nil, err - } - - return kem, nil -} diff --git a/go.mod b/go.mod index 8468159..ee7bca1 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.21 require ( github.com/cloudflare/circl v0.0.0-00010101000000-000000000000 - github.com/open-quantum-safe/liboqs-go v0.0.0-20230726174627-a49f79a6b626 github.com/pelletier/go-toml/v2 v2.0.9 github.com/spf13/cobra v1.7.0 golang.org/x/crypto v0.12.0 diff --git a/go.sum b/go.sum index bd85fe5..02ac48d 100644 --- a/go.sum +++ b/go.sum @@ -17,8 +17,6 @@ github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= -github.com/open-quantum-safe/liboqs-go v0.0.0-20230726174627-a49f79a6b626 h1:aDWl8Y1TZ7SVYBtZYZf+kYiCzztCMV7zdLwJ0xWV1BQ= -github.com/open-quantum-safe/liboqs-go v0.0.0-20230726174627-a49f79a6b626/go.mod h1:7o26+0OF/Oh1Vo1sWUN+2jZavRhXvuLldh++utxFvRI= github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/handshake.go b/handshake.go index e622cfe..3a56ebb 100644 --- a/handshake.go +++ b/handshake.go @@ -5,6 +5,8 @@ package rosenpass import ( "errors" + + "github.com/cloudflare/circl/kem" ) var ( @@ -87,7 +89,7 @@ func (hs *handshake) decryptAndMix(ct []byte) ([]byte, error) { return pt, nil } -func (hs *handshake) encapAndMix(typ kemType, pk []byte) ([]byte, error) { +func (hs *handshake) encapAndMix(typ kem.Scheme, pk []byte) ([]byte, error) { kem, err := newKEM(typ, pk) if err != nil { return nil, err @@ -103,7 +105,7 @@ func (hs *handshake) encapAndMix(typ kemType, pk []byte) ([]byte, error) { return ct, nil } -func (hs *handshake) decapAndMix(typ kemType, sk, pk, ct []byte) error { +func (hs *handshake) decapAndMix(typ kem.Scheme, sk, pk, ct []byte) error { kem, err := newKEM(typ, sk) if err != nil { return err diff --git a/oqs_test.go b/oqs_test.go deleted file mode 100644 index f99f0e5..0000000 --- a/oqs_test.go +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Steffen Vogel -// SPDX-License-Identifier: Apache-2.0 - -//go:build cgo - -package rosenpass - -import ( - "testing" - - "github.com/open-quantum-safe/liboqs-go/oqs" - "github.com/stretchr/testify/require" -) - -// TestLibOQS verifies that liboqs supports the required -// KEM algorithms for rosenpass. -func TestLibOQS(t *testing.T) { - require := require.New(t) - - require.True(oqs.IsKEMEnabled(kemEphemeral)) - require.True(oqs.IsKEMEnabled(kemStatic)) -}