Skip to content

Commit

Permalink
Adding the remainder signatures.
Browse files Browse the repository at this point in the history
  • Loading branch information
armfazh committed Jul 25, 2020
1 parent 50efdbf commit 309e00a
Show file tree
Hide file tree
Showing 12 changed files with 326 additions and 52 deletions.
6 changes: 6 additions & 0 deletions sign/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@ package api

import (
"github.com/cloudflare/circl/sign"
"github.com/cloudflare/circl/sign/ed25519"
"github.com/cloudflare/circl/sign/ed448"
"github.com/cloudflare/circl/sign/eddilithium3"
"github.com/cloudflare/circl/sign/eddilithium4"
)

var allSchemes [sign.SchemeCount]sign.Scheme
var allSchemeNames map[string]sign.Scheme

func init() {
allSchemeNames = make(map[string]sign.Scheme)
register(ed25519.Scheme)
register(ed448.Scheme)
register(eddilithium3.Scheme)
register(eddilithium4.Scheme)
}

func register(s sign.Scheme) {
Expand Down
12 changes: 9 additions & 3 deletions sign/api/api_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package api_test

import (
"crypto"
"fmt"
"testing"

"github.com/cloudflare/circl/sign"
"github.com/cloudflare/circl/sign/api"
)

Expand Down Expand Up @@ -57,18 +59,22 @@ func TestApi(t *testing.T) {
}

msg := []byte(fmt.Sprintf("Signing with %s", scheme.Name()))
sig := scheme.Sign(sk, msg, nil)
opts := &sign.SignatureOpts{
Hash: crypto.Hash(0),
Context: "a context",
}
sig := scheme.Sign(sk, msg, opts)

if scheme.SignatureSize() != uint(len(sig)) {
t.Fatal()
}

if !scheme.Verify(pk2, msg, sig, nil) {
if !scheme.Verify(pk2, msg, sig, opts) {
t.Fatal()
}

sig[0]++
if scheme.Verify(pk2, msg, sig, nil) {
if scheme.Verify(pk2, msg, sig, opts) {
t.Fatal()
}

Expand Down
45 changes: 33 additions & 12 deletions sign/ed25519/ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import (
"fmt"
"io"
"strconv"

"github.com/cloudflare/circl/sign"
)

const (
Expand Down Expand Up @@ -95,17 +97,14 @@ type PrivateKey []byte
// Equal reports whether priv and x have the same value.
func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
xx, ok := x.(PrivateKey)
if !ok {
return false
}
return subtle.ConstantTimeCompare(priv, xx) == 1
return ok && subtle.ConstantTimeCompare(priv, xx) == 1
}

// Public returns the PublicKey corresponding to priv.
func (priv PrivateKey) Public() crypto.PublicKey {
publicKey := make([]byte, PublicKeySize)
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, priv[SeedSize:])
return PublicKey(publicKey)
return publicKey
}

// Seed returns the private key seed corresponding to priv. It is provided for
Expand All @@ -117,6 +116,28 @@ func (priv PrivateKey) Seed() []byte {
return seed
}

func (priv PrivateKey) Scheme() sign.Scheme { return Scheme }

func (pub PublicKey) Scheme() sign.Scheme { return Scheme }

func (priv PrivateKey) MarshalBinary() (data []byte, err error) {
privateKey := make(PrivateKey, PrivateKeySize)
copy(privateKey, priv)
return privateKey, nil
}

func (pub PublicKey) MarshalBinary() (data []byte, err error) {
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, pub)
return publicKey, nil
}

// Equal reports whether pub and x have the same value.
func (pub PublicKey) Equal(x crypto.PublicKey) bool {
xx, ok := x.(PublicKey)
return ok && bytes.Equal(pub, xx)
}

// Sign creates a signature of a message with priv key.
// This function is compatible with crypto.ed25519 and also supports the
// three signature variants defined in RFC-8032, namely Ed25519 (or pure
Expand Down Expand Up @@ -164,7 +185,7 @@ func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
}

