@@ -69,6 +69,8 @@ type SignatureFile struct {
6969 Challenge string
7070 // The signature response
7171 Response string
72+ // The aggregated commitment used for signing
73+ Commitment string
7274}
7375
7476// Our crypto-suite used in the program
@@ -259,34 +261,65 @@ func VerifySignature(file, sigFile string) bool {
259261// Message is your own hash, and reply contains the inclusion proof + signature
260262// on the aggregated message
261263func verifySignature (message hashid.HashId , reply * defs.StampReply ) bool {
264+ // First check if the challenge is ok
265+ if err := verifyChallenge (suite , reply ); err != nil {
266+ dbg .Lvl1 ("Challenge-check : FAILED (" , err , ")" )
267+ return false
268+ }
269+ dbg .Lvl1 ("Challenge-check : OK" )
270+ // Then check if the signature is ok
262271 sig := defs.BasicSignature {
263272 Chall : reply .SigBroad .C ,
264273 Resp : reply .SigBroad .R0_hat ,
265274 }
266275 public , _ := cliutils .ReadPub64 (suite , strings .NewReader (conf .AggPubKey ))
267- if err := SchnorrVerify (suite , reply .MerkleRoot , public , sig ); err != nil {
276+ // Incorporate the timestamp in the message since the verification process
277+ // is done by reconstructing the challenge
278+ var b bytes.Buffer
279+ if err := binary .Write (& b , binary .LittleEndian , reply .Timestamp ); err != nil {
280+ dbg .Lvl1 ("Error marshaling the timestamp for signature verification" )
281+ }
282+ msg := append (b .Bytes (), []byte (reply .MerkleRoot )... )
283+ if err := SchnorrVerify (suite , msg , public , sig ); err != nil {
268284 dbg .Lvl1 ("Signature-check : FAILED (" , err , ")" )
269285 return false
270286 }
271287 dbg .Lvl1 ("Signature-check : OK" )
272288
273- // Verify inclusion proof
274- // First, concat the timestamp to the message
275- buf := []byte (message )
276- bt := new (bytes.Buffer )
277- if err := binary .Write (bt , binary .LittleEndian , reply .Timestamp ); err != nil {
278- dbg .Fatal ("Timestamp have not been appended to the message. Abort" )
279- }
280- messageConcat := append (buf , bt .Bytes ()... )
281- // Then check the proof
282- if ! proof .CheckProof (suite .Hash , reply .MerkleRoot , hashid .HashId (messageConcat ), reply .Prf ) {
289+ // finally check the proof
290+ if ! proof .CheckProof (suite .Hash , reply .MerkleRoot , hashid .HashId (message ), reply .Prf ) {
283291 dbg .Lvl1 ("Inclusion-check : FAILED" )
284292 return false
285293 }
286294 dbg .Lvl1 ("Inclusion-check : OK" )
287295 return true
288296}
289297
298+ // verifyChallenge will recontstruct the challenge in order to see if any of the
299+ // components of the challenge has been spoofed or not. It may be a different
300+ // timestamp .
301+ func verifyChallenge (suite abstract.Suite , reply * defs.StampReply ) error {
302+
303+ // marshal the V
304+ pbuf , err := reply .SigBroad .V0_hat .MarshalBinary ()
305+ if err != nil {
306+ return err
307+ }
308+ c := suite .Cipher (pbuf )
309+ // concat timestamp and merkle root
310+ var b bytes.Buffer
311+ if err := binary .Write (& b , binary .LittleEndian , reply .Timestamp ); err != nil {
312+ return err
313+ }
314+ cbuf := append (b .Bytes (), reply .MerkleRoot ... )
315+ c .Message (nil , nil , cbuf )
316+ challenge := suite .Secret ().Pick (c )
317+ if challenge .Equal (reply .SigBroad .C ) {
318+ return nil
319+ }
320+ return errors .New ("Challenge reconstructed is not equal to the one given ><" )
321+ }
322+
290323// A simple verification of a schnorr signature given the message
291324//TAKEN FROM SIG_TEST from abstract
292325func SchnorrVerify (suite abstract.Suite , message []byte , publicKey abstract.Point , sig defs.BasicSignature ) error {
@@ -322,24 +355,29 @@ func WriteSignatureFile(nameSig, file string, hash []byte, stamp *defs.StampRepl
322355 for _ , pr := range stamp .Prf {
323356 p = append (p , base64 .StdEncoding .EncodeToString (pr ))
324357 }
325- // Write challenge and response part
358+ // Write challenge and response + commitment part
326359 var bufChall bytes.Buffer
327360 var bufResp bytes.Buffer
361+ var bufCommit bytes.Buffer
328362 if err := cliutils .WriteSecret64 (suite , & bufChall , stamp .SigBroad .C ); err != nil {
329363 dbg .Fatal ("Could not write secret challenge :" , err )
330364 }
331365 if err := cliutils .WriteSecret64 (suite , & bufResp , stamp .SigBroad .R0_hat ); err != nil {
332366 dbg .Fatal ("Could not write secret response : " , err )
333367 }
368+ if err := cliutils .WritePub64 (suite , & bufCommit , stamp .SigBroad .V0_hat ); err != nil {
369+ dbg .Fatal ("Could not write aggregated commitment : " , err )
370+ }
334371 // Signature file struct containing everything needed
335372 sigStr := & SignatureFile {
336- Name : file ,
337- Timestamp : stamp .Timestamp ,
338- Hash : base64 .StdEncoding .EncodeToString (hash ),
339- Proof : p ,
340- Root : base64 .StdEncoding .EncodeToString (stamp .MerkleRoot ),
341- Challenge : bufChall .String (),
342- Response : bufResp .String (),
373+ Name : file ,
374+ Timestamp : stamp .Timestamp ,
375+ Hash : base64 .StdEncoding .EncodeToString (hash ),
376+ Proof : p ,
377+ Root : base64 .StdEncoding .EncodeToString (stamp .MerkleRoot ),
378+ Challenge : bufChall .String (),
379+ Response : bufResp .String (),
380+ Commitment : bufCommit .String (),
343381 }
344382
345383 // Print to the screen, and write to file
@@ -382,7 +420,11 @@ func ReadSignatureFile(name string) ([]byte, *defs.StampReply, error) {
382420 if err != nil {
383421 dbg .Fatal ("Could not read secret challenge : " , err )
384422 }
385- reply .SigBroad .C , err = cliutils .ReadSecret64 (suite , strings .NewReader (sigStr .Challenge ))
423+ if reply .SigBroad .C , err = cliutils .ReadSecret64 (suite , strings .NewReader (sigStr .Challenge )); err != nil {
424+ dbg .Fatal ("Could not read the aggregate commitment :" , err )
425+ }
426+ reply .SigBroad .V0_hat , err = cliutils .ReadPub64 (suite , strings .NewReader (sigStr .Commitment ))
427+
386428 return hash , reply , err
387429
388430}
0 commit comments