Skip to content

Commit

Permalink
Add multi-message test
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-wood committed Oct 13, 2023
1 parent 96f8dfe commit a00adb5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 33 deletions.
67 changes: 39 additions & 28 deletions bbs/bbs.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,45 @@ func (s Signature) Encode() []byte {
return append(AEnc, eEnc...)
}

// XXX(caw): rename this function
func octetsToSignature(data []byte) (Signature, error) {
// 1. expected_len = octet_point_length + octet_scalar_length
expectedLen := octetPointLen + octetScalarLen
// 2. if length(signature_octets) != expected_len, return INVALID
if len(data) != expectedLen {
return Signature{}, fmt.Errorf("bbs: malformed signature")
}

// 3. A_octets = signature_octets[0..(octet_point_length - 1)]
// 4. A = octets_to_point_g1(A_octets)
AOctets := data[0:octetPointLen]
A := &pairing.G1{}
A.SetBytes(AOctets)

// 5. if A is INVALID, return INVALID
if !A.IsOnG1() {
return Signature{}, fmt.Errorf("bbs: invalid A signature component (not in G1)")
}
// 6. if A == Identity_G1, return INVALID
if A.IsIdentity() {
return Signature{}, fmt.Errorf("bbs: invalid A signature component (identity element)")
}

// 7. index = octet_point_length
// 8. end_index = index + octet_scalar_length - 1
// 9. e = OS2IP(signature_octets[index..end_index])
e := &pairing.Scalar{}
e.SetBytes(data[octetPointLen:])

// 10. if e = 0 OR e >= r, return INVALID
// 11. return (A, e)

return Signature{
A: A,
e: e,
}, nil
}

// (Abar, Bbar, r2^, r3^, (m^_j1, ..., m^_jU), c)
type Proof struct {
Abar *pairing.G1
Expand Down Expand Up @@ -92,10 +131,6 @@ func publicKey(sk *pairing.Scalar) []byte {
return W.BytesCompressed()
}

// Serialize
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bbs-signatures-03#name-serialize
// XXX(caw): this function feels too complicated and should instead be replaced separate serializeFunctions invoked directly

// Domain calculation
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bbs-signatures-03#name-domain-calculation
// XXX(caw): this function needs test vectors for the draft
Expand Down Expand Up @@ -305,33 +340,9 @@ func sign(sk *pairing.Scalar, pk []byte, header []byte, messages [][]byte) ([]by
return sig.Encode(), nil
}

func octetsToSignature(data []byte) (Signature, error) {
// 1. expected_len = octet_point_length + octet_scalar_length
// 2. if length(signature_octets) != expected_len, return INVALID
// 3. A_octets = signature_octets[0..(octet_point_length - 1)]
// 4. A = octets_to_point_g1(A_octets)
// 5. if A is INVALID, return INVALID
// 6. if A == Identity_G1, return INVALID
// 7. index = octet_point_length
// 8. end_index = index + octet_scalar_length - 1
// 9. e = OS2IP(signature_octets[index..end_index])
// 10. if e = 0 OR e >= r, return INVALID
// 11. return (A, e)

// XXX(caw): writeme

return Signature{}, nil
}

// Signature verification
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bbs-signatures-03#name-signature-verification-veri
func rawVerify(pk []byte, signature Signature, header []byte, messages [][]byte) error {
// 1. (Q_1, H_1, ..., H_L) = create_generators(L+1, PK)
// 2. domain = calculate_domain(PK, Q_1, (H_1, ..., H_L), header)
// 3. B = P1 + Q_1 * domain + H_1 * msg_1 + ... + H_L * msg_L
// 4. if e(A, W + BP2 * e) * e(B, -BP2) != Identity_GT, return INVALID
// 5. return VALID

// 1. L = length(messages)
L := len(messages)

Expand Down
29 changes: 24 additions & 5 deletions bbs/bbs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,30 @@ func TestSingleMessageSignature(t *testing.T) {
t.Fatal(err)
}

// sigEEnc, err := sig.e.MarshalBinary()
// if err != nil {
// t.Fatal(err)
// }
// fmt.Println(hex.EncodeToString(sigEEnc))
sigEnc := sig.Encode()
if !bytes.Equal(sigEnc, expectedSigEnc) {
t.Fatalf("incorrect signature, got %s, wanted %s", hex.EncodeToString(sigEnc), hex.EncodeToString(expectedSigEnc))
}
}

// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bbs-signatures-03#name-valid-multi-message-signatur
func TestMultiMessageSignature(t *testing.T) {
header := mustDecodeHex("11223344556677889900aabbccddeeff")
messages := testMessages()
expectedSigEnc := mustDecodeHex("895cd9c0ccb9aca4de913218655346d718711472f2bf1f3e68916de106a0d93cf2f47200819b45920bbda541db2d91480665df253fedab2843055bdc02535d83baddbbb2803ec3808e074f71f199751e")

ikm := mustDecodeHex("746869732d49532d6a7573742d616e2d546573742d494b4d2d746f2d67656e65726174652d246528724074232d6b6579")
keyInfo := mustDecodeHex("746869732d49532d736f6d652d6b65792d6d657461646174612d746f2d62652d757365642d696e2d746573742d6b65792d67656e")

sk, err := keyGen(ikm, keyInfo, nil)
if err != nil {
t.Fatal(err)
}

sig, err := rawSign(sk, publicKey(sk), header, messages)
if err != nil {
t.Fatal(err)
}

sigEnc := sig.Encode()
if !bytes.Equal(sigEnc, expectedSigEnc) {
Expand Down

0 comments on commit a00adb5

Please sign in to comment.