privateKey := NewKeyFromSeed(seed)
publicKey := make([]byte, PublicKeySize)
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, privateKey[SeedSize:])

return publicKey, privateKey, nil
Expand All @@ -175,7 +196,7 @@ func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
// package.
func NewKeyFromSeed(seed []byte) PrivateKey {
privateKey := make([]byte, PrivateKeySize)
privateKey := make(PrivateKey, PrivateKeySize)
newKeyFromSeed(privateKey, seed)
return privateKey
}
Expand All @@ -193,7 +214,7 @@ func newKeyFromSeed(privateKey, seed []byte) {
_ = P.ToBytes(privateKey[SeedSize:])
}

func sign(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
if l := len(privateKey); l != PrivateKeySize {
panic("ed25519: bad private key length: " + strconv.Itoa(l))
}
Expand Down Expand Up @@ -260,7 +281,7 @@ func sign(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash
// It will panic if len(privateKey) is not PrivateKeySize.
func Sign(privateKey PrivateKey, message []byte) []byte {
signature := make([]byte, SignatureSize)
sign(signature, privateKey, message, []byte(""), false)
signAll(signature, privateKey, message, []byte(""), false)
return signature
}

Expand All @@ -277,7 +298,7 @@ func SignPh(privateKey PrivateKey, message []byte, ctx string) []byte {
}

signature := make([]byte, SignatureSize)
sign(signature, privateKey, message, []byte(ctx), true)
signAll(signature, privateKey, message, []byte(ctx), true)
return signature
}

Expand All @@ -293,7 +314,7 @@ func SignWithCtx(privateKey PrivateKey, message []byte, ctx string) []byte {
}

signature := make([]byte, SignatureSize)
sign(signature, privateKey, message, []byte(ctx), false)
signAll(signature, privateKey, message, []byte(ctx), false)
return signature
}

Expand Down
2 changes: 1 addition & 1 deletion sign/ed25519/pubkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ package ed25519
import cryptoEd25519 "crypto/ed25519"

// PublicKey is the type of Ed25519 public keys.
type PublicKey = cryptoEd25519.PublicKey
type PublicKey cryptoEd25519.PublicKey
14 changes: 0 additions & 14 deletions sign/ed25519/pubkey112.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,5 @@

package ed25519

import (
"bytes"
"crypto"
)

// PublicKey is the type of Ed25519 public keys.
type PublicKey []byte

// Equal reports whether pub and x have the same value.
func (pub PublicKey) Equal(x crypto.PublicKey) bool {
xx, ok := x.(PublicKey)
if !ok {
return false
}
return bytes.Equal(pub, xx)
}
75 changes: 75 additions & 0 deletions sign/ed25519/signapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package ed25519

import (
"crypto/rand"
"encoding/asn1"

"github.com/cloudflare/circl/sign"
)

// Scheme is
const Scheme = scheme(sign.Ed25519)

type scheme sign.SchemeID

func (scheme) ID() sign.SchemeID { return sign.SchemeID(Scheme) }
func (scheme) Name() string { return "Ed25519" }
func (scheme) PublicKeySize() uint { return PublicKeySize }
func (scheme) PrivateKeySize() uint { return PrivateKeySize }
func (scheme) SignatureSize() uint { return SignatureSize }
func (scheme) SeedSize() uint { return SeedSize }
func (scheme) TLSIdentifier() uint { return 0xfe61 /* TODO */ }
func (scheme) Oid() asn1.ObjectIdentifier {
return asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 44363, 15, 10 /* TODO */}
}

func (scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
return GenerateKey(rand.Reader)
}

func (scheme) Sign(
sk sign.PrivateKey,
message []byte,
opts *sign.SignatureOpts) []byte {
priv, ok := sk.(PrivateKey)
if !ok {
panic(sign.ErrType)
}
return Sign(priv, message)
}

