forked from lightninglabs/aperture
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathidentifier.go
More file actions
128 lines (106 loc) · 3.31 KB
/
identifier.go
File metadata and controls
128 lines (106 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package lsat
import (
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"io"
"github.com/lightningnetwork/lnd/lntypes"
)
const (
// LatestVersion is the latest version used for minting new LSATs.
LatestVersion = 0
// SecretSize is the size in bytes of a LSAT's secret, also known as
// the root key of the macaroon.
SecretSize = 32
// TokenIDSize is the size in bytes of an LSAT's ID encoded in its
// macaroon identifier.
TokenIDSize = 32
)
var (
// byteOrder is the byte order used to encode/decode a macaroon's raw
// identifier.
byteOrder = binary.BigEndian
// ErrUnknownVersion is an error returned when attempting to decode an
// LSAT identifier with an unknown version.
ErrUnknownVersion = errors.New("unknown LSAT version")
)
// TokenID is the type that stores the token identifier of an LSAT token.
type TokenID [TokenIDSize]byte
// String returns the hex encoded representation of the token ID as a string.
func (t *TokenID) String() string {
return hex.EncodeToString(t[:])
}
// MakeIDFromString parses the hex encoded string and parses it into a token ID.
func MakeIDFromString(newID string) (TokenID, error) {
if len(newID) != hex.EncodedLen(TokenIDSize) {
return TokenID{}, fmt.Errorf("invalid id string length of %v, "+
"want %v", len(newID), hex.EncodedLen(TokenIDSize))
}
idBytes, err := hex.DecodeString(newID)
if err != nil {
return TokenID{}, err
}
var id TokenID
copy(id[:], idBytes)
return id, nil
}
// Identifier contains the static identifying details of an LSAT. This is
// intended to be used as the identifier of the macaroon within an LSAT.
type Identifier struct {
// Version is the version of an LSAT. Having a version allows us to
// introduce new fields to the identifier in a backwards-compatible
// manner.
Version uint16
// PaymentHash is the payment hash linked to an LSAT. Verification of
// an LSAT depends on a valid payment, which is enforced by ensuring a
// preimage is provided that hashes to our payment hash.
PaymentHash lntypes.Hash
// TokenID is the unique identifier of an LSAT.
TokenID TokenID
}
// EncodeIdentifier encodes an LSAT's identifier according to its version.
func EncodeIdentifier(w io.Writer, id *Identifier) error {
if err := binary.Write(w, byteOrder, id.Version); err != nil {
return err
}
switch id.Version {
// A version 0 identifier consists of its linked payment hash, followed
// by the token ID.
case 0:
if _, err := w.Write(id.PaymentHash[:]); err != nil {
return err
}
_, err := w.Write(id.TokenID[:])
return err
default:
return fmt.Errorf("%w: %v", ErrUnknownVersion, id.Version)
}
}
// DecodeIdentifier decodes an LSAT's identifier according to its version.
func DecodeIdentifier(r io.Reader) (*Identifier, error) {
var version uint16
if err := binary.Read(r, byteOrder, &version); err != nil {
return nil, err
}
switch version {
// A version 0 identifier consists of its linked payment hash, followed
// by the token ID.
case 0:
var paymentHash lntypes.Hash
if _, err := r.Read(paymentHash[:]); err != nil {
return nil, err
}
var tokenID TokenID
if _, err := r.Read(tokenID[:]); err != nil {
return nil, err
}
return &Identifier{
Version: version,
PaymentHash: paymentHash,
TokenID: tokenID,
}, nil
default:
return nil, fmt.Errorf("%w: %v", ErrUnknownVersion, version)
}
}