-
Notifications
You must be signed in to change notification settings - Fork 29
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
Conversation
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.
This changes the service factory to remove the static registry and have instead a registry per server.
83c1d77
to
8713c63
Compare
Is there a document describing what you're doing here? |
Question:
|
Follow-ups (marked as TODO in the code):
|
There was a problem hiding this 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 |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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/
ciphersuite/ciphersuite.go
Outdated
} | ||
|
||
func (d *CipherData) String() string { | ||
buf := append([]byte(d.Name), d.Data...) |
There was a problem hiding this comment.
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...
ciphersuite/ciphersuite.go
Outdated
// 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) |
There was a problem hiding this comment.
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?
ciphersuite/ciphersuite.go
Outdated
|
||
// Packable provides the primitives necessary to make network | ||
// messages out of interfaces. | ||
type Packable interface { |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
ciphersuite/unsecure_csuite.go
Outdated
|
||
const nonceLength = 16 | ||
|
||
// UnsecureCipherSuiteName is the reference name for the cipher suite |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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?
ciphersuite/unsecure_csuite.go
Outdated
// 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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DefaultAddress
?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
ciphersuite/ciphersuite.go
Outdated
Signature() Signature | ||
|
||
// KeyPair must return a random secret key and its associated public key. | ||
KeyPair() (PublicKey, SecretKey) |
There was a problem hiding this comment.
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
?
ciphersuite/registry.go
Outdated
func (cr *Registry) KeyPair(name Name) (PublicKey, SecretKey) { | ||
c, err := cr.get(name) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
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") |
There was a problem hiding this comment.
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").
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.") |
There was a problem hiding this comment.
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."
This improves the code to prevent mixing cipher data between different element types.
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. |
069d10e
to
9ec1d63
Compare
Closes #579