Skip to content

Commit ba4580b

Browse files
committed
v1.0.12
1 parent 77c88c9 commit ba4580b

File tree

5 files changed

+181
-38
lines changed

5 files changed

+181
-38
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Following functions included:
2222
- `crypto_pwhash_opslimit_sensitive` `crypto_pwhash_memlimit_sensitive`
2323
- `crypto_shorthash` `crypto_generichash_init` `crypto_generichash_update` `crypto_generichash_final`
2424
- `crypto_kdf_keygen` `crypto_kdf_derive_from_key`
25+
- `crypto_kx_keypair` `crypto_kx_seed_keypair` `crypto_kx_server_session_keys` `crypto_kx_client_session_keys`
2526
- `crypto_aead_chacha20poly1305_ietf_encrypt` `crypto_aead_chacha20poly1305_ietf_decrypt` `crypto_aead_chacha20poly1305_ietf_encrypt_detached` `crypto_aead_chacha20poly1305_ietf_decrypt_detached`
2627
- `sodium_memzero` `sodium_memcmp` `sodium_increment`
2728

box.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,6 @@ func (k BoxPublicKey) Size() int {
2727
return cryptoBoxPublicKeyBytes
2828
}
2929

30-
type CommonKey struct {
31-
Bytes
32-
}
33-
34-
func (k CommonKey) Size() int {
35-
return cryptoScalarmultBytes
36-
}
37-
3830
type BoxSecretKey struct {
3931
Bytes
4032
}
@@ -50,13 +42,6 @@ func (k BoxSecretKey) PublicKey() BoxPublicKey {
5042
return BoxPublicKey(CryptoScalarmultBase(Scalar(k)))
5143
}
5244

53-
//CommonKey calculates common key from BoxSecretKey and other's BoxPublicKey.
54-
func (k BoxSecretKey) CommonKey(p BoxPublicKey) CommonKey {
55-
checkTypedSize(&p, "PublicKey")
56-
57-
return CommonKey(CryptoScalarmult(Scalar(k), Scalar(p)))
58-
}
59-
6045
type BoxSeed struct {
6146
Bytes
6247
}

