Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement schnorrkel and fix various idioms and linting errors #45

Merged
merged 3 commits into from
Dec 5, 2019

Conversation

actuallyachraf
Copy link
Contributor

I implemented the schnorrkel algorithm which in my opinion is better suited for curve25519, I also used the ristretto255 library instead of the previous one. Fixed various golang idiomatic errors and linting issues.
All tests are passing.

Copy link
Owner

@mimoo mimoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey!

Thanks for submitting this PR! A lot of good stuff.

I've requested some changes.

I'd like to know more about schnorrkel before accepting this PR as well, is there a spec somewhere instead of just a repository?

libdisco/apis.go Outdated
@@ -1,5 +1,5 @@
// These Utility functions implement the net.Conn interface. Most of this code
// was either taken directly or inspired from Go's crypto/tls package.
// Package libdisco these utility functions implement the net.Conn interface.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Package libdisco these utility"?

@@ -123,21 +123,21 @@ var errNoProof = errors.New("Disco: no public key proof set in Config")

func checkRequirements(isClient bool, config *Config) (err error) {
ht := config.HandshakePattern
if ht == Noise_NX || ht == Noise_KX || ht == Noise_XX || ht == Noise_IX {
if ht == NoiseNX || ht == NoiseKX || ht == NoiseXX || ht == NoiseIX {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now let's keep the underscore, this is what the documentation uses as well: https://www.discocrypto.com/#/protocol/Noise_N

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm how about I upgrade both and make it consistent with Go idioms ?

"golang.org/x/crypto/curve25519"
)

//
// The following code defines the X25519, chacha20poly1305, SHA-256 suite.
//
// The following code implements the Schnorrkel variant of Schnorr signatures
// over ristretto255.
// This implementation was picked from https://github.com/w3f/schnorrkel
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe move this comment to the actual implementation of schnorrkel

@@ -24,7 +27,7 @@ const (

// KeyPair contains a private and a public part, both of 32-byte.
// It can be generated via the GenerateKeyPair() function.
// The public part can also be extracted via the ExportPublicKey() function.
// The public part can also be extracted via the String() function.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep ExportPublicKey for now as well, this is what is in the doc

func (kp SigningKeyPair) ExportPublicKey() string {
return hex.EncodeToString(kp.SecretKey.Bytes()) + hex.EncodeToString(kp.PublicKey.Bytes())
// String returns a hexstring encoding of the signing keypair.
func (kp SigningKeypair) String() string {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's keep ExportPublicKey()

}
}

func BenchmarkSign(b *testing.B) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

sigNBytes := sigN.Encode()

if !bytes.Equal(sigBytes[:], sigNBytes[:]) {
b.Fatal("failed to generate deterministic signatures")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this a benchmark? Why would it fail?

sig := kp.Sign(input)

if ok, err := kp.Verify(input, sig); !ok || err != nil {
b.Fatal("failed to verify signature with error : ", err)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you're supposed to fail in a benchmark, since it's not a test per se : o

libdisco/conn.go Outdated
@@ -47,14 +47,18 @@ func (c *Conn) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}

// Addr abstract an address
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"abstracts"

@@ -127,47 +127,47 @@ type handshakeState struct {
// Serialize is a helper function to serialize a handshake state, later to be unserialized via
// the `RecoverState()` function.
// For security purposes, the long-term static keypair is not serialized. Same for the psk
func (hs handshakeState) Serialize() []byte {
func (h *handshakeState) Serialize() []byte {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we keep hs?

Also for changes like this, it's better to split them in multiple PRs : o

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update to hs to make it consistent across the API.

@actuallyachraf
Copy link
Contributor Author

actuallyachraf commented Nov 25, 2019

Will review the changes and make the modifications !
Schnorrkel is the name of the library, it uses a similar algorithm to EdDSA where s = k + xe instead of k - xe . The original library uses merlin transcript for to encode the message and compute hashes. The signature is also R,s instead of s,e .
Some more references :
dedis/kyber#131
https://crypto.stackexchange.com/questions/34863/ec-schnorr-signature-multiple-standard
Edit : There's no specific reference or standard for schnorr over elliptic curves, the wikipedia algorithm, paper... don't document the behavior of deterministic signatures.

@mimoo
Copy link
Owner

mimoo commented Nov 26, 2019

Ah I see, I think this is fine for now, but obviously it'd be good to have a better story here :)

libdisco/apis.go Outdated
@@ -1,5 +1,5 @@
// These Utility functions implement the net.Conn interface. Most of this code
// was either taken directly or inspired from Go's crypto/tls package.
// Package libdisco this file implements a net.Conn interface over Disco.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the "Package libdisco" is still here :p

@actuallyachraf
Copy link
Contributor Author

the recent commit fixes the "package libdisco" comment and adjustes the examples (Noise_XK -> NoiseXK instead).

Copy link
Owner

@mimoo mimoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay and thanks again for that PR!

There's one minor change and this can be merged :)

(I think you should be able to merge it with my approval, if you can't I'll merge it : o )

@@ -127,7 +127,7 @@ type handshakeState struct {
// Serialize is a helper function to serialize a handshake state, later to be unserialized via
// the `RecoverState()` function.
// For security purposes, the long-term static keypair is not serialized. Same for the psk
func (hs handshakeState) Serialize() []byte {
func (hs *handshakeState) Serialize() []byte {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldn't be mutable, unless I'm missing something

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep you're missing the consistency in receiver types
https://github.com/golang/go/wiki/CodeReviewComments#receiver-type

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting, I always thought you shouldn't use a pointer if you don't intent to mutate your value

@mimoo mimoo merged commit 6b185fa into mimoo:master Dec 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants