[go] crypto/ed25519: implement Ed25519ph in Sign and VerifyWithOptions

251 views
Skip to first unread message

Filippo Valsorda (Gerrit)

unread,
Jan 5, 2022, 8:34:49 AM1/5/22
to Katie Hockman, Jonathan Rudenberg, goph...@pubsubhelper.golang.org, Julie Qiu, Roland Shoemaker, Filippo Valsorda, golang-co...@googlegroups.com

Attention is currently required from: Katie Hockman, Jonathan Rudenberg.

Filippo Valsorda would like Katie Hockman and Jonathan Rudenberg to review this change.

View Change

crypto/ed25519: implement Ed25519ph in Sign and VerifyWithOptions

Fixes #31804

Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
---
M src/crypto/ed25519/ed25519_test.go
M src/crypto/ed25519/ed25519.go
2 files changed, 136 insertions(+), 11 deletions(-)

diff --git a/src/crypto/ed25519/ed25519.go b/src/crypto/ed25519/ed25519.go
index 09c5269..f76443e 100644
--- a/src/crypto/ed25519/ed25519.go
+++ b/src/crypto/ed25519/ed25519.go
@@ -77,19 +77,39 @@
return seed
}

-// Sign signs the given message with priv.
-// Ed25519 performs two passes over messages to be signed and therefore cannot
-// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
-// indicate the message hasn't been hashed. This can be achieved by passing
-// crypto.Hash(0) as the value for opts.
+// Sign signs the given message with priv. rand is ignored. If opts.HashFunc()
+// is crypto.SHA512, the pre-hashed variant Ed25519ph is used and message is
+// expected to be a SHA-512 hash, otherwise opts.HashFunc() must be
+// crypto.Hash(0) and the message must not be hashed, as Ed25519 performs two
+// passes over messages to be signed.
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
- if opts.HashFunc() != crypto.Hash(0) {
- return nil, errors.New("ed25519: cannot sign hashed message")
+ switch opts.HashFunc() {
+ case crypto.SHA512:
+ if l := len(message); l != sha512.Size {
+ return nil, errors.New("ed25519: bad Ed25519ph message hash length: " + strconv.Itoa(l))
+ }
+ signature := make([]byte, SignatureSize)
+ sign(signature, priv, message, domPrefixPh)
+ return signature, nil
+ case crypto.Hash(0):
+ return Sign(priv, message), nil
+ default:
+ return nil, errors.New("ed25519: expected opts zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
}
-
- return Sign(priv, message), nil
}

+// Options can be used with PrivateKey.Sign or VerifyWithOptions
+// to select Ed25519 variants.
+type Options struct {
+ // Hash can be zero for regular Ed25519, or crypto.SHA512 for Ed25519ph.
+ Hash crypto.Hash
+
+ // TODO(filippo): add Context, a string of at most 255 bytes which when
+ // non-zero selects Ed25519ctx.
+}
+
+func (o *Options) HashFunc() crypto.Hash { return o.Hash }
+
// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
@@ -141,11 +161,20 @@
// Outline the function body so that the returned signature can be
// stack-allocated.
signature := make([]byte, SignatureSize)
- sign(signature, privateKey, message)
+ sign(signature, privateKey, message, domPrefixPure)
return signature
}

