Skip to content
This repository has been archived by the owner on Sep 6, 2022. It is now read-only.

Provide interfaces related to the abstract cryptographic operation being done #92

Open
keks opened this issue Sep 27, 2016 · 6 comments

Comments

@keks
Copy link

keks commented Sep 27, 2016

The current PrivKey is a Key that can also sign stuff, so it actually is a SigKey. You could also let MACs implement this interface.

  • Signatures (SigKey and VerifyKey)
  • Key Exchange (KXPrivKey.Exchange(KXPubKey)
  • Symmetric Secrets implementing SignKey and VerifyKey as well as EncryptKey and DecryptKey and AuthEncKey and AuthDecKey (as in golang.org/x/crypto/nacl/secretbox).
  • Asymmetric Authenticated Encryption, providing defaults by combining Key Exchange + symmetric AE (or just use golang.org/x/crypto/nacl/box).

I'll keep on thinking about this and drop some notes over the day.

@keks
Copy link
Author

keks commented Sep 27, 2016

Obvious:

type SigKey interface {
Key
Sign(data []byte) (sig []byte)
}

type VerifyKey interface {
Key
Verify(data, sig []byte) bool
}

@keks
Copy link
Author

keks commented Sep 27, 2016

type KXPrivKey interface {
  Key
  Exchange(KXPubKey) Key
}

type KXPubKey interface {
  Key
  Exchange(KXPrivKey) Key
}

We can now use the resulting Key as input for e.g. SecretboxKey and use it to create secretboxes:

func AsSecretboxKey(k Key) SecretboxKey
type SecretboxKey Key
func (sbk SecretboxKey) Seal(data, nonce []byte) (ciphertext []byte) {...}
func (sbk SecretboxKey) Open(ciphertext, nonce []byte) (data []byte) {...}

Which brings us to the interface for Authenticated Encryption:

type AuthEncSymKey interface {
  Key
  Seal(data, nonce []byte) []byte
  Open(ciphertext, nonce []byte) []byte
}

And the asymmetric version would be

type AuthEncPrivKey interface {
  Key
  Seal(k AuthEncPubKey, data, nonce []byte) (ciphertext []byte)
  Open(k AuthEncPubKey, ciphertext, nonce []byte) (data []byte)
}

Doing AE with RSA is pretty common nowadays too, so I think this is the right interface. We can should provide EncryptionKey and DecryptionKey interfaces

type EncryptionKey interface {
  Key
  Encrypt([]byte) []byte
}
type DecryptionKey interface {
  Key
  Decrypt([]byte) []byte
}

Then we could provide some default types for NaCl boxes, RSA and Ed25519.

I'm pretty much free right now so I can do it if you like the idea.

@Kubuxu
Copy link
Member

Kubuxu commented Sep 27, 2016

Warning: doing encryption and signing using same RSA key leaks information and is potentially unsafe.

@keks
Copy link
Author

keks commented Sep 27, 2016

My primary concern is not the concrete implementations but the interfaces. I don't plan to make changes to the Rsa* types, except maybe changing some type such that it fits the new interfaces.

Looking at the code, currently we seem to allow using the same keys for encryption and signing. We might want to fix that too. Filed libp2p/go-libp2p-crypto#9.

@keks
Copy link
Author

keks commented Sep 28, 2016

Looking at the interfaces I proposed again, this all feels weird. E.g. the key exchange is not performed by the keys, but it's two communicating entities using the Keys to negotiate a shared secret. The key doesn't sign the data, it's the algorithm using the key. I'll think about interfaces that reflect that.

@keks
Copy link
Author

keks commented Sep 28, 2016

How about

type Key interface {
  Type() KeyType // e.g. ed25519-pub, rsa-priv, secret
  Purpose() Purpose // eg. Signing, Encryption, Decryption, KeyDerivation, ...
  Bytes() []byte
  String() string // for good measure
}

// example
func Sign(k Key, data []byte) ([]byte, error) {
  var sig []byte

  if !k.Purpose() == Signing {
    return WrongPurposeError
  }

  switch k.Type() {
  case ed25519-priv: 
    ...
    sig = ...
  case ...
  }

  return sig
}

This way it behaves a bit more like a net.Addr. What do you think about this?

@Stebalien Stebalien transferred this issue from libp2p/go-libp2p-crypto Dec 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants