This repository has been archived by the owner on Apr 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wrapper for signing credentials as well as generating a proof. Includ…
…es a refactor of some existing methods to match a pattern to encapsulate the `unsafe.Pointer` handles from callers. (#25) Signed-off-by: Phil Feairheller <[email protected]>
- Loading branch information
1 parent
1be50fe
commit d1d4d04
Showing
10 changed files
with
1,483 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package ursa | ||
|
||
import ( | ||
"encoding/json" | ||
"math/big" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestCredentialDefinition(t *testing.T) { | ||
t.Run("happy path", func(t *testing.T) { | ||
fields := []string{"attr1", "attr2", "attr3"} | ||
var nonfields []string | ||
|
||
credDef := createCredentialDefinition(t, fields, nonfields) | ||
|
||
pubKeyJSON, err := credDef.PubKey.ToJSON() | ||
assert.NoError(t, err) | ||
m := map[string]interface{}{} | ||
err = json.Unmarshal(pubKeyJSON, &m) | ||
assert.NoError(t, err) | ||
|
||
pkey, ok := m["p_key"].(map[string]interface{}) | ||
assert.True(t, ok) | ||
|
||
r, ok := pkey["r"].(map[string]interface{}) | ||
assert.True(t, ok) | ||
|
||
for _, field := range fields { | ||
x, ok := r[field].(string) | ||
assert.True(t, ok) | ||
i := new(big.Int) | ||
_, ok = i.SetString(x, 10) | ||
assert.True(t, ok) | ||
} | ||
|
||
privKeyJSON, err := credDef.PrivKey.ToJSON() | ||
assert.NoError(t, err) | ||
assert.NotEmpty(t, privKeyJSON) | ||
|
||
correctnessJSON, err := credDef.PubKey.ToJSON() | ||
assert.NoError(t, err) | ||
|
||
m = map[string]interface{}{} | ||
err = json.Unmarshal(correctnessJSON, &m) | ||
assert.NoError(t, err) | ||
|
||
pkey, ok = m["p_key"].(map[string]interface{}) | ||
assert.True(t, ok) | ||
|
||
r, ok = pkey["r"].(map[string]interface{}) | ||
assert.True(t, ok) | ||
|
||
for _, field := range fields { | ||
x, ok := r[field].(string) | ||
assert.True(t, ok) | ||
i := new(big.Int) | ||
_, ok = i.SetString(x, 10) | ||
assert.True(t, ok) | ||
} | ||
|
||
err = credDef.PubKey.Free() | ||
assert.NoError(t, err) | ||
|
||
err = credDef.PrivKey.Free() | ||
assert.NoError(t, err) | ||
|
||
err = credDef.KeyCorrectnessProof.Free() | ||
assert.NoError(t, err) | ||
}) | ||
} | ||
|
||
func createCredentialDefinition(t *testing.T, fields, nonfields []string) *CredentialDef { | ||
|
||
fields = append(fields, "master_secret") | ||
|
||
schema := createSchema(t, fields) | ||
|
||
nonschema := createNonSchema(t, nonfields) | ||
|
||
credDef, err := NewCredentialDef(schema, nonschema, false) | ||
assert.NoError(t, err) | ||
|
||
return credDef | ||
} | ||
|
||
func createSchema(t *testing.T, fields []string) *CredentialSchemaHandle { | ||
schemaBuilder, err := NewCredentialSchemaBuilder() | ||
assert.NoError(t, err) | ||
|
||
for _, field := range fields { | ||
err = schemaBuilder.AddAttr(field) | ||
assert.NoError(t, err) | ||
} | ||
|
||
schema, err := schemaBuilder.Finalize() | ||
assert.NoError(t, err) | ||
|
||
return schema | ||
} | ||
|
||
func createNonSchema(t *testing.T, fields []string) *NonCredentialSchemaHandle { | ||
nonSchemaBuilder, err := NewNonCredentialSchemaBuilder() | ||
assert.NoError(t, err) | ||
|
||
for _, field := range fields { | ||
err = nonSchemaBuilder.AddAttr(field) | ||
assert.NoError(t, err) | ||
} | ||
|
||
nonSchema, err := nonSchemaBuilder.Finalize() | ||
assert.NoError(t, err) | ||
|
||
return nonSchema | ||
} | ||
|
||
func createValues(t *testing.T, values map[string]interface{}) *CredentialValues { | ||
builder, err := NewValueBuilder() | ||
assert.NoError(t, err) | ||
|
||
for k, v := range values { | ||
err = builder.AddDecKnown(k, EncodeValue(v)) | ||
assert.NoError(t, err) | ||
} | ||
|
||
value, err := builder.Finalize() | ||
assert.NoError(t, err) | ||
|
||
return value | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package ursa | ||
|
||
/* | ||
#cgo LDFLAGS: -lursa | ||
#include "ursa_cl.h" | ||
#include <stdlib.h> | ||
*/ | ||
import "C" | ||
import ( | ||
"unsafe" | ||
) | ||
|
||
type MasterSecret Handle | ||
|
||
func NewMasterSecret() (*MasterSecret, error) { | ||
var ms unsafe.Pointer | ||
|
||
result := C.ursa_cl_prover_new_master_secret(&ms) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return &MasterSecret{ms}, nil | ||
} | ||
|
||
//MasterSecretFromJson creates and returns nonce json | ||
func MasterSecretFromJSON(jsn []byte) (*MasterSecret, error) { | ||
var handle unsafe.Pointer | ||
cjson := C.CString(string(jsn)) | ||
defer C.free(unsafe.Pointer(cjson)) | ||
|
||
result := C.ursa_cl_master_secret_from_json(cjson, &handle) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return &MasterSecret{handle}, nil | ||
} | ||
|
||
func (r *MasterSecret) ToJSON() ([]byte, error) { | ||
var d *C.char | ||
defer C.free(unsafe.Pointer(d)) | ||
|
||
result := C.ursa_cl_master_secret_to_json(r.ptr, &d) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
out := []byte(C.GoString(d)) | ||
return out, nil | ||
} | ||
|
||
func (r *MasterSecret) Free() error { | ||
result := C.ursa_cl_master_secret_free(r.ptr) | ||
if result.code != 0 { | ||
return ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package ursa | ||
|
||
import ( | ||
"encoding/json" | ||
"math/big" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestMasterSecret(t *testing.T) { | ||
t.Run("happy path", func(t *testing.T) { | ||
ms, err := NewMasterSecret() | ||
assert.NoError(t, err) | ||
|
||
js, err := ms.ToJSON() | ||
assert.NoError(t, err) | ||
|
||
m := struct { | ||
MasterSecret string `json:"ms"` | ||
}{} | ||
err = json.Unmarshal(js, &m) | ||
assert.NoError(t, err) | ||
|
||
i := new(big.Int) | ||
_, ok := i.SetString(m.MasterSecret, 10) | ||
assert.True(t, ok) | ||
|
||
ms, err = MasterSecretFromJSON(js) | ||
assert.NoError(t, err) | ||
assert.NotEmpty(t, ms) | ||
|
||
err = ms.Free() | ||
assert.NoError(t, err) | ||
}) | ||
|
||
t.Run("bad json", func(t *testing.T) { | ||
ms, err := MasterSecretFromJSON([]byte(`{"t": "123"}`)) | ||
assert.Error(t, err) | ||
assert.Empty(t, ms) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package ursa | ||
|
||
/* | ||
#cgo LDFLAGS: -lursa | ||
#include "ursa_cl.h" | ||
#include <stdlib.h> | ||
*/ | ||
import "C" | ||
import ( | ||
"unsafe" | ||
) | ||
|
||
type ProofBuilder Handle | ||
type ProofHandle Handle | ||
|
||
func NewProofBuilder() (*ProofBuilder, error) { | ||
var builder unsafe.Pointer | ||
|
||
result := C.ursa_cl_prover_new_proof_builder(&builder) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return &ProofBuilder{builder}, nil | ||
} | ||
|
||
func ProofFromJSON(jsn []byte) (*ProofHandle, error) { | ||
var builder unsafe.Pointer | ||
cjson := C.CString(string(jsn)) | ||
defer C.free(unsafe.Pointer(cjson)) | ||
|
||
result := C.ursa_cl_proof_from_json(cjson, &builder) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return &ProofHandle{builder}, nil | ||
} | ||
|
||
func (r *ProofBuilder) AddCommonAttribute(attr string) error { | ||
cattr := C.CString(attr) | ||
defer C.free(unsafe.Pointer(cattr)) | ||
|
||
result := C.ursa_cl_proof_builder_add_common_attribute(r.ptr, cattr) | ||
if result.code != 0 { | ||
return ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (r *ProofBuilder) AddSubProofRequest(subProof *SubProofRequestHandle, credSchema *CredentialSchemaHandle, | ||
nonCredSchema *NonCredentialSchemaHandle, signature *CredentialSignature, values *CredentialValues, pubKey *CredentialDefPubKey) error { | ||
|
||
result := C.ursa_cl_proof_builder_add_sub_proof_request(r.ptr, subProof.ptr, credSchema.ptr, nonCredSchema.ptr, | ||
signature.ptr, values.ptr, pubKey.ptr /*revoc_reg*/, nil /*witness*/, nil) | ||
if result.code != 0 { | ||
return ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (r *ProofBuilder) Finalize(nonce *Nonce) (*ProofHandle, error) { | ||
var proof unsafe.Pointer | ||
|
||
result := C.ursa_cl_proof_builder_finalize(r.ptr, nonce.ptr, &proof) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return &ProofHandle{proof}, nil | ||
} | ||
|
||
func (r *ProofHandle) ToJSON() ([]byte, error) { | ||
var d *C.char | ||
defer C.free(unsafe.Pointer(d)) | ||
|
||
result := C.ursa_cl_proof_to_json(r.ptr, &d) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return []byte(C.GoString(d)), nil | ||
} | ||
|
||
func (r *ProofHandle) Free() error { | ||
result := C.ursa_cl_proof_free(r.ptr) | ||
if result.code != 0 { | ||
return ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
type SubProofRequestBuilder Handle | ||
type SubProofRequestHandle Handle | ||
|
||
func NewSubProofRequestBuilder() (*SubProofRequestBuilder, error) { | ||
var builder unsafe.Pointer | ||
|
||
result := C.ursa_cl_sub_proof_request_builder_new(&builder) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return &SubProofRequestBuilder{builder}, nil | ||
|
||
} | ||
|
||
func (r *SubProofRequestBuilder) AddPredicate(attr, ptype string, value int32) error { | ||
cattr := C.CString(attr) | ||
defer C.free(unsafe.Pointer(cattr)) | ||
cptype := C.CString(ptype) | ||
defer C.free(unsafe.Pointer(cptype)) | ||
|
||
result := C.ursa_cl_sub_proof_request_builder_add_predicate(r.ptr, cattr, cptype, C.int32_t(value)) | ||
if result.code != 0 { | ||
return ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (r *SubProofRequestBuilder) AddRevealedAttr(attr string) error { | ||
cattr := C.CString(attr) | ||
defer C.free(unsafe.Pointer(cattr)) | ||
|
||
result := C.ursa_cl_sub_proof_request_builder_add_revealed_attr(r.ptr, cattr) | ||
if result.code != 0 { | ||
return ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (r *SubProofRequestBuilder) Finalize() (*SubProofRequestHandle, error) { | ||
var proof unsafe.Pointer | ||
|
||
result := C.ursa_cl_sub_proof_request_builder_finalize(r.ptr, &proof) | ||
if result.code != 0 { | ||
return nil, ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return &SubProofRequestHandle{proof}, nil | ||
} | ||
|
||
func (r *SubProofRequestHandle) Free() error { | ||
result := C.ursa_cl_sub_proof_request_free(r.ptr) | ||
if result.code != 0 { | ||
return ursaError(C.GoString(result.message)) | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.