Пример #1
0
// Checks the signature against
// the message
func SchnorrVerify(suite abstract.Suite,
	kp SchnorrPublicKey,
	msg []byte, sig []byte) (bool, error) {

	buf := bytes.NewBuffer(sig)
	signature := SchnorrSignature{}
	err := abstract.Read(buf, &signature, suite)
	if err != nil {
		return false, err
	}

	s := signature.S
	e := signature.E

	var gs, ye, r abstract.Point
	gs = suite.Point().Mul(nil, s)  // g^s
	ye = suite.Point().Mul(kp.Y, e) // y^e
	r = suite.Point().Add(gs, ye)   // g^xy^e

	r_bin, _ := r.MarshalBinary()
	msg_and_r := append(msg, r_bin...)
	hasher := sha3.New256()
	hasher.Write(msg_and_r)
	h := hasher.Sum(nil)

	// again I'm hoping this just reads the state out
	// and doesn't  actually perform any ops
	lct := suite.Cipher(h)

	ev := suite.Secret().Pick(lct)
	return ev.Equal(e), nil
}
Пример #2
0
// ReadPubKey will read the file and decrypt the public key inside
// It takes a suite to decrypt and a file name
// Returns the public key, whatever text is in front and an error if anything went wrong
func ReadPubKey(suite abstract.Suite, fileName string) (abstract.Point, string, error) {

	public := suite.Point()
	// Opening files
	pubFile, err := os.Open(fileName)
	if err != nil {
		return nil, "", err
	}
	defer pubFile.Close()

	// read the string before
	by, err := ioutil.ReadAll(pubFile)
	if err != nil {
		return nil, "", errors.New(fmt.Sprintf("Error reading the whole file  %s", err))
	}
	splits := strings.Split(string(by), " ")
	if len(splits) != 2 {
		return nil, "", errors.New(fmt.Sprintf("Error reading pub key file format is not correct (val space val)"))
	}

	before := splits[0]
	key := strings.NewReader(splits[1])

	// Some readings
	public, err = ReadPub64(suite, key)
	if err != nil {
		return nil, "", errors.New(fmt.Sprintf("Error reading the public key itself: %s", err))
	}

	return public, before, nil

}
Пример #3
0
func ElGamalVerify(suite abstract.Suite, message []byte, publicKey abstract.Point,
	signatureBuffer []byte, g abstract.Point) error {

	// Decode the signature
	buf := bytes.NewBuffer(signatureBuffer)
	sig := basicSig{}
	if err := abstract.Read(buf, &sig, suite); err != nil {
		return err
	}
	r := sig.R
	c := sig.C

	// Compute base**(r + x*c) == T
	var P, T abstract.Point
	P = suite.Point()
	T = suite.Point()
	T.Add(T.Mul(g, r), P.Mul(publicKey, c))

	// Verify that the hash based on the message and T
	// matches the challange c from the signature
	c = hashElGamal(suite, message, T)
	if !c.Equal(sig.C) {
		return errors.New("invalid signature")
	}

	return nil
}
/* GenerateZ takes some random agreed information and creates
   Z the "public-only" key that is witness-independent as per
   the paper. We've probably broken that slightly in this implementation
   because I could not pick a point without generating it
   via a Secret, instead of directly via a Point - that is, even as a
   32-byte string, we cannot decode on C25519 (and this wouldn't work
   for abstract suites anyway).

   However, it demonstrates the idea.
*/
func GenerateZ(suite abstract.Suite, info []byte) (abstract.Point, error) {

	hasher := sha3.New256()
	hasher.Write(info)
	zraw := hasher.Sum(nil)

	//I think this might be cheating
	zrawCt := suite.Cipher(zraw)

	zfactor := suite.Secret().Pick(zrawCt)
	Z := suite.Point()
	Z.Mul(nil, zfactor)

	// every 32-bit integer exists on Curve25519 only if we have the fullgroup
	// this should work, but doesn't.

	/*var Z abstract.Point
	  zrawBuf := bytes.NewBuffer(zraw)
	  err := abstract.Read(zrawBuf, &Z, suite);
	  if err != nil {
	      return nil, err
	  }*/

	return Z, nil
}
Пример #5
0
func NewNode(hn coconet.Host, suite abstract.Suite, random cipher.Stream) *Node {
	sn := &Node{Host: hn, suite: suite}
	msgSuite = suite
	sn.PrivKey = suite.Secret().Pick(random)
	sn.PubKey = suite.Point().Mul(nil, sn.PrivKey)

	sn.peerKeys = make(map[string]abstract.Point)
	sn.Rounds = make(map[int]*Round)

	sn.closed = make(chan error, 20)
	sn.done = make(chan int, 10)
	sn.commitsDone = make(chan int, 10)
	sn.viewChangeCh = make(chan string, 0)

	sn.FailureRate = 0
	h := fnv.New32a()
	h.Write([]byte(hn.Name()))
	seed := h.Sum32()
	sn.Rand = rand.New(rand.NewSource(int64(seed)))
	sn.Host.SetSuite(suite)
	sn.VoteLog = NewVoteLog()
	sn.Actions = make(map[int][]*Vote)
	sn.RoundsPerView = 100
	return sn
}
Пример #6
0
// Determine all the alternative DH point positions for a ciphersuite.
func (si *suiteInfo) init(ste abstract.Suite, nlevels int) {
	si.ste = ste
	si.tag = make([]uint32, nlevels)
	si.pos = make([]int, nlevels)
	si.plen = ste.Point().(abstract.Hiding).HideLen() // XXX

	// Create a pseudo-random stream from which to pick positions
	str := fmt.Sprintf("NegoCipherSuite:%s", ste.String())
	rand := ste.Cipher([]byte(str))

	// Alternative 0 is always at position 0, so start with level 1.
	levofs := 0 // starting offset for current level
	//fmt.Printf("Suite %s positions:\n", ste.String())
	for i := 0; i < nlevels; i++ {

		// Pick a random position within this level
		var buf [4]byte
		rand.XORKeyStream(buf[:], buf[:])
		levlen := 1 << uint(i) // # alt positions at this level
		levmask := levlen - 1  // alternative index mask
		si.tag[i] = binary.BigEndian.Uint32(buf[:])
		levidx := int(si.tag[i]) & levmask
		si.pos[i] = levofs + levidx*si.plen

		//fmt.Printf("%d: idx %d/%d pos %d\n",
		//		i, levidx, levlen, si.pos[i])

		levofs += levlen * si.plen // next level table offset
	}

	// Limit of highest point field
	si.max = si.pos[nlevels-1] + si.plen
}
Пример #7
0
// Binary shuffle ("biffle") for 2 ciphertexts based on general ZKPs.
func Biffle(suite abstract.Suite, G, H abstract.Point,
	X, Y [2]abstract.Point, rand abstract.Cipher) (
	Xbar, Ybar [2]abstract.Point, prover proof.Prover) {

	// Pick the single-bit permutation.
	bit := int(random.Byte(rand) & 1)

	// Pick a fresh ElGamal blinding factor for each pair
	var beta [2]abstract.Scalar
	for i := 0; i < 2; i++ {
		beta[i] = suite.Scalar().Pick(rand)
	}

	// Create the output pair vectors
	for i := 0; i < 2; i++ {
		pi_i := i ^ bit
		Xbar[i] = suite.Point().Mul(G, beta[pi_i])
		Xbar[i].Add(Xbar[i], X[pi_i])
		Ybar[i] = suite.Point().Mul(H, beta[pi_i])
		Ybar[i].Add(Ybar[i], Y[pi_i])
	}

	or := bifflePred()
	secrets := map[string]abstract.Scalar{
		"beta0": beta[0],
		"beta1": beta[1]}
	points := bifflePoints(suite, G, H, X, Y, Xbar, Ybar)
	choice := map[proof.Predicate]int{or: bit}
	prover = or.Prover(suite, secrets, points, choice)
	return
}
Пример #8
0
// Create new signing node that incorporates a given private key
func NewKeyedNode(hn coconet.Host, suite abstract.Suite, PrivKey abstract.Secret) *Node {
	sn := &Node{Host: hn, suite: suite, PrivKey: PrivKey}
	sn.PubKey = suite.Point().Mul(nil, sn.PrivKey)

	sn.peerKeys = make(map[string]abstract.Point)

	sn.closed = make(chan error, 20)
	sn.done = make(chan int, 10)
	sn.commitsDone = make(chan int, 10)
	sn.viewChangeCh = make(chan string, 0)

	sn.RoundCommits = make(map[int][]*SigningMessage)
	sn.RoundResponses = make(map[int][]*SigningMessage)

	sn.FailureRate = 0
	h := fnv.New32a()
	h.Write([]byte(hn.Name()))
	seed := h.Sum32()
	sn.Rand = rand.New(rand.NewSource(int64(seed)))
	sn.Host.SetSuite(suite)
	sn.VoteLog = NewVoteLog()
	sn.Actions = make(map[int][]*Vote)
	sn.RoundsPerView = 0
	sn.Rounds = make(map[int]Round)
	sn.MaxWait = 50 * time.Second
	return sn
}
Пример #9
0
// VerifySignature verifies if the challenge and the secret (from the response phase) form a
// correct signature for this message using the aggregated public key.
func VerifySignature(suite abstract.Suite, msg []byte, public abstract.Point, challenge, secret abstract.Scalar) error {
	// recompute the challenge and check if it is the same
	commitment := suite.Point()
	commitment = commitment.Add(commitment.Mul(nil, secret), suite.Point().Mul(public, challenge))

	return verifyCommitment(suite, msg, commitment, challenge)

}
Пример #10
0
func ElGamalDecrypt(suite abstract.Suite, prikey abstract.Secret, K, C abstract.Point) (
	M abstract.Point) {

	// ElGamal-decrypt the ciphertext (K,C) to reproduce the message.
	S := suite.Point().Mul(K, prikey) // regenerate shared secret
	M = suite.Point().Sub(C, S)       // use to un-blind the message
	return
}
Пример #11
0
// DefaultConstructors gives a default constructor for protobuf out of the global suite
func DefaultConstructors(suite abstract.Suite) protobuf.Constructors {
	constructors := make(protobuf.Constructors)
	var point abstract.Point
	var secret abstract.Scalar
	constructors[reflect.TypeOf(&point).Elem()] = func() interface{} { return suite.Point() }
	constructors[reflect.TypeOf(&secret).Elem()] = func() interface{} { return suite.Scalar() }
	return constructors
}
Пример #12
0
// GenerateKeyPair generates a new random private/public keypair in the specified group
func GenerateKeyPair(suite abstract.Suite) (*PriKey, *PubKey) {
	secret := suite.Secret().Pick(suite.Cipher(nil))
	base := suite.Point().Base()

	pk := PubKey{suite, base, suite.Point().Mul(base, secret)}
	sk := PriKey{pk, secret}

	return &sk, &pk
}
Пример #13
0
// ReadPubHex reads a hexadecimal representation of a public point and convert it to the
// right struct
func ReadPubHex(suite abstract.Suite, s string) (abstract.Point, error) {
	encoded, err := hex.DecodeString(s)
	if err != nil {
		return nil, err
	}
	point := suite.Point()
	err = point.UnmarshalBinary(encoded)
	return point, err
}
Пример #14
0
func ElGamalDecrypt(suite abstract.Suite, prikey abstract.Secret, K, C abstract.Point) (
	message []byte, err error) {

	// ElGamal-decrypt the ciphertext (K,C) to reproduce the message.
	S := suite.Point().Mul(K, prikey) // regenerate shared secret
	M := suite.Point().Sub(C, S)      // use to un-blind the message
	message, err = M.Data()           // extract the embedded data
	return
}
Пример #15
0
// GetSharedSecret returns the shared secret, as in the Verdict hash-based construction, for the given public and
// private keys
func GetSharedSecret(pk *PubKey, sk *PriKey) (abstract.Secret, abstract.Point) {
	var suite abstract.Suite
	suite = crypto.Suite
	point := suite.Point().Mul(pk.Elem, sk.secret)

	r := crypto.HashKDF(point)
	R := suite.Point().Mul(crypto.Generator, r)

	return r, R
}
Пример #16
0
// generate keys for the tree
func (t *Tree) GenKeys(suite abstract.Suite, rand abstract.Cipher) {
	t.TraverseTree(func(t *Tree) {
		PrivKey := suite.Secret().Pick(rand)
		PubKey := suite.Point().Mul(nil, PrivKey)
		prk, _ := PrivKey.MarshalBinary()
		pbk, _ := PubKey.MarshalBinary()
		t.PriKey = string(hex.EncodeToString(prk))
		t.PubKey = string(hex.EncodeToString(pbk))
	})
}
Пример #17
0
// computeSubtreeAggregate will compute the aggregate subtree public key for
// each node of the tree.
// root is the root of the subtree we want to compute the aggregate for
// recursive function so it will go down to the leaves then go up to the root
// Return the aggregate sub tree public key for this root (and compute each sub
// aggregate public key for each of the children).
func (t *Tree) computeSubtreeAggregate(suite abstract.Suite, root *TreeNode) abstract.Point {
	aggregate := suite.Point().Add(suite.Point().Null(), root.ServerIdentity.Public)
	// DFS search
	for _, ch := range root.Children {
		aggregate = aggregate.Add(aggregate, t.computeSubtreeAggregate(suite, ch))
	}

	// sets the field
	root.PublicAggregateSubTree = aggregate
	return aggregate
}
Пример #18
0
func ElGamalEncrypt(suite abstract.Suite, pubkey abstract.Point, M abstract.Point) (
	K, C abstract.Point, remainder []byte) {

	// Embed the message (or as much of it as will fit) into a curve point.
	//M, remainder := suite.Point().Pick(message, random.Stream)

	// ElGamal-encrypt the point to produce ciphertext (K,C).
	k := suite.Secret().Pick(random.Stream) // ephemeral private key
	K = suite.Point().Mul(nil, k)           // ephemeral DH public key
	S := suite.Point().Mul(pubkey, k)       // ephemeral DH shared secret
	C = S.Add(S, M)                         // message blinded with secret
	return
}
Пример #19
0
func (v *stateVector) addShuffle(suite abstract.Suite, shuf *shuffler,
	rand abstract.Cipher) error {

	// Get the previous shuffle state.
	i := len(v.States)
	prev := v.States[i-1]
	X, Y := prev.X, prev.Dec

	// Compute the new base using the public keys of the remaining
	// servers.
	H := suite.Point().Null()
	for j := i - 1; j < shuf.N; j++ {
		H = suite.Point().Add(H, shuf.HH[j])
	}

	// Do a key-shuffle.
	Xbar, Ybar, prover := shuffle.Shuffle(suite, nil, H, X, Y, rand)
	prf, err := proof.HashProve(suite, "PairShuffle", rand, prover)
	if err != nil {
		return err
	}

	// Seeded random for the decryption proof.
	seed := abstract.Sum(suite, prf)
	prfRand := suite.Cipher(seed)

	// Scratch space for calculations.
	zs := suite.Secret()
	zp := suite.Point()

	// Peel off a layer of encryption.
	dec := make([]abstract.Point, len(Xbar))
	decPrf := make([]*decryptionProof, len(Xbar))
	for j := range Xbar {
		// Decryption.
		zp.Mul(Xbar[j], shuf.h)
		dec[j] = suite.Point().Sub(Ybar[j], zp)

		// Decryption proof.
		t := suite.Secret().Pick(rand)
		T := suite.Point().Mul(Xbar[j], t)
		c := suite.Secret().Pick(prfRand)
		s := suite.Secret().Add(t, zs.Mul(c, shuf.h))
		decPrf[j] = &decryptionProof{T, s}
	}

	// Append the new state to the state vector.
	state := &shuffleState{H, Xbar, Ybar, dec, prf, decPrf}
	v.States = append(v.States, state)
	return nil
}
Пример #20
0
// The schnorrGenerateKeypair does exactly that -
// it generates a valid keypair for later use
// in producing signatures.
// I wanted to add a little bit of proper key
// management to the process but I couldn't work out
// how to pass a simple random stream to suite.Secret().Pick().
// I looked into Go streams very briefly  but decided
// I was spending too much time on that
// instead I passed /dev/urandom through the cipher
// interface.
func SchnorrGenerateKeypair(suite abstract.Suite) (SchnorrKeyset, error) {
	rsource := make([]byte, 16)
	_, err := rand.Read(rsource)
	if err != nil {
		return SchnorrKeyset{}, err
	}

	rct := suite.Cipher(rsource)

	x := suite.Secret().Pick(rct)  // some x
	y := suite.Point().Mul(nil, x) // y = g^x \in G, DLP.

	return SchnorrKeyset{x, y}, nil
}
Пример #21
0
func newHost(suite abstract.Suite, rand cipher.Stream, hostname string) *host {
	h := &host{}
	h.name = hostname
	h.log.init(suite)

	h.pri = suite.Secret().Pick(rand)
	h.pub = suite.Point().Mul(nil, h.pri)
	h.id = abstract.HashBytes(suite, h.pub.Encode())

	h.peers = make(map[string]*peer)
	h.trees = make(map[string]*treeNode)

	return h
}
func SchnorrMGenerateCommitment(suite abstract.Suite) (SchnorrMPrivateCommitment, error) {
	rsource := make([]byte, 16)
	_, err := rand.Read(rsource)
	if err != nil {
		return SchnorrMPrivateCommitment{}, err
	}
	// I have no idea if I just encrypted randomness or not
	// I'm hoping this just reads the state out.
	rct := suite.Cipher(rsource)

	v := suite.Secret().Pick(rct)  // some v
	t := suite.Point().Mul(nil, v) // g^v = t
	return SchnorrMPrivateCommitment{T: t, V: v}, nil
}
Пример #23
0
func (c *ownedCoder) commonSetup(suite abstract.Suite) {
	c.suite = suite

	// Divide the embeddable data in the verifiable point
	// between an encryption key and a MAC check
	c.keylen = suite.Cipher(nil).KeySize()
	c.maclen = suite.Point().PickLen() - c.keylen
	if c.maclen < c.keylen*3/4 {
		panic("misconfigured ciphersuite: MAC too small!")
	}

	randkey := make([]byte, suite.Cipher(nil).KeySize())
	rand.Read(randkey)
	c.random = suite.Cipher(randkey)
}
Пример #24
0
// Verify checks a signature generated by Sign.
//
// The caller provides the message, anonymity set, and linkage scope
// with which the signature was purportedly produced.
// If the signature is a valid linkable signature (linkScope != nil),
// this function returns a linkage tag that uniquely corresponds
// to the signer within the given linkScope.
// If the signature is a valid unlinkable signature (linkScope == nil),
// returns an empty but non-nil byte-slice instead of a linkage tag on success.
// Returns a nil linkage tag and an error if the signature is invalid.
func Verify(suite abstract.Suite, message []byte, anonymitySet Set,
	linkScope []byte, signatureBuffer []byte) ([]byte, error) {

	n := len(anonymitySet)              // anonymity set size
	L := []abstract.Point(anonymitySet) // public keys in ring

	// Decode the signature
	buf := bytes.NewBuffer(signatureBuffer)
	var linkBase, linkTag abstract.Point
	sig := lSig{}
	sig.S = make([]abstract.Scalar, n)
	if linkScope != nil { // linkable ring signature
		if err := suite.Read(buf, &sig); err != nil {
			return nil, err
		}
		linkStream := suite.Cipher(linkScope)
		linkBase, _ = suite.Point().Pick(nil, linkStream)
		linkTag = sig.Tag
	} else { // unlinkable ring signature
		if err := suite.Read(buf, &sig.C0); err != nil {
			return nil, err
		}
		if err := suite.Read(buf, &sig.S); err != nil {
			return nil, err
		}
	}

	// Pre-hash the ring-position-invariant parameters to H1.
	H1pre := signH1pre(suite, linkScope, linkTag, message)

	// Verify the signature
	var P, PG, PH abstract.Point
	P = suite.Point()
	PG = suite.Point()
	if linkScope != nil {
		PH = suite.Point()
	}
	s := sig.S
	ci := sig.C0
	for i := 0; i < n; i++ {
		PG.Add(PG.Mul(nil, s[i]), P.Mul(L[i], ci))
		if linkScope != nil {
			PH.Add(PH.Mul(linkBase, s[i]), P.Mul(linkTag, ci))
		}
		ci = signH1(suite, H1pre, PG, PH)
	}
	if !ci.Equal(sig.C0) {
		return nil, errors.New("invalid signature")
	}

	// Return the re-encoded linkage tag, for uniqueness checking
	if linkScope != nil {
		tag, _ := linkTag.MarshalBinary()
		return tag, nil
	} else {
		return []byte{}, nil
	}
}
Пример #25
0
// Initialize...
func (sk *SKEME) Init(suite abstract.Suite, rand cipher.Stream,
	lpri PriKey, rpub Set, hide bool) {
	sk.suite = suite
	sk.hide = hide
	sk.lpri, sk.rpub = lpri, rpub

	// Create our Diffie-Hellman keypair
	sk.lx = suite.Secret().Pick(rand)
	sk.lX = suite.Point().Mul(nil, sk.lx)
	sk.lXb, _ = sk.lX.MarshalBinary()

	// Encrypt and send the DH key to the receiver.
	// This is a deviation from SKEME, to protect message metadata
	// and further harden messages against tampering or active MITM DoS.
	sk.lm = Encrypt(suite, rand, sk.lXb, rpub, hide)
}
Пример #26
0
func benchGenKeys(suite abstract.Suite,
	nkeys int) ([]abstract.Point, abstract.Secret) {

	rand := random.Stream

	// Create an anonymity set of random "public keys"
	X := make([]abstract.Point, nkeys)
	for i := range X { // pick random points
		X[i], _ = suite.Point().Pick(nil, rand)
	}

	// Make just one of them an actual public/private keypair (X[mine],x)
	x := suite.Secret().Pick(rand)
	X[0] = suite.Point().Mul(nil, x)

	return X, x
}
Пример #27
0
// VerifySignatureWithException will verify the signature taking into account
// the exceptions given. An exception is the pubilc key + commitment of a peer that did not
// sign.
// NOTE: No exception mechanism for "before" commitment has been yet coded.
func VerifySignatureWithException(suite abstract.Suite, public abstract.Point, msg []byte, challenge, secret abstract.Scalar, exceptions []Exception) error {
	// first reduce the aggregate public key
	subPublic := suite.Point().Add(suite.Point().Null(), public)
	aggExCommit := suite.Point().Null()
	for _, ex := range exceptions {
		subPublic = subPublic.Sub(subPublic, ex.Public)
		aggExCommit = aggExCommit.Add(aggExCommit, ex.Commitment)
	}

	// recompute the challenge and check if it is the same
	commitment := suite.Point()
	commitment = commitment.Add(commitment.Mul(nil, secret), suite.Point().Mul(public, challenge))
	// ADD the exceptions commitment here
	commitment = commitment.Add(commitment, aggExCommit)
	// check if it is ok
	return verifyCommitment(suite, msg, commitment, challenge)
}
Пример #28
0
// VerifySchnorr verifies a given Schnorr signature. It returns nil iff the given signature is valid.
func VerifySchnorr(suite abstract.Suite, public abstract.Point, msg []byte, sig SchnorrSig) error {
	// compute rv = g^s * y^e (where y = g^x)
	gs := suite.Point().Mul(nil, sig.Response)
	ye := suite.Point().Mul(public, sig.Challenge)
	rv := suite.Point().Add(gs, ye)

	// recompute challenge (e) from rv
	e, err := hash(suite, rv, msg)
	if err != nil {
		return err
	}

	if !e.Equal(sig.Challenge) {
		return errors.New("Signature not valid: Reconstructed challenge isn't equal to challenge in signature")
	}

	return nil
}
Пример #29
0
// SignSchnorr creates a Schnorr signature from a msg and a private key
func SignSchnorr(suite abstract.Suite, private abstract.Scalar, msg []byte) (SchnorrSig, error) {
	// using notation from https://en.wikipedia.org/wiki/Schnorr_signature
	// create random secret k and public point commitment r
	k := suite.Scalar().Pick(random.Stream)
	r := suite.Point().Mul(nil, k)

	// create challenge e based on message and r
	e, err := hash(suite, r, msg)
	if err != nil {
		return SchnorrSig{}, err
	}

	// compute response s = k - x*e
	xe := suite.Scalar().Mul(private, e)
	s := suite.Scalar().Sub(k, xe)

	return SchnorrSig{Challenge: e, Response: s}, nil
}
Пример #30
0
// This simplified implementation of ElGamal Signatures is based on
// crypto/anon/sig.go
func ElGamalSign(suite abstract.Suite, random cipher.Stream, message []byte,
	privateKey abstract.Secret) BasicSig {

	// Create random secret v and public point commitment T
	v := suite.Secret().Pick(random)
	T := suite.Point().Mul(nil, v)

	// Create challenge c based on message and T
	c := hashElGamal(suite, message, T)

	// Compute response r = v - x*c
	r := suite.Secret()
	r.Mul(privateKey, c).Sub(v, r)

	// Return verifiable signature {c, r}
	sig := BasicSig{c, r}
	return sig
}