// PointEncodeTo provides a generic implementation of Point.EncodeTo // based on Point.Encode. func PointMarshalTo(p abstract.Point, w io.Writer) (int, error) { buf, err := p.MarshalBinary() if err != nil { return 0, err } return w.Write(buf) }
// HashKDF is a random map from G to Z_p, for use as the key derivation function (KDF) in the hash-based Verdict // construction func HashKDF(point abstract.Point) abstract.Secret { bytes, _ := point.MarshalBinary() cipher := Suite.Cipher(bytes) // This seems to be the only easy way to get outside data reliably in an abstract.Secret. return Suite.Secret().Pick(cipher) }
func (rh *RandHound) newSession(public abstract.Point, purpose string, time time.Time) (*Session, []byte, error) { buf := new(bytes.Buffer) pub, err := public.MarshalBinary() if err != nil { return nil, nil, err } if err = binary.Write(buf, binary.LittleEndian, pub); err != nil { return nil, nil, err } tm, err := time.MarshalBinary() if err != nil { return nil, nil, err } if err = binary.Write(buf, binary.LittleEndian, tm); err != nil { return nil, nil, err } if err = binary.Write(buf, binary.LittleEndian, []byte(purpose)); err != nil { return nil, nil, err } return &Session{ Fingerprint: pub, Purpose: purpose, Time: time}, rh.hash(buf.Bytes()), nil }
// Checks the signature against // the message func SchnorrVerify(suite abstract.Suite, kp SchnorrPublicKey, msg []byte, sig []byte) (bool, error) { buf := bytes.NewBuffer(sig) signature := SchnorrSignature{} err := abstract.Read(buf, &signature, suite) if err != nil { return false, err } s := signature.S e := signature.E var gs, ye, r abstract.Point gs = suite.Point().Mul(nil, s) // g^s ye = suite.Point().Mul(kp.Y, e) // y^e r = suite.Point().Add(gs, ye) // g^xy^e r_bin, _ := r.MarshalBinary() msg_and_r := append(msg, r_bin...) hasher := sha3.New256() hasher.Write(msg_and_r) h := hasher.Sum(nil) // again I'm hoping this just reads the state out // and doesn't actually perform any ops lct := suite.Cipher(h) ev := suite.Secret().Pick(lct) return ev.Equal(e), nil }
// Verify takes a signature issued by EdDSA.Sign and // return nil if it is a valid signature, or an error otherwise // Takes: // - public key used in signing // - msg is the message to sign // - sig is the signature return by EdDSA.Sign func Verify(public abstract.Point, msg, sig []byte) error { if len(sig) != 64 { return errors.New("Signature length invalid") } R := suite.Point() if err := R.UnmarshalBinary(sig[:32]); err != nil { return fmt.Errorf("R invalid point: %s", err) } s := suite.Scalar() s.UnmarshalBinary(sig[32:]) // reconstruct h = H(R || Public || Msg) Pbuff, err := public.MarshalBinary() if err != nil { return err } hash := sha512.New() hash.Write(sig[:32]) hash.Write(Pbuff) hash.Write(msg) h := suite.Scalar().SetBytes(hash.Sum(nil)) // reconstruct S == k*A + R S := suite.Point().Mul(nil, s) hA := suite.Point().Mul(public, h) RhA := suite.Point().Add(R, hA) if !RhA.Equal(S) { return errors.New("Recontructed S is not equal to signature") } return nil }
/* Given a Diffie-Hellman shared public key, produces a secret to encrypt * another secret * * Arguments * diffieBase = the DH shared public key * * Return * the DH secret */ func (p *Deal) diffieHellmanSecret(diffieBase abstract.Point) abstract.Secret { buff, err := diffieBase.MarshalBinary() if err != nil { panic("Bad shared secret for Diffie-Hellman given.") } cipher := p.suite.Cipher(buff) return p.suite.Secret().Pick(cipher) }
// 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.Scalar, 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.C0); err != nil { return nil, err } if err := suite.Read(buf, &sig.S); 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 } }
// Returns a hash of the message and the random secret: // H( m || V ) // Returns an error if something went wrong with the marshalling func (s *Schnorr) hashMessage(msg []byte, v abstract.Point) (abstract.Scalar, error) { vb, err := v.MarshalBinary() if err != nil { return nil, err } c := s.suite.Cipher(vb) c.Message(nil, nil, msg) return s.suite.Scalar().Pick(c), nil }
func signH1pre(suite abstract.Suite, linkScope []byte, linkTag abstract.Point, message []byte) abstract.Cipher { H1pre := suite.Cipher(message) // m if linkScope != nil { H1pre.Write(linkScope) // L tag, _ := linkTag.MarshalBinary() H1pre.Write(tag) // ~y } return H1pre }
func signH1(suite abstract.Suite, H1pre abstract.Cipher, PG, PH abstract.Point) abstract.Secret { H1 := H1pre.Clone() PGb, _ := PG.MarshalBinary() H1.Write(PGb) if PH != nil { PHb, _ := PH.MarshalBinary() H1.Write(PHb) } H1.Message(nil, nil, nil) // finish message absorption return suite.Secret().Pick(H1) }
func hash(suite abstract.Suite, r abstract.Point, msg []byte) (abstract.Scalar, error) { rBuf, err := r.MarshalBinary() if err != nil { return nil, err } cipher := suite.Cipher(rBuf) cipher.Message(nil, nil, msg) // (re)compute challenge (e) e := suite.Scalar().Pick(cipher) return e, nil }
func verifyCommitment(suite abstract.Suite, msg []byte, commitment abstract.Point, challenge abstract.Scalar) error { pb, err := commitment.MarshalBinary() if err != nil { return err } cipher := suite.Cipher(pb) cipher.Message(nil, nil, msg) // reconstructed challenge reconstructed := suite.Scalar().Pick(cipher) if !reconstructed.Equal(challenge) { return errors.New("Reconstructed challenge not equal to one given") } return nil }
// PubHex converts a Public point to a hexadecimal representation func PubHex(suite abstract.Suite, point abstract.Point) (string, error) { pbuf, err := point.MarshalBinary() return hex.EncodeToString(pbuf), err }
// Returns a secret that depends on on a message and a point func hashElGamal(suite abstract.Suite, message []byte, p abstract.Point) abstract.Secret { pb, _ := p.MarshalBinary() c := suite.Cipher(pb) c.Message(nil, nil, message) return suite.Secret().Pick(c) }
func handleAnnouncement(params map[string]interface{}) { var g abstract.Point = nil keyList := util.ProtobufDecodePointList(params["keys"].([]byte)) valList := params["vals"].([]util.ByteArray) size := len(keyList) if val, ok := params["g"]; ok { // contains g byteG := val.([]byte) g = anonServer.Suite.Point() g.UnmarshalBinary(byteG) g = anonServer.Suite.Point().Mul(g, anonServer.Roundkey) // verify the previous shuffle verifyNeffShuffle(params) } else { g = anonServer.Suite.Point().Mul(nil, anonServer.Roundkey) } X1 := make([]abstract.Point, 1) X1[0] = anonServer.PublicKey newKeys := make([]abstract.Point, size) newVals := make([][]byte, size) for i := 0; i < len(keyList); i++ { // encrypt the public key using modPow newKeys[i] = anonServer.Suite.Point().Mul(keyList[i], anonServer.Roundkey) // decrypt the reputation using ElGamal algorithm MM, err := anon.Decrypt(anonServer.Suite, valList[i].Arr, anon.Set(X1), 0, anonServer.PrivateKey, false) util.CheckErr(err) newVals[i] = MM // update key map anonServer.KeyMap[newKeys[i].String()] = keyList[i] } byteNewKeys := util.ProtobufEncodePointList(newKeys) byteNewVals := util.SerializeTwoDimensionArray(newVals) byteG, err := g.MarshalBinary() util.CheckErr(err) if size <= 1 { // no need to shuffle, just send the package to next server pm := map[string]interface{}{ "keys": byteNewKeys, "vals": byteNewVals, "g": byteG, } event := &proto.Event{proto.ANNOUNCEMENT, pm} util.Send(anonServer.Socket, anonServer.NextHop, util.Encode(event)) return } Xori := make([]abstract.Point, len(newVals)) for i := 0; i < size; i++ { Xori[i] = anonServer.Suite.Point().Mul(nil, anonServer.PrivateKey) } byteOri := util.ProtobufEncodePointList(Xori) rand := anonServer.Suite.Cipher(abstract.RandomKey) // *** perform neff shuffle here *** Xbar, Ybar, _, Ytmp, prover := neffShuffle(Xori, newKeys, rand) prf, err := proof.HashProve(anonServer.Suite, "PairShuffle", rand, prover) util.CheckErr(err) // this is the shuffled key finalKeys := convertToOrigin(Ybar, Ytmp) finalVals := rebindReputation(newKeys, newVals, finalKeys) // send data to the next server byteXbar := util.ProtobufEncodePointList(Xbar) byteYbar := util.ProtobufEncodePointList(Ybar) byteFinalKeys := util.ProtobufEncodePointList(finalKeys) byteFinalVals := util.SerializeTwoDimensionArray(finalVals) bytePublicKey, _ := anonServer.PublicKey.MarshalBinary() // prev keys means the key before shuffle pm := map[string]interface{}{ "xbar": byteXbar, "ybar": byteYbar, "keys": byteFinalKeys, "vals": byteFinalVals, "proof": prf, "prev_keys": byteOri, "prev_vals": byteNewKeys, "shuffled": true, "public_key": bytePublicKey, "g": byteG, } event := &proto.Event{proto.ANNOUNCEMENT, pm} util.Send(anonServer.Socket, anonServer.NextHop, util.Encode(event)) }
// Returns a secret that depends on on a message and a point func hashSchnorr(suite abstract.Suite, message []byte, p abstract.Point) abstract.Scalar { pb, _ := p.MarshalBinary() c := suite.Cipher(pb) c.Message(nil, nil, message) return suite.Scalar().Pick(c) }
func (rh *RandHound) sessionID(nodes int, faulty int, purpose string, time time.Time, rand []byte, threshold []int, clientKey abstract.Point, serverKey [][]abstract.Point) ([]byte, error) { buf := new(bytes.Buffer) if len(threshold) != len(serverKey) { return nil, fmt.Errorf("Non-matching number of group thresholds and keys") } if err := binary.Write(buf, binary.LittleEndian, uint32(nodes)); err != nil { return nil, err } if err := binary.Write(buf, binary.LittleEndian, uint32(faulty)); err != nil { return nil, err } if _, err := buf.WriteString(purpose); err != nil { return nil, err } t, err := time.MarshalBinary() if err != nil { return nil, err } if _, err := buf.Write(t); err != nil { return nil, err } if _, err := buf.Write(rand); err != nil { return nil, err } cb, err := clientKey.MarshalBinary() if err != nil { return nil, err } if _, err := buf.Write(cb); err != nil { return nil, err } for _, t := range threshold { if err := binary.Write(buf, binary.LittleEndian, uint32(t)); err != nil { return nil, err } } for _, gk := range serverKey { for _, k := range gk { kb, err := k.MarshalBinary() if err != nil { return nil, err } if _, err := buf.Write(kb); err != nil { return nil, err } } } return crypto.HashBytes(rh.Suite().Hash(), buf.Bytes()) }
// Returns a secret that depends on on a message and a point func (cosi *CosiStruct) HashElGamal(message []byte, p abstract.Point) abstract.Secret { pb, _ := p.MarshalBinary() c := cosi.Suite.Cipher(pb) c.Message(nil, nil, message) return cosi.Suite.Secret().Pick(c) }