From d837630ff6b7d1592d9e4095d6ae7877205be394 Mon Sep 17 00:00:00 2001 From: Keith Petkus Date: Fri, 7 May 2021 12:27:53 -0400 Subject: [PATCH] remove libsodium dependency in favor of the native go/crypto ed25519 library --- CONTRIBUTING.md | 1 - lib/common/fuzz/Dockerfile | 3 +- lib/crypto/ed25519.go | 79 ++++++++++++-------------------------- lib/crypto/ed25519_test.go | 33 ++++++++++++++++ 4 files changed, 59 insertions(+), 57 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 23b96b6..6dec5c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,6 @@ Install required dependencies This example assumes Ubuntu 16.04 ```sh -sudo apt-get install pkg-config libsodium-dev go get github.com/hkparker/go-i2p go get github.com/Sirupsen/logrus go get github.com/stretchr/testify/assert diff --git a/lib/common/fuzz/Dockerfile b/lib/common/fuzz/Dockerfile index 12bc288..284cedc 100644 --- a/lib/common/fuzz/Dockerfile +++ b/lib/common/fuzz/Dockerfile @@ -1,8 +1,7 @@ FROM golang RUN apt-get update && \ - apt-get upgrade -y && \ - apt-get install libsodium-dev -y + apt-get upgrade -y RUN go get github.com/dvyukov/go-fuzz/go-fuzz RUN go get github.com/dvyukov/go-fuzz/go-fuzz-build diff --git a/lib/crypto/ed25519.go b/lib/crypto/ed25519.go index 040a10c..3a2db82 100644 --- a/lib/crypto/ed25519.go +++ b/lib/crypto/ed25519.go @@ -1,54 +1,37 @@ package crypto -/* -#cgo pkg-config: libsodium -#include -#include -*/ -import "C" - import ( + "crypto/ed25519" "crypto/sha512" "errors" - "fmt" ) -type Ed25519PublicKey [32]byte +type Ed25519PublicKey []byte type Ed25519Verifier struct { - k [32]C.uchar + k []byte } func (k Ed25519PublicKey) NewVerifier() (v Verifier, err error) { - ev := new(Ed25519Verifier) - for i, b := range k { - ev.k[i] = C.uchar(b) - } - v = ev - return + temp := new(Ed25519Verifier) + temp.k = k + v = temp + return temp, nil } func (v *Ed25519Verifier) VerifyHash(h, sig []byte) (err error) { - if len(sig) == C.crypto_sign_BYTES { - // valid size of sig - // copy signature and hash - var csig, ch [32]C.uchar - for i, b := range h { - ch[i] = C.uchar(b) - } - for i, b := range sig { - csig[i] = C.uchar(b) - } - // verify - if C.crypto_sign_verify_detached(&csig[0], &ch[0], C.ulonglong(32), &v.k[0]) == 0 { - // valid signature - } else { - // bad signature - err = ErrInvalidSignature - } - } else { - // bad size of sig + if len(sig) != ed25519.SignatureSize { err = ErrBadSignatureSize + return + } + if len(v.k) != ed25519.PublicKeySize { + err = errors.New("failed to verify: invalid ed25519 public key size") + return + } + + ok := ed25519.Verify(v.k, h, sig) + if !ok { + err = errors.New("failed to verify: invalid signature") } return } @@ -59,35 +42,23 @@ func (v *Ed25519Verifier) Verify(data, sig []byte) (err error) { return } -type Ed25519PrivateKey [32]byte +type Ed25519PrivateKey ed25519.PrivateKey type Ed25519Signer struct { - k [32]C.uchar + k []byte } func (s *Ed25519Signer) Sign(data []byte) (sig []byte, err error) { + if len(s.k) != ed25519.PrivateKeySize { + err = errors.New("failed to sign: invalid ed25519 private key size") + return + } h := sha512.Sum512(data) sig, err = s.SignHash(h[:]) return } func (s *Ed25519Signer) SignHash(h []byte) (sig []byte, err error) { - var ch [32]C.uchar - for i, b := range h { - ch[i] = C.uchar(b) - } - var csig [32]C.uchar - var smlen_p C.ulonglong - res := C.crypto_sign_detached(&csig[0], &smlen_p, &ch[0], C.ulonglong(32), &s.k[0]) - if res == 0 { - // success signing - sig = make([]byte, 32) - for i, b := range csig { - sig[i] = byte(b) - } - } else { - // failed signing - err = errors.New(fmt.Sprintf("failed to sign: crypto_sign_detached exit code %d", int(res))) - } + sig = ed25519.Sign(s.k, h) return } diff --git a/lib/crypto/ed25519_test.go b/lib/crypto/ed25519_test.go index e746c7a..c6507b9 100644 --- a/lib/crypto/ed25519_test.go +++ b/lib/crypto/ed25519_test.go @@ -1,9 +1,42 @@ package crypto import ( + "crypto/ed25519" + "crypto/rand" + "io" "testing" ) func TestEd25519(t *testing.T) { + var pubKey Ed25519PublicKey + signer := new(Ed25519Signer) + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Log("Failed to generate ed25519 test key") + t.Fail() + } + pubKey = []byte(pub) + signer.k = []byte(priv) + + message := make([]byte, 123) + io.ReadFull(rand.Reader, message) + + sig, err := signer.Sign(message) + if err != nil { + t.Log("Failed to sign message") + t.Fail() + } + + verifier, err := pubKey.NewVerifier() + if err != nil { + t.Logf("Error from verifier: %s", err) + t.Fail() + } + + err = verifier.Verify(message, sig) + if err != nil { + t.Log("Failed to verify message") + t.Fail() + } }