pblind

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

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

Go to latest
Published: Oct 24, 2023 License: GPL-3.0 Imports: 8 Imported by: 2

README

⚠️⚠️⚠️⚠️ Caution: The Masayuki Abe and Tatsuaki Okamoto signature scheme is not secure for concurrent sessions (multiple simultaneous clients). See the paper On the (in)security of ROS from 2020 for more details. I advise to use another scheme. ⚠️⚠️⚠️⚠️

Pblind

Pblind is a small library implementing the Masayuki Abe and Tatsuaki Okamoto scheme for partially blind signatures based on Schnorr signatures. As the underlying group pblind allows the use of all the (NIST) curves from the `crypto/elliptic`` package.

Note: pblind is not stable, message and signature formats subject to change.

Partially blind signatures

Partially blind signatures allows a signer and a requester to construct a blind signature on a document with additional common information ("info") visible to both signer and requester. This allows the signer some level of control over the contents of the document being signed, while also providing a level of privacy / untraceability for the requester, at the two extremes:

  • If the entire document is used as "info", you get an ordinary signature scheme.
  • If "info" is a constant, the scheme becomes a traditional blind-signature scheme.

The interesting applications lie somewhere between the two. One such example might be a shop system allowing the buyers to sign anonymous reviews of the products they have purchased:

Using traditional blind signatures it is not possible for the service to know what product the buyer is reviewing and therefore not possible to check if they have purchased the item at all. This problem of "controlling the domain" of the blind signatures is usually solved by having district keys for the different message types, but clearly becomes infeasible when the number of types becomes large. However using partially blind signatures an item identifier can be used as common info and reviews of any item in the shop can be verified using the same key.

Example usage

Below a simplied example of how to use pblind (without the required error handling). All messages in pblind can be serialized using any marshaling which supports *big.Int. Here an example using asn1:

func main() {

	// generate a key-pair

	curve := elliptic.P256()

	sk, _ := pblind.NewSecretKey(curve)
	pk := sk.GetPublicKey()

	msgStr := []byte("blinded message")
	infoStr := []byte("plaintext info")

	// create signer/requester with shared public info

	info, _ := pblind.CompressInfo(curve, infoStr)
	requester, _ := pblind.CreateRequester(pk, info, msgStr)
	signer, _ := pblind.CreateSigner(sk, info)

	// signer

	msg1S, _ := signer.CreateMessage1()
	ser1S, _ := asn1.Marshal(msg1S)
	fmt.Println("signer -> requester :", len(ser1S), "bytes")

	// requester

	var msg1R pblind.Message1
	asn1.Unmarshal(ser1S, &msg1R)
	requester.ProcessMessage1(msg1R)
	msg2R, _ := requester.CreateMessage2()
	ser2R, _ := asn1.Marshal(msg2R)
	fmt.Println("requester -> signer :", len(ser2R), "bytes")

	// signer

	var msg2S pblind.Message2
	asn1.Unmarshal(ser2R, &msg2S)
	signer.ProcessMessage2(msg2S)
	msg3S, _ := signer.CreateMessage3()
	ser3S, _ := asn1.Marshal(msg3S)
	fmt.Println("signer -> requester :", len(ser3S), "bytes")

	// requester

	var msg3R pblind.Message3
	asn1.Unmarshal(ser3S, &msg3R)
	requester.ProcessMessage3(msg3R)
	signature, _ := requester.Signature()
	sig, _ := asn1.Marshal(signature)
	fmt.Println("encoded signature   :", len(sig), "bytes")

	// check signature

	fmt.Println("ok:", pk.Check(signature, info, msgStr))
}

Of course json, xml, bson, gob or another format could also be used.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrorPointNotOnCurve       = errors.New("Point not on curve")
	ErrorInvalidSignerState    = errors.New("Signer is in invalid state")
	ErrorInvalidRequesterState = errors.New("Signer is in invalid state")
	ErrorInvalidSignature      = errors.New("Signature is invalid")
	ErrorInvalidScalar         = errors.New("Scalar is too large")
	ErrorInvalidPublicKey      = errors.New("Public key is invalid")
)

Functions

This section is empty.

Types

type Info

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

func CompressInfo

func CompressInfo(curve elliptic.Curve, info []byte) (c Info, err error)

func (Info) Equals

func (info1 Info) Equals(info2 Info) bool

func (Info) String

func (info Info) String() string

type Message1

type Message1 struct {
	Ax, Ay *big.Int
	Bx, By *big.Int
}

type Message2

type Message2 struct {
	E *big.Int
}

type Message3

type Message3 struct {
	R *big.Int
	C *big.Int
	S *big.Int
}

type PublicKey

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

func PublicKeyFromBytes

func PublicKeyFromBytes(curve elliptic.Curve, val []byte) (PublicKey, error)

func (PublicKey) Bytes

func (pk PublicKey) Bytes() []byte

func (PublicKey) Check

func (pk PublicKey) Check(sig Signature, info Info, msg []byte) bool

func (PublicKey) String

func (pk PublicKey) String() string

type SecretKey

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

func NewSecretKey

func NewSecretKey(curve elliptic.Curve) (SecretKey, error)

func SecretKeyFromBytes

func SecretKeyFromBytes(curve elliptic.Curve, val []byte) SecretKey

func (SecretKey) Bytes

func (sk SecretKey) Bytes() []byte

func (SecretKey) GetPublicKey

func (sk SecretKey) GetPublicKey() PublicKey

func (SecretKey) String

func (sk SecretKey) String() string

type Signature

type Signature struct {
	P *big.Int
	W *big.Int
	O *big.Int
	G *big.Int
}

type StateRequester

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

func CreateRequester

func CreateRequester(pk PublicKey, info Info, message []byte) (*StateRequester, error)

func (*StateRequester) CreateMessage2

func (st *StateRequester) CreateMessage2() (Message2, error)

func (*StateRequester) ProcessMessage1

func (st *StateRequester) ProcessMessage1(msg Message1) error

func (*StateRequester) ProcessMessage3

func (st *StateRequester) ProcessMessage3(msg Message3) error

func (*StateRequester) Signature

func (st *StateRequester) Signature() (Signature, error)

type StateSigner

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

func CreateSigner

func CreateSigner(sk SecretKey, info Info) (*StateSigner, error)

func (*StateSigner) CreateMessage1

func (st *StateSigner) CreateMessage1() (Message1, error)

func (*StateSigner) CreateMessage3

func (st *StateSigner) CreateMessage3() (Message3, error)

func (*StateSigner) ProcessMessage2

func (st *StateSigner) ProcessMessage2(msg Message2) error

Jump to

Keyboard shortcuts

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