-
Notifications
You must be signed in to change notification settings - Fork 6
/
client.go
125 lines (108 loc) · 4.62 KB
/
client.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
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
package zkgroup
/*
#cgo LDFLAGS: ${SRCDIR}/lib/libzkgroup.a
#include "./lib/zkgroup.h"
*/
import "C"
import (
"encoding/binary"
"github.com/pkg/errors"
)
// ClientZkGroupCipher ...
type ClientZkGroupCipher struct {
groupSecretParams GroupSecretParams
}
// NewClientZkGroupCipher ...
func NewClientZkGroupCipher(groupSecretParams GroupSecretParams) *ClientZkGroupCipher {
return &ClientZkGroupCipher{groupSecretParams: groupSecretParams}
}
// EncryptBlob ...
func (c ClientZkGroupCipher) EncryptBlob(plaintext []byte) ([]byte, error) {
rand := randBytes(32)
return c.EncryptBlobDeterministic(rand, plaintext)
}
// EncryptBlobDeterministic ...
func (c ClientZkGroupCipher) EncryptBlobDeterministic(random []byte, plaintext []byte) ([]byte, error) {
paddedPlaintext := append([]byte{0x00, 0x00, 0x00, 0x00}, plaintext...)
ciphertext := make([]byte, len(paddedPlaintext)+29)
if res := C.FFI_GroupSecretParams_encryptBlobDeterministic(cBytes(c.groupSecretParams), cLen(c.groupSecretParams), cBytes(random), cLen(random), cBytes(paddedPlaintext), cLen(paddedPlaintext), cBytes(ciphertext), cLen(ciphertext)); res != C.FFI_RETURN_OK {
return nil, errFromCode(res)
}
return ciphertext, nil
}
// DecryptBlob ...
func (c ClientZkGroupCipher) DecryptBlob(ciphertext []byte) ([]byte, error) {
out := make([]byte, len(ciphertext)-29)
if res := C.FFI_GroupSecretParams_decryptBlob(cBytes(c.groupSecretParams), cLen(c.groupSecretParams), cBytes(ciphertext), cLen(ciphertext), cBytes(out), cLen(out)); res != C.FFI_RETURN_OK {
return nil, errFromCode(res)
}
if len(out) < 4 {
return nil, ErrVerificationFailed
}
padLenBytes := out[0:4]
padLen := int(binary.BigEndian.Uint32(padLenBytes))
if len(out) < (4 + padLen) {
return nil, ErrVerificationFailed
}
return out[4 : len(out)-padLen], nil
}
// EncryptUUID ...
func (c ClientZkGroupCipher) EncryptUUID(uuid UUID) ([]byte, error) {
if len(uuid) != C.UUID_LEN {
return nil, errors.Errorf("invalid uuid length")
}
ciphertext := make([]byte, C.UUID_CIPHERTEXT_LEN)
if res := C.FFI_GroupSecretParams_encryptUuid(cBytes(c.groupSecretParams), cLen(c.groupSecretParams), cBytes(uuid), cLen(uuid), cBytes(ciphertext), cLen(ciphertext)); res != C.FFI_RETURN_OK {
return nil, errFromCode(res)
}
return ciphertext, nil
}
// DecryptUUID ...
func (c ClientZkGroupCipher) DecryptUUID(ciphertext []byte) (UUID, error) {
uuid := make([]byte, C.UUID_LEN)
if res := C.FFI_GroupSecretParams_decryptUuid(cBytes(c.groupSecretParams), cLen(c.groupSecretParams), cBytes(ciphertext), cLen(ciphertext), cBytes(uuid), cLen(uuid)); res != C.FFI_RETURN_OK {
return nil, errFromCode(res)
}
return uuid, nil
}
// ClientZkAuthOperations ...
type ClientZkAuthOperations struct {
serverPublicParams ServerPublicParams
}
// NewClientZkAuthOperations ...
func NewClientZkAuthOperations(serverPublicParams ServerPublicParams) (*ClientZkAuthOperations, error) {
if serverPublicParams == nil {
return nil, errors.Errorf("empty server public params")
}
return &ClientZkAuthOperations{serverPublicParams: serverPublicParams}, nil
}
// ReceiveAuthCredential ...
func (c ClientZkAuthOperations) ReceiveAuthCredential(uuid UUID, redemptionTime uint32, authCredentialResponse AuthCredentialResponse) (AuthCredential, error) {
out := make([]byte, C.AUTH_CREDENTIAL_LEN)
if res := C.FFI_ServerPublicParams_receiveAuthCredential(
cBytes(c.serverPublicParams), cLen(c.serverPublicParams),
cBytes(uuid), cLen(uuid),
C.uint32_t(redemptionTime),
cBytes(authCredentialResponse), cLen(authCredentialResponse),
cBytes(out), cLen(out)); res != C.FFI_RETURN_OK {
return nil, errFromCode(res)
}
return AuthCredential(out), nil
}
// CreateAuthCredentialPresentation ...
func (c ClientZkAuthOperations) CreateAuthCredentialPresentation(groupSecretParams GroupSecretParams, authCredential AuthCredential) (AuthCredentialPresentation, error) {
return c.CreateAuthCredentialPresentationDeterministic(randBytes(32), groupSecretParams, authCredential)
}
// CreateAuthCredentialPresentationDeterministic ...
func (c ClientZkAuthOperations) CreateAuthCredentialPresentationDeterministic(random []byte, groupSecretParams GroupSecretParams, authCredential AuthCredential) (AuthCredentialPresentation, error) {
out := make([]byte, C.AUTH_CREDENTIAL_PRESENTATION_LEN)
if res := C.FFI_ServerPublicParams_createAuthCredentialPresentationDeterministic(
cBytes(c.serverPublicParams), cLen(c.serverPublicParams),
cBytes(random), cLen(random),
cBytes(groupSecretParams), cLen(groupSecretParams),
cBytes(authCredential), cLen(authCredential),
cBytes(out), cLen(out)); res != C.FFI_RETURN_OK {
return nil, errFromCode(res)
}
return AuthCredentialPresentation(out), nil
}