forked from elastic/logstash-forwarder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
session.go
76 lines (63 loc) · 2.41 KB
/
session.go
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
package sodium
// #include <sodium.h>
// #cgo pkg-config: sodium
import "C"
import "unsafe"
import "fmt"
type Session struct {
// the public key of the agent who is sending you encrypted messages
Public [PUBLICKEYBYTES]byte
// your secret key
Secret [SECRETKEYBYTES]byte
// for beforenm/afternm optimization
k [crypto_box_BEFORENMBYTES]byte
// The nonce generator.
Nonce func() []byte
}
func NewSession(pk [PUBLICKEYBYTES]byte, sk [SECRETKEYBYTES]byte) (s *Session){
s = new(Session)
s.Public = pk
s.Secret = sk
s.Precompute()
s.Nonce = RandomNonceStrategy()
//s.Nonce = IncrementalNonceStrategy()
return s
}
func (s *Session) Precompute() {
C.crypto_box_curve25519xsalsa20poly1305_ref_beforenm(
(*C.uchar)(unsafe.Pointer(&s.k[0])),
(*C.uchar)(unsafe.Pointer(&s.Public[0])),
(*C.uchar)(unsafe.Pointer(&s.Secret[0])))
}
func (s *Session) Box(plaintext []byte) (ciphertext []byte, nonce []byte) {
// XXX: ciphertext needs to be zero-padded at the start for crypto_box_ZEROBYTES
// ZEROBYTES + len(plaintext) is ciphertext length
ciphertext = make([]byte, crypto_box_ZEROBYTES + len(plaintext))
nonce = s.Nonce()
m := make([]byte, crypto_box_ZEROBYTES + len(plaintext))
copy(m[crypto_box_ZEROBYTES:], plaintext)
C.crypto_box_curve25519xsalsa20poly1305_ref_afternm(
(*C.uchar)(unsafe.Pointer(&ciphertext[0])),
(*C.uchar)(unsafe.Pointer(&m[0])), (C.ulonglong)(len(m)),
(*C.uchar)(unsafe.Pointer(&nonce[0])),
(*C.uchar)(unsafe.Pointer(&s.k[0])))
//fmt.Printf("ciphertext: %v\n", ciphertext)
//fmt.Printf("ciphertext2: %v\n", ciphertext[crypto_box_BOXZEROBYTES:])
return ciphertext[crypto_box_BOXZEROBYTES:], nonce[:]
}
func (s *Session) Open(nonce []byte, ciphertext []byte) ([]byte) {
// This function assumes the verbatim []byte given by Session.Box() is passed
m := make([]byte, crypto_box_BOXZEROBYTES + len(ciphertext))
copy(m[crypto_box_BOXZEROBYTES:], ciphertext)
plaintext := make([]byte, len(m))
if len(nonce) != crypto_box_NONCEBYTES {
panic(fmt.Sprintf("Invalid nonce length (%d). Expected %d\n",
len(nonce), crypto_box_NONCEBYTES))
}
C.crypto_box_curve25519xsalsa20poly1305_ref_open_afternm(
(*C.uchar)(unsafe.Pointer(&plaintext[0])),
(*C.uchar)(unsafe.Pointer(&m[0])), (C.ulonglong)(len(m)),
(*C.uchar)(unsafe.Pointer(&nonce[0])),
(*C.uchar)(unsafe.Pointer(&s.k[0])))
return plaintext[crypto_box_ZEROBYTES:]
}