Skip to content

Commit 9e8b46f

Browse files
committed
Ed25519 public key to curve25519
1 parent 12707e7 commit 9e8b46f

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

pin.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import (
1616
"encoding/json"
1717
"encoding/pem"
1818
"errors"
19+
"fmt"
1920
"io"
2021
"time"
2122

23+
"github.com/MixinNetwork/mixin/crypto/edwards25519"
2224
"golang.org/x/crypto/curve25519"
2325
)
2426

@@ -76,10 +78,10 @@ func EncryptEd25519PIN(ctx context.Context, pin, pinTokenBase64, sessionId, priv
7678
if err != nil {
7779
return "", err
7880
}
79-
var dst, curve, pub [32]byte
80-
PrivateKeyToCurve25519(&curve, private)
81+
var keyBytes, curvePriv, pub [32]byte
82+
PrivateKeyToCurve25519(&curvePriv, private)
8183
copy(pub[:], public[:])
82-
curve25519.ScalarMult(&dst, &curve, &pub)
84+
curve25519.ScalarMult(&keyBytes, &curvePriv, &pub)
8385

8486
pinByte := []byte(pin)
8587
timeBytes := make([]byte, 8)
@@ -91,7 +93,7 @@ func EncryptEd25519PIN(ctx context.Context, pin, pinTokenBase64, sessionId, priv
9193
padding := aes.BlockSize - len(pinByte)%aes.BlockSize
9294
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
9395
pinByte = append(pinByte, padtext...)
94-
block, err := aes.NewCipher(dst[:])
96+
block, err := aes.NewCipher(keyBytes[:])
9597
if err != nil {
9698
return "", err
9799
}
@@ -158,3 +160,33 @@ func PrivateKeyToCurve25519(curve25519Private *[32]byte, privateKey ed25519.Priv
158160

159161
copy(curve25519Private[:], digest)
160162
}
163+
164+
func PublicKeyToCurve25519(curve25519Public *[32]byte, publicKey ed25519.PublicKey) error {
165+
var k [32]byte
166+
copy(k[:], publicKey[:])
167+
var A edwards25519.ExtendedGroupElement
168+
if !A.FromBytes(&k) {
169+
return fmt.Errorf("Invalid public key %x", publicKey)
170+
}
171+
172+
// A.Z = 1 as a postcondition of FromBytes.
173+
var x edwards25519.FieldElement
174+
edwardsToMontgomeryX(&x, &A.Y)
175+
edwards25519.FeToBytes(curve25519Public, &x)
176+
return nil
177+
}
178+
179+
func edwardsToMontgomeryX(outX, y *edwards25519.FieldElement) {
180+
// We only need the x-coordinate of the curve25519 point, which I'll
181+
// call u. The isomorphism is u=(y+1)/(1-y), since y=Y/Z, this gives
182+
// u=(Y+Z)/(Z-Y). We know that Z=1, thus u=(Y+1)/(1-Y).
183+
var oneMinusY edwards25519.FieldElement
184+
edwards25519.FeOne(&oneMinusY)
185+
edwards25519.FeSub(&oneMinusY, &oneMinusY, y)
186+
edwards25519.FeInvert(&oneMinusY, &oneMinusY)
187+
188+
edwards25519.FeOne(outX)
189+
edwards25519.FeAdd(outX, outX, y)
190+
191+
edwards25519.FeMul(outX, outX, &oneMinusY)
192+
}

0 commit comments

Comments
 (0)