Skip to content

Commit

Permalink
ckem: change crypto/elliptic to crypto/ecdh
Browse files Browse the repository at this point in the history
  • Loading branch information
MingLLuo committed Jan 18, 2025
1 parent 3d8cc98 commit 1cde56f
Showing 1 changed file with 66 additions and 43 deletions.
109 changes: 66 additions & 43 deletions kem/hybrid/ckem.go
Original file line number Diff line number Diff line change
@@ -1,57 +1,71 @@
package hybrid

// TODO move over to crypto/ecdh once we can assume Go 1.20.

import (
"crypto/elliptic"
"crypto/ecdh"
cryptoRand "crypto/rand"
"crypto/subtle"
"math/big"

"github.com/cloudflare/circl/kem"
"github.com/cloudflare/circl/xof"
)

type cPublicKey struct {
scheme *cScheme
x, y *big.Int
key *ecdh.PublicKey
}
type cPrivateKey struct {
scheme *cScheme
key []byte
key *ecdh.PrivateKey
}
type cScheme struct {
curve elliptic.Curve
}

var p256Kem = &cScheme{elliptic.P256()}

func (sch *cScheme) scSize() int {
return (sch.curve.Params().N.BitLen() + 7) / 8
curve ecdh.Curve
}

func (sch *cScheme) ptSize() int {
return (sch.curve.Params().BitSize + 7) / 8
}
var p256Kem = &cScheme{ecdh.P256()}

func (sch *cScheme) Name() string {
return sch.curve.Params().Name
switch sch.curve {
case ecdh.P256():
return "P256"
case ecdh.P384():
return "P384"
case ecdh.P521():
return "P521"
default:
panic("unsupported curve")
}
}

func (sch *cScheme) PublicKeySize() int {
return 2*sch.ptSize() + 1
switch sch.curve {
case ecdh.P256():
return 65
case ecdh.P384():
return 97
case ecdh.P521():
return 133
default:
panic("unsupported curve")
}
}

func (sch *cScheme) PrivateKeySize() int {
return sch.scSize()
switch sch.curve {
case ecdh.P256():
return 32
case ecdh.P384():
return 48
case ecdh.P521():
return 66
default:
panic("unsupported curve")
}
}

func (sch *cScheme) SeedSize() int {
return sch.PrivateKeySize()
}

func (sch *cScheme) SharedKeySize() int {
return sch.ptSize()
return sch.PrivateKeySize()
}

func (sch *cScheme) CiphertextSize() int {
Expand All @@ -66,9 +80,7 @@ func (sk *cPrivateKey) Scheme() kem.Scheme { return sk.scheme }
func (pk *cPublicKey) Scheme() kem.Scheme { return pk.scheme }

func (sk *cPrivateKey) MarshalBinary() ([]byte, error) {
ret := make([]byte, len(sk.key))
copy(ret, sk.key)
return ret, nil
return sk.key.Bytes(), nil
}

func (sk *cPrivateKey) Equal(other kem.PrivateKey) bool {
Expand All @@ -79,16 +91,15 @@ func (sk *cPrivateKey) Equal(other kem.PrivateKey) bool {
if oth.scheme != sk.scheme {
return false
}
return subtle.ConstantTimeCompare(oth.key, sk.key) == 1
return oth.key.Equal(sk.key)
}

func (sk *cPrivateKey) Public() kem.PublicKey {
x, y := sk.scheme.curve.ScalarBaseMult(sk.key)
return &cPublicKey{
sk.scheme,
x,
y,
pk, err := sk.scheme.curve.NewPublicKey(sk.key.Bytes())
if err != nil {
panic(err)
}
return &cPublicKey{scheme: sk.scheme, key: pk}
}

func (pk *cPublicKey) Equal(other kem.PublicKey) bool {
Expand All @@ -99,11 +110,11 @@ func (pk *cPublicKey) Equal(other kem.PublicKey) bool {
if oth.scheme != pk.scheme {
return false
}
return oth.x.Cmp(pk.x) == 0 && oth.y.Cmp(pk.y) == 0
return oth.key.Equal(pk.key)
}

func (pk *cPublicKey) MarshalBinary() ([]byte, error) {
return elliptic.Marshal(pk.scheme.curve, pk.x, pk.y), nil
return pk.key.Bytes(), nil
}

func (sch *cScheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
Expand All @@ -122,13 +133,14 @@ func (sch *cScheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
}
h := xof.SHAKE256.New()
_, _ = h.Write(seed)
key, x, y, err := elliptic.GenerateKey(sch.curve, h)
privKey, err := sch.curve.GenerateKey(h)
if err != nil {
panic(err)
}
pubKey := privKey.PublicKey()

sk := cPrivateKey{scheme: sch, key: key}
pk := cPublicKey{scheme: sch, x: x, y: y}
sk := cPrivateKey{scheme: sch, key: privKey}
pk := cPublicKey{scheme: sch, key: pubKey}

return &pk, &sk
}
Expand All @@ -147,9 +159,14 @@ func (pk *cPublicKey) X(sk *cPrivateKey) []byte {
panic(kem.ErrTypeMismatch)
}

sharedKey := make([]byte, pk.scheme.SharedKeySize())
xShared, _ := pk.scheme.curve.ScalarMult(pk.x, pk.y, sk.key)
xShared.FillBytes(sharedKey)
privKey, err := pk.scheme.curve.NewPrivateKey(sk.key.Bytes())
if err != nil {
panic(err)
}
sharedKey, err := privKey.ECDH(pk.key)
if err != nil {
panic(err)
}
return sharedKey
}

Expand Down Expand Up @@ -193,15 +210,21 @@ func (sch *cScheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error)
if len(buf) != sch.PublicKeySize() {
return nil, kem.ErrPubKeySize
}
x, y := elliptic.Unmarshal(sch.curve, buf)
return &cPublicKey{sch, x, y}, nil
key, err := sch.curve.NewPublicKey(buf)
if err != nil {
return nil, err
}
return &cPublicKey{sch, key}, nil
}

func (sch *cScheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
if len(buf) != sch.PrivateKeySize() {
return nil, kem.ErrPrivKeySize
}
ret := cPrivateKey{sch, make([]byte, sch.PrivateKeySize())}
copy(ret.key, buf)
key, err := sch.curve.NewPrivateKey(buf)
if err != nil {
return nil, err
}
ret := cPrivateKey{sch, key}
return &ret, nil
}

0 comments on commit 1cde56f

Please sign in to comment.