summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Erbsen <andreser@yahoo-inc.com>2015-07-24 17:21:22 -0700
committerAdam Langley <agl@imperialviolet.org>2015-08-30 11:28:03 -0700
commit446061e2131e917e692f241c66202d143338e0bb (patch)
tree1ae47487ed4c9800ed6ab85e1daec657ee104689
parent550d88df8d246c0f8f04cb6b4ce0978303586c2b (diff)
downloaded25519-446061e2131e917e692f241c66202d143338e0bb.tar.xz
edwards25519.FromBytes: do not negate the point
edwards25519.FromBytes is an exported method and should thus live up to its name. In particular, X == ToBytes(FromBytes(X)) should hold. Up to now, FromBytes silently negate the point it was deserializing, and ed25519.Verify was missing a negation -- these two defects cancelled each other out.
-rw-r--r--ed25519.go2
-rw-r--r--edwards25519/edwards25519.go2
-rw-r--r--marshal_test.go58
3 files changed, 61 insertions, 1 deletions
diff --git a/ed25519.go b/ed25519.go
index 700938d..e5f873f 100644
--- a/ed25519.go
+++ b/ed25519.go
@@ -103,6 +103,8 @@ func Verify(publicKey *[PublicKeySize]byte, message []byte, sig *[SignatureSize]
if !A.FromBytes(publicKey) {
return false
}
+ edwards25519.FeNeg(&A.X, &A.X)
+ edwards25519.FeNeg(&A.T, &A.T)
h := sha512.New()
h.Write(sig[:32])
diff --git a/edwards25519/edwards25519.go b/edwards25519/edwards25519.go
index f883a3a..9079818 100644
--- a/edwards25519/edwards25519.go
+++ b/edwards25519/edwards25519.go
@@ -754,7 +754,7 @@ func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool {
}
}
- if FeIsNegative(&p.X) == (s[31] >> 7) {
+ if FeIsNegative(&p.X) != (s[31] >> 7) {
FeNeg(&p.X, &p.X)
}
diff --git a/marshal_test.go b/marshal_test.go
new file mode 100644
index 0000000..5f01d35
--- /dev/null
+++ b/marshal_test.go
@@ -0,0 +1,58 @@
+package ed25519
+
+import (
+ "crypto/rand"
+ "testing"
+
+ "github.com/agl/ed25519/edwards25519"
+)
+
+func TestUnmarshalMarshal(t *testing.T) {
+ pk, _, _ := GenerateKey(rand.Reader)
+
+ var A edwards25519.ExtendedGroupElement
+ ret := A.FromBytes(pk)
+
+ var pk2 [32]byte
+ A.ToBytes(&pk2)
+
+ if *pk != pk2 {
+ _ = ret
+ t.Errorf("FromBytes(%v)->ToBytes not idempotent:\n%x\nbytes:\n\t%x\n\t%x\ndelta: %x\n", ret, A, *pk, pk2, int(pk[31])-int(pk2[31]))
+ }
+}
+
+func TestUnmarshalMarshalTwice(t *testing.T) {
+ pk, _, _ := GenerateKey(rand.Reader)
+
+ var A edwards25519.ExtendedGroupElement
+ A.FromBytes(pk)
+
+ var pk2 [32]byte
+ A.ToBytes(&pk2)
+
+ var B edwards25519.ExtendedGroupElement
+ ret := B.FromBytes(&pk2)
+
+ var pk3 [32]byte
+ B.ToBytes(&pk3)
+
+ if *pk != pk3 {
+ t.Errorf("FromBytes(%v)->ToBytes not idempotent:\n%x\nbytes:\n\t%x\n\t%x\ndelta: %x\n", ret, A, *pk, pk3, int(pk[31])-int(pk2[31]))
+ }
+}
+
+func TestUnmarshalMarshalNegative(t *testing.T) {
+ pk, _, _ := GenerateKey(rand.Reader)
+
+ var A edwards25519.ExtendedGroupElement
+ ret := A.FromBytes(pk)
+
+ var pk2 [32]byte
+ A.ToBytes(&pk2)
+ pk2[31] ^= 0x80
+
+ if *pk == pk2 {
+ t.Errorf("flipping sign did not change public key:\n%x\nbytes:\n\t%x\n\t%x\ndelta: %x\n", ret, A, *pk, pk2, int(pk[31])-int(pk2[31]))
+ }
+}