From 3b281b00d4bc0cd608c0af48cc8a73de643a59d4 Mon Sep 17 00:00:00 2001 From: Freddie Coleman Date: Sun, 6 Mar 2022 13:18:24 +0000 Subject: [PATCH] bls.PrependSign to enable signing with any pk prepended --- CHANGELOG.md | 6 +- pkg/signatures/bls/bls_sig/usual_bls.go | 14 +++++ .../bls/bls_sig/usual_bls_sig_aug_test.go | 57 +++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22b2adae..248b2b2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,11 @@ All notable changes to this repo will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## v2.0.0 +## v2.1.0 + +### Add + +- Added PrependSign to SigAug in BLS Signatures to allow prepending message with any public key. ### Add diff --git a/pkg/signatures/bls/bls_sig/usual_bls.go b/pkg/signatures/bls/bls_sig/usual_bls.go index a827b188..7f99b55e 100644 --- a/pkg/signatures/bls/bls_sig/usual_bls.go +++ b/pkg/signatures/bls/bls_sig/usual_bls.go @@ -237,6 +237,20 @@ func (b SigAug) PartialSign(sks *SecretKeyShare, pk *PublicKey, msg []byte) (*Pa return sks.partialSign(bytes, b.dst) } +// Computes a signature in G1 with a prepended public key that is not necessary derived from the secret key +func (b SigAug) PrependSign(sk *SecretKey, msg []byte, pk *PublicKey) (*Signature, error) { + if len(msg) == 0 { + return nil, fmt.Errorf("message cannot be empty or nil") + } + + bytes, err := pk.MarshalBinary() + if err != nil { + return nil, fmt.Errorf("MarshalBinary failed") + } + bytes = append(bytes, msg...) + return sk.createSignature(bytes, b.dst) +} + // CombineSignatures takes partial signatures to yield a completed signature func (b SigAug) CombineSignatures(sigs ...*PartialSignature) (*Signature, error) { return combineSigs(sigs) diff --git a/pkg/signatures/bls/bls_sig/usual_bls_sig_aug_test.go b/pkg/signatures/bls/bls_sig/usual_bls_sig_aug_test.go index 178cd7e2..ecdc2ee2 100644 --- a/pkg/signatures/bls/bls_sig/usual_bls_sig_aug_test.go +++ b/pkg/signatures/bls/bls_sig/usual_bls_sig_aug_test.go @@ -332,6 +332,33 @@ func TestAugPartialSign(t *testing.T) { } } +func TestAugPrependSign(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigAug() + pk1, sk1, err := bls.KeygenWithSeed(ikm) + pk2, _, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + readRand(ikm, t) + sig, err := bls.PrependSign(sk1, ikm, pk2) + + if res, _ := bls.Verify(pk1, ikm, sig); !res { + t.Errorf("Aug Verify failed") + } + + if res, _ := bls.Verify(pk2, ikm, sig); !res { + t.Errorf("Aug Verify failed") + } + + ikm[0] += 1 + if res, _ := bls.Verify(pk1, ikm, sig); res { + t.Errorf("Aug Verify succeeded when it should've failed.") + } +} + // Ensure that mixed partial signatures from distinct origins create invalid composite signatures func TestAugPartialMixupShares(t *testing.T) { total := uint(5) @@ -410,3 +437,33 @@ func TestAugPartialSignNilMessage(t *testing.T) { t.Errorf("Expected partial sign of nil message to fail") } } + +func TestAugPrependSignEmptyMessage(t *testing.T) { + bls := NewSigAug() + _, sk, err := bls.Keygen() + pk, _, err := bls.Keygen() + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + // Sign a nil message + _, err = bls.PrependSign(sk, nil, pk) + if err == nil { + t.Errorf("Expected sign of nil message to fail") + } +} + +func TestAugPrependSignNilMessage(t *testing.T) { + bls := NewSigAug() + _, sk, err := bls.Keygen() + pk, _, err := bls.Keygen() + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + // Sign an empty message + _, err = bls.PrependSign(sk, []byte{}, pk) + if err == nil { + t.Errorf("Expected sign of empty message to fail") + } +}