-func sign(signature, privateKey, message []byte) {
+// Domain separation prefixes used to disambiguate Ed25519/Ed25519ph.
+// See RFC 8032, Section 2 and Section 5.1.
+const (
+ // domPrefixPure is empty for pure Ed25519.
+ domPrefixPure = ""
+ // domPrefixPh is dom2(phflag=1, context="") for Ed25519ph.
+ domPrefixPh = "SigEd25519 no Ed25519 collisions\x01\x00"
+)
+
+func sign(signature, privateKey, message []byte, domPrefix string) {
if l := len(privateKey); l != PrivateKeySize {
panic("ed25519: bad private key length: " + strconv.Itoa(l))
}
@@ -156,6 +185,7 @@
prefix := h[32:]

mh := sha512.New()
+ mh.Write([]byte(domPrefix))
mh.Write(prefix)
mh.Write(message)
messageDigest := make([]byte, 0, sha512.Size)
@@ -165,6 +195,7 @@
R := (&edwards25519.Point{}).ScalarBaseMult(r)

kh := sha512.New()
+ kh.Write([]byte(domPrefix))
kh.Write(R.Bytes())
kh.Write(publicKey)
kh.Write(message)
@@ -181,6 +212,36 @@
// Verify reports whether sig is a valid signature of message by publicKey. It
// will panic if len(publicKey) is not PublicKeySize.
func Verify(publicKey PublicKey, message, sig []byte) bool {
+ return verify(publicKey, message, sig, domPrefixPure)
+}
+
+// VerifyWithOptions reports whether sig is a valid signature of message by
+// publicKey. A valid signature is indicated by returning a nil error.
+// If opts.HashFunc() is crypto.SHA512, the pre-hashed variant Ed25519ph is used
+// and message is expected to be a SHA-512 hash, otherwise opts.HashFunc() must
+// be crypto.Hash(0) and the message must not be hashed, as Ed25519 performs two
+// passes over messages to be signed.
+func VerifyWithOptions(publicKey PublicKey, message, sig []byte, opts *Options) error {
+ switch opts.HashFunc() {
+ case crypto.SHA512:
+ if l := len(message); l != sha512.Size {
+ return errors.New("ed25519: bad Ed25519ph message hash length: " + strconv.Itoa(l))
+ }
+ if !verify(publicKey, message, sig, domPrefixPh) {
+ return errors.New("ed25519: invalid signature")
+ }
+ return nil
+ case crypto.Hash(0):
+ if !verify(publicKey, message, sig, domPrefixPure) {
+ return errors.New("ed25519: invalid signature")
+ }
+ return nil
+ default:
+ return errors.New("ed25519: expected opts zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
+ }
+}
+
+func verify(publicKey PublicKey, message, sig []byte, domPrefix string) bool {
if l := len(publicKey); l != PublicKeySize {
panic("ed25519: bad public key length: " + strconv.Itoa(l))
}
@@ -195,6 +256,7 @@
}

kh := sha512.New()
+ kh.Write([]byte(domPrefix))
kh.Write(sig[:32])
kh.Write(publicKey)
kh.Write(message)
diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go
index 8a973b3..80bce54 100644
--- a/src/crypto/ed25519/ed25519_test.go
+++ b/src/crypto/ed25519/ed25519_test.go
@@ -10,6 +10,7 @@
"compress/gzip"
"crypto"
"crypto/rand"
+ "crypto/sha512"
"encoding/hex"
"os"
"strings"
@@ -41,6 +42,49 @@
}
}

+func TestSignVerifyHashed(t *testing.T) {
+ // From RFC 8032, Section 7.3
+ key, _ := hex.DecodeString("833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf")
+ expectedSig, _ := hex.DecodeString("98a70222f0b8121aa9d30f813d683f809e462b469c7ff87639499bb94e6dae4131f85042463c2a355a2003d062adf5aaa10b8c61e636062aaad11c2a26083406")
+ message, _ := hex.DecodeString("616263")
+
+ private := PrivateKey(key)
+ public := private.Public().(PublicKey)
+ hash := sha512.Sum512(message)
+ sig, err := private.Sign(nil, hash[:], crypto.SHA512)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(sig, expectedSig) {
+ t.Error("signature doesn't match test vector")
+ }
+ sig, err = private.Sign(nil, hash[:], &Options{Hash: crypto.SHA512})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(sig, expectedSig) {
+ t.Error("signature doesn't match test vector")
+ }
+ if err := VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA512}); err != nil {
+ t.Errorf("valid signature rejected: %v", err)
+ }
+
+ wrongHash := sha512.Sum512([]byte("wrong message"))
+ if VerifyWithOptions(public, wrongHash[:], sig, &Options{Hash: crypto.SHA512}) == nil {
+ t.Errorf("signature of different message accepted")
+ }
+
+ sig[0] ^= 0xff
+ if VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA512}) == nil {
+ t.Errorf("invalid signature accepted")
+ }
+ sig[0] ^= 0xff
+ sig[SignatureSize-1] ^= 0xff
+ if VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA512}) == nil {
+ t.Errorf("invalid signature accepted")
+ }
+}
+
func TestCryptoSigner(t *testing.T) {
var zero zeroReader
public, private, _ := GenerateKey(zero)
@@ -64,6 +108,14 @@
t.Fatalf("error from Sign(): %s", err)
}

