Skip to content

Commit

Permalink
support both basic and aug mpl
Browse files Browse the repository at this point in the history
  • Loading branch information
freddiecoleman committed Mar 6, 2022
1 parent c1cfde6 commit b8b1515
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 44 deletions.
2 changes: 1 addition & 1 deletion asserter/construction.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ func SignatureType(
signature types.SignatureType,
) error {
switch signature {
case types.Ecdsa, types.EcdsaRecovery, types.Ed25519, types.Schnorr1, types.SchnorrPoseidon, types.BlsG2Element:
case types.Ecdsa, types.EcdsaRecovery, types.Ed25519, types.Schnorr1, types.SchnorrPoseidon, types.Bls12381BasicMpl, types.Bls12381AugMpl:
return nil
default:
return fmt.Errorf("%w: %s", ErrSignatureTypeNotSupported, signature)
Expand Down
112 changes: 84 additions & 28 deletions keys/signer_bls12381.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,56 +43,80 @@ func (s *SignerBls12381) Sign(
return nil, err
}

if !(payload.SignatureType == types.BlsG2Element || payload.SignatureType == "") {
if !(payload.SignatureType == types.Bls12381BasicMpl || payload.SignatureType == types.Bls12381AugMpl || payload.SignatureType == "") {
return nil, fmt.Errorf(
"%w: expected %v but got %v",
"%w: expected %v or %v but got %v",
ErrSignUnsupportedPayloadSignatureType,
types.BlsG2Element,
types.Bls12381BasicMpl,
types.Bls12381AugMpl,
payload.SignatureType,
)
}

if sigType != types.BlsG2Element {
// Generate private key bytes
privKeyBytes := s.KeyPair.PrivateKey
privKey := &bls_sig.SecretKey{}
_ = privKey.UnmarshalBinary(privKeyBytes)

switch sigType {
case types.Bls12381BasicMpl:
sigBytes, _ := signBasic(privKey, payload, s.KeyPair.PublicKey)

return &types.Signature{
SigningPayload: payload,
PublicKey: s.KeyPair.PublicKey,
SignatureType: payload.SignatureType,
Bytes: sigBytes,
}, nil
case types.Bls12381AugMpl:
sigBytes, _ := signAug(privKey, payload, s.KeyPair.PublicKey)

return &types.Signature{
SigningPayload: payload,
PublicKey: s.KeyPair.PublicKey,
SignatureType: payload.SignatureType,
Bytes: sigBytes,
}, nil
default:
return nil, fmt.Errorf(
"%w: expected %v but got %v",
"%w: expected %v or %v but got %v",
ErrSignUnsupportedSignatureType,
types.BlsG2Element,
types.Bls12381BasicMpl,
types.Bls12381AugMpl,
sigType,
)
}
}

// Generate private key bytes
privKeyBytes := s.KeyPair.PrivateKey
privKey := &bls_sig.SecretKey{}
_ = privKey.UnmarshalBinary(privKeyBytes)

func signBasic(sk *bls_sig.SecretKey, payload *types.SigningPayload, pk *types.PublicKey) ([]byte, error) {
bls := bls_sig.NewSigBasic()
sig, err := bls.Sign(privKey, payload.Bytes)

sig, err := bls.Sign(sk, payload.Bytes)

if err != nil {
return nil, err
}
sigBytes, _ := sig.MarshalBinary()

return sigBytes, nil
}

func signAug(sk *bls_sig.SecretKey, payload *types.SigningPayload, pk *types.PublicKey) ([]byte, error) {
bls := bls_sig.NewSigAug()

sig, err := bls.Sign(sk, payload.Bytes)

if err != nil {
return nil, err
}
sigBytes, _ := sig.MarshalBinary()

return &types.Signature{
SigningPayload: payload,
PublicKey: s.KeyPair.PublicKey,
SignatureType: payload.SignatureType,
Bytes: sigBytes,
}, nil
return sigBytes, nil
}

// Verify verifies a Signature, by checking the validity of a Signature,
// the SigningPayload, and the PublicKey of the Signature.
func (s *SignerBls12381) Verify(signature *types.Signature) error {
if signature.SignatureType != types.BlsG2Element {
return fmt.Errorf(
"%w: expected %v but got %v",
ErrVerifyUnsupportedPayloadSignatureType,
types.BlsG2Element,
signature.SignatureType,
)
}

pubKeyBytes := signature.PublicKey.Bytes
pubKey := &bls_sig.PublicKey{}
_ = pubKey.UnmarshalBinary(pubKeyBytes)
Expand All @@ -106,8 +130,40 @@ func (s *SignerBls12381) Verify(signature *types.Signature) error {
return fmt.Errorf("%w: %s", ErrVerifyFailed, err)
}

switch signature.SignatureType {
case types.Bls12381BasicMpl:
return verifyBasic(pubKey, signature.SigningPayload.Bytes, sig)
case types.Bls12381AugMpl:
return verifyAug(pubKey, signature.SigningPayload.Bytes, sig)
default:
return fmt.Errorf(
"%w: expected %v or %v but got %v",
ErrVerifyUnsupportedPayloadSignatureType,
types.Bls12381BasicMpl,
types.Bls12381AugMpl,
signature.SignatureType,
)
}
}

func verifyBasic(pubKey *bls_sig.PublicKey, payload []byte, signature *bls_sig.Signature) error {
bls := bls_sig.NewSigBasic()
result, err := bls.Verify(pubKey, signature.SigningPayload.Bytes, sig)
result, err := bls.Verify(pubKey, payload, signature)

if err != nil {
return err
}

if !result {
return fmt.Errorf("%w: %s", ErrVerifyFailed, "Verify failed")
}

return nil
}

func verifyAug(pubKey *bls_sig.PublicKey, payload []byte, signature *bls_sig.Signature) error {
bls := bls_sig.NewSigAug()
result, err := bls.Verify(pubKey, payload, signature)

if err != nil {
return err
Expand Down
100 changes: 91 additions & 9 deletions keys/signer_bls12381_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ import (

"github.com/stretchr/testify/assert"

"github.com/coinbase/kryptology/pkg/signatures/bls/bls_sig"
"github.com/coinbase/rosetta-sdk-go/types"
)

var bls12381Keypair *KeyPair
var signerBls12381 Signer
var payloadBytes []byte
var augSigner Signer
var augPayload []byte

func init() {
bls12381Keypair, _ := GenerateKeypair(types.Bls12381)
bls12381Keypair, _ = GenerateKeypair(types.Bls12381)
signerBls12381, _ = bls12381Keypair.Signer()

unsignedPayloadStr := "a7ca4bce10200d073ef10c46e9d27c3b4e31263d4c07fbec447650fcc1b286" +
Expand All @@ -37,15 +41,15 @@ func init() {
payloadBytes, _ = hex.DecodeString(unsignedPayloadStr)
}

func TestSignBls12381(t *testing.T) {
func TestSignBls12381Basic(t *testing.T) {
type payloadTest struct {
payload *types.SigningPayload
err bool
errMsg error
}

var payloadTests = []payloadTest{
{mockPayload(payloadBytes, types.BlsG2Element), false, nil},
{mockPayload(payloadBytes, types.Bls12381BasicMpl), false, nil},
{mockPayload(payloadBytes, ""), false, nil},
{mockPayload(payloadBytes, types.Ecdsa), true, ErrSignUnsupportedPayloadSignatureType},
{
Expand All @@ -55,7 +59,7 @@ func TestSignBls12381(t *testing.T) {
},
}
for _, test := range payloadTests {
signature, err := signerBls12381.Sign(test.payload, types.BlsG2Element)
signature, err := signerBls12381.Sign(test.payload, types.Bls12381BasicMpl)

if !test.err {
assert.NoError(t, err)
Expand All @@ -67,14 +71,14 @@ func TestSignBls12381(t *testing.T) {
}
}

func TestVerifyBls(t *testing.T) {
func TestVerifyBls12381Basic(t *testing.T) {
type signatureTest struct {
signature *types.Signature
errMsg error
}

payload := mockPayload(payloadBytes, types.BlsG2Element)
testSignature, err := signerBls12381.Sign(payload, types.BlsG2Element)
payload := mockPayload(payloadBytes, types.Bls12381BasicMpl)
testSignature, err := signerBls12381.Sign(payload, types.Bls12381BasicMpl)
assert.NoError(t, err)

simpleBytes := make([]byte, 32)
Expand All @@ -92,7 +96,7 @@ func TestVerifyBls(t *testing.T) {
payloadBytes,
simpleBytes), ErrVerifyUnsupportedPayloadSignatureType},
{mockSignature(
types.BlsG2Element,
types.Bls12381BasicMpl,
signerBls12381.PublicKey(),
simpleBytes,
testSignature.Bytes), ErrVerifyFailed},
Expand All @@ -105,11 +109,89 @@ func TestVerifyBls(t *testing.T) {

// happy path
goodSignature := mockSignature(
types.BlsG2Element,
types.Bls12381BasicMpl,
signerBls12381.PublicKey(),
payloadBytes,
testSignature.Bytes,
)

assert.Equal(t, nil, signerBls12381.Verify(goodSignature))
}

func mockPublicKey(
pubkey_bytes []byte,
curveType types.CurveType,
) *types.PublicKey {
mockPubKey := &types.PublicKey{
Bytes: pubkey_bytes,
CurveType: curveType,
}

return mockPubKey
}

func mockKP(
pubkey *types.PublicKey,
pk_bytes []byte,
) *KeyPair {
mockKP := &KeyPair{
PublicKey: pubkey,
PrivateKey: pk_bytes,
}

return mockKP
}

func TestBls12381AugPrepend(t *testing.T) {
type signatureTest struct {
signature *types.Signature
errMsg error
}

sk1_bytes, _ := hex.DecodeString("1603e1217d13437657e2716bd51ecb84e803170368e0dcbf2b6eb704d6914d1c")
synthetic_sk_bytes, _ := hex.DecodeString("0c0dd789a90f993feb20dc4ce7d9d689ce9a669341d06d6638696cba1eea3177")
synthetic_offset_sk_bytes, _ := hex.DecodeString("1d0baa87e45f286a6a1cde0566191e6a0e6a6fa7223764f894c4836565207360")

payload := mockPayload(payloadBytes, types.Bls12381AugMpl)

sk1 := new(bls_sig.SecretKey)
sk1.UnmarshalBinary(sk1_bytes)
pk1, _ := sk1.GetPublicKey()
pk1_bytes, _ := pk1.MarshalBinary()
pubKey := mockPublicKey(pk1_bytes, types.Bls12381)
keyPair := mockKP(pubKey, sk1_bytes)
signer, _ := keyPair.Signer()

sig1, _ := signer.Sign(payload, types.Bls12381AugMpl)
assert.Equal(t, nil, signer.Verify(sig1))

synthetic_sk := new(bls_sig.SecretKey)
synthetic_sk.UnmarshalBinary(synthetic_sk_bytes)
synthetic_pk, _ := synthetic_sk.GetPublicKey()
synthetic_pk_bytes, _ := synthetic_pk.MarshalBinary()
syntheticPubKey := mockPublicKey(synthetic_pk_bytes, types.Bls12381)
syntheticKeyPair := mockKP(syntheticPubKey, synthetic_sk_bytes)
syntheticSigner, _ := syntheticKeyPair.Signer()

sig2, _ := syntheticSigner.Sign(payload, types.Bls12381AugMpl)
assert.Equal(t, nil, syntheticSigner.Verify(sig2))

synthetic_offset_sk := new(bls_sig.SecretKey)
synthetic_offset_sk.UnmarshalBinary(synthetic_offset_sk_bytes)
synthetic_offset_pk, _ := synthetic_offset_sk.GetPublicKey()
synthetic_offset_pk_bytes, _ := synthetic_offset_pk.MarshalBinary()
syntheticOffsetPubKey := mockPublicKey(synthetic_offset_pk_bytes, types.Bls12381)
syntheticOffsetKeyPair := mockKP(syntheticOffsetPubKey, synthetic_offset_sk_bytes)
syntheticOffsetSigner, _ := syntheticOffsetKeyPair.Signer()

prependedPayload := mockPayload(append(syntheticPubKey.Bytes, payloadBytes...), types.Bls12381AugMpl)

offset_sig, _ := syntheticOffsetSigner.Sign(prependedPayload, types.Bls12381AugMpl)
assert.Equal(t, nil, syntheticOffsetSigner.Verify(offset_sig))

sig3, _ := signer.Sign(prependedPayload, types.Bls12381AugMpl)

assert.Equal(t, nil, signer.Verify(sig3))
assert.Equal(t, nil, syntheticOffsetSigner.Verify(sig3))
assert.Equal(t, nil, syntheticSigner.Verify(sig3))
}
13 changes: 7 additions & 6 deletions types/signature_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ type SignatureType string

// List of SignatureType
const (
BlsG2Element SignatureType = "bls12381_g2_element"
Ecdsa SignatureType = "ecdsa"
EcdsaRecovery SignatureType = "ecdsa_recovery"
Ed25519 SignatureType = "ed25519"
Schnorr1 SignatureType = "schnorr_1"
SchnorrPoseidon SignatureType = "schnorr_poseidon"
Bls12381BasicMpl SignatureType = "bls12381_basic_mpl"
Bls12381AugMpl SignatureType = "bls12381_aug_mpl"
Ecdsa SignatureType = "ecdsa"
EcdsaRecovery SignatureType = "ecdsa_recovery"
Ed25519 SignatureType = "ed25519"
Schnorr1 SignatureType = "schnorr_1"
SchnorrPoseidon SignatureType = "schnorr_poseidon"
)

0 comments on commit b8b1515

Please sign in to comment.