@@ -22,10 +22,10 @@ func (ws *wotsSignature) fromBytes(p *params, c *cursor) {
22
22
}
23
23
24
24
// See FIPS 205 -- Section 5 -- Algorithm 5.
25
- func (s * state ) chain (x []byte , index , step uint32 , addr address ) (out []byte ) {
25
+ func (s * state ) chain (x []byte , index , steps uint32 , addr address ) (out []byte ) {
26
26
out = x
27
27
s .F .address .Set (addr )
28
- for j := index ; j < index + step ; j ++ {
28
+ for j := index ; j < index + steps ; j ++ {
29
29
s .F .address .SetHashAddress (j )
30
30
s .F .SetMessage (out )
31
31
out = s .F .Final ()
@@ -60,6 +60,10 @@ func (s *statePriv) wotsPkGen(addr address) wotsPublicKey {
60
60
61
61
// See FIPS 205 -- Section 5.2 -- Algorithm 7.
62
62
func (s * statePriv ) wotsSign (sig wotsSignature , msg []byte , addr address ) {
63
+ if len (msg ) != int (s .wotsLen1 ()/ 2 ) {
64
+ panic (ErrMsgLen )
65
+ }
66
+
63
67
curSig := cursor (sig )
64
68
wotsLen1 := s .wotsLen1 ()
65
69
csum := wotsLen1 * (wotsW - 1 )
@@ -68,6 +72,7 @@ func (s *statePriv) wotsSign(sig wotsSignature, msg []byte, addr address) {
68
72
s .PRF .address .SetTypeAndClear (addressWotsPrf )
69
73
s .PRF .address .SetKeyPairAddress (addr .GetKeyPairAddress ())
70
74
75
+ // Signs every nibble of the message and computes the checksum.
71
76
for i := uint32 (0 ); i < wotsLen1 ; i ++ {
72
77
s .PRF .address .SetChainAddress (i )
73
78
sk := s .PRF .Final ()
@@ -79,6 +84,7 @@ func (s *statePriv) wotsSign(sig wotsSignature, msg []byte, addr address) {
79
84
csum -= msgi
80
85
}
81
86
87
+ // Lastly, every nibble of the checksum is also signed.
82
88
for i := uint32 (0 ); i < wotsLen2 ; i ++ {
83
89
s .PRF .address .SetChainAddress (wotsLen1 + i )
84
90
sk := s .PRF .Final ()
@@ -94,6 +100,10 @@ func (s *statePriv) wotsSign(sig wotsSignature, msg []byte, addr address) {
94
100
func (s * state ) wotsPkFromSig (
95
101
sig wotsSignature , msg []byte , addr address ,
96
102
) wotsPublicKey {
103
+ if len (msg ) != int (s .wotsLen1 ()/ 2 ) {
104
+ panic (ErrMsgLen )
105
+ }
106
+
97
107
wotsLen1 := s .wotsLen1 ()
98
108
csum := wotsLen1 * (wotsW - 1 )
99
109
@@ -104,6 +114,8 @@ func (s *state) wotsPkFromSig(
104
114
s .T .Reset ()
105
115
curSig := cursor (sig )
106
116
117
+ // Signs every nibble of the message, computes the checksum, and
118
+ // feeds each signature to the T function.
107
119
for i := uint32 (0 ); i < wotsLen1 ; i ++ {
108
120
addr .SetChainAddress (i )
109
121
msgi := uint32 ((msg [i / 2 ] >> ((1 - (i & 1 )) << 2 )) & 0xF )
@@ -113,6 +125,8 @@ func (s *state) wotsPkFromSig(
113
125
csum -= msgi
114
126
}
115
127
128
+ // Every nibble of the checksum is also signed feeding the signature
129
+ // to the T function.
116
130
for i := uint32 (0 ); i < wotsLen2 ; i ++ {
117
131
addr .SetChainAddress (wotsLen1 + i )
118
132
csumi := (csum >> (8 - 4 * i )) & 0xF
@@ -121,5 +135,6 @@ func (s *state) wotsPkFromSig(
121
135
s .T .WriteMessage (sigi )
122
136
}
123
137
138
+ // Generates the public key as the output of the T function.
124
139
return s .T .Final ()
125
140
}
0 commit comments