signkey

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2021 License: Apache-2.0 Imports: 7 Imported by: 0

README

SignKey

Signature verification based on Ed25519.

If you are interested in a CLI utility, go to the signutil directory.

Quick start

This package can create a key, sign and verify signatures. It does not concern itself with the actual content being signed.

// other key types are available, only difference is the prefix
key, _ := signkey.NewKey(signkey.UserKeyPrefix)

// serialize the public key and secret
// you need to keep the secret...secret!
pubkeyStr, _ := key.PublicKey()
secretStr, _ := key.Secret()

// deserialize to a new key instance using the secret
// you can sign AND verify data
key2, _ := signkey.FromSecret(secretStr)
data := []byte("howdy partner")
sig, _ := key2.Sign(data)
err := key2.Verify(data, sig)

// now image your friend knows your public key.
// we pass sig and data to your friend...

// deserialize to a new key using the public key.
// this new key can only do verification.
key3, _ := signkey.FromPublicKey(pubkeyStr)
err3 := key3.Verify(data, sig)
if signkey.IsInvalidSignature(err3) {
    panic("bad signature!")
}

// now your friend is sure that `data` came from you.

Public key and secret

Both are serialized to base32 encoded string, i.e. 0-9, A-Z.

Source of entropy

The NewKey method uses rand.Reader as its source of entropy. You can change that by simply prepopulate the raw secret with your choice of random data. Just make sure it
is 32 bytes long.

var rawSecret [signkey.SecretSize]byte
_, err := io.ReadFull(rand.Reader, rawSecret[:])
user, _ := signkey.FromRawSecret(UserKeyPrefix, rawSecret)

Documentation

Overview

Package signkey implements message signing using ed25519.

Use NewKey method to create a key, or From* methods to unmarshal from a previously created key.

Key unmarshaled from secret can sign and verify messages, but key unmarshaled from public key can only verify.

Use package signutil for a CLI utility that implements signkey.

Index

Examples

Constants

View Source
const SecretSize = ed25519.SeedSize

SecretSize is ed25519 seed size.

Variables

View Source
var (
	// CannotSignError is returned if key cannot be used to sign.
	CannotSignError = errors.New("key cannot be used to sign")
	// InvalidChecksumError is returned if checksum is invalid.
	InvalidChecksumError = errors.New("checksum is invalid")
	// InvalidEncodingError is returned if key cannot be decoded.
	InvalidEncodingError = errors.New("invalid key encoding")
	// InvalidKeyPrefixError is returned if key prefix byte is invalid.
	InvalidKeyPrefixError = errors.New("invalid key prefix byte")
	// InvalidSecretLengthError is returned if secret size is invalid.
	InvalidSecretLengthError = errors.New("invalid secret size")
	// InvalidSecretError is returned if secret is invalid.
	InvalidSecretError = errors.New("invalid secret")
	// InvalidSignatureError is returned if signature is invalid.
	InvalidSignatureError = errors.New("invalid signature")
	// InvalidPublicKeyError is returned if public key is invalid.
	InvalidPublicKeyError = errors.New("invalid public key")
	// PublicKeyKnownOnlyError is returned if only public key is known.
	PublicKeyKnownOnlyError = errors.New("only public key is known")
)

Functions

func IsInvalidSignature

func IsInvalidSignature(err error) bool

IsInvalidSignature returns true if err is InvalidSignatureError.

func IsKey

func IsKey(src []byte) bool

IsKey returns true only if the encoded data is a valid key.

func IsPublicKey

func IsPublicKey(src string) bool

IsPublicKey returns true if the key is a public public. Only private and secret keys are not public.

Types

type Key

type Key interface {
	// Secret returns the base-32 encoded secret.
	Secret() (string, error)
	// PublicKey returns the base-32 encoded public key.
	PublicKey() (string, error)
	// Sign calculates the signature of input, using secret.
	Sign(input []byte) ([]byte, error)
	// Verify input against signature sig, using public key.
	Verify(input []byte, sig []byte) error
	// Reset overwrites internal data with random data.
	Reset()
}

Key is abstract interface for a key.

func FromPublicKey

func FromPublicKey(public string) (Key, error)

FromPublicKey unmarshals a key using the public key specified. This key can be used to verify signatures only.

func FromRawSecret

func FromRawSecret(prefix KeyPrefix, rawSecret []byte) (Key, error)

FromRawSecret is the same as FromSecret, but assumes that the secret provided has already been decoded.

Example

ExampleFromRawSecret demonstrates creating a key from an alternative source of entropy.

package main

import (
	"fmt"
	"github.com/imacks/signkey"
	"io"
	"os"
)

func main() {
	// use /dev/urandom to populate rawSeed with entropy data.
	// note that rawSeed must be exactly signkey.SecretSize long.
	ef, err := os.Open("/dev/urandom")
	if err != nil {
		panic(err)
	}
	var rawSeed [signkey.SecretSize]byte
	_, err = io.ReadFull(ef, rawSeed[:])
	if err != nil {
		panic(err)
	}

	// create the key using rawSeed
	key, err := signkey.FromRawSecret(signkey.UserKeyPrefix, rawSeed[:])
	if err != nil {
		panic(err)
	}

	// show that signature verification works
	message := []byte("hello world")
	signature, _ := key.Sign(message)
	err = key.Verify(message, signature)
	if signkey.IsInvalidSignature(err) {
		fmt.Printf("invalid signature\n")
	} else {
		fmt.Printf("good signature\n")
	}

}
Output:

good signature

func FromSecret

func FromSecret(secret string) (Key, error)

FromSecret unmarshals a key using the secret specified. This key can both sign and verify.

func NewKey

func NewKey(prefix KeyPrefix) (Key, error)

NewKey creates a new key, using the key prefix specified. This function uses rand.Reader as its source of entropy. If you want to specify a custom entropy source, use the FromRawSecret function instead.

type KeyPrefix

type KeyPrefix byte

KeyPrefix represents the key type.

const (
	// SecretKeyPrefix denotes secret key.
	SecretKeyPrefix KeyPrefix = 18 << 3 // base32 S
	// PrivateKeyPrefix denotes private key.
	PrivateKeyPrefix KeyPrefix = 15 << 3 // base32 P
	// UserKeyPrefix denotes user key.
	UserKeyPrefix KeyPrefix = 20 << 3 // base32 U
	// UnknownKeyPrefix denotes unknown key type.
	UnknownKeyPrefix KeyPrefix = 23 << 3 // base32 X
)

func KeyType

func KeyType(src string) KeyPrefix

KeyType returns the key prefix, which indicates the type of key.

func (KeyPrefix) String

func (p KeyPrefix) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL