Skip to content

Commit

Permalink
add checks on curve, and serialize using gnark (#422)
Browse files Browse the repository at this point in the history
Co-authored-by: Bowen Xue <[email protected]>
  • Loading branch information
bxue-l2 and Bowen Xue authored Apr 2, 2024
1 parent 675f0e9 commit 4bf724f
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 67 deletions.
16 changes: 10 additions & 6 deletions core/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,17 @@ func (p *G1Point) VerifyEquivalence(p2 *G2Point) (bool, error) {
}

func (p *G1Point) Serialize() []byte {
return bn254utils.SerializeG1(p.G1Affine)
res := p.RawBytes()
return res[:]
}

func (p *G1Point) Deserialize(data []byte) (*G1Point, error) {
point, err := bn254utils.DeserializeG1(data)
var point bn254.G1Affine
_, err := point.SetBytes(data)
if err != nil {
return nil, err
}
return &G1Point{point}, nil
return &G1Point{&point}, nil
}

func (p *G1Point) Clone() *G1Point {
Expand Down Expand Up @@ -85,15 +87,17 @@ func (p *G2Point) Sub(p2 *G2Point) {
}

func (p *G2Point) Serialize() []byte {
return bn254utils.SerializeG2(p.G2Affine)
res := p.RawBytes()
return res[:]
}

func (p *G2Point) Deserialize(data []byte) (*G2Point, error) {
point, err := bn254utils.DeserializeG2(data)
var point bn254.G2Affine
_, err := point.SetBytes(data)
if err != nil {
return nil, err
}
return &G2Point{point}, nil
return &G2Point{&point}, nil
}

func (p *G2Point) Clone() *G2Point {
Expand Down
57 changes: 0 additions & 57 deletions core/bn254/attestation.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package bn254

import (
"errors"
"math/big"

"github.com/consensys/gnark-crypto/ecc/bn254"
Expand Down Expand Up @@ -94,62 +93,6 @@ func MulByGeneratorG2(a *fr.Element) *bn254.G2Affine {
return new(bn254.G2Affine).ScalarMultiplication(g2Gen, a.BigInt(new(big.Int)))
}

func SerializeG1(p *bn254.G1Affine) []byte {
b := make([]byte, 0)
tmp := p.X.Bytes()
for i := 0; i < 32; i++ {
b = append(b, tmp[i])
}
tmp = p.Y.Bytes()
for i := 0; i < 32; i++ {
b = append(b, tmp[i])
}
return b
}

func DeserializeG1(b []byte) (*bn254.G1Affine, error) {
if len(b) != 64 {
return nil, errors.New("could not deserialize G1 point: length must be exactly 64")
}
p := new(bn254.G1Affine)
p.X.SetBytes(b[0:32])
p.Y.SetBytes(b[32:64])
return p, nil
}

func SerializeG2(p *bn254.G2Affine) []byte {
b := make([]byte, 0)
tmp := p.X.A0.Bytes()
for i := 0; i < 32; i++ {
b = append(b, tmp[i])
}
tmp = p.X.A1.Bytes()
for i := 0; i < 32; i++ {
b = append(b, tmp[i])
}
tmp = p.Y.A0.Bytes()
for i := 0; i < 32; i++ {
b = append(b, tmp[i])
}
tmp = p.Y.A1.Bytes()
for i := 0; i < 32; i++ {
b = append(b, tmp[i])
}
return b
}

func DeserializeG2(b []byte) (*bn254.G2Affine, error) {
if len(b) != 128 {
return nil, errors.New("could not deserialize G2 point: length must be exactly 128")
}
p := new(bn254.G2Affine)
p.X.A0.SetBytes(b[0:32])
p.X.A1.SetBytes(b[32:64])
p.Y.A0.SetBytes(b[64:96])
p.Y.A1.SetBytes(b[96:128])
return p, nil
}

func MakePubkeyRegistrationData(privKey *fr.Element, operatorAddress common.Address) *bn254.G1Affine {
toHash := make([]byte, 0)
toHash = append(toHash, crypto.Keccak256([]byte("BN254PubkeyRegistration(address operator)"))...)
Expand Down
14 changes: 14 additions & 0 deletions core/serialization.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"slices"

binding "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDAServiceManager"
"github.com/consensys/gnark-crypto/ecc/bn254"

"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/wealdtech/go-merkletree"
Expand Down Expand Up @@ -362,6 +363,19 @@ func (h *BlobHeader) Serialize() ([]byte, error) {

func (h *BlobHeader) Deserialize(data []byte) (*BlobHeader, error) {
err := decode(data, h)

if !(*bn254.G1Affine)(h.BlobCommitments.Commitment).IsInSubGroup() {
return nil, fmt.Errorf("in BlobHeader Commitment is not in the subgroup")
}

if !(*bn254.G2Affine)(h.BlobCommitments.LengthCommitment).IsInSubGroup() {
return nil, fmt.Errorf("in BlobHeader LengthCommitment is not in the subgroup")
}

if !(*bn254.G2Affine)(h.BlobCommitments.LengthProof).IsInSubGroup() {
return nil, fmt.Errorf("in BlobHeader LengthProof is not in the subgroup")
}

return h, err
}

Expand Down
31 changes: 27 additions & 4 deletions encoding/serialization.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"encoding/json"
"fmt"

"github.com/consensys/gnark-crypto/ecc/bn254"
)
Expand All @@ -14,6 +15,10 @@ func (c *Frame) Serialize() ([]byte, error) {

func (c *Frame) Deserialize(data []byte) (*Frame, error) {
err := decode(data, c)
if !c.Proof.IsInSubGroup() {
return nil, fmt.Errorf("proof is in not the subgroup")
}

return c, err
}

Expand All @@ -39,11 +44,15 @@ func Decode(b []byte) (Frame, error) {
}

func (c *G1Commitment) Serialize() ([]byte, error) {
return encode(c)
res := (*bn254.G1Affine)(c).Bytes()
return res[:], nil
}

func (c *G1Commitment) Deserialize(data []byte) (*G1Commitment, error) {
err := decode(data, c)
_, err := (*bn254.G1Affine)(c).SetBytes(data)
if err != nil {
return nil, err
}
return c, err
}

Expand All @@ -55,15 +64,25 @@ func (c *G1Commitment) UnmarshalJSON(data []byte) error {
}
c.X = g1Point.X
c.Y = g1Point.Y

if !(*bn254.G1Affine)(c).IsInSubGroup() {
return fmt.Errorf("G1Commitment not in the subgroup")
}

return nil
}

func (c *G2Commitment) Serialize() ([]byte, error) {
return encode(c)
res := (*bn254.G2Affine)(c).Bytes()
return res[:], nil
}

func (c *G2Commitment) Deserialize(data []byte) (*G2Commitment, error) {
err := decode(data, c)
_, err := (*bn254.G2Affine)(c).SetBytes(data)
if err != nil {
return nil, err
}

return c, err
}

Expand All @@ -75,6 +94,10 @@ func (c *G2Commitment) UnmarshalJSON(data []byte) error {
}
c.X = g2Point.X
c.Y = g2Point.Y

if !(*bn254.G2Affine)(c).IsInSubGroup() {
return fmt.Errorf("G2Commitment not in the subgroup")
}
return nil
}

Expand Down
3 changes: 3 additions & 0 deletions node/grpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ func (s *Server) validateStoreChunkRequest(in *pb.StoreChunksRequest) error {
if blob.GetHeader() == nil {
return api.NewInvalidArgError("missing blob header in request")
}
if ValidatePointsFromBlobHeader(blob.GetHeader()) != nil {
return api.NewInvalidArgError("invalid points contained in the blob header in request")
}
if len(blob.GetHeader().GetQuorumHeaders()) == 0 {
return api.NewInvalidArgError("missing quorum headers in request")
}
Expand Down
53 changes: 53 additions & 0 deletions node/grpc/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/encoding"
"github.com/Layr-Labs/eigenda/node"
"github.com/consensys/gnark-crypto/ecc/bn254"
"github.com/consensys/gnark-crypto/ecc/bn254/fp"
"github.com/wealdtech/go-merkletree"
"github.com/wealdtech/go-merkletree/keccak256"
Expand All @@ -37,6 +38,7 @@ func GetBlobMessages(in *pb.StoreChunksRequest) ([]*core.BlobMessage, error) {
blobs := make([]*core.BlobMessage, len(in.GetBlobs()))
for i, blob := range in.GetBlobs() {
blobHeader, err := GetBlobHeaderFromProto(blob.GetHeader())

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -65,6 +67,43 @@ func GetBlobMessages(in *pb.StoreChunksRequest) ([]*core.BlobMessage, error) {
return blobs, nil
}

func ValidatePointsFromBlobHeader(h *pb.BlobHeader) error {
commitX := new(fp.Element).SetBytes(h.GetCommitment().GetX())
commitY := new(fp.Element).SetBytes(h.GetCommitment().GetY())
commitment := &encoding.G1Commitment{
X: *commitX,
Y: *commitY,
}

if !(*bn254.G1Affine)(commitment).IsInSubGroup() {
return errors.New("commitment is not in the subgroup")
}

var lengthCommitment, lengthProof encoding.G2Commitment
if h.GetLengthCommitment() != nil {
lengthCommitment.X.A0 = *new(fp.Element).SetBytes(h.GetLengthCommitment().GetXA0())
lengthCommitment.X.A1 = *new(fp.Element).SetBytes(h.GetLengthCommitment().GetXA1())
lengthCommitment.Y.A0 = *new(fp.Element).SetBytes(h.GetLengthCommitment().GetYA0())
lengthCommitment.Y.A1 = *new(fp.Element).SetBytes(h.GetLengthCommitment().GetYA1())
}

if !(*bn254.G2Affine)(&lengthCommitment).IsInSubGroup() {
return errors.New("lengthCommitment is not in the subgroup")
}

if h.GetLengthProof() != nil {
lengthProof.X.A0 = *new(fp.Element).SetBytes(h.GetLengthProof().GetXA0())
lengthProof.X.A1 = *new(fp.Element).SetBytes(h.GetLengthProof().GetXA1())
lengthProof.Y.A0 = *new(fp.Element).SetBytes(h.GetLengthProof().GetYA0())
lengthProof.Y.A1 = *new(fp.Element).SetBytes(h.GetLengthProof().GetYA1())
}

if !(*bn254.G2Affine)(&lengthProof).IsInSubGroup() {
return errors.New("lengthProof is not in the subgroup")
}
return nil
}

// GetBlobHeaderFromProto constructs a core.BlobHeader from a proto of pb.BlobHeader.
func GetBlobHeaderFromProto(h *pb.BlobHeader) (*core.BlobHeader, error) {
commitX := new(fp.Element).SetBytes(h.GetCommitment().GetX())
Expand All @@ -73,20 +112,34 @@ func GetBlobHeaderFromProto(h *pb.BlobHeader) (*core.BlobHeader, error) {
X: *commitX,
Y: *commitY,
}

if !(*bn254.G1Affine)(commitment).IsInSubGroup() {
return nil, errors.New("commitment is not in the subgroup")
}

var lengthCommitment, lengthProof encoding.G2Commitment
if h.GetLengthCommitment() != nil {
lengthCommitment.X.A0 = *new(fp.Element).SetBytes(h.GetLengthCommitment().GetXA0())
lengthCommitment.X.A1 = *new(fp.Element).SetBytes(h.GetLengthCommitment().GetXA1())
lengthCommitment.Y.A0 = *new(fp.Element).SetBytes(h.GetLengthCommitment().GetYA0())
lengthCommitment.Y.A1 = *new(fp.Element).SetBytes(h.GetLengthCommitment().GetYA1())
}

if !(*bn254.G2Affine)(&lengthCommitment).IsInSubGroup() {
return nil, errors.New("lengthCommitment is not in the subgroup")
}

if h.GetLengthProof() != nil {
lengthProof.X.A0 = *new(fp.Element).SetBytes(h.GetLengthProof().GetXA0())
lengthProof.X.A1 = *new(fp.Element).SetBytes(h.GetLengthProof().GetXA1())
lengthProof.Y.A0 = *new(fp.Element).SetBytes(h.GetLengthProof().GetYA0())
lengthProof.Y.A1 = *new(fp.Element).SetBytes(h.GetLengthProof().GetYA1())
}

if !(*bn254.G2Affine)(&lengthProof).IsInSubGroup() {
return nil, errors.New("lengthProof is not in the subgroup")
}

quorumHeaders := make([]*core.BlobQuorumInfo, len(h.GetQuorumHeaders()))
for i, header := range h.GetQuorumHeaders() {
if header.GetQuorumId() > core.MaxQuorumID {
Expand Down

0 comments on commit 4bf724f

Please sign in to comment.