-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathlabel.go
120 lines (100 loc) · 2.21 KB
/
label.go
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
//
// label.go
//
// Copyright (c) 2019-2024 Markku Rossi
//
// All rights reserved.
//
package ot
import (
"encoding/binary"
"fmt"
"io"
)
// Wire implements a wire with 0 and 1 labels.
type Wire struct {
L0 Label
L1 Label
}
func (w Wire) String() string {
return fmt.Sprintf("%s/%s", w.L0, w.L1)
}
// Label implements a 128 bit wire label.
type Label struct {
D0 uint64
D1 uint64
}
// LabelData contains lable data as byte array.
type LabelData [16]byte
func (l Label) String() string {
return fmt.Sprintf("%016x%016x", l.D0, l.D1)
}
// Equal test if the labels are equal.
func (l Label) Equal(o Label) bool {
return l.D0 == o.D0 && l.D1 == o.D1
}
// NewLabel creates a new random label.
func NewLabel(rand io.Reader) (Label, error) {
var buf LabelData
var label Label
if _, err := rand.Read(buf[:]); err != nil {
return label, err
}
label.SetData(&buf)
return label, nil
}
// NewTweak creates a new label from the tweak value.
func NewTweak(tweak uint32) Label {
return Label{
D1: uint64(tweak),
}
}
// S tests the label's S bit.
func (l Label) S() bool {
return (l.D0 & 0x8000000000000000) != 0
}
// SetS sets the label's S bit.
func (l *Label) SetS(set bool) {
if set {
l.D0 |= 0x8000000000000000
} else {
l.D0 &= 0x7fffffffffffffff
}
}
// Mul2 multiplies the label by 2.
func (l *Label) Mul2() {
l.D0 <<= 1
l.D0 |= (l.D1 >> 63)
l.D1 <<= 1
}
// Mul4 multiplies the label by 4.
func (l *Label) Mul4() {
l.D0 <<= 2
l.D0 |= (l.D1 >> 62)
l.D1 <<= 2
}
// Xor xors the label with the argument label.
func (l *Label) Xor(o Label) {
l.D0 ^= o.D0
l.D1 ^= o.D1
}
// GetData gets the labels as label data.
func (l Label) GetData(buf *LabelData) {
binary.BigEndian.PutUint64(buf[0:8], l.D0)
binary.BigEndian.PutUint64(buf[8:16], l.D1)
}
// SetData sets the labels from label data.
func (l *Label) SetData(data *LabelData) {
l.D0 = binary.BigEndian.Uint64((*data)[0:8])
l.D1 = binary.BigEndian.Uint64((*data)[8:16])
}
// Bytes returns the label data as bytes.
func (l Label) Bytes(buf *LabelData) []byte {
l.GetData(buf)
return buf[:]
}
// SetBytes sets the label data from bytes.
func (l *Label) SetBytes(data []byte) {
l.D0 = binary.BigEndian.Uint64(data[0:8])
l.D1 = binary.BigEndian.Uint64(data[8:16])
}