xlab-si / emmy Goto Github PK
View Code? Open in Web Editor NEWLibrary for zero-knowledge proof based applications (like anonymous credentials)
License: Apache License 2.0
Library for zero-knowledge proof based applications (like anonymous credentials)
License: Apache License 2.0
Currently emmy Client is implemented as follows:
type Client struct {
id int32
conn *grpc.ClientConn
client *pb.ProtocolClient
stream pb.Protocol_RunClient
schema pb.SchemaType // int32
variant pb.SchemaVariant
handler *ClientHandler
}
func (c *Client) Pedersen(dlog *dlog.ZpDLog, val big.Int) error {
c.handler.pedersenCommitter = commitments.NewPedersenCommitter(dlog)
... // c.handler.pedersenCommitter is used
}
func (c *Client) Schnorr(protocolType common.ProtocolType, dlog *dlog.ZpDLog, secret big.Int) error {
c.handler.schnorrProver = dlogproofs.NewSchnorrProver(dlog, protocolType)
... // c.handler.schnorrProver is used
}
So example has to be started like this:
genClient := getGenericClient(endpoint, example)
genClient.ExecuteProtocol(protocolParams) // decides whether c.Pedersen() whether c.Schnorr() is run
What bothers me is that such an approach is hard to read. Also, when adding support for new schema, one has to modify everything: the Client struct (hook additional function), the ClientHandler struct (store additional Commiter) and the ExecuteProtocol() function (additional case).
What if Client was an interface:
type Client interface{
ExecuteProtocol()
}
and we implement it for each schema we provide:
type PedersenClient struct{}
func (c *PedersenClient) ExecuteProtocol(){
// bouncing protocol is run
}
type SchnorrClient struct{}
func (c *SchnorrClient) ExecuteProtocol(){
// bouncing protocol is run
}
All we had to do to start emmy client then is to pick appropriate implementation at the very beginning. So example would be started like this:
func PickClient(schemaName string) Client{
switch schemaName{
case "pedersen":
return &PedersenClient{}
case "schnorr":
return &SchnorrClient{}
}
}
client := PickClient(schemaName)
client.ExecuteProtocol()
Notice how PickClient()
return type is the interface. This means that your program, from this point on, does not care what implementation is underneath.
The nice thing, should we decide to go with such an approach, would be that emmy program doesnt even notice if we implement yet another scheme. In other words, to support a new scheme, we only need to provide another interface implementation and update the PickClient()
function with additional case. All other parts of the program would remain untouched!
I believe this may feel like reimplementing the whole program, but that's not true. I think we would quite enjoy to first implement e.g. Pedersen knowing that the other four schemas will come at no cost.
@mancabizjak @miha-stopar What do you think?
Currently, type Credential is implemented as struct with, among others, fields T1 and T2 as arrays of big.Int: (https://github.com/xlab-si/emmy/blob/master/crypto/pseudonymsys/org_issue.go#L28)
type Credential struct {
SmallAToGamma *big.Int
SmallBToGamma *big.Int
AToGamma *big.Int
BToGamma *big.Int
T1 []*big.Int
T2 []*big.Int
}
If I'm not wrong, the T1 and T2 arrays always hold the same structure (A, B, Hash, ZAlpha).
In my opinion, they should be represented as struct instead of big.Int arrays.
The obvious arguments are type safety and code readability.
Another reason (and the reason I came across this problem) is the binding to Java code, where arrays of strings are not supported (strings are used instead of big.Int for ease of conversion). Because of this, mobile library currently doesn't fully support the Credential type.
I propose to create a type Transcript struct
holding A, B, Hash, ZAlpha values, and use this type in Credential
.
It makes it easy to run make on all desktops and you CI.
That's because it's just golang.
You can run it compiled of interpreted ( like make files).
It just needs a golang install.
I got it working with vgo to replace deposit also.
Solved a ton of little issues and now runs everywhere consistently everywhere.
https://github.com/magefile/mage
https://godoc.org/golang.org/x/vgo
See tour of vgo to get started.
I plan to put up an example repo but it's not yet separated from lots of other crap.
I am building a client.
Should it keep the keys in a secure storage on the OS ? I ask because I am not sure of the mechanisms being used crytographically
If organization name passed in TransferCredential RPC is not a name of saved organization ("org1"), dlogMap["p"]
returns nil, which causes
panic: interface conversion: interface {} is nil, not string
here:
Line 114 in ee2f257
I assume the same would happen on other functions loading configuration parameters.
I suggest checking if the organization exists, returning nil, and handling that in higher functions as well, so that the server returns a request error.
The issue can be reproduced with the demo Android app pushed here:
https://github.com/zitnik/emmy-demo-android/tree/invalid-org-test
Running go test -cover github.com/xlab-si/emmy/...
produces the following output:
? github.com/xlab-si/emmy [no test files]
? github.com/xlab-si/emmy/cli [no test files]
ok github.com/xlab-si/emmy/client 35.640s coverage: 82.1% of statements
? github.com/xlab-si/emmy/client/compatibility [no test files]
? github.com/xlab-si/emmy/config [no test files]
ok github.com/xlab-si/emmy/crypto/commitments 16.089s coverage: 37.2% of statements
ok github.com/xlab-si/emmy/crypto/common 17.141s coverage: 60.6% of statements
ok github.com/xlab-si/emmy/crypto/encryption 3.872s coverage: 54.7% of statements
ok github.com/xlab-si/emmy/crypto/groups 3.391s coverage: 17.4% of statements
? github.com/xlab-si/emmy/crypto/secretsharing [no test files]
ok github.com/xlab-si/emmy/crypto/signatures 2.374s coverage: 89.0% of statements
ok github.com/xlab-si/emmy/crypto/zkp/primitives/commitments 36.600s coverage: 96.6% of statements
ok github.com/xlab-si/emmy/crypto/zkp/primitives/dlogproofs 15.144s coverage: 90.1% of statements
ok github.com/xlab-si/emmy/crypto/zkp/primitives/preimage 1.149s coverage: 32.9% of statements
? github.com/xlab-si/emmy/crypto/zkp/primitives/qrproofs [no test files]
ok github.com/xlab-si/emmy/crypto/zkp/primitives/representationproofs 1.784s coverage: 91.4% of statements
? github.com/xlab-si/emmy/crypto/zkp/protocoltypes [no test files]
? github.com/xlab-si/emmy/crypto/zkp/schemes/pseudonymsys [no test files]
ok github.com/xlab-si/emmy/log 0.016s coverage: 28.6% of statements
? github.com/xlab-si/emmy/protobuf [no test files]
? github.com/xlab-si/emmy/server [no test files]
? github.com/xlab-si/emmy/storage [no test files]
I think we should make an effort to improve our test coverage across several packages. Even for many of the packages that do have tests, the coverage is quite low. According to Codeship's best practices for Go, the minimal test coverage should be no less than 80%.
Hey and thanks for your awesome library. Dumb question, but what is the purpose of SchnorrSafePrimeGroup
? Can't find it's usage around the codebase, also can't verify anything with it:
package main
import (
"fmt"
"math/big"
"github.com/xlab-si/emmy/crypto/common"
"github.com/xlab-si/emmy/crypto/groups"
"github.com/xlab-si/emmy/crypto/zkp/primitives/dlogproofs"
)
func main() {
group, err := groups.NewSchnorrSafePrimeGroup(256)
if err != nil {
panic(err)
}
var bases [3]*big.Int
for i := 0; i < len(bases); i++ {
r := common.GetRandomInt(group.Q)
bases[i] = group.Exp(group.G, r)
}
var secrets [3]*big.Int
for i := 0; i < 3; i++ {
secrets[i] = common.GetRandomInt(group.Q)
}
y := big.NewInt(1)
for i := 0; i < 3; i++ {
f := group.Exp(bases[i], secrets[i])
y = group.Mul(y, f)
}
prover, err := dlogproofs.NewSchnorrProver(group, secrets[:], bases[:], y)
if err != nil {
panic(err)
}
verifier := dlogproofs.NewSchnorrVerifier(group)
proofRandomData := prover.GetProofRandomData()
verifier.SetProofRandomData(proofRandomData, bases[:], y)
challenge := verifier.GetChallenge()
proofData := prover.GetProofData(challenge)
verified := verifier.Verify(proofData)
fmt.Printf("verified: %t\n", verified) // false
}
From the ReadMe it looks like it has built-in client-server model support. But not clear if it supports the clients over HTTP. Would be great if it can be made to work with HTTP/REST API.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.