Пример #1
0
func benchScalarMult(curve elliptic.Curve, k []byte, n int) {
	x := curve.Params().Gx
	y := curve.Params().Gy
	for i := 0; i < n; i++ {
		curve.ScalarMult(x, y, k)
	}
}
Пример #2
0
func DecryptMark(c elliptic.Curve, m *Mark, priv []byte) (int, error) {
	tx, ty := c.ScalarMult(m.ax, m.ay, priv)
	tm := big.NewInt(0)
	tm.Sub(c.Params().P, ty)
	tm.Mod(tm, c.Params().P)
	px, py := c.Add(m.bx, m.by, tx, tm)
	return DiscreteLog(px, py, c, 1<<10)
}
Пример #3
0
func VoteOne(c elliptic.Curve, px *big.Int, py *big.Int) *Checkbox {
	var err error
	h := new(Checkbox)
	h.s, err = rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("this shouldn't happen")
	}
	h.ax, h.ay = c.ScalarBaseMult(h.s.Bytes())
	tx, ty := c.ScalarMult(px, py, h.s.Bytes())
	h.bx, h.by = c.Add(tx, ty, c.Params().Gx, c.Params().Gy)
	//TODO: refactor: lots of similar logic here but parts very
	//c2, r2 fake, c1 r1 genuine
	//Form the faked challenge
	h.c2, err = rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("this shouldn't happen")
	}
	h.r2, err = rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("this shouldn't happen")
	}
	//Compute the commitments v3, v4 as the verifier will
	v3x, v3y := doublescalarmult(c, c.Params().Gx, c.Params().Gy, h.r2.Bytes(),
		h.ax, h.ay, h.c2.Bytes())
	v4x, v4y := doublescalarmult(c, px, py, h.r2.Bytes(),
		h.bx, h.by, h.c2.Bytes())
	//Commit to other side
	s1, err := rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("something deeply wrong")
	}
	v1x, v1y := c.ScalarBaseMult(s1.Bytes())
	v2x, v2y := c.ScalarMult(px, py, s1.Bytes())
	//Compute the total challenge
	var entries [6][]byte
	entries[0] = elliptic.Marshal(c, h.ax, h.ay)
	entries[1] = elliptic.Marshal(c, h.bx, h.by)
	entries[2] = elliptic.Marshal(c, v1x, v1y)
	entries[3] = elliptic.Marshal(c, v2x, v2y)
	entries[4] = elliptic.Marshal(c, v3x, v3y)
	entries[5] = elliptic.Marshal(c, v4x, v4y)
	challenge := sha256.Sum256(bytes.Join(entries[:], []byte{}))
	ctot := big.NewInt(0)
	ctot.SetBytes(challenge[:])
	ctot.Mod(ctot, c.Params().N)
	h.c1 = big.NewInt(0)
	h.c1.Sub(ctot, h.c2)
	h.c1.Mod(h.c1, c.Params().N)
	//r=s1-c1*h.s
	t := big.NewInt(0)
	t.Mul(h.c1, h.s)
	t.Mod(t, c.Params().N)
	t.Sub(s1, t)
	t.Mod(t, c.Params().N)
	h.r1 = t
	return h
}
Пример #4
0
// kexECDH performs Elliptic Curve Diffie-Hellman key exchange as
// described in RFC 5656, section 4.
func (c *ClientConn) kexECDH(curve elliptic.Curve, magics *handshakeMagics, hostKeyAlgo string) (*kexResult, error) {
	ephKey, err := ecdsa.GenerateKey(curve, c.config.rand())
	if err != nil {
		return nil, err
	}

	kexInit := kexECDHInitMsg{
		ClientPubKey: elliptic.Marshal(curve, ephKey.PublicKey.X, ephKey.PublicKey.Y),
	}

	serialized := marshal(msgKexECDHInit, kexInit)
	if err := c.writePacket(serialized); err != nil {
		return nil, err
	}

	packet, err := c.readPacket()
	if err != nil {
		return nil, err
	}

	var reply kexECDHReplyMsg
	if err = unmarshal(&reply, packet, msgKexECDHReply); err != nil {
		return nil, err
	}

	x, y := elliptic.Unmarshal(curve, reply.EphemeralPubKey)
	if x == nil {
		return nil, errors.New("ssh: elliptic.Unmarshal failure")
	}
	if !validateECPublicKey(curve, x, y) {
		return nil, errors.New("ssh: ephemeral server key not on curve")
	}

	// generate shared secret
	secret, _ := curve.ScalarMult(x, y, ephKey.D.Bytes())

	hashFunc := ecHash(curve)
	h := hashFunc.New()
	writeString(h, magics.clientVersion)
	writeString(h, magics.serverVersion)
	writeString(h, magics.clientKexInit)
	writeString(h, magics.serverKexInit)
	writeString(h, reply.HostKey)
	writeString(h, kexInit.ClientPubKey)
	writeString(h, reply.EphemeralPubKey)
	K := make([]byte, intLength(secret))
	marshalInt(K, secret)
	h.Write(K)

	return &kexResult{
		H:         h.Sum(nil),
		K:         K,
		HostKey:   reply.HostKey,
		Signature: reply.Signature,
		Hash:      hashFunc,
	}, nil
}
Пример #5
0
// Generates an ephemeral public key and returns a function that will compute
// the shared secret key.  Used in the identify module.
//
// Focuses only on ECDH now, but can be made more general in the future.
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
	var curve elliptic.Curve

	switch curveName {
	case "P-224":
		curve = elliptic.P224()
	case "P-256":
		curve = elliptic.P256()
	case "P-384":
		curve = elliptic.P384()
	case "P-521":
		curve = elliptic.P521()
	}

	priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
	if err != nil {
		return nil, nil, err
	}

	var pubKey bytes.Buffer
	pubKey.Write(x.Bytes())
	pubKey.Write(y.Bytes())

	done := func(theirPub []byte) ([]byte, error) {
		// Verify and unpack node's public key.
		curveSize := curve.Params().BitSize

		if len(theirPub) != (curveSize / 4) {
			return nil, errors.New("Malformed public key.")
		}

		bound := (curveSize / 8)
		x := big.NewInt(0)
		y := big.NewInt(0)

		x.SetBytes(theirPub[0:bound])
		y.SetBytes(theirPub[bound : bound*2])

		if !curve.IsOnCurve(x, y) {
			return nil, errors.New("Invalid public key.")
		}

		// Generate shared secret.
		secret, _ := curve.ScalarMult(x, y, priv)

		return secret.Bytes(), nil
	}

	return pubKey.Bytes(), done, nil
}
Пример #6
0
func FillBallot(c elliptic.Curve, px *big.Int, py *big.Int, entry int,
	size int) *Ballot {
	b := new(Ballot)
	b.boxes = make([]*Checkbox, size, size)
	for i := 0; i < size; i++ {
		if i == entry {
			b.boxes[i] = VoteOne(c, px, py)
		} else {
			b.boxes[i] = VoteZero(c, px, py)
		}
	}
	//TODO: add validation
	//Let A be the sum of all the A, B the sum of all the B
	//Then we want log_g(A)=log_h(B-g)

	ax := big.NewInt(0)
	ay := big.NewInt(0)
	bx := big.NewInt(0)
	by := big.NewInt(0)
	s := big.NewInt(0)
	for i := 0; i < size; i++ {
		ax, ay = c.Add(ax, ay, b.boxes[i].ax, b.boxes[i].ay)
		bx, by = c.Add(bx, by, b.boxes[i].bx, b.boxes[i].by)
		s.Add(s, b.boxes[i].s)
	}
	s.Mod(s, c.Params().N)
	k, err := rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("Not here, not now")
	}
	v1x, v1y := c.ScalarBaseMult(k.Bytes())
	v2x, v2y := c.ScalarMult(px, py, k.Bytes())
	var commit [4][]byte
	commit[0] = elliptic.Marshal(c, ax, ay)
	commit[1] = elliptic.Marshal(c, bx, by)
	commit[2] = elliptic.Marshal(c, v1x, v1y)
	commit[3] = elliptic.Marshal(c, v2x, v2y)
	cb := bytes.Join(commit[:], []byte{})
	cbytes := sha256.Sum256(cb[:])
	b.c = big.NewInt(0)
	b.c.SetBytes(cbytes[:])
	b.c.Mod(b.c, c.Params().N)
	b.r = big.NewInt(0)
	//r=k-c*s
	b.r.Mul(b.c, s)
	b.r.Sub(k, b.r)
	b.r.Mod(b.r, c.Params().N)
	return b
}
Пример #7
0
// Generates an ephemeral public key and returns a function that will compute
// the shared secret key.  Used in the identify module.
//
// Focuses only on ECDH now, but can be made more general in the future.
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
	var curve elliptic.Curve

	switch curveName {
	case "P-224":
		curve = elliptic.P224()
	case "P-256":
		curve = elliptic.P256()
	case "P-384":
		curve = elliptic.P384()
	case "P-521":
		curve = elliptic.P521()
	}

	priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
	if err != nil {
		return nil, nil, err
	}

	pubKey := elliptic.Marshal(curve, x, y)
	// log.Debug("GenerateEKeyPair %d", len(pubKey))

	done := func(theirPub []byte) ([]byte, error) {
		// Verify and unpack node's public key.
		x, y := elliptic.Unmarshal(curve, theirPub)
		if x == nil {
			return nil, fmt.Errorf("Malformed public key: %d %v", len(theirPub), theirPub)
		}

		if !curve.IsOnCurve(x, y) {
			return nil, errors.New("Invalid public key.")
		}

		// Generate shared secret.
		secret, _ := curve.ScalarMult(x, y, priv)

		return secret.Bytes(), nil
	}

	return pubKey, done, nil
}
Пример #8
0
func doublescalarmult(c elliptic.Curve, ax *big.Int, ay *big.Int, s1 []byte,
	bx *big.Int, by *big.Int, s2 []byte) (*big.Int, *big.Int) {
	t1x, t1y := c.ScalarMult(ax, ay, s1)
	t2x, t2y := c.ScalarMult(bx, by, s2)
	return c.Add(t1x, t1y, t2x, t2y)
}
Пример #9
0
func VoteZero(c elliptic.Curve, px *big.Int, py *big.Int) *Checkbox {
	var err error
	h := new(Checkbox)
	h.s, err = rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("this shouldn't happen")
	}
	h.ax, h.ay = c.ScalarBaseMult(h.s.Bytes())
	h.bx, h.by = c.ScalarMult(px, py, h.s.Bytes())
	//TODO: get the proof generated
	//c1, r1 fake,  c2, r2 genuine
	//First compute the missing B-g
	tx := big.NewInt(0)
	tx.Set(c.Params().Gx)
	ty := big.NewInt(0)
	ty.Set(c.Params().Gy)
	ty.Neg(ty)
	ty.Mod(ty, c.Params().P)
	bgx, bgy := c.Add(tx, ty, h.bx, h.by)
	//Now fake the challenge
	h.c1, err = rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("this shouldn't happen")
	}
	h.r1, err = rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("this shouldn't happen")
	}
	//Compute v1, v2 as verifier will
	v1x, v1y := doublescalarmult(c, c.Params().Gx, c.Params().Gy,
		h.r1.Bytes(), h.ax, h.ay, h.c1.Bytes())
	v2x, v2y := doublescalarmult(c, px, py, h.r1.Bytes(),
		bgx, bgy, h.c1.Bytes())
	//Other part of commitment
	s1, err := rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		panic("something is deeply wrong")
	}
	v3x, v3y := c.ScalarBaseMult(s1.Bytes())
	v4x, v4y := c.ScalarMult(px, py, s1.Bytes())
	//Compute total challenge
	var entries [6][]byte
	entries[0] = elliptic.Marshal(c, h.ax, h.ay)
	entries[1] = elliptic.Marshal(c, h.bx, h.by)
	entries[2] = elliptic.Marshal(c, v1x, v1y)
	entries[3] = elliptic.Marshal(c, v2x, v2y)
	entries[4] = elliptic.Marshal(c, v3x, v3y)
	entries[5] = elliptic.Marshal(c, v4x, v4y)
	challenge := sha256.Sum256(bytes.Join(entries[:], []byte{}))
	ctot := big.NewInt(0)
	ctot.SetBytes(challenge[:])
	ctot.Mod(ctot, c.Params().N)
	h.c2 = big.NewInt(0)
	h.c2.Sub(ctot, h.c1)
	h.c2.Mod(h.c2, c.Params().N)
	//r2=s1-c2*s
	h.r2 = big.NewInt(0)
	h.r2.Mul(h.c2, h.s)
	h.r2.Sub(s1, h.r2)
	h.r2.Mod(h.r2, c.Params().N)
	return h
}
Пример #10
0
// kexECDH performs Elliptic Curve Diffie-Hellman key agreement on a
// ServerConnection, as documented in RFC 5656, section 4.
func (s *ServerConn) kexECDH(curve elliptic.Curve, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
	packet, err := s.readPacket()
	if err != nil {
		return
	}

	var kexECDHInit kexECDHInitMsg
	if err = unmarshal(&kexECDHInit, packet, msgKexECDHInit); err != nil {
		return
	}

	clientX, clientY := elliptic.Unmarshal(curve, kexECDHInit.ClientPubKey)
	if clientX == nil {
		return nil, errors.New("ssh: elliptic.Unmarshal failure")
	}

	if !validateECPublicKey(curve, clientX, clientY) {
		return nil, errors.New("ssh: not a valid EC public key")
	}

	// We could cache this key across multiple users/multiple
	// connection attempts, but the benefit is small. OpenSSH
	// generates a new key for each incoming connection.
	ephKey, err := ecdsa.GenerateKey(curve, s.config.rand())
	if err != nil {
		return nil, err
	}

	hostKeyBytes := MarshalPublicKey(priv.PublicKey())

	serializedEphKey := elliptic.Marshal(curve, ephKey.PublicKey.X, ephKey.PublicKey.Y)

	// generate shared secret
	secret, _ := curve.ScalarMult(clientX, clientY, ephKey.D.Bytes())

	hashFunc := ecHash(curve)
	h := hashFunc.New()
	writeString(h, magics.clientVersion)
	writeString(h, magics.serverVersion)
	writeString(h, magics.clientKexInit)
	writeString(h, magics.serverKexInit)
	writeString(h, hostKeyBytes)
	writeString(h, kexECDHInit.ClientPubKey)
	writeString(h, serializedEphKey)

	K := make([]byte, intLength(secret))
	marshalInt(K, secret)
	h.Write(K)

	H := h.Sum(nil)

	// H is already a hash, but the hostkey signing will apply its
	// own key specific hash algorithm.
	sig, err := signAndMarshal(priv, s.config.rand(), H)
	if err != nil {
		return nil, err
	}

	reply := kexECDHReplyMsg{
		EphemeralPubKey: serializedEphKey,
		HostKey:         hostKeyBytes,
		Signature:       sig,
	}

	serialized := marshal(msgKexECDHReply, reply)
	if err := s.writePacket(serialized); err != nil {
		return nil, err
	}

	return &kexResult{
		H:       H,
		K:       K,
		HostKey: reply.HostKey,
		Hash:    hashFunc,
	}, nil
}
Пример #11
0
// ComputeShared computes the shared key for the private key material priv and
// the x and y public coordinates
func ComputeShared(curve elliptic.Curve, x, y *big.Int, priv []byte) []byte {
	x, _ = curve.ScalarMult(x, y, priv)
	return x.Bytes()
}
Пример #12
0
func testScalarMult(curve elliptic.Curve, x1, y1, k, ex, ey *big.Int) bool {
	x, y := curve.ScalarMult(x1, y1, k.Bytes())
	return x.Cmp(ex) == 0 && y.Cmp(ey) == 0
}