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 ¶
- type PrivateKey
- type PublicKey
- type Scheme
- func (s *Scheme) GenerateKeyPair() (PrivateKey, PublicKey, error)
- func (s *Scheme) PrivateKeySize() int
- func (s *Scheme) PublicKeyFromPrivate(privateKey PrivateKey) (PublicKey, error)
- func (s *Scheme) PublicKeySize() int
- func (s *Scheme) Sign(privateKey PrivateKey, message []byte) (sig []byte, err error)
- func (s *Scheme) SignatureSize() int
- func (s *Scheme) Verify(publicKey PublicKey, message []byte, sig []byte) bool
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Scheme ¶
type Scheme struct {
// contains filtered or unexported fields
}
Scheme represents one-time signature signing/verification configuration.
func NewScheme ¶
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 ¶
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 ¶
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 ¶
SignatureSize returns signature size in bytes.