-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathx25519_test.go
More file actions
151 lines (126 loc) · 4.09 KB
/
Copy pathx25519_test.go
File metadata and controls
151 lines (126 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package x25519_test
import (
"strings"
"testing"
"github.com/fil-forge/ucantone/did"
"github.com/fil-forge/ucantone/multikey/ed25519"
"github.com/fil-forge/ucantone/multikey/x25519"
"github.com/stretchr/testify/require"
)
func TestGenerate(t *testing.T) {
k, err := x25519.Generate()
require.NoError(t, err)
require.Len(t, k.Raw(), x25519.KeySize)
require.Len(t, k.Public().Raw(), x25519.KeySize)
// Two independent keypairs differ.
k2, err := x25519.Generate()
require.NoError(t, err)
require.NotEqual(t, k.Raw(), k2.Raw())
}
func TestPrivateKeyRoundTrip(t *testing.T) {
k, err := x25519.Generate()
require.NoError(t, err)
t.Run("tagged bytes carry the x25519-priv code", func(t *testing.T) {
b := k.Bytes()
// 2-byte varint for 0x1302 + 32 raw bytes.
require.Len(t, b, 34)
decoded, err := x25519.Decode(b)
require.NoError(t, err)
require.Equal(t, k.Raw(), decoded.Raw())
})
t.Run("FromRaw", func(t *testing.T) {
decoded, err := x25519.FromRaw(k.Raw())
require.NoError(t, err)
require.Equal(t, k.Bytes(), decoded.Bytes())
})
t.Run("Parse(String())", func(t *testing.T) {
decoded, err := x25519.Parse(k.String())
require.NoError(t, err)
require.Equal(t, k.Raw(), decoded.Raw())
})
t.Run("Decode rejects the wrong key type", func(t *testing.T) {
// An ed25519 private key is multiformat-tagged with a different code.
signer, err := ed25519.Generate()
require.NoError(t, err)
_, err = x25519.Decode(signer.Bytes())
require.Error(t, err)
})
t.Run("FromRaw rejects the wrong length", func(t *testing.T) {
_, err := x25519.FromRaw([]byte{1, 2, 3})
require.Error(t, err)
})
}
func TestPublicKeyRoundTrip(t *testing.T) {
k, err := x25519.Generate()
require.NoError(t, err)
pub := k.Public()
t.Run("tagged bytes carry the x25519-pub code", func(t *testing.T) {
b := pub.Bytes()
require.Len(t, b, 34)
decoded, err := x25519.DecodePublic(b)
require.NoError(t, err)
require.Equal(t, pub.Raw(), decoded.Raw())
})
t.Run("PublicFromRaw", func(t *testing.T) {
decoded, err := x25519.PublicFromRaw(pub.Raw())
require.NoError(t, err)
require.Equal(t, pub.Bytes(), decoded.Bytes())
})
t.Run("ParsePublic(String())", func(t *testing.T) {
decoded, err := x25519.ParsePublic(pub.String())
require.NoError(t, err)
require.Equal(t, pub.Raw(), decoded.Raw())
})
t.Run("DecodePublic rejects the wrong key type", func(t *testing.T) {
// Tagged private bytes have the x25519-priv code, not x25519-pub.
_, err := x25519.DecodePublic(k.Bytes())
require.Error(t, err)
})
}
func TestKeyDID(t *testing.T) {
k, err := x25519.Generate()
require.NoError(t, err)
d := k.KeyDID()
require.Equal(t, "key", d.Method())
// X25519 did:key identifiers (x25519-pub, base58btc) begin "z6LS".
require.True(t, strings.HasPrefix(d.String(), "did:key:z6LS"),
"unexpected did:key prefix: %s", d.String())
t.Run("ParsePublicKeyDID round trips", func(t *testing.T) {
pub, err := x25519.ParsePublicKeyDID(d)
require.NoError(t, err)
require.Equal(t, k.Public().Raw(), pub.Raw())
})
t.Run("ParsePublicKeyDID rejects a non-key DID", func(t *testing.T) {
_, err := x25519.ParsePublicKeyDID(did.New("plc", "abc123"))
require.Error(t, err)
})
t.Run("ParsePublicKeyDID rejects an ed25519 did:key", func(t *testing.T) {
signer, err := ed25519.Generate()
require.NoError(t, err)
_, err = x25519.ParsePublicKeyDID(signer.KeyDID())
require.Error(t, err)
})
}
func TestECDH(t *testing.T) {
alice, err := x25519.Generate()
require.NoError(t, err)
bob, err := x25519.Generate()
require.NoError(t, err)
t.Run("both parties derive the same shared secret", func(t *testing.T) {
ab, err := alice.ECDH(bob.Public())
require.NoError(t, err)
ba, err := bob.ECDH(alice.Public())
require.NoError(t, err)
require.NotEmpty(t, ab)
require.Equal(t, ab, ba)
})
t.Run("a public key recovered from its DID agrees too", func(t *testing.T) {
bobPub, err := x25519.ParsePublicKeyDID(bob.KeyDID())
require.NoError(t, err)
viaDID, err := alice.ECDH(bobPub)
require.NoError(t, err)
direct, err := alice.ECDH(bob.Public())
require.NoError(t, err)
require.Equal(t, direct, viaDID)
})
}