exchange.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package sodium
2+
3+
// #cgo pkg-config: libsodium
4+
// #include <stdlib.h>
5+
// #include <sodium.h>
6+
import "C"
7+
8+
var (
9+
cryptoKXPublicKeyBytes = int(C.crypto_kx_publickeybytes())
10+
cryptoKXSecretKeyBytes = int(C.crypto_kx_secretkeybytes())
11+
cryptoKXSeedBytes = int(C.crypto_kx_seedbytes())
12+
cryptoKXSessionKeyBytes = int(C.crypto_kx_sessionkeybytes())
13+
)
14+
15+
type KXKP struct {
16+
PublicKey KXPublicKey
17+
SecretKey KXSecretKey
18+
}
19+
20+
//MakeKXKP generates a keypair for signing
21+
func MakeKXKP() KXKP {
22+
pkb := make([]byte, cryptoKXPublicKeyBytes)
23+
skb := make([]byte, cryptoKXSecretKeyBytes)
24+
if int(C.crypto_kx_keypair(
25+
(*C.uchar)(&pkb[0]),
26+
(*C.uchar)(&skb[0]))) != 0 {
27+
panic("see libsodium")
28+
}
29+
30+
return KXKP{
31+
KXPublicKey{pkb},
32+
KXSecretKey{skb},
33+
}
34+
}
35+
36+
//SeedKXKP generates a keypair for exchanging from a KXSeed.
37+
//
38+
//The same pair of keys will be generated with the same 'seed'
39+
func SeedKXKP(seed KXSeed) KXKP {
40+
checkTypedSize(&seed, "seed")
41+
pkb := make([]byte, cryptoKXPublicKeyBytes)
42+
skb := make([]byte, cryptoKXSecretKeyBytes)
43+
if int(C.crypto_kx_seed_keypair(
44+
(*C.uchar)(&pkb[0]),
45+
(*C.uchar)(&skb[0]),
46+
(*C.uchar)(&seed.Bytes[0]))) != 0 {
47+
panic("see libsodium")
48+
}
49+
50+
return KXKP{
51+
KXPublicKey{pkb},
52+
KXSecretKey{skb},
53+
}
54+
}
55+
56+
// ClientSessionKeys calculates Rx (for receving) and Tx (for sending) session keys
57+
// with server's public key.
58+
// return error when server_pk is not acceptable.
59+
func (kp KXKP) ClientSessionKeys(server_pk KXPublicKey) (*KXSessionKeys, error) {
60+
checkTypedSize(&kp.PublicKey, "Client Public Key")
61+
checkTypedSize(&kp.SecretKey, "Client Secret Key")
62+
checkTypedSize(&server_pk, "Server Public Key")
63+
64+
rxb := make([]byte, cryptoKXSessionKeyBytes)
65+
txb := make([]byte, cryptoKXSessionKeyBytes)
66+
if int(C.crypto_kx_client_session_keys(
67+
(*C.uchar)(&rxb[0]),
68+
(*C.uchar)(&txb[0]),
69+
(*C.uchar)(&kp.PublicKey.Bytes[0]),
70+
(*C.uchar)(&kp.SecretKey.Bytes[0]),
71+
(*C.uchar)(&server_pk.Bytes[0]))) != 0 {
72+
return nil, ErrInvalidKey
73+
}
74+
75+
return &KXSessionKeys{
76+
Rx: KXSessionKey{rxb},
77+
Tx: KXSessionKey{txb},
78+
}, nil
79+
}
80+
81+
// ServerSessionKeys calculates Rx (for receving) and Tx (for sending) session keys
82+
// with client's public key.
83+
// return error when client_pk is not acceptable.
84+
func (kp KXKP) ServerSessionKeys(client_pk KXPublicKey) (*KXSessionKeys, error) {
85+
checkTypedSize(&kp.PublicKey, "Server Public Key")
86+
checkTypedSize(&kp.SecretKey, "Server Secret Key")
87+
checkTypedSize(&client_pk, "Client Public Key")
88+
89+
rxb := make([]byte, cryptoKXSessionKeyBytes)
90+
txb := make([]byte, cryptoKXSessionKeyBytes)
91+
if int(C.crypto_kx_server_session_keys(
92+
(*C.uchar)(&rxb[0]),
93+
(*C.uchar)(&txb[0]),
94+
(*C.uchar)(&kp.PublicKey.Bytes[0]),
95+
(*C.uchar)(&kp.SecretKey.Bytes[0]),
96+
(*C.uchar)(&client_pk.Bytes[0]))) != 0 {
97+
return nil, ErrInvalidKey
98+
}
99+
100+
return &KXSessionKeys{
101+
Rx: KXSessionKey{rxb},
102+
Tx: KXSessionKey{txb},
103+
}, nil
104+
}
105+
106+
type KXSessionKeys struct {
107+
Rx KXSessionKey
108+
Tx KXSessionKey
109+
}
110+
111+
type KXPublicKey struct {
112+
Bytes
113+
}
114+
115+
func (k KXPublicKey) Size() int {
116+
return cryptoKXPublicKeyBytes
117+
}
118+
119+
type KXSecretKey struct {
120+
Bytes
121+
}
122+
123+
func (k KXSecretKey) Size() int {
124+
return cryptoKXSecretKeyBytes
125+
}
126+
127+
type KXSessionKey struct {
128+
Bytes
129+
}
130+
131+
func (k KXSessionKey) Size() int {
132+
return cryptoKXSessionKeyBytes
133+
}
134+
135+
type KXSeed struct {
136+
Bytes
137+
}
138+
139+
func (k KXSeed) Size() int {
140+
return cryptoKXSeedBytes
141+
}

sodium.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,25 +86,32 @@
8686
//
8787
//(X25519-XSalsa20-Poly1305)
8888
//
89-
//Diffie-Hellman Key Exchange
89+
//Key Exchanging
9090
//
91-
//BoxPublicKey can be calculated from BoxSecretKey:
91+
//Server and Client exchange their public key and calculates a common session key with their own
92+
//secret key.
9293
//
93-
// //High-level function should be used most of the time.
94-
// func (k BoxSecretKey) PublicKey() BoxPublicKey
95-
//
96-
// //Low-level function:
97-
// func CryptoScalarmultBase(n Scalar) (q Scalar)
94+
// type KXKP struct {
95+
// PublicKey KXPublicKey
96+
// SecretKey KXSecretKey
97+
// }
98+
// func MakeKXKP() KXKP
99+
// func SeedKXKP(seed KXSeed) KXKP
98100
//
99-
//A CommonKey can be calculated from BoxSecretKey and other's BoxPublicKey:
101+
// type KXSessionKeys struct {
102+
// Rx KXSessionKey
103+
// Tx KXSessionKey
104+
// }
100105
//
101-
// //High-level function should be used most of the time.
102-
// func (k BoxSecretKey) CommonKey(p BoxPublicKey) CommonKey
106+
// // session keys for client
107+
// func (kp KXKP) ClientSessionKeys(server_pk KXPublicKey) (*KXSessionKeys, error)
103108
//
104-
// //Low-level function.
105-
// func CryptoScalarmult(n, p Scalar) (q ScalarMult)
109+
// // session keys for server
110+
// func (kp KXKP) ServerSessionKeys(client_pk KXPublicKey) (*KXSessionKeys, error) {
111+
// // client's rx == server's tx
112+
// // client's tx == server's rx
106113
//
107-
//(X25519)
114+
//(rx || tx = BLAKE2B-512(p.n || client_pk || server_pk))
108115
//
109116
//Secret Key Authentication
110117
//
@@ -176,6 +183,7 @@ var (
176183
ErrOpenSign = errors.New("sodium: Signature forged")
177184
ErrDecryptAEAD = errors.New("sodium: Can't decrypt message")
178185
ErrPassword = errors.New("sodium: Password not matched")
186+
ErrInvalidKey = errors.New("sodium: Invalid key")
179187
)
180188

181189
//Typed has pre-defined size.

sodium_test.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,6 @@ func ExampleBoxSecretKey_PublicKey() {
143143
//Output: true
144144
}
145145

146-
func ExampleBoxSecretKey_CommonKey() {
147-
skp := MakeBoxKP()
148-
rkp := MakeBoxKP()
149-
sck := skp.SecretKey.CommonKey(rkp.PublicKey)
150-
rck := rkp.SecretKey.CommonKey(skp.PublicKey)
151-
152-
fmt.Println(MemCmp(sck.Bytes, rck.Bytes, sck.Length()) == 0)
153-
//Output: true
154-
}
155-
156146
func ExampleNewGenericHashKeyed() {
157147
kp := MakeBoxKP()
158148
key := GenericHashKey{kp.SecretKey.Bytes}
@@ -336,3 +326,21 @@ func ExampleMasterKey_Derive() {
336326
//Output: testblab
337327
//true
338328
}
329+
330+
func ExampleMakeKXKP() {
331+
skp := MakeKXKP()
332+
ckp := MakeKXKP()
333+
334+
sss, _ := skp.ServerSessionKeys(ckp.PublicKey)
335+
css, _ := ckp.ClientSessionKeys(skp.PublicKey)
336+
337+
fmt.Println(MemCmp(sss.Tx.Bytes, css.Rx.Bytes, sss.Tx.Size()) == 0)
338+
fmt.Println(MemCmp(sss.Rx.Bytes, css.Tx.Bytes, sss.Rx.Size()) == 0)
339+
340+
fmt.Println(MemCmp(sss.Tx.Bytes, sss.Rx.Bytes, sss.Tx.Size()) == 0)
341+
fmt.Println(MemCmp(css.Tx.Bytes, css.Rx.Bytes, css.Tx.Size()) == 0)
342+
//Output: true
343+
//true
344+
//false
345+
//false
346+
}

0 commit comments

Comments
 (0)