func (m *Macaroon) Bind(sig []byte) {
	m.sig = *bindForRequest(sig, &m.sig)
}
Bind prepares the macaroon for being used to discharge the
macaroon with the given signature sig. This must be
used before it is used in the discharges argument to Verify.
package macaroon
import (
	"bytes"
	"crypto/hmac"
	"crypto/rand"
	"fmt"
	"io"
	"unicode/utf8"
)
type Macaroon struct {
	location string
	id       []byte
	caveats  []Caveat
	sig      [hashLen]byte
	version  Version
}
func (m *Macaroon) Equal(m1 *Macaroon) bool {
	if m == m1 || m == nil || m1 == nil {
		return m == m1
	}
	if m.location != m1.location ||
		!bytes.Equal(m.id, m1.id) ||
		m.sig != m1.sig ||
		m.version != m1.version ||
		len(m.caveats) != len(m1.caveats) {
		return false
	}
	for i, c := range m.caveats {
		if !c.Equal(m1.caveats[i]) {
			return false
		}
	}
	return true
}
type Caveat struct {
	Id []byte
	VerificationId []byte
	Location string
}
func (c Caveat) Equal(c1 Caveat) bool {
	return bytes.Equal(c.Id, c1.Id) &&
		bytes.Equal(c.VerificationId, c1.VerificationId) &&
		c.Location == c1.Location
}
func (cav *Caveat) isThirdParty() bool {
	return len(cav.VerificationId) > 0
}
func New(rootKey, id []byte, loc string, version Version) (*Macaroon, error) {
	var m Macaroon
	if version < V2 {
		if !utf8.Valid(id) {
			return nil, fmt.Errorf("invalid id for %v macaroon", id)
		}
	}
	if version < V1 || version > LatestVersion {
		return nil, fmt.Errorf("invalid version %v", version)
	}
	m.version = version
	m.init(append([]byte(nil), id...), loc, version)
	derivedKey := makeKey(rootKey)
	m.sig = *keyedHash(derivedKey, m.id)
	return &m, nil
}
func (m *Macaroon) init(id []byte, loc string, vers Version) {
	m.location = loc
	m.id = append([]byte(nil), id...)
	m.version = vers
}
func (m *Macaroon) SetLocation(loc string) {
	m.location = loc
}
func (m *Macaroon) Clone() *Macaroon {
	m1 := *m
	m1.caveats = m1.caveats[0:len(m1.caveats):len(m1.caveats)]
	return &m1
}
func (m *Macaroon) Location() string {
	return m.location
}
func (m *Macaroon) Id() []byte {
	return append([]byte(nil), m.id...)
}
func (m *Macaroon) Signature() []byte {
	sig := new([hashLen]byte)
	*sig = m.sig
	return sig[:]
}
func (m *Macaroon) Caveats() []Caveat {
	return m.caveats[0:len(m.caveats):len(m.caveats)]
}
func (m *Macaroon) appendCaveat(caveatId, verificationId []byte, loc string) {
	if len(verificationId) == 0 {
		verificationId = nil
	}
	m.caveats = append(m.caveats, Caveat{
		Id:             caveatId,
		VerificationId: verificationId,
		Location:       loc,
	})
}
func (m *Macaroon) addCaveat(caveatId, verificationId []byte, loc string) error {
	if m.version < V2 {
		if !utf8.Valid(caveatId) {
			return fmt.Errorf("invalid caveat id for %v macaroon", m.version)
		}
	}
	m.appendCaveat(caveatId, verificationId, loc)
	if len(verificationId) == 0 {
		m.sig = *keyedHash(&m.sig, caveatId)
	} else {
		m.sig = *keyedHash2(&m.sig, verificationId, caveatId)
	}
	return nil
}
func keyedHash2(key *[keyLen]byte, d1, d2 []byte) *[hashLen]byte {
	var data [hashLen * 2]byte
	copy(data[0:], keyedHash(key, d1)[:])
	copy(data[hashLen:], keyedHash(key, d2)[:])
	return keyedHash(key, data[:])
}