@@ -16,9 +16,11 @@ import (
16
16
"encoding/json"
17
17
"encoding/pem"
18
18
"errors"
19
+ "fmt"
19
20
"io"
20
21
"time"
21
22
23
+ "github.com/MixinNetwork/mixin/crypto/edwards25519"
22
24
"golang.org/x/crypto/curve25519"
23
25
)
24
26
@@ -76,10 +78,10 @@ func EncryptEd25519PIN(ctx context.Context, pin, pinTokenBase64, sessionId, priv
76
78
if err != nil {
77
79
return "" , err
78
80
}
79
- var dst , curve , pub [32 ]byte
80
- PrivateKeyToCurve25519 (& curve , private )
81
+ var keyBytes , curvePriv , pub [32 ]byte
82
+ PrivateKeyToCurve25519 (& curvePriv , private )
81
83
copy (pub [:], public [:])
82
- curve25519 .ScalarMult (& dst , & curve , & pub )
84
+ curve25519 .ScalarMult (& keyBytes , & curvePriv , & pub )
83
85
84
86
pinByte := []byte (pin )
85
87
timeBytes := make ([]byte , 8 )
@@ -91,7 +93,7 @@ func EncryptEd25519PIN(ctx context.Context, pin, pinTokenBase64, sessionId, priv
91
93
padding := aes .BlockSize - len (pinByte )% aes .BlockSize
92
94
padtext := bytes .Repeat ([]byte {byte (padding )}, padding )
93
95
pinByte = append (pinByte , padtext ... )
94
- block , err := aes .NewCipher (dst [:])
96
+ block , err := aes .NewCipher (keyBytes [:])
95
97
if err != nil {
96
98
return "" , err
97
99
}
@@ -158,3 +160,33 @@ func PrivateKeyToCurve25519(curve25519Private *[32]byte, privateKey ed25519.Priv
158
160
159
161
copy (curve25519Private [:], digest )
160
162
}
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