Skip to content

Commit 4742bd1

Browse files
authored
fix(ledger): raw binary signable opcert (#1444)
Signed-off-by: Chris Gianelloni <wolf31o2@blinklabs.io>
1 parent 0da51aa commit 4742bd1

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

ledger/forging/keys.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ package forging
1818
import (
1919
"bytes"
2020
"crypto/ed25519"
21+
"encoding/binary"
2122
"errors"
2223
"fmt"
2324
"sync"
2425

2526
"github.com/blinklabs-io/bursa"
26-
"github.com/blinklabs-io/gouroboros/cbor"
2727
"github.com/blinklabs-io/gouroboros/kes"
2828
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
2929
"github.com/blinklabs-io/gouroboros/vrf"
@@ -290,20 +290,21 @@ func (pc *PoolCredentials) ValidateOpCert() error {
290290
return errors.New("KES verification key mismatch: loaded key does not match OpCert.KESVKey")
291291
}
292292

293-
// Verify cold key signature over [KES vkey, issue number, KES period]
293+
// Verify cold key signature over the raw signable representation:
294+
// KES vkey (32 bytes) || issue number (8 bytes BE) || KES period (8 bytes BE)
295+
// See: cardano-ledger OCertSignable.getSignableRepresentation
294296
if len(pc.opCert.ColdVKey) != ed25519.PublicKeySize {
295297
return fmt.Errorf(
296298
"invalid cold verification key size: expected %d, got %d",
297299
ed25519.PublicKeySize,
298300
len(pc.opCert.ColdVKey),
299301
)
300302
}
301-
certBody := []any{pc.opCert.KESVKey, pc.opCert.IssueNumber, pc.opCert.KESPeriod}
302-
certCbor, err := cbor.Encode(certBody)
303-
if err != nil {
304-
return fmt.Errorf("failed to encode OpCert body for signature verification: %w", err)
305-
}
306-
if !ed25519.Verify(pc.opCert.ColdVKey, certCbor, pc.opCert.Signature) {
303+
var certBody [48]byte
304+
copy(certBody[:32], pc.opCert.KESVKey)
305+
binary.BigEndian.PutUint64(certBody[32:40], pc.opCert.IssueNumber)
306+
binary.BigEndian.PutUint64(certBody[40:48], pc.opCert.KESPeriod)
307+
if !ed25519.Verify(pc.opCert.ColdVKey, certBody[:], pc.opCert.Signature) {
307308
return errors.New("OpCert signature verification failed: cold key signature is invalid")
308309
}
309310

ledger/forging/keys_test.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package forging
1717
import (
1818
"crypto/ed25519"
1919
"crypto/rand"
20+
"encoding/binary"
2021
"encoding/hex"
2122
"os"
2223
"path/filepath"
@@ -238,11 +239,13 @@ func TestOpCertValidation(t *testing.T) {
238239
issueNumber := uint64(0)
239240
kesPeriod := uint64(0)
240241

241-
// Sign the cert body with the cold private key
242-
certBody := []any{kesVKey, issueNumber, kesPeriod}
243-
certCbor, err := cbor.Encode(certBody)
244-
require.NoError(t, err)
245-
signature := ed25519.Sign(coldPrivKey, certCbor)
242+
// Sign the raw signable representation:
243+
// KES vkey (32 bytes) || issue number (8 bytes BE) || KES period (8 bytes BE)
244+
var certBody [48]byte
245+
copy(certBody[:32], kesVKey)
246+
binary.BigEndian.PutUint64(certBody[32:40], issueNumber)
247+
binary.BigEndian.PutUint64(certBody[40:48], kesPeriod)
248+
signature := ed25519.Sign(coldPrivKey, certBody[:])
246249

247250
pc.kesVKey = kesVKey
248251
pc.opCert = &OpCert{

0 commit comments

Comments
 (0)