[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