func SchnorrVerify(suite abstract.Suite, message []byte, publicKey abstract.Point, signatureBuffer []byte) error { // Decode the signature buf := bytes.NewBuffer(signatureBuffer) sig := basicSig{} if err := suite.Read(buf, &sig); err != nil { return err } r := sig.R c := sig.C // Compute base**(r + x*c) == T var P, T abstract.Point P = suite.Point() T = suite.Point() T.Add(T.Mul(nil, r), P.Mul(publicKey, c)) // Verify that the hash based on the message and T // matches the challange c from the signature c = hashSchnorr(suite, message, T) if !c.Equal(sig.C) { return errors.New("invalid signature") } return nil }
// Verify checks a signature generated by Sign. // // The caller provides the message, anonymity set, and linkage scope // with which the signature was purportedly produced. // If the signature is a valid linkable signature (linkScope != nil), // this function returns a linkage tag that uniquely corresponds // to the signer within the given linkScope. // If the signature is a valid unlinkable signature (linkScope == nil), // returns an empty but non-nil byte-slice instead of a linkage tag on success. // Returns a nil linkage tag and an error if the signature is invalid. func Verify(suite abstract.Suite, message []byte, anonymitySet Set, linkScope []byte, signatureBuffer []byte) ([]byte, error) { n := len(anonymitySet) // anonymity set size L := []abstract.Point(anonymitySet) // public keys in ring // Decode the signature buf := bytes.NewBuffer(signatureBuffer) var linkBase, linkTag abstract.Point sig := lSig{} sig.S = make([]abstract.Secret, n) if linkScope != nil { // linkable ring signature if err := suite.Read(buf, &sig); err != nil { return nil, err } linkStream := suite.Cipher(linkScope) linkBase, _ = suite.Point().Pick(nil, linkStream) linkTag = sig.Tag } else { // unlinkable ring signature if err := suite.Read(buf, &sig.uSig); err != nil { return nil, err } } // Pre-hash the ring-position-invariant parameters to H1. H1pre := signH1pre(suite, linkScope, linkTag, message) // Verify the signature var P, PG, PH abstract.Point P = suite.Point() PG = suite.Point() if linkScope != nil { PH = suite.Point() } s := sig.S ci := sig.C0 for i := 0; i < n; i++ { PG.Add(PG.Mul(nil, s[i]), P.Mul(L[i], ci)) if linkScope != nil { PH.Add(PH.Mul(linkBase, s[i]), P.Mul(linkTag, ci)) } ci = signH1(suite, H1pre, PG, PH) } if !ci.Equal(sig.C0) { return nil, errors.New("invalid signature") } // Return the re-encoded linkage tag, for uniqueness checking if linkScope != nil { tag, _ := linkTag.MarshalBinary() return tag, nil } else { return []byte{}, nil } }
// ReadPrivKey will read the file and decrypt the private key inside // It takes a suite to decrypt and a filename to know where to read // Returns the secret and an error if anything wrong occured func ReadPrivKey(suite abstract.Suite, fileName string) (abstract.Secret, error) { secret := suite.Secret() // Opening files privFile, err := os.Open(fileName) if err != nil { return nil, err } defer privFile.Close() // Read the keys err = suite.Read(privFile, &secret) if err != nil { return nil, err } return secret, nil }
// ReadScalar64 takes a Base64-encoded scalar and returns that scalar, // optionally an error func ReadScalar64(suite abstract.Suite, r io.Reader) (abstract.Scalar, error) { s := suite.Scalar() dec := base64.NewDecoder(base64.StdEncoding, r) err := suite.Read(dec, &s) return s, err }
// ReadPub64 a public point to a base64 representation func ReadPub64(suite abstract.Suite, r io.Reader) (abstract.Point, error) { public := suite.Point() dec := base64.NewDecoder(base64.StdEncoding, r) err := suite.Read(dec, &public) return public, err }
func ReadSecret64(suite abstract.Suite, r io.Reader) (abstract.Secret, error) { sec := suite.Secret() dec := base64.NewDecoder(base64.StdEncoding, r) err := suite.Read(dec, &sec) return sec, err }