Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of the cipher suite registry #587

Closed
wants to merge 14 commits into from

Conversation

Gilthoniel
Copy link
Contributor

@Gilthoniel Gilthoniel commented Oct 15, 2019

  • Add a ciphersuite package that contains the abstraction of the cryptographic primitives.
  • Add a builder.go file that contains the implementation of a server builder.
  • Remove the public API to create a server.
  • Remove the service factory to have a non-static service registration through the builder.

Closes #579

The registry will be used to replace the Kyber primitives so that Onet
can have access to a wider range of cipher suite at runtime.
@Gilthoniel Gilthoniel self-assigned this Oct 15, 2019
@Gilthoniel Gilthoniel force-pushed the crypto_interfaces_579 branch from 83c1d77 to 8713c63 Compare October 18, 2019 12:37
@ineiti
Copy link
Member

ineiti commented Oct 21, 2019

Is there a document describing what you're doing here?

@Gilthoniel
Copy link
Contributor Author

Question:

  • Rename ciphersuite to something shorter ? csuite ?

@Gilthoniel
Copy link
Contributor Author

Gilthoniel commented Oct 22, 2019

Follow-ups (marked as TODO in the code):

  • server.go : it's using an online service to verify the connection or find the host
  • builder.go : better check of the parameters
  • service.go : database name mixed between the builder and old logic
  • simulation.go : better use of the builder if possible

Copy link
Member

@ineiti ineiti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to have my opinion on this PR, then you will need to split it into different PRs. As far as I can see (I might be completely wrong), you're doing quite a lot in this PR (perhaps I should not throw this stone - but I think I got better on this front). Too much for me, too many parts of onet touched/changed. The last 20-something files are not even shown in the git-overview...

There is quite a lot of changes in the services and messages that I don't understand and where I don't find anything in the README. I did make some comments in there, but I have no idea what is going on.

With regard to the cipher suite registry, I don't see how you want to make this work with either the kyber or the lattigo implementation. I would like to have an example of both of these in the ciphersuite_test.go, I think that would also help you to improve the interface. I'm sure it's possible, but I don't see how. Also, please make sure that your new interfaces make sense and discuss with Bryan, Philipp, and Christian.

Also, the UnsecureCipherSuite sounds like a really bad idea to me. People might use it. It doesn't show how to use it in a given setting. I would prefer to have something like Ed25519CipherSuite or so, which is kind of a simple suite that should give you all you need. But having a Signature method that puts the message in the signature is really bad precedence for people trying to learn what you're doing... Again, they might just copy it and use it for something critical.

My proposition to go on with this PR is to focus on the cipher suite registry and undo all other changes to the service and message-passing that are not directly linked to the cipher suite registry.

Anyway - my 2 cents.

creating a service to extend the base interface and force the registration of the
service with this extended cipher suite:

```go
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer seeing the actual cipher suite definition with some explanation here, and then how to extend it...


// CipherData is a self-contained message type that can be used
// over the network in the contrary of the interfaces.
type CipherData struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you use the same system as with the kyber suite binaryMarshaller? It reminds me of https://xkcd.com/927/

}

func (d *CipherData) String() string {
buf := append([]byte(d.Name), d.Data...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a string I would do something like

fmt.Sprintf("%s: %x", d.Name, d.Data)

makes it a little bit nicer...

// MarshalText implements the encoding interface TextMarshaler so that
// it can be serialized in format such as TOML.
func (d *CipherData) MarshalText() ([]byte, error) {
name := []byte(d.Name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it ends up in a toml file it will be read by persons, so I'd prefer to have a clear-text representation of the Name. So I would rather use String() here.
Also, I don't see why you want to add the size here?


// Packable provides the primitives necessary to make network
// messages out of interfaces.
type Packable interface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work together with the current way of registering the interfaces to the protobuf package?


// Sign must produce a signature that can be validated by the
// associated public key of the secret key.
Sign(sk SecretKey, msg []byte) (Signature, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure: is this enough for lattice-based crypto? Should there be a more generic interface?

// Verify must return nil when the signature is valid for the
// message and the public key. Otherwise it should return the
// reason of the invalidity.
Verify(pk PublicKey, signature Signature, msg []byte) error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here: are there more parameters needed in the case of lattigo?


const nonceLength = 16

// UnsecureCipherSuiteName is the reference name for the cipher suite
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is only used for testing, then why isn't it in _test.go?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it unsecure? Why do you need an unsecure suite?

// Sign takes a secret key and a message and returns the signature of
// the message that can be verified by the associated public key.
func (c *UnsecureCipherSuite) Sign(sk SecretKey, msg []byte) (Signature, error) {
if len(msg) == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most often you don't sign the message, but you sign the hash of the message. As sha256([]byte{}) is defined, I think it's wrong to return an error here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would at least use sha256 here in the 'signature'. Then you have a constant length signature, which is much more accurate, even for a UnsecureCipherSuite.

// messages going to protocol instances
c.RegisterProcessor(o,
ProtocolMsgID, // protocol instance's messages
RequestTreeMsgID, // request a tree
ResponseTreeMsgID, // send a tree back to a request
RequestRosterMsgID,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did these messages go to? Are they not needed anymore?

if host != "" {
builder.SetHost(host)
} else {
builder.SetHost("0.0.0.0")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DefaultAddress?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it gets overwriten by next if host == "".

"golang.org/x/xerrors"
)

var sizeLength = 32 / 8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const, not very descriptive name.

Signature() Signature

// KeyPair must return a random secret key and its associated public key.
KeyPair() (PublicKey, SecretKey)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an action, not a value, GenRandomKeyPair?

func (cr *Registry) KeyPair(name Name) (PublicKey, SecretKey) {
c, err := cr.get(name)
if err != nil {
panic(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why panic? The others func of this API are returning error when something is not found.

// will also return an error if the cipher suite is unknown.
func (cr *Registry) Verify(pk PublicKey, sig Signature, msg []byte) error {
if pk.Name() != sig.Name() {
return xerrors.New("mismatching cipher names")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, you can use import "errors" directly now (Errorf is now part of "fmt").

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think cothority still wants to keep backward-compatibility with 1.12, which has no xerrors in the stdlib yet.

// List is the list of actual entities.
List []*network.ServerIdentity
Aggregate kyber.Point
List []*network.ServerIdentity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type Roster []*network.ServerIdentity

return r
// Len returns the length of the roster.
func (ro *Roster) Len() int {
return len(ro.List)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? It's shorter to write len() and avoid the call.

if err != nil {
return RosterID{}, xerrors.Errorf("marshaling: %v", err)
// An error at that point would mean something worst is
// happening, so we keep the function simple and panic.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or, we can have a RosterBuilder which populate the ID field when building :P

data := n.Host().ServerIdentity.ServicePublic(name)
pk, err := n.overlay.cr.UnpackPublicKey(data)
if err != nil {
log.Error(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log.Panicf

if err != nil {
log.Error(err)
panic("Couldn't unpack the public key of the distant node. Please check " +
"the of the server.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Sure, I'll check the of the server."

Gaylor Bosson added 2 commits October 24, 2019 16:19
This improves the code to prevent mixing cipher data between different
element types.
@dedis dedis deleted a comment Oct 28, 2019
@Gilthoniel
Copy link
Contributor Author

I heard your thoughts! Thanks, I'm going to create multiple small PRs with independent modules and a last one to make them work together.

Gilthoniel pushed a commit to dedis/cothority that referenced this pull request Oct 28, 2019
@Gilthoniel Gilthoniel force-pushed the crypto_interfaces_579 branch from 069d10e to 9ec1d63 Compare December 4, 2019 08:12
@Gilthoniel Gilthoniel closed this Mar 24, 2020
@ineiti ineiti deleted the crypto_interfaces_579 branch March 24, 2020 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make Onet independent from Kyber
3 participants