+ signature2, err := signer.Sign(zero, message, &Options{Hash: noHash})
+ if err != nil {
+ t.Fatalf("error from Sign(): %s", err)
+ }
+ if !bytes.Equal(signature, signature2) {
+ t.Errorf("signatures keys do not match")
+ }
+
if !Verify(public, message, signature) {
t.Errorf("Verify failed on signature from Sign()")
}

To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
Gerrit-Change-Number: 373076
Gerrit-PatchSet: 1
Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
Gerrit-CC: Julie Qiu <ju...@golang.org>
Gerrit-CC: Roland Shoemaker <rol...@golang.org>
Gerrit-Attention: Katie Hockman <ka...@golang.org>
Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-MessageType: newchange

Filippo Valsorda (Gerrit)

unread,
Jan 5, 2022, 11:27:43 AM1/5/22
to Filippo Valsorda, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Attention is currently required from: Katie Hockman, Jonathan Rudenberg, Filippo Valsorda.

Filippo Valsorda uploaded patch set #3 to this change.

View Change

crypto/ed25519: implement Ed25519ph in Sign and VerifyWithOptions

Fixes #31804

Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
---
M api/next.txt
M src/crypto/ed25519/ed25519_test.go
M src/crypto/ed25519/ed25519.go
3 files changed, 140 insertions(+), 11 deletions(-)

To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
Gerrit-Change-Number: 373076
Gerrit-PatchSet: 3
Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
Gerrit-CC: Julie Qiu <ju...@golang.org>
Gerrit-CC: Roland Shoemaker <rol...@golang.org>
Gerrit-Attention: Katie Hockman <ka...@golang.org>
Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
Gerrit-MessageType: newpatchset

Katie Hockman (Gerrit)

unread,
Jan 31, 2022, 3:16:23 PM1/31/22
to Filippo Valsorda, goph...@pubsubhelper.golang.org, Gopher Robot, Jonathan Rudenberg, Julie Qiu, Roland Shoemaker, golang-co...@googlegroups.com

Attention is currently required from: Jonathan Rudenberg, Filippo Valsorda.

Patch set 3:Run-TryBot +1Code-Review +2Trust +1

View Change

1 comment:

    • 	// TODO(filippo): add Context, a string of at most 255 bytes which when

    • 	// non-zero selects Ed25519ctx.

      Maybe link to an issue instead of you individually? Is there one for this specific piece?

To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
Gerrit-Change-Number: 373076
Gerrit-PatchSet: 3
Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
Gerrit-CC: Julie Qiu <ju...@golang.org>
Gerrit-CC: Roland Shoemaker <rol...@golang.org>
Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
Gerrit-Comment-Date: Mon, 31 Jan 2022 20:16:20 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment

Filippo Valsorda (Gerrit)

unread,
May 5, 2022, 9:26:21 AM5/5/22
to Filippo Valsorda, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Attention is currently required from: Filippo Valsorda, Jonathan Rudenberg, Katie Hockman.

Filippo Valsorda uploaded patch set #4 to this change.

View Change

crypto/ed25519: implement Ed25519ph in Sign and VerifyWithOptions

Updates #31804

Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
---
A api/next/31804.txt
M src/crypto/ed25519/ed25519.go
M src/crypto/ed25519/ed25519_test.go

3 files changed, 140 insertions(+), 11 deletions(-)

To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
Gerrit-Change-Number: 373076
Gerrit-PatchSet: 4
Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
Gerrit-CC: Julie Qiu <ju...@golang.org>
Gerrit-CC: Roland Shoemaker <rol...@golang.org>
Gerrit-Attention: Katie Hockman <ka...@golang.org>
Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
Gerrit-MessageType: newpatchset

