wots

package module
v0.0.0-...-b19125f Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2018 License: BSD-2-Clause Imports: 4 Imported by: 1

README

Go implementation of Winternitz-Lamport-Diffie one-time signature scheme.

If the hash function is one-way and of sufficient length, the private key is
random, not known to the attacker, and used to sign only one message, and
there are no bugs in this implementation, it is infeasible to forge
signatures (even on quantum computer, provided that it can't break the
underlying hash function).


INSTALLATION

	$ go get github.com/dchest/wots

USAGE

	import "github.com/dchest/wots"

See documentation for example.

DOCUMENTATION

See https://godoc.org/github.com/dchest/wots

LICENSE

BSD-like, see LICENSE file.

Documentation

Overview

Package wots implements Winternitz-Lamport-Diffie one-time signature scheme.

If the hash function is one-way and of sufficient length, the private key is random, not known to the attacker, and used to sign only one message, and there are no bugs in this implementation, it is infeasible to forge signatures (even on quantum computer, provided that it can't break the underlying hash function).

Implementation details

Cost/size trade-off parameter w=8 bits, which means that public key generation takes (n+2)*256+1 hash function evaluations, where n is hash output size in bytes. Similarly, on average, signing or verifying a single message take 1+((n+2)*255)/2 evaluations.

Message hash is calculated with randomization as specified in NIST SP-800-106 "Randomized Hashing for Digital Signatures", with length of randomization string equal to the length of hash function output. The randomization string is prepended to the signature.

Example
package main

import (
	"crypto/rand"
	"crypto/sha256"
	"fmt"

	"github.com/dchest/wots"
)

func main() {
	// Define scheme using SHA-256. There's no need to always
	// create this scheme, it can be a global variable.
	var wotssha256 = wots.NewScheme(sha256.New, rand.Reader)

	// Generating key pair.
	privateKey, publicKey, err := wotssha256.GenerateKeyPair()
	if err != nil {
		panic("key generation failed")
	}

	// Signing.
	message := []byte("Hello world!")
	signature, err := wotssha256.Sign(privateKey, message) // => 1120-byte signature
	if err != nil {
		panic("signature calculation failed")
	}

	// After signing once, private key must not be used to sign more messages!
	// This is a one-time signature scheme.

	// Verifying.
	if wotssha256.Verify(publicKey, message, signature) {
		fmt.Println("verification succeeded")
	} else {
		fmt.Println("verification failed")
	}
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type PrivateKey

type PrivateKey []byte

PrivateKey represents a private key.

type PublicKey

type PublicKey []byte

PublicKey represents a public key.

type Scheme

type Scheme struct {
	// contains filtered or unexported fields
}

Scheme represents one-time signature signing/verification configuration.

func NewScheme

func NewScheme(h func() hash.Hash, rand io.Reader) *Scheme

NewScheme returns a new signing/verification scheme from the given function returning hash.Hash type and a random byte reader (must be cryptographically secure, such as crypto/rand.Reader).

The hash function output size must have minimum 16 and maximum 128 bytes, otherwise GenerateKeyPair method will always return error.

func (*Scheme) GenerateKeyPair

func (s *Scheme) GenerateKeyPair() (PrivateKey, PublicKey, error)

GenerateKeyPair generates a new private and public key pair.

func (*Scheme) PrivateKeySize

func (s *Scheme) PrivateKeySize() int

PrivateKeySize returns private key size in bytes.

func (*Scheme) PublicKeyFromPrivate

func (s *Scheme) PublicKeyFromPrivate(privateKey PrivateKey) (PublicKey, error)

PublicKeyFromPrivate returns a public key corresponding to the given private key.

func (*Scheme) PublicKeySize

func (s *Scheme) PublicKeySize() int

PublicKeySize returns public key size in bytes.

func (*Scheme) Sign

func (s *Scheme) Sign(privateKey PrivateKey, message []byte) (sig []byte, err error)

Sign signs an arbitrary length message using the given private key and returns signature.

IMPORTANT: Do not use the same private key to sign more than one message! It's a one-time signature.

func (*Scheme) SignatureSize

func (s *Scheme) SignatureSize() int

SignatureSize returns signature size in bytes.

func (*Scheme) Verify

func (s *Scheme) Verify(publicKey PublicKey, message []byte, sig []byte) bool

Verify verifies the signature of message using the public key, and returns true iff the signature is valid.

Note: verification time depends on message and signature.

Jump to

Keyboard shortcuts

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