Giter VIP home page Giter VIP logo

kyber's Introduction

Go test Coverage Status Quality Gate Status Go Reference

DEDIS Advanced Crypto Library for Go

This package provides a toolbox of advanced cryptographic primitives for Go, targeting applications like Cothority that need more than straightforward signing and encryption. Please see the Godoc documentation for this package for details on the library's purpose and API functionality.

This package includes a mix of variable time and constant time implementations. If your application is sensitive to timing-based attacks and you need to constrain Kyber to offering only constant time implementations, you should use the suites.RequireConstantTime() function in the init() function of your main package.

Target Audience

This library is intended to be used by developers who are at least moderately knowledgeable about cryptography. If you want a crypto library that makes it easy to implement "basic crypto" functionality correctly - i.e., plain public-key encryption and signing - then NaCl secretbox may be a better choice. Or use Google's Tink

This toolkit's purpose is to make it possible - and preferably easy - to do slightly more interesting things that most current crypto libraries don't support effectively. The one existing crypto library that this toolkit is probably most comparable to is the Charm rapid prototyping library for Python.

Versioning - Development

We use the following versioning model:

  • crypto.v0 was the first semi-stable version. See migration notes.
  • kyber.v1 never existed, in order to keep kyber, onet and cothorithy versions linked
  • gopkg.in/dedis/kyber.v2 was the last stable version
  • Starting with v3.0.0, kyber is a Go module, and we respect semantic versioning.

So if you depend on the master branch, you can expect breakages from time to time. If you need something that doesn't change in a backward-compatible way you should use have a go.mod file in the directory where your main package is.

Using the module

Kyber supports Go modules, and currently has a major version of 3, which means that the import path is: go.dedis.ch/kyber/v3.

Here is a basic example of getting started using it:

  1. Make a new directory called “ex". Change directory to “ex" and put this in main.go:
package main

import (
    "fmt"
    "go.dedis.ch/kyber/v3/suites"
)

func main() {
    s := suites.MustFind("Ed25519")
    x := s.Scalar().Zero()
    fmt.Println(x)
}
  1. Type “go mod init example.com/ex”. The resulting go.mod file will have no dependencies listed yet.
  2. Type “go build”. The go tool will fill in the new dependencies that it find for you, i.e. "require go.dedis.ch/kyber/v3 v3.0.13”.
  3. Running ./ex will print 0000000000000000000000000000000000000000000000000000000000000000.

A note on deriving shared secrets

Traditionally, ECDH (Elliptic curve Diffie-Hellman) derives the shared secret from the x point only. In this framework, you can either manually retrieve the value or use the MarshalBinary method to take the combined (x, y) value as the shared secret. We recommend the latter process for new softare/protocols using this framework as it is cleaner and generalizes across different types of groups (e.g., both integer and elliptic curves), although it will likely be incompatible with other implementations of ECDH. See the Wikipedia page on ECDH.

Reporting security problems

This library is offered as-is, and without a guarantee. It will need an independent security review before it should be considered ready for use in security-critical applications. If you integrate Kyber into your application it is YOUR RESPONSIBILITY to arrange for that audit.

If you notice a possible security problem, please report it to [email protected].

kyber's People

Contributors

anomalroil avatar bford avatar cag avatar cedriccook avatar christophebertrand avatar daeinar avatar davidiw avatar feihuang avatar gilthoniel avatar gnarula avatar ineiti avatar iuliatamas avatar jbsv avatar jeffallen avatar joaoandresa avatar k1li4nl avatar kc1212 avatar liamsi avatar liminalsheeps avatar nikirill avatar nikkolasg avatar nkcr avatar parinayc20 avatar pierluca avatar pizzawhisperer avatar rkopiga avatar seratym avatar tharvik avatar tobowers avatar zytekaron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kyber's Issues

Documentation

Make sure the documentation is up-to-date:

  • README.md
  • godoc is correct
  • only relevant files in kyber-root-dir

Shamir branch : Schnorr verify fails with T > 2 in tests

The things we noted so far:

  • for T = 2, it works
  • for T > 2, it fails ,whatever the N value (number of peers in the setup)
  • Every peers generate the exact same signature at the end, and their corresponding longterm share and random share are correct.
  • The partial signatures generated are also correct since they pass the test AddPartialSig which makes the verification described in the paper (stinson01, 4.2.2)
  • For the Shamir signing application in github.com/dedis/cothority branch development, everything works as expected EVEN IF T > 2. In fact, I've put T = N for the shamir app (I've tested that also in the test suite, it does not work). The fact that it is working for shamir app disturbs me a lot because I've checked for every little omission in any crypto computations, but if there was something missing, it would have been detected as the Shamir app would not have worked.
    Any ideas ?

Secret Sharing and Schnorr Signature Tweaks

  • VerifySchnorrSig [1] should be changed so that it can be used "offline" after the JVSS group (and thus the Schnorr struct) has vanished.
  • Creation of Schnorr signatures in JVSS (r = v + cx) [2] and CoSi (r = v - cx) should be unified.
  • NewReceiver [3] does not need the suite as a parameter because it's already stored in *config.KeyPair

[1] https://github.com/dedis/crypto/blob/master/poly/schnorr.go#L245
[2] https://github.com/dedis/crypto/blob/master/poly/schnorr.go#L177
[3] https://github.com/dedis/crypto/blob/master/poly/joint.go#L72

Code does not adhere to gofmt standard

Code does not adhere to the gofmt standards. The Go community expects that all good go code is formatted according to this standard (http://blog.golang.org/go-fmt-your-code, http://golang.org/doc/effective_go.html#formatting, https://github.com/golang/go/wiki/CodeReviewComments#gofmt). This is a necessary step for being taken seriously by the community at large.

It makes life much easier, as you can hook gofmt to run on save for most editors and it will deal with all formatting (http://blog.golang.org/go-fmt-your-code). There is an extension called goimports that you can run instead that analyzes your code, formats it, and handles imports (dropping them or adding them as needed). This will make dependency management easier as there will not be the "unused import" error and files won't have stray, commented out imports.

All these commands run very quickly, almost unnoticably quickly.

crypto/protobuf package needs to go away in favor of using dedis/protobuf

Danny @jackowitzd2 - I didn't notice until now that you had recently made some changes to the crypto/protobuf package, instead of to the newer top-level protobuf repo (https://github.com/DeDiS/protobuf), which we forked off of the crypto repo because at least one external user wanted to use it separately from the crypto library. I had meant to delete the old crypto/protobuf package from the crypto library once the fork-off was complete, but forgot to do that. So can you:

  1. Propagate your recent bug fix into the protobuf repo if needed and make sure some (non-crypto-specific) test in that repo covers it, assuming Alec Thomas's work didn't already do this.
  2. Move your crypto-specific Encoding test into, say, an addition to the TestSuite function in the crypto/test package, so that all suites will automatically get tested for functional Encoding support.
  3. Create a temporary github branch of crypto and a Pull request announcing the impending deletion of the crypto/protobuf package and warning anyone else to move to using the top-level protobuf package. @dyv and @iuliatamas might also currently have code that depends on it and needs to be updated, for example.

Thanks

Protobuf constructors map signature

Go complains when inserting values into the Constructors map in protobuf/decode.go:

cannot use suite.Secret (type func() abstract.Secret) as type func() interface {} in map value

Changing suite.Secret() to return interface{} fixes the issue (i.e. the signatures have to match exactly), but I don't think we'd want to do that. I instead propose type Constructors map[reflect.Type]reflect.Value and then using reflection to call the constructor function. I have a patch using this approach and can confirm that it works.

[Sign] Schnorr should be EdDSA compatible for verification

There are three things that makes the current sign.Schnorr signature incompatible with the verification function of eddsa.Verify.

  • The sign.SchnorrSign uses the hash function of the suite. While in principle it's correct, here that breaks compatibility with the EdDSA implementation which uses a sha512 while the regular ed25519 suite use sha256.
    We should switch to sha512 so our signatures are verifiable by the regular EdDSA verification implementations.

The signature format in sign.Schnorr is c, s with c = H(Random || Public || message) and s = r - c*x. In eddsa, the signature is R || s.

  • The schnorr format should follow eddsa format. No need to follow Wikipedia format, since nobody uses it.
  • The signature must be changed from s = r - c * x to s = r + c * x.

TestAES in sha3 package fails (sometimes)

Just stumbled upon this twice today. To reproduce run the tests in github.com/dedis/crypto/cipher/sha3 until you see (using some loop provided by your favourite shell):

--- FAIL: TestAES (0.00s)
        cipher.go:183: Encryptions not sufficiently different 0.28125
FAIL
FAIL    github.com/dedis/crypto/cipher/sha3     0.115s

(Maybe be related to issue #70?)

[Scalar] UnmarshalFrom should read only exact amount

Currently, a Scalar is a nist.Int and its method UnmarshalFrom reads the full content of the given io.Reader. It should only read the necessary amount of data, by knowing its expected length since nist.Int is always represented using the same length (in practice).

[Encoding] Usefulness of our own encoding

Now that the whole onet, cothority and some parts of the crypto library are using the protobuf library, it is questionable whether we want to keep the "hand crafted" encoding format coded in encoding.go.
For the moment, quite a few packages are still using it but it should not be complicated to move that to using protobuf too.
If this transition is done, it would be fairly easy to remove the Encoding and Constructor interfaces from the Suite definition interface.

suite.Point.Null() unmarshal fail

Say I have a structure with

type a struct {
b abstract.Point
}
and I set b to suite.Point().Null() ( where suite is already good and intialized)
If I Marshal a via protobuf and I send it via the network, when I Get it I error with "failed to unmarshal binary"

Any other Point value works. If b==nil it also works. At the moment, as a workaround, I perform a check and if b is Point.Null() I just make it equal to nil and send it like that.

I added a pull request that would add to master a small test of this, which at the moment fails with this error:
nullPoint_test.go:19: invalid elliptic curve point

PubPoly Check fails when marshalling/ unmarshalling

@davidiw
@bford
@jackowitzd2

In my prifi commit for life insurance, I am experiencing a strange bug in regards to public polynomials. I am passing public polynomials into messages that I then marshal/ unmarshal to send across the network. When I do so, the public polynomial no longer successfully validates shares.

As quick terminology:

msg = the message before marshalling
newMsg = the message after marshalling

What makes this even more interesting is the following:

- msg properly validates msg.Share as well as newMsg.Share. So, the secrets seem to be
intact.

 - Comparing msg.PubCommit and newMsg.PubCommit, they are not only equal according
to the Equal function but also marshal to the same byte arrays.

Nevertheless, newMsg.PubCommit fails to recognize newMsg.share.

As for other notes of information:

  • I am using abstract.Write / abstract.Read to do my marshalling / unmarshalling.

Here's the code:

// These messages are used to send insurance requests. A node looking for an
// insurance policy will send these to other nodes to ask them to become
// insurers.
type RequestInsuranceMessage struct {
// The public key of the insured.
PubKey abstract.Point

// The number of the share being sent.
ShareNumber *nist.Int

// The private share to give to the insurer
Share abstract.Secret

// The public polynomial used to verify the share
PubCommit *poly.PubPoly

}

/* Creates a new insurance request message
*

  • Arguments:
  • s = the shared secret to give to the insurer.
  •  pc = the public polynomial to check the share against.
    
  • Returns:
  • A new insurance request message.
    */
    func (msg *RequestInsuranceMessage) createMessage(p abstract.Point, shareNum int,
    s abstract.Secret, pc *poly.PubPoly) *RequestInsuranceMessage {
    msg.PubKey = p
    msg.ShareNumber = nist.NewInt(int64(shareNum), big.NewInt(int64(math.MaxInt64)))
    msg.Share = s
    msg.PubCommit = pc
    return msg
    }

// Encodes the message for sending.
func (msg *RequestInsuranceMessage) MarshalBinary() ([]byte, error) {
b := bytes.Buffer{}
abstract.Write(&b, msg, INSURE_GROUP)
return b.Bytes(), nil
// return protobuf.Encode(msg);
}

// Decodes a message received.
// NOTE: In order to be encoded properly, public polynomials need to be
// initialized with the right group and minimum number of shares.
func (msg _RequestInsuranceMessage) UnmarshalBinary(data []byte) (_RequestInsuranceMessage, error) {
msg.PubCommit = new(poly.PubPoly)
msg.PubCommit.Init(INSURE_GROUP, TSHARES, nil)
msg.PubKey = KEY_SUITE.Point()
msg.Share = INSURE_GROUP.Secret().Pick(random.Stream)
msg.ShareNumber = nist.NewInt(int64(0), big.NewInt(int64(math.MaxInt64)))
b := bytes.NewBuffer(data)
err := abstract.Read(b, msg, INSURE_GROUP)
if err != nil {
panic(err)
}
return msg, err
// return msg, protobuf.Decode(data, msg)

}

Here's how I create the secret and public polynomial I pass into it:

var secret = INSURE_GROUP.Secret().Pick(random.Stream)

var pripoly = new(poly.PriPoly).Pick(INSURE_GROUP, TSHARES, secret, random.Stream)

// Used to initialize the public commit polynomial.
func producePubPoly() *poly.PubPoly {
testPubPoly := new(poly.PubPoly)
testPubPoly.Init(INSURE_GROUP, n, nil)
return testPubPoly.Commit(pripoly, nil)
}

This is the piece of code that fails:

!newMsg.PubCommit.Check(int(newMsg.ShareNumber.V.Int64()), newMsg.Share)

Whereas the following succeed

!msg.PubCommit.Check(int(msg.ShareNumber.V.Int64()), msg.Share)
!msg.PubCommit.Check(int(newMsg.ShareNumber.V.Int64()), newMsg.Share)

Does anyone happen to know if this is a bug on my end or on the crypto side?

Building Crypto library in Windows

Hey all,

At the last group meeting I mentioned to Danny that I haven't actually been able to successfully build the crypto library so far, and we were both confused about the output I get when I run go test -v ./... within my local dedis/crypto repository.

Danny mentioned that I might actually be the first person trying to build the library in Windows, so I was wondering if anyone else has run into similar issues, or if anyone has an idea of what could be going wrong? Danny was particularly interested in the line I've marked with the "<---- *****" below. In particular, we're confused how the build can be failing for github.com/dedis/crypto but certain tests in subdirectories of that one are still succeeding. I just did a git pull so my repo should be in sync with the online copy.

Does anyone have any insight into what might be going on? For what it's worth, my laptop is running Windows 7 64-bit.

$ go test -v ./...
warning: GOPATH set to GOROOT (C:\Go) has no effect

github.com/dedis/crypto/cipher/bench

cipher\bench\cipher_test.go:10:2: cannot find package "golang.org/x/crypto/blowfish" in any of:
C:\Go\src\golang.org\x\crypto\blowfish (from $GOROOT)
($GOPATH not set)
FAIL github.com/dedis/crypto/cipher/bench [setup failed]

github.com/dedis/crypto/test

test\cipher.go:301: undefined: cipher.Read

github.com/dedis/crypto/openssl

realgcc.exe: warning: '-x c' after last input file has no effect <---- ******
realgcc.exe: no input files
FAIL github.com/dedis/crypto [build failed]
? github.com/dedis/crypto/abstract [no test files]
FAIL github.com/dedis/crypto/anon [build failed]
=== RUN TestEncode
--- PASS: TestEncode (0.00s)
=== RUN TestEncoder
--- PASS: TestEncoder (0.00s)
=== RUN TestEncoderBuffering
--- PASS: TestEncoderBuffering (0.00s)
=== RUN TestDecode
--- PASS: TestDecode (0.00s)
=== RUN TestDecoder
--- PASS: TestDecoder (0.00s)
=== RUN TestDecoderBuffering
--- PASS: TestDecoderBuffering (0.00s)
=== RUN TestDecodeCorrupt
--- PASS: TestDecodeCorrupt (0.00s)
=== RUN TestBig
--- PASS: TestBig (0.00s)
=== RUN TestNewLineCharacters
--- PASS: TestNewLineCharacters (0.00s)
=== RUN TestDecoderIssue3577
--- PASS: TestDecoderIssue3577 (0.00s)
=== RUN TestDecoderIssue4779
--- PASS: TestDecoderIssue4779 (0.00s)
=== RUN TestDecoderIssue7733
--- PASS: TestDecoderIssue7733 (0.00s)
=== RUN: ExampleEncoding_EncodeToString
--- PASS: ExampleEncoding_EncodeToString (0.00s)
=== RUN: ExampleEncoding_DecodeString
--- PASS: ExampleEncoding_DecodeString (0.00s)
=== RUN: ExampleNewEncoder
--- PASS: ExampleNewEncoder (0.00s)
PASS
ok github.com/dedis/crypto/base64 0.189s
? github.com/dedis/crypto/cipher [no test files]
FAIL github.com/dedis/crypto/cipher/aes [build failed]
? github.com/dedis/crypto/cipher/norx [no test files]
? github.com/dedis/crypto/cipher/norx/check [no test files]
=== RUN TestKeccakKats
--- PASS: TestKeccakKats (0.38s)
sha3_test.go:95: SHA3-224
sha3_test.go:95: SHA3-256
sha3_test.go:95: SHA3-384
sha3_test.go:95: SHA3-512
sha3_test.go:95: SHAKE128
sha3_test.go:95: SHAKE256
=== RUN TestUnalignedWrite
--- PASS: TestUnalignedWrite (0.05s)
=== RUN TestAppend
--- PASS: TestAppend (0.00s)
=== RUN TestAppendNoRealloc
--- PASS: TestAppendNoRealloc (0.00s)
=== RUN TestSqueezing
--- PASS: TestSqueezing (0.00s)
sha3_test.go:178: SHAKE128
sha3_test.go:178: SHAKE256
=== RUN TestReadSimulation
--- PASS: TestReadSimulation (0.00s)
PASS
ok github.com/dedis/crypto/cipher/sha3 0.757s
? github.com/dedis/crypto/clique [no test files]
? github.com/dedis/crypto/config [no test files]
FAIL github.com/dedis/crypto/edwards [build failed]
FAIL github.com/dedis/crypto/edwards/ed25519 [build failed]
? github.com/dedis/crypto/group [no test files]
? github.com/dedis/crypto/ints [no test files]
? github.com/dedis/crypto/math [no test files]
=== RUN TestNego
Total hdrlen: 1888
--- PASS: TestNego (3.04s)
PASS
ok github.com/dedis/crypto/nego 3.269s
FAIL github.com/dedis/crypto/nist [build failed]
FAIL github.com/dedis/crypto/openssl [build failed]
=== RUN TestPriPolyPick
--- PASS: TestPriPolyPick (0.00s)
=== RUN TestPriPolySecret
--- PASS: TestPriPolySecret (0.00s)
=== RUN TestPriPolyEqual
--- PASS: TestPriPolyEqual (0.00s)
=== RUN TestPriPolyAdd
--- PASS: TestPriPolyAdd (0.00s)
=== RUN TestPriPolyString
--- PASS: TestPriPolyString (0.00s)
=== RUN TestPriSharesSplitShare
--- PASS: TestPriSharesSplitShare (0.00s)
=== RUN TestPriSharesEmpty
--- PASS: TestPriSharesEmpty (0.00s)
=== RUN TestPriSharesSetShare
--- PASS: TestPriSharesSetShare (0.00s)
=== RUN TestPriSharesxCoord
--- PASS: TestPriSharesxCoord (0.00s)
=== RUN TestPriSharesSecret
--- PASS: TestPriSharesSecret (0.00s)
=== RUN TestPriSharesString
--- PASS: TestPriSharesString (0.00s)
=== RUN TestPubPolyInit
--- PASS: TestPubPolyInit (0.00s)
=== RUN TestPubPolyCommit
--- PASS: TestPubPolyCommit (1.18s)
=== RUN TestPubPolySecretCommit
--- PASS: TestPubPolySecretCommit (0.32s)
=== RUN TestPubPolyLen
--- PASS: TestPubPolyLen (0.01s)
=== RUN TestPubPolyEncodeDecode
--- PASS: TestPubPolyEncodeDecode (0.33s)
=== RUN TestPubPolyEqual
--- PASS: TestPubPolyEqual (1.34s)
=== RUN TestPubPolyAdd
--- PASS: TestPubPolyAdd (1.04s)
=== RUN TestPubPolyCheck
--- PASS: TestPubPolyCheck (0.36s)
=== RUN TestPubPolyString
--- PASS: TestPubPolyString (0.00s)
=== RUN TestPolyEval
--- PASS: TestPolyEval (0.61s)
=== RUN TestPubSharesSplitShare
--- PASS: TestPubSharesSplitShare (0.18s)
=== RUN TestPubSharesSetShare
--- PASS: TestPubSharesSetShare (0.37s)
=== RUN TestPubSharesxCoord
--- PASS: TestPubSharesxCoord (0.31s)
=== RUN TestPubSharesSecret
--- PASS: TestPubSharesSecret (0.82s)
=== RUN TestPubSharesString
--- PASS: TestPubSharesString (0.01s)
PASS
ok github.com/dedis/crypto/poly 8.146s
FAIL github.com/dedis/crypto/proof [build failed]
? github.com/dedis/crypto/random [no test files]
FAIL github.com/dedis/crypto/shuffle [build failed]
? github.com/dedis/crypto/subtle [no test files]
FAIL github.com/dedis/crypto/suites [build failed]

Insurance Blame Protocol

@bford
@jackowitzd2

I'm working on pull request #40 and I wanted to ask your advice on how to verify blame proofs. As a brief summary:

  • One server called the promiser will take out a Promise and ask several servers to act as guardians of the promise. The promise will be the private key of the promiser. The guardians will receive PriShares of the private key.
  • The Promise object contains a list of all the shares encrypted with a Diffie-Hellman shared key with the appropriate guardian and the promiser.
  • If the share is malformed, the guardian wants to have a way of blaming the promiser.
  • To provide proof of blame, the guardian will reveal its Diffie-Hellman shared secret along with the decrypted share.
  • To verify, another server will make sure that the share provided in the blame proof (when it is encrypted by the provided Diffie-Hellman shared secret) equals the entry provided in the Promise
  • If the share fails to be checked by the public polynomial, the blame is justified

The issue I am having is how to verify that the Diffie-Hellman secret was constructed appropriately. Under the current setting, a malicious guardian who wanted to accuse the promiser could decrypt the Promise share using an invalid Diffie-Hellman shared secret. The result would produce a bad share, which would fail the public polynomial check. However, I would not want this case to be considered a valid blame proof.

My initial thought is to have the accuser be forced to reveal their own private key. Since the promise has the public key of the promiser, the proper Diffie-Hellman secret could then be reconstructed. I could also check whether the private key corresponds to the public key the promise has for the specific guardian. This would discourage false accusers since they would be giving away their private key and would have to get a new one.

However, the issue here is that an honest accuser has to reveal its private key even though it has done nothing wrong.

Do you have any suggestions?

[EdDSA] Inconsistent (Un)Marshalling

Now:

  • eddsa.Marshal outputs the seed and the public key in a slice of bytes.
  • eddsa.Unmarshal reads the secret key and public key from a slice of bytes.

Wanted:

  • eddsa.Marshal outputs the seed and the public key in a slice of bytes.
  • eddsa.Unmarshal reads the seed key and public key from a slice of bytes.

With a test.

Fix Code Licensing / Attribution Issues

The following code licensing / attribution problems need to be fixed asap:

  • GPLv2 is too restrictive and should be replaced by a more liberal license (e.g. LGPL).
  • We need to properly attribute the code that we pulled in from @agl and add the missing license file (see 1ea738d). The rest of the code base should be checked for similar issues.

sha3.Shake128 with abstract.NoKey NOT random

Found a unusual behavior when debugging edwards/ed25519 suites:
If you create a rand := cipher.Stream from those suites (using sha3.Shake128), and then retrieve a slice of bytes from it using random.Bytes(32,rand), the slice of bytes are always zero the first 6 times. Having discussed with @Daeinar , it may be related to the size of the state of sha3.Shake128 but as I'm really not familiar with those sponge cipher (yet!), I can't say.
It's definitely not a correct behavior as every output should look completely random whatever the input is.
This faulty behavior is kinda hidden in nist.Int.Pick(rand) where this function calls random.Int which iterates as long as the number returned fulfills n != 0.

Equal Troubles

@jackowitzd2
@bford

I am running into issues with testing equality for extPoint. When I run tests, I get a nil pointer error. As diagnostics, I have written the following code in my testing procedures:

var group abstract.Group = new(edwards.ExtendedCurve).Init(
edwards.Param25519(), false)
var k int = 10
var n int = 20
var secret = group.Secret()
var point = group.Point()
...
func TestGroup(t *testing.T) {
group.Point().Equal(group.Point())
}

When I then run the code, I get the following error

--- FAIL: TestGroup (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x50bfcc]

goroutine 21 [running]:
testing.func·006()
/usr/local/go/src/testing/testing.go:441 +0x181
math/big.(_Int).Mod(0xc208048030, 0xc208048030, 0x0, 0xc208048030)
/usr/local/go/src/math/big/int.go:251 +0x22c
github.com/dedis/crypto/nist.(_Int).Mul(0xc208048030, 0x7f7755b31e68, 0xc208062160, 0x7f7755b31e68, 0xc208062260, 0x0, 0x0)
/home/william/Desktop/CPSC490/src/src/github.com/dedis/crypto/nist/int.go:219 +0x122
github.com/dedis/crypto/edwards.(*extPoint).Equal(0xc208062160, 0x7f7755b31dc8, 0xc208062210, 0x54c61991)
/home/william/Desktop/CPSC490/src/src/github.com/dedis/crypto/edwards/ext.go:81 +0x121
github.com/dedis/crypto/poly.TestGroup(0xc20808a090)
/home/william/Desktop/CPSC490/src/src/github.com/dedis/crypto/poly/sharing_test.go:279 +0x90
testing.tRunner(0xc20808a090, 0x699de0)
/usr/local/go/src/testing/testing.go:447 +0xbf
created by testing.RunTests
/usr/local/go/src/testing/testing.go:555 +0xa8b

goroutine 1 [chan receive]:
testing.RunTests(0x608798, 0x699c60, 0x15, 0x15, 0xd1735f78be5cda01)
/usr/local/go/src/testing/testing.go:556 +0xad6
testing.(*M).Run(0xc20805dbd0, 0x6a2f20)
/usr/local/go/src/testing/testing.go:485 +0x6c
main.main()
github.com/dedis/crypto/poly/_test/_testmain.go:92 +0x1d5
exit status 2
FAIL github.com/dedis/crypto/poly 0.095s

Here is some more code on this:

edwards/ext.go

func (P1 _extPoint) Equal(CP2 abstract.Point) bool {
P2 := CP2.(_extPoint)
var t1, t2 nist.Int
xeq := t1.Mul(&P1.X, &P2.Z).Equal(t2.Mul(&P2.X, &P1.Z)) <--------
yeq := t1.Mul(&P1.Y, &P2.Z).Equal(t2.Mul(&P2.Y, &P1.Z))
return xeq && yeq
}

nist/Int.go:

func (i _Int) Mul(a, b abstract.Secret) abstract.Secret {
ai := a.(_Int)
bi := b.(*Int)
i.M = ai.M
i.V.Mul(&ai.V, &bi.V).Mod(&i.V, i.M) <----
return i
}

It seems to be an initialization issue. As one last thing, I researched more on how the point is made:

edwards/ext.go

// Create a new Point on this curve.
func (c *ExtendedCurve) Point() abstract.Point {
P := new(extPoint)
P.c = c
//P.Set(&c.null)
return P
}

type extPoint struct {
X, Y, Z, T nist.Int
c *ExtendedCurve
}

Should the Point function do any additional initialization (or does it expect me to do so)?

kyber v1

This is the epic for v1 of our new kyber!

Anon/lSig uSig unexported failure on abstract.Read/Write

Using anon/lSig which embeds a anon/uSig, it is not possible to using the encoding library in abstract because of uSig being unexported. When did it work is a mystery, but it must not have been caught for a long time now.

added gcd() method

I needed gcd() for Pohlig Hellman. I Changed abstract/group.go(added gcd signature) and nist/int.go(added gcd implementation).

Add hash.Bytes() utility function

The hash package should have a function that allows to hash an arbitrary number of byte slices, i.e. similar to hash.Structures(...) but more specialised.

Branch-and-merge workflow vs Go absolute paths

Crap, I hate how Go basically forces you to put absolute, global pathnames in every package in a large multi-package collection, just to allow one package in the collection to refer to another package in the same collection. In particular, it seems like it perhaps fundamentally breaks the multi-branch, pull-request-oriented Github workflow for any change that involves multiple packages - or especially that involves adding new packages, as my current pull request does (#11).

In particular, the Travis CI script wants to build the version in my pull request, but when one package requires another new package added in the same pull request (e.g., crypto/subtle), it goes looking for the new package in the original master repository at the global package address ("github.com/dedis/crypto/subtle"); it's of course not there, so of course Travis CI complains.

So to fix it looks like I have to "temporarily" change the global address of the referenced package in the pull-request version - but can't forget to change it back before actually merging, otherwise the master version of the library will end up incorrectly referring to packages in side-branches like my personal repo. Ugh!!!

Does anyone know a good solution to this? This must have caused a bunch of people significant amounts of pain by now. Perhaps it's one major reason why the golang developers don't use the branch-and-merge workflow - but eliminating the possibility of using such a workflow seems like a really horrible thing for a language to do, in general. Does anyone know if there's a facility in golang to force a temporary substitution of a top-level package name, e.g., to build a repository so as to pretend that "github.com/dedis/crypto/..." imports in the repo really mean "github.com/bford/crypto/..." just for the moment? That would be a hack but would at least work around the problem.

Thanks
Bryan

Nil Cipher Options

@bford

For abstract.Group:

 Cipher(key []byte, options ...interface{}) Cipher

When I try to create a cipher with a suite:

cipher := p.shareSuite.Cipher(diffieBase.MarshalBinary())

I get the following error:

 2015/02/27 18:09:55 Unsupported option <nil>
     panic: Unsupported option <nil>

When I checked "cipher/sponge", I saw the issue:

func (sc *spongeCipher) parseOptions(options []interface{}) bool {
    more := false
    for _, opt := range options {
         switch v := opt.(type) {
             case Padding:
                 sc.pad = byte(v)
            default:
                 log.Panicf("Unsupported option %v", opt)
        }
     }
     return more
 }

It doesn't have a case for handling a nil options. However, it seems as though the options parameter is optional since I was able to call Cipher by only specifying the bytes field. I did the following fix and everything worked:

func (sc *spongeCipher) parseOptions(options []interface{}) bool {
    more := false
    for _, opt := range options {
         switch v := opt.(type) {
             case Padding:
                 sc.pad = byte(v)
             case nil:
                 continue
            default:
                 log.Panicf("Unsupported option %v", opt)
        }
     }
     return more
 }

Is this functionality desirable?

Add coverage

Like for cothority and onet, add a coverage-script.

NIST P256 Point Encode/Decode

nist/p256 Points with negative y-coords lose the negative sign after going through an Encode/Decode cycle. This may be on Go's end, since we just call out to crypto/elliptic.

poly.Schnorr API broken

The more I work with poly.Schnorr the more I tell my self that it should be fixed on the following points:

  • NewRound design is a bad idea. We should generate a new SchnorrRound or something which is ephemereal instead of re-using the same Schnorr struct.
  • NewRound takes a hash.Hash and then call hash.Sum(nil) to get the hash of the message. I remember there were some discussions suggesting it can suppor streaming or something but it's not clear to me how (calling h.Sum(nil) "stops" the streaming ...). I suggest going back to straightforward msg []byte.
  • The original paper computes the "challenge" (cosi terminology) using H ( aggRandom || msg) where aggRandom is the equivalent of the aggregate commit in a CoSi round. In a CoSi round the hash is done like H ( aggCommit || aggPublic || msg) . Since I'm working on randhoundco, I've already made possible to specify the hash we want, but in mainstream we should propose the two behaviors (alongside with their verification methods).

Adding `New`-methods to `nist/int.go`

While looking through crypto/nist/nist.go, I found some inconsistencies:

  • there is only NewInt which should be called NewInt64
  • there is no NewInt that takes a big.Int
  • NewInt64 doesn't take a ByteOrder

My proposal is to make

  • NewInt64, NewInt, NewIntBytes, NewIntString and remove the Init*-methods

Work-item: generic test-suite for new abstract.Cipher interface

Here's a nice small work-item that would be a great way for someone new to jump in and get started on something quickly - but I would like whoever takes it on to jump into it quickly, i.e., say today or tomorrow, and try to produce first-cut code by say this weekend.

The 'cipher' branch and a new pull request (#23) contains an update on the abstract.Cipher interface for general symmetric cipher functionality: please see that pull request and the checked-in documentation-comments for that interface for the details. This new Cipher interface needs a proper generic test-suite, which will take any reasonable object implementing the Cipher interface and check a bunch of invariants and properties it's supposed to have. I expect the new code to go in, say, a function defined as:

func TestCipher(newCipher func(key []byte, options ...interface{}) abstract.Cipher) { ... }

in a new file 'crypto/test/cipher.go' in the 'crypto/test' package. The function will take a Cipher constructor as a higher-order function, and use it to create ciphers to test. That package currently contains generic tests for the Group and Suite interfaces; it needs a similar, generic test for Cipher implementations.

Some of the particular tests I would like to see this TestCipher function perform are:

  • Create several Cipher objects with different keys (passed to the newCipher constructor), encrypt the same short message with all of them, and verify that all the encryptions come out different.
  • Decrypt all of the differently-keyed encryptions above and make sure they correctly decrypt to the original message.
  • Create a suite of constant, sample plaintext messages with different lengths - e.g., 0-byte, 1-byte, "Hello World", a 1KB buffer initialized to 1,2,3,... bytes, and a 1MB buffer initialized similarly - and make a test that does an authenticated-encryption of each message with some fixed key, then does an authenticated-decryption of the same message, verifying that the decrypted plaintext comes out right and that the MAC check succeeds. (See the Cipher interface comment-documentation for how the authenticated encryption should be done.)
  • Run authenticated-decryptions on each of the above encrypted messages, but using the wrong key, and verify that: (a) the MAC check fails, and (b) "close to" half of the bits differ between the incorrectly-decrypted plaintext and the original plaintext of the corresponding message. For example, check that at least 30-40% of the bits differ or something like that - or if you want to be fancy, break out your probability/statistics textbook and figure out a reasonable Chernoff-bounded w.h.p. threshold suitable for each message size.
  • Simulate a single-bit-flipping adversary: given each of the correct authenticated-encryptions produced above, create an incorrect ciphertext with one bit flipped, either: (a) in the very first byte, (b) in the very last byte, (c) in a randomly-chosen byte of the ciphertext, or (d) in a randomly-chosen byte of the MAC. Then attempt to "decrypt" the corrupted ciphertext and verify not only that the MAC fails to check but that "close to half" of the bits differ from the correct MAC for that ciphertext.
  • Using the Cipher as a pseudo-random number generator, produce a whole bunch of random bytes (say 1MB), then count up the number of occurrences of each byte-value in a [256]int table of counters, and verify that each counter ends up being "close enough" to N/256 where N is the total number of bytes. (Another basic statistical-randomness test.)
  • Implement one or two of the other well-known statistical randomness tests in similar fashion (e.g., see: http://csrc.nist.gov/groups/ST/toolkit/rng/documents/nissc-paper.pdf). No need to do all of them by any means; just maybe one or two of the simpler ones as sanity-checks.
  • Check the stream-oriented operation invariants of the cipher.Partial call: for the largest "sample plaintext" in the message test-suite above, do an authenticated-encryption using the whole message in one cipher.Message() call, then break up the message into a bunch of much smaller pieces and do the same authenticated-encryption in multiple calls to cipher.Partial() followed by cipher.Message() to finalize the message, and check that the result (both the encrypted ciphertext and the MAC value) comes out the same.
  • Check "stream cipher" operation invariants: produce two different sample messages m1 and m2 of the same size; "encrypt" both of them separately in stream-cipher mode (i.e., cipher.Partial(dst, src, nil)) into cipher texts c1 and c2, then check that (c1 XOR c2) == (m1 XOR m2). This is of course a generic weakness of stream ciphers, but I want this test in order to check that when the 'key' argument is nil, the output pseudorandom bits do not depend on the input message or on anything else.
  • Multiple-message tests: starting with a given Cipher instance, perform several authenticated encryptions in a row (e.g., one using each of the sample messages in the internal test-suite); then decrypt and authenticate the corresponding list of multiple authenticated-encryptions in the same order, verifying that everything comes out right, and hence the Cipher stays "in sync" between encryption and decryption across multiple messages.
  • Similarly, process multiple messages as above, but corrupt one bit of the ciphertext or the MAC of the second-to-last message, and verify that the encryption/decryption process stays in sync for all but the last two messages (but fails on the last two).
  • Implement any other interesting and relevant tests you might be able to think of. :)

Thanks
Bryan

Encoding Bytes Arrays

@davidiw
@bford
@jackowitzd2

I am working with abstract.Write and abstract.Read encoding. I am attempting to encode a struct of the form:

type PolicyApprovedMessage struct {
PubKey abstract.Point
Message []byte
Signature []byte
}

where Message is a string converted to a byte array and signature is a digital signature of the message. When I do the encoding:

b := bytes.Buffer{}
abstract.Write(&b, msg, KEY_SUITE)

and decoding
b := bytes.NewBuffer(data)
err := abstract.Read(b, msg, KEY_SUITE)

The public key comes out fine. However, the byte arrays are of length 0 when I decode. When I encode via encoding/gob, I am able to get my arrays back:

// var b bytes.Buffer
// enc := gob.NewEncoder(&b)
// err := enc.Encode(msg.Message)
// err = enc.Encode(msg.Signature)

// b := bytes.NewBuffer(data)
// dec := gob.NewDecoder(b)
/// err := dec.Decode(&msg.Message)
// err = dec.Decode(&msg.Signature)

Am I simply not handling encoding of byte arrays properly, or is this an error with encoding? Could someone try encoding a byte array and seeing if they can reproduce this error?

Implement a Clone method for abstract.Point

Due to popular demand, we want to add a Clone(p abstract.Point) method to the abstract.Point interface. Currently, there are three ways to do create a copy of an existing point: using internal representation, using (un)marshal, with Add() or Mul() with Zero() or One() respectively. For this issue we want:

  • benchmarks (on ed25519?) of the 3 mentioned methods to be sure which method is the most efficient
  • add a Clone method to the interface and implement it according to the findings above
  • add a Set method to abstract.Point to be consistent
  • add a Clone method to abstract.Scalar to be consistent

CoSi-cleanup

cosi.cosi.go:189-203 has some non-ideal flow. Change:

  • calculate first sigR
  • then calculate sigS
  • adjust panic-messages

Organization and naming issues

There are a number of naming and package-structure changes that probably need to happen at some point, but they'll be somewhat invasive and touch a lot of code, and I'd like to get some discussion and feedback on these before committing to any of them. Roughly from highest-level to lower-level:

  • Top-level organization: Originally the main abstract interfaces such as 'Point' and 'Secret' lived in the top-level 'crypto' package. I moved them down into a package called 'abstract' basically so that the top-level package and its godoc-generated documentation could easily contain high-level "working examples" such as those in dh_test.go and enc_test.go without creating circular dependences. (Those examples need to depend on cipher suites in sub-packages, which in turn need to depend on the basic abstract interfaces; hence those examples and the abstract interfaces cannot live in the same package.) However, I've been having second thoughts as to whether this was a good tradeoff; those examples are probably not important enough to justify relegating the library's most crucial, keystone interfaces and definitions to a sub package that users have to dig for to find. So I'm thinking of moving the high-level examples to a sub-package, e.g., 'examples', and moving the contents of 'abstract' back up to the top-level. This means (if the name of the library/repo doesn't change) we'll need to refer to Point as 'crypto.Point' rather than 'abstract.Point', etc. Comments, preferences?
  • Crypto library and repository name: 'crypto' is very generic and probably suggests to people that it provides functionality at a comparable level to the many other "crypto libraries" such as SSL-crypto, NaCl, etc., which is inaccurate since this library's purpose is to provide much higher-level functionality (building on many of the primitives provided in other crypto libraries). The closest analog I'm aware of is the Charm library for Python (http://charm-crypto.com/Main.html), which wisely has a name other than simply 'crypto library'. Any good naming ideas? My current idea is 'curvy', since it's short and all about doing fun stuff with elliptic curves and (with the above reorganization) you'd get to write 'curvy.Point', 'curvy.Secret', etc.
  • Rename Secret to Scalar, to align the two main interfaces to "group elements" to common ECC nomenclature (where an element of the cryptographic group is a "point" and a secret that you multiply a point with to encrypt is typically called a "scalar"). Originally the library's interfaces used something closer to multiplicative group notation traditionally used in pre-ECC Diffie-Hellman etc, but the library has been gradually becoming more ECC-centric and hence incrementally migrating toward ECC and additive-group-centric nomenclature, but that process is still incomplete.
  • An even more fundamental change that's worth considering and discussing, though at the moment I'm not sure I'm in favor of it, is to combine Point and Scalar into one interface, e.g., 'Element', similar to the way the Stanford PBC (pairing-based crypto) library has only one abstract "group element" interface that's used for ECC points and scalars and everything. On the plus side, this makes some sense mathematically and might reduce code and interface duplication here and there. Code duplication might be reduced in certain functions that can be performed on either "points" or "scalars": some parts of the Verifiable Secret Sharing code in crypto/poly come to mind immediately. A significant downside is that eleminating the Point/Scalar type-distinction will significantly weaken the clarity of the distinction between these two kinds of things - which tend to play very different security roles even if they're mathematically very closely-related structures - thereby making code using these interfaces less "self-documenting" and weakening the compiler's ability to statically check the separation of these roles properly in code. Clearly some significant subjective tradeoffs and judgment calls are involved here.
  • Swap the order of the arguments to Point.Mul, so the Secret/Scalar comes first. This method was originally called Exp and its argument-order corresponded to the pre-ECC Diffie-Hellman expoentiation argument-order: e.g., "Exp(x,y)" means "x^y". But in additive-group ECC terminology and notation the scalar typically comes first in scalar multiplication: e.g., "sP" for multiplying point P by the scalar s. Also, P is often nil, and it just looks a bit better for the second argument to be nil than the first.
  • Fix the inconsistency between the method signatures of Secret.Pick and Point.Pick (the latter supports embedded data, the former does not). This could be done in at least two ways: (a) consider the latter to be a different function and rename it to, say, Embed(); (b) do the same as (a) but also have a one-argument point.Pick(rand) that's equivalent to point.Embed(nil, rand); (c) keep the Pick name for both but add data-embedding functionality to Secret/Scalar (which would be technically pretty trivial though I'm not sure how often this capability would actually get used). Thoughts/preferences?

More such possible changes might come to mind, which I'll add to this thread as they do, and feel free to suggest others. I'd like to decide on a batch of such invasive changes and apply them about the same time, to minimize the painfulness of updating all the code that depends on these. Thanks.

NewKeyPair() should return a KeyPair struct

I think the recently added method NewKeyPair() should return a KeyPair struct instead of separate private and public keys, see [1]. One example where this is already realised is in the following test: [2].

In order to use things like ConstructDeal, see [3], one would otherwise need to generate a KeyPair yet again from the above private and public keys which can be clearly avoided.

[1] https://github.com/dedis/crypto/blob/master/config/key.go#L23
[2] https://github.com/dedis/crypto/blob/master/poly/deal_test.go#L32
[3] https://github.com/dedis/crypto/blob/master/poly/deal.go#L239

Add response exception handling/mechanism to cosi

In the current libcosi branch there is no possibility for nodes to raise an exception in the response phase.

To the cosi package we want to add two new functions which can create a response and signature with exceptions (maybe ResponseException and SignatureException).
VerifySignature needs to be modified so that it can handle both signatures: those created by the current Signature func. and the to be created SignatureExcpetion func. The difference between both signatures is that the first creates a signature of the form Comm || Resp || mask and the second creates one of the form Comm || Resp || mask || AggCommit.

Make it clear in the documentation which functions and how they are (not) compatible to each other.

[Refactoring] Secret Sharing

This will address (at least) the following issues:

  • Deletion of the entire secret sharing code base found in dedis/crypto/poly
  • New framework for secret sharing now in dedis/crypto/share
    • Rewrite the core of the library for polynomials
    • Integration of public verifiable secret sharing found in randhound
    • Rewrite of the old poly/deal.go into share/vss.go
    • Rewrite of the poly/joint.go and poly/schnorr.go
    • Adapt/rename the (JVSS)[https://github.com/dedis/cothority/tree/master/jvss]

By side effect, this will also include

  • sign package to pave the way for later bigger restructuring. It will include a basic Schnorr signature.
  • DLEQ (discrete log equality) functionality into the proof package

Openssl abstract.Suite definitely broken

Essentially if you do a lot of openssl operations (Add) on the elliptic curves everything stops working. You start getting sig panics that trace back to the openssl function EC_POINT_point2oct originating from the openssl/curve.go:219. This has been verified on both Mac OS and Linux. In addition to this error, occasionally double frees will happen or unallocated frees. This has been checked with the -race flag and no data races were detected either. This bug is non-deterministic in how it fails, if it fails, and if it fails silently or loudly.

coco.test(61675,0xb0104000) malloc: *** error for object 0x5001e30: double free
*** set a breakpoint in malloc_error_break to debug
15 announces
SIGABRT: abort
PC=0x7fff9565f282
signal arrived during cgo execution

goroutine 59 [syscall, locked to thread]:
coco.test(61675,0xb028d000) malloc: *** error for object 0x5223610: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
runtime.cgocall_errno(0x40019e0, 0xc2081bdb98, 0xc200000000)
    /Users/dylanvisher/gosource/go/src/runtime/cgocall.go:130 +0x104 fp=0xc2081bdb78 sp=0xc2081bdb50
github.com/dedis/crypto/openssl._Cfunc_EC_POINT_mul(0x5200960, 0x5222a40, 0x5222950, 0x0, 0x0, 0x52016b0, 0xc200000000)
    /Users/dylanvisher/go/src/github.com/dedis/crypto/openssl/:304 +0x3c fp=0xc2081bdb98 sp=0xc2081bdb78
github.com/dedis/crypto/openssl.(*point).Mul(0xc2080ee380, 0x0, 0x0, 0x4422f6064 announces
, 0xc2081881b0, 0x0, 0x0)
    /Users/dylanvisher/go/src/github.com/dedis/crypto/openssl/curve.go:197 +0xd2 fp=0xc2081bdc18 sp=0xc2081bdb98
github.com/dedis/prifi/coco.(*SigningNode).Commit(0xc20803bee0)
    /Users/dylanvisher/go/src/github.com/dedis/prifi/coco/collectiveSigning.go:68 +0x28c fp=0xc2081bddf0 sp=0xc2081bdc18
github.com/dedis/prifi/coco.(*SigningNode).Announce(0xc20803bee0, 0xc2080ee040)
    /Users/dylanvisher/go/src/github.com/dedis/prifi/coco/collectiveSigning.go:61 +0x41b fp=0xc2081bdf40 sp=0xc2081bddf0
github.com/dedis/prifi/coco.func·001()
    /Users/dylanvisher/go/src/github.com/dedis/prifi/coco/collectiveSigning.go:38 +0x1fc fp=0xc2081bdfe0 sp=0xc2081bdf40
runtime.goexit()
    /Users/dylanvisher/gosource/go/src/runtime/asm_amd64.s:2430 +0x1 fp=0xc2081bdfe8 sp=0xc2081bdfe0
created by github.com/dedis/prifi/coco.(*SigningNode).Listen
    /Users/dylanvisher/go/src/github.com/dedis/prifi/coco/collectiveSigning.go:44 +0xa1

This package is unusable, but a good alternative seems to be the nist package which does not have this problem.

Fork of protobuf package

Hello,

I couldn't find any contact details, but I thought it would be polite to let you know that I've created a fork of the protobuf package from this repository. It enhances the package and makes it available without pulling this entire repository in.

The two major feature additions are:

  1. Control over field IDs, names and optional/required state via Go struct field tags.
  2. Generate .proto source via reflection to aid in interoperability with other languages.

It is licensed under the GPLv2 as per the licensing requirements mentioned in this repository.

Alec

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.