func (scheme) Verify(
pk sign.PublicKey,
message, signature []byte,
opts *sign.SignatureOpts) bool {
pub, ok := pk.(PublicKey)
if !ok {
panic(sign.ErrType)
}
return Verify(pub, message, signature)
}

func (scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
privateKey := NewKeyFromSeed(seed)
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, privateKey[SeedSize:])
return publicKey, privateKey
}

func (scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
if len(buf) < PublicKeySize {
return nil, sign.ErrPubKeySize
}
pub := make(PublicKey, PublicKeySize)
copy(pub, buf[:PublicKeySize])
return pub, nil
}

func (scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
if len(buf) < PrivateKeySize {
return nil, sign.ErrPrivKeySize
}
priv := make(PrivateKey, PrivateKeySize)
copy(priv, buf[:PrivateKeySize])
return priv, nil
}
33 changes: 22 additions & 11 deletions sign/ed448/ed448.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (

"github.com/cloudflare/circl/ecc/goldilocks"
sha3 "github.com/cloudflare/circl/internal/shake"
"github.com/cloudflare/circl/sign"
)

const (
Expand Down Expand Up @@ -83,10 +84,7 @@ type PublicKey []byte
// Equal reports whether pub and x have the same value.
func (pub PublicKey) Equal(x crypto.PublicKey) bool {
xx, ok := x.(PublicKey)
if !ok {
return false
}
return bytes.Equal(pub, xx)
return ok && bytes.Equal(pub, xx)
}

// PrivateKey is the type of Ed448 private keys. It implements crypto.Signer.
Expand All @@ -95,10 +93,7 @@ type PrivateKey []byte
// Equal reports whether priv and x have the same value.
func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
xx, ok := x.(PrivateKey)
if !ok {
return false
}
return subtle.ConstantTimeCompare(priv, xx) == 1
return ok && subtle.ConstantTimeCompare(priv, xx) == 1
}

// Public returns the PublicKey corresponding to priv.
Expand All @@ -117,6 +112,22 @@ func (priv PrivateKey) Seed() []byte {
return seed
}

func (priv PrivateKey) Scheme() sign.Scheme { return Scheme }

func (pub PublicKey) Scheme() sign.Scheme { return Scheme }

func (priv PrivateKey) MarshalBinary() (data []byte, err error) {
privateKey := make(PrivateKey, PrivateKeySize)
copy(privateKey, priv)
return privateKey, nil
}

func (pub PublicKey) MarshalBinary() (data []byte, err error) {
publicKey := make(PublicKey, PublicKeySize)
copy(publicKey, pub)
return publicKey, nil
}

// Sign creates a signature of a message given a key pair.
// This function supports all the two signature variants defined in RFC-8032,
// namely Ed448 (or pure EdDSA) and Ed448Ph.
Expand Down Expand Up @@ -192,7 +203,7 @@ func newKeyFromSeed(privateKey, seed []byte) {
_ = goldilocks.Curve{}.ScalarBaseMult(s).ToBytes(privateKey[SeedSize:])
}

func sign(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
if len(ctx) > ContextMaxSize {
panic(fmt.Errorf("ed448: bad context length: " + strconv.Itoa(len(ctx))))
}
Expand Down Expand Up @@ -264,7 +275,7 @@ func sign(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash
// It will panic if len(privateKey) is not PrivateKeySize.
func Sign(priv PrivateKey, message []byte, ctx string) []byte {
signature := make([]byte, SignatureSize)
sign(signature, priv, message, []byte(ctx), false)
signAll(signature, priv, message, []byte(ctx), false)
return signature
}

Expand All @@ -275,7 +286,7 @@ func Sign(priv PrivateKey, message []byte, ctx string) []byte {
// 255. It can be empty.
func SignPh(priv PrivateKey, message []byte, ctx string) []byte {
signature := make([]byte, SignatureSize)
sign(signature, priv, message, []byte(ctx), true)
signAll(signature, priv, message, []byte(ctx), true)
return signature
}

Expand Down
Loading

0 comments on commit 309e00a

Please sign in to comment.