Filippo Valsorda (Gerrit)

unread,
May 5, 2022, 9:26:22 AM5/5/22
to Filippo Valsorda, goph...@pubsubhelper.golang.org, Katie Hockman, Gopher Robot, Jonathan Rudenberg, Julie Qiu, Roland Shoemaker, golang-co...@googlegroups.com

Attention is currently required from: Filippo Valsorda, Jonathan Rudenberg, Katie Hockman.

View Change

1 comment:

  • File src/crypto/ed25519/ed25519.go:

    • Patch Set #3, Line 107:

      	// TODO(filippo): add Context, a string of at most 255 bytes which when
      // non-zero selects Ed25519ctx.

      Maybe link to an issue instead of you individually? Is there one for this specific piece?

    • Addressing this in a follow-up CL.

To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
Gerrit-Change-Number: 373076
Gerrit-PatchSet: 4
Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
Gerrit-CC: Julie Qiu <ju...@golang.org>
Gerrit-CC: Roland Shoemaker <rol...@golang.org>
Gerrit-Attention: Katie Hockman <ka...@golang.org>
Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
Gerrit-Comment-Date: Thu, 05 May 2022 13:26:16 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Katie Hockman <ka...@golang.org>
Gerrit-MessageType: comment

Filippo Valsorda (Gerrit)

unread,
May 5, 2022, 9:27:10 AM5/5/22
to Filippo Valsorda, goph...@pubsubhelper.golang.org, Katie Hockman, Gopher Robot, Jonathan Rudenberg, Julie Qiu, Roland Shoemaker, golang-co...@googlegroups.com

Attention is currently required from: Filippo Valsorda, Jonathan Rudenberg, Katie Hockman.

Patch set 4:Code-Review +1

View Change

    To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
    Gerrit-Change-Number: 373076
    Gerrit-PatchSet: 4
    Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
    Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
    Gerrit-Reviewer: Filippo Valsorda <vals...@google.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
    Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
    Gerrit-CC: Julie Qiu <ju...@golang.org>
    Gerrit-CC: Roland Shoemaker <rol...@golang.org>
    Gerrit-Attention: Katie Hockman <ka...@golang.org>
    Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
    Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
    Gerrit-Comment-Date: Thu, 05 May 2022 13:27:05 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    David Chase (Gerrit)

    unread,
    May 5, 2022, 10:37:29 AM5/5/22
    to Filippo Valsorda, goph...@pubsubhelper.golang.org, Gopher Robot, Filippo Valsorda, Katie Hockman, Jonathan Rudenberg, Julie Qiu, Roland Shoemaker, golang-co...@googlegroups.com

    Attention is currently required from: Filippo Valsorda, Jonathan Rudenberg, Katie Hockman.

    Patch set 4:Code-Review +1

    View Change

      To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
      Gerrit-Change-Number: 373076
      Gerrit-PatchSet: 4
      Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
      Gerrit-Reviewer: David Chase <drc...@google.com>
      Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
      Gerrit-Reviewer: Filippo Valsorda <vals...@google.com>
      Gerrit-Reviewer: Gopher Robot <go...@golang.org>
      Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
      Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
      Gerrit-CC: Julie Qiu <ju...@golang.org>
      Gerrit-CC: Roland Shoemaker <rol...@golang.org>
      Gerrit-Attention: Katie Hockman <ka...@golang.org>
      Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
      Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
      Gerrit-Comment-Date: Thu, 05 May 2022 14:37:24 +0000

      Michael Knyszek (Gerrit)

      unread,
      May 18, 2022, 6:24:57 PM5/18/22
      to Filippo Valsorda, goph...@pubsubhelper.golang.org, David Chase, Gopher Robot, Katie Hockman, Jonathan Rudenberg, Julie Qiu, Roland Shoemaker, golang-co...@googlegroups.com

      Attention is currently required from: Filippo Valsorda, Jonathan Rudenberg, Katie Hockman.

      Patch set 4:Code-Review +1

      View Change

        To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
        Gerrit-Change-Number: 373076
        Gerrit-PatchSet: 4
        Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
        Gerrit-Reviewer: David Chase <drc...@google.com>
        Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
        Gerrit-Reviewer: Filippo Valsorda <vals...@google.com>
        Gerrit-Reviewer: Gopher Robot <go...@golang.org>
        Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
        Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
        Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
        Gerrit-CC: Julie Qiu <ju...@golang.org>
        Gerrit-CC: Roland Shoemaker <rol...@golang.org>
        Gerrit-Attention: Katie Hockman <ka...@golang.org>
        Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
        Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
        Gerrit-Comment-Date: Wed, 18 May 2022 22:24:52 +0000

        Roland Shoemaker (Gerrit)

        unread,
        Oct 18, 2022, 2:53:36 PM10/18/22
        to Filippo Valsorda, goph...@pubsubhelper.golang.org, David Chase, Gopher Robot, Katie Hockman, Jonathan Rudenberg, Julie Qiu, golang-co...@googlegroups.com

        Attention is currently required from: Filippo Valsorda, Jonathan Rudenberg, Katie Hockman.

        Patch set 4:Code-Review +2

        View Change

          To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
          Gerrit-Change-Number: 373076
          Gerrit-PatchSet: 4
          Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
          Gerrit-Reviewer: David Chase <drc...@google.com>
          Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
          Gerrit-Reviewer: Filippo Valsorda <vals...@google.com>
          Gerrit-Reviewer: Gopher Robot <go...@golang.org>
          Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
          Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
          Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
          Gerrit-Reviewer: Roland Shoemaker <rol...@golang.org>
          Gerrit-CC: Julie Qiu <ju...@golang.org>
          Gerrit-Attention: Katie Hockman <ka...@golang.org>
          Gerrit-Attention: Jonathan Rudenberg <jona...@titanous.com>
          Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
          Gerrit-Comment-Date: Tue, 18 Oct 2022 18:53:31 +0000

          Filippo Valsorda (Gerrit)

          unread,
          Oct 24, 2022, 8:11:29 AM10/24/22
          to Filippo Valsorda, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Roland Shoemaker, Michael Knyszek, David Chase, Gopher Robot, Katie Hockman, Jonathan Rudenberg, Julie Qiu, golang-co...@googlegroups.com

          Filippo Valsorda submitted this change.

          View Change


          Approvals: Filippo Valsorda: Looks good to me, but someone else must approve Roland Shoemaker: Looks good to me, approved Gopher Robot: TryBots succeeded Filippo Valsorda: Run TryBots David Chase: Looks good to me, but someone else must approve Katie Hockman: Looks good to me, approved Michael Knyszek: Looks good to me, but someone else must approve
          crypto/ed25519: implement Ed25519ph in Sign and VerifyWithOptions

          Updates #31804

          Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
          Reviewed-on: https://go-review.googlesource.com/c/go/+/373076
          Reviewed-by: Filippo Valsorda <vals...@google.com>
          Reviewed-by: Michael Knyszek <mkny...@google.com>
          Run-TryBot: Filippo Valsorda <fil...@golang.org>
          Reviewed-by: Roland Shoemaker <rol...@golang.org>
          TryBot-Result: Gopher Robot <go...@golang.org>
          Reviewed-by: Katie Hockman <ka...@golang.org>
          Reviewed-by: David Chase <drc...@google.com>

          ---
          A api/next/31804.txt
          M src/crypto/ed25519/ed25519.go
          M src/crypto/ed25519/ed25519_test.go
          3 files changed, 148 insertions(+), 11 deletions(-)

          diff --git a/api/next/31804.txt b/api/next/31804.txt
          new file mode 100644
          index 0000000..e5968c8
          --- /dev/null
          +++ b/api/next/31804.txt
          @@ -0,0 +1,4 @@
          +pkg crypto/ed25519, func VerifyWithOptions(PublicKey, []uint8, []uint8, *Options) error #31804
          +pkg crypto/ed25519, method (*Options) HashFunc() crypto.Hash #31804
          +pkg crypto/ed25519, type Options struct #31804
          +pkg crypto/ed25519, type Options struct, Hash crypto.Hash #31804
          diff --git a/src/crypto/ed25519/ed25519.go b/src/crypto/ed25519/ed25519.go
          index 601da50..cb6b293 100644
          --- a/src/crypto/ed25519/ed25519.go
          +++ b/src/crypto/ed25519/ed25519.go
          @@ -75,19 +75,39 @@
          return bytes.Clone(priv[:SeedSize])
          @@ -142,11 +162,20 @@

          // Outline the function body so that the returned signature can be
          // stack-allocated.
          signature := make([]byte, SignatureSize)
          - sign(signature, privateKey, message)
          + sign(signature, privateKey, message, domPrefixPure)
          return signature
          }

          -func sign(signature, privateKey, message []byte) {
          +// Domain separation prefixes used to disambiguate Ed25519/Ed25519ph.
          +// See RFC 8032, Section 2 and Section 5.1.
          +const (
          + // domPrefixPure is empty for pure Ed25519.
          + domPrefixPure = ""
          + // domPrefixPh is dom2(phflag=1, context="") for Ed25519ph.
          + domPrefixPh = "SigEd25519 no Ed25519 collisions\x01\x00"
          +)
          +
          +func sign(signature, privateKey, message []byte, domPrefix string) {
          if l := len(privateKey); l != PrivateKeySize {
          panic("ed25519: bad private key length: " + strconv.Itoa(l))
          }
          @@ -160,6 +189,7 @@

          prefix := h[32:]

          mh := sha512.New()
          + mh.Write([]byte(domPrefix))
          mh.Write(prefix)
          mh.Write(message)
          messageDigest := make([]byte, 0, sha512.Size)
          @@ -172,6 +202,7 @@

          R := (&edwards25519.Point{}).ScalarBaseMult(r)

          kh := sha512.New()
          + kh.Write([]byte(domPrefix))
          kh.Write(R.Bytes())
          kh.Write(publicKey)
          kh.Write(message)
          @@ -191,6 +222,36 @@
          @@ -205,6 +266,7 @@

          }

          kh := sha512.New()
          + kh.Write([]byte(domPrefix))
          kh.Write(sig[:32])
          kh.Write(publicKey)
          kh.Write(message)
          diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go
          index 2e7fe23..fbd4982 100644
          --- a/src/crypto/ed25519/ed25519_test.go
          +++ b/src/crypto/ed25519/ed25519_test.go
          @@ -11,6 +11,7 @@
          "crypto"
          "crypto/internal/boring"
          "crypto/rand"
          + "crypto/sha512"
          "encoding/hex"
          "internal/testenv"
          "os"
          @@ -43,6 +44,49 @@
          @@ -66,6 +110,14 @@

          t.Fatalf("error from Sign(): %s", err)
          }

          + signature2, err := signer.Sign(zero, message, &Options{Hash: noHash})
          + if err != nil {
          + t.Fatalf("error from Sign(): %s", err)
          + }
          + if !bytes.Equal(signature, signature2) {
          + t.Errorf("signatures keys do not match")
          + }
          +
          if !Verify(public, message, signature) {
          t.Errorf("Verify failed on signature from Sign()")
          }

          To view, visit change 373076. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I5a48dfc57401576902674aff20b557e4a8ce8ab8
          Gerrit-Change-Number: 373076
          Gerrit-PatchSet: 5
          Gerrit-Owner: Filippo Valsorda <fil...@golang.org>
          Gerrit-Reviewer: David Chase <drc...@google.com>
          Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
          Gerrit-Reviewer: Filippo Valsorda <vals...@google.com>
          Gerrit-Reviewer: Gopher Robot <go...@golang.org>
          Gerrit-Reviewer: Jonathan Rudenberg <jona...@titanous.com>
          Gerrit-Reviewer: Katie Hockman <ka...@golang.org>
          Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
          Gerrit-Reviewer: Roland Shoemaker <rol...@golang.org>
          Gerrit-CC: Julie Qiu <ju...@golang.org>
          Gerrit-MessageType: merged
          Reply all
          Reply to author
          Forward
          0 new messages