ringsig: github.com/Nik-U/ringsig Index | Examples | Files | Directories

package ringsig

import "github.com/Nik-U/ringsig"

Package ringsig implements ring signatures in Go. Ring signatures are a special type of digital signature that prove a message was signed by one of a set of possible signers, without revealing which member of the set created the signature. Ring signatures were originally proposed by Rivest, Shamir, and Tauman in the paper titled "How to Leak a Secret".

Ring signatures can be used to construct many interesting schemes. One traditional example is leaking secret documents while protecting the identity of the leaker. Another example is the sender of a message proving their identity to the recipient without allowing the recipient to convincingly convey this proof to a third party.


A ring signature scheme consists of four algorithms: setup, key generation, signing, and verification.

The setup phase occurs once, before the deployment of the scheme. It produces scheme-specific parameters that must be shared with all participants of the system. The setup algorithm is of the following form:

params ← setup()

These parameters must be passed to the other functions of the scheme. Some schemes do not require the setup phase (i.e., their parameters are empty).

The key generation algorithm is of the following form:

(privKey, pubKey) ← keyGen(params)

keyGen returns a private key and the corresponding public key.

The signing algorithm is of the following form:

signature ← sign(params, message, ring, privKey)

sign returns a signature for the given message. ring is a set of public keys, and privKey is a secret key corresponding to one of the public keys in ring.

The verification algorithm is of the following form:

ok ← verify(params, message, signature, ring)

verify returns true if the given signature is valid for the given message. The signature is valid if it was produced by any secret key corresponding to a public key in the ring.

All ring signature schemes share the property that it is computationally infeasible, given only a message, signature, and ring, to determine which secret key was used to produce the signature.

Security Properties

Some ring signature schemes provide additional security properties or introduce some additional limitations (usually in order to improve efficiency or provable security). Schemes might exhibit one or more of the following characteristics:

• Chosen-key anonymity: the scheme preserves anonymity even when only two members of the ring are honest (i.e., not colluding with the adversary).

• Full-key disclosure anonymity: the scheme preserves anonymity even when the secret keys of all users are disclosed to the adversary after the signature has been produced.

• Fixed-ring unforgeability: an adversary cannot produce a signature for a message that verifies against a given ring, even when they can receive valid signatures for selected (different) messages in the same ring.

• Chosen-subring unforgeability: the same as fixed-ring unforgeability, but both the final output ring and the signing oracle rings can be subrings chosen by the adversary.

• Insider corruption unforgeability: the same as chosen-subring unforgeability, but the adversary can also corrupt honest users, thereby revealing their secret keys. The adversary should not be able to produce a valid message for a subring that does not contain a corrupted user.

• c-user: the ring signature only operates on fixed rings of size c.

• Identity-based: public keys are derived solely from plaintext strings, allowing users to be included in the ring even if they do not participate in the signature scheme.

Ring signature schemes may also prove their security properties in different models. For example, some schemes are only secure in the random oracle model, while others are secure in the standard model. Different may schemes also require different infeasibility assumptions.

For additional information about ring signature properties, see "Ring Signatures: Stronger Definitions, and Constructions Without Random Oracles" from Bender, Katz, and Morselli.


Ring signature implementations are placed in subpackages. The rationale for this is that some implementations may require complex dependencies that not all clients need.


This package is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

For additional details, see the COPYING and COPYING.LESSER files.


// Generate new scheme parameters
scheme, _ := shacham.New(2)

// In the real world, these parameters would be saved using scheme.WriteTo
// and then loaded by the clients using shacham.Load.

// Two clients generate key pairs
alice := scheme.KeyGen()
bob := scheme.KeyGen()

// We will sign over the ring of the two users. In general, higher level
// communication protocols will somehow specify the ring used to sign the
// message (either explicitly or implicitly).
ring := []ringsig.PublicKey{alice.Public, bob.Public}

// Alice signs a message intended for Bob
sig, _ := scheme.Sign("message", ring, alice)

// Bob verifies the signature
if scheme.Verify("message", sig, ring) {
    // Both Alice and Bob are now convinced that Alice signed the message.
    // However, nobody else can be convinced of this cryptographically.



Package Files

doc.go errors.go ringsig.go


var (
    ErrUnsupportedLevel  = errors.New("unsupported security level requested")
    ErrInvalidParameters = errors.New("scheme parameters are invalid")
    ErrWrongScheme       = errors.New("keys used in the wrong scheme")
    ErrNotInRing         = errors.New("public key is not part of the ring")
    ErrInvalidKeyPair    = errors.New("private key does not match public key")
    ErrRingTooSmall      = errors.New("ring is too small")
    ErrRingDuplication   = errors.New("ring contains duplicated key")

type Exportable Uses

type Exportable interface {
    Bytes() []byte

Exportable represents a type that can be encoded into a binary stream. They can be written to a Writer or transformed directly into bytes.

type KeyPair Uses

type KeyPair struct {
    Public  PublicKey
    Private PrivateKey

KeyPair is the combination of a public key and the associated private key. It implements Exportable.

func (*KeyPair) Bytes Uses

func (pair *KeyPair) Bytes() []byte

func (*KeyPair) WriteTo Uses

func (pair *KeyPair) WriteTo(w io.Writer) (n int64, err error)

type PrivateKey Uses

type PrivateKey interface {

PrivateKey represents a private key for a ring signature scheme. Private keys are used to create signatures.

type PublicKey Uses

type PublicKey interface {
    Equals(PublicKey) bool

PublicKey represents a public key for a ring signature scheme. Public keys are used to form rings, which in turn are used to sign and verify signatures. Every public key has an associated private key.

type Scheme Uses

type Scheme interface {

    KeyGen() *KeyPair
    Sign(message string, ring []PublicKey, key *KeyPair) (Signature, error)
    Verify(message string, signature Signature, ring []PublicKey) bool

    LoadPublicKey(io.Reader) (PublicKey, error)
    LoadPrivateKey(io.Reader) (PrivateKey, error)
    LoadKeyPair(io.Reader) (*KeyPair, error)
    LoadSignature(io.Reader) (Signature, error)

Scheme represents a ring signature scheme. All ring signature operations must be performed in the context of a scheme, and all protocol participants must share the same scheme.

Schemes can either be generated or loaded. Scheme generation is performed by calling a New* function for the desired scheme — a task normally performed by a trusted authority. The scheme can then be exported and distributed to the protocol participants, who duplicate it using a Load* function.

Key generation occurs by calling KeyGen on the scheme. The resulting key pair can be saved, and the public key can be independently exported for transmission to other parties.

Signatures are generated using the Sign method. Sign will return a signature or an error in case of failure. Rings must have at least two public keys in them, and one of the public keys must match the signing key pair. There must also be no duplication of public keys in the ring.

Signatures are verified using the Verify method. The given ring must be the same as the one used to sign the message (e.g., it may not be a subset or superset).

All keys and signatures must be loaded in the context of a scheme using the Load* methods.

type Signature Uses

type Signature interface {

Signature represents a digital signature of a message under a ring signature scheme.


shachamPackage shacham implements efficient Shacham-Waters ring signatures.

Package ringsig imports 3 packages (graph) and is imported by 2 packages. Updated 2016-07-21. Refresh now. Tools for package owners.