Skip to content

Commit

Permalink
no log.Fatal any more
Browse files Browse the repository at this point in the history
new Check for Curve25519
return error for ComputeSecret
  • Loading branch information
hurae committed May 19, 2020
1 parent 48861f4 commit 6d4a09b
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 26 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[![Godoc Reference](https://godoc.org/github.com/hurae/ecdh?status.svg)](https://godoc.org/github.com/hurae/ecdh)
[![Build Status](https://travis-ci.org/hurae/ecdh.svg?branch=master)](https://travis-ci.org/hurae/ecdh)

Fork of `github.com/aead/ecdh`

## The ECDH key exchange

Expand All @@ -11,9 +12,12 @@ This package implements a generic interface for ECDH and supports the generic [c
and the [x/crypto/curve25519](https://godoc.org/golang.org/x/crypto/curve25519) out of the box.

### Installation
Install in your GOPATH: `go get -u github.com/hurae/ecdh`

Install in your GOPATH: `go get -u github.com/hurae/ecdh`

### Difference:

Fork of `github.com/aead/ecdh`, I’d like to have a version that always return a []byte type public key.
Also, I'd like to use non-deprecated new X25519 API.
- always return a []byte type public key
- use non-deprecated new X25519 API.
- implement Check for Curve25519, just the same check inside golang.org/x/crypto/curve25519. That means length 32 and not all zero.
- ComputeSecret will now pass the error which golang.org/x/crypto/curve25519 gives out.
24 changes: 17 additions & 7 deletions curve25519.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
// Copyright (c) 2020 Andreas huraway. All rights reserved.
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.

package ecdh

import (
"crypto/rand"
"crypto/subtle"
"errors"
"fmt"
"golang.org/x/crypto/curve25519"
"io"
"log"
)

type ecdh25519 struct{}

var zero [32]byte

var curve25519Params = CurveParams{
Name: "Curve25519",
BitSize: 255,
Expand Down Expand Up @@ -57,18 +63,22 @@ func (ecdh25519) PublicKey(private []byte) (public []byte) {
return pub
}

func (ecdh25519) Check([]byte) (err error) {
func (ecdh25519) Check(publicKey []byte) (err error) {
if l := len(publicKey); l != 32 {
return fmt.Errorf("bad point length: %d, expected %d", l, 32)
}
if subtle.ConstantTimeCompare(publicKey, zero[:]) == 1 {
return errors.New("bad input point: low order point")
}
return nil
}

func (ecdh25519) ComputeSecret(private []byte, peersPublic []byte) (secret []byte) {
var err error

func (ecdh25519) ComputeSecret(private []byte, peersPublic []byte) (secret []byte, err error) {
//curve25519.ScalarMult(&sec, &pri, &pub)
secret, err = curve25519.X25519(private, peersPublic)
if err != nil {
log.Fatal(err)
return secret, err
}

return secret
return secret, nil
}
8 changes: 5 additions & 3 deletions ecdh.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2020 Andreas huraway. All rights reserved.
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -29,14 +31,14 @@ type KeyExchange interface {

// Check returns a non-nil error if the peers public key cannot used for the
// key exchange - for instance the public key isn't a point on the elliptic curve.
// Only implemented for NIST curves. Curve25519 didn't provide such function.
// Actually, Curve25519 do not need this check. See https://cr.yp.to/ecdh.html.
// Generally, Curve25519 do not need this check, but an all zero key or nil key is not permitted.
// See https://cr.yp.to/ecdh.html for more detail about Curve25519.
// It's recommended to check peer's public key before computing the secret.
Check(peersPublic []byte) (err error)

// ComputeSecret returns the secret value computed from the given private key
// and the peers public key.
ComputeSecret(private []byte, peersPublic []byte) (secret []byte)
ComputeSecret(private []byte, peersPublic []byte) (secret []byte, err error)
}

// CurveParams contains the parameters of an elliptic curve.
Expand Down
23 changes: 13 additions & 10 deletions ecdh_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2020 Andreas huraway. All rights reserved.
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -29,12 +31,12 @@ func ExampleGeneric() {
if err := p256.Check(publicBob); err != nil {
fmt.Printf("Bob's public key is not on the curve: %s\n", err)
}
secretAlice := p256.ComputeSecret(privateAlice, publicBob)
secretAlice, _ := p256.ComputeSecret(privateAlice, publicBob)

if err := p256.Check(publicAlice); err != nil {
fmt.Printf("Alice's public key is not on the curve: %s\n", err)
}
secretBob := p256.ComputeSecret(privateBob, publicAlice)
secretBob, _ := p256.ComputeSecret(privateBob, publicAlice)

if !bytes.Equal(secretAlice, secretBob) {
fmt.Printf("key exchange failed - secret X coordinates not equal\n")
Expand All @@ -54,16 +56,17 @@ func ExampleX25519() {
if err != nil {
fmt.Printf("Failed to generate Bob's private/public key pair: %s\n", err)
}

if err := c25519.Check(publicBob); err != nil {
fmt.Printf("Bob's public key is not on the curve: %s\n", err)
}
secretAlice := c25519.ComputeSecret(privateAlice, publicBob)

secretAlice, err := c25519.ComputeSecret(privateAlice, publicBob)
if err != nil {
fmt.Println("Failed to Compute secret for the key", err)
}
if err := c25519.Check(publicAlice); err != nil {
fmt.Printf("Alice's public key is not on the curve: %s\n", err)
}
secretBob := c25519.ComputeSecret(privateBob, publicAlice)
secretBob, err := c25519.ComputeSecret(privateBob, publicAlice)

if !bytes.Equal(secretAlice, secretBob) {
fmt.Printf("key exchange failed - secret X coordinates not equal\n")
Expand Down Expand Up @@ -94,8 +97,8 @@ func TestX25519(t *testing.T) {
}
pubBob := dh.PublicKey(priBob)

secAlice := dh.ComputeSecret(priAlice, pubBob)
secBob := dh.ComputeSecret(priBob, pubAlice)
secAlice, _ := dh.ComputeSecret(priAlice, pubBob)
secBob, _ := dh.ComputeSecret(priBob, pubAlice)

if !bytes.Equal(secAlice, secBob) {
toStr := hex.EncodeToString
Expand Down Expand Up @@ -123,7 +126,7 @@ func BenchmarkX25519(b *testing.B) {
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
curve.ComputeSecret(privateAlice, publicBob)
_, _ = curve.ComputeSecret(privateAlice, publicBob)
}
}

Expand All @@ -150,7 +153,7 @@ func BenchmarkP256(b *testing.B) {
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
p256.ComputeSecret(privateAlice, publicBob)
_, _ = p256.ComputeSecret(privateAlice, publicBob)
}
}

Expand Down
6 changes: 4 additions & 2 deletions generic.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2020 Andreas huraway. All rights reserved.
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -63,9 +65,9 @@ func (g genericCurve) Check(peersPublic []byte) (err error) {
return
}

func (g genericCurve) ComputeSecret(private []byte, peersPublic []byte) (secret []byte) {
func (g genericCurve) ComputeSecret(private []byte, peersPublic []byte) (secret []byte, _ error) {
x, y := elliptic.Unmarshal(g.curve, peersPublic)
sX, _ := g.curve.ScalarMult(x, y, private)
secret = sX.Bytes()
return
return secret, nil
}

0 comments on commit 6d4a09b

Please sign in to comment.