Пример #1
0
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
}
Пример #2
0
func (c *ownedCoder) ownerEncode(payload, payout []byte, p abstract.Point) {

	// XXX trap-encode

	// Pick a fresh random key with which to encrypt the payload
	key := make([]byte, c.keylen)
	c.random.XORKeyStream(key, key)

	// Encrypt the payload with it
	c.suite.Cipher(key).XORKeyStream(payout, payload)

	// Compute a MAC over the encrypted payload
	h := c.suite.Hash()
	h.Write(payout)
	mac := h.Sum(nil)[:c.maclen]

	// Combine the key and the MAC into the Point for this cell header
	hdr := append(key, mac...)
	if len(hdr) != p.PickLen() {
		panic("oops, length of key+mac turned out wrong")
	}
	mp, _ := c.suite.Point().Pick(hdr, c.random)

	// Add this to the blinding point we already computed to transmit.
	p.Add(p, mp)
}
Пример #3
0
// 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)
}
Пример #4
0
// 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
}
Пример #5
0
// Verifies that the 'message' is included in the signature and that it
// is correct.
// Message is your own hash, and reply contains the inclusion proof + signature
// on the aggregated message
func VerifySignature(suite abstract.Suite, reply *StampSignature, public abstract.Point, message []byte) bool {
	// Check if aggregate public key is correct
	if !public.Equal(reply.AggPublic) {
		dbg.Lvl1("Aggregate-public-key check: FAILED (maybe you have an outdated config file of the tree)")
		return false
	}
	// First check if the challenge is ok
	if err := VerifyChallenge(suite, reply); err != nil {
		dbg.Lvl1("Challenge-check: FAILED (", err, ")")
		return false
	}
	dbg.Lvl2("Challenge-check: OK")

	// Incorporate the timestamp in the message since the verification process
	// is done by reconstructing the challenge
	var b bytes.Buffer
	if err := binary.Write(&b, binary.LittleEndian, reply.Timestamp); err != nil {
		dbg.Lvl1("Error marshaling the timestamp for signature verification")
		return false
	}
	msg := append(b.Bytes(), []byte(reply.MerkleRoot)...)
	if err := VerifySchnorr(suite, msg, public, reply.Challenge, reply.Response); err != nil {
		dbg.Lvl1("Signature-check: FAILED (", err, ")")
		return false
	}
	dbg.Lvl2("Signature-check: OK")

	// finally check the proof
	if !proof.CheckProof(suite.Hash, reply.MerkleRoot, hashid.HashId(message), reply.Prf) {
		dbg.Lvl2("Inclusion-check: FAILED")
		return false
	}
	dbg.Lvl2("Inclusion-check: OK")
	return true
}
Пример #6
0
// 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
}
Пример #7
0
// 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)
}
Пример #8
0
func MarshalPoint(pt abstract.Point) []byte {
	buf := new(bytes.Buffer)
	ptByte := make([]byte, SecretSize)
	pt.MarshalTo(buf)
	buf.Read(ptByte)
	return ptByte
}
Пример #9
0
/* 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)
}
Пример #10
0
/* Verifies that a PolicyApproveMessage has been properly constructed.
 *
 * Arguments:
 *	su         = the suite that the insurer's public key was derived from.
 *      insuredKey = the public key of the insured or the client
 *      insurerKey = the public key of the insurer or "trustee"
 *
 * Returns:
 *	whether or not the message is valid.
 */
func (msg *PolicyApprovedMessage) verifyCertificate(su abstract.Suite,
	insuredKey abstract.Point) bool {

	set := anon.Set{msg.PubKey}
	_, err := anon.Verify(su, msg.Message, set, nil, msg.Signature)
	correctMsg := msg.PubKey.String() + " insures " + insuredKey.String()
	return err == nil && correctMsg == string(msg.Message)
}
Пример #11
0
// NewServerIdentity creates a new ServerIdentity based on a public key and with a slice
// of IP-addresses where to find that entity. The Id is based on a
// version5-UUID which can include a URL that is based on it's public key.
func NewServerIdentity(public abstract.Point, addresses ...string) *ServerIdentity {
	url := NamespaceURL + "id/" + public.String()
	return &ServerIdentity{
		Public:    public,
		Addresses: addresses,
		ID:        ServerIdentityID(uuid.NewV5(uuid.NamespaceURL, url)),
	}
}
Пример #12
0
// accommodate nils
func (sn *Node) sub(a abstract.Point, b abstract.Point) {
	if a == nil {
		a = sn.suite.Point().Null()
	}
	if b != nil {
		a.Sub(a, b)
	}
}
Пример #13
0
// 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
}
Пример #14
0
/* Adds a new connection to the connection manager
 *
 * Arguments:
 * 	theirkey = the key of the peer that this server wishes to connect to
 *
 * Returns:
 * 	An error denoting whether creating the new connection was successful.
 */
func (gcm *ChanConnManager) AddConn(theirKey abstract.Point) error {
	newConn, err := coconet.NewGoConn(gcm.dir, gcm.pubKey.String(),
		theirKey.String())
	if err != nil {
		return err
	}
	gcm.peerMap[theirKey.String()] = newConn
	return nil
}
Пример #15
0
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
}
Пример #16
0
func (c *Coordinator) AddClient(key abstract.Point, val *net.UDPAddr) {
	// delete the client who has same ip address
	for k, v := range c.Clients {
		if v.String() == val.String() {
			delete(c.Clients, k)
			break
		}
	}
	c.Clients[key.String()] = val
}
// (Either side) This function computes the shared public key
// by adding public key points over the curve group.
// Since each public key is already g*k where g is the group
// generator this is all we need to do
func SchnorrMComputeSharedPublicKey(suite abstract.Suite,
	pkeys []SchnorrPublicKey) SchnorrMultiSignaturePublicKey {

	var P abstract.Point = pkeys[0].Y

	for _, pkey := range pkeys[1:] {
		P.Add(P, pkey.Y)
	}
	return SchnorrMultiSignaturePublicKey{P}
}
Пример #18
0
/* Creates a new policy-approved message
 *
 * Arguments:
 *	kp       = the private/public key of the insuring server.
 *      theirKey = the public key of the server who requested the insurance
 *
 * Returns:
 *	A new policy approved message.
 *
 * NOTE:
 *	The approved certificate is a string of the form:
 *     		"My_Public_Key insures Their_Public_Key"
 *
 *	It will always be of this form for easy validation.
 */
func (msg *PolicyApprovedMessage) createMessage(kp *config.KeyPair,
	theirKey abstract.Point) *PolicyApprovedMessage {

	set := anon.Set{kp.Public}
	approveMsg := kp.Public.String() + " insures " + theirKey.String()
	msg.PubKey = kp.Public
	msg.Message = []byte(approveMsg)
	msg.Signature = anon.Sign(kp.Suite, random.Stream, msg.Message,
		set, nil, 0, kp.Secret)
	return msg
}
Пример #19
0
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)
}
Пример #20
0
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
}
Пример #21
0
func (c *ownedCoder) inlineEncode(payload []byte, p abstract.Point) {

	// Hash the cleartext payload to produce the MAC
	h := c.suite.Hash()
	h.Write(payload)
	mac := h.Sum(nil)[:c.maclen]

	// Embed the payload and MAC into a Point representing the message
	hdr := append(payload, mac...)
	mp, _ := c.suite.Point().Pick(hdr, c.random)

	// Add this to the blinding point we already computed to transmit.
	p.Add(p, mp)
}
// (Client side) The client requiring the n-signature scheme
// performs the addition of points under the elliptic curve group
// and returns the aggregate commitment as a raw point
// in bytes for transmission to the server
func SchnorrMComputeAggregateCommitment(suite abstract.Suite,
	pcommits []SchnorrMPublicCommitment) SchnorrMAggregateCommmitment {
	var P abstract.Point = pcommits[0].T

	for _, pcommit := range pcommits[1:] {
		P.Add(P, pcommit.T)
	}
	k := SchnorrMAggregateCommmitment{P}
	return k

	/*buf := bytes.Buffer{}
	  abstract.Write(&buf, &k, suite)
	  return buf.Bytes()*/
}
Пример #23
0
func ElGamalVerify(suite abstract.Suite, message []byte, publicKey abstract.Point,
	signatureBuffer []byte, g abstract.Point) error {

	// Decode the signature
	buf := bytes.NewBuffer(signatureBuffer)
	sig := basicSig{}
	if err := abstract.Read(buf, &sig, suite); 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(g, r), P.Mul(publicKey, c))

	// Verify that the hash based on the message and T
	// matches the challange c from the signature
	c = hashElGamal(suite, message, T)
	if !c.Equal(sig.C) {
		return errors.New("invalid signature")
	}

	return nil
}
Пример #24
0
func EncryptKey(g abstract.Group, msgPt abstract.Point, pks []abstract.Point) (abstract.Point, abstract.Point) {
	k := g.Scalar().Pick(random.Stream)
	c1 := g.Point().Mul(nil, k)
	var c2 abstract.Point = nil
	for _, pk := range pks {
		if c2 == nil {
			c2 = g.Point().Mul(pk, k)
		} else {
			c2 = c2.Add(c2, g.Point().Mul(pk, k))
		}
	}
	c2 = c2.Add(c2, msgPt)
	return c1, c2
}
Пример #25
0
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
}
Пример #26
0
func Encrypt(g abstract.Group, msg []byte, pks []abstract.Point) ([]abstract.Point, []abstract.Point) {
	c1s := []abstract.Point{}
	c2s := []abstract.Point{}
	var msgPt abstract.Point
	remainder := msg
	for len(remainder) != 0 {
		msgPt, remainder = g.Point().Pick(remainder, random.Stream)
		k := g.Scalar().Pick(random.Stream)
		c1 := g.Point().Mul(nil, k)
		var c2 abstract.Point = nil
		for _, pk := range pks {
			if c2 == nil {
				c2 = g.Point().Mul(pk, k)
			} else {
				c2 = c2.Add(c2, g.Point().Mul(pk, k))
			}
		}
		c2 = c2.Add(c2, msgPt)
		c1s = append(c1s, c1)
		c2s = append(c2s, c2)
	}
	return c1s, c2s
}
Пример #27
0
// PointDecodeFrom provides a generic implementation of Point.DecodeFrom,
// based on Point.Decode, or Point.Pick if r is a Cipher or cipher.Stream.
// The returned byte-count is valid only when decoding from a normal Reader,
// not when picking from a pseudorandom source.
func PointUnmarshalFrom(p abstract.Point, r io.Reader) (int, error) {
	if strm, ok := r.(cipher.Stream); ok {
		p.Pick(nil, strm)
		return -1, nil // no byte-count when picking randomly
	}
	buf := make([]byte, p.MarshalSize())
	n, err := io.ReadFull(r, buf)
	if err != nil {
		return n, err
	}
	return n, p.UnmarshalBinary(buf)
}
Пример #28
0
func ElGamalVerify(suite abstract.Suite, message []byte, publicKey abstract.Point,
	sig BasicSig) error {
	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 = hashElGamal(suite, message, T)
	if !c.Equal(sig.C) {
		return errors.New("invalid signature")
	}

	return nil
}
Пример #29
0
func SchnorrVerify(suite abstract.Suite, message []byte,
	signature net.BasicSignature) error {
	publicKey := signature.Pub
	r := signature.Resp
	c := signature.Chall

	// 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(signature.Chall) {
		return errors.New("invalid signature")
	}

	return nil
}
Пример #30
0
// Pick a [pseudo-]random curve point with optional embedded data,
// filling in the point's x,y coordinates
// and returning any remaining data not embedded.
func (c *curve) pickPoint(P point, data []byte, rand cipher.Stream) []byte {

	// How much data to embed?
	dl := c.pickLen()
	if dl > len(data) {
		dl = len(data)
	}

	// Retry until we find a valid point
	var x, y nist.Int
	var Q abstract.Point
	for {
		// Get random bits the size of a compressed Point encoding,
		// in which the topmost bit is reserved for the x-coord sign.
		l := c.PointLen()
		b := make([]byte, l)
		rand.XORKeyStream(b, b) // Interpret as little-endian
		if data != nil {
			b[0] = byte(dl)       // Encode length in low 8 bits
			copy(b[1:1+dl], data) // Copy in data to embed
		}
		util.Reverse(b, b) // Convert to big-endian form

		xsign := b[0] >> 7                    // save x-coordinate sign bit
		b[0] &^= 0xff << uint(c.P.BitLen()&7) // clear high bits

		y.M = &c.P // set y-coordinate
		y.SetBytes(b)

		if !c.solveForX(&x, &y) { // Corresponding x-coordinate?
			continue // none, retry
		}

		// Pick a random sign for the x-coordinate
		if c.coordSign(&x) != uint(xsign) {
			x.Neg(&x)
		}

		// Initialize the point
		P.initXY(&x.V, &y.V, c.self)
		if c.full {
			// If we're using the full group,
			// we just need any point on the curve, so we're done.
			return data[dl:]
		}

		// We're using the prime-order subgroup,
		// so we need to make sure the point is in that subgroup.
		// If we're not trying to embed data,
		// we can convert our point into one in the subgroup
		// simply by multiplying it by the cofactor.
		if data == nil {
			P.Mul(P, &c.cofact) // multiply by cofactor
			if P.Equal(c.null) {
				continue // unlucky; try again
			}
			return data[dl:]
		}

		// Since we need the point's y-coordinate to make sense,
		// we must simply check if the point is in the subgroup
		// and retry point generation until it is.
		if Q == nil {
			Q = c.self.Point()
		}
		Q.Mul(P, &c.order)
		if Q.Equal(c.null) {
			return data[dl:]
		}

		// Keep trying...
	}
}