Skip to content

Commit 444400b

Browse files
committed
add fat error encryption and decryption
1 parent 568d591 commit 444400b

7 files changed

+780
-0
lines changed

attributable_error_crypto.go

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package sphinx
2+
3+
import (
4+
"crypto/hmac"
5+
"crypto/sha256"
6+
)
7+
8+
type payloadSource byte
9+
10+
const (
11+
// payloadIntermediateNode is a marker to signal that this attributable
12+
// error payload is originating from a node between the payer and the error
13+
// source.
14+
payloadIntermediateNode payloadSource = 0
15+
16+
// payloadErrorNode is a marker to signal that this attributable error
17+
// payload is originating from the error source.
18+
payloadErrorNode payloadSource = 1
19+
)
20+
21+
type AttributableErrorStructure struct {
22+
HopCount int
23+
FixedPayloadLen int
24+
}
25+
26+
type attributableErrorBase struct {
27+
maxHops int
28+
totalHmacs int
29+
allHmacsLen int
30+
hmacsAndPayloadsLen int
31+
allPayloadsLen int
32+
payloadLen int
33+
payloadDataLen int
34+
}
35+
36+
func newAttributableErrorBase(
37+
structure *AttributableErrorStructure) attributableErrorBase {
38+
39+
var (
40+
payloadDataLen = structure.FixedPayloadLen
41+
42+
// payloadLen is the size of the per-node payload. It consists of a
43+
// 1-byte payload type followed by the payload data.
44+
payloadLen = 1 + payloadDataLen
45+
46+
totalHmacs = (structure.HopCount *
47+
(structure.HopCount + 1)) / 2
48+
49+
allHmacsLen = totalHmacs * sha256.Size
50+
allPayloadsLen = payloadLen * structure.HopCount
51+
hmacsAndPayloadsLen = allHmacsLen + allPayloadsLen
52+
)
53+
54+
return attributableErrorBase{
55+
totalHmacs: totalHmacs,
56+
allHmacsLen: allHmacsLen,
57+
hmacsAndPayloadsLen: hmacsAndPayloadsLen,
58+
allPayloadsLen: allPayloadsLen,
59+
maxHops: structure.HopCount,
60+
payloadLen: payloadLen,
61+
payloadDataLen: payloadDataLen,
62+
}
63+
}
64+
65+
// getMsgComponents splits a complete failure message into its components
66+
// without re-allocating memory.
67+
func (o *attributableErrorBase) getMsgComponents(data []byte) ([]byte, []byte,
68+
[]byte) {
69+
70+
payloads := data[len(data)-o.hmacsAndPayloadsLen : len(data)-o.allHmacsLen]
71+
hmacs := data[len(data)-o.allHmacsLen:]
72+
message := data[:len(data)-o.hmacsAndPayloadsLen]
73+
74+
return message, payloads, hmacs
75+
}
76+
77+
// calculateHmac calculates an hmac given a shared secret and a presumed
78+
// position in the path. Position is expressed as the distance to the error
79+
// source. The error source itself is at position 0.
80+
func (o *attributableErrorBase) calculateHmac(sharedSecret Hash256,
81+
position int, message, payloads, hmacs []byte) []byte {
82+
83+
umKey := generateKey("um", &sharedSecret)
84+
hash := hmac.New(sha256.New, umKey[:])
85+
86+
// Include message.
87+
_, _ = hash.Write(message)
88+
89+
// Include payloads including our own.
90+
_, _ = hash.Write(payloads[:(o.maxHops-position)*o.payloadLen])
91+
92+
// Include downstream hmacs.
93+
var hmacsIdx = position + o.maxHops
94+
for j := 0; j < o.maxHops-position-1; j++ {
95+
_, _ = hash.Write(
96+
hmacs[hmacsIdx*sha256.Size : (hmacsIdx+1)*sha256.Size],
97+
)
98+
99+
hmacsIdx += o.maxHops - j - 1
100+
}
101+
102+
return hash.Sum(nil)
103+
}

0 commit comments

Comments
 (0)