irma_signature.go 1.84 KB
Newer Older
1
2
3
4
5
6
package irma

import (
	"crypto/sha256"
	"encoding/asn1"
	"log"
7
	gobig "math/big"
8
9
10

	"github.com/bwesterb/go-atum"
	"github.com/mhe/gabi"
11
	"github.com/mhe/gabi/big"
12
13
)

14
// SignedMessage is a message signed with an attribute-based signature
15
// The 'realnonce' will be calculated as: SigRequest.GetNonce() = ASN1(nonce, SHA256(message), timestampSignature)
16
type SignedMessage struct {
17
18
19
20
21
22
	Signature gabi.ProofList            `json:"signature"`
	Indices   DisclosedAttributeIndices `json:"indices"`
	Nonce     *big.Int                  `json:"nonce"`
	Context   *big.Int                  `json:"context"`
	Message   string                    `json:"message"`
	Timestamp *atum.Timestamp           `json:"timestamp"`
23
24
}

25
26
func (sm *SignedMessage) GetNonce() *big.Int {
	return ASN1ConvertSignatureNonce(sm.Message, sm.Nonce, sm.Timestamp)
27
28
}

29
30
31
32
func (sm *SignedMessage) MatchesNonceAndContext(request *SignatureRequest) bool {
	return sm.Nonce.Cmp(request.Nonce) == 0 &&
		sm.Context.Cmp(request.Context) == 0 &&
		sm.GetNonce().Cmp(request.GetNonce()) == 0
33
34
}

35
36
37
38
39
40
41
func (sm *SignedMessage) Disclosure() *Disclosure {
	return &Disclosure{
		Proofs:  sm.Signature,
		Indices: sm.Indices,
	}
}

42
43
44
// ASN1ConvertSignatureNonce computes the nonce that is used in the creation of the attribute-based signature:
//    nonce = SHA256(serverNonce, SHA256(message), timestampSignature)
// where serverNonce is the nonce sent by the signature requestor.
45
46
func ASN1ConvertSignatureNonce(message string, nonce *big.Int, timestamp *atum.Timestamp) *big.Int {
	msgHash := sha256.Sum256([]byte(message))
47
	tohash := []interface{}{nonce.Value(), new(gobig.Int).SetBytes(msgHash[:])}
48
49
50
51
	if timestamp != nil {
		tohash = append(tohash, timestamp.Sig.Data)
	}
	asn1bytes, err := asn1.Marshal(tohash)
52
	if err != nil {
53
		log.Print(err) // TODO
54
55
56
57
	}
	asn1hash := sha256.Sum256(asn1bytes)
	return new(big.Int).SetBytes(asn1hash[:])
}