Skip to content

Commit

Permalink
Merge pull request #761 from oasisprotocol/andrew7234/misc-fixes
Browse files Browse the repository at this point in the history
Post-reindex hotfixes
  • Loading branch information
Andrew7234 authored Oct 18, 2024
2 parents daf42bf + 6cea7b2 commit 63f9f91
Show file tree
Hide file tree
Showing 11 changed files with 477 additions and 945 deletions.
11 changes: 11 additions & 0 deletions .changelog/761.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
post-reindex fixes

This PR combines several minor fixes that were applied during
the reindex of production.

1. Damask-style proposals are now unmarshalled correctly
2. Cobalt PVSS txs are now unmarshalled correctly using vendored
oasis-core types.
3. TakeEscrow events are now indexed properly.
4. minor bump in oapi-codegen version to v1.12. A subsequent PR
will bump it to v2
2 changes: 1 addition & 1 deletion analyzer/consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,7 @@ func (m *processor) queueEscrows(batch *storage.QueryBatch, data *stakingData) e
}
}
for _, e := range data.TakeEscrows {
var debondingAmount string
debondingAmount := "0"
if e.DebondingAmount != nil {
debondingAmount = e.DebondingAmount.String()
}
Expand Down
6 changes: 4 additions & 2 deletions coreapi/v21.1.1/beacon/api/pvss.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"

"github.com/oasisprotocol/oasis-core/go/common/crypto/signature"

pvss "github.com/oasisprotocol/nexus/coreapi/v21.1.1/common/crypto/pvss"
)

// removed var block
Expand All @@ -25,7 +27,7 @@ type PVSSCommit struct {
Epoch EpochTime `json:"epoch"`
Round uint64 `json:"round"`

Commit interface{} `json:"commit,omitempty"`
Commit pvss.Commit `json:"commit,omitempty"`
}

// Implements transaction.MethodMetadataProvider.
Expand All @@ -36,7 +38,7 @@ type PVSSReveal struct {
Epoch EpochTime `json:"epoch"`
Round uint64 `json:"round"`

Reveal interface{} `json:"reveal,omitempty"`
Reveal pvss.Reveal `json:"reveal,omitempty"`
}

// Implements transaction.MethodMetadataProvider.
Expand Down
105 changes: 105 additions & 0 deletions coreapi/v21.1.1/common/crypto/pvss/pvss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Package pvss implements a PVSS backed commit-reveal scheme loosely
// based on the Scalable Randomness Attested by Public Entities
// protocol by Casudo and David.
//
// In practice this implementation omits the things that make SCRAPE
// scalable/fast, and is just a consensus backed PVSS based beacon.
// The differences are as follows:
//
// - The coding theory based share verification mechanism is not
// implemented. The check is as in Schoenmakers' paper. This
// could be added at a future date for a performance gain.
//
// - The commit/reveal based fast path that skips having to recover
// each participant's secret if they submitted a protocol level
// reveal is omitted. It is possible to game the system by
// publishing shares for one secret and a commitment for another
// secret, and then choosing to reveal or not after everyone else
// has revealed. While this behavior is detectable, it either
// involves having to recover the secret from the shares anyway
// rendering the optimization moot, or having a userbase that
// understands that slashing is integral to the security of the
// system.
//
// See: https://eprint.iacr.org/2017/216.pdf
package pvss

import "go.dedis.ch/kyber/v3/group/nist"

var (
// Yes, this uses the NIST P-256 curve, due to vastly superior
// performance compared to kyber's Ed25519 implementation. In
// theory Ed25519 should be faster, but the runtime library's
// P-256 scalar multiply is optimized, and kyber's Ed25519
// is basically ref10.
suite = nist.NewBlakeSHA256P256()
)

// Config is the configuration for an execution of the PVSS protocol.
// removed type

// Instance is an instance of the PVSS protocol.
// removed type

// SetScalar sets the private scalar belonging to an instance. Under
// most circumstances this will be handled by the constructor.
// removed func

// Commit executes the commit phase of the protocol, generating a commitment
// message to be broadcasted to all participants.
// removed func

// OnCommit processes a commitment message received from a participant.
//
// Note: This assumes that the commit is authentic and attributable.
// removed func

// MayReveal returns true iff it is possible to proceed to the reveal
// step, and the total number of distinct valid commitments received.
// removed func

// Reveal executes the reveal phase of the protocol, generating a reveal
// message to be broadcasted to all participants.
// removed func

// OnReveal processes a reveal message received from a participant.
//
// Note: This assumes that the reveal is authentic and attributable.
// removed func

// MayRecover returns true iff it is possible to proceed to the recovery
// step, and the total number of distinct valid reveals received.
// removed func

// Recover executes the recovery phase of the protocol, returning the resulting
// composite entropy and the indexes of the participants that contributed fully.
// removed func

// New creates a new protocol instance with the provided configuration.
// removed func

// removed func

// removed func

// NewKeyPair creates a new scalar/point pair for use with a PVSS instance.
// removed func

// Commit is a PVSS commit.
type Commit struct {
Index int `json:"index"`
Shares []*CommitShare `json:"shares"`
}

// Reveal is a PVSS reveal.
type Reveal struct {
Index int `json:"index"`
DecryptedShares map[int]*PubVerShare `json:"decrypted_shares"`
}

// CommitState is a PVSS commit and the corresponding decrypted share,
// if any.
type CommitState struct {
Commit *Commit `json:"commit"`
DecryptedShare *PubVerShare `json:"decrypted_share,omitempty"`
}
232 changes: 232 additions & 0 deletions coreapi/v21.1.1/common/crypto/pvss/s11n.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
package pvss

import (
"crypto/elliptic"
"encoding/base64"
"fmt"

"go.dedis.ch/kyber/v3"
)

// As convenient as it is to use kyber's PVSS implementation, scalars and
// points being interfaces makes s11n a huge pain, and mandates using
// wrapper types so that this can play nice with CBOR/JSON etc.
//
// Aut viam inveniam aut faciam.

// Point is an elliptic curve point.
type Point struct {
inner kyber.Point
}

// Inner returns the actual kyber.Point.
// removed func

// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
func (p *Point) UnmarshalBinary(data []byte) error {
inner := suite.Point()
if err := inner.UnmarshalBinary(data); err != nil {
return fmt.Errorf("pvss/s11n: failed to deserialize point: %w", err)
}

checkPoint := Point{inner: inner}
if err := checkPoint.isWellFormed(); err != nil {
return fmt.Errorf("pvss/s11n: deserialized point is invalid: %w", err)
}
if checkPoint2, ok := inner.(isCanonicalAble); ok {
// edwards25519.Point.IsCanonical takes a buffer, since points
// that get serialized are always in canonical form.
if !checkPoint2.IsCanonical(data) {
return fmt.Errorf("pvss/s11n: point is not in canonical form")
}
}

p.inner = inner

return nil
}

// UnmarshalPEM decodes a PEM marshaled point.
// removed func

// UnmarshalText decodes a text marshaled point.
func (p *Point) UnmarshalText(text []byte) error {
b, err := base64.StdEncoding.DecodeString(string(text))
if err != nil {
return fmt.Errorf("pvss/s11n: failed to deserialize base64 encoded point: %w", err)
}

return p.UnmarshalBinary(b)
}

// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (p Point) MarshalBinary() ([]byte, error) {
if err := p.isWellFormed(); err != nil {
return nil, fmt.Errorf("pvss/s11n: refusing to serialize invalid point: %w", err)
}

data, err := p.inner.MarshalBinary()
if err != nil {
return nil, fmt.Errorf("pvss/s11n: failed to serialize point: %w", err)
}

return data, nil
}

// MarshalPEM encodes a point into PEM form.
// removed func

// MarshalText encodes a point into text form.
func (p *Point) MarshalText() ([]byte, error) {
b, err := p.MarshalBinary()
if err != nil {
return nil, err
}

return []byte(base64.StdEncoding.EncodeToString(b)), nil
}

// LoadPEM loads a point from a PEM file on disk. Iff the point is missing
// and a Scalar is provided, the Scalar's corresponding point will be written
// and loaded.
// removed func

func (p *Point) isWellFormed() error {
// Can never happen(?), but check anyway.
if p.inner == nil {
return fmt.Errorf("pvss/s11n: point is missing")
}

if !pointIsValid(p.inner) {
return fmt.Errorf("pvss/s11n: point is invalid")
}

return nil
}

type validAble interface {
Valid() bool
}

type hasSmallOrderAble interface {
HasSmallOrder() bool
}

type isCanonicalAble interface {
IsCanonical([]byte) bool
}

func pointIsValid(point kyber.Point) bool {
switch validator := point.(type) {
case validAble:
// P-256 point validation (ensures point is on curve)
//
// Note: Kyber's idea of a valid point includes the point at
// infinity, which does not ensure contributory behavior when
// doing ECDH.

// We write out the point to binary data, and unmarshal
// it with elliptic.Unmarshal, which checks to see if the
// point is on the curve (while rejecting the point at
// infinity).
//
// In theory, we could just examine the x/y coordinates, but
// there's no way to get at those without reflection hacks.
//
// WARNING: If this ever needs to support NIST curves other
// than P-256, this will need to get significantly more
// involved.
b, err := point.MarshalBinary()
if err != nil {
return false
}
if x, _ := elliptic.Unmarshal(elliptic.P256(), b); x == nil {
return false
}
return true
case hasSmallOrderAble:
// Ed25519 point validation (rejects small-order points)
return !validator.HasSmallOrder()
default:
return false
}
}

// removed func

// Scalar is a scalar.
type Scalar struct {
inner kyber.Scalar
}

// Inner returns the actual kyber.Scalar.
// removed func

// Point returns the corresponding point.
// removed func

// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
func (s *Scalar) UnmarshalBinary(data []byte) error {
inner := suite.Scalar()
if err := inner.UnmarshalBinary(data); err != nil {
return fmt.Errorf("pvss/s11n: failed to deserialize scalar: %w", err)
}

s.inner = inner

return nil
}

// UnmarshalPEM decodes a PEM marshaled scalar.
// removed func

// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (s Scalar) MarshalBinary() ([]byte, error) {
data, err := s.inner.MarshalBinary()
if err != nil {
return nil, fmt.Errorf("pvss/s11n: failed to serialize scalar: %w", err)
}

return data, nil
}

// MarshalPEM encodes a scalar into PEM form.
// removed func

// LoadOrGeneratePEM loads a scalar from a PEM file on disk. Iff the
// scalar is missing, a new one will be generated, written, and loaded.
// removed func

// removed func

// removed func

// PubVerShare is a public verifiable share (`pvss.PubVerShare`)
type PubVerShare struct {
V Point `json:"v"` // Encrypted/decrypted share

C Scalar `json:"c"` // Challenge
R Scalar `json:"r"` // Response
VG Point `json:"vg"` // Public commitment with respect to base point G
VH Point `json:"vh"` // Public commitment with respect to base point H
}

// removed func

// removed func

// removed func

// CommitShare is a commit share.
type CommitShare struct {
PolyV Point `json:"poly_v"` // Share of the public commitment polynomial
PubVerShare
}

// removed func

// removed func

// removed func

// removed func
Loading

0 comments on commit 63f9f91

Please sign in to comment.