[Pkg-privacy-commits] [golang-ed25519-dev] 03/11: Add functions to convert to curve25519 keys.
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 12:55:26 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository golang-ed25519-dev.
commit 8f60da0a969a8a8b590e56799eb2090700dda242
Author: Adam Langley <agl at imperialviolet.org>
Date: Sun Dec 22 12:15:47 2013 -0500
Add functions to convert to curve25519 keys.
---
ed25519.go | 41 +++++++++++++++++++++++++++++++++++++++++
ed25519_test.go | 19 +++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/ed25519.go b/ed25519.go
index 9013eb3..7d474af 100644
--- a/ed25519.go
+++ b/ed25519.go
@@ -2240,3 +2240,44 @@ func Verify(publicKey *[PublicKeySize]byte, message []byte, sig *[SignatureSize]
R.ToBytes(&checkR)
return bytes.Equal(sig[:32], checkR[:])
}
+
+// PrivateKeyToCurve25519 converts an ed25519 private key into a corresponding
+// curve25519 private key such that the resulting curve25519 public key will
+// equal the result from PublicKeyToCurve25519.
+func PrivateKeyToCurve25519(curve25519Private *[32]byte, privateKey *[PrivateKeySize]byte) {
+ h := sha512.New()
+ h.Write(privateKey[:32])
+ digest := h.Sum(nil)
+
+ digest[0] &= 248
+ digest[31] &= 127
+ digest[31] |= 64
+
+ copy(curve25519Private[:], digest)
+}
+
+// PublicKeyToCurve25519 converts an Ed25519 public key into the curve25519
+// public key that would be generated from the same private key.
+func PublicKeyToCurve25519(curve25519Public *[32]byte, publicKey *[PublicKeySize]byte) bool {
+ // We only need the x-coordinate of the curve25519 point, which I'll call u.
+ // The isomorphism is u=(y+1)/(1-y), since y=Y/Z, this gives u=(Y+Z)/(Z-Y).
+
+ var A extendedGroupElement
+ if !A.FromBytes(publicKey) {
+ return false
+ }
+
+ // Z=1 since we have just unpacked the public key. Thus u=(Y+1)/(1-Y).
+ var oneMinusY fieldElement
+ feOne(&oneMinusY)
+ feSub(&oneMinusY, &oneMinusY, &A.Y)
+ feInvert(&oneMinusY, &oneMinusY)
+
+ var yPlusOne fieldElement
+ feOne(&yPlusOne)
+ feAdd(&yPlusOne, &yPlusOne, &A.Y)
+
+ feMul(&yPlusOne, &yPlusOne, &oneMinusY)
+ feToBytes(curve25519Public, &yPlusOne)
+ return true
+}
diff --git a/ed25519_test.go b/ed25519_test.go
index 0dc2b13..ca21719 100644
--- a/ed25519_test.go
+++ b/ed25519_test.go
@@ -8,11 +8,14 @@ import (
"bufio"
"bytes"
"compress/gzip"
+ "crypto/rand"
"encoding/hex"
"io"
"os"
"strings"
"testing"
+
+ "code.google.com/p/go.crypto/curve25519"
)
type zeroReader struct{}
@@ -103,3 +106,19 @@ func TestGolden(t *testing.T) {
}
}
}
+
+func TestCurve25519Conversion(t *testing.T) {
+ public, private, _ := GenerateKey(rand.Reader)
+
+ var curve25519Public, curve25519Public2, curve25519Private [32]byte
+ PrivateKeyToCurve25519(&curve25519Private, private)
+ curve25519.ScalarBaseMult(&curve25519Public, &curve25519Private)
+
+ if !PublicKeyToCurve25519(&curve25519Public2, public) {
+ t.Fatalf("PublicKeyToCurve25519 failed")
+ }
+
+ if !bytes.Equal(curve25519Public[:], curve25519Public2[:]) {
+ t.Errorf("Values didn't match: curve25519 produced %x, conversion produced %x", curve25519Public[:], curve25519Public2[:])
+ }
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/golang-ed25519-dev.git
More information about the Pkg-privacy-commits
mailing list