@@ -26,6 +26,14 @@ import (
2626 "math"
2727
2828 "github.com/blinklabs-io/gouroboros/cbor"
29+ "github.com/blinklabs-io/gouroboros/ledger/allegra"
30+ "github.com/blinklabs-io/gouroboros/ledger/alonzo"
31+ "github.com/blinklabs-io/gouroboros/ledger/babbage"
32+ "github.com/blinklabs-io/gouroboros/ledger/common"
33+ "github.com/blinklabs-io/gouroboros/ledger/conway"
34+ "github.com/blinklabs-io/gouroboros/ledger/leios"
35+ "github.com/blinklabs-io/gouroboros/ledger/mary"
36+ "github.com/blinklabs-io/gouroboros/ledger/shelley"
2937 "golang.org/x/crypto/blake2b"
3038)
3139
@@ -131,27 +139,100 @@ func (s Sum0KesSig) Verify(
131139 return ed25519 .Verify (pubKey , msg , s )
132140}
133141
134- // TODO: make this work on anything from Shelley onward (#845)
142+ func extractKesFieldsShelleyAlonzo (
143+ header interface {},
144+ ) (bodyCbor []byte , sig []byte , hotVkey []byte , kesPeriod uint64 , slot uint64 , err error ) {
145+ switch h := header .(type ) {
146+ case * shelley.ShelleyBlockHeader :
147+ bodyCbor , err = cbor .Encode (h .Body )
148+ if err != nil {
149+ return nil , nil , nil , 0 , 0 , err
150+ }
151+ return bodyCbor , h .Signature , h .Body .OpCertHotVkey , uint64 (h .Body .OpCertKesPeriod ), h .Body .Slot , nil
152+ case * allegra.AllegraBlockHeader :
153+ bodyCbor , err = cbor .Encode (h .Body )
154+ if err != nil {
155+ return nil , nil , nil , 0 , 0 , err
156+ }
157+ return bodyCbor , h .Signature , h .Body .OpCertHotVkey , uint64 (h .Body .OpCertKesPeriod ), h .Body .Slot , nil
158+ case * mary.MaryBlockHeader :
159+ bodyCbor , err = cbor .Encode (h .Body )
160+ if err != nil {
161+ return nil , nil , nil , 0 , 0 , err
162+ }
163+ return bodyCbor , h .Signature , h .Body .OpCertHotVkey , uint64 (h .Body .OpCertKesPeriod ), h .Body .Slot , nil
164+ case * alonzo.AlonzoBlockHeader :
165+ bodyCbor , err = cbor .Encode (h .Body )
166+ if err != nil {
167+ return nil , nil , nil , 0 , 0 , err
168+ }
169+ return bodyCbor , h .Signature , h .Body .OpCertHotVkey , uint64 (h .Body .OpCertKesPeriod ), h .Body .Slot , nil
170+ default :
171+ return nil , nil , nil , 0 , 0 , fmt .Errorf ("unsupported header type: %T" , header )
172+ }
173+ }
174+
175+ func extractKesFieldsBabbagePlus (
176+ header interface {},
177+ ) (bodyCbor []byte , sig []byte , hotVkey []byte , kesPeriod uint64 , slot uint64 , err error ) {
178+ switch h := header .(type ) {
179+ case * babbage.BabbageBlockHeader :
180+ bodyCbor , err = cbor .Encode (h .Body )
181+ if err != nil {
182+ return nil , nil , nil , 0 , 0 , err
183+ }
184+ return bodyCbor , h .Signature , h .Body .OpCert .HotVkey , uint64 (h .Body .OpCert .KesPeriod ), h .Body .Slot , nil
185+ case * conway.ConwayBlockHeader :
186+ bodyCbor , err = cbor .Encode (h .Body )
187+ if err != nil {
188+ return nil , nil , nil , 0 , 0 , err
189+ }
190+ return bodyCbor , h .Signature , h .Body .OpCert .HotVkey , uint64 (h .Body .OpCert .KesPeriod ), h .Body .Slot , nil
191+ case * leios.LeiosBlockHeader :
192+ bodyCbor , err = cbor .Encode (h .Body )
193+ if err != nil {
194+ return nil , nil , nil , 0 , 0 , err
195+ }
196+ return bodyCbor , h .Signature , h .Body .OpCert .HotVkey , uint64 (h .Body .OpCert .KesPeriod ), h .Body .Slot , nil
197+ default :
198+ return nil , nil , nil , 0 , 0 , fmt .Errorf ("unsupported header type: %T" , header )
199+ }
200+ }
201+
135202func VerifyKes (
136- header * BabbageBlockHeader ,
203+ header common. BlockHeader ,
137204 slotsPerKesPeriod uint64 ,
138205) (bool , error ) {
139206 // Ref: https://github.com/IntersectMBO/ouroboros-consensus/blob/de74882102236fdc4dd25aaa2552e8b3e208448c/ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Protocol/Praos.hs#L125
140207 // Ref: https://github.com/IntersectMBO/cardano-ledger/blob/master/libs/cardano-protocol-tpraos/src/Cardano/Protocol/TPraos/BHeader.hs#L189
141- msgBytes , err := cbor .Encode (header .Body )
142- if err != nil {
143- return false , err
208+ var msgBytes []byte
209+ var signature []byte
210+ var hotVkey []byte
211+ var kesPeriod uint64
212+ var slot uint64
213+ var err error
214+
215+ switch h := header .(type ) {
216+ case * shelley.ShelleyBlockHeader , * allegra.AllegraBlockHeader , * mary.MaryBlockHeader , * alonzo.AlonzoBlockHeader :
217+ msgBytes , signature , hotVkey , kesPeriod , slot , err = extractKesFieldsShelleyAlonzo (h )
218+ if err != nil {
219+ return false , fmt .Errorf ("VerifyKes: %w" , err )
220+ }
221+ case * babbage.BabbageBlockHeader , * conway.ConwayBlockHeader , * leios.LeiosBlockHeader :
222+ msgBytes , signature , hotVkey , kesPeriod , slot , err = extractKesFieldsBabbagePlus (h )
223+ if err != nil {
224+ return false , fmt .Errorf ("VerifyKes: %w" , err )
225+ }
226+ default :
227+ return false , fmt .Errorf ("VerifyKes: unsupported block header type %T" , header )
144228 }
145- opCert := header .Body .OpCert
146- opCertVkHotBytes := header .Body .OpCert .HotVkey
147- startOfKesPeriod := uint64 (opCert .KesPeriod )
148- currentSlot := header .Body .Slot
229+
149230 return VerifyKesComponents (
150231 msgBytes ,
151- header . Signature ,
152- opCertVkHotBytes ,
153- startOfKesPeriod ,
154- currentSlot ,
232+ signature ,
233+ hotVkey ,
234+ kesPeriod ,
235+ slot ,
155236 slotsPerKesPeriod ,
156237 )
157238}
@@ -189,3 +270,25 @@ func verifySignedKES(vkey []byte, period uint64, msg []byte, sig []byte) bool {
189270 isValid := proof .Verify (period , vkey , msg )
190271 return isValid
191272}
273+
274+ // GetHeaderBodyCbor returns the CBOR-encoded bytes of the block header body
275+ func GetHeaderBodyCbor (header common.BlockHeader ) ([]byte , error ) {
276+ switch h := header .(type ) {
277+ case * shelley.ShelleyBlockHeader :
278+ return cbor .Encode (h .Body )
279+ case * allegra.AllegraBlockHeader :
280+ return cbor .Encode (h .Body )
281+ case * mary.MaryBlockHeader :
282+ return cbor .Encode (h .Body )
283+ case * alonzo.AlonzoBlockHeader :
284+ return cbor .Encode (h .Body )
285+ case * babbage.BabbageBlockHeader :
286+ return cbor .Encode (h .Body )
287+ case * conway.ConwayBlockHeader :
288+ return cbor .Encode (h .Body )
289+ case * leios.LeiosBlockHeader :
290+ return cbor .Encode (h .Body )
291+ default :
292+ return nil , fmt .Errorf ("GetHeaderBodyCbor: unsupported block header type %T" , header )
293+ }
294+ }
0 commit comments