-
Notifications
You must be signed in to change notification settings - Fork 0
/
asymmetric.go
76 lines (60 loc) · 1.78 KB
/
asymmetric.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 asymmetric
import (
"crypto/rand"
"crypto/subtle"
"errors"
"github.com/D3vl0per/crypt/generic"
"golang.org/x/crypto/nacl/box"
)
///
/// NaCl Box Suite
///
const (
BoxKeySize = 32
BoxNonceSize = 24
)
type keypairs struct {
PK []byte
SK []byte
}
//nolint:golint
func GenerateBoxKeypair() (keypairs, error) {
pk, sk, err := box.GenerateKey(rand.Reader)
if err != nil {
return keypairs{}, nil
}
return keypairs{
PK: pk[:],
SK: sk[:],
}, nil
}
func EncryptBox(senderSK, recipientPK, plaintext []byte) ([]byte, error) {
var recipientPublicKey [BoxKeySize]byte
subtle.ConstantTimeCopy(1, recipientPublicKey[:], recipientPK)
var senderSecretKey [BoxKeySize]byte
subtle.ConstantTimeCopy(1, senderSecretKey[:], senderSK)
sharedEncryptKey := new([BoxKeySize]byte)
box.Precompute(sharedEncryptKey, &recipientPublicKey, &senderSecretKey)
nonceRaw, err := generic.CSPRNG(BoxNonceSize)
if err != nil {
return nil, err
}
var nonce [BoxNonceSize]byte
subtle.ConstantTimeCopy(1, nonce[:], nonceRaw)
return box.SealAfterPrecomputation(nonce[:], plaintext, &nonce, sharedEncryptKey), nil
}
func DecryptBox(senderPK, recipientSK, ciphertext []byte) ([]byte, error) {
var senderPublicKey [BoxKeySize]byte
subtle.ConstantTimeCopy(1, senderPublicKey[:], senderPK)
var recipientSecretKey [BoxKeySize]byte
subtle.ConstantTimeCopy(1, recipientSecretKey[:], recipientSK)
var sharedDecryptKey [BoxKeySize]byte
box.Precompute(&sharedDecryptKey, &senderPublicKey, &recipientSecretKey)
var decryptNonce [BoxNonceSize]byte
subtle.ConstantTimeCopy(1, decryptNonce[:], ciphertext[:BoxNonceSize])
decrypted, ok := box.OpenAfterPrecomputation(nil, ciphertext[BoxNonceSize:], &decryptNonce, &sharedDecryptKey)
if !ok {
return nil, errors.New("decryption error")
}
return decrypted, nil
}