Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions sdk/action/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,15 @@ func (c *ClientImpl) BuildCascadeMetadataFromFile(ctx context.Context, filePath
// GenerateStartCascadeSignatureFromFile computes blake3(file) and signs it with the configured key.
// Returns base64-encoded signature suitable for StartCascade.
func (c *ClientImpl) GenerateStartCascadeSignatureFromFile(ctx context.Context, filePath string) (string, error) {
// Compute blake3(file), encode as base64 string, and sign the string bytes
h, err := utils.Blake3HashFile(filePath)
if err != nil {
return "", fmt.Errorf("blake3: %w", err)
}
sig, err := keyringpkg.SignBytes(c.keyring, c.config.Account.KeyName, h)
dataHashB64 := base64.StdEncoding.EncodeToString(h)
sig, err := keyringpkg.SignBytes(c.keyring, c.config.Account.KeyName, []byte(dataHashB64))
if err != nil {
return "", fmt.Errorf("sign hash: %w", err)
return "", fmt.Errorf("sign hash string: %w", err)
}
return base64.StdEncoding.EncodeToString(sig), nil
}
Expand Down
35 changes: 20 additions & 15 deletions sdk/task/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"os"
"sort"

actionkeeper "github.com/LumeraProtocol/lumera/x/action/v1/keeper"
"github.com/LumeraProtocol/supernode/v2/pkg/utils"
"github.com/LumeraProtocol/supernode/v2/sdk/adapters/lumera"
)
Expand Down Expand Up @@ -74,28 +75,32 @@
return fmt.Errorf("failed to decode cascade metadata: %w", err)
}

// Extract the base64-encoded data hash from the metadata
base64EnTcketDataHash := cascadeMetaData.DataHash
// Extract the base64-encoded data hash string from the metadata
dataHashB64 := cascadeMetaData.DataHash

// Decode the data hash from base64 to raw bytes
dataHashBytes, err := base64.StdEncoding.DecodeString(base64EnTcketDataHash)
// Decode the provided signature from base64 to raw bytes and coerce to r||s
signatureRaw, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
return fmt.Errorf("failed to decode data hash: %w", err)
return fmt.Errorf("failed to decode signature: %w", err)
}

// Decode the provided signature from base64 to raw bytes
signatureBytes, err := base64.StdEncoding.DecodeString(signature)
sigRS, err := actionkeeper.CoerceToRS64(signatureRaw)

Check failure on line 86 in sdk/task/helpers.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: actionkeeper.CoerceToRS64
if err != nil {
return fmt.Errorf("failed to decode signature: %w", err)
return fmt.Errorf("coerce signature: %w", err)
}

// Verify the signature using the Lumera client
// This checks if the signature was produced by the action creator
// for the given data hash
err = m.lumeraClient.VerifySignature(ctx, action.Creator, dataHashBytes, signatureBytes)
// Try raw verification over []byte(dataHashB64). If it fails, try ADR-36 bytes.
err = m.lumeraClient.VerifySignature(ctx, action.Creator, []byte(dataHashB64), sigRS)
if err != nil {
m.logger.Error(ctx, "Signature validation failed", "actionID", action.ID, "error", err)
return fmt.Errorf("signature validation failed: %w", err)
// ADR-36 fallback: sign doc with data = base64(dataHashB64)
doc, derr := actionkeeper.MakeADR36AminoSignBytes(action.Creator, base64.StdEncoding.EncodeToString([]byte(dataHashB64)))

Check failure on line 95 in sdk/task/helpers.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: actionkeeper.MakeADR36AminoSignBytes
if derr != nil {
m.logger.Error(ctx, "ADR36 doc build failed", "actionID", action.ID, "error", derr)
return fmt.Errorf("signature validation failed: %w", err)
}
if err2 := m.lumeraClient.VerifySignature(ctx, action.Creator, doc, sigRS); err2 != nil {
m.logger.Error(ctx, "Signature validation failed", "actionID", action.ID, "error", err)
return fmt.Errorf("signature validation failed: %w", err)
}
}

return nil
Expand Down
19 changes: 16 additions & 3 deletions supernode/cascade/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"sort"
"time"

actionkeeper "github.com/LumeraProtocol/lumera/x/action/v1/keeper"
actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types"
"github.com/LumeraProtocol/supernode/v2/pkg/cascadekit"
"github.com/LumeraProtocol/supernode/v2/pkg/codec"
Expand Down Expand Up @@ -117,12 +118,24 @@
return fmt.Errorf("get action for signature verification: %w", err)
}
creator := act.GetAction().Creator
sigBytes, err := base64.StdEncoding.DecodeString(signature)
sigRaw, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
return fmt.Errorf("invalid base64 signature: %w", err)
}
if err := task.LumeraClient.Verify(ctx, creator, []byte(actionID), sigBytes); err != nil {
return err
sigRS, err := actionkeeper.CoerceToRS64(sigRaw)

Check failure on line 125 in supernode/cascade/download.go

View workflow job for this annotation

GitHub Actions / cascade-e2e-tests

undefined: actionkeeper.CoerceToRS64

Check failure on line 125 in supernode/cascade/download.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.CoerceToRS64

Check failure on line 125 in supernode/cascade/download.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: actionkeeper.CoerceToRS64

Check failure on line 125 in supernode/cascade/download.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.CoerceToRS64
if err != nil {
return fmt.Errorf("coerce signature: %w", err)
}
if err := task.LumeraClient.Verify(ctx, creator, []byte(actionID), sigRS); err != nil {
// Fallback to ADR-36 sign-bytes verification over base64(actionID)
dataB64 := base64.StdEncoding.EncodeToString([]byte(actionID))
doc, derr := actionkeeper.MakeADR36AminoSignBytes(creator, dataB64)

Check failure on line 132 in supernode/cascade/download.go

View workflow job for this annotation

GitHub Actions / cascade-e2e-tests

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 132 in supernode/cascade/download.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 132 in supernode/cascade/download.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 132 in supernode/cascade/download.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.MakeADR36AminoSignBytes
if derr != nil {
return fmt.Errorf("build adr36 doc: %w", derr)
}
if err2 := task.LumeraClient.Verify(ctx, creator, doc, sigRS); err2 != nil {
return err
}
}
return nil
}
Expand Down
34 changes: 30 additions & 4 deletions supernode/cascade/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"strconv"

"cosmossdk.io/math"
actionkeeper "github.com/LumeraProtocol/lumera/x/action/v1/keeper"
actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types"
"github.com/LumeraProtocol/supernode/v2/pkg/cascadekit"
"github.com/LumeraProtocol/supernode/v2/pkg/codec"
Expand Down Expand Up @@ -87,13 +88,26 @@
if err != nil {
return cascadekit.IndexFile{}, nil, err
}
creatorSig, err := base64.StdEncoding.DecodeString(creatorSigB64)
creatorSigRaw, err := base64.StdEncoding.DecodeString(creatorSigB64)
if err != nil {
return cascadekit.IndexFile{}, nil, err
}
if err := task.LumeraClient.Verify(ctx, creator, []byte(indexB64), creatorSig); err != nil {
// Coerce signature to r||s then try raw -> ADR36
sigRS, err := actionkeeper.CoerceToRS64(creatorSigRaw)

Check failure on line 96 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / cascade-e2e-tests

undefined: actionkeeper.CoerceToRS64

Check failure on line 96 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.CoerceToRS64

Check failure on line 96 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: actionkeeper.CoerceToRS64

Check failure on line 96 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.CoerceToRS64
if err != nil {
return cascadekit.IndexFile{}, nil, err
}
if err := task.LumeraClient.Verify(ctx, creator, []byte(indexB64), sigRS); err != nil {
// Fallback to ADR-36 verification
dataB64 := base64.StdEncoding.EncodeToString([]byte(indexB64))
signDoc, derr := actionkeeper.MakeADR36AminoSignBytes(creator, dataB64)

Check failure on line 103 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / cascade-e2e-tests

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 103 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 103 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 103 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.MakeADR36AminoSignBytes
if derr != nil {
return cascadekit.IndexFile{}, nil, derr
}
if err2 := task.LumeraClient.Verify(ctx, creator, signDoc, sigRS); err2 != nil {
return cascadekit.IndexFile{}, nil, err
}
}
// Decode index
indexFile, err := cascadekit.DecodeIndexB64(indexB64)
if err != nil {
Expand All @@ -107,13 +121,25 @@
if err := cascadekit.VerifySingleBlock(layout); err != nil {
return cascadekit.IndexFile{}, nil, err
}
layoutSig, err := base64.StdEncoding.DecodeString(indexFile.LayoutSignature)
layoutSigRaw, err := base64.StdEncoding.DecodeString(indexFile.LayoutSignature)
if err != nil {
return cascadekit.IndexFile{}, nil, err
}
if err := task.LumeraClient.Verify(ctx, creator, layoutB64, layoutSig); err != nil {
layoutSigRS, err := actionkeeper.CoerceToRS64(layoutSigRaw)

Check failure on line 128 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / cascade-e2e-tests

undefined: actionkeeper.CoerceToRS64

Check failure on line 128 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.CoerceToRS64

Check failure on line 128 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: actionkeeper.CoerceToRS64

Check failure on line 128 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.CoerceToRS64
if err != nil {
return cascadekit.IndexFile{}, nil, err
}
if err := task.LumeraClient.Verify(ctx, creator, layoutB64, layoutSigRS); err != nil {
// Fallback to ADR-36 verification over string(layoutB64)
dataB64 := base64.StdEncoding.EncodeToString([]byte(string(layoutB64)))
signDoc, derr := actionkeeper.MakeADR36AminoSignBytes(creator, dataB64)

Check failure on line 135 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / cascade-e2e-tests

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 135 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 135 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: actionkeeper.MakeADR36AminoSignBytes

Check failure on line 135 in supernode/cascade/helper.go

View workflow job for this annotation

GitHub Actions / build

undefined: actionkeeper.MakeADR36AminoSignBytes
if derr != nil {
return cascadekit.IndexFile{}, nil, derr
}
if err2 := task.LumeraClient.Verify(ctx, creator, signDoc, layoutSigRS); err2 != nil {
return cascadekit.IndexFile{}, nil, err
}
}
return indexFile, layoutB64, nil
}

Expand